我的提交树看起来像
---A---B---C master
\
D-----E dev
我想将E合并到master上,以便领先的主提交看起来像完全像E :
---A---B--C--F master
\ /
D-----E dev
所以F应与E完全相同。
我做的是:
> git checkout master
> git merge -X theirs E
生成的F没有错误消息,但 E和F 之间存在一些差异。它们并不完全相同,就像我需要它们一样。
我知道我可以手动合并并修复差异。但是,1)我确实需要E来完全覆盖C和2)我不能把它搞砸了,所以一些自动的方法比手工操作要好得多。
我做错了什么?我需要做些什么不同的事情?
更新:
> git merge -X theirs dev
也没有帮助。结果相同。
答案 0 :(得分:2)
首先,请注意:您想要的结果是“邪恶合并”的一个例子,它可能会导致某些问题。如果这是你需要的,那就是你需要的;但请注意,在某些rebase
操作(以及其他可能的操作)中,可能会错误地解释其结果与默认值不同的合并(尤其是当默认值不冲突时)。
那说:有一些混乱,因为默认合并策略采用-X
参数“我们的”或“他们的”告诉它如何解决冲突;但这并没有改变合并操作从双方采取非冲突的变化。更令人困惑的是, 也是一种名为“我们的”的合并策略,完全忽略了其他分支的变化 - 但没有相应的“他们的”策略。
所以你可以做一些事情。一种选择是
git checkout dev
git merge -s ours master
git checkout master
git merge dev
(您希望最后一次合并是快进;默认情况下会是这样,但如果您的设置更改了默认设置,则可能需要--ff
选项。)
这与将dev
合并到master
并不完全相同,因为父母会被逆转;但如果这对你没关系,那么这可能是最简单的方法。
另一种选择是手动编辑合并。
git checkout master
git merge --no-commit dev
现在,您需要使工作树和索引看起来像提交E
。我想是
git checkout dev -- .
git clean
当然,您可以使用git diff
进行验证。
这种方法使父母的顺序保持“合理预期” - 但不要忘记,它仍然是一个邪恶的合并。
答案 1 :(得分:2)
-s theirs
不存在但有几种替代品。请参阅此问题的其他答案,搜索StackOverflow以及" git合并策略他们的",和/或仔细阅读Is there a "theirs" version of "git merge -s ours"? (因为原来的querent实际上正在寻找{ {1}},我在下面介绍过)。或者使用以下相当神奇的sh / bash脚本代码:
-X theirs
将您想要的提交消息放入文件git merge --ff-only $(git commit-tree -p HEAD -p dev dev^{tree} -F /tmp/commitmsg)
之后。 请确保这是您想要做的事情,因为它几乎从未如此。
/tmp/commitmsg
(扩展参数)-X
和ours
并不意味着使用我们的版本或使用他们的版本。他们的意思是 ,当发生冲突 时,请使用我们的更改或使用他们的更改。
在您的示例中,theirs
的提示是提交master
,而C
的提示是提交dev
。因此,如果当前分支为E
,则当前提交为master
。此时无论您是将名称C
或提交dev
的哈希ID - 传递给E
都无关紧要:两者都选择提交git merge
作为提交合并
在任何情况下,提交E
都是合并基础,因为同时从A
和C
向后追溯到它们遇到的第一个点,到达提交{{1} }。
因此,E
将:
A
针对提交git merge
:这是当前分支中发生的变化,即A
。C
反对提交ours
:这是 A
中发生的变化。假设在所有三次提交中,其中一个文件名为E
。在提交theirs
中,我们找到了一些关于猫的线条和一些关于大象的线条。还有更多的线条(关于土豚,蝙蝠,狗,雀,沙鼠,仓鼠,鬣蜥,长耳鹦鹉等等 - 对于字母表中的每一个字母来说都是如此!)但我们现在会专注于猫和大象。 ..还有Shrews,它们是共享的。
在提交animals.txt
与A
相比,对猫有新的或不同的主张。因此,从C
到A
的差异显示了关于猫(C)的这种变化。 Shrews也有变化:
A
在提交C
与$ git diff <hash-of-A> <hash-of-C>
...
@@ ... @@
blah blah
-something about Cats
+something different about Cats
blah blah
@@ ... @@
etc
-the Shrew flies through the air, carefree
+the Shrew swims the ocean, carefree
etc
相比,有关于大象的新的或不同的主张。所以E
- 到 - A
的差异显示了关于大象的这种变化。对Shrews有一个不同的,冲突的更改 - 我们将省略除此之外的所有内容:
A
当Git进入合并这些更改时,它会从E
- 到 - @@ ... @@
etc
-the Shrew flies through the air, carefree
+the Shrew eats rhinos, though it causes indigestion
etc
获取对Cats的更改,并从{{1}更改为大象} -to - A
。 这些更改不会发生冲突,因此组合它们没有问题。但它也会看到关于泼妇谎言的变化,而这些变化冲突并且不能合并。
C
选项指示Git选择冲突的一方或另一方因为这里存在冲突,Git需要帮助解决合并问题。默认情况下,Git只声明&#34;存在冲突&#34;,将两个更改写入工作树,并停止冲突,让您自己清理混乱。 (幕后有很多工作可以帮助你解决冲突,但现在这些都不重要。)
使用其中一个A
选项,Git被告知选择我们的,或者选择他们的,然后继续前进。但是此仅影响冲突的更改。 Git仍会照常组合非冲突的更改:在上面的示例中,无论您选择哪个E
,Git都会同时进行Cat和Elephant更改,而-X
只会选择将Shrew更改为挑
有一个名为-X
的Git合并策略,调用为-X
,与-X
选项非常不同。这个策略告诉Git不要为了合并基础而烦恼,只是为了保持源代码树免受&#34;我们的&#34;承诺。 Git将完成合并提交,之后根本不做任何工作来产生合适的合并。效果是&#34;杀掉&#34;另一个分支,同时保留其提交;这允许你删除其他分支名称,保留提交,以防你想在某个时候查看它们,同时声明你打算永远不再使用它们(但显然不是很确定:-))。 / p>
如果ours
存在,它会做同样的事情,除非它会&#34;杀掉&#34; 当前分支支持新分支。有时你可能想要这个,当它们出现时,如果Git有git merge -s ours
可能会很好,但无论出于什么原因,它只有-X ours
。
替换工作,git merge -s theirs
的技巧允许你使用附加到任何现有提交的任意现有源树将任意多次提交绑定在一起 - 因此它涵盖了git merge -s theirs
(使用{{1} }}和git merge -s ours
。生成的提交对象没有名称,但是git commit-tree
提交的直接后代,因此-s ours
会将其添加到当前分支。
答案 2 :(得分:1)
-X theirs
的git merge
选项告诉它在使用默认策略(-s recursive
)时如何解决合并冲突。可以合并清洁的更改不受影响。合并的文件将包含在两个分支上运行的更改。
ours
strategy可用于创建合并提交,忽略合并分支上的更改。为了使var numbers = {
x: 'hi',
y: 'dawd',
z: 'ohgroe',
};
function calc({x = "", y = "", z = ""} = {}) {
return x + y + z;
}
console.log(calc(numbers));
看起来与F
相同,您必须将E
合并到master
中,但这不是您要求的。
您的请求的可能解决方案(我没有对其进行测试)可能是这样的:
--no-commit
选项;这样,Git准备合并提交,但让你审查(并可能改变)它; dev
提交中的repo状态; 命令是:
E