31

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

しかし、Clearcase や Accurev などの他のシステムでは、ブランチが何らかの継承メカニズムで満たされる方法を指定できます。つまり、Clearcase では config_spec を使用して、「ブランチ /main/issue001 で変更されたすべてのファイルを取得し、次に、/main またはこの特定のベースラインにあるものに進みます。」

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

Git を使用していて、これを見逃していませんか? この継承が必須であるシナリオを列挙できますか?

ありがとう

更新実際に私の質問に焦点を当てるには、以下のVonCの回答をお読みください。「線形ストレージ」と DAG ベースの SCM にはさまざまな機能があることに同意したら、私の質問は次のとおりです。 (特に OSS よりも多くの企業にとって) 線形が DAG では不可能なことを実行できる実際のシナリオはどれですか? 彼らは価値がありますか?

4

9 に答える 9

30

Git が「継承メカニズム」(コミットを含まない) と呼ばれるものを提供しない理由を理解するには、まず、これらの SCM のコア概念の 1 つを理解する必要があります (Git と ClearCase など)。

  • ClearCase は線形バージョン ストレージを使用します。要素 (ファイルまたはディレクトリ) の各バージョンは、同じ要素の前のバージョンと直接線形関係でリンクされます。

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

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

ブランチは、特定の選択規則の特定のバージョンの線形履歴のフォークです (その選択規則より前の他のすべての選択規則は引き続き適用されるため、「継承」効果が発生します)。

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

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

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

Gitで「失っている」のは、ある種の「構成」です(連続する異なる選択ルールで異なるバージョンを選択している場合)が、D VCS(「分散」の場合のように)では実用的ではありません。 Git でブランチを作成するには、開始点とコンテンツを明確に定義し、他のリポジトリに簡単に複製する必要があります。

純粋に中央の VCS では、必要なルールを使用してワークスペース (ClearCase では、スナップショットまたは動的のいずれかの「ビュー」) を定義できます。


unknown-googleはコメント (および上記の彼の質問) に次のように追加します。

したがって、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 システムで簡単に実行できます。線形システムではより困難になる可能性があります (特に、「構成仕様」が扱いにくい「ベース ClearCase」の場合) が、同じ線形ベースのツールの UCM 方法論で実施されます。

「プライベート選択ルールのトリック」(ClearCase、いくつかの選択ルールの順序)を介してその「構成」を達成する代わりに、VCS操作(リベースまたはマージ)のみでそれを達成し、全員が従うべき明確な痕跡を残します(反対に開発者専用の構成仕様、またはすべてではなく一部の開発者間で共有される構成仕様)。繰り返しになりますが、後で再現するのに苦労する可能性がある「動的な柔軟性」とは対照的に、一貫の感覚を強制します。

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

于 2009-04-18T21:11:13.487 に答える
3

あなたが何を求めているのか完全にはわかりませんが、gitの追跡セマンティクスがあなたが望んでいるようです。am origin から分岐すると、次のようなことができます。

git -t -b my_branch オリジン/マスター

そして、将来の「git pull」は、オリジン/マスターを作業ブランチに自動的にマージします。次に、「git cherry -v origin/master」を使用して違いを確認できます。変更を公開する前に「git rebase」を使用して履歴をクリーンアップできますが、履歴が公開されたら (つまり、他の人がそのブランチをフォローしている場合)、rebase を使用しないでください。

于 2009-04-18T10:31:49.093 に答える
3

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

于 2009-04-18T08:06:42.530 に答える
2

accurev で使用される継承スキームについて: GIT ユーザーは、git-flowを見るとおそらくすべてを「取得」するでしょう(参照: http://github.com/nvie/gitflowおよびhttp://jeffkreeftmeijer.com/ 2010/why-arent-you-using-git-flow/ )

この GIT 分岐モデルは多かれ少なかれ (手動で、または git-flow ツールの助けを借りて) accurev が自動的に、優れた GUI サポートを使用して行うことを行います。

したがって GIT は accurev が行うことを実行できるようです。私は実際に git/git-flow を日常的に使用したことがないので、実際にどのように機能するかは言えませんが、有望に見えます。(マイナスの適切な GUI サポート :-)

于 2010-09-10T13:58:42.157 に答える
2

私はあなたの質問に答えようとします。(ここで、GIT を使用したことはなく、それについて読んだだけであると言わなければなりません。そのため、以下で言及する何かが間違っている場合は、私を修正してください)

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

あなたが持っているツールで問題を解決することができ、あなたの環境にとって有効な解決策になるかもしれないので、それが必須であるとは言いません。ツール自体よりもプロセスの問題だと思います。プロセスが一貫していることを確認し、時間をさかのぼって中間のステップ/状態を再現できるようにすることが目標です。さらに、このツールを使用すると、プロセスと SCMP をできるだけ簡単に実行できます。

この「継承」動作を持ち、構成仕様の力を使用すると便利なシナリオの 1 つは、一連の変更を「分離」してタスク (devtask、CR、SR、または定義するもの) にマップする場合です。変更セットの目的/範囲)

