Git sign在历史中某处提交

时间:2015-11-29 02:52:13

标签: git version-control sign git-sign

在互联网的许多部分(例如here)上,暗示git提交必须在完成时签名或从不签名。

但是,从技术上讲,提交上的签名只不过是提交对象上的签名(如here所示),它由"树"的哈希组成。 file(即git对象的哈希列表),父哈希和一些元数据。

因此,似乎没有任何东西可以阻止提交被后验签名,而不会重写整个历史记录。

真的有可能吗?有推荐的方法吗?这样一个事后签名会不会很好地推动和拉动?

2 个答案:

答案 0 :(得分: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数据的存在意味着它总是会提供与未提交的提交版本不同的哈希值。

答案 1 :(得分:1)

每个git对象都由它自己的SHA-1哈希标识。所以他们都是不变的。

如果您签署了之前已完成的提交,那么您实际上是复制提交,但是以签名方式提交。所以原始提交仍然存在 - 如果你记得它的哈希值或任何引用它,你甚至可以git show。您要做的是创建一个具有等效更改和元数据的新提交,但添加了签名,并使您当前所在的参考 - 即您当前的分支 - 指向它。

提交的树和每个其他依赖对象都是相同的。但是,随着提交本身发生变化,您将获得一个新的提交对象 - 因此您将重写历史记录。