gpg未能签署数据致命:未能写入提交对象

我在Git 2.10发行说明中关注了很多关于漂亮属性的文章。 经过其中将git升级到2.10.0,并对全局.gitconfig进行了更改,结果如下 –

 [filter "lfs"] clean = git-lfs clean %f smudge = git-lfs smudge %f required = true [user] name = xyz email = abc.def@gmail.com signingkey = AAAAAAA [core] excludesfile = /Users/xyz/.gitignore_global editor = 'subl' --wait [difftool "sourcetree"] cmd = opendiff \"$LOCAL\" \"$REMOTE\" path = [mergetool "sourcetree"] cmd = /Applications/SourceTree.app/Contents/Resources/opendiff-w.sh \"$LOCAL\" \"$REMOTE\" -ancestor \"$BASE\" -merge \"$MERGED\" trustExitCode = true [alias] lg = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative [color "diff"] old = red strike new = green italic 

但是,现在我试图签署我的提交使用

 git commit -a -S -m "message" 

我看到以下错误 –

您需要密码才能解锁密钥

用户:“XYZ(数字签名)”

2048位RSA密钥,ID AAAAAAAA,创build于2016-07-01

错误:gpg未能签署数据致命:未能写入提交对象

注意 – 我仍然可以使用git commit -a -m "message"提交更改git commit -a -m "message"

有没有办法克服这个问题? 或者gpg所需的任何更改configuration与git的升级相处?


更新1

还寻求进一步的有用性,下面是否有一种方法来“自动签名”提交Git与GPG密钥? 。 我已经configuration了使用的密钥

 git config --global user.signingkey ED5CDE14(with my key) git config --global commit.gpgsign true 

无论如何,相当明显地得到相同的错误。

我遇到了这个问题与OSX。

原始答案:

好像gpg更新(brew)更改为gpg位置为gpg1 ,您可以更改git查找gpg的二进制文件:

 git config --global gpg.program gpg1 

如果你没有gpg1: brew install gpg1

更新回答:

它看起来像gpg1被弃用/ “轻轻推迟使用” ,所以你可能应该实际上更新到gpg2,不幸的是这涉及到更多的步骤/一些时间:

 brew upgrade gnupg # This has a make step which takes a while brew link --overwrite gnupg brew install pinentry-mac echo "pinentry-program /usr/local/bin/pinentry-mac" >> ~/.gnupg/gpg-agent.conf killall gpg-agent 

第一部分安装gpg2,后者是使用它所需的一个黑客 。 对于故障排除,看到这个答案 (虽然这是关于Linux不酿造),这表明一个很好的testing:

 echo "test" | gpg --clearsign # on linux it's gpg2 but brew stays as gpg 

如果此testing成功(没有错误/输出包括PGP签名),您已成功更新到最新的gpg版本。

你现在应该可以再次使用git签名了!
值得注意的是你需要有:

 git config --global gpg.program gpg # perhaps you had this already? On linux maybe gpg2 git config --global commit.gpgsign true # if you want to sign every commit 

注意:在您运行已签名的提交之后,您可以validation它是通过以下方式签名的:

 git log --show-signature -1 

其中将包括上次提交的gpg信息。

如果使用gnupg2和gpg-agent 2.x,请确保设置环境variablesGPG_TTY

 export GPG_TTY=$(tty) 

请参阅GPG有关常见问题的文档 。

2016年10月更新: 问题871确实提到“签署在Git 2.9.3中停止工作”

前两天发布的Git for Windows 2.10.1 (2016年10月4日)已经修复了交互式GPG签名提交和标记问题。

git中最近的gpg-sign改变(在Linux上没有引入任何问题)暴露了一个问题,在Windows上,非MSYS2-git与MSYS2-gpg交互。


原始答案:

阅读“ 7.4 Git工具 – 签署你的工作 ”,我假设你有你的“ user.signingkey ”configuration集。

在gpg周围的最后一个大的重构(在Git 2.10之前)是在提交2f47eae2a ,在这里错误消息被移动到gpg-interface.c

该文件上的日志显示了最新的提交af2b21e (Git 2.10)

gpg2默认已经使用了长格式,但由于兼容性的原因,大多数发行版似乎还是将“gpg”作为较旧的1.x版本。 老版本的gpg只显示32位的短ID,这是非常不安全的。

这对validation本身并不重要:如果validation通过,pgp签名是好的。
但是,如果您还没有真正拥有密钥,并且想要获取它,或者您想要检查确切使用哪个密钥并想要检查它,则应该更加精确地指定密钥。

因此,请检查您指定的user.signingkeyconfiguration以及您正在使用的gpg版本(gpg1或gpg2),以查看这些configuration是否对错误消息有任何影响。

还有提交0581b54 ,它改变了gpg failed to sign the data错误消息的条件(补充提交0d2b664 ):

