How to sign git commits from within an IDE like IntelliJ?
Since git 2.19.1, gpg2 is supported!
gpg-agent can handle automatic signing now, remembering your passphrase
This should make it easier to use gpg to sign commits automatically. To be exact, git version 2.19.1 has at least gpg 2.2.9. These instructions were tested on Windows 7, Windows 8.1, Windows 10, Arch Linux and Fedora 29.
Steps to configure git commit signing
- It is recommended that you have set up ssh, see e.g. help.github.com/en/articles/connecting-to-github-with-ssh (also when you don't use GitHub)
- Start (on Linux) a terminal or (on Windows) git bash, check with
git --version
that git is at least 2.19.1 and withgpg --version
that you are using gpg2.
If not, check with where gpg
(or which gpg
if the where
command is not available) that the top-most path is the git one.
- If you see no paths or not any one which has gpg2, try the
gpg2
command instead ofgpg
, sogpg2 --version
. If that works, you'll have to usegpg2
instead ofgpg
from now on. - If you see a git path but it's not the top one, put (on Windows)
alias gpg="'C:\path\to\Git\usr\bin\gpg.exe'"
in yourC:\Users\username\.bash_profile
, create the file if it doesn't exist, and restart git bash. Trywhere gpg
andgpg --version
again. From now on, wheregpg
is typed into a file you should replace it with'C:\path\to\Git\usr\bin\gpg.exe'
.
- Check in the output of
gpg --version
if the home directory is something like (on Linux)/home/username/.gnupg
or (on windows)/c/Users/username/.gnupg
. This directory doesn't have to exist, yet.
If the path is incorrect, try to change it - for example one time on Windows I saw my home was prefixed by the path in which I ran the command, so I put an alias in the .bash_profile
with alias gpg="gpg --homedir=/c/Users/s156757/.gnupg"
and restarted bash, then checked again.
- The next few steps are from the good Github's guide, preferably you check there if commands are still correct. First, generate a new GPG key pair (but do not install the gnupg tools!): Run
gpg --full-generate-key
- Select RSA and RSA and 4096 bits.
- As real name use your
user.name
as in your~\.gitconfig
. - As email, use the email from
user.email
in your~\.gitconfig
, making sure that this email is a verified email on GitHub. - If you want to try gpg-agent (you will have to provide your password at least once after each reboot) or if you are fine with an 'unverified' badge on GitHub, provide a password. Otherwise, leave it empty.
- Every time your want to check what keys you have, use
gpg --list-secret-keys --keyid-format LONG
. Do it now, and copy thekey_id
(as I will name your key from now on) from the outputsec rsa4096/key_id 2018-10-27 [SC] ...
. - Print the public key with
gpg --armor --export key_id
. - Add the GPG key to your GitHub account: go to
Settings | SSH and GPG keys
and add the public key block (including the header and footer). - Tell Git about your GPG key in Settings > Version Control > Git > Configure GPG Key as shown in Mahozad's answer, please give it an upvote or tell git manually:
git config --global user.signingkey key_id
. - If you had to use the
--homedir
option before, you need to make sure that when git starts gpg, the home is also properly changed. Create a fileC:\Users\username\start-gpg.sh
and put into itgpg --homedir=/c/Users/s156757/.gnupg "$@"
. Then rungit config --global gpg.program C:\\Users\\username\\start-gpg.sh
to tell git to use it. - Restart bash.
- Sign a commit with GPG with
git commit -S -m "signed commit"
and confirm that it is Verified on Github, you should see a little badge when you view your commit. - Set commits to be signed by default with
git config --global commit.gpgsign true
. Make a new commit in IntelliJ and verify if it was signed withgit verify-commit HEAD
.
Steps to make the commit signing happen automatically: three options
1. I have no passphrase on my key
You're done.
2. I want to try gpg-agent
For me this option didn't work: I still had to provide my passphrase often, though not always. But in theory this works:
- Update the cache time, in
C:\Users\username\.gnupg\gpg-agent.conf
: create file if it doesn't exist, adddefault-cache-ttl 34560000
andmax-cache-ttl 34560000
. - Restart gpg-agent using
gpgconf --kill gpg-agent
- Now you should have to enter your passphrase once when committing and then not anymore. Check that your commit is
Verified
on GitHub.
3. Pipe the passphrase in plaintext to gpg
This means that you never have to provide your passphrase, but for me this means that GitHub puts an Unverified
badge on my commit. Question here: The key whose key-id is in the signature did not sign this commit
- If you created it already, replace all of the contents of
C:\Users\username\start-gpg.sh
with the code below. If you didn't, create the file with the contents below, remove the--homedir
flag and rungit config --global gpg.program C:\\Users\\username\\start-gpg.sh
. In any case, restart bash.
Yes, you're going to place your password in plaintext on your computer! If you know a better way, please leave a comment...
# Passphrase-file-descriptor is set to 0 (STDIN), to use it --batch must be used
# The --pinentry-mode loopback is required since gpg 2.1.0 for --passphrase-fd
# The "$@" makes sure that whatever git wanted gpg to do, is still done
echo mypassphrase | gpg --homedir=/c/Users/username/.gnupg --passphrase-fd 0 --batch --yes --pinentry-mode loopback "$@"
- Commit and push and check that you were not asked for a passphrase, and that your commit is still
Verified
on GitHub.
Old answer for older git versions without gpg2
For the reference, here are the full instructions, or rather the steps I did to make it somewhat work. With 'work' I mean that commits are signed automatically, but there are two disadvantages:
- GitHub recognizes them as
unverified
:The key whose key-id is in the signature did not sign this commit. Someone may be trying to trick you.
The follow-up question regarding this is The key whose key-id is in the signature did not sign this commit - Creating a commit takes a much longer time, like five seconds instead of less than one.
If you get stuck, check the steps in the question to see if I had the same problem.
First few steps are from the good Github's guide: Generate a new GPG key pair
Add the GPG key to your GitHub account
Associate a verified (by GitHub) email with your GPG key and make sure the name and email in your
.gitconfig
are the same.Tell Git about your GPG key
Sign a commit with GPG and confirm that it is Verified on Github, you should see a little badge when you view your commit.
Set commits to be signed by default with
git config --global commit.gpgsign true
. Make a new commit and verify if it was signed withgit verify-commit HEAD
.The gpg version that comes with git is too old, so install Gpg4win (binary releases, at the bottom) which should install gpg 2. With
where gpg
you should see two path, of which probably the second is your new gpg, something likeC:\Program Files (x86)\GnuPG\bin\gpg.exe
. If not, try to install Gnupg 2 separately from the downloads page.I put
alias gpg="'C:\Program Files (x86)\GnuPG\bin\gpg.exe'"
to point thegpg
command to my new gpg in myC:\Users\username\.bash_profile
, restart Git Bash and check withgpg --version
that I'm now using gpg 2.Add a new environment variable called
GNUPGHOME
which points toC:\Users\username\.gnupg
. Reboot and check withprintenv GNUPGHOME
that you added it correctly.Make a script
C:\Users\username\gpg-no-tty.sh
and put into itecho passphrase | "C:\Program Files (x86)\GnuPG\bin\gpg.exe" --passphrase-fd 0 --batch --no-tty --yes "$@"
The reason you are putting your passphrase in plaintext here is because the --batch
option, which makes it all work, needs the passphrase fed. To me it seems like there should exist a better solution than saving your passphrase in plaintext on your computer, so please leave a comment if you found something better.
Point git to this script with
git config --global gpg.program C:\\Users\\username\\gpg-no-tty.sh
.Now test both in Git Bash and IntelliJ that you can commit, and verify that it worked by doing
git verify-commit HEAD
.
IDEA is not a terminal and cannot handle signing at the moment. See https://youtrack.jetbrains.com/issue/IDEA-127802.
There is a workaround though, check the https://youtrack.jetbrains.com/issue/IDEA-127802#comment=27-1866498