(Git合并)何时使用“我们的”策略,“我们的”选项和“他们的”选项?

Unc*_*ers 7 git version-control merge github

git merge文档中提取的递归合并策略的定义。

这只能使用3向合并算法解析两个磁头。当有一个以上的公共祖先可用于三路合并时,它将创建一个公共祖先的合并树,并将其用作三路合并的参考树。据报道,这样做可以减少合并冲突,而不会因对Linux 2.6内核开发历史记录中的实际合并提交进行测试而导致合并错误。此外,这可以检测和处理涉及重命名的合并。当拉或合并一个分支时,这是默认的合并策略。

递归策略可以采用以下选项:

如前所述,递归策略是默认策略,它使用3向递归合并算法(在此处Wikipedia上进行了说明)。

我的理解是冲突的大块必须手动解决,并且通常以这种方式表示

<<<<<<<<<<<
developer 1's code here
============
developer 2's code here
>>>>>>>>>>>
Run Code Online (Sandbox Code Playgroud)

我们的递归合并策略的选择进行了说明如下:

通过支持我们的版本,此选项可以强制自动解决冲突的大块。与另一棵树不冲突的更改会反映到合并结果中。对于二进制文件,全部内容都是从我们这边获取的。

这不应与我们的合并策略混淆,该策略甚至根本不看另一棵树包含的内容。它丢弃另一棵树所做的所有操作,声明我们的历史包含其中发生的所有事件。

现在假设我有两个分支Y和M的头,并且具有一个共同的基本祖先B,如下所示

在此处输入图片说明

当使用默认递归策略合并Y和M时,第30行将变为Print("hello");行,因为在第30行,Y表示从基本祖先开始的更改,而M则不是。但是如果我在M分支上并运行

git merge -s recursive -X ours Y

第30行会成为Print("bye");合并后的输出吗?

对于那些说这很明显的人,请注意我们的选项指出

通过支持我们的版本,此选项可以强制自动解决冲突的大块

但是(据我了解)在第30行没有冲突的块。

为了完整起见,我还将提供他们的选项的文档:

这与我们的相反。


我们的策略文档如下:

这样可以解析任意数量的head,但是合并的结果树始终是当前分支head的树,有效地忽略了所有其他分支的所有更改。它旨在取代侧支的旧开发历史。请注意,这与递归合并策略的-Xours选项不同。

所以回到上面的例子,如果我跑了

git merge -s ours Y

在分支M上,很明显第30行将Print("bye");在合并的输出中。在这种情况下,为什么也没有他们的策略?我如何才能获得与我们的策略相同且相反的行为?

我之所以这样问是因为我正在开发一个项目,无论何时成功构建开发分支上的代码,我都希望使用另一个开发分支上的更改定期并完全覆盖master分支。这样,我可以确保开发分支永远不会偏离master分支,并且master分支上的代码将成功构建。

我看到了这个问题,建议解决方案

git checkout dev-branch
git merge -s ours master
Run Code Online (Sandbox Code Playgroud)

但是Already up-to-date,尽管两个分支包含不同的代码(dev-branch实际上是前面的几个提交master),但Git只是输出。

我当前的解决方案是

git merge -s recursive -X theirs dev-branch

我也看到了这个问题,其建议使用他们的选择的递归策略。但是,由于我们递归策略的选择明显不同于我们的策略,因此他们递归策略的选择也不同于我在说的他们的策略。

Mar*_*Liu 7

git merge -s recursive -X ours Y第 30 行会Print("bye");出现在合并的输出中吗?

不,它也会输出Print("hello");. 这是因为只有另一端(Y分支)改变了这个文件,M分支上的文件版本与其祖先相同B,所以递归合并策略保持Y分支的更新版本。

您可以尝试:只有来自M分支的文件版本与其祖先不同B(例如提交更改 30 行 as Print(“bye1”);),然后-X选项可以工作。现在,如果您使用 git merge -s recursive -X ours Y,则输出将为Print(“bye1”);.

并且您还可以在您链接文章的图 4中找到,如果文件的一侧与其祖先相同(如第 30 行和第 70 行),则该文件将保留另一侧(更改后的)版本作为合并结果。

git merge -s ours Y输出原因Print("bye");:

正如文档所说, 这可以解析任意数量的头,但合并的结果树始终是当前分支头的树,有效地忽略了所有其他分支的所有更改

这意味着它将忽略来自Y分支的版本,并且只保留当前分支的版本。所以你得到的输出是Mbranch的版本Print("bye");

为什么没有git merge -s theirsfor -s 选项:

Git 只定义了octupusoursrecursiveresolvesubtree的合并策略,所以-s theirs无法识别,这是一个设计问题。详细原因,可能只有 git 版本控制系统开发人员知道。


对于您的情况(确保development分支覆盖master分支),您可以cherry-pick使用-X theirs选项从开发分支到主分支的最新提交:

# On master branch
git cherry-pick development -X theirs
Run Code Online (Sandbox Code Playgroud)

这将完全覆盖master分支。

注意: development ingit cherry-pick命令表示development分支指向的提交(分支上的最新提交development)。您也可以改用 commit sha-1 值。


归档时间:

查看次数:

5840 次

最近记录:

8 年,3 月 前