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

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

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

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


当前回答

请参阅Junio Hamano被广泛引用的答案:如果您要丢弃已提交的内容,那么只需丢弃提交,或者无论如何要将其排除在主历史记录之外。将来为什么要麻烦每个人从没有提供任何东西的提交中读取提交消息呢?

但有时会有管理要求,或者其他原因。对于那些你真的必须记录没有贡献的提交的情况,你想要:

(编辑:哇,我以前错了吗?这个是可行的。)

git update-ref HEAD $(
        git commit-tree -m 'completely superseding with branchB content' \
                        -p HEAD -p branchB    branchB:
)
git reset --hard

其他回答

我解决了我的问题

git checkout -m old
git checkout -b new B
git merge -s ours old

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

git pull --strategy=theirs remote_branch

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

git fetch origin
git reset --hard origin

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

为什么它不存在?

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

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

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

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

我觉得你真正想要的是

git checkout -B mergeBranch branchB
git merge -s ours branchA
git checkout branchA
git merge mergeBranch
git branch -D mergeBranch

这看起来很笨拙,但应该有用。我唯一不喜欢这个解决方案的是git的历史会令人困惑…但至少历史记录将被完全保存,您不需要为删除的文件做什么特别的事情。