このコンポジションを使用すると、開発ブランチをクリーンにし、残りのコードの異なる組み合わせ (コンポジションを使用) を引き続き使用でき、タスクのライフサイクル全体でブランチに分離されたタスクに関連するもののみを保持できます。統合フェーズまで。

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

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

  • 非常にうるさいので、1 人の開発者に対応する変更セットのコード行 (追加/変更/削除) を正確にカウントし、後でコードと労力の見積もりの​​ 1 つの入力として使用したい場合があります。

  • コードだけを 1 つのブランチにまとめておくと (他の変更にくっつかない)、さまざまな段階でコードを確認しやすくなります。

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

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

ここでの再現性は、構成仕様をタスクとともに devTask システムに保存するだけで達成されたので、各タスクはアップストリームで要件にマッピングされ、ダウンストリームで構成仕様にマッピングされ、一連の変更 (コード ファイル、設計ドキュメント、テスト ドキュメント)等)

したがって、ここまでの結論は、プロジェクトが十分に大きく/複雑である場合 (そして、プロジェクトの存続期間中に SC マネージャーを雇う余裕がある場合のみ:))、「継承」動作が必要かどうかだけを考え始めることになります。それ以外の場合は、無料のツールに直接移動し、SCM の一貫性を既に処理しています... しかし、SCM ツールには、1 つまたは別のツールに固執する可能性のある他の要因がある可能性があります.. 。読む..

いくつかの補足事項、それは話題から外れているかもしれませんが、私のようないくつかのケースでは考慮する必要があると思います.

ここで、UCM ではなく「古き良き CC」を使用していることを付け加える必要があります。より一貫性のある構成に向けて柔軟性を「導く」ことができる優れた方法論について、VonC に完全に同意します。良い点は、CC は非常に柔軟であり、他の SCM では無料で利用できるかもしれないが、一貫性を持たせるための良い方法を (ある程度の努力なしではなく) 見つけることができるということです。しかし、たとえばここ (および私が CC で作業した他の場所) では、C/C++ プロジェクトの場合、winkinを持たないという代償を支払う余裕はありません。機能 (派生オブジェクトを再利用) を使用すると、コンパイル時間が X 倍短縮されます。設計を改善し、コードを分離し、Makefile を最適化することで、全体をコンパイルする必要性を減らすことができると主張できますが、1 日に何度も獣全体をコンパイルする必要があり、DO を共有することで節約できる場合があります。時間/お金の山。私は現在、できるだけ多くの無料ツールを使用しようとしています。winkin機能を実装する安価なツールまたは無料ツールを見つけることができれば、CC をなくすことができると思います。

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

私の2セント

于 2010-10-18T23:18:52.370 に答える
2

理論はさておき、ここで、AccuRev を商用生産環境で何年も使用してきた私の観点から、これに関するある種の明白な実用的な見方を示します。まだ開発中です。継承するストリームがあまりにも異なる場合、それは失敗します。

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

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

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

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

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

于 2012-09-08T13:35:30.330 に答える
2

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

これを使用するだけです:

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

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

次の手順では、マスター ブランチをチェックアウトし、Makefile を 2 つ前のリビジョンに戻し、hello.c誤って削除して、インデックスから取得します。

$ git checkout master             
$ git checkout master~2 Makefile             
$ rm -f hello.c            
$ git checkout hello.c            
于 2010-11-11T08:29:09.993 に答える
1

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

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

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

于 2009-11-30T14:26:44.160 に答える
0

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

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

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

さまざまなツールがさまざまな目的に適しています。それぞれが何に適しているかを尋ねると便利です

于 2009-04-18T14:33:12.443 に答える