我正在练习GIT。以下命令之间的区别是什么?
git merge -s ours branch
git merge -s theirs branch
git merge -X ours branch
git merge -X theirs branch
答案 0 :(得分:2)
在我开始回答这个问题之前,请允许我强调,有两个不同的单词都拼写为" merge"。有一个动词形式,合并,这意味着"组合变化"。有一个名词或形容词形式,合并或合并提交,它指的是特定类型的提交。
git merge
命令通常同时执行这两项操作:合并(动词)一些更改,然后使合并(名词)或合并提交(形容词)。不过,Git有许多方法可以使用动词形式的合并。它还允许 git merge
命令省略最终名词形式合并(但我们完全忽略这种情况)。
简短版本是您几乎不需要策略选项-s ours
。
使用-X
(eXtended)选项,您可以告诉Git支持"我们的"或者"他们的"冲突情况下合并的一面 。也就是说,假设文件wallaby.txt
的合并基础版本部分地说:
The Bennett's wallaby is
a variety of the red-necked wallaby.
两个分支提示版本中的一个 - 让我们称之为左侧或本地或--ours
版本 - 说:
The Bennett's wallaby is
a smaller variety of the red-necked wallaby.
另一个分支提示版本,即右侧或远程或其他或--theirs
版本 - 说:< / p>
The Bennett's wallaby,
which is found on Tasmania,
is a variety of the red-necked wallaby.
当我们将基本版本与两个分支提示进行比较时,比较会对相同范围的行进行类似但不完全相同的更改:
$ git diff $base $left
...
The Bennett's wallaby is
-a variety of the red-necked wallaby.
+a smaller variety of the red-necked wallaby.
...
可是:
$ git diff $base $right
...
-The Bennett's wallaby is
-a variety of the red-necked wallaby.
+The Bennett's wallaby,
+which is found on Tasmania,
+is a variety of the red-necked wallaby.
这两个更改发生冲突,您将收到合并冲突。
eXtended -X ours
选项意味着&#34;更喜欢我们的更改&#34;:两个更改发生冲突的地方,完全忽略他们的更改,并我们的 >相反。扩展-X theirs
选项意味着&#34;更喜欢他们的改变&#34;,即忽略我们的。
请注意,无论您喜欢哪种更改,都会丢失一些内容。一个变化提到Bennett的小袋鼠有点小,而其他人提到它是塔斯马尼亚形式。如果你选择一个,你会失去另一个。您可能应该手动组合此更改,而不是让Git选择一方。
-s ours
如果这是仅对文件的更改,则使用-s ours
代替-X ours
不会对此特定文件级合并产生影响:无论哪种方式,我们都会采取&#34;我们的&#34; (左侧)改变,并忽略他们的。但是假设只有他们的版本修复了文件中其他地方的拼写错误:
$ git diff $base $right
...
-walaby
+wallaby
...
在$left
(本地或--ours
)输出中没有类似内容。如果我们使用-X ours
代替-s ours
,我们至少会选择此修复程序。当然,右侧可能会更改添加拼写错误而不是删除它们。 Git不知道或不关心:它的工作是结合变化,而不是决定它们是否有意义,无论是单独的还是组合的!
此外,as Tim Beigeleisen mentioned in a comment above,-s ours
选项甚至不会查看右侧的差异。事实上,它根本没有任何差异!它告诉Git以任何方式进行合并提交而不使用另一方。换句话说,它只记录是一个合并,而不实际进行任何合并。
执行此操作的唯一原因是创建合并的提交图历史记录。正如提交图本身所记录的那样,这个历史决定了你和Git将如何看待&#34;发生了什么事,当你或其他任何人 - 稍后回来看。存在合并提交意味着你和Git会看到合并已经已经采取了所有合并的好部分 - 即使&#34的方法;服用&#34;是忽略一切。已经拿走了所有这些部分,你永远不会再拿它们了:所以-s ours
可以让你去掉#34;一个分支,不仅仅是忽略它,而是记录你故意杀死它的所有历史记录。
Git 不记录合并策略,也不记录任何策略选项。因此,唯一可以判断是否有人使用此类选项的方法就是猜测。如果你遇到一些存储库,里面有一些合并提交,你可以自己重复合并,看看你是否得到了相同的结果。如果你做获得相同的结果,那么进行合并的人可能使用你刚刚使用的完全相同的命令。如果您得到不同的结果,那么执行合并的人可能使用不同的命令或不同的参数集。或者也许他们手动解决了任何冲突!
有关更多背景信息,请让我引用我常年没有进展的事情(因为我有一份工作:-))。
合并的目标很容易理解。一些人或团体,或者甚至只有一个人有两个或更多任务,从一个共同的代码库开始,并进行了一系列的更改。例如,在Marsupial Maker中,当Bob在袋鼠上工作时,Alice可能正在研究袋熊。每个人或团体(甚至只有一个人担任多个角色)在她或他的私人存储库和/或私人分支机构中工作。这两个发展路线 - 即我们在第1章中提到的哲学意义上的分支 - 与这个共同的起点相关。我们不会担心他们如何设法分享他们的提交,但在某些时候,某人 - 可能是Alice或Bob,或者可能是第三人 - 将结合这些变化。组合应该采取两个变化的所有好部分。最简单的组合方法是从同一章执行三向合并。既然我们已经理解了提交图,并且对将旧提交与旧提交进行比较有了一般性的想法,那么现在是时候对Git和Mercurial如何执行合并进行简要的高级分析了。
在第2章中,我们简要地注意到(参见第38页和第45页)任何两个提交的LCA是它们的合并基础。在某些情况下,可能有多个合并基础,但这种情况很少见,我们暂不解决。相反,让我们注意,根据定义,可能是单合并基础不仅仅是 另外两个提交的共同祖先。实际上,它是正确的共同起点:它是从两个头(Mercurial)或分支提示(Git)可以到达的第一个提交我们正在合并。 VCS需要找到合并基础,以找出我们做了什么和他们做了什么。
在Git和Mercurial中,我们通过正常的结帐流程选择我们的两个提交之一。无论我们现在检查了什么提交 - 我们的当前提交 - 参与合并。我们使用一些适当的commit-identifier选择第二次提交,通常是分支名称,但偶尔会有一个哈希ID,或者在Mercurial中,
一个简单的修订版号(或者有时甚至一无所有,并且
VCS为我们解决了这个问题)。这将是“其他”或“他们的”提交。 18 然后我们可以简单地运行git merge otherbranch
或
hg merge otherbranch
。
18 我在这里调用了三个提交 base , current 和 other 。 Git没有针对当前和其他提交的单一,一致的名称。 Mercurial一直称他们为本地和其他提交。我还将两个非基本提交称为合并的 sides 。在几个地方,Git会调用当前的提交我们的,而另一个提交他们的。 然而,我们将在后面看到我们/他们的术语时出现问题,当时我们将讨论挑选和重新定位。