git rebase -i - 为什么它会改变提交哈希值?

时间:2018-02-05 16:16:16

标签: git rebase

所以我或多或少熟悉变基法的工作原理,但直到最近我才刚刚做了git rebase -i HEAD~20,并修改了需要修改的内容。

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

我不确定是什么原因导致其他18个提交的哈希更改,因为他们的父母既不会改变他们的内容......或者是吗?也许是时间戳?

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

5 个答案:

答案 0 :(得分:4)

来自rebase doc

  

之前保存到临时区域的提交是   然后按顺序逐个重新应用到当前分支

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

您可以详细了解如何计算SHA here

答案 1 :(得分:3)

  

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

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

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

例如,据我所知,当我压缩最后两次提交时会发生什么:

{{1}}

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

答案 2 :(得分:1)

请注意,在Git 2.29(2020年第四季度)之前,Git还可以在todo消息中更改要作为基准的提交的哈希,提交应该更改(因为您正在将旧提交重播到此)。

请参见commit 5da69c0Antti Keränen (Detegr)(2020年8月13日)。
(由Junio C Hamano -- gitster --commit 4499a42中合并,2020年8月19日)

rebase -i:将待办事项的哈希值修正为错误

创始人:JussiKeränen
签名人:AnttiKeränen
Acked-by:阿尔班·格鲁因(Alban Gruin)

todo_list_write_to_file”可能会覆盖源自“ find_unique_abbrev”的静态缓冲区,该静态缓冲区用于存储“ c”的短提交哈希“ # Rebase a..b onto c”消息在待办事项编辑器中。

这是因为从“ find_unique_abbrev”返回的缓冲区是有效的,直到对find_unique_abbrev进行了另外4次调用。

由于'todo_list_write_to_file'为每个重新提交的提交调用'find_unique_abbrev',因此如果重新提交中有4个或更多提交,则'c'的哈希将被覆盖。
自引入以来,这种行为已被破坏。

在调用“ todo_list_write_to_file”之前,通过将提交到提交哈希的缩写存储在另一个仍然有效的缓冲区中来解决此问题。

答案 3 :(得分:0)

您可能会觉得自己没有更改某些提交,但实际上您已经通过多种方式对其进行了更改:

  • 每个提交都包含其父项的sha1。因此,更改父级的sha1会修改提交,因此会修改其sha1。哈希被束缚,改变过去的任何事物都会改变未来。从技术上讲,这被称为Merkle tree。这是Git的一个重要属性,因为给定一个sha1,它不仅保证了当前提交的完整性,而且保证了导致它的整个历史(假设你在sha1中找不到碰撞,which is no longer really the case today,但是碰撞仍然很难找到。)

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

  • 如前所述,提交包含时间戳(作者的一个时间戳,一个用于提交者的时间戳,第二个用于重新定义时更改)。

答案 4 :(得分:-1)

这是因为当您在HEAD中重新定义当前交互式提交之前的20个节点时,您将从HEAD 20提交前的节点开始并重新应用后续的20次提交,就好像它们一样。新的,可以选择进行更改。即使您只更改(压缩)提交-20和-19,您仍然会重新应用后续的18次提交,就好像他们是新的提交一样。您没有为这18个提交重复使用相同的节点,您正在复制其内容,但是将新的内容添加到您的重新设置的HEAD中。

关于变基的git书:

  

再次记住,这是一个rebasing命令 - 包括每个提交   在HEAD~3 ...... HEAD范围内将被重写,无论你改变了   消息与否。