题
将主题分支“B”合并到“A”时使用 git merge
, ,我遇到一些冲突。我知道所有的冲突都可以使用“B”中的版本来解决。
我知道 git merge -s ours
. 。但我想要的是类似的东西 git merge -s theirs
.
为什么它不存在?与现有的冲突合并后如何获得相同的结果 git
命令?(git checkout
B 中每个未合并的文件)
更新:只是丢弃分支 A 中的任何内容(树的 B 版本的合并提交点)的“解决方案”不是我正在寻找的。
解决方案
将 -X
选项添加到他们的
。例如:
git checkout branchA
git merge -X theirs branchB
所有东西都会以所需的方式合并。
我见过的唯一问题是文件是否从branchB中删除。如果git之外的其他东西都被删除,它们就会显示为冲突。
修复很简单。只需使用已删除的文件的名称运行 git rm
:
git rm {DELETED-FILE-NAME}
之后, -X他们的
应该按预期工作。
当然,使用 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 the branchB
。
较旧版本的git允许您使用“他们的”合并策略:
git pull --strategy=theirs remote_branch
但此后已被删除,如 Junio Hamano 在此消息中所述(Git维护者)。如链接中所述,您可以这样做:
git fetch origin
git reset --hard origin
请注意,这与实际合并不同。您的解决方案可能是您真正想要的选择。
我从现在开始使用Paul Pladijs的答案。我发现,你可以做一个“正常”的事情。合并,冲突发生,所以你做
git checkout --theirs <file>
通过使用其他分支的修订来解决冲突。如果对每个文件执行此操作,则会产生与
相同的行为git merge <branch> -s theirs
无论如何,努力比合并策略更多! (这是使用git版本1.8.0测试的)
目前还不完全清楚你期望的结果是什么,所以对于“正确”的结果存在一些混淆。在答案和评论中这样做的方式。我尝试概述并看到以下三个选项:
尝试合并并使用B进行冲突
这是不“ git merge -s our
”的“他们的版本”但是他们的 git merge -X our
&quot; (这是 git merge -s recursive -X our
的缩写):
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 our
&quot;的真实版本。它具有与之前选项相同的内容(即仅来自 branchB
的内容),但父项的顺序是正确的,即第一个父来自 branchA
,第二个来自 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版本上测试
合并主题分支“B”时在“A”中使用git merge,我得到了一些冲突。我&gt;知道所有冲突都可以使用“B”中的版本来解决。
我知道我们的git merge -s。但我想要的是像git merge&gt; -s他们的东西。
我假设你创建了一个master的分支,现在想要合并回master,覆盖master中的任何旧东西。这正是我在遇到这篇文章时想要做的事情。
完全按照你想做的去做,除了先将一个分支合并到另一个分支。我刚刚这样做了,效果很好。
git checkout Branch
git merge master -s ours
然后,结帐主人并将你的分支合并进去(现在会很顺利):
git checkout master
git merge Branch
要真正正确地执行合并,只需要从您正在合并的分支中输入 ,您就可以
git merge --strategy =我们的参与合并
git diff --binary ref-to-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 年第 4 季度)现在更加清晰:
' 的文档
-X<option>
``因为合并被误导地暗示了“-s theirs
”存在,但事实并非如此。
看 提交 c25d98b (2017 年 9 月 25 日) 朱尼奥·C·滨野(gitster
).
(合并于 朱尼奥·C·滨野—— gitster
-- 在 提交 4da3e23, ,2017 年 9 月 28 日)
合并策略:避免暗示“
-s theirs
“存在的描述
-Xours
合并选项的括号说明,告诉读者它与-s ours
,这是正确的,但是-Xtheirs
随之而来的是,粗心地说:“这与ours
“给人一种错误的印象,即读者还需要警告它与-s theirs
, ,实际上根本不存在。
-Xtheirs
是一个 策略选择 应用于递归策略。这意味着递归策略仍然会合并任何它可以合并的东西,并且只会回退到“theirs
“发生冲突时的逻辑。
关于相关性或不相关性的争论 theirs
合并策略最近被带回来 在这个九月2017年主题.
它承认 较旧的 (2008) 线程
简而言之,前面的讨论可以概括为“我们不希望”
-s theirs
’因为它鼓励了错误的工作流程”。
它提到了别名:
mtheirs = !sh -c 'git merge -s ours --no-commit $1 && git read-tree -m -u $1' -
雅罗斯拉夫·哈尔琴科试图再次倡导这一战略, 但朱尼奥·C.滨野补充道:
我们的历史和他们的历史之所以不对称,是因为你是你而不是他们——我们的历史和他们的历史的控制和所有权是不对称的。
一旦你决定他们的历史是主线,你宁愿将你的发展线视为一个侧分支,并朝那个方向进行合并,即生成的合并的第一个父级是对其历史记录的提交,第二个父级是历史记录中最后一个错误的提交。所以你最终会使用“
checkout their-history && merge -s ours your-history
“保持第一父母的明智。那时,使用“
-s ours
“不再是缺乏”的解决方法-s theirs
".
它是所需语义的适当部分,即从幸存的规范历史线的角度来看,你想要保留它所做的事情,取消另一条历史线所做的事情.
这个使用git plumbing命令读取树,但缩短了整体工作流程。
git checkout <base-branch>
git merge --no-commit -s ours <their-branch>
git read-tree -u --reset <their-branch>
git commit
# Check your work!
git diff <their-branch>
这会将你的newBranch合并到现有的baseBranch
中git checkout <baseBranch> // this will checkout baseBranch
git merge -s ours <newBranch> // this will simple merge newBranch in baseBranch
git rm -rf . // this will remove all non references files from baseBranch (deleted in newBranch)
git checkout newBranch -- . //this will replace all conflicted files in baseBranch
我认为你真正想要的是:
git checkout -B mergeBranch branchB
git merge -s ours branchA
git checkout branchA
git merge mergeBranch
git branch -D mergeBranch
这看起来很笨拙,但应该有效。唯一认为我真的不喜欢这个解决方案的是git历史会让人感到困惑......但至少历史记录会完全保留下来,你不需要为删除的文件做些特别的事情。
等效(保留父顺序)为'git merge -s the branchB'
!!!确保你处于干净状态!!!
进行合并:
git commit-tree -m "take theirs" -p HEAD -p branchB 'branchB^{tree}'
git reset --hard 36daf519952 # is the output of the prev command
我们做了什么? 我们创建了一个新的提交,我们和他们的两个父母和他们的提交的contnet是branchB - 他们的
更确切地说:
git commit-tree -m "take theirs" -p HEAD -p 'SOURCE^{commit}' 'SOURCE^{tree}'
Paul Pladijs给出了答案。为了方便,我只是接受了他的命令并制作了一个git别名。
编辑.gitconfig并添加以下内容:
[alias]
mergetheirs = "!git merge -s ours \"$1\" && git branch temp_THEIRS && git reset --hard \"$1\" && git reset --soft temp_THEIRS && git commit --amend && git branch -D temp_THEIRS"
然后你可以“git merge -s他们的A”。通过运行:
git checkout B (optional, just making sure we're on branch B)
git mergetheirs A
我最近需要为两个共享共同历史记录的独立存储库执行此操作。我开始于:
Org/repository1 master
Org/repository2 master
我想要所有的改变 repository2 master
应用于 repository1 master
, ,接受repository2 所做的所有更改。用 git 的话来说,这 应该 是一个称为 -s theirs
但它不存在。要小心,因为 -X theirs
名字就像你想要的那样,但它是 不是 相同(甚至在手册页中也这么说)。
我解决这个问题的方法是去 repository2
并创建一个新分支 repo1-merge
. 。在那个分支里,我跑了 git pull git@gitlab.com:Org/repository1 -s ours
并且它融合得很好,没有任何问题。然后我将其推送到遥控器。
然后我回到 repository1
并创建一个新分支 repo2-merge
. 。在那个分支,我跑 git pull git@gitlab.com:Org/repository2 repo1-merge
这将完成有问题。
最后,您需要在以下位置发出合并请求: repository1
使其成为新的主控,或者只是将其保留为分支。
简单直观(在我看来)两步走的方法是
git checkout branchB .
git commit -m "Picked up the content from branchB"
接着是
git merge -s ours branchB
(将两个分支标记为合并)
唯一的缺点是它不会从当前分支中删除已在branchB中删除的文件。之后两个分支之间的简单差异将显示是否存在任何此类文件。
这种方法也从修订日志中明确了之后所做的事情以及目标是什么。