質問

私の質問は、Git がブランチを処理する方法についてです。コミットから分岐するたびに、このブランチは親ブランチから変更を受け取ることはありません。 それをマージします。

しかし、Clearcase や Accurev などの他のシステムでは、ブランチをどのように埋めるかを指定できます。 何らかの継承メカニズム:つまり、Clearcase では、config_spec を使用して、「ブランチ /main/issue001 で変更されたすべてのファイルを取得し、その後、/main 上のファイルまたはこの特定のベースラインを使用して続行する」ことができます。

Accurev には、ブランチ上で新しいコミットをマージしたり作成したりせずに、ストリームが上位ブランチ (ストリームが呼び出す方法) から変更を受信できるようにする同様のメカニズムもあります。

Gitを使っているとこんなことを見逃しませんか?これが起こるシナリオを列挙できますか? 継承 必須ですか?

ありがとう

アップデート 実際に私の質問に焦点を当てるには、以下の VonC の回答を読んでください。「リニア ストレージ」と DAG ベースの SCM には異なる機能があることに同意したら、私の質問は次のとおりです。 DAG では不可能なことをリニアで実現できる実際のシナリオ (特に OSS よりも多くの企業) はどれですか?価値はあるのでしょうか?

役に立ちましたか?

解決

Git が「継承メカニズム」と呼ばれるもの (コミットを伴わないもの) を提供しない理由を理解するには、まず次のいずれかを理解する必要があります。 コアコンセプト これらの SCM (Git とたとえば、ClearCase)

  • ClearCase は リニアバージョンストレージ:要素 (ファイルまたはディレクトリ) の各バージョンは直接リンクされています。 線形 同じ要素の前のバージョンとの関係。

  • Git は DAG - 有向非巡回グラフ:ファイルの各「バージョン」は、実際には、それ自体がコミットの一部であるツリー内のグローバルな変更セットの一部です。その以前のバージョンは以前のコミット内に存在し、単一の有向非巡回グラフ パスを通じてアクセスできる必要があります。

線形システムでは、構成仕様で、表示される「継承」を実現するためのいくつかのルールを指定できます (特定のファイルに対して、最初に特定のバージョンを選択し、存在しない場合は別のバージョンを選択し、存在しない場合は別のバージョンを選択します)。 3 番目など)。

その支店は、 フォーク線形 特定の選択ルールの特定のバージョンの履歴 (その選択ルールより前の他のすべての選択ルールは引き続き適用されるため、「継承」効果があります)

DAG では、コミットは、これまでに取得するすべての「継承」を表します。バージョンの「累積」選択はありません。このグラフには、この時点 (コミット) で表示されるすべてのファイルを選択するためのパスが 1 つだけあります。
ブランチは、このグラフにおける新しいパスにすぎません。

Git で他のバージョンを適用するには、次のいずれかを行う必要があります。

ただし、Git は DAG ベースの SCM であるため、常に新しいコミットが発生します。

Git で「失う」のは、ある種の「構成」です (連続する異なる選択ルールで異なるバージョンを選択する場合) が、それは実際的な環境では実用的ではありません。 DVCS (「分散」と同様):Git でブランチを作成する場合は、開始点を使用してブランチを作成する必要があります。 そして内容 明確に定義されており、他のリポジトリに簡単に複製できます。

純粋に中央の VCS では、任意のルールを使用してワークスペース (ClearCase ではスナップショットまたはダイナミックの「ビュー」) を定義できます。


不明-グーグル コメント(および上記の質問)に次のように追加します。

したがって、2 つのモデルが異なること (線形と DAG) を達成できることがわかったら、私の質問は次のとおりです。DAG では不可能なことをリニアで実現できる実際のシナリオ (特に OSS よりも多くの企業) はどれですか?それだけの価値があるのでしょうか?

選択ルールの観点から「現実のシナリオ」に関して言えば、線形モデルでできることは次のとおりです。 いくつかの 選択ルール 同じファイルセットに対して.

この「構成仕様」を考えてみましょう(つまり、ClearCase を使用した選択ルールの「構成仕様」):

element /aPath/... aLabel3 -mkbranch myNewBranch
element /aPath/... aLabel2 -mkbranch myNewBranch

「」というラベルの付いたすべてのファイルが選択されます。aLabel2' (およびそこから分岐)、' とラベルが付いているものを除くaLabel3' - そしてそこから分岐します - (そのルールは ' について言及しているルールよりも前にあるため)aLabel2').

その価値はありますか?

いいえ。

実際、ClearCase の UCM フレーバー (「統合構成管理「ClearCase 製品に含まれており、ClearCase の基本的な使用法から推定されるすべての「ベスト プラクティス」を表す方法論)では、次の理由によりそれが許可されていません。 単純さ. 。ファイルのセットは「コンポーネント」と呼ばれ、特定のラベル (「ベースライン」と呼ばれる) に分岐したい場合、それは次の構成仕様のように変換されます。

