git rebase -i-为什么更改提交哈希?

Áko*_*dra 8 git rebase

因此,我或多或少地熟悉了变基的工作原理,但是直到最近,我通常只做了一个git rebase -i HEAD~20,然后修改了需要修改的地方。

我惊讶地发现这将修改所有20次提交的哈希值,即使我所采取的唯一行动是压倒最后两个提交。

我不确定是什么原因导致其他18次提交的哈希值发生变化,因为他们的父母都没有,他们的内容也没有变化……或者是吗?也许是时间戳记?

还有办法防止这种情况吗?

Jon*_*ink 10

rebase文档

然后将先前保存到临时区域中的提交依次重新应用于当前分支

当提交“重新应用”时,它实际上是在创建一个全新的提交...其内容可能相同,但是它将具有不同的时间戳,这是其SHA生成方式的一部分...因此,新提交将具有新的SHA。

您可以在此处详细了解SHA的计算方式。

  • 这是一个问题-有没有办法防止修改时间戳? (2认同)

Mat*_*Moy 5

你可能觉得你没有改变一些提交,但你实际上在几个方面改变了它们:

  • 每个提交都包含其父项的 sha1。因此,更改父项的 sha1 会修改提交,因此其 sha1。散列是链接在一起的,改变过去的任何事情都会改变未来。从技术上讲,这称为Merkle 树。这是 Git 的一个重要属性,因为给定 sha1,它不仅可以保证当前提交的完整性,还可以保证导致它的整个历史记录的完整性(假设您在 sha1 中找不到冲突,但事实已不再如此)今天,但仍然很难找到碰撞)。

  • 每个提交都包含项目当前状态的快照。因此,即使提交看起来相同,因为它引入了相同的差异,它也可能不对应于项目的相同状态(与相同的树对象)。

  • 如前所述,提交包含时间戳(作者的一个时间戳,提交者的一个时间戳,第二个在您变基时更改)。


jth*_*ill 5

这将修改所有 20 个提交的哈希值,即使我采取的唯一操作是压缩最后两个。

如果“最后两个”是指历史上最近的两次提交,那么不,它不会。

请具体一点,展示您正在查看的实际证据、您获得的待办事项清单以及您执行的清单。特征太不可靠,容易受到非共享上下文的影响。

例如,根据我的理解,当我压缩最后两个提交时会发生什么:

$ git log --oneline --reverse @{u}..
00f53a2 echo >master6
afcef3e echo >master7
1f55c48 echo >master8
c3197a0 echo >master9
d30bb35 (HEAD -> master) echo >master10
$ GIT_SEQUENCE_EDITOR='sed -i 5s/pick/squash/' git rebase -i
[detached HEAD 16dc80d] echo >master9
 Date: Mon Feb 5 09:25:55 2018 -0800
 2 files changed, 2 insertions(+)
 create mode 100644 master10
 create mode 100644 master9
Successfully rebased and updated refs/heads/master.
$ git log --oneline --reverse @{u}..
00f53a2 echo >master6
afcef3e echo >master7
1f55c48 echo >master8
16dc80d (HEAD -> master) echo >master9
$ 
Run Code Online (Sandbox Code Playgroud)

你可以看到最后两个提交被压缩在一起,所有历史没有改变的提交的 id 保持不变。

  • 嗯,那一定是个小故障。 (2认同)