1. ホーム
  2. git

[解決済み] gitのマージ戦略を使い分けるとしたら、どんなとき?

2022-03-21 10:21:05

質問

git-mergeのmanページには、使用可能なマージ戦略がいくつか紹介されています。

  • 解決する - これは、3 者間マージアルゴリズムを使って 2 つのヘッド (つまり、現在のブランチとプルした別のブランチ) のみを解決することができます。これは、交差するマージのあいまいさを慎重に検出しようとするもので、一般に安全で高速だと考えられています。

  • 再帰的 - これは、3-way merge アルゴリズムを使用して、2つの頭しか解決できません。3 者間マージに使用できる共通の先祖が複数ある場合、共通の先祖をマージしたツリーを作成し、それを 3 者間マージの参照ツリーとして使用します。これは、Linux 2.6 カーネルの開発履歴から採取した実際のマージコミットに対して行ったテストにより、誤マージを発生させずにマージ衝突を少なくすることが報告されています。さらに、これは名前の変更を含むマージを検出して処理することができます。これは、1つのブランチをプルまたはマージするときのデフォルトのマージ戦略です。

  • オクトパス - これは2つのヘッド以上のケースを解決しますが、手動での解決が必要な複雑なマージは拒否されます。主にトピックブランチのヘッドを束ねるために使用されることを想定しています。これは、複数のブランチをプルしたりマージしたりする際のデフォルトのマージ方法です。

  • 当社 - これは任意の数のヘッドを解決しますが、マージの結果は常に現在のブランチのヘッドとなります。サイドブランチの古い開発履歴を上書きするために使用することを意図しています。

  • サブツリー - これは、修正された再帰的戦略である。木AとBをマージするとき、BがAの部分木に対応する場合、同じレベルの木を読むのではなく、まずBがAの木構造に合うように調整される。この調整は、共通の祖先木に対しても行われる。

どのような場合にデフォルトと異なる指定をすればよいのでしょうか? また、それぞれどのようなシナリオに最適なのでしょうか?

どのように解決するのですか?

resolveはよく知らないのですが、他は使ったことがあります。

再帰的

Recursive は、fast-forward でないマージのデフォルトです。私たちは皆、これに慣れ親しんでいます。

オクトパス

私は、複数のツリーをマージする必要があるときに、オクトパスを使用したことがあります。 これは大きなプロジェクトで、多くのブランチが独立して開発され、それが一つの頭脳にまとまる準備が整ったときに見られます。

octopusブランチは、きれいにできる限り、1回のコミットで複数のヘッドをマージします。

たとえば、あるプロジェクトにマスターがあり、マージするブランチが3つあるとします (a、b、c と呼びます)。

一連の再帰的なマージは次のようになります(再帰を強制していないので、最初のマージは早送りであることに注意してください)。

しかし、1つの蛸壺のマージは次のようになります。

commit ae632e99ba0ccd0e9e06d09e8647659220d043b9
Merge: f51262e... c9ce629... aa0f25d...

私たち

Ours == 別のheadを引き込みたいが、そのheadが導入するすべての変更を捨てたい。

これは、ブランチの影響を一切受けずに、ブランチの履歴を保持するものです。

(読み方:そのブランチ間の変更も見ていない。ブランチはマージされるだけで、ファイルには何もされません。もし、他のブランチにマージしたいのに、毎回 "私たちのファイルのバージョンか彼らのバージョンか" という質問がある場合、次のように使うことができます。 git merge -X ours )

サブツリー

サブツリーは、他のプロジェクトを現在のプロジェクトのサブディレクトリにマージしたい場合に便利です。サブモジュールとして含めたくないライブラリがある場合に便利です。