合并既不保留也不不保留提交 ID。合并使new提交(假设您以避免“快进”操作的方式执行这些操作)。
也就是说,给定一系列单独的提交,我将用单个字母标记:
A - B - C
\
D
commit C
(这可能真的是 ID6da748a...
)已提交B
它的父级,并提交D
(也许实际上740c281...
)也有提交B
作为其父级。要合并这两个提交,git 必须创建一个新的提交two父母:
A - B - C - M
\ /
D
这个新的提交M
与其他提交有不同的 ID,但提交D
完全没有改变,因此仍然具有相同的 ID (740c281...
).
许多人试图避免进行这种相对琐碎的合并。而不是拿走他们的工作(提交C
)和你的工作(提交D
)并进行新的合并提交,他们会复制您的提交消息(包括作者和日期)并进行相同的更改C
你所做的B
。这个操作确实被称为“cherry pick”(也称为“rebasing”),但它会产生一个新的、不同的提交,我们可以称之为D'
,使用新的、不同的提交 ID:
A - B - C - D'
和原来的最明显的区别D
和这个新的D'
就是它D'
已提交C
作为其父级,而不是提交B
。 (在正常情况下,它也有不同的树内容,因为您的B
-to-D
更改已应用于版本中所示的文件C
,在某些地方可能与B
.)
Commit D'
不是一个merge然而,请承诺。 (合并提交是具有至少两个父提交的任何提交。使用git log --graph
or gitk
或其他一些图形查看器可以更直接地查看提交图。)
如果您的工作被重新定位(或精心挑选)到上游,并且您获取并尝试合并上游,git 有时(但并非总是)能够检测到重复并自动清理。当它无法自动检测重复时,您几乎总是会遇到各种合并冲突:git 看到您试图更改一些代码(在您的提交中)D
在上面的例子中),他们试图改变相同的代码,但以稍微不同的方式(在他们的提交中)D'
在上面)。出于这个原因,通常不认为对别人的代码进行变基是非常礼貌的:相反,上游往往会要求您自己对代码进行变基(尽管它仍然是您私有的),然后他们可以将其作为“快进”(合并-免费)添加到他们的存储库中。
(这样您还可以自己进行变基操作所需的任何更改。例如,如果您修复了版本中的错误D
他们也固定在他们的C
,但是你和他们采取了不同的方法,你可以解决这个冲突——可能比他们更容易,因为你知道你做了什么,为什么这样做,以及你的新功能是否依赖于your修复版本。)