Skip to content

Instantly share code, notes, and snippets.

@mflatischler
Last active February 26, 2024 22:18
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mflatischler/4d4b45f1b89a1a6f6151 to your computer and use it in GitHub Desktop.
Save mflatischler/4d4b45f1b89a1a6f6151 to your computer and use it in GitHub Desktop.
Setting up Git for Windows and Gpg4win (WIP)

Setting up Git for Windows and Gpg4win

This article will help you set up your development environment with git and gpg to sign your commits and manage your gpg keys for different personas.

This article will not guide you step by step to install the programms needed, explain how gpg works nor will it tell you why you should sign your git commits.

Prerequisites

  • You are on a Windows (7+) system
  • You have installed [msysgit]
  • You have installed Gpg4win
  • You may have already generated your gpg keys with msysgit's gpg or with Gpg4win

Generating your gpg keys

Open %UserProfile%/AppData/Roaming/gnupg/gpg.conf and add the following lines:

personal-digest-preferences SHA256
cert-digest-algo SHA256

The create your keys either with GPA, Kleopatra or on the command line.

Setting up msysgit's gpg

Download and extract iconv.dll to /path/to/Git/bin

Open /path/to/Git/etc/profile and change the following line:
export GNUPGHOME=~/.gnupg
to
export GNUPGHOME="/c/Users/UserName/AppData/Roaming/gnupg"

Open Git bash and enter the following:
$> gpg --list-key
You should now see your keys

If you have generated your keys first with msysgit's gpg (on Git bash) then copy the files under
%UserProfile%/.gnupg to %UserProfile%/AppData/Roaming/gnupg

Export and import your public and secret keys between the two locations, otherwise.

Git Bash uses GPG 1.4.x and Gpg4win uses 2.0.x

TODO

Managing multiple keys in a git repository

by mflatischler under CC-BY-SA

@exoosh
Copy link

exoosh commented Feb 15, 2022

An alternative to copying is to create a junction point or symbolic link from %APPDATA%\gnupg to %USERPROFILE%\.gnupg, that is either (after moving the old %USERPROFILE%\.gnupg out of the way):

mklink /j "%APPDATA%\gnupg" "%USERPROFILE%\.gnupg"

or (this requires to be run in an elevated prompt, unless the option to create symbolic links was enabled for the current user, e.g. via the Git for Windows installer):

mklink /d "%APPDATA%\gnupg" "%USERPROFILE%\.gnupg"

From experience the respective files can live side by side peacefully and you don't have to remember copying settings around or some such. Of course it's perfectly reasonable, too, to use your method if there are reasons which make my described method unsuitable.

Copy link

ghost commented Nov 22, 2022

Useful information, thanks

@mflatischler
Copy link
Author

@Fouad-Bechar I'm sorry, the manual is outdated and works no more in current versions as of writing.
The git bash included in recent releases are already updated to 2.x … I'm not sure

@mflatischler
Copy link
Author

I mean, the GPG version in git bash is surely 2.x upwards

@exoosh
Copy link

exoosh commented Nov 22, 2022

@Fouad-Bechar I'm sorry, the manual is outdated and works no more in current versions as of writing. The git bash included in recent releases are already updated to 2.x … I'm not sure

Yes it is:

❯ git --version
git version 2.38.1.windows.1
❯ /usr/bin/gpg --version
gpg (GnuPG) 2.2.29-unknown
libgcrypt 1.9.3-unknown
Copyright (C) 2021 Free Software Foundation, Inc.
License GNU GPL-3.0-or-later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Home: /c/Users/oschneider/.gnupg
Supported algorithms:
Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA
Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
        CAMELLIA128, CAMELLIA192, CAMELLIA256
Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2

Copy link

ghost commented Nov 22, 2022

Thanks for this correction.

@exoosh
Copy link

exoosh commented Nov 22, 2022

Side-note: in ~/.gitconfig I also (meanwhile) have this because otherwise the gpg command from Git for Windows is going to take precedence:

[gpg]
        program = C:\\Program Files (x86)\\GnuPG\\bin\\gpg.exe

Adjust the installation path as appropriate on your system. (This means the junction point business isn't strictly needed, if you get Git to use the gpg.exe you want)

Copy link

ghost commented Nov 22, 2022

The path is correct for me and no problems so far, thanks

@gremo
Copy link

gremo commented Jul 5, 2023

Without changing the gpg program, you get (when trying to sign a commit):

gpg: invalid size of lockfile 'C:/Users/<User>/AppData/Roaming/gnupg/pubring.kbx.lock'
gpg: cannot read lockfile
gpg: can't lock 'C:/Users/<User>/AppData/Roaming/gnupg/pubring.kbx'
gpg: invalid size of lockfile 'C:/Users/<User>/AppData/Roaming/gnupg/gnupg_spawn_agent_sentinel.lock'
gpg: cannot read lockfile
gpg: can't connect to the agent: Invalid argument
gpg: keydb_search failed: No agent running
gpg: skipped "13698640": No agent running
gpg: signing failed: No agent running
error: gpg failed to sign the data
fatal: failed to write commit object

@Rabadash8820
Copy link

Rabadash8820 commented Feb 14, 2024

@exoosh's comment explains how to make git use Gpg4win when signing commits/tags. Quoting it here for completeness:

Side-note: in ~/.gitconfig I also (meanwhile) have this because otherwise the gpg command from Git for Windows is going to take precedence:

[gpg]
        program = C:\\Program Files (x86)\\GnuPG\\bin\\gpg.exe

Adjust the installation path as appropriate on your system. (This means the junction point business isn't strictly needed, if you get Git to use the gpg.exe you want)

However, to make gpg commands themselves use Gpg4win in git bash, I found the easiest solution to be simply defining an alias.
That is, add the following line:

# ~/.bashrc (add it if it's not there)
alias gpg='/c/Program\ Files\ \(x86\)/GnuPG/bin/gpg.exe'

Then just source ~/.bashrc or restart git bash to apply this alias. Now commands like gpg --list-keys will give you the same output in git bash or in cmd/PowerShell.

I should note that, with the above commands, @mflatischler's original instructions to install iconv.dll and export GNUPGHOME are unnecessary.

UPDATE: If you use a separate git client, you might need to point that program at the Gpg4win executable for signing as well. I just ran into an issue where GitKraken was set up to use gpg as the GPG program, which is what I what I wanted when making commits from GitKraken, as the gpg command pointed at the Gpg4win executable. However, GitKraken was set up to sync preferences with my global gitconfig, so it overwrote the config change recommended above (and apparently processes started by a shell, like git, don't honor shell aliases).

@exoosh
Copy link

exoosh commented Feb 15, 2024

However, to make gpg commands themselves use Gpg4win in git bash, I found the easiest solution to be simply defining an alias. That is, add the following line:

# ~/.bashrc (add it if it's not there)
alias gpg='/c/Program\ Files\ \(x86\)/GnuPG/bin/gpg.exe'

@Rabadash8820 Good point! Just one remark, depending on the details it may be somewhat more robust to use:

alias gpg="$(printf "%q" "$(cygpath -amF 42)")"'/GnuPG/bin/gpg.exe'

The -F allows you to use one of the folder IDs for well-known shell folders.

PS: originally gave another method, but that turns out to be troublesome thanks to the quoting and escaping requirements by Bash.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment