Git章鱼合并多个分支的顺序 [英] Git octopus merge order of multiple branches

查看:1284
本文介绍了Git章鱼合并多个分支的顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用git发生了一件有趣的事情,想知道是否有人可以向我解释,这样我可以更好地理解。



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

  git merge AB 

失败为非快进,而

  git merge BA 

好。为什么会这样?

解决方案

假设A是严格的, direct child 。然后假设B是一个严格的直接子 A



章鱼合并,处理由左至右的参数,如果它试图应用B然后A,但是如果它进行了转换,则会遇到冲突,但是如果它试图应用B然后A,那么对于索引独立于索引成功地不会发生冲突。


$ b

根据 git-merge 手册, MERGE STRATEGIES部分

  octopus 
这样可以解决两个以上头的情况,但拒绝执行需要手动解析的
复杂合并。

例如:

 〜$ git init testdir&& cd testdir&&回声这是C> myfile 
/home/huitseeker/testdir/.git/
$ b〜/ testdir $ git add myfile&&&& git commit -mC
[master(root-commit)f0c8c82] C
1个文件已更改,1个插入(+),0个删除( - )
创建模式100644 myfile

〜/ testdir(master)$ git checkout -bA&&回声这是A1> myfile
切换到新分支'A'
〜/ testdir(A)$ git commit -mA1myfile
[A ac5b51c] A1
1个文件已更改,1插入(+),删除1个( - )

〜/ testdir(A)$ git checkout -bB&&回声这是B1>> myfile
切换到新分支'B'
〜/ testdir(B)$ git commit -mB1myfile
[B 5bc838c] B1
1个文件已更改,1插入(+),0删除( - )

〜/ testdir(B)$ git checkout master
转换到分支'master'
〜/ testdir(master)$ git合并BA
快速转发到:B
已经与A
合并,章鱼合并。
myfile | 3 ++ -
1个文件已更改,2个插入(+),1个删除( - )

〜/ testdir(主)$ git reset --hard HEAD ^^^
HEAD现在位于f0c8c82 C
〜/ testdir(master)$ git合并AB
快速转发到:A
快速转发到:B
错误:条目'myfile '会被合并覆盖。无法合并。
与策略章鱼合并失败。

〜/ testdir(master)$ cat myfile
这是A1



实际上,当快速转发到A时,虽然树已经有了,但是master的标签还没有被推送。


 〜/ testdir(master)$ git status 
#在分支主机上
#要提交的更改:
#(使用git reset HEAD< file> ...

#modified:myfile

在章鱼合并的代码中,我手动执行这个操作(看上面的哈希):

 〜/ testdir(master )$ git reset --hard f0c8c82 
HEAD现在在f0c8c82 C
〜/ testdir(master)$ git read-tree -u -m f0c8c82 ac5b51c
〜/ testdir(master)$ git read-tree -u -m f0c8c82 5bc838c
错误:条目'myfile'将被合并覆盖。无法合并。

在另一个方向( merge BA )现在,如果再看一下merge-octopus的代码,它会尝试检测我们要添加的分支是否已经在树中(第二个 case > for loop)。的确,在A合并时,它看到ac5b51c(又名A的头)是A和B的共同祖先,并且在没有执行第二个读取树的情况下放弃。 p>

这种行为与新版本的git一致:虽然我已经指出v.1.3.1,但这仍然在我的版本中发生。

 〜/ testdir(master)$ git --version 
git版本1.7.5.4

tl; dr:您希望章鱼合并分支触及不同文件

I had an interesting thing happen using git, wondering if anyone could explain it to me so I can understand better.

When doing a merge of multiple branches (A,B),

git merge A B

fails as non-fast-forward, while

git merge B A

worked well. Why would that be?

解决方案

Let's assume that A is a strict, direct child of the current branch. Then assume that B is a strict, direct child of A.

The octopus merge, which processes heads given as arguments from left to right, incrementally with respect to the tree, but independently with respect to the index succeeds without conflict if it tries to apply B and then A, but encounters a conflict if it does the convert.

As per the git-merge manual, section MERGE STRATEGIES:

octopus
   This resolves cases with more than two heads, but refuses to do a
   complex merge that needs manual resolution.

For instance:

 ~                 $ 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

Indeed, when fast-forwarding to A, the label of master has not been pushed forward, though the tree has.

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

If, looking at the code of what the octopus merge does, I perform this manually (look above for hashes):

 ~/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.

In the other direction (merge B A), now, if you look again at the code of merge-octopus, it tries to detect the branch we are trying to add is already in the tree (second case of the for loop). Indeed, at the merge of A, it sees ac5b51c (a.k.a. A's head) is the common ancestor of A and B, and aborts without doing the second read-tree.

This behavior is consistent with the fresh version of git : though I've pointed to v.1.3.1, this is still happening with my version.

 ~/testdir(master) $ git --version
 git version 1.7.5.4

tl;dr : you want your octopus merge branches to touch distinct files

这篇关于Git章鱼合并多个分支的顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