当使用git merge将主题分支“B”合并为“A”时,我得到了一些冲突。我知道所有的冲突都可以用B的版本解决。

我知道git合并是我们的。但我想要的是类似git merge -s的东西。

为什么它不存在?如何在与现有git命令冲突合并后实现相同的结果?(git从B中检出所有未合并的文件)

仅仅丢弃分支A中的任何东西(合并提交点到树的B版本)的“解决方案”不是我想要的。


当前回答

旧版本的git允许你使用“their”合并策略:

git pull --strategy=theirs remote_branch

但是这已经被删除了,正如Junio Hamano (Git维护者)在这条消息中解释的那样。正如链接中提到的,相反,你会这样做:

git fetch origin
git reset --hard origin

但是要注意,这与实际的合并不同。你的解决方案可能就是你真正在寻找的选项。

其他回答

如果你在分支A上,请:

git merge -s recursive -X theirs B

在git版本1.7.8上测试

这个答案是由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 their A”通过运行:

git checkout B (optional, just making sure we're on branch B)
git mergetheirs A

为什么它不存在?

虽然我在“git命令使一个分支像另一个分支一样”中提到了如何模拟git合并-s,但请注意,git 2.15(2017年Q4)现在更清晰了:

用于合并的'-X<option>'的文档具有误导性 写的是“-s their”的存在,但事实并非如此。

参见Junio C Hamano (gitster)的commit c25d98b(2017年9月25日)。 (由Junio C Hamano—gitster—在commit 4da3e23,2017年9月28日合并)

合并策略:避免暗示“-s their”的存在 -Xours合并选项的说明有一个插入说明 这告诉读者,它与我们的-s非常不同, 这是正确的,但是后面的- xtheir的描述 不小心说“这是我们的相反”,给了一个错误 这种印象也需要提醒读者,它是非常的 不同于他们的-s,而后者在现实中根本不存在。

xtheir是一个应用于递归策略的策略选项。这意味着递归策略仍然会合并任何它可以合并的东西,并且只会在发生冲突时退回到“他们的”逻辑。

关于他们合并战略的相关性的争论最近在2017年9月的帖子中被重新提起。 它承认旧线程(2008年)

简而言之,前面的讨论可以总结为“我们不想要‘-s their’,因为它鼓励错误的工作流程”。

它提到了别名:

mtheirs = !sh -c 'git merge -s ours --no-commit $1 && git read-tree -m -u $1' -

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.

正如Mike Beaton所评论的那样,Junio补充道:

Git merge -s ours <their-ref>有效地说“标记提交构成<their-ref>在他们的分支作为提交被永久忽略”; 这很重要,因为如果您随后从分支的后面的状态合并,它们后面的更改将被引入,而不会引入被忽略的更改。

旧版本的git允许你使用“their”合并策略:

git pull --strategy=theirs remote_branch

但是这已经被删除了,正如Junio Hamano (Git维护者)在这条消息中解释的那样。正如链接中提到的,相反,你会这样做:

git fetch origin
git reset --hard origin

但是要注意,这与实际的合并不同。你的解决方案可能就是你真正在寻找的选项。

这一个使用了git管道命令读树,但是使得整个工作流程更短。

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>