Git 合并 diff3 样式需要说明 [英] Git merge diff3 style need explanation

查看:23
本文介绍了Git 合并 diff3 样式需要说明的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我合并了 2 个分支并出现了冲突,我需要一些提示,它从哪里开始到哪里结束等等.我用一些伪造的数据替换了代码,以便于阅读和讨论.

I've merged 2 branches and conflicts appeared, I would need some hints where it starts where it ends, etc. I've replaced the code with some faked data to make it easier to read and talk about.

<<<<<<< HEAD
    aaaaaa
||||||| merged common ancestors
<<<<<<< Temporary merge branch 1
    bbbbbb
=======
    cccccc
>>>>>>> mybranch
    dddddd
<<<<<<< HEAD
    eeeeee
||||||| merged common ancestors
    ffffff
||||||| merged common ancestors
    gggggg
=======
>>>>>>> Temporary merge branch 2
=======
    hhhhhh
>>>>>>> mybranch

推荐答案

你在这个例子中看到的(带有 Temporary merge branch 标记)是 diff3 与交叉合并的结果冲突.我将用一系列定义来解释这一点.

What you're seeing in this example (with Temporary merge branch markers) is the result of diff3 with a criss-cross merge conflict. I'll explain this with a sequence of definitions.

  • merge base:两个合并分支最近偏离的提交.当发生合并冲突时,对两个分支中的同一行进行了不同的更改.merge base 包含这些行在任一分支更改它们之前的内容.
  • 合并的共同祖先:diff3 输出一个额外的中间"部分,显示它们在合并基础中的行.这是两个分支的起点.
  • 纵横合并:合并历史,其中两个分支以一种不可能是快进合并的方式相互合并.我在下面举一个例子.在交叉合并的情况下,有多个合并基.
  • 临时合并分支:当有多个合并基时,diff3尝试将它们合并在一起(使用临时合并分支)以形成一个共同祖先 显示在 diff3 的中间部分.这在没有冲突时无缝地工作,但是当有冲突时,您会在中间合并的共同祖先部分中看到临时合并分支的冲突标记.
  • merge base: The commit where the two merging branches most recently diverged from. When a merge conflict occurs, different changes were made to the same lines in both branches. The merge base contains what those lines were before either branch changed them.
  • merged common ancestors: diff3 outputs an additional "middle" section showing the lines as they were in the merge base. This is the starting point for both branches.
  • Criss-cross merge: A merge history where two branches merge into each other in ways that one could not have been a fast-forward merge. I give an example below. In a criss-cross merge situation, there are multiple merge bases.
  • Temporary merge branch: When there are multiple merge bases, diff3 attempts to merge them together (using temporary merge branches) to form a single common ancestor to show in diff3's middle section. This works seamlessly when there are no conflicts, but when there are conflicts, you see the temporary merge branch's conflict markers inside the middle merged common ancestors section.

每当两个分支在不同的时间点相互合并时,就会发生纵横合并.

A criss-cross merge occurs whenever two branches merge into each other at different points in time.

m3 *
   |
   | 
   |  * B1
   |  |
m2 *  * B0
   |/|
   |/|
m1 *  * A
   | /
   |/
m0 *

考虑这一系列事件:

  • m0 作为 origin/master
  • 存在
  • 我用一次提交A
  • 创建了一个特性分支feature-A
  • m1 被其他人承诺掌握
  • 我在A
  • 上创建了一个新的功能分支feature-B
  • 我将 origin/master (m1) 合并到 feature-B 中.它发生冲突,我解决了它.合并提交是 B0.
  • 我实现了功能 B 并将工作提交为 B1.
  • feature-A 已准备好发布,因此有人将其合并到 master 中.它冲突.他们解决了它,但他们的分辨率与B0中的分辨率不同.合并提交是 m2.
  • feature-B 已准备好发布,因此有人将其合并到 master 中.git 尝试确定 merge base,但 m1A 都同样符合合并基础.git在一个临时合并分支中合并m1A,导致冲突.我们在合并的共同祖先部分看到了 diff3 输出,类似于 OP 的问题.
  • m0 exists as origin/master
  • I create a feature branch feature-A with one commit A
  • m1 gets committed to master by someone else
  • I start a new feature branch feature-B that builds on A
  • I merge origin/master (m1) into feature-B. It conflicts, and I resolve it. The merge commit is B0.
  • I implement feature-B and commit the work as B1.
  • feature-A is ready to ship, so someone merges it into master. It conflicts. They resolve it, but their resolution differs from the resolution in B0. The merge commit is m2.
  • feature-B is ready to ship, so someone merges it into master. git tries to determine the merge base, but m1 and A both qualify equally as merge bases. git merges m1 and A in a temporary merge branch, which results in a conflict. We see diff3 output in the merged common ancestors section, similar to the OP's question.

关闭 diff3 后,这个合并冲突看起来就像这样:

With diff3 off, this merge conflict would look simply like this:

<<<<<<< HEAD
    aaaaaa
=======
    hhhhhh
