有没有一种方法可以使用GPG密钥在Git中“自动签名”提交?


213

有没有一种简单的方法可以使Git始终对创建的每个提交或标记进行签名?

我尝试了类似的东西:

别名commit = commit -S

但这并不能解决问题。

我不想安装其他程序来实现此目的。容易做到吗?

只是一个附带的问题,也许不应该对提交进行签名,而只能标记我从未创建过的标签,因为我为Homebrew等项目提交了单个提交。


8
别名起作用的原因是因为您不能为已存在的命令设置别名。(相关:stackoverflow.com/questions/5875275/git-commit-v-by-default stackoverflow.com/questions/2500586/... stackoverflow.com/questions/1278296/...
丹D.

2
仅供参考:重写将要推送的所有提交以对其进行签名:(git filter-branch -f --commit-filter 'git commit-tree -S "$@"' HEAD@{u}..HEAD我并不是说您应该使用此)。
六。

Answers:


274

注意:如果您不想一直-S花费所有时间来确保您的提交已签名,则有一个建议(pu现在,在2013年12月分支' ',因此不能保证它将添加到git版本中)。 config,它将为您处理该选项。
2014年5月更新:它在Git 2.0中(在此补丁系列中重新发送之后)

提交2af2ef3尼古拉斯·Vigier(boklm)

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

如果您想对所有提交进行GPG签名,则必须一直添加该-S选项。
commit.gpgsign配置选项允许自动登录所有的提交。

commit.gpgsign

一个布尔值,用于指定是否所有提交都应由GPG签名。
在执行诸如变基之类的操作时使用此选项可能导致对大量提交进行签名。使用代理来避免多次键入GPG密码可能会很方便。


该配置通常是针对每个存储库设置的(您无需签署您的私人实验本地存储库):

cd /path/to/repo/needing/gpg/signature
git config commit.gpgsign true

您可以将其与user.signingKey用作全局设置结合使用(用于要签署提交的所有存储库的唯一密钥)

git config --global user.signingkey F2C7AB29

user.signingKey是在git 1.5.0(2007年1月)中引入的,提交为d67778e

我不应该要求我在git存储库和gpg密钥中使用相同形式的名称。
此外,我的钥匙圈中可能有多个钥匙,并且可能想使用与我在提交消息中使用的地址不匹配的钥匙。

该补丁添加了一个配置条目“ user.signingKey”,如果存在,它将被传递到gpg的“ -u”开关,从而允许覆盖标签签名密钥。

这与强制执行承诺aba9119为了赶在那里如果用户错误配置的情况下(GIT 1.5.3.2)user.signingKey在他们的.git/config或根本就没有自己的钥匙圈任何密钥。

笔记:


太棒了。在github上有一种简单的方法可以执行git description之类的操作,而无需下载Hole Repo?

13
您不需要签署您的私人实验存储库...但是为什么不呢?
安迪·海登

168
git config --global user.signingKey 9E08524833CB3038FDE385C54C0AFCCFED5CDE14
git config --global commit.gpgSign true

将9E08524833CB3038FDE385C54C0AFCCFED5CDE14替换为您的密钥ID。请记住:使用简短ID绝不是一个好主意

更新:根据新的git edict,所有配置键都应位于camelCase中。


您是否只是从VonC的答案中复制并粘贴了此内容?
罗比·阿夫里尔

19
不。您可以在版本历史中看到有人在他的答案中添加了我的示例。ED5CDE14是我自己的个人密钥。但是没问题。
费利佩

7
奇怪 明天我将还原更改,因为它对您来说很不利
Robbie Averill

您如何找到您的密钥签名ID?还有,对于我所有的git repos来说只有1个GPG密钥不好吗?因为我非常希望不必在漂亮的关联项目中处理4个diff键。
MarcusJ

1
这可能对Linux用户有帮助:为了使其在某些场合下工作(例如在Vim上,使用存储在需要输入PIN的智能卡中的密钥),我必须进行编辑~/.gnupg/gpg-agent.conf和添加pinentry-program /usr/bin/pinentry-gtk-2(遵循本指南wiki.archlinux.org/ index.php / GnuPG#pinentry
iakovos Gurulian '17

49

编辑:作为Git版本1.7.9,可能签署的Git提交(git commit -S)。稍微更新答案以反映这一点。

问题标题为:

有没有一种方法可以使用GPG密钥在Git中“自动签名”提交?

简短的回答:是的,但是不要这样做。

解决输入中的错字:git commit -s不签署提交。而是从man git-commit页面:

-s,--signoff
在提交日志消息的末尾,由提交者添加“按签署者退出”行。

这将提供类似于以下内容的日志输出:


± $ git log                                                                                 [0:43:31]
commit 155deeaef1896c63519320c7cbaf4691355143f5
Author: User Name 
Date:   Mon Apr 16 00:43:27 2012 +0200

    Added .gitignore

    Signed-off-by: User Name 

注意“ Sign-off-by:...”位;是由上的-s标志生成的git-commit

引用发布公告电子邮件

  • “ git commit”获悉“ -S”以进行GPG签名;这可以通过“ git log”的“ --show-signature”选项显示。

因此,可以签署提交。但是,我个人强烈建议您谨慎使用此选项;自动签署提交几乎没有意义,请参见下文:

只是一个附带的问题,也许不应该对提交进行签名,而应该只标记我从未创建的标签,因为我提交单个提交。

没错 提交未签名;标签是。原因可以在Linus Torvalds的此消息中找到,该消息的最后一段说:

签署每个提交完全是愚蠢的。这仅意味着您将其自动化,并使签名价值降低。它也没有增加任何实际价值,因为SHA1的git DAG链的工作方式,您只需要一个 签名就可以使该提交有效地覆盖所有提交。因此,对每个提交进行签名只是遗漏了要点。

我鼓励浏览链接的消息,这阐明了为什么自动签名提交不是一个比我可以做的更好的好主意。

但是,如果您想自动对标签进行签名,则可以通过将其包装git-tag -[s|u]在别名中来实现;如果要执行此操作,则可能要在其中设置密钥ID ~/.gitconfig或特定于项目的.git/config文件。有关该过程的更多信息,请参见git社区书。签署标签比签署您的每次提交都更加有用。


74
“签署每个提交完全是愚蠢的。” ->当有一个“老鼠”开发人员喜欢用伪造的作者和提交者推送提交时,哪种更好的方法来保护提交呢?除非服务器上有钩子魔术,否则他可以将其定向git blame到任何想要的人。
六。

11
0 文章,1。“足以签下所有的人” - >如何分辨“我声称,真的是我的。DIFF(但不确定以往任何进一步的提交)我想提出一个签名上犯无需断言我从中央服务器/任何地方提取的提交内容2.在不受信任的环境中,仍然应该有一个可靠的工具来找出谁是有罪的。如果服务器检查所有提交都使用提交者的电子邮件密钥签名,那就是难以伪造的提交(如果您保护您的计算机以及)。
六,

9
如果代码永不更改,则签署一次提交就足够了。添加更多提交后,您将需要更多签名。签署标签会标记所有比该提交更旧的内容。如果在提交时需要细粒度的验证,则对每个提交进行签名是有意义的。否则,您将不得不使用很多标签,这只会使回购变得混乱。在经过身份验证的远程git repos上,您每次每次提交提交时都必须提供密码或ssh密钥,而不仅是在推送标签时。这是类似的情况。
Hans-Christoph Steiner 2012年

22
我觉得Linus有点不足。他似乎与签名线程中的OP有着完全不同的用例。(验证整个项目的完整性,而不是验证单个提交的作者权。)
Ajedi32'1

9
-1表示“是,但不要这样做。” 答案应该是完全肯定的“是”。签署提交证明作者是作者,否则可以在提交中撒谎。
Urda

6

要使自动签名在git版本2.0之前可用,您必须添加git别名进行提交。

# git config --global alias.commit commit -S
[alias]
    commit = commit -S

0

您需要明确指出,如果您签署了提交或标记,则并不意味着您同意整个历史记录。在提交的情况下,您只需在手头签名更改,在使用标记的情况下,..您需要定义它的含义。您可能已拉出一个更改,声称它是您发来的,但不是(因为其他人将其推到了您的遥控器上)。或者,您不想进行更改,但是您刚刚对标签进行了签名。

在典型的OSS项目中,这种情况可能不那么常见,但是在企业场景中,您不时地仅触摸代码,而您没有阅读全部历史记录,这可能会被忽略。

如果将提交提交重新签名或与其他父母挑选,则签署提交是一个问题。但是,如果修改后的提交可以指向实际验证的“原始”提交,那就太好了。


3
变基础就像说谎。应该非常谨慎地使用它。另一件事是,提交带有签名的签名是“签名”代码,因此,请务必确保它是:a)不抗CYA和b)不浪费精力。

11
@Barry“变基础就像说谎。应该非常谨慎地使用它” –事实并非如此。基于基础的工作流与基于合并的工作流一样有效。变基太强大了,因此无法谨慎使用。
Lukas Juhrich

1
当与GitHub一起专门使用这没问题时,合并提交将不会由您签名,因为GitHub不支持此操作。在此环境中签名每个(非合并)提交的优点是,当通过PR添加流氓提交时非常明显,因为它不会使用您的GPG密钥进行签名。
Arran Cudbard-Bell 2015年

3
“如果您签署了一项提交或标记(都将签署整个历史记录,则很危险,因为您可能已经撤回了一个声称来自您的更改”)。认可您的所有承诺。您不一定要声明这些过去的更改是有效的或得到您的认可,仅是您根据这些更改创建了提交。(尽管带有标签,但我同意您确实在该标签可到达的所有提交上签字。)
Ajedi32 '16

1
@ ArranCudbard-Bell作为更新,如果您commit.gpgsign按照@VonC的建议将其设置为true ,则合并提交将由您签名
Jay
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.