从Git合并文档中了解到,递归合并策略只能使用3方合并算法来解决两个分支。当存在多个公共祖先可用于3方合并时,它会创建一个公共祖先的合并树,并将其用作3方合并的参考树。据实际取自Linux 2.6内核开发历史记录的合并提交的测试报告,这种方法可以减少合并冲突而不会导致错误合并。此外,该方法还可以检测和处理涉及重命名的合并。这是拉取或合并一个分支时的默认合并策略。
递归合并策略可以采用以下选项:
作为默认策略的递归合并策略使用3方递归合并算法(在这里和Wikipedia上有解释)。
我的理解是,具有冲突块的部分必须手动解决,它们通常呈现为以下形式:
<<<<<<<<<<<
developer 1's code here
============
developer 2's code here
>>>>>>>>>>>
递归合并策略的ours选项文档如下:
此选项通过优先考虑我们的版本来自动清除冲突块。与我们的一面不冲突的其他树更改会反映到合并结果中。对于二进制文件,整个内容都取自我们这一面。
这不应与ours合并策略混淆,后者甚至不看其他树包含什么。它丢弃了其他树所做的一切,声明我们的历史包含了其中发生的所有事情。
假设现在有两个分支Y和M,共同的基础祖先B如下所示:
当使用默认的递归策略合并Y和M时,由于在第30行,Y表示从基本祖先进行的更改而M不是,因此第30行将变为Print("hello");
。但是如果我在M分支上运行
git merge -s recursive -X ours Y
合并输出中的第30行是否为Print("bye");
?
对于那些认为这很明显的人,请注意ours选项所述:
此选项通过优先考虑我们的版本来自动清除冲突块。
但是(据我所知)在第30行没有冲突块。
完整起见,我还将给出theirs选项的文档:
这与ours相反。
ours策略的文档如下:
这解决了任意数量的头,但合并的结果树始终是当前分支头的树,有效地忽略了所有其他分支的更改。它旨在用于取代旁路的旧开发历史。请注意,这与recursive合并策略的-Xours选项不同。
因此,返回上面的示例,如果我在M分支上运行:
git merge -s ours Y
很明显,在合并输出中的第30行将是Print("bye");
。在这种情况下,为什么也没有一个theirs策略呢?我该如何实现等同于ours策略的相反行为?
我之所以提出这个问题,是因为我正在一个项目中工作,在该项目中,每当开发分支上的代码成功构建时,我都想定期完全覆盖主分支上的更改。这样我就可以确保我的开发分支不会远离主分支太远,并且在主分支上的代码将成功构建。
我看到这个问题 ,它推荐以下解决方案:
git checkout dev-branch
git merge -s ours master
但是 Git 只会输出Already up-to-date
,尽管这两个分支包含不同的代码(并且dev-branch
实际上比master
要领先几个提交)。
我的当前解决方案是执行:
git merge -s recursive -X theirs dev-branch
我也看到了这个问题,它建议使用递归策略的theirs选项。 但是由于递归策略的ours选项明显不同于我们策略,因此其选项的递归策略与我所说的其策略也将不同。