原因是git merge
默认情况下使用了一种名为“递归”合并的策略。它能够执行三向合并:从一侧取得补丁,并将补丁应用到另一侧,以产生新文件。它也以递归方式执行此操作,在更复杂的情况下发生了很多分支和合并,并且有两个合并基础。
我最近遇到这个同样的情况:
$ git merge-base --all 90d64557 05b3dd8f
711d1ad9772e42d64e5ecd592bee95fd63590b86
f303c59666877696feef62844cfbb7960d464fc1
$
随着2个合并基地,一个3路合并是不可能的。因此,“递归”的策略解决了这个由第一递归到这两个提交的合并:
$ git merge-base 711d1ad9 f303c596
3f5db59435ffa4a453e5e82348f478547440e7eb
$
OK,只有一个合并的基础,因此,合并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(-)
$
这两个差异列表都修改了同一个文件,所以他们不能使用的只是把每个文件的较新版本从各侧(指数合并)一个简单的策略来解决。相反,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 +++++++++
$
但是再次更改了文件的不同部分,并因此服用DIFF并将其应用到另一边是成功的。
因此,C git能够通过首先在两个起点的两个合并基础上进行3路合并,然后对两个原始提交进行另一个3路合并进行合并,第一次合并的中间结果。
Github的自动分辨率不会这样做。它并不一定是无能为力的,我不确定它实现了多少递归策略,但它在谨慎的方面却犯了错误,这正是你所期望的那样的一个大绿色按钮:-)。
递归合并策略的好处。 +1对我自己的答案有很好的补充。 – VonC