Git如何在历史记录中对提交进行签名?

5
在互联网的许多部分(例如这里),暗示必须在提交git时签名,否则就不需要签名。
然而,从技术上讲,提交的签名实际上就是对提交对象的签名(如此处所示),该对象由“tree”文件的哈希值(即git对象哈希值列表)、父级哈希值和一些元数据组成。
因此,似乎没有什么可以阻止提交后面签署,而无需重写整个历史记录。
真的可能吗? 有推荐的操作方式吗?这样的事后签名能够很好地与推送和拉取配合使用吗?
2个回答

2

我不相信你可以在不重写历史记录的情况下完成这个任务。我刚才为了进行测试,克隆了同一个代码库两次。我在两个代码库中都做了相同的更改,然后使用相同的日志信息(“foobar”)提交了更改,唯一的区别就是其中一个签名了,而另一个没有。

# unsigned test
parent 50c6dd65f1d7a240cf6b5c9585ce363ef4708d1e
new    b3ff731922f80a417b84ed492537c1f7ba74715e

# signed test
parent 50c6dd65f1d7a240cf6b5c9585ce363ef4708d1e
new    688b3be2e55558c45b00b6a6c02086a03768e02d

正如您所看到的,从相同的父级 (50c6dd65) 开始,结果是两个不同的提交哈希。因此对于未推送的提交,它与任何其他历史记录重写没有区别(因此具有相同的责任)。

回答您的评论,问哈希值是否仅因时间戳差异而更改,我不这样认为。如果您使用 cat-file 进行检查:

$ git cat-file -p 688b3be2e55558c45b00b6a6c02086a03768e02d
tree 074e53e54670dea3502229e9494f3d571f5dcc16
parent 50c6dd65f1d7a240cf6b5c9585ce363ef4708d1e
author Dan Lowe <dan@XXXXXXXX.com> 1448768563 -0500
committer Dan Lowe <dan@XXXXXXXX.com> 1448768563 -0500
gpgsig -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1

 iQEVAwUAVlp0N1rGfrtJ2k+kAQIbYQf7BLx3/jqU/vwvoJOcbq5MPK0ok7B8mOaF
 VWhNCbAeOBMzXdrn8IQxY2xYcPsy+d6pNx6ZOF70L3VZm6rWFxNzZQRrjS4ByOAM
 VyoL8bXceMcrb/sQUHM5yTCaDcfoYx40K0q91XsGew2EIzNKcOraK1Ee4hEtPg1D
 ojyPVjiWz2qMJJ0YYAATSvWwlKFO2ShTC6tGZDHrx0e6BAEN5QS4KdGhNech/vpU
 IPFDjIKWtGPTbYY8Z95vKLAMYWPZDJ8j/x1gRytN8PDjRufRtpRnZMccB6JQoXNZ
 5L23WQFfUFeXRdWf0MtkrbrSwzuaaIF8l1oGYnEtYT6nOIktPT47Fw==
 =/U9b
 -----END PGP SIGNATURE-----

foobar

据我理解,这些元数据都是哈希算法输入的一部分,最终形成提交 ID。如果是这样的话,这里存在 gpgsig 数据意味着它将始终给出与未签名版本不同的哈希值。

我刚刚在一个仓库中运行了 git cat-file -p [提交哈希值] 命令,发现时间戳似乎包含在提交内容中(以及时区)。你的测试是否包括这个事实,或者你看到的哈希值变化是由于两次测试之间时间戳的改变导致的可能性? - Ekleog
@Ekleog 我更新了我的答案,展示了 cat-file 的输出和我对其含义的分析。 - Dan Lowe
记录一下,git/commit.c文件的1566和1569行(提交编号2635c2b8bfc9aec07b7f023d8e3b3d02df715344中的commit_tree_extended函数)似乎验证了这种观点。谢谢! - Ekleog

1
每个git对象都由自己的SHA-1哈希标识。因此它们都是不可变的。
如果您签署了之前完成的提交,则实际上是以签名方式复制该提交。因此原始提交仍然存在-如果您记得其哈希或具有任何引用指向它,则甚至可以使用git show查看它。您要做的是创建一个新的提交,其中包含等效的更改和元数据,但添加了签名,并使您当前所在的分支-即当前分支-指向它。
提交的树和其他所有依赖对象将保持不变。但是,由于提交本身已更改,因此您将获得一个新的提交对象-因此您正在重写历史记录。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接