element /aPath/... .../myNewBranch
element /aPath/... aLabel3 -mkbranch myNewBranch
element /aPath/... /main/0 -mkbranch myNewBranch

選ばなければなりません 1つ 開始点(ここでは「aLabel3') そしてそこから行きます。' のファイルも必要な場合は、aLabel2'、すべての ' からマージを行います。aLabel2' ファイルを 'myNewBranch' 内のファイルに追加します。

これは、DAG を使用する必要のない「単純化」です。グラフの各ノードは、関係するファイルのセットが何であれ、ブランチの一意に定義された「開始点」を表します。

マージとリベースは、特定の履歴を保持しながら、目的の「構成」を達成するために、その開始点を特定のファイル セットの他のバージョンと結合するのに十分です。 隔離中 支店で。

一般的な目標は、「」を推論することです。筋の通った に適用されるバージョン管理操作 筋の通った 成分"。「コヒーレントな」ファイルのセットとは、明確に定義されたコヒーレントな状態にあるファイルのセットです。

  • ラベルが付いている場合、 全て そのファイルにはラベルが付けられています
  • 分岐している場合、 全て そのファイルは、 同じユニークな 出発点

これは DAG システムで簡単に実行できます。線形システムでは (特に「構成仕様」が難しい「Base ClearCase」の場合) はさらに困難になる可能性がありますが、同じ線形ベースのツールの UCM 方法論で強制されます。

「プライベート選択ルールのトリック」 (ClearCase の一部の選択ルール順序) を通じてその「構成」を実現するのではなく、VCS 操作 (リベースまたはマージ) のみでそれを実現します。開発者にプライベートな構成仕様、またはすべての開発者ではなく一部の開発者の間で共有される構成仕様)。繰り返しますが、それは次のような感覚を強制します 一貫性, 「動的な柔軟性」とは対照的に、後で再現するのが難しい可能性があります。.

それによってあなたはその領域を離れることができます VCS (バージョン管理システム) そして、の領域に入ります SCM (ソフトウェア構成管理), 、主に「」に関するものです。再現性」。そして、それ (SCM 機能) は、線形ベースまたは DAG ベースの VCS で実現できます。

他のヒント

あなたが探しているものは次のようなものかもしれません git rebase. 。ブランチをリベースすると、概念的には、ブランチを元のブランチ ポイントから切り離し、別のポイントに再接続します。(実際には、リベースは、ブランチの各パッチを新しいブランチ ポイントに順番に適用し、新しいパッチのセットを作成することによって実装されます。) この例では、ブランチを上のブランチの現在の先端にリベースできます。基本的に、他のブランチに加えられたすべての変更を「継承」します。

私はあなたが何を求めているのか完全には明確ではありませんが、Gitの追跡セマンティクスがあなたが望むものであるように聞こえます。あなたがAm Originから分岐するとき、あなたは次のようなことをすることができます:

git -t -b my_branch 起点/マスター

そして、将来の「Git Pull」は、Origin/Masterを作業ブランチに自動マージします。その後、「Git Cherry -V Origin/Master」を使用して、違いが何であるかを確認できます。変更を公開して歴史をクリーンアップする前に「Git Rebase」を使用できますが、履歴が公開されたらRebaseを使用しないでください(つまり、他の人がそのブランチをフォローしています)。

accurev で使用される継承スキームについては、次のとおりです。GIT ユーザーは、これを見ればおそらくすべてを「理解」できるでしょう。 git-flow (以下も参照してください: http://github.com/nvie/gitflow そして http://jeffkreeftmeijer.com/2010/why-arent-you-using-git-flow/)

この GIT ブランチング モデルは、accurev がすぐに使用できる機能とほぼ同じことを (手動で / git-flow ツールの助けを借りて) 実行します。 素晴らしい GUIのサポート。

それで 現れる GIT では、accurev と同じことができます。私は実際に git/git-flow を日常的に使用したことがないので、それがどのように機能するかを実際に言うことはできませんが、期待できそうです。(ただし、適切な GUI サポートはありません :-)

あなたの質問に答えてみます。(ここで言っておきますが、私は読んだだけで GIT を使用したことがないので、以下で言及する内容が間違っている場合は、修正してください)

「この継承が必須となるシナリオを列挙できますか?」

手持ちのツールで問題を解決でき、環境にとっては有効な解決策になる可能性があるため、これが必須とは言いません。それはツール自体というよりもプロセスの問題だと思います。プロセスの一貫性を確保し、過去に戻って中間のステップ/状態を再現できるようにすることが目標です。さらに、このツールを使用すると、プロセスと SCMP を可能な限り苦痛なく実行できるようになります。

これがあると便利だとわかるシナリオが 1 つあります '継承' 一連の変更が必要な場合は、動作を変更し、構成仕様の力を使用します。孤立した" タスク (devtask、CR、SR、または変更セットの目的/範囲を定義するもの) にマップされます

この構成を使用すると、開発ブランチをクリーンにし、残りのコードの別の組み合わせ (構成を使用) を引き続き使用できます。 タスクに関連するもののみ 途中で支店内で孤立 全体 統合フェーズまでのタスクのライフサイクル。

「定義された開始点」を持つためだけにコミット/マージ/リベースを行う必要がある純粋主義者であるため、おそらくそれは「汚染する' あなたのブランチを選択すると、あなたの変更と他の変更がブランチ/変更セットに含まれることになります。

この分離はいつ、どこで役立ちますか?以下の点は、CMM および一部の ISO 認証を追求する企業のコンテキストでのみ意味をなす可能性があり、他の種類の企業や OSS には興味がないかもしれません。

  • 非常にこだわりが強いので、単一の開発者に対応する変更セットのコード行 (追加/変更/削除) を正確に数え、後でコードと作業量の見積もりの​​ 1 つの入力として使用することをお勧めします。

  • コードだけを 1 つのブランチに (他の変更と結合せずに) 置くと、さまざまな段階でコードをレビューするのが簡単になります。

複数のチームと 500 人以上の開発者が同じベース コードで同時にアクティブに作業している大規模なプロジェクト (グラフィカルな個々の要素のバージョン ツリーは、大口顧客ごとに 1 つ、またはテクノロジごとに 1 つずつ、複数のロードラインを持つ乱雑に絡み合った Web のように見えます)数度の深さの構成を使用した仕様により、これだけの人員がシームレスに作業して、同じ製品/システム (ベースコード) をさまざまな目的に適応させることができました。この構成仕様を使用すると、中間の統合ブランチを作成したり、すべてを常にマージしてリベースしたりする必要がなく、各チームまたはサブチームに、必要なものとどこからブランチする必要があるかについての異なるビュー (いくつかのケースでカスケード) が動的に提供されました。まずは始める必要がある部分。同じタスク/目的からのコードが異なるラベルの分岐でしたが、意味はありました。(ここでは、SCMの原則として「既知のベースライン」を議論することができますが、書かれたSCM計画で想定されている単純なラベルは作業を行いました)GITでこれを解決することは可能です(私は非動的な方法で推測します)が、私は見つけることができますこの「継承」の動作なしで想像するのは本当に難しいです。VonC が述べた「分岐した場合、すべてのファイルは同じ一意の開始点から分岐する」という点はここで壊れていたと思いますが、SCMP に十分に文書化されていることに加えて、そのようにするのには強力なビジネス上の理由があったことを覚えています。

はい、上で述べたこれらの構成仕様の構築は無料ではありませんでした。当初は SCM の背後に 4 ~ 5 人の高給取りの人員がいたのですが、ラベル/ブランチ/機能と意志に関して何を望むかを尋ねる自動化されたスクリプトによって、後に削減されました。 CS を書きます。

ここでの再現性は、構成仕様をタスクとともに devTask システムに保存するだけで実現されているため、各タスクの上流では要件にマップされ、下流では構成仕様、つまり一連の変更 (コード ファイル、設計ドキュメント、テスト ドキュメント) にマップされます。等)

ここで、プロジェクトが十分に大きく/複雑である場合にのみ、ここで1つの結論があるかもしれません(そして、プロジェクトの生活に沿ってSCマネージャーを買う余裕があります:))。本当に汎用性の高いツールです。そうでなければ、無料のAAツールに直接移動します。しかし、SCM ツールには他の要因があり、どちらかのツールに固執する可能性があります...続きを読む..

余談ですが、それは主題から外れているかもしれませんが、私のようなケースでは考慮する必要があると思います。

ここで、UCM ではなく「古き良き CC」を使用していることを付け加えなければなりません。については VonC に完全に同意します。 優れた方法論により、柔軟性をより一貫性のある構成に「導く」ことができます。. 。良い点は、CC は非常に柔軟であり、他の SCM では無料で利用できるものの、一貫性を持たせるための良い方法を (多少の努力なしではなく) 見つけることができることです。しかし、たとえばここ (および私が CC と協力した他の場所) では、C/C++ プロジェクトの場合、 ウィンキン この機能 (Derive オブジェクトの再利用) により、コンパイル時間が数倍短縮されます。より良い設計、より分離されたコード、および Makefile の最適化により、全体をコンパイルする必要性を減らすことができると主張することもできますが、場合によっては、獣全体を 1 日に何度もコンパイルする必要があり、DO 保存を共有する必要があります。膨大な時間/お金。私が今いるところでは、できる限り無料のツールを使用するようにしています。もし、 ウィンキン 特徴。

