是否有“他们的”版本的“git merge -s ours”?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/173919/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there a "theirs" version of "git merge -s ours"?
提问by elmarco
When merging topic branch "B" into "A" using git merge
, I get some conflicts. I know all the conflicts can be solved using the version in "B".
使用 将主题分支“B”合并到“A”时git merge
,我遇到了一些冲突。我知道使用“B”中的版本可以解决所有冲突。
I am aware of git merge -s ours
. But what I want is something like git merge -s theirs
.
我知道git merge -s ours
. 但我想要的是类似的东西git merge -s theirs
。
Why doesn't it exist? How can I achieve the same result after the conflicting merge with existing git
commands? (git checkout
every unmerged file from B)
为什么不存在?与现有git
命令发生冲突合并后如何获得相同的结果?(git checkout
来自 B 的每个未合并的文件)
UPDATE: The "solution" of just discarding anything from branch A (the merge commit point to B version of the tree) is not what I am looking for.
更新:从分支 A(树的 B 版本的合并提交点)丢弃任何内容的“解决方案”不是我正在寻找的。
回答by Alan W. Smith
Add the -X
option to theirs
. For example:
将-X
选项添加到theirs
. 例如:
git checkout branchA
git merge -X theirs branchB
Everything will merge in the desired way.
一切都会以所需的方式合并。
The only thing I've seen cause problems is if files were deleted from branchB. They show up as conflicts if something other than git did the removal.
我看到的唯一导致问题的是文件是否从 branchB 中删除。如果除 git 之外的其他东西进行了删除,它们会显示为冲突。
The fix is easy. Just run git rm
with the name of any files that were deleted:
修复很容易。只需git rm
使用已删除的任何文件的名称运行:
git rm {DELETED-FILE-NAME}
After that, the -X theirs
should work as expected.
之后,-X theirs
应该按预期工作。
Of course, doing the actual removal with the git rm
command will prevent the conflict from happening in the first place.
当然,使用git rm
命令进行实际删除将首先防止冲突发生。
Note: A longer form option also exists.
注意:还存在更长的形式选项。
To use it, replace:
要使用它,请替换:
-X theirs
with:
和:
--strategy-option=theirs
回答by Paul Pladijs
A possible and tested solution for merging branchB into our checked-out branchA:
将 branchB 合并到我们已检出的 branchA 中的可能且经过测试的解决方案:
# in case branchA is not our current branch
git checkout branchA
# make merge commit but without conflicts!!
# the contents of 'ours' will be discarded later
git merge -s ours branchB
# make temporary branch to merged commit
git branch branchTEMP
# get contents of working tree and index to the one of branchB
git reset --hard branchB
# reset to our merged commit but
# keep contents of working tree and index
git reset --soft branchTEMP
# change the contents of the merged commit
# with the contents of branchB
git commit --amend
# get rid off our temporary branch
git branch -D branchTEMP
# verify that the merge commit contains only contents of branchB
git diff HEAD branchB
To automate it you can wrap it into a script using branchA and branchB as arguments.
要自动化它,您可以使用 branchA 和 branchB 作为参数将其包装到脚本中。
This solution preserves the first and second parent of the merge commit, just as you would expect of git merge -s theirs branchB
.
该解决方案保留了合并提交的第一个和第二个父项,正如您对git merge -s theirs branchB
.
回答by Pat Notz
Older versions of git allowed you to use the "theirs" merge strategy:
旧版本的 git 允许您使用“他们的”合并策略:
git pull --strategy=theirs remote_branch
But this has since been removed, as explained in this message by Junio Hamano(the Git maintainer). As noted in the link, instead you would do this:
但这已被删除,正如Junio Hamano(Git 维护者)在此消息中所解释的那样。如链接中所述,您可以这样做:
git fetch origin
git reset --hard origin
Beware, though, that this is different than an actual merge. Your solution is probably the option you're really looking for.
但是请注意,这与实际合并不同。您的解决方案可能是您真正正在寻找的选项。
回答by siegi
It is not entirely clear what your desired outcome is, so there is some confusion about the "correct" way of doing it in the answers and their comments. I try to give an overview and see the following three options:
并不完全清楚您想要的结果是什么,因此在答案和他们的评论中对“正确”的做法有些困惑。我尝试给出一个概述并看到以下三个选项:
Try merge and use B for conflicts
尝试合并并使用 B 解决冲突
This is notthe "theirs version for git merge -s ours
" but the "theirs version for git merge -X ours
" (which is short for git merge -s recursive -X ours
):
这不是“他们的”版本,git merge -s ours
而是“他们的”版本git merge -X ours
(是 的缩写git merge -s recursive -X ours
):
git checkout branchA
# also uses -s recursive implicitly
git merge -X theirs branchB
This is what e.g. Alan W. Smith's answerdoes.
这就是例如Alan W. Smith 的回答所做的。
Use content from B only
仅使用来自 B 的内容
This creates a merge commit for both branches but discards all changes from branchA
and only keeps the contents from branchB
.
这会为两个分支创建一个合并提交,但会丢弃branchA
来自branchB
.
# Get the content you want to keep.
# If you want to keep branchB at the current commit, you can add --detached,
# else it will be advanced to the merge commit in the next step.
git checkout branchB
# Do the merge an keep current (our) content from branchB we just checked out.
git merge -s ours branchA
# Set branchA to current commit and check it out.
git checkout -B branchA
Note that the merge commits first parent now is that from branchB
and only the second is from branchA
. This is what e.g. Gandalf458's answerdoes.
请注意,合并提交的第一个父级现在是 frombranchB
并且只有第二个是 from branchA
。这就是例如Gandalf458 的回答所做的。
Use content from B only and keep correct parent order
仅使用来自 B 的内容并保持正确的父顺序
This is the real "theirs version for git merge -s ours
". It has the same content as in the option before (i.e. only that from branchB
) but the order of parents is correct, i.e. the first parent comes from branchA
and the second from branchB
.
这是真正的“他们的版本git merge -s ours
”。它与之前的选项具有相同的内容(即只有 from branchB
),但父母的顺序是正确的,即第一个父母来自,branchA
第二个来自branchB
。
git checkout branchA
# Do a merge commit. The content of this commit does not matter,
# so use a strategy that never fails.
# Note: This advances branchA.
git merge -s ours branchB
# Change working tree and index to desired content.
# --detach ensures branchB will not move when doing the reset in the next step.
git checkout --detach branchB
# Move HEAD to branchA without changing contents of working tree and index.
git reset --soft branchA
# 'attach' HEAD to branchA.
# This ensures branchA will move when doing 'commit --amend'.
git checkout branchA
# Change content of merge commit to current index (i.e. content of branchB).
git commit --amend -C HEAD
This is what Paul Pladijs's answerdoes (without requiring a temporary branch).
这就是Paul Pladijs 的回答(不需要临时分支)。
回答by musicmatze
I used the answer from Paul Pladijs since now. I found out, you can do a "normal" merge, conflicts occur, so you do
从现在开始,我使用了 Paul Pladijs 的答案。我发现,您可以进行“正常”合并,但会发生冲突,因此您可以
git checkout --theirs <file>
to resolve the conflict by using the revision from the other branch. If you do this for each file, you have the same behaviour as you would expect from
通过使用来自另一个分支的修订来解决冲突。如果对每个文件都执行此操作,您将获得与预期相同的行为
git merge <branch> -s theirs
Anyway, the effort is more than it would be with the merge-strategy! (This was tested with git version 1.8.0)
无论如何,工作量比合并策略要多!(这是用 git 版本 1.8.0 测试的)
回答by elmarco
I solved my problem using
我解决了我的问题
git checkout -m old
git checkout -b new B
git merge -s ours old
回答by Gandalf458
When merging topic branch "B" in "A" using git merge, I get some conflicts. I >know all the conflicts can be solved using the version in "B".
I am aware of git merge -s ours. But what I want is something like git merge >-s their.
使用 git merge 合并“A”中的主题分支“B”时,我遇到了一些冲突。我>知道使用“B”中的版本可以解决所有冲突。
我知道 git merge -s 我们的。但我想要的是 git merge >-s 他们的东西。
I'm assuming that you created a branch off of master and now want to merge back into master, overriding any of the old stuff in master. That's exactly what I wanted to do when I came across this post.
我假设您从 master 创建了一个分支,现在想要合并回 master,覆盖 master 中的任何旧内容。当我看到这篇文章时,这正是我想做的。
Do exactly what it is you want to do, Except merge the one branch into the other first. I just did this, and it worked great.
做你想做的事情,除了先把一个分支合并到另一个分支。我就是这样做的,而且效果很好。
git checkout Branch
git merge master -s ours
Then, checkout master and merge your branch in it (it will go smoothly now):
然后,结帐 master 并将您的分支合并到其中(现在会顺利进行):
git checkout master
git merge Branch
回答by rafalmag
If you are on branch A do:
如果您在分支 A 上,请执行以下操作:
git merge -s recursive -X theirs B
Tested on git version 1.7.8
在 git 版本 1.7.8 上测试
回答by thoutbeckers
To really properly do a merge which takes onlyinput from the branch you are merging you can do
要真正正确地进行合并,该合并仅从您正在合并的分支中获取输入,您可以这样做
git merge --strategy=ours ref-to-be-merged
git merge --strategy=ours ref-to-be-merged
git diff --binary ref-to-be-merged | git apply --reverse --index
git diff --binary ref-to-be-merged | git apply --reverse --index
git commit --amend
git commit --amend
There will be no conflicts in any scenario I know of, you don't have to make additional branches, and it acts like a normal merge commit.
在我所知道的任何情况下都不会有冲突,您不必创建额外的分支,它的作用就像一个正常的合并提交。
This doesn't play nice with submodules however.
然而,这对子模块并不友好。
回答by VonC
Why doesn't it exist?
为什么不存在?
While I mention in "git command for making one branch like another" how to simulate git merge -s theirs
, note that Git 2.15 (Q4 2017) is now clearer:
虽然我在“用于使一个分支像另一个分支一样的 git 命令”中提到如何模拟git merge -s theirs
,但请注意 Git 2.15(2017 年第 4 季度)现在更加清晰:
The documentation for '
-X<option>
' for merges was misleadingly written to suggest that "-s theirs
" exists, which is not the case.
-X<option>
用于合并的' '文档被误导地编写,以表明“-s theirs
”存在,但事实并非如此。
See commit c25d98b(25 Sep 2017) by Junio C Hamano (gitster
).
(Merged by Junio C Hamano -- gitster
--in commit 4da3e23, 28 Sep 2017)
请参阅Junio C Hamano() 的commit c25d98b(2017 年 9 月 25 日)。(由Junio C Hamano合并-- --在2017 年 9 月 28 日提交 4da3e23 中)gitster
gitster
merge-strategies: avoid implying that "
-s theirs
" existsThe description of
-Xours
merge option has a parenthetical note that tells the readers that it is very different from-s ours
, which is correct, but the description of-Xtheirs
that follows it carelessly says "this is the opposite ofours
", giving a false impression that the readers also need to be warned that it is very different from-s theirs
, which in reality does not even exist.
合并策略:避免暗示“
-s theirs
”存在
-Xours
合并选项的描述有一个括号,告诉读者它与 非常不同-s ours
,这是正确的,但它后面的描述-Xtheirs
粗心大意地说“这是相反的ours
”,给人一种错误的印象,读者也需要需要注意的是-s theirs
,它与现实中甚至不存在的非常不同。
-Xtheirs
is a strategy optionapplied to recursive strategy. This means that recursive strategy will still merge anything it can, and will only fall back to "theirs
" logic in case of conflicts.
-Xtheirs
是应用于递归策略的策略选项。这意味着递归策略仍然会合并它可以合并的任何东西,并且只会theirs
在发生冲突时回退到“ ”逻辑。
That debate for the pertinence or not of a theirs
merge strategy was brought back recently in this Sept. 2017 thread.
It acknowledges older (2008) threads
theirs
最近在 2017 年 9 月的帖子中重新讨论了合并策略的相关性与否。
它确认较旧的(2008)线程
In short, the previous discussion can be summarized to "we don't want '
-s theirs
' as it encourages the wrong workflow".
简而言之,前面的讨论可以总结为“我们不想要 '
-s theirs
',因为它鼓励错误的工作流程”。
It mentions the alias:
它提到了别名:
mtheirs = !sh -c 'git merge -s ours --no-commit && git read-tree -m -u ' -
Yaroslav Halchenko tries to advocate once more for that strategy, but Junio C. Hamano adds:
Yaroslav Halchenko 试图再次倡导该策略,但 Junio C. Hamano 补充道:
The reason why ours and theirs are not symmetric is because you are you and not them---the control and ownership of our history and their history is not symmetric.
Once you decide that their history is the mainline, you'd rather want to treat your line of development as a side branch and make a merge in that direction, i.e. the first parent of the resulting merge is a commit on their history and the second parent is the last bad one of your history. So you would end up using "
checkout their-history && merge -s ours your-history
" to keep the first-parenthood sensible.And at that point, use of "
-s ours
" is no longer a workaround for lack of "-s theirs
".
It is a proper part of the desired semantics, i.e. from the point of view of the surviving canonical history line, you want to preserve what it did, nullifying what the other line of history did.
我们的和他们的不对称的原因是因为你是你而不是他们——我们的历史和他们的历史的控制和所有权是不对称的。
一旦你决定他们的历史是主线,你宁愿把你的开发线当作一个分支并在那个方向上进行合并,即结果合并的第一个父级是他们历史上的提交,第二个是提交父母是你历史上最后一个坏人。所以你最终会使用“
checkout their-history && merge -s ours your-history
”来保持第一父母身份的合理性。那时,使用“
-s ours
”不再是缺少“-s theirs
”的解决方法。
它是所需语义的适当部分,即从幸存的规范历史线的角度来看,您希望保留它所做的事情,使另一条历史线所做的事情无效。
Junio adds, as commented by Mike Beaton:
Junio 补充道,正如Mike Beaton所评论的:
git merge -s ours <their-ref>
effectively says 'mark commits made up to<their-ref>
on their branch as commits to be permanently ignored';
and this matters because, if you subsequently merge from later states of their branch, their later changes will be brought in without the ignored changes ever being brought in.
git merge -s ours <their-ref>
有效地表示“将<their-ref>
其分支上的提交标记为永久忽略的提交”;
这很重要,因为如果您随后从其分支的后续状态合并,则将引入他们以后的更改,而不会引入被忽略的更改。