在Visual Studio Code中,Git出现“gpg无法签名数据”的错误。

27

在进行了新的Linux安装后,我正在尝试设置我的环境,但在本地提交更改时不断收到Git: gpg failed to sign the data错误。我使用的是专有的Visual Studio Code版本,而不是开源版本。

.gitconfig:

[user]
    name = djweaver-dev
    email = djweaver@djweaver.dev
    signingkey = 37A0xxxx...
[core]
    excludesfile = /home/dweaver/.gitignore_global
[commit]
    gpgSign = true

糟糕,此外我找不到一种方法来复制输出日志,也不知道该日志存放在哪里,所以这里有一张图片:

output log

我已经采取的步骤:

  • 在gnugp中生成了新的密钥(RSA 4096)
  • 将签名密钥添加到全局.gitconfig中
  • 在Visual Studio Code设置中设置"git.enableCommitSigning": true
  • 克隆了我的github仓库

通常情况下,在过去提交时,我会得到一个对话框,要求进行GPG身份验证。现在我没有得到这个对话框,只有错误对话框。

更新:好吧,现在我真的很困惑。我重新启动了vscode(在这个过程中我不是第一次这样做),然后神奇地,它就可以工作了。我唯一能想到的可能是我搞砸了目录?无论如何,现在它可以工作了。

更新:奇怪的是,经过一个全新的arch安装后,我在近一个月后又遇到了同样的问题。我尝试了我能够在这个网站上找到的所有方法,没有一种方法有效。

我尝试将export GPG_TTY = $ (tty)添加到.bash_profile和.bashrc中

Git日志:

Looking for git in: git
Using git 2.26.2 from git
> git rev-parse --show-toplevel
> git rev-parse --git-dir
Open repository: /home/dw/dev/website
> git status -z -u
> git symbolic-ref --short HEAD
> git rev-parse master
> git rev-parse --symbolic-full-name master@{u}
> git rev-list --left-right master...refs/remotes/origin/master
> git for-each-ref --format %(refname) %(objectname) --sort -committerdate
> git remote --verbose
Failed to watch ref '/home/dw/dev/website/.git/refs/remotes/origin/master', is most likely packed.
Error: ENOENT: no such file or directory, watch '/home/dw/dev/website/.git/refs/remotes/origin/master'
    at FSWatcher.start (internal/fs/watchers.js:165:26)
    at Object.watch (fs.js:1270:11)
    at Object.t.watch (/usr/lib/code/extensions/git/dist/main.js:1:604919)
    at T.updateTransientWatchers (/usr/lib/code/extensions/git/dist/main.js:1:83965)
    at e.fire (/usr/lib/code/out/vs/workbench/services/extensions/node/extensionHostProcess.js:46:87)
    at e.updateModelState (/usr/lib/code/extensions/git/dist/main.js:1:103179)
> git config --get commit.template
> git check-ignore -v -z --stdin
> git check-ignore -v -z --stdin
> git commit --quiet --allow-empty-message --file - -S
error: gpg failed to sign the data
fatal: failed to write commit object
> git config --get-all user.name
> git config --get-all user.email

上次使用了相同的配置,user.nameuser.email 和每个尝试过的密钥都匹配... user.signingkey 也匹配。不确定还能做什么,因为我已经在新初始化的本地仓库和从 GitHub 拉取的仓库上尝试过,无论是在官方的 MS VSCode (AUR) 还是 OSS 版本中,在 vscode 终端模拟器和 gnome 终端中都获得了相同的结果,所以这一定是一个 git 问题或 gnugp 问题。

我注意到的是,在未签名提交后,它会立即工作:第一次会提示我输入密钥密码,然后在后续提交中就可以工作,直到几分钟后它突然停止工作,进程必须重复进行。有几个 macOS 用户报告说在后台运行了一个停滞的 gpg-agent 并解决了问题,但是,我看到的是:

[dw@dwLinux website]$ gpg-agent
gpg-agent[2870]: gpg-agent running and available

有趣的是,通过执行 echo "test" | gpg --clearsign 我得到了相同的结果:它可以在短时间内工作,然后我就不能再签名了。

更新

好吧,尝试修复这个问题第二天。为了排除如此处所述的gpg-agent理论,我按照Arch Linux Wiki上演示的使用$ gpg-connect-agent reloadagent /bye命令重新加载gpg-agent的说明进行操作。

但是没有效果

既然我可以在vscode官方、oss code和vscodium以及bash中重现这个问题,我想也许这是一个权限相关的问题,因为很多Linux问题通常都是如此。我已经将我的用户添加到各种组中,包括root,但是这也没有效果,所以我认为我可以安全地排除以下内容:

  • VS Code
  • GnuGP
  • gpg-agent
  • Linux 权限