最後にポールが言及したことで終わりますが、 目的ごとに異なるツールが他のツールよりも優れている しかし、私はあなたが一貫したプロセスを持ち、再現性を怖がらせることなく、ツールの何らかの制限から逃れることができると付け加えます。 それは価値がある? は、「問題」、実行している SDLC、SCM プロセス、および環境で役立つ追加機能 (ウィンキンなど) があるかどうかによって異なります。

私の2セント

理論はさておき、商業生産環境で長年にわたって AccuRev を使用してきた私の観点から、これについての明白な実際的な見解を以下に示します。継承モデルは、子ストリームが開発中の祖先から大きく分岐していない限り、非常にうまく機能します。継承するストリームが違いすぎると失敗します。

継承 (後のバージョンが以前のバージョンの子として) により、誰も何もしなくても、祖先ストリームの変更を子ストリームでアクティブにすることができます (マージが必要な場合を除き、その場合は深い重複として表示されます。これを確認できるのは良いことです) )。

関係するすべてのストリームが比較的類似している場合、これは素晴らしいことのように聞こえますが、実際にもそのとおりです。このモデルは、特定の製品リリース以下のホットフィックスおよびサービス パック レベルのストリームに使用されます。(実際には私たちにとってはもう少し複雑ですが、それが一般的な考え方です。)

製品リリースは並行して行われ、継承はなく、それぞれの下にホットフィックスとサービス パックの子が含まれます。新しいリリースを開始するということは、新しいリリース レベルのストリームを作成し、前のリリースの最新のメンテナンス ストリームからすべてを手動でプッシュすることを意味します。その後、以前のリリースへの変更を後のリリースに適用するには、それぞれのリリースに手動でプッシュする必要があり、より多くの作業が必要になりますが、より高度な制御が可能になります。

私たちは当初、すべてのリリースにわたって継承モデルを使用しており、後のリリースは以前のリリースの子でした​​。しばらくはうまくいきましたが、時間が経つにつれて管理できなくなりました。リリース間でアーキテクチャに大きな違いがあるため、変更を継承することは避けられず、悪い考えになりました。はい、間にスナップショットを入れて継承をブロックすることはできますが、その場合はすべての変更を手動でプッシュする必要があります。また、親、スナップショット、子ストリームと並列非継承ストリームの唯一の本当の違いは、グラフィカル ストリーム ビュー全体が継続的にプッシュダウンされることです。そして右側はPITAです。

AccuRev の本当に優れた点の 1 つは、いつでもこの選択ができることです。これは、SCM プログラムのアーキテクチャに固有の制約ではありません。

GIT を使用して特定のファイル バージョンをチェックアウトできることに気づきましたか?

これを使ってください:

git checkout [< tree-ish >] [--] < paths >

構成仕様ごとに、ファイルの既存のバージョン (パス) をワークツリーにロードできます。git-checkout ドキュメントからの引用:

次のシーケンスでは、master ブランチをチェックアウトし、Makefile を 2 つ前のリビジョンに戻し、削除します。 hello.c 誤ってインデックスからそれを返します。

$ git checkout master             
$ git checkout master~2 Makefile             
$ rm -f hello.c            
$ git checkout hello.c            

MultiSite を持たない ClearCase は単一のリポジトリですが、Git は分散されています。ClearCase はファイル レベルでコミットしますが、Git はリポジトリ レベルでコミットします。(この最後の違いは、ここの他の投稿で指摘されているように、元の質問が誤解に基づいていることを意味します。)

これらが私たちが話している違いである場合、「リニア」と「DAG」はこれらの SCM システムを区別するための混乱を招く方法だと思います。ClearCase では、ファイルのすべてのバージョンはファイルのバージョン「ツリー」と呼ばれますが、実際には有向非巡回グラフです。Git との本当の違いは、ClearCase の DAG がファイルごとに存在することです。したがって、ClearCase を非 DAG と呼び、Git を DAG と呼ぶのは誤解を招くと思います。

(ところで、ClearCase はファイルと同様の方法でディレクトリをバージョン化しますが、それはまた別の話です。)

何か質問しているかどうかはわかりませんが、Accurev ストリームが Git (または SVN) ブランチとは異なるツールであることを示しています。(クリアケースは知りません。)

たとえば、Accurev を使用すると、 強制的, おっしゃるとおり、特定のワークフローを使用すると、Git でサポートされていない変更の監査可能な履歴が得られます。Accurev の継承により、特定のワークフローがより効率的になり、他のワークフローは不可能になります。

Git を使用すると、探索的なコーディングをローカル リポジトリまたは機能ブランチに分離できますが、Accurev ではこれを十分にサポートできません。

異なるツールは異なる目的に適しています。それぞれの良い点を尋ねることは有益です のために.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top