假设我们有两个分支(B和C)从一个共同的祖先A分歧。从B合并到C会产生与从C合并到B相同的结果吗?
A
|
/ \
B C
澄清一下-我假设任何手动合并冲突解决方案都将在两个方向上发生。但是发生的任何自动合并会导致选择相同的代码吗?这就是我的假设,因为两个方向的提交日期都是相同的。
进一步澄清 - 我知道实际的合并会根据方向产生彼此的“镜像”。我只是在询问自动解决的冲突。
假设我们有两个分支(B和C)从一个共同的祖先A分歧。从B合并到C会产生与从C合并到B相同的结果吗?
A
|
/ \
B C
澄清一下-我假设任何手动合并冲突解决方案都将在两个方向上发生。但是发生的任何自动合并会导致选择相同的代码吗?这就是我的假设,因为两个方向的提交日期都是相同的。
进一步澄清 - 我知道实际的合并会根据方向产生彼此的“镜像”。我只是在询问自动解决的冲突。
默认合并的答案是肯定的。三路合并找到一个共同的祖先,然后应用双方的差异,这是一个不依赖于顺序的操作。合并排序和交换性的话题在git list上引发了一场有趣的讨论(如果你喜欢那种东西,那就是)。注意B into C
和应该是对称的,但对于vsC into B
不一定是相同的。(B into C) into A
B into (C into A)
[编辑说明,2020 年 4 月:如果您添加类似-X ours
or-X theirs
的选项,答案将变为“否”,请参阅twalberg 的答案和其他人以获取更多注意事项。]
更详细地说,根据下面文斯的评论和 seh 对问题的评论, 和 之间会有两个明显的区别B into C
,C 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
在这种情况下,E 的“第一父”E^1
是合并前 first_branch 的小费。second_branch 是合并提交的“第二个父级”,又名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
这些差异都不会影响自动合并解析,但是当您反转三向合并顺序时,它们确实会出现。
这取决于您所说的“相同结果”是什么意思。从内容的角度来看,假设没有冲突,或者所有现有的冲突都以完全相同的方式精心解决,则生成的新合并提交的内容应该是相同的。
但是,从历史拓扑的角度来看,两者是非常不同的。如果您在分支 B 上并在 C 中合并,则 B 的 HEAD 将移动以指向合并提交,但 C 保持在原处。相反,如果您在 C 上并在 B 中合并,则 C 的 HEAD 移动,而 B 保持原位。所以最终的拓扑结构非常不同,这对任何一个分支的未来开发都有影响,即使新提交的内容在任何一种情况下都是相同的。
不,我认为它不会是对称的。首先,您可以设置合并策略选项,特别是在您的情况下theirs
orours
确定是否选择 B 或 C。
在自动合并中,我认为例如,如果您要合并到您的远程分支,则远程分支优先于您的更改,因此这意味着git merge C
从 B 调用将导致选择 C 更改。不过,我不是 100% 确定,所以您可以自己尝试并告诉我们。
内容是对称的,但是如果你使用 GitHub 或 Bitbucket 或者你最喜欢的本地 Git 查看器来查看合并时所做的更改,你会看到合并提交中列出的文件更改是不同的。(以及上面提到的其他事情。)
git checkout b
git merge c
合并中显示的文件更改将是c
自那时以来所做的更改b
和c
发散的更改。
git checkout c
git merge b
合并中显示的文件更改将是b
自那时以来所做的更改b
和c
发散的更改。