目前我们没有从stderr读取。 但是,我们希望在未来的补丁中,所以这也为我们做好了准备(在这种情况下在读取所有input之前,gpg 确实会写入,尽pipe如此,密钥uid也不会填满pipe道缓冲区)。

提交4322353显示gpg现在使用一个临时文件,所以可能有正确的问题。

让我们转换为使用tempfile对象,它处理我们的困难情况,并添加缺less的清理调用。

我已经完成了这个简单容易的配方:

在MacOS上自动签名提交(全局和使用不同的IDE):

以这种方式获取您的signingkey

 brew install gnupg gnupg2 pinentry-mac git config --global user.signingkey <YOUR_SIGNING_KEY> git config --global commit.gpgsign true git config --global gpg.program gpg 

gpg.conf文件中gpg.conf以下内容(使用gpg.conf nano ~/.gnupg/gpg.conf命令编辑文件):

 no-tty 

gpg-agent.conf文件中添加以下内容(使用nano ~/.gnupg/gpg-agent.conf命令编辑文件):

 pinentry-program /usr/local/bin/pinentry-mac 

我遇到了同样的问题。 我很高兴地报告,问题不在于git 2.10.0而在于gnupg 1.4.21

暂时将gnupg降级到1.4.20为我解决了这个问题。

如果你使用的是自制软件,并且像我一样升级了你的软件包,那么你可以运行brew switch gnupg 1.4.20来恢复。

可能有助于杀死可能被旧数据困住的进程gpg-agent 。 所以新gpg-agent开始会要求input密码

我和最新的Git源代码(2.12.2)一起构build了一个类似的问题,它包含了所有依赖项(Zlib,Bzip,cURL,PCRE,ReadLine,IDN2,iConv,Unistring等)的最新源代码。

原来libreadline给了GnuPG问题:

 $ gpg --version gpg: symbol lookup error: /usr/local/lib/libreadline.so.7: undefined symbol: UP 

当然,尝试从-vvv获得Git的有用信息失败了,所以失败是一个谜。

要解决由于ReadLine引起的PGP故障,请按照无法更新或使用软件包pipe理器 – gpg错误的说明进行操作 :

在docker:

 ls /usr/local/lib 

那里有一堆readline libs(libreadline.so.BLAH-BLAH),所以我:

 su mkdir temp mv /usr/local/lib/libreadline* temp ldconfig 

如果与GPG密钥的uid相关联的电子邮件与您在git中使用的电子邮件不同,那么您需要将另一个用户ID添加到密钥中,或者使用与哪个电子邮件完全匹配的密钥。

您可以使用以下方法添加另一个UID:

$ gpg –edit-key

参见mo https://superuser.com/questions/293184/one-gnupg-pgp-key-pair-two-emails

使用cygwin,我最近切换到gpg2 。 然后在设置git config gpg.program gpg2之后,我有和git一样的问题。

尝试echo "test" | gpg2 --clearsign echo "test" | gpg2 --clearsign查看gpg2是否正常工作。 我发现它是最简单的解决scheme,只需设置git config gpg.program gpg ,因为这是git config gpg.program gpg 。 但是这样你也会得到一个更好的错误 – 例如你需要安装pinentry。

确保你有正确的电子邮件设置。

 git config --global user.email "user@example.com" 

上述答案都不符合我的问题。 我的gpg二进制文件( /usr/local/bin/gpg -> /usr/local/MacGPG2/bin/gpg2 )作为GPG Suite的一部分安装,而不是通过brew。

不过,我觉得这个build议归结为:“使用任何一个gpg二进制文件是可用的最新版本”。 所以我试了一下:

 brew update brew upgrade git brew install gpg # the following are suggestions from brew's Caveats, to make `/usr/local/bin/gpg` # point to the brew binary: rm '/usr/local/bin/gpg' brew link --overwrite gnupg2 

我validation了我已经正确地改变了$PATH上的gpg指向brew中的新可执行文件:

 🍔 which gpg /usr/local/bin/gpg 🍔 ls -l /usr/local/bin/gpg lrwxr-xr-x 1 burger admin 33 Feb 13 13:22 /usr/local/bin/gpg -> ../Cellar/gnupg2/2.0.30_3/bin/gpg 

而且我也明确告诉过git使用哪个gpg二进制文件:

 git config --global gpg.program gpg 

好吧,也许这不是完全的水密,因为它对path很敏感。 我没有真正确认git已经转向调用gpg

在任何情况下:这一切都不足以使git commit成功再次签署我的提交。


最终为我工作的是更新GPG套件 。 我正在运行版本2016.7,我发现更新到2016年10月为我解决了这个问题。

我打开了GPG Keychain.app ,然后点击“检查更新…”。 使用新版本:签名提交再次正常工作。

如果这只是随机发生的,并且在过去一直很完美,就像我的情况一样,尝试退出( cmd+shift+q )并重新login。为我工作

禁用自动gpg签名:

$ git config commit.gpgsign false