为什么三向合并优于两向合并?


Answers:


259

假设您和您的朋友都签出了文件,并对文件进行了一些更改。您在开头删除了一行,而您的朋友在结尾添加了一行。然后他提交了他的文件,您需要将他的更改合并到副本中。

如果您正在执行双向合并(即diff),则该工具可以比较两个文件,并看到第一行和最后一行是不同的。但是,它怎么知道如何处理这些差异?合并后的版本是否应包含第一行?它应该包括最后一行吗?

通过三向合并,它可以比较两个文件,但也可以将每个文件与原始副本进行比较(在您更改任何一个文件之前)。这样可以看到您删除了第一行,而您的朋友添加了最后一行。并且它可以使用该信息来生成合并的版本。


“但是它怎么知道如何处理这些差异呢?” 没明白。如果它已经可以看到两个文件之间的差异(不参考原始文件),为什么它不能按文件时间戳的升序依次应用这两个更改?也就是说:它以我朋友的已提交副本开始,将其作为(新的)原始副本(在顶部添加行),然后在其顶部应用我的本地更改(在botton删除行)。
哈里

7
@Harry说原版有三行(ABC)。它以我朋友的副本(ABCD)开头,然后与我的副本(BC)比较。没有看到原件,可能会认为我同时删除了A和D,并且最终结果应该是BC。
JW。

80

perforce演示文稿中的这张幻灯片很有趣:

幻灯片图像

三向合并工具的基本逻辑很简单:

  • 比较基本文件,源文件和目标文件
  • 在源文件和目标文件中标识“块”:
    • 与基础不匹配的块
    • 与基数匹配的块
  • 然后,将合并结果合并在一起,包括:
    • 所有3个文件中彼此匹配的块
    • 源或目标中都与基数不匹配的块,但两者均不匹配
    • 与基础不匹配但彼此匹配的块(即,在源和目标中都以相同的方式对其进行了更改)
    • 冲突的块的占位符,由用户解决。

请注意,此图中的“块”仅是象征性的。每一个都可以代表文件中的行,层次结构中的节点,甚至目录中的文件。这完全取决于特定合并工具的功能。

您可能会问,三向合并相对于两向合并有什么优势。实际上,没有双向合并之类的东西,只有一些工具可以区分两个文件,并允许您通过从一个文件或另一个文件中选取块来“合并”。
只有三向合并才能让您知道块是否与原点相比有所更改以及更改是否冲突。


“是否更改冲突。” -2向合并(diff)也不会显示冲突(尽管信息从冲突源中丢失了)/
Vlad 2014年

1
但是,在Git中进行4路合并是很常见的,其基数实际上并不相同。三向合并还是两向更好。
2014年

@Wnightnight,有5向合并吗?
Pacerier

@Pacerier我不知道,但这就是在git cherry-pick或rebase过程中实际发生的情况。
2015年

非常详细和有用的解释
Kaneg

20

我写了一篇非常详细的文章。基本上,您无法使用双向方法来跟踪删除/添加,这非常无用。


@pablo,如果我在X之前添加一个函数,并且在X之后添加另一个函数,然后执行三步合并,则该工具将自动应用这两个更改。但是,当我的更改实际上与您的更改冲突时会发生什么(例如,我们每个人都使用相同的函数名称创建一个新函数)?自动合并应该如何得知我们的“非常容易”的合并实际上会引起冲突
Pacerier 2015年

1
只需阅读您的教程,对我真的很有帮助。我感觉与您描述的开发人员相同。我一直担心三路合并。
racl101 2015年

3
我建议您复制并粘贴文章的某些部分。我认为这将帮助您获得支持,并与stackoverflow的哲学更加一致。
塞缪尔

好文章。我曾经喜欢使用补丁程序进行基础调整,因为您可以看到更多的上下文,并且可以使用编辑器和环境来检查事物,但是那样的话,太多了手动操作简单的事情。遗憾的是,没有一种很好的方法将两者的
优点融为一体

20

一种三向合并,其中将两个变更集在应用到一个基础文件时进行合并,而不是应用一个变更集,然后将结果与另一个合并。

例如,在同一位置添加一行的两个更改可以解释为两个添加,而不是一行的更改。

例如

文件a已被两个人修改,一个添加了驼鹿,一个添加了鼠标。

#File a
    dog
    cat

#diff b, a
    dog
+++ mouse
    cat

#diff c, a
    dog
+++ moose
    cat

现在,如果我们在应用变更集时合并它们,我们将获得(3路合并)

#diff b and c, a
    dog
+++ mouse
+++ moose
    cat

但是如果我们应用b,然后看一下从b到c的变化,就好像我们只是将'u'更改为'o'(2向合并)

    #diff b, c
    dog
--- mouse
+++ moose
    cat
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.