链式分支合并策略

问题描述 投票:0回答:1

我从master创建了分支A.完成后我创建了拉取请求掌握。当A的工作正在审查中时,我开始处理基于分支A的任务,所以从分支A我创建了分支B.然后我将分支B合并到A并且想要将B合并到主人,但是冲突出现了。在这种情况下,避免冲突的最佳做法是什么?在从A的请求之前,两个分支都是本地的。

[编辑]

在分支A和B中编辑了同一行,那么为什么它不会自动合并?

enter image description here

git merge
1个回答
2
投票

Git(这里需要强调,因为你可能使用的不仅仅是Git本身)没有“基础分支”的概念。

当您使用GitHub或Bitbucket上的Web界面来创建“拉取请求”时,它就是选择上游分支名称的Web界面,以建议拉取请求。 Git本身并不知道你会发出一个pull请求.1所有Git都知道并关心提交,通常是通过哈希ID。

当你运行git merge时,你选择两个提交,通常是两个分支提示。你选择一个运行git checkout,通常是git checkout <somebranch>。该提交成为您当前的提交。这是Git调用local或--ours的提交;我通常把它称为左,本地或--ours。 (注意,如果你没有在git checkout之前运行git merge,那么你现在检查的内容仍然是你当前的提交,因此你选择那个作为你的L提交。)

然后你运行git merge <name-or-hash-id>。 Git将名称(如果您给它一个)转换为提交哈希ID。这是你如何选择其他提交,Git有时会调用远程或其他或--theirs提交,我打电话给R.

Git使用L和R提交哈希ID以及存储库中的所有其他提交来查找合并基础提交哈希ID。简而言之,这个合并基础提交是两个分支“一起回来”的“最近”提交。 Git将在此处找到的提交取决于现有提交图的拓扑。

如果Git能够自己进行合并,Git会生成一个包含合并结果的新提交。新的提交有两个父项,而不只是一个:第一个父项是你运行git merge时L的提交,第二个是R的提交。新的提交在当前分支上进行,所以当前分支名称 - 您已签出的分支名称 - 现在指向新的合并提交。

您在上面绘制的图表很难让我解释:我无法从您的绘图中看出哪些提交可以从哪个分支提示提交,或者就此而言,哪些提交首先是分支提示。特别是你已经绘制了两个似乎是合并提交的提交,但我不知道早期(祖先)提交是左侧还是右侧。此外,您的文本描述了进行一次合并,而不是两次。假设先前的提交是向左 - 那个时间从左到右流动,就像在这里 - 我在这里是如何在文本中绘制大部分图形:

       o--o   o--o   <-- branch-B
      /    \ /
     | __---o   <-- branch-A
     |/
...--o   <-- master

但请注意,此图只有一个合并提交,在这种情况下是branch-A指向的提交。 branch-B这个名字指向最顶层的最右侧提交。

在这个特定的例子中,branch-B包含图中绘制的每个提交,而branch-A包含除最近两个提交之外的所有提交,而master仅包含底线上的提交以及导致该点的任何早期提交。 branch-B(提交L)的提示提交和master(提交R)的提示提交的合并基础将是master的提示提交,即提交R本身。因此,在分支git merge上运行branch-B将选择它作为合并基础。合并将是微不足道的(但事实上被拒绝),因为没有合并冲突。所以这显然不是你在做什么,显然不是正确的图形。

没有正确的图表,就不可能说出Git选择的合并基础。但是如果你确实遇到了合并冲突,那是因为当比较合并基础提交提交L时,Git看到一个文件的某些行发生了变化,然后当比较合并基础提交提交R时,Git看到了不同的变化到同一文件的同一行。 Git无法在这两个更改之间进行选择,因此它在合并冲突时停止,使文件的工作树版本应用了两个更改。现在由你来解决这个冲突(以及任何其他冲突),git add正确的合并结果,并运行git merge --continue来完成合并;或运行git merge --abort来停止合并,并将事情恢复到Git尝试合并之前的状态。


1虽然它们是相关的,但不要将这些外部提供的Web界面与git request-pull命令行命令混淆。那个是内置于Git,但它要求你,而不是Git,选择<start>提交。当GitHub为您做出选择时,他们正在使用Git本身无法获得的信息。具体来说,GitHub知道 - 已经记录了自己,在一个位置它有效保密Git - 你点击GitHub“fork”按钮时使用的上游项目。他们(GitHub)也控制该上游项目的Git存储库,因此他们可以窥视它并选择一个<start>。但他们这样做; Git没有。

2记住,在计算合并基础提交后,Git有效地运行:

git diff --find-renames <base> L   # see what we did on --ours
git diff --find-renames <base> R   # see what they did on --theirs

然后尝试将这两组更改组合成一个大的“自基础更改集后的每个人的更改”,并将组合的更改应用于<base>提交中的任何内容。我们刚刚宣称<base>和R是相同的提交,所以这里一定没有任何变化。这种合并的结果将完全匹配提交L.事实上,对于这种情况,Git会说“已经是最新的”并且拒绝做任何事情。

© www.soinside.com 2019 - 2024. All rights reserved.