Git中的合并是否对称?

时间:2012-08-30 08:08:13

标签: git merge branching-and-merging git-merge symmetry

假设我们有两个分支( B C ),它们与共同的祖先 A 不同。将 B 合并到 C 会产生与从 C 合并到 B 相同的结果吗?

  A
  |
 / \
B   C

澄清 - 我假设任何手动合并冲突解决方案都会在两个方向上发生。但是,任何自动合并都会导致选择相同的代码吗?这就是我所假设的,因为提交日期在两个方向都是相同的。

为了进一步澄清 - 我知道实际的合并会导致基于方向的“镜像”相互影响。我只是询问自动解决的冲突。

4 个答案:

答案 0 :(得分:21)

默认合并的答案是肯定的。三向合并找到一个共同的祖先,然后应用两边的差异,这是一个不依赖于顺序的操作。合并排序和交换的主题引发了对git list的迷人讨论(如果你是这样的话,那就是)。注意B into CC into B应该是对称的,但(B into C) into AB into (C into A)不一定相同。


再详细说明一下,根据Vince的评论和seh对该问题的评论,B into CC into B之间会有两个明显的差异,这会影响问题中引用的自动合并解决方案。

首先,历史会有所不同。合并提交的父母将根据合并顺序进行更改。对于这些例子,我将使用" first_branch"和" second_branch",所以我可以保留字母来表示提交。

git checkout first_branch && git merge second_branch

E <- merge commit
|\
| D <- second_branch's tip
| |
| C <- another commit on second_branch 
| |
| B <- and another
|/
A <- first_branch's tip before the merge

在这种情况下,&#34;第一个父母&#34; E,E^1,是合并前的第一个分支。 second_branch是&#34;第二个父母&#34;合并提交,即E^2。现在考虑相反的情况:

git checkout second_branch && git merge first_branch

E <- merge commit
|\
| D <- first_branch's tip
| |
| C <- another commit on first_branch 
| |
| B <- and another
|/
A <- second_branch's tip before the merge

父母被逆转了。 E^1是合并前second_branch的提示。 E^2是first_branch的提示。

其次,冲突的显示顺序将反转。在第一种情况下,冲突可能如下所示:

<<<<<<< HEAD
This line was added from the first_branch branch.
=======
This line was added from the second_branch branch.
>>>>>>> second_branch

在第二种情况下,同样的冲突看起来像这样:

<<<<<<< HEAD
This line was added from the second_branch branch.
=======
This line was added from the first_branch branch.
>>>>>>> first_branch

这些差异都不会影响自动合并分辨率,但是当您撤消三向合并顺序时,它们会出现。

答案 1 :(得分:2)

这取决于“相同结果”的含义。从内容的角度来看,假设没有冲突,或者以完全相同的方式精确地解决所有现有冲突,生成的新合并提交的内容应该是相同的。

然而,从历史拓扑的角度来看,两者是截然不同的。如果您在分支B上并在C中合并,则B的HEAD将指向合并提交,但C保持在原来的位置。相反,如果你在C上并且在B中合并,则C的HEAD会移动,而B会保持原样。因此,最终的拓扑结构非常不同,这对任何一个分支的未来开发都有影响,即使新提交的内容在任何一种情况下都是相同的。

答案 2 :(得分:0)

不,我认为它不会是对称的。首先,您可以设置合并策略选项,尤其是在您确定是选择B还是C的theirsours的情况下。

在自动合并中,我认为例如远程分支优先于您的更改,如果您要合并到您的更改中,这意味着从B调用git merge C将导致选择C更改。我不是百分百肯定的,所以你可以尝试自己,让我们知道。

答案 3 :(得分:0)

内容是对称的,但是如果您使用GitHub或Bitbucket或您喜欢的本地Git查看器来查看合并时所做的更改,您将看到合并提交中列出的文件更改是不同的。 (以及上述其他内容。)

git checkout b
git merge c

由于cb分开,因此合并中显示的文件更改将是在c上所做的更改。

git checkout c
git merge b

由于bb分开,因此合并中显示的文件更改将是在c上所做的更改。