合并后提交 ID 是否保持不变?

kmd*_*hrm 8 git bitbucket git-merge

我的团队使用 git 和 Bitbucket 进行版本控制。

我之前创建了一个从我的存储库分支之一到团队主存储库分支之一的拉取请求。

这个拉取请求被接受,我的分支被合并了。

昨天我在我的存储库中的同一个分支中添加了一些更改。当我尝试向团队存储库上的同一分支创建拉取请求时,我收到了一些合并冲突的通知。

我查看了团队分支的提交日志,发现虽然提交信息、作者(我)和日期相同,但远程分支中的提交ID不同。

这里可能有什么问题?

我的印象是,即使在合并提交 ID 被保留之后。

可能是其他原因导致这种情况吗?

PS我读过cherry-pick可以更改提交ID。有什么想法吗?

tor*_*rek 6

合并既不保留也不不保留提交 ID。合并进行新的提交(假设您以一种避免“快进”操作的方式执行它们,无论如何)。

也就是说,给定一系列单独的提交,我将用单个字母标记这些提交:

A - B - C
      \
        D
Run Code Online (Sandbox Code Playgroud)

commit C(可能真的是 ID 6da748a...)已经提交了B它的父级,并且 commit D(也许实际上740c281...)也有 commitB作为它的父级。要合并这两个提交,git 必须创建一个具有两个父项的新提交:

A - B - C - M
      \   /
        D
Run Code Online (Sandbox Code Playgroud)

这个新提交M与其他所有提交都有不同的 ID,但提交D完全没有改变,因此仍然具有相同的 ID ( 740c281...)。

许多人试图避免进行这种相对简单的合并。他们不会拿走他们的工作 (commit C) 和您的工作 (commit D) 并进行新的合并提交,而是复制您的提交消息(包括作者和日期),并对C您所做的更改进行相同的更改B。这个操作确实被称为“樱桃采摘”(也称为“rebase”),但它D'使用新的、不同的提交 ID进行了一个新的、不同的提交,我们可能称之为:

A - B - C - D'
Run Code Online (Sandbox Code Playgroud)

您的原始文件D和新文件之间最明显的区别D'D'commitC作为其父项,而不是 commit B。(在正常情况下,它也有不同的树内容,因为您的B-to-D更改已应用于文件,如 version 中所见,C在某些地方可能与 中的文件不同B。)

但是,提交D'不是合并提交。(合并提交是具有至少两个父提交的任何提交。使用git log --graphgitk或其他一些图形查看器更直接地查看提交图。)

如果您的工作被重新定位(或挑选)到上游,并且您获取然后尝试合并上游,git 有时(但并非总是)能够检测到重复并自动清理。当它无法自动检测重复时,您几乎总是会遇到各种合并冲突:git 看到您尝试更改某些代码(在D上面示例中的提交中),并且他们尝试更改相同的代码,但略有不同方式(在D'上面的提交中)。出于这个原因,对别人的代码进行 rebase 通常不被认为是非常礼貌的:相反,上游倾向于要求您自己对代码进行 rebase(虽然它仍然对您是私有的),然后他们可以将其包含为“快进”(合并-免费)添加到他们的存储库中。

(通过这种方式,您也可以自己进行变基操作所需的任何更改。例如,如果您修复了版本D中的一个错误,他们也在他们的 中修复了错误C,但是您和他们采取了不同的方法,您可以解决这个冲突——可能更多比他们更容易,因为您知道自己做了什么以及为什么这样做,以及您的新功能是否取决于的修复版本。)