>>>>>>> mybranch

首先,使用所有额外的标记,您需要确定实际的冲突行是什么,以便将其与 diff3 共同祖先输出区分开来.

First, with all the extra markers, you'll want to determine what the actual conflicting lines are, so you can differentiate it from the diff3 common ancestor output.

aaaaaahhhhhh,那好一点.;-)

aaaaaahhhhhh, that's a little better. ;-)

在两个冲突解决方案冲突的情况下,aaaaaahhhhhh就是两个解决方案.

In the case where two conflict resolutions are conflicting, aaaaaa and hhhhhh are the two resolutions.

接下来,检查合并的共同祖先的内容.

Next, examine the content of the merged common ancestor.

在这个特定的合并历史中,有超过 2 个合并基础,这需要多个临时合并分支,然后将它们合并在一起.当有许多合并基础和冲突时,结果会变得非常复杂且难以阅读.有人说不要打扰,只需在这些情况下关闭 diff3.

With this particular merge history, there were more than 2 merge bases, which required multiple temporary merge branches which were then merged together. The result when there are many merge bases and conflicts can get pretty hairy and difficult to read. Some say don't bother, just turn off diff3 for these situations.

另请注意,git 内部可能会决定使用不同的合并策略来自动解决冲突,因此输出可能难以理解.如果可以,请理解它,但要知道它不是供人类食用的.在这种情况下,在bbbbbbcccccc 之间将mybranch 合并到Temporary merge branch 1 时发生了冲突.行 dddddd 在临时合并分支之间没有冲突.然后在将Temporary merge branch 2 合并到HEAD 时发生了单独的冲突,具有多个共同的祖先.HEAD 已经通过将 ffffffgggggg 合并为 eeeeee 解决了冲突,但是 Temporary merge branch 2 通过删除(或移动)该行(因此 ======Temporary merge branch 2 之间没有行)解决了同样的冲突.

Also be aware that git internally may decide to use different merge strategies to auto-resolve conflicts, so the output can be hard to understand. Make sense out of it if you can, but know that it was not intended for human consumption. In this case, a conflict occurred when merging mybranch into Temporary merge branch 1 between bbbbbb and cccccc. Line dddddd had no conflicts between the temporary merge branches. Then a separate conflict occurred when merging Temporary merge branch 2 into HEAD, with multiple common ancestors. HEAD had resolved the conflict by merging ffffff and gggggg as eeeeee, but Temporary merge branch 2 resolved that same conflict by deleting (or moving) the line (thus no lines between ====== and Temporary merge branch 2.

你如何解决这样的冲突?虽然技术分析可能是可能的,但您最安全的选择通常是返回并查看冲突周围所有相关分支的历史记录,并根据您的理解手动制定解决方案.

How do you resolve a conflict like this? While technical analysis may be possible, your safest option is usually to go back and review the history in all the involved branches around the conflict, and manually craft a resolution based on your understanding.

这些冲突是最糟糕的,但有一些行为可以帮助防止它们.

These conflicts are the worst, but there are some behaviors that will help prevent them.

  1. 避免交叉合并.在上面的例子中,feature-Borigin/master 合并为 B0.可能不需要这种合并以与 master 保持同步(尽管有时是这样).如果 origin/master 从未合并到 feature-B 中,就不会有合并纵横交错,m3 会是一个正常的与 A 作为唯一的合并基础发生冲突.

  1. Avoid criss-cross merges. In the example above, feature-B merged origin/master as B0. It's possible that this merge to stay up-to-date with master wasn't necessary (though sometimes it is). If origin/master was never merged into feature-B, there would have been no merge criss-cross, and m3 would have been a normal conflict with A as the only merge base.

m3 *              m3 *
   |                |
   |                | 
   |  * B1           |  * B1
   |  |              |  |
m2 *  * B0   VS   m2 *  |
   |/|              | |
   |/|              | |
m1 *  * A         m1 *  * A
   | /               | /
   |/                |/
m0 *              m0 *

  • 与冲突解决方案保持一致.在这个例子中,临时合并基础冲突只是因为m2B0有不同的冲突解决方案.如果他们以相同的方式解决了冲突,m3 将是一个干净的合并.意识到这是一个简单的交叉合并,应该具有相同的分辨率.其他情况可能有不同的解决方案.当合并点之间有 2 个以上的合并基础和多个提交时,事情会变得更加复杂.也就是说,如果您在纵横交错的情况下故意不同意冲突解决方案,那么以后可能会头疼.
  • Be consistent with conflict resolutions. In the example, the Temporary merge base conflict only occurred because m2 and B0 had different conflict resolutions. If they had resolved the conflict identically, m3 would have been a clean merge. Realize though that this is a simple criss-cross merge that ought to have had the same resolution. Other situations may rightly have different resolutions. Things get more complicated when there are more than 2 merge bases and multiple commits between the merge points. That said, if you are knowingly inconsistent with conflict resolutions in criss-cross situations, expect headaches later.
  • 这篇关于Git 合并 diff3 样式需要说明的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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