使用 reflog 撤消 git 变基时,选择哪个提交有关系吗?

When undoing a git rebase with reflog, does it matter which commit you choose?

在尝试变基之前,我知道我的功能分支 (GL18) 的提交 (b7104e0) 是什么,但变基很糟糕。我正在查看 Eclipse 中的 Git Reflog,它多次列出提交 b7104e0。我想将 GL18 的头部重置回 b7104e0。我在 reflog 中选择要重置的 b7104e0 提交是否重要,还是完全相同?

git 哈希是使用提交消息、提交作者、提交日期、树哈希和所有父提交哈希计算的,请参阅 this blog post on the anatomy of a Git commit 了解详细信息。

这意味着您看到的每个具有相同哈希值的提交都是完全相同的提交。您可以使用其中任何一个。事实上,如果你重置,你重置为提交哈希:git reset --hard b7104e0.

不——但为了清楚起见,因为标题和 body 文字乍一看似乎提出了不同的问题,让我们在这里明确说明:

  • 任何提交(或 git 中的任何存储库 object)的 "true name" 是其 SHA-1,在本例中以 b7104e0(但继续另外 33 个字符)。这个 true-name 唯一标识了 object。它可以缩写为更短的内容,就像在这种情况下一样,只要更短的版本保持唯一即可。

  • 所有其他名称,例如分支名称、标签、非常特殊的 ref HEAD、稍微不那么特殊(但仍然很特殊)的 ORIG_HEADMERGE_HEAD, CHERRY_PICK_HEAD, 等等,以及 (finally :-) ) 像 HEAD@{3}<em>branchname</em>@{1},只是表达 "true name" SHA-1 ID 的方式。当使用 git checkout 或重写引用名称的命令时,此规则有一个特殊的豁免,但通常,名称或引用日志条目只解析为 ID。许多名称可能会解析为一个 ID,或者可能只有一个名称会解析为一个 ID,但通常这些名称确实会解析为 ID。1

一旦您拥有正确的 ID,您是如何获得它的并不重要。


1只是为了完整性:很明显,如果我们要更改名称的目标 SHA-1 ID,例如,要移动分支或将新值写入 CHERRY_PICK_HEAD,我们需要名称,而不是其当前 ID。我们需要名称的另一个地方是在使用 indirect ("symbolic") 引用时,例如当 HEAD names ref: refs/heads/master 时,您on branch master 正如 git status 所说。

我们还有一种特殊情况,其中名称无法解析为任何 SHA-1 ID,这就是 "branch yet to be born" 一种情况,这在完全没有提交的新存储库中最常见:在此在这种情况下,您在分支 master 上,但是 refs/heads/master 无法解析为提交 ID,因为还没有提交。如果您使用 git checkout --orphan 创建一个(尚未)指向任何 SHA-1 的新分支(它将在下一次提交时获取其初始 SHA-1),这种特殊情况可能会在以后再次出现。在这两个奇怪的案例中,HEAD 引用存在,但命名了一个分支,字面意思是 不存在 (还)。