我在的BASE文件中具有以下内容git merge:
<<<<<<<<< Temporary merge branch 1
- _modifiedTimeWeak = 4.25.2019::11:41:6;
- _lastID = 3;
- weakCGTime = 4.25.2019::11:42:20;
- strongCGTime = 1.2.1990::0:0:0;
=========
- _modifiedTimeWeak = 5.1.2019::8:52:36;
- _lastID = 3;
- weakCGTime = 5.1.2019::8:52:36;
- strongCGTime = 3.20.2019::17:13:20;
>>>>>>>>> Temporary merge branch 2
Run Code Online (Sandbox Code Playgroud)
我现在已经对该文件进行了无基础的合并,因此没有未解决的问题,但是我想了解可能出了什么问题。
我已经检查了由标识的BASE提交git merge-base,并且它不包括所介绍的合并冲突,因此可以排除。这也是这是第一次,尽管在此存储库发生之前已经进行了许多合并。
可能值得注意的是,我正在使用git merge merge-tool。
执行合并时,可能导致BASE文件出现合并冲突的原因是什么,可以采取什么步骤来避免将来发生这种情况?
当存在多个合并库并且合并合并库产生合并冲突时,会发生这些情况。合并基础候选者是您选择要合并的提交的LCA,在提交引起的子图中:
定义3.1。令G =(V; E)为DAG,令x; ÿ?V。令G x; y是由x和y的所有共同祖先集合引起的G的子图。将SLCA(x; y)定义为G x中的出度0节点(叶)的集合;ÿ。x和y的最低共同祖先是SLCA(x; y)的元素。
(请参阅https://www3.cs.stonybrook.edu/~bender/pub/JALG05-daglca.pdf)。这里摹是在你的仓库中提交,并形成了向无环图X和Ÿ是你选择合并这两个提交。我实际上更喜欢3.2的定义,尽管它使用posets,并且可能更行话:感觉更相关(实际上是用于家谱研究,这是Git在做的事情)。
该递归合并策略,-s recursive,使用所有合并基础,合并各合并基础和提交的结果,完成合并冲突,并使用该临时提交的新的合并基础。因此,这就是问题第一部分的答案(“什么可能导致基本文件……发生合并冲突”)。
为避免这种情况,您有几种选择,但是首先让我们更容易地描述问题。
您提到您曾经使用过git merge-base。默认情况下,git merge-base选择一个基于最佳合并的提交候选者并打印其哈希ID。如果您git merge-base --all在两个分支技巧提交上运行,则会看到有多个基于最佳合并的提交候选。
在典型的简单分支合并模式中,我们有:
o--o--o <-- branch-A
/
...--o--o--*
\
o--o--o <-- branch-B
Run Code Online (Sandbox Code Playgroud)
通用合并基础-如引用的论文中的3.1或3.2所示;在3.2版本中,您可以从两个分支提示中退回,直到找到在两个分支上都存在的提交为止—当然是提交,*而Git仅需要*分别与分支A和分支B的两个提示提交进行比较。
并非所有的图形都那么简洁明了。获得两个合并基础的最简单方法是在历史链中进行纵横交错的合并,如下所示:
...--o--o--*---o--o--o <-- branch-C
\ /
X
/ \
...--o--o--*---o--o--o <-- branch-D
Run Code Online (Sandbox Code Playgroud)
请注意,两个已加星标的提交都在两个分支上,并且两个提交都同样接近两个分支提示。运行git merge-base --all branch-C branch-D将打印两个哈希ID。Git应该使用哪个提交作为合并基础?
Git的默认答案是:让我们全部使用它们! Git将运行,实际上:
git merge <hash-of-first-base> <hash-of-second-base>
Run Code Online (Sandbox Code Playgroud)
作为递归(内部)合并。此合并可能会有冲突!
如果合并确实存在冲突,则Git不会停止并从您(用户)那里获得帮助。它只是提交冲突的结果。这成为外部的输入git merge,即您直接要求的输入:
...--o--o--*---o--o--o <-- branch-C
\ /
M <-- temporarily-committed merge result
/ \
...--o--o--*---o--o--o <-- branch-D
Run Code Online (Sandbox Code Playgroud)
临时提交实际上不是在图中,但对你的外在合并的目的,它也可能是。
现在我们所看到的问题是如何产生的,该如何避免它更清晰,不完全明确,但明确呃比他们,至少包括:
方法1:避免纵横交错的合并。
通过避免任何会产生多个合并基础的事情,您永远不会陷入困境。纵横交错的合并是在某种情况下具有branch-C和branch-D在这种情况下创建的:
o--o--o <-- branch-C
/
...--o
\
o--o--o <-- branch-D
Run Code Online (Sandbox Code Playgroud)
有人-假设某人C-跑来git checkout branch-C; git merge branch-D获得:
o--o--o---M1 <-- branch-C
/ /
...--o /
\ /
o--o--o <-- branch-D
Run Code Online (Sandbox Code Playgroud)
于是,有人,可能是别人,谁没有新的提交上自己的 branch-C ; 让我们称这个人为D -ran git checkout branch-D; git merge <commit that was the previous tip of branch-C before the new merge was just added>,得到:
o--o--o <-- branch-C
/ \
...--o \
\ \
o--o--o---M2 <-- branch-D
Run Code Online (Sandbox Code Playgroud)
C和D共享新提交后,结果是:
o--o--o---M1 <-- branch-C
/ \ /
...--o X
\ / \
o--o--o---M2 <-- branch-D
Run Code Online (Sandbox Code Playgroud)
然后定时炸弹被放置了。直到您稍后尝试合并提交,它才开始运行,但这就是它的设置。
方法2:如果确实进行此类合并,请小心使用它们。 编辑:这实际上并没有帮助:Git仍在使用commit 和之后的提交,并重新合并它们。尽管如此,还是值得考虑一下。我将保留其中一些文本。M1M2
合并通常都是对称的。注意,当个人C和D运行两个git merge命令时,他们具有相同的提交,从而形成相同的图。它们从相同的合并基础开始,具有相同的两个分支提示提交。通过比较合并基础与每个分支尖端而产生的两个差异是相同的差异。
因此,人员C和D必须解决一些冲突,就像您在自己的合并合并库中看到的一样。他们可能因此自动完成:例如,人物C可能是碰上git merge -X ours喜欢他的提示提交变化,你发现,在冲突的文件M1,而人d可能也运行git merge -X ours到喜欢她的尖提交的变化M2。
这些非对称结果是无害的,除了定时炸弹本身以及您以后进行递归合并的事实。您会看到冲突。再次由您决定解决这个问题,但是这一次,如果对C和D人有用,我们/他们的技巧绝非易事。
方法3(简单但可以说是错误的):使用不同的合并策略。
递归合并策略,-s recursive是在一个采用此图,发现所有的合并基础提交的考生,如果有一个以上的,将它们合并和使用结果作为输入您的合并。有一种名为resolve(-s resolve)的策略,与递归策略共享几乎所有代码。所不同的是,当(或之后)计算的所有合并基地,它只需一个多基地。
在这种情况下,如果有两个合并候选M1和M2,它们-s resolve只会随机选择M1或M2(实际上不是随机的,无论哪个首先弹出,但控制方式都不是很好:没有明显的理由选择一个vs另一个)。Git将使用这一提交作为合并基础。
这里的问题很明显:通过使用一个提交(人C或人D),您将忽略另一人选择的冲突解决方案。两人这次离开了您,这枚炸弹给您留下了答案,那-s resolve就是让炸弹摧毁两个结果之一,而我却没有看到谁是正确的,还是应该做些更好的事情。
无论如何,都没有一个正确的答案,这与任何合并冲突都是一样的。问题是您现在正在解决一个冲突,该冲突在过去这两个冲突的合并进行时可能应该已经解决了。
| 归档时间: |
|
| 查看次数: |
94 次 |
| 最近记录: |