REBASE与MERGE中的Git冲突 [英] Git conflicts in rebase vs merge
问题描述
合并到分支时的冲突数量与更改分支的基数有什么区别吗?为什么会这样?
在进行合并时,合并更改存储在合并提交本身(两个父级的提交)中。 但在执行REBASE时,合并存储在哪里?
谢谢, Omer
推荐答案
Rebase(大多数情况下)只是一系列挑剔的选择。选择樱桃和合并使用相同的逻辑--我称之为合并逻辑和文档通常称为三向合并逻辑--来创建新的提交。
该逻辑是,给定提交X和Y:
从较早的提交开始。这称为合并基。
区分以前的提交和X。
区分早期提交和Y。
将两个差异应用于较早的提交,并且:
a.如果可以执行该操作,则创建一个新的提交来表示结果。
b.如果您无法执行此操作,请抱怨您遇到了冲突。
在这方面,Merge和Cherry-Pick(因此是Merge和Rebase)几乎是相同的,但有一些不同。一个特别重要的区别是,在三方合并的逻辑中,谁是第三方和第三方。特别是,他们可能对第一步(合并基础)中较早提交的是谁有不同的想法。
让我们首先来看一个退化的示例,其中合并和Cherry-Pick几乎相同:
A -- B -- C <-- master
F <-- feature
如果您将Feature合并到master中,Git将查找Commit where Feature和master最近出现分歧的地方。这就是B。在我们的合并逻辑--合并基础中,它是前面提交的。因此,Git将C与B进行比较,并将F与B进行比较,并将这两个差异应用于B以形成新的提交。它提供提交两个父对象C和F,并移动master
指针:
A -- B - C - Z <-- master
/
/
F <-- feature
如果您选择功能到主功能,Git将查找功能的父,即F的父功能。这又是B!(那是因为我故意选择了这个堕落的案例。)这就是我们的合并逻辑中较早的提交。因此,Git再一次将C与B进行比较,并将F与B进行比较,并将这两个差异应用于B以形成新的提交。现在,它为该提交提供一个父级C,并移动master
指针:
A -- B - C - F' <-- master
F <-- feature
如果将功能重新设置为主功能,则Git会对每个提交功能进行精挑细选并移动feature
指针。在我们退化的情况下,功能上只有一次提交:
A -- B - C <-- master
F' <-- feature
F
现在,在这些图表中,作为合并基础的早期提交在每种情况下都是相同的:B.因此合并逻辑是相同的,因此在每个图表中发生冲突的可能性是相同的。
但如果我在功能上引入更多提交,情况就会改变:
A -- B -- C <-- master
F -- G <-- feature
现在,将Feature重新定位到Master意味着在C上选择F(给予F‘),然后在C上选择G(给予G’)。对于第二个Cherry-Pick,Git使用F作为前面的提交";(合并基),因为它是G的父级。这引入了一种我们以前没有考虑过的情况。具体地说,合并逻辑将涉及从F到F‘的差异,以及从F到G的差异
因此,当我们改变基准时,我们沿着重新建立基础的分支迭代地挑选每个提交,并且在每次迭代中,我们的合并逻辑中比较的三个提交是不同的。因此,很明显,我们为合并冲突引入了新的可能性,因为实际上,我们正在进行更多不同的合并。这篇关于REBASE与MERGE中的Git冲突的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!