因此,我的下一个焦点是配置文件本身,但是如先前所述,凭据与.gitconfig中的密钥匹配,并且我的.bash_profile已正确配置为使用export GPG_TTY=$(tty)

关于官方GnuPG文档中提到的一个有趣的注意事项,显示了他们的方式和GitHub文档这里上的方式之间的语法不一致。

来自GnuPG:"造成这种情况的最常见原因是没有正确设置环境变量GPG_TTY。确保它已设置为真正的tty设备,而不仅仅是'/dev/tty';即'tty'是明显错误的;您想要的是'tty'——请注意反引号。还要确保导出此环境变量,也就是说,您应该在设置后跟随'export GPG_TTY'"

我理解bash中的$(whatever)是执行命令,但是为了安全起见,我已经使用两种方式都附加了.bash_profile,但是都没有解决问题

最后一件事

这篇文章中,用户谈到守护进程化时gpg-agent身份验证不可用,当其他应用程序(如IDE,如VSCode)发起gpg访问时,这解释了我为什么可以在提交随机文件或执行echo "test" | gpg --clearsign并进行身份验证后 暂时签署提交,但是像这个主题的大多数其他“解决方案”一样,他们揭示了最终只需将export GPG_TTY=$(tty)添加到他们的.bash_profile中即可,但我已经尝试过了。

从这里开始?

我仍然无


3
这个方法对我起了作用:如果你和我一样在使用VSCode的WSL模式,尝试在(WSL)终端里面VSCode中做安全签名提交,它会要求你输入密码一次并进行提交。从此以后,它将支持VSCode集成。如果这种方法不起作用,或者你没有使用WSL,请告诉我,因为我现在已经弄清楚了。 - Danilo Ramirez
@DaniloRamirez 这似乎只是一个临时解决方案。它可以工作一段时间(几个小时),然后又出现了同样的问题。你的解决方案能够永久地解决这个问题吗? - LewlSauce
1
@LewlSauce,我记不清了,抱歉。在那条评论发布后的一个月内,我就放弃了在vscode上使用WSL,并完全转向Ubuntu。它可能只是暂时的问题,但已经过了一段时间,所以我希望vscode团队已经为您解决了这个问题。 - Danilo Ramirez
只是提醒那些不耐烦的人 - 如果您的密钥已过期,这个错误信息也会出现。 - Winny
我在更新macOS到12.3时,使用GPG Keychain出现了故障。您可以在GPG Keychain网站上查看解决方案。 - William Entriken
6个回答

31

首先确保添加

export GPG_TTY=$(tty)

在您的.bashrc文件中

显然,VSCode没有要求输入密钥短语,这就是为什么它会出错的原因。我不知道原因。我的个人解决方案是先在控制台提交或运行以下命令:

echo "test" | gpg --clearsign

编辑

为了避免每次提交时都要输入口令,您可以让 GPG 记住它8小时或直到下一次重启:

mkdir -p ~/.gnupg
echo "default-cache-ttl 28800" >> ~/.gnupg/gpg-agent.conf

GitHub指南


4
这是一种很好的方法,可以在不使用Git的情况下测试您的gpg密钥是否可用。 - Winny
3
这个答案缺少一个非常重要的部分。也就是,在VSCode中打开一个集成终端窗口,然后运行此答案中的命令。您将被要求提供密码,然后在该会话中所有签名提交都将起作用。如果您关闭并重新打开VSCode,则需要再次执行此操作,打开集成终端窗口... - Akshay Hiremath
1
最后的编辑是一个很好的解决方案!非常感谢。 - jgu7man

8

也许是git找不到gpg了?这是我在使用VSCode和Remote-Containers创建开发容器时遇到的问题。尝试在VSCode终端中(在容器内部)运行以下命令:

git config --global --unset gpg.program
git config --global --add gpg.program /usr/bin/gpg

或者在您的 gpg 安装位置。您可以通过键入以下内容来查找:

which gpg

如果这样可以的话,你就可以将它放在你的 Dockerfile 中用于开发容器。


7

几天前,我在使用VS Code和WSL时遇到了同样的问题。问题在于VS Code无法正确加载.profile文件中的所有环境变量(尝试运行此命令,但未得到正确结果:echo $GPG_TTY)。幸运的是,在VS Code首选项中为shell args设置"-l"选项对我有用。这确保了.profile(或.zprofile)文件被成功加载。 我将以下这些行添加到settings.json

"terminal.integrated.shellArgs.linux": [
    "-l"
]

请确保在您的 .profile 文件中添加 export GPG_TTY=$(tty),然后重新启动终端和 VS Code。


