Setting up git+ssh+gpg on Windows
Tags: git, tools, scoop, windows
Published: 2019-02-24 18:23:50

---
title: Setting up git+ssh+gpg on Windows
published: true
description: Setting up environment with `scoop`
tags: [git, tools, scoop, windows]
cover_image: https://thepracticaldev.s3.amazonaws.com/i/gt2y98rxqikknssd9dn2.png
---

Sometimes we all end up having to use Windows.
I was trying to avoid this, but it sneaks up on you.
So, how does one set up basic git with SSH authentication and GPG commit signing, for VS Code and command line?
Maybe I was spoiled by Linux community documentation, but I basically didn't get an answer. So, today we *investigate*!

**Not in scope**: We won't be:

- generating the SSH identity with `ssh-keygen -t rsa -b 4096 -C "YOUR.ACTUAL@MAIL.HERE"`
- or GPG key with `gpg --generate-key`,
- nor adding them to https://github.com/settings/keys.

This article assumes you want to use your existing keys. But all these are well-documented. If you disagree and would like me to post a writeup on those, please leave a comment.

We will be using `scoop` instead of `chocolatey`, so that our setup is unprivileged and confined to the local user.

We'll assume you don't have anything installed.
So let's open up PowerShell (**not** as administrator) and begin:

## Scoop

```powershell
# Enable powershell executables
Set-ExecutionPolicy RemoteSigned -scope CurrentUser
# Install scoop
iex (new-object net.webclient).downloadstring('https://get.scoop.sh')

# scoop uses aria2 for parallel downloads
scoop install aria2
```

## Git
```powershell
scoop install git
```
Now, if you are on Windows 10 and don't follow Windows news,
run `ssh -V` and prepare to be shocked.
Since April 2018, Windows ships with OpenSSH!
> some reports indicate that you may have to activate the feature as follows (I didn't have to):
> ```powershell
> Add-WindowsCapability -Online -Name OpenSSH.Client*
> ```
Since we are going for a minimal setup here, we will not install our own version.
We still have to add an environmental variable for `git` to start using it, though:
```powershell
[environment]::setenvironmentvariable('GIT_SSH', (resolve-path (scoop which ssh)), 'USER')
```
<small>Don't forget to restart PowerShell / VS Code or wherever you plan to use git after this to load the environmental variable.</small>

Now, let's continue configuring `git`:

```powershell
git config --global user.name "YOUR ACTUAL NAME HERE"
git config --global user.email YOUR.ACTUAL@MAIL.HERE
```
Let's print the config to verify, it should look something like this:

```powershell
git config -l --global
# user.email=YOUR.ACTUAL@MAIL.HERE
# user.name=YOUR ACTUAL NAME HERE
# credential.helper=manager
```
Now, let's add our actual key to `ssh`:

```powershell
ssh-add YOUR\KEY\PATH\id_rsa
```

<small>Note: If your key is located at `~/.ssh/id_rsa`, and you have `pshazz` installed, you can (re)open a powershell, and [`pshazz` will run `ssh-add`](https://github.com/lukesampson/pshazz/blob/e0cbd3fe165ea194a0d2e58001306b9cab22aa56/plugins/ssh.ps1#L52), adding it automatically (this will prompt you for the passphrase if you have one). I don't find it particularly valuable to keep your key there on Windows, so you can `ssh-add` it and then remove the file.</small>

Now, assuming you will be using GitHub (similar for gitlab et al.), let's do a test connection (and save GitHub's signature, otherwise VS Code will get confused and silently fetch forever):

```powershell
ssh -T git@github.com
# The authenticity of host 'github.com (192.30.253.112)' can't be established.
# RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8.
# Are you sure you want to continue connecting (yes/no)? yes
# Warning: Permanently added 'github.com,192.30.253.112' (RSA) to the list of known hosts.
```

At this point, we have working git, but the commits will not get signed yet.

## GPG

Now, the `git` package comes with a `gpg` executable, at:

```powershell
# It's my first time writing powershell, any advice welcome
join-path (scoop prefix git) 'usr\bin\gpg.exe'
```

Let's temporarily alias it to `gpg`! 
```powershell
sal gpg (join-path (scoop prefix git) 'usr\bin\gpg.exe')
```
Aside: `sal` is an alias <small>(*wow, much meta*)</small> for `Set-Alias`.
<small>But according to `alias alias`, `alias` isn't an alias for `Get-Alias`? 🤔🤔🤔</small></aside>

In my case it's a slightly older version than is available standalone.
```powershell
scoop info gpg
gpg --version
```
But, once again, we're going for a minimal setup.
So, let's just jam our key right on in there.

```powershell
# Enable signing all commits by default
git config --global commit.gpgsign true
```
Now, let's import our key:

```powershell
gpg --import C:\YOUR\KEY\LOCATION\_SOMETHNG_-private.{key,gpg}
```
You may also want to ultimately trust your key:

```powershell
$(echo trust; echo 5; echo y; echo quit) | gpg --command-fd 0 --edit-key YOUR.ACTUAL@MAIL.HERE
```
It is fine to remove your key file after this, it was imported into the gpg install.


Finally, let's install some more packages:

```powershell
# the default bucket doesn't include GUI applications such as VS Code
scoop bucket add extras

# check for (self)updates
scoop update
scoop update *

# install the good nice things
scoop install vscode pshazz
```

## **🎉 We are done! 🎉**

The result should look like this:

```powershell
git config -l --global
# user.email=YOUR.ACTUAL@MAIL.HERE
# user.name=YOUR ACTUAL NAME HERE
# credential.helper=manager
# commit.gpgsign=true

gpg -K
# C:/Users/YOUR_NAME/AppData/Roaming/gnupg/pubring.kbx
# ------------------------------------------------
# sec   rsa4096 2017-10-18 [SC]
#       8E84465BB27D2E97F5B379C0D41763D409EF23A0
# uid           [ultimate] YOUR ACTUAL NAME HERE <YOUR.ACTUAL@MAIL.HERE>
# ssb   rsa4096 2017-10-18 [E]
```

To test signing, make a commit:

```powershell
git init git-signature-test
pushd git-signature-test
echo "" > butts
git add butts
git commit -m Init
git log --show-signature
popd
rm -r -fo git-signature-test
```

The output should include "Good signature from" followed by `YOUR ACTUAL NAME HERE <YOUR.ACTUAL@MAIL.HERE>`.

**Edit**: It seems like we installed the whole `scoop` mostly just to get `git` :)
Originally this article included installing your own OpenSSH and GPG, and even something from `chocolatey`, but after reading GitHub issues and experimenting, it turned out that just this is plenty. 🎉