Git章鱼合并多个分支的顺序

Jam*_*ney 37 git branching-and-merging

我有一个有趣的事情发生在使用git,想知道是否有人可以解释给我,所以我可以更好地理解.

在进行多个分支(A,B)的合并时,

git merge A B
Run Code Online (Sandbox Code Playgroud)

失败,因为非快进,而

git merge B A
Run Code Online (Sandbox Code Playgroud)

运作良好.那为什么会这样?

hui*_*ker 48

让我们假设A是当前分支的严格直接子代.再假设B是严格的,直接子A的.

章鱼合并,这从左至右处理作为参数头,增量相对于树,但独立相对于该指数成功,没有冲突,如果它试图申请B,然后A,但如果它确实遇到冲突兑换.

根据git-merge手册,MERGE战略部分:

octopus
   This resolves cases with more than two heads, but refuses to do a
   complex merge that needs manual resolution.
Run Code Online (Sandbox Code Playgroud)

例如:

 ~                 $ git init testdir && cd testdir && echo "This is C" > myfile
 Initialized empty Git repository in /home/huitseeker/testdir/.git/

 ~/testdir         $ git add myfile && git commit -m "C" 
 [master (root-commit) f0c8c82] C
  1 files changed, 1 insertions(+), 0 deletions(-)
  create mode 100644 myfile

 ~/testdir(master) $ git checkout -b "A" && echo "This is A1" > myfile
 Switched to a new branch 'A'
 ~/testdir(A)      $ git commit -m "A1" myfile
 [A ac5b51c] A1
  1 files changed, 1 insertions(+), 1 deletions(-)

 ~/testdir(A)      $ git checkout -b "B" && echo "This is B1" >> myfile
 Switched to a new branch 'B'
 ~/testdir(B)      $ git commit -m "B1" myfile
 [B 5bc838c] B1
  1 files changed, 1 insertions(+), 0 deletions(-)

 ~/testdir(B)      $ git checkout master
 Switched to branch 'master'
 ~/testdir(master) $ git merge B A
 Fast-forwarding to: B
 Already up-to-date with A
 Merge made by octopus.
  myfile |    3 ++-
  1 files changed, 2 insertions(+), 1 deletions(-)

 ~/testdir(master) $ git reset --hard HEAD^^^
 HEAD is now at f0c8c82 C
 ~/testdir(master) $ git merge A B
 Fast-forwarding to: A
 Fast-forwarding to: B
 error: Entry 'myfile' would be overwritten by merge. Cannot merge.
 Merge with strategy octopus failed.

 ~/testdir(master) $ cat myfile
 This is A1
Run Code Online (Sandbox Code Playgroud)

实际上,当快速转发到A时,虽然树有,但是master的标签还没有被推进.

 ~/testdir(master) $ git status
 # On branch master
 # Changes to be committed:
 #   (use "git reset HEAD <file>..." to unstage)
 #
 #  modified:   myfile
 #
Run Code Online (Sandbox Code Playgroud)

如果,查看章鱼合并的代码,我手动执行此操作(请查看上面的哈希):

 ~/testdir(master) $ git reset --hard f0c8c82
 HEAD is now at f0c8c82 C     
 ~/testdir(master) $ git read-tree -u -m f0c8c82 ac5b51c
 ~/testdir(master) $ git read-tree -u -m f0c8c82 5bc838c
 error: Entry 'myfile' would be overwritten by merge. Cannot merge.
Run Code Online (Sandbox Code Playgroud)

在另一个方向上(merge B A),现在,如果你在合并,章鱼的代码再看看,它会尝试检测,我们正在尝试添加已经在树(第二分支case中的for循环).实际上,在A的合并中,它看到ac5b51c(又名A的头部)是A和B的共同祖先,并且在没有做第二个的情况下中止read-tree.

这个行为与git的新版本一致:虽然我已经指向v.1.3.1,但我的版本仍然会发生这种情况.

 ~/testdir(master) $ git --version
 git version 1.7.5.4
Run Code Online (Sandbox Code Playgroud)

tl; dr:你想要你的章鱼合并分支来触摸不同的文件

  • 你是对的,我非常不精确.我编辑了我的答案以反映您的评论,添加了章鱼不会更新合并应用程序之间的头索引的关键指示,并包含一个最小的示例. (5认同)