使用GPG签署git提交

38

有没有一种方法可以使用gpg签署git提交?对于标签来说非常简单(使用-s而不是-a),看起来应该有类似的功能可以用于提交。


2
为什么要对每个提交进行签名?如果您对标签进行签名,则从该标签可达的所有提交也都已签名(因为每个提交的哈希包括父ID)。对每个提交进行签名几乎没有什么好处。 - knittl
5
@Magnesium: 不行。从初始提交开始没有任何可达的提交记录。只有反过来才行。如果你签署了最新的提交(创建一个已签名的标签指向它),那么在它之前的所有提交记录(父级/祖先)都会被自动信任。 - knittl
3
签署每个提交的一个原因是为了获得更强的证据,以确保提交实际上来自您认为的那个人。签署标签仅允许您检测历史记录是否已更改。 - Hans-Christoph Steiner
4
我认为只签署标签存在的问题是,对于那些不是 Linux 内核开发人员的人来说,很容易有人发布使用你姓名和电子邮件的提交,而这些提交又无法与你本人的提交区分开来。在像 GitHub 这样的社交编程网站上,你可能会为许多不同的项目做出贡献,如果突然出现带有你的名字的恶意代码,并且无法与你实际完成的工作区分开来,这可能会严重影响你的声誉。=) - cib
2
@MichaelFreidgeim 这提出了一个不同的问题:是否有可能签署之前的提交。这个问题询问的是如何在提交时签署提交。 - Mark Rotteveel
显示剩余6条评论
2个回答

63
注意:始终添加-S选项可能很麻烦。在git 2.0及更高版本中,您可以添加一个配置文件来为您处理该选项。
请参见commit 2af2ef3Nicolas Vigier (boklm)

添加commit.gpgsign选项以签署所有提交

如果您想要GPG签署所有提交,您必须始终添加-S选项。
commit.gpgsign配置选项允许自动签署所有提交。

commit.gpgsign

一个布尔值,用于指定是否所有提交都应该使用 GPG 签名。在执行 rebase 等操作时使用此选项可能会导致大量的提交被签名。使用代理可以避免多次输入 GPG 密码,这可能更加方便。如 Apteryx 在下面的 评论中 所述:要在全局命令行上设置此选项:
git config --global commit.gpgsign true

在Git 2.27(2020年第二季度)中,“git rebase”学会了“--no-gpg-sign”选项,以取消用户可能设置的commit.gpgSign

请查看 commit 5c5bac1commit 4369d3acommit 9da37fecommit ae06ba6commit cf0ad4dcommit c241371(于2020年4月3日由Đoàn Trần Công Danh (``)提交)
(合并自Junio C Hamano -- gitster --commit fc3f6fd中,于2020年4月22日)

cherry-pick/revert: 在所有情况下都尊重 --no-gpg-sign

签名:Đoàn Trần Công Danh

{cherry-pick,revert} --edit 迄今未尊重 --no-gpg-sign。

将此选项传递给 git commit 以予以尊重。


请注意, "git rebase --rebase-merges"(man) 在使用非默认合并策略重播合并或重播八爪鱼合并时,未能正确传递--gpg-sign命令行选项给底层的"git merge"(因为使用默认策略重播双头合并在单独的代码路径中完成,所以这个问题并没有对大多数用户触发),这已经在Git 2.30 (Q1 2021)中得到了修正。

查看 commit 43ad4f2, commit 19dad04, commit ae03c97 (2020年10月18日) 由Samuel Čavoj (sammko)提交。
(合并自Junio C Hamano -- gitster --commit 73af6a4,2020年11月2日)

顺序执行器:修复传递给合并子命令的 gpg 选项

签名:Samuel Čavoj

当使用--rebase-merges进行变基时,使用自定义策略指定-s或章鱼合并,并且同时启用gpgsign(无论是重做-S还是配置commit.gpgsign),操作会在创建合并提交时失败。

与使用密钥 ID 替换的 "-S%s" 不同,只传递裸密钥 ID 给底层合并命令,底层合并命令尝试将其解释为引用。

修复此问题并按 Johannes Schindelin 和 Junio C Hamano 的建议添加测试用例。

以及:

序列控制器:在合并中显式传递--no-gpg-sign

签署者:Samuel Čavoj

对于使用非默认策略进行合并的合并子命令,它会使用自己的默认行为来决定如何签署提交,而不管opts->gpg_sign设置为什么。
例如,如果将--no-gpg-sign标志明确给rebase,则会被忽略,如果commit.gpgsign设置为true

修复此问题,并添加一个测试用例来测试此行为。

已修复:

"

\"git rebase --rebase-merges\"(man) 没有正确地将 --gpg-sign 命令行选项传递给底层的 \"git merge\",当使用非默认合并策略回放合并或回放八爪鱼合并时(因为使用默认策略回放双头合并是在一个单独的代码路径中完成的,所以大多数用户没有触发问题),这已经在 Git 2.30(2021年第一季度)中得到了修正。

"

查看 commit 43ad4f2, commit 19dad04, commit ae03c97 (2020年10月18日) 由 Samuel Čavoj (sammko) 提交。
(由 Junio C Hamano -- gitster -- 合并于 commit 73af6a4, 2020年11月2日)

sequencer: 修正传递给 merge 子命令的 gpg 选项

签名作者: Samuel Čavoj

当使用自定义策略指定的 -s 或者章鱼合并进行 --rebase-mergesrebase 操作,并且同时启用了 gpgsign(通过 rebase -S 或配置文件 commit.gpgsign),则该操作在创建合并提交时会失败。
与其将带有替换键 ID 的 "-S%s" 一起传递,只会传递裸的键 ID 给底层的合并命令,该命令会试图将其解释为引用。

修复该问题并按照 Johannes Schindelin 和 Junio C Hamano 的建议添加测试用例。


3
在命令行中全局设置这个选项:git config --global commit.gpgSign true - Apteryx
@Apteryx 谢谢你。我已经将你的评论包含在答案中,以增加其可见性。 - VonC
有一个奇怪的问题,是否有类似的标志可以暂时挂起 config.gpgsign=true,而不是执行单独的 git config --global commit.gpgsign false,然后再执行 git config --global commit.gpgsign true - Chris.Wilson
3
@Chris.Wilson 你可以在仓库级别暂停它(cd /path/to/repo; git config commit.gpgsign false)。或者你可以在命令级别暂停它:git -c commit.gpgsign=false xxx。两者都将优先于全局设置。 - VonC

36

git commit -S(需要 git >= 1.7.9):最初的回答。


8
等价于 gpg commit --gpg-sign。您也可以使用 gpg commit --gpg-sign=DEADBEEF 来指定密钥。我是通过查看源代码发现的,似乎没有记录在文档中。 - Keith Thompson
2
那就解释了为什么我看不到它,因为我使用的是1.7.8版本以保持向后兼容性。我猜他们读懂了我的想法! - austin1howard
7
如何将--gpg-sign设为git commit的默认选项? - Hongli
2
@wRAR 不幸的是,这仅适用于用户明确使用 git commit 创建的提交。例如,如果您执行了一个变基,并希望签署它创建的所有新提交,则别名无法让您执行此操作。我所知道的唯一方法是进行交互式变基并手动签署每个提交。对于非快进合并,情况类似,除非您执行 git merge --no-commit ...,否则合并提交将不会被签署。 - Patrick Niedzielski
3
通过将commit.gpgsign配置变量设置为true,可以告知"git commit"始终对生成的提交进行GPG签名(no-gpg-sign应覆盖命令行选项)。 - rofrol
显示剩余6条评论

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