gpt4 book ai didi

git - (Git Merging) 何时使用 'ours' 策略、 'ours' 选项和 'theirs' 选项?

转载 作者:太空狗 更新时间:2023-10-29 13:12:36 25 4
gpt4 key购买 nike

git merge documentation 中提取的递归 merge 策略的定义.

This can only resolve two heads using a 3-way merge algorithm. When there is more than one common ancestor that can be used for 3-way merge, it creates a merged tree of the common ancestors and uses that as the reference tree for the 3-way merge. This has been reported to result in fewer merge conflicts without causing mismerges by tests done on actual merge commits taken from Linux 2.6 kernel development history. Additionally this can detect and handle merges involving renames. This is the default merge strategy when pulling or merging one branch.

The recursive strategy can take the following options:

如前所述,递归策略是默认策略,它使用三向递归 merge 算法(解释 hereWikipedia)。

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

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

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

This option forces conflicting hunks to be auto-resolved cleanly by favoring our version. Changes from the other tree that do not conflict with our side are reflected to the merge result. For a binary file, the entire contents are taken from our side.

This should not be confused with the ours merge strategy, which does not even look at what the other tree contains at all. It discards everything the other tree did, declaring our history contains all that happened in it.

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

enter image description here

当使用默认递归策略 merge Y 和 M 时,第 30 行将变为 Print("hello");,因为在第 30 行,Y 表示对基祖先的更改,而 M 没有。但是如果我在分支 M 上运行

git merge -s recursive -X ours Y

第 30 行会在 merge 后的输出中变成 Print("bye"); 吗?

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

This option forces conflicting hunks to be auto-resolved cleanly by favoring our version.

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

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

This is the opposite of ours.


我们的策略的文档如下:

This resolves any number of heads, but the resulting tree of the merge is always that of the current branch head, effectively ignoring all changes from all other branches. It is meant to be used to supersede old development history of side branches. Note that this is different from the -Xours option to the recursive merge strategy.

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

git merge -s ours Y

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

我问这个问题是因为我正在做一个项目,只要开发分支上的代码成功构建,我就希望使用另一个开发分支的更改定期并完全覆盖 master 分支。这样我就可以确保我的开发分支永远不会偏离 master 分支太远,而且 master 分支上的代码将成功构建。

我看过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建议使用递归 策略的他们的 选项。但是由于递归策略的我们的选项与我们的策略明显不同,因此他们的选项也是如此递归 策略与我正在谈论的他们的 策略不同。

最佳答案

git merge -s recursive -X ours Y will line 30 become Print("bye"); in the merged output?

不,它还会输出Print("hello");。这是因为只有对方(Y 分支)改变了这个文件,M 分支上的文件版本与它们的祖先B 相同,所以递归 merge 策略保留 Y 分支的更新版本。

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

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

Reason for git merge -s ours Y output Print("bye");:

正如文件所说,这解决了任意数量的头,但 merge 的结果树始终是当前分支头的树,有效地忽略所有其他分支的所有更改

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

Why there is no git merge -s theirs for -s option:

Git 只定义了octupusoursrecursiveresolvesubtree 的 merge 策略,因此无法识别 -s theirs,这是一个设计问题。具体原因,可能只有git版本控制系统的开发者才知道。


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

# On master branch
git cherry-pick development -X theirs

这将完全覆盖 master 分支。

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

关于git - (Git Merging) 何时使用 'ours' 策略、 'ours' 选项和 'theirs' 选项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45402742/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com