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

时间:2017-07-30 17:35:43

标签: git github version-control merge

git merge documentation拉出的递归合并策略的定义。

  

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

     

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

如上所述,递归策略是默认策略,它使用3向递归合并算法(解释hereWikipedia)。

我的理解是,必须手动解决冲突的帅哥,它们通常表示为

<<<<<<<<<<<
developer 1's code here
============
developer 2's code here
>>>>>>>>>>>

递归合并策略的我们的选项记录如下:

  

此选项可以通过支持我们的版本来强制自动解决冲突的帅哥。来自与我们方不冲突的其他树的更改将反映到合并结果中。对于二进制文件,整个内容都来自我们这边。

     

这不应该与我们的合并策略混淆,后者甚至不会查看其他树包含的内容。它会丢弃其他树所做的一切,声明我们的历史包含其中发生的所有事情。

现在假设我有两个分支Y和M的头部,共同的基础祖先B如下

enter image description here

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

git merge -s recursive -X ours Y

第30行将在合并输出中成为Print("bye");吗?

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

  

此选项可以通过支持我们的版本来强制自动解析冲突的帅哥

但是(据我所知)第30行没有冲突的大块头。

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

  

这与我们的相反。

我们的策略的文档如下:

  

这解决了任意数量的头,但是合并的结果树始终是当前分支头的树,实际上忽略了来自所有其他分支的所有更改。它旨在用于取代侧枝的旧发展历史。请注意,这与递归合并策略的-Xours选项不同。

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

git merge -s ours Y

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

我正在问,因为我正在开发一个项目,我想定期完全覆盖主分支,只要开发分支上的代码成功构建,就可以使用其他开发分支的更改。这样我就可以确保我的开发分支从不偏离主分支太远,并且主分支上的代码也将成功构建。

我见过this question推荐解决方案

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

我还看到this question建议使用递归策略的他们的选项。但由于递归策略的我们的选项明显不同我们的策略,所以他们的选项也是如此递归策略与我所说的他们的策略不同。

1 个答案:

答案 0 :(得分:3)

  

git merge -s recursive -X ours Y第30行将成为Print("bye");   合并输出?

不,它也会输出Print("hello");。这是因为只有另一方(Y分支)更改了此文件,M分支上的文件版本与其祖先B相同,因此递归合并策略保留更新版本{ {1}}分支。

您可以尝试:只有Y分支中的文件版本与其祖先M不同(例如将30行更改为B),然后是{{ 1}}选项可以工作。现在,如果您使用Print(“bye1”);,则输出将为-X

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

  

git merge -s recursive -X ours Y输出打印的原因(&#34;再见&#34;);

正如文件所说, 这会解析任意数量的头,但合并的结果树始终是当前分支头的树,实际上忽略来自所有其他分支的所有更改

这意味着它将忽略来自Print(“bye1”);分支的版本,并且只保留当前分支的版本。因此,您将输出作为git merge -s ours Y分支Y的版本。

  

为什么没有M for -s选项:

Git仅使用 octupus 我们的递归解决子树定义了合并策略,因此Print("bye");无法识别,这是一个设计问题。由于详细原因,只有git版本控制系统开发人员可能知道。

根据您的情况(确保git merge -s theirs分支覆盖-s theirs分支),您可以 development 从开发分支到主分支的最新提交 master 选项:

cherry-pick

这将完全覆盖-X theirs分支。

注意:# On master branch git cherry-pick development -X theirs 命令中的 master表示development分支指向的提交(git cherry-pick分支上的最新提交)。您也可以使用commit sha-1值。