Unable to commit to git with the gpg key error

5.5k views Asked by At

Using git version 2.20.1 and the official guide, I ran the following commands to generate a pgp key

$ gpg --full-generate-key
...
$ gpg --list-secret-keys --keyid-format LONG
gpg: checking the trustdb
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
/home/mahmood/.gnupg/pubring.kbx
--------------------------------
sec   rsa4096/CFEFE6D58A392624 2020-09-08 [SC]
      26XX594XXXE2BAXXXE40AXXXCFXXX6D5XXXXX624
uid                 [ultimate] mahmood <EMAIL>
ssb   rsa4096/3B138A448B277FD9 2020-09-08 [E]

Now I can see the public key with this command:

$ gpg --armor --export CFEFE6D58A392624
-----BEGIN PGP PUBLIC KEY BLOCK-----

mQINBF9XdKoBEACyQjVUlBYjOLSqv7YRIIq0+iJ9A0UzkItUoWBnDrHmTdnH+UeK
...
=WCOk
-----END PGP PUBLIC KEY BLOCK-----

I then copied the key in the website according to this official page.

enter image description here

Now when I want to commit, I get a key signing error:

$ git commit -S -m "...."
error: gpg failed to sign the data
fatal: failed to write commit object

How can I fix that?

UPDATE:

Exporting the following variable will fix the problem.

export GPG_TTY=$(tty)

How did I reach that? First I checked ~/.gitconfig to be sure that [user] section is correct. Then I ran the following test command which gave me an ioctl error

$ echo "test" | gpg --clearsign
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

test
gpg: signing failed: Inappropriate ioctl for device
gpg: [stdin]: clear-sign failed: Inappropriate ioctl for device

Searching for that error led to export GPG_TTY=$(tty) and then the test command was fine. Consequently the commit command is now OK.

2

There are 2 answers

2
Simba On

man gpg-agent,

         You should always add the following lines to your .bashrc  or  whatever
         initialization file is used for all shell invocations:

           GPG_TTY=$(tty)
           export GPG_TTY


         It is important that this environment variable always reflects the out-
         put of the tty command.  For W32 systems this option is not required.

From my using experience, environment variable GPG_TTY is needed by the gpg-agent to detect which tty/window/shell is active and pop up a passphrase input prompt.

You also need to update this info time by time. Otherwise the passphrase prompt may not pops up in your working shell, but another shell.

Most of the time, export GPG_TTY is enough. If you're using gpg-agent as a ssh agent as well. tty info is also need to be updated for gpg-agent's ssh support. Here is what I do for gpg-agent's ssh support in ZSH.

# Updates the gpg-agent TTY before every command since
# there's no way to detect this info in the ssh-agent protocol
function _gpg-agent-update-tty {
  gpg-connect-agent UPDATESTARTUPTTY /bye &>/dev/null
}

autoload -Uz add-zsh-hook
add-zsh-hook preexec _gpg-agent-update-tty
0
BaharaJr On

If you are still having problems in macOS, open ~/.gitconfig and change everything under [gpg] to program = /usr/local/bin/gpg