その理由は、git merge
デフォルトで「再帰的」マージと呼ばれる戦略を使用するためです。3 方向のマージを実行できます。一方の側からパッチを取得し、そのパッチをもう一方の側に適用して、新しいファイルを生成します。また、多くの分岐とマージが発生し、マージされる 2 つのコミットのマージ ベースが複数ある、より複雑な状況では、これを再帰的に行います。
私は最近、この同じ状況に遭遇しました:
$ git merge-base --all 90d64557 05b3dd8f
711d1ad9772e42d64e5ecd592bee95fd63590b86
f303c59666877696feef62844cfbb7960d464fc1
$
マージベースが2つあるため、3方向のマージはできません。したがって、「再帰」戦略は、最初にこれら 2 つのコミットのマージに再帰することでこれを解決しました。
$ git merge-base 711d1ad9 f303c596
3f5db59435ffa4a453e5e82348f478547440e7eb
$
OK、マージ ベースは 1 つだけなので、3 方向のマージを開始できます。両サイドの変化は?
$ git diff --stat 3f5db594 711d1ad9
normalize/coll.py | 116 ++++++++++++++++++++++++++++++++++++++-----------
normalize/visitor.py | 49 ++++++++++-----------
tests/test_property.py | 10 +++--
3 files changed, 120 insertions(+), 55 deletions(-)
$ git diff --stat 3f5db594 f303c596
normalize/identity.py | 38 +++++++++++++++++++++++++++++++-------
tests/test_property.py | 2 ++
2 files changed, 33 insertions(+), 7 deletions(-)
$
これら 2 つの diff はどちらも同じファイルに変更を加えているため、各ファイルの新しいバージョンをそれぞれの側から取得する (インデックス マージ)という単純な方法を使用して解決することはできません。代わりに、git は一方から新しいファイルを取得し、他方からパッチを適用しようとします。結果は結合されたコミットであり、次のようにシミュレートできます。
$ git checkout -b tmp
Switched to a new branch 'tmp'
$ git reset --hard f303c59666877696feef62844cfbb7960d464fc1
HEAD is now at f303c59 record_id: throw a more helpful error if record identity is not hashable
$ git merge 711d1ad9772e42d64e5ecd592bee95fd63590b86
Auto-merging tests/test_property.py
Merge made by the 'recursive' strategy.
normalize/coll.py | 116 ++++++++++++++++++++++++++++++++++++++-----------
normalize/visitor.py | 49 ++++++++++-----------
tests/test_property.py | 10 +++--
3 files changed, 120 insertions(+), 55 deletions(-)
$ git diff --stat 3f5db594 HEAD tests/test_property.py
tests/test_property.py | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
$
次に、このマージ結果を開始点として使用して、元の 3 方向マージに戻ります。これには、同じファイルへの変更も含まれます。
$ git diff --stat HEAD 90d64557| grep selector
normalize/selector.py | 17 +--
tests/test_selector.py | 19 ++--
$ git diff --stat HEAD 05b3dd8f| grep selector
normalize/selector.py | 29 +++++++++++++++++------------
tests/test_selector.py | 9 +++++++++
$
ただし、ここでも変更はファイルの異なるセクションに対するものであるため、差分を取得して反対側に適用することは成功しています。
したがって、C git は、最初に 2 つの開始点の 2 つのマージ ベースで 3 方向マージを実行し、次にマージされる 2 つの元のコミットとその中間結果で別の 3 方向マージを実行することにより、このマージを解決できました。初合流。
Github の自動解決ではこれが行われません。必ずしも不可能というわけではなく、再帰的な戦略がどれだけ実装されているかはわかりませんが、注意を怠っています。これはまさに、そのような大きな緑色のボタンに期待されることです:-)。