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

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

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

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


当前回答

这并不一定能回答最初发帖者的问题,但我在这里遇到的情况是,我已经尝试了合并,但最终发生了冲突。通常我在IDE中管理冲突,但当我无法访问时,可以使用以下REGEX来查找并替换“their”内容的差异:

Replce <<<<<<< HEAD\n[^•>]+\n==========\n([^•>]+)>>>>>>> .+\n with \1

(以防其他人因为和我一样的原因登陆这个页面)。

其他回答

为什么它不存在?

虽然我在“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>在他们的分支作为提交被永久忽略”; 这很重要,因为如果您随后从分支的后面的状态合并,它们后面的更改将被引入,而不会引入被忽略的更改。

这将合并现有的baseBranch中的newBranch

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 -m old
git checkout -b new B
git merge -s ours old

一个简单而直观的(在我看来)两步方法是

git checkout branchB .
git commit -m "Picked up the content from branchB"

紧随其后的是

git merge -s ours branchB

(将两个分支标记为合并)

唯一的缺点是它不能从当前分支中删除branchB中已删除的文件。然后,两个分支之间的简单区别将显示是否存在这样的文件。

这种方法还可以从之后的修订日志中清楚地看出所做的工作以及意图。

等价于'git merge -s their branchB'(保持父顺序)

在合并之前:

! !确保你处于清洁状态!!

进行合并:

git commit-tree -m "take theirs" -p HEAD -p branchB 'branchB^{tree}'
git reset --hard 36daf519952 # is the output of the prev command

我们做了什么? 我们创建了一个新的提交,它的两个父节点是我们的和他们的,提交的连接是他们的分支b

合并后:

更准确地说应该是:

git commit-tree -m "take theirs" -p HEAD -p 'SOURCE^{commit}' 'SOURCE^{tree}'