当使用主题分支"B"合并到"A"时git merge
,我会遇到一些冲突.我知道使用"B"中的版本可以解决所有冲突.
我知道git merge -s ours
.但我想要的是类似的东西git merge -s theirs
.
它为什么不存在?在与现有git
命令冲突合并后,如何获得相同的结果?(git checkout
来自B的每个未合并文件)
更新:从分支A(合并提交点到树的B版本)丢弃任何东西的"解决方案"不是我想要的.
添加-X
选项theirs
.例如:
git checkout branchA git merge -X theirs branchB
一切都会以理想的方式融合.
我唯一看到的问题是文件是否从branchB中删除.如果除了git之外的其他东西都被删除,它们就会显示为冲突.
修复很容易.只需git rm
使用已删除的任何文件的名称运行:
git rm {DELETED-FILE-NAME}
在那之后,-X theirs
应该按预期工作.
当然,使用git rm
命令进行实际删除可以防止冲突首先发生.
注意:还存在更长的表单选项.要使用它,请替换:
-X theirs
有:
--strategy-option=theirs
一种可行且经过测试的解决方案,用于将branchB合并到我们的签出分支A中:
# 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
要自动化它,您可以使用branchA和branchB作为参数将其包装到脚本中.
此解决方案保留了合并提交的第一个和第二个父级,就像您期望的那样git merge -s theirs branchB
.
较旧版本的git允许您使用"他们的"合并策略:
git pull --strategy=theirs remote_branch
但是这已被删除,正如Junio Hamano(Git维护者)在此消息中所解释的那样.如链接中所述,您可以这样做:
git fetch origin git reset --hard origin
但要注意,这与实际合并不同.您的解决方案可能是您真正想要的选择.
我从现在开始使用Paul Pladijs的答案.我发现,你可以做一个"正常"合并,发生冲突,所以你这样做
git checkout --theirs
通过使用来自其他分支的修订来解决冲突.如果对每个文件执行此操作,则会产生与预期相同的行为
git merge-s theirs
无论如何,努力比合并策略更多!(这是用git版本1.8.0测试的)
目前还不完全清楚你期望的结果是什么,所以对于在答案和评论中这样做的"正确"方式存在一些困惑.我尝试概述并查看以下三个选项:
尝试合并并使用B进行冲突
这不是 "他们的版本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
这就是Alan W. Smith的回答.
仅使用B中的内容
这将为两个分支创建合并提交,但会丢弃所有更改,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
请注意,现在合并提交第一个父级是来自branchB
且仅来自第二个父级branchA
.这就是Gandalf458的答案.
仅使用B中的内容并保持正确的父订单
这是真正的"他们的版本git merge -s ours
".它具有与之前选项相同的内容(即仅来自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
这就是Paul Pladijs的回答(不需要临时分支).
我解决了我的问题
git checkout -m old git checkout -b new B git merge -s ours old
如果你在分支A上做:
git merge -s recursive -X theirs B
测试了git版本1.7.8
当使用git merge在"A"中合并主题分支"B"时,我会遇到一些冲突.我>知道使用"B"中的版本可以解决所有冲突.
我知道git merge-是我们的.但我想要的是像git merge> -s他们的东西.
我假设你创建了一个master的分支,现在想要合并回master,覆盖master中的任何旧东西.当我遇到这篇文章时,这正是我想要做的.
完全按照你想做的去做,除了首先将一个分支合并到另一个分支.我刚刚这样做了,效果很好.
git checkout Branch git merge master -s ours
然后,结帐主人并合并你的分支(它现在将顺利):
git checkout master git merge Branch
要真正正确地执行合并,只需要合并您正在合并的分支的输入即可
git merge --strategy=ours ref-to-be-merged
git diff --binary ref-to-be-merged | git apply --reverse --index
git commit --amend
在我知道的任何场景中都不会发生冲突,您不必进行额外的分支,它就像普通的合并提交一样.
但是,这对子模块不起作用.
请参见Junio Hamano广为引用的答案:如果您要丢弃已提交的内容,请丢弃已提交的内容,或者至少将其保留在主要历史记录之外。为什么将来要打扰每个人都从没有提供内容的提交中读取提交消息?
但是有时存在管理要求,或者可能还有其他原因。对于那些确实必须记录不起作用的提交的情况,您需要:
(编辑:哇,我以前设法弄错了吗。这个有效。)
git update-ref HEAD $( git commit-tree -m 'completely superseding with branchB content' \ -p HEAD -p branchB branchB: ) git reset --hard
为什么不存在?
虽然我在“ git命令使一个分支像另一个分支 ”中提到了如何模拟git merge -s theirs
,但请注意,Git 2.15(2017年第四季度)现在更加清晰:
-X
误写了“ ”用于合并的文档以表明-s theirs
存在“ ”,事实并非如此。
参见Junio C Hamano()提交的commit c25d98b(25 Sep 2017 )。(通过合并JUNIOÇ滨野- -在提交4da3e23,2017年9月28日)gitster
gitster
合并策略:避免暗示“
-s theirs
”存在
-Xours
合并选项的描述带有括号,告诉读者它与完全不同-s ours
,这是正确的,但-Xtheirs
随后的描述却粗心地说“这与ours
” 相反,给读者以错误的印象请注意,它与根本不同-s theirs
,实际上甚至不存在。
-Xtheirs
是应用于递归策略的策略选项。这意味着递归策略仍将合并所有可能的内容,并且仅theirs
在发生冲突时才退回到逻辑上。
有关theirs
合并策略是否相关的争论最近在2017年9月的这个话题中引起了人们的注意。
它承认较旧的(2008)线程
简而言之,前面的讨论可以总结为“我们不希望'
-s theirs
',因为它会鼓励错误的工作流程”。
它提到了别名:
mtheirs = !sh -c 'git merge -s ours --no-commit $1 && git read-tree -m -u $1' -
雅罗斯拉夫·哈尔琴科(Yaroslav Halchenko)再次尝试倡导该策略,但Junio C. Hamano补充说:
我们和他们之所以不对称的原因是因为你是你而不是他们-我们历史及其历史的控制和所有权不是对称的。
一旦确定他们的历史是主线,您就希望将您的开发线视为分支,并在该方向上进行合并,即,产生的合并的第一个父项是对他们的历史的提交,第二个父母是您历史上的最后一个坏人。因此,您最终将使用“
checkout their-history && merge -s ours your-history
”来保持初婚年龄。在这一点上,使用“
-s ours
”不再是缺少“-s theirs
” 的解决方法。
它是所需语义的适当部分,即,从尚存的规范历史路线的角度来看,您想要保留它所做的事情,而使其他历史路线所做的事情无效。
Junio补充说,正如Mike Beaton所说:
git merge -s ours
有效地说:“标记提交在其分支上被弥补为永久忽略的提交”;
这很重要,因为如果您随后从其分支的较后状态进行合并,则将引入其较后的更改,而不会引入被忽略的更改。