Creating a GPG key for signing Git commits

I’m reading What is Commit Signing in Git? by freeCodeCamp. It suggests using Git Bash.

custom Windows Terminal profile

I don’t like using Git Bash directly, so I made a custom Windows Terminal profile for Git Bash by following the instructions in Using Git Bash with the Microsoft Terminal by Sascha Corti. I removed some unnecessary lines and made the guid string one line so that it was valid JSON. Also, Git Bash was opening to system 32 by default for some reason, so I found in the official Windows Terminal docs the startingDirectory property and what its value should be. Here’s what I ended up with:

{
      "guid": "{00000000-0000-0000-0000-000000012345}",
      "hidden": false,
      "name": "Git Bash",
      "commandline": "\"%PROGRAMFILES%\\git\\bin\\bash.exe\" --login -i -l",
      "icon": "%PROGRAMFILES%\\git\\mingw64\\share\\git\\git-for-windows.ico",
      "startingDirectory": "%USERPROFILE%"
}

guides and tools for GPG keys

Later, I found other potentially helpful guides: Signing commits by GitHub, and 7.4 Git Tools - Signing Your Work on Git’s official site. How (and why) to sign Git commits, by Alessandro Segala, gives some examples of why to sign Git commits.

It sounds like Gpg4win is the easiest way to sign commits in Windows, but I finished the gpg-agent setup before finding that out.

GPG keys can be reused, but not all GPG keys are compatible with Git and GitHub.

gpg commands

These can run in Git Bash and some other shells, but not PowerShell.

Don’t forget to delete exported key files after using them.

sample outputs

Here’s the output from generating a key in Git Bash (with gpg --full-gen-key), after answering the prompts:

gpg: directory '/c/Users/chris/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/c/Users/chris/.gnupg/openpgp-revocs.d/keyFingerPrintShownHere.rev'
public and secret key created and signed.

pub   rsa4096 2024-01-25 [SC]
      keyFingerPrintShownHere
uid                      Chris Wheeler <chrisw289@gmail.com>
sub   rsa4096 2024-01-25 [E]

Here’s the output from gpg --list-keys:

$ gpg --list-keys
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
/c/Users/chris/.gnupg/pubring.kbx
---------------------------------
pub   rsa4096 2024-01-25 [SC]
      keyFingerPrintShownHere
uid           [ultimate] Chris Wheeler <chrisw289@gmail.com>
sub   rsa4096 2024-01-25 [E]

A key’s fingerprint is kind of like its name.

I saved my public and private keys to my password manager, but I’m not sure how to set up a new device with existing keys. I’ll figure that out when I need to.

caching the password

The key’s password is being requested on almost every commit, which is annoying. This Stack Exchange discussion describes how to increase how long the password is cached by gpg-agent. If the file gpg-agent.conf doesn’t exist, it’s fine to create it.

Device restarts clear the cache.

moving to Ubuntu

I’m switching from Windows 11 to Ubuntu. I copied my .gitconfig file without changes. It has my name, email, & signing key, and gpgsign is set to true. When I first tried to commit in Ubuntu, I got the error message “error: gpg failed to sign the data”. To fix this, I needed to copy/download my secret key I saved from Windows 11, run gpg --import secret-key.asc on it, and then delete the secret key file. I don’t know if all secret keys have the .asc extension. I was then able to confirm the import with gpg --list-keys. Now I am able to commit in Ubuntu.