更新:由于 VSCode 已经弃用了 shellArgs 选项,请使用以下代码片段作为替代方案。

"terminal.integrated.profiles.linux": {
    "bash": {
        "path": "bash",
        "args": ["-l"],
        "icon": "terminal-bash"
    },
    "zsh": {
        "path": "zsh",
        "args": ["-l"],
    },
    "fish": {
        "path": "fish",
        "args": ["-l"],
    },
    "tmux": {
        "path": "tmux",
        "args": ["-l"],
        "icon": "terminal-tmux"
    },
    "pwsh": {
        "path": "pwsh",
        "args": ["-l"],
        "icon": "terminal-powershell"
    }
},
"terminal.integrated.defaultProfile.linux": "bash"

所有终端配置文件都增加了-l选项,可以删除未使用的配置文件,并设置您想要的默认配置文件。

我在 .zprofile 中添加了导出功能,更新了设置,重新启动后问题仍然存在。 - Pramus
3
请注意,此方法已被弃用,请改用 #terminal.integrated.defaultProfile.linux# - MCMZL
@MCMZL 终端综合默认配置文件.linux应该设置什么值,它是否与“-l”相同,并且它将是数组中的一个值还是只有一个值“-l”? - Akshay Hiremath

3

我也遇到了同样的问题,但我已经解决了它。

背景

  • macOS操作系统
  • 使用GPG Suite生成GPG密钥
  • 使用pinentry-mac

如何解决这个问题

我看到了这个答案,并且按照它的步骤进行了操作。

  1. 获取密钥
gpg2 --list-keys

结果

/Users/xxuser/.gnupg/pubring.kbx
---------------------------------
pub   dsa2048 2010-08-19 [SC] [expires: 2024-05-11]
      85E38F69046BSDFB07B76D78F0500D026C4
uid           [ unknown] GPGTools Team <team@gpgtools.org>
uid           [ unknown] [jpeg image of size 6329]
sub   rsa4096 2014-04-08 [S] [expires: 2024-05-11]
sub   rsa4096 2020-05-11 [E] [expires: 2024-05-11]

pub   rsa4096 2020-05-04 [SC] [expires: 2024-05-03]
      B97E9964ACAD1928300D37CC8A9E3745558E41AF
uid           [ unknown] GPGTools Support <support@gpgtools.org>
sub   rsa4096 2020-05-04 [E] [expires: 2024-05-03]

pub   rsa4096 2021-07-29 [SC] [expires: 2025-07-29]
      926E268C01892E8A2FCCD2A101CEB6267272A9A5
uid           [ultimate] xxuser <x@xxgolo.com>
sub   rsa4096 2021-07-29 [E] [expires: 2025-07-29]
  1. 由于我为x@xxgolo.com创建了一个秘密,因此我需要的是926E268C01892E8A2FCCD2A101CEB6267272A9A5密钥代码。
  2. 让git使用这个密钥。
git config --global user.signingkey 926E268C01892E8A2FCCD2A101CEB6267272A9A5

现在应该可以工作了。
git commit -S -m "This is a signed commit"

注意 如果您需要与Github一起使用,则需要按照此指南将您的公共GPG密钥添加到Github。


1
请确保在尝试以下操作之前,echo "test" | gpg --clearsign 的运行是成功的。
检查 git commit 在背后正在做什么很有帮助。执行以下提交,使用 GIT_TRACE=1 如下所示。
GIT_TRACE=1 git commit -S -m "MESSAGE"

这将展示Git在提交时使用了哪些用户名、电子邮件和密钥。
在我的情况下,我发现Git选择了错误的用户和密钥详情来签署提交。我主要打算使用存储库的本地配置而不是全局配置,并将以下内容添加到本地Git配置中(位于“REPO_PATH/.git/config”),这样就可以在终端和VSCode中签署提交。
[user]
    name = USER NAME
    email = USER EMAIL
    signingKey = SIGNING KEY

可以使用以下方式进行设置:
git config --local user.name "USER NAME"
git config --local user.email "USER EMAIL"
git config --local user.signingkey "USIGNING KEY"

1
我不确定是否已经太晚了,但是…我找到了一个即时的解决方案。
要查看user.name和user.email,请运行:
git config -l
你可能会注意到有两个user.name条目。你可能犯了和我一样的错误!我在那里放了我的真名而不是GitHub用户名,结果出现了两个user.name的条目!我只需将全局user.name改回我的GitHub用户名,像这样…
git config --global user.name "ghusername"
接下来,git commit,它应该可以工作:
git commit -m ""
如果这对你起作用,请告诉我,我想知道是否是相同的问题。

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