(Git合并)何时使用“我们的"策略,“我们的"选项和“他们的"选项? [英] (Git Merging) When to use 'ours' strategy, 'ours' option and 'theirs' option?
问题描述
这只能使用3向合并算法解析两个磁头.当有一个以上的公共祖先可用于三向合并时,它将创建一个公共祖先的合并树,并将其用作三向合并的参考树.据报道,通过对来自Linux 2.6内核开发历史记录的实际合并提交进行的测试,可以减少合并冲突,而不会引起合并错误.此外,这可以检测和处理涉及重命名的合并.这是拉出或合并一个分支时的默认合并策略.
递归策略可以采用以下选项:
如上所述,递归策略是默认策略,它使用三向递归合并算法(解释为维基百科).
我的理解是冲突的大块必须手动解决,并且通常以这种方式表示
<<<<<<<<<<<
developer 1's code here
============
developer 2's code here
>>>>>>>>>>>
递归合并策略的我们的选项记录如下:
此选项通过支持 our 版本来强制自动解决冲突的块.与其他树不冲突的更改会反映到合并结果中.对于二进制文件,全部内容都是从我们这边获取的.
这不应与 ours 合并策略混淆,后者甚至根本不会查看另一棵树包含的内容.它丢弃另一棵树所做的所有操作,声明我们的历史记录包含其中发生的所有事件.
现在假设我有两个分支Y和M的首部,并且具有相同的基本祖先B
当使用默认递归策略合并Y和M时,第30行将变为Print("hello");
,因为在第30行,Y表示从基本祖先开始的更改,而M则不是.但是如果我在M分支上并运行
git merge -s recursive -X ours Y
第30行在合并后的输出中会变成Print("bye");
吗?
对于那些说这很明显的人,请注意我们的选项指出
此选项通过支持 our 版本来强制自动解决冲突的帅哥.
但是(据我所知),第30行没有冲突的块.
为完整起见,我还将提供其选项的文档:
这与我们的相反.
我们的策略的文档如下:
这可以解析任意数量的head,但是合并的结果树始终是当前分支head的树,从而有效地忽略了所有其他分支的所有更改.它旨在取代侧支的旧开发历史.请注意,这与递归合并策略的-Xours选项不同.
如果我跑了,回到上面的例子
git merge -s ours Y
上,很明显,合并后的输出中的第30行是Print("bye");
.在这种情况下,为什么还没有他们的策略?如何实现与我们的策略相同和相反的行为?
之所以问,是因为我正在开发一个项目,无论何时成功构建开发分支上的代码,我都想用另一个开发分支上的更改定期并完全覆盖master分支.这样,我可以确保开发分支永远不会偏离master分支,并且确保master分支上的代码将成功构建.
我看过这个问题建议使用递归策略的其选项.但是,由于递归策略的我们的选项与我们的策略明显不同,因此, 递归策略与我所说的他们的策略不同.
git merge -s recursive -X ours Y
将第30行变成 合并的输出?
否,它还会输出Print("hello");
.这是因为只有另一端(Y
分支)更改了此文件,M
分支上的文件版本与其祖先B
相同,因此,递归合并策略将更新的版本保留为Y
分支.>
您可以尝试:只有M
分支中的文件版本不同于其祖先B
(例如,将30行更改为Print(bye1);
的提交),然后-X
选项才可以使用.现在,如果您使用git merge -s recursive -X ours Y
,则输出将为Print(bye1);
.
您还可以在
如文件所述,
这可以解析任意数量的head,但是合并的结果树始终是当前分支head的树,有效地忽略了所有其他分支的所有更改. 这意味着它将忽略 为什么-s选项没有 Git仅使用 octupus ,我们的,递归,解决和子树定义了合并策略,因此 根据您的情况(确保 这将完全覆盖 注意: Definition of recursive merge strategy pulled from the git merge documentation. 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: As stated, the recursive strategy, which is the default strategy, makes use of the 3-way recursive merge algorithm (explained here and on Wikipedia). My understanding is that conflicting hunks must be manually resolved and they are typically represented like this The ours option of the recursive merge strategy is documented as follows: 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. Now suppose I have the heads of two branches Y and M, with a common base ancestor B as follows When merging Y and M using the default recursive strategy, line 30 will become will line 30 become To those of you who say that this is obvious, note that the ours option states This option forces conflicting hunks to be auto-resolved cleanly by favoring our version. But (as I understand) there is no conflicting hunk at line 30. For completeness, I will also give the documentation of the theirs option: This is the opposite of ours.
The documentation for the ours strategy is as follows: 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. So returning to the example above, if I ran on branch M, it is clear that line 30 will be I'm asking because I'm working on a project where I want to regularly and completely overwrite the master branch with changes from another development branch, whenever the code on the development branch builds successfully. This way I can ensure that my development branch never drifts too far off from the master branch and also that the code on the master branch will build successfully. I have seen this question which recommends the solution But Git simply outputs My current solution is to do I have also seen this question which recommends using the theirs option of the recursive strategy. But as the ours option of the recursive strategy is clearly different ours strategy, so too would the theirs option of the recursive strategy be different from the theirs strategy that I'm talking about. No, it will also output And you can have try: only the file’s version from And you can also find in Figure 4 of the article you linked, if one side of the file is same as their ancestor (as line 30 and 70), the file will keep the other side (changed) version as the merge results. Reason for As the document said,
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. That means it will ignore the version from Why there is no Git only defined the merge strategies with octupus, ours, recursive, resolve and subtree, so the For your situation (make sure This will fully overwrite Note: 这篇关于(Git合并)何时使用“我们的"策略,“我们的"选项和“他们的"选项?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!Y
分支的版本,而仅保留当前分支的版本.因此,您得到的输出为M
分支Print("bye");
的版本.
git merge -s theirs
:-s theirs
无法识别,这是一个设计问题.出于详细原因,只有git版本控制系统开发人员可能知道.
development
分支覆盖master
分支),您可以使用 -X theirs
cherry-pick
从开发分支到主分支的最新提交 strong>选项:# On master branch
git cherry-pick development -X theirs
master
分支.git cherry-pick
命令中的development
表示development
分支指向的提交(development
分支上的最新提交).您也可以改用commit sha-1值.
<<<<<<<<<<<
developer 1's code here
============
developer 2's code here
>>>>>>>>>>>
Print("hello");
since at line 30, Y represents a change from the base ancestor and M does not. But if I were on branch M and rungit merge -s recursive -X ours Y
Print("bye");
in the merged output?
git merge -s ours Y
Print("bye");
in the merged output. In this case, why is there also not a theirs strategy? How can I achieve behaviour equal and opposite to the ours strategy?git checkout dev-branch
git merge -s ours master
Already up-to-date
, despite the fact that the two branches contain different code (and dev-branch
is actually a few commits ahead of master
).git merge -s recursive -X theirs dev-branch
git merge -s recursive -X ours Y
will line 30 become Print("bye");
in
the merged output?Print("hello");
. This is because only the other side (Y
branch) changed this file, file version on M
branch is the same as their ancestor B
, so recursive merge strategy keep the updated version from Y
branch.M
branch is different from their ancestor B
(such as commit for changing 30 line as Print("bye1");
), then the -X
options can works. Now if you use git merge -s recursive -X ours Y
, the output will be Print("bye1");
.
git merge -s ours Y
output Print("bye");:Y
branch and only keep the version as current branch is. So you got the output as the version of M
branch Print("bye");
.
git merge -s theirs
for -s option:-s theirs
can’t be recognized and it’s a design issue. For the detail reason, only the git version control system developers may know.
development
branch overwrite master
branch), you can cherry-pick
the latest commit from development branch to master branch with -X theirs
option:# On master branch
git cherry-pick development -X theirs
master
branch.development
in git cherry-pick
command means the commit which development
branch is point to (latest commit on development
branch). You can also use commit sha-1 value instead.