为什么 3 路合并比 2 路合并更有优势?

发布于 2024-10-01 10:08:04 字数 180 浏览 7 评论 0原文

维基百科说三向合并比双向合并,通常不需要用户干预。为什么会这样呢?

3 路合并成功而 2 路合并失败的示例会很有帮助。

Wikipedia says a 3-way merge is less error-prone than a 2-way merge, and often times doesn't need user intervention. Why is this the case?

An example where a 3-way merge succeeds and a 2-way merge fails would be helpful.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

疯到世界奔溃 2024-10-08 10:08:04

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

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

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

Say you and your friend both checked out a file, and made some changes to it. You removed a line at the beginning, and your friend added a line at the end. Then he committed his file, and you need to merge his changes into your copy.

If you were doing a two-way merge (in other words, a diff), the tool could compare the two files, and see that the first and last lines are different. But how would it know what to do with the differences? Should the merged version include the first line? Should it include the last line?

With a three-way merge, it can compare the two files, but it can also compare each of them against the original copy (before either of you changed it). So it can see that you removed the first line, and that your friend added the last line. And it can use that information to produce the merged version.

半衾梦 2024-10-08 10:08:04

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

幻灯片图像

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

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

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

您可能会问 3 路合并比 2 路合并有什么优势。实际上,不存在双向合并这样的东西,只有能够区分两个文件并允许您通过从一个文件或另一个文件中选取块来“合并”的工具。
只有三向合并才能让您知道某个块是否是对源的更改以及更改是否冲突。

This slide from a perforce presentation is interesting:

slide image

The essential logic of a three-way merge tool is simple:

  • Compare base, source, and target files
  • Identify the "chunks" in the source and target files file:
    • Chunks that don't match the base
    • Chunks that do match the base
  • Then, put together a merged result consisting of:
    • The chunks that match one another in all 3 files
    • The chunks that don't match the base in either the source or in the target but not in both
    • The chunks that don't match the base but that do match each other (i.e., they've been changed the same way in both the source and the target)
    • Placeholders for the chunks that conflict, to be resolved by the user.

Note that the "chunks" in this illustration are purely symbolic. Each could represent lines in a file, or nodes in a hierarchy, or even files in a directory. It all depends on what a particular merge tool is capable of.

You may be asking what advantage a 3-way merge offers over a 2-way merge. Actually, there is no such thing as a two-way merge, only tools that diff two files and allow you to "merge" by picking chunks from one file or the other.
Only a 3-way merge gives you the ability to know whether or not a chunk is a change from the origin and whether or not changes conflict.

离不开的别离 2024-10-08 10:08:04

三向合并是指将两个变更集在应用时合并到一个基本文件,而不是应用一个变更集,然后将结果与另一个合并。

例如,在同一位置添加一行的两次更改可能会被解释为两次添加,而不是一行的更改。

例如,文件a已被两个人修改,其中一个添加了moose,另一个添加了mouse

#File a
    dog
    cat

#diff b, a
    dog
+++ mouse
    cat

#diff c, a
    dog
+++ moose
    cat

现在,如果我们在应用变更集时合并它们,我们将得到(三向合并)

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

但是如果我们应用 b,然后查看从 b 到 c 的更改,看起来我们只是将“u”更改为'o'(2 路合并)

    #diff b, c
    dog
--- mouse
+++ moose
    cat

A three-way merge is where two changesets to one base file are merged as they are applied, as opposed to applying one, then merging the result with the other.

For example, having two changes where a line is added in the same place could be interpreted as two additions, not a change of one line.

For example, file a has been modified by two people, one adding moose, one adding mouse.

#File a
    dog
    cat

#diff b, a
    dog
+++ mouse
    cat

#diff c, a
    dog
+++ moose
    cat

Now, if we merge the changesets as we apply them, we will get (3-way merge)

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

But if we apply b, then look at the change from b to c it will look like we are just changing a 'u' to an 'o' (2-way merge)

    #diff b, c
    dog
--- mouse
+++ moose
    cat
甜中书 2024-10-08 10:08:04

在日常工作中,只要有可能,我们都会做或者更愿意让 git 做双向合并。问题是为什么需要3 路合并,而不是默认的2 路合并

默认的合并策略是快进合并(见下左图),但是如果git无法进行快进合并因为开发历史已经出现分歧,示例额外提交已提交到源分支(但不是由您提交),git 必须做一些工作,并且它使用三向合并< /code>(下右图)​​。可以在此处找到推荐阅读内容。当然,对于 git 的所有内容,您还可以通过使用选项 --no-ff 来决定进行 3 向合并,即使不需要。

输入图片此处描述

借自 AWS CodeCommit:
开发者工具>代码提交>存储库>存储库名称>
拉取请求>拉取请求名称>合并

In day-to-day work, we would do or rather let git do a 2-way merge whenever possible. The question would be why is a 3-way merge needed, instead of the default 2-way merge.

The default merge strategy is a fast-forward merge(see left picture below), but if git can't do a fast-forward merge because the development history has diverged, example extra-commits has been committed to the source branch(but not by you), git has to do some work and it uses a three-way merge (right picture below). A recommended read can be found here. Of course, with all things git, you can also decide to do a 3-way merge by using the option --no-ff, even when it is not required.

enter image description here

Borrowed from AWS CodeCommit:
Developer Tools > CodeCommit > Repositories > RepositoryName >
Pull requests > Pull request name > Merge

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文