让我们假设存储库看起来像这样:
master
|
A--B--C--K--L--M
\
E-F-G
|\
| H-I-J
topicA |
topicB
git merge topicB
时master
会做什么?它是否仅适用于提交H
,I
和J
?或者从topicA
的初始叉点开始的所有提交?
git rebase master topicA
会做什么?它会导致这个:
master
|
A--B--C--K--L--M
\
E'-F'-G'
|\
| H'-I'-J'
topicA |
topicB
还是更像这样的东西?
master
|
A--B--C--K--L--M
\ \
\ E'-F'-G'
\ |
\ topicA
\
E-F-G-H-I-J
|
topicB
答案 0 :(得分:2)
除了解析分支名称以提交ID之外,合并或重新关注任何分支标签所指向的位置。他们只查看提交图。
我认为,git merge
的工作方式更容易理解。除了保存默认合并提交消息的分支名称外,git merge
只使用git rev-parse
来查找提交ID。
对于第一个问题,在分支git merge topicB
上给定master
时,git会找到三个提交ID:
HEAD
解析为提交M
(分支master
上的提示最多提交;这也是您在运行git rev-parse HEAD
时看到的提交ID。)topicB
解析为提交J
(分支topicB
上的提示最多提交;这也是您在运行git rev-parse topicB
时看到的提交ID。)C
。找到合并基础后,git会运行两个git diff
:一个在merge-base和HEAD
提交之间(看看你的分支“做了什么),另一个在合并之间base和topicB
提交(查看“他们的分支”做了什么)。它结合了两组更改,如果没有冲突(或者如果它可以通过git rerere
解决它们),则进行一个新的提交,其中两个父项按此顺序 - 当前HEAD
提交,以及topicB
提交。使新提交像往常一样更新当前分支,以便HEAD
现在指向新提交(或更准确地说,HEAD
仍然指向master
和master
点到新的提交)。
这个问题:
它只适用于提交H,I和J吗?或者来自topicA的初始分支点的所有提交?
暗示了对git的合并算法的基本误解:git不会查看中间提交的任何。它仅查看此处标识的三个提交:M
,J
和C
。 Git可以像这样“作弊”,因为每个提交在提交的源树内容方面是完全独立的。
Rebase更复杂(你在上面的第二次猜测中已经做到了,但无论如何我们都要经历它。)
它仍然使用相同的“通过git rev-parse
”技巧解析分支名称到ID,但它使用更复杂的git rev-list
变体。 git rev-list
所做的是在提交图上计算集合操作(一旦它实际进入图形本身,再次忽略任何标签)。
鉴于git rebase master topicA
,我们(好吧,我无论如何:-))首先要检查the rebase
documentation,我们发现master
被视为< upstream> 参数和topicA
被视为&lt; branch&gt; 参数,并且它对最后一个参数的所有操作都是{{1}首先,然后继续进行,就像你没有提供它一样。因此,在精神上,我们可以假设您从git checkout <branch>
开始,然后运行git checkout topicA
。 &lt; upstream&gt; 参数为git rebase master
,master
表示分支HEAD
,因此它标识提交topicA
。
过去,在G
git rebase
之前,更容易确定接下来会发生什么。今天,根据文档,您必须确定是否启用了--fork-point
。因为你 提供了一个实际的&lt; upstream&gt; 参数,所以它默认是禁用的:只有在命令行中给出--fork-point
时才会启用它。你没有;因此我们不需要深入研究--fork-point
的谜团(哇,呀!:-))。所以,这里发生的是rebase本质上运行--fork-point
来获取要复制的提交列表。这会列出提交git rev-list master..HEAD
,E
和F
,因为这些是G
但不能HEAD
可以访问的集合中的提交。
然后,rebase进程在master
参数给出的提交中分离HEAD
(如果有的话)(没有),或者&lt; upstream&gt; < / em>参数。那是--onto
所以这是提交master
。从这里开始,rebase基本上只是挑选它之前发现的每个提交,这会为您提交M
,E'
和F'
。如果所有这些都能正常工作,那么git对rebase的最后一步是将最初的当前分支(G'
,再次)指向最后一次提交topicA
。没有其他标签更改,因此您可以获得最终的图表。