Git 在历史中的某个地方签署提交

Ekl*_*eog 5 git version-control sign git-sign

在 Internet 的许多部分(例如此处)上,暗示 git 提交必须在完成或从不签名。

然而,从技术上讲,提交上的签名只不过是提交对象上的签名(如此处所示,它由“树”文件的哈希值(即 git 对象的哈希值列表)、哈希值组成父级和一些元数据。

因此,似乎没有什么可以阻止事后签署提交,而无需重写整个历史记录。

真的可能吗?有推荐的方法吗?这样的事后签名能很好地处理推拉操作吗?

Dan*_*owe 2

我不相信你能在不重写历史的情况下做到这一点。我刚刚克隆了同一个存储库两次来进行测试。我在两个存储库中进行了相同的更改,然后使用相同的日志消息(“foobar”)提交,唯一的区别是一个已签名,另一个未签名。

# unsigned test
parent 50c6dd65f1d7a240cf6b5c9585ce363ef4708d1e
new    b3ff731922f80a417b84ed492537c1f7ba74715e

# signed test
parent 50c6dd65f1d7a240cf6b5c9585ce363ef4708d1e
new    688b3be2e55558c45b00b6a6c02086a03768e02d
Run Code Online (Sandbox Code Playgroud)

如您所见,从同一个父级 (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
Run Code Online (Sandbox Code Playgroud)

据我了解,这些元数据都是哈希算法输入的一部分,从而产生提交 ID。如果是这种情况,这里数据的存在gpgsig意味着它总是会为您提供与提交的未签名版本不同的哈希值。