如何在 git 中使用新的 SHA 创建提交?

How can I create a commit with a new SHA in git?

我需要在 Git 中创建一个具有不同 SHA 的等效提交对象。所有提交都经过 GPG 签名。我知道我可以更改作者 + 提交时间戳,但分辨率只有一秒钟,而且我们不允许偏离系统时钟超过一秒钟。我也无法更改提交消息、作者/提交者姓名和电子邮件和/或用于签署提交的密钥。我可以更改提交的哪些其他字段以获得不同的提交消息?


动机:我们正在使用一个内部工具,如果两个属性引用同一个提交,由于某种原因该工具不起作用,即使我们是有意设置它也是如此。

问题的技术答案是这样的:

哈希数据包括:

  • a header 你无法控制(也就是说,在任何情况下,都是从我即将提到的其他数据中得出的)
  • 提交的 TREE object 哈希 - 提交内容的反映
  • parentCOMMITobject(s) 散列(es)
  • 作者姓名、电子邮件、时间戳
  • 提交者姓名、电子邮件、时间戳
  • 提交消息

改变 TREE 可能会扩展 "equivalent" 提交的定义。您已明确排除更改提交消息或作者/提交者信息的可能性。剩下的选项是提交 parent 列表,但是谈论它是否有意义取决于你在做什么。

由于选项有限,让我们快速浏览一下其中的每一个(即使是那些似乎被排除在外的选项):

TREE object:这唯一地表示内容 - 即您将在工作树中的什么路径的什么文件中看到什么数据。乍一看,这似乎是满足"equivalent commit"最基本定义必须不变的东西。当然,任何更改——无论多小,无论在工作树中的哪个位置——都会更改哈希值,因此也许您可以嵌入一个专门针对随机数值的文件或目录来改变哈希值?

作者或提交者信息:首先要考虑的是:不触及姓名的要求有多敏感?你能不能在名字的末尾贴一个不可见的字符就可以了,还是必须匹配 bit-for-bit?

或者,那些时间戳...说你不能改变系统时钟,当提交时间戳被定义为指代提交创建时间时,除非你试图创建几个等效的提交,否则看起来很迂腐一次全部。即使你同时需要两个,你也应该能够在不超过你的承受能力的情况下做到这一点。

Commit Message:再说一次,不更改这个的要求有多严格?你能用一个换行符,或者至少一个不可见的字符吗?

Parent 提交:如果以上所有内容您仍处于困境,那么剩下的就是这些。这真的归结为,for 的提交是什么?重复提交是否会具有相同的 parent?

P -- A
 \
  A'

在那种情况下,你真的不能在这里做任何事情。但或者,如果它是平行的提交树:

P -- A

P' -- A'

好吧,那么您需要做的就是为每棵树播种一个在某些方面有所不同的根提交。提交消息,例如 "Root commit 1"、"Root commit 2"、...?