Connecting to GitHub from TortoiseHg Using SSH Keys

Step-by-step instructions to set up a completely seamless integration between TortoiseHg and GitHub. No passwords. No Pageant. No friction of any kind.

Connecting to GitHub from TortoiseHg Using SSH Keys

In this article, I'm going to take you step-by-step through setting up a fully transparent connection between a Mercurial repository in TortoiseHg and that same repository running in Git and hosted on GitHub.  

The hggit extension keeps everything in sync, and a saved PuTTY session means you don't need to start Pageant or enter a password* every time you interact with GitHub from TortoiseHg.

Let's get started.

* You have the option of providing a passphrase when you create your SSH key pair, but if you forgo that option you can achieve passwordless integration between TortoiseHg and GitHub.

Prerequisites

You will need the following things:

As an alternative to performing a traditional install of those last three requirements, you can use the Chocolatey package manager for Windows.  With that, you can install the requirements from an admin cmd window using the following commands:

choco install tortoisehg
choco install openssh
choco install putty

High-Level Overview

Here are the basic steps.  We'll cover the details below.

  1. Generate a public-private SSH key pair
  2. Add the public key to your GitHub account
  3. Convert the private key to a PuTTY-compatible format
  4. Create a named PuTTY SSH session
  5. Enable hggit in TortoiseHg
  6. Clone an existing GitHub repository using the git+ssh protocol and your named PuTTY SSH session from step 4

Generating the Public-Private Key Pair

We're going to use ssh-keygen.exe as recommended by GitHub.

  1. Open a non-admin cmd window
  2. Change directories to C:\Windows\System32\OpenSSH\
  3. Run the following command: ssh-keygen -t ed25519 -C "{your GitHub email address}"
  4. Press [Enter] to accept the default folder: C:\Users\{your_login}\.ssh\
  5. [Optional] Enter a passphrase when prompted or just press [Enter] to skip
  6. This will create two new files:
    • a private key with no extension
    • a public key with extension .pub
  7. [Optional] Rename the private key by giving it the extension .privatekey to make it easier to identify later
C:\Windows\System32\OpenSSH>ssh-keygen -t ed25519 -C "mike@grandjean.net"

The above command created two files in my C:\Users\Mike\.ssh\ folder, which I renamed as follows:

  1. id_ed25519 --> github-mwolfe02_ed25519.privatekey
  2. id_ed25519.pub  -->  github-mwolfe02_ed25519.pub

NOTE: If ssh-keygen.exe is not in C:\Windows\System32\OpenSSH\, first make sure that the OpenSSH Optional Windows Feature has been installed.  If it has, then I recommend using the Everything utility to search for the executable.

Add Public Key to GitHub Account

  1. Sign in to GitHub
  2. Click on your profile photo in the top right then choose Settings
  3. Click on "SSH and GPG keys" then click [New SSH Key]
  4. Upload the .pub file you created earlier

Convert Private Key to PuTTY Format

PuTTY cannot directly use the private key we generated using ssh-keygen.  The good news is that it is easy to convert the key to a format PuTTY can use with the puttygen.exe utility.

  1. Open PuTTY Key Generator (puttygen.exe)
  2. Click the [Load] button
  3. Switch the file extension filter from .ppk to All Files (*.*)
  4. Browse to find the .privatekey file, select it, and click [Open]
  5. Click [OK] to acknowledge the successful import of the private key
  6. Click [Save private key] and save the key with the default .ppk (PuTTY Private Key) extension

Connect via PuTTY

Create the Configuration in PuTTY

  1. Open PuTTY
  2. Set Host Name to github.com
  3. Click on Data in the nav tree
  4. Enter git for the Auto-login username (do NOT enter your GitHub user name)
  5. Expand the SSH node in the nav tree
  6. Click on Auth in the nav tree
  7. Click [Browse...] and select the *.ppk file you just saved
  8. Click on Session in the nav tree
  9. Enter github in the Saved Sessions text box*
  10. Click [Save] to save the named session

* You can name the session anything you want.  If you name it something other than "github," you will need to use that other name when you create the remote path in TortoiseHg later.

Set the Host Name to "github.com".
Set the auto-login username to "git".
Load the PuTTY-formatted private key file (*.ppk).
Give the session a name and save it.

Test the Configuration

Before you try to rely on this configuration in TortoiseHg, you should first test it from within PuTTY.  This is a bit tricky to do, because GitHub does not actually provide any shell access.  The way to test it, then, is to enable session logging before attempting to open the connection.

  1. Click on Logging in the nav tree
  2. Switch "Session logging" radio button to (o) All session output
  3. Click [Open] to open a session
  4. Click [Yes] to cache the GitHub Host Key fingerprint (you only need to do this once)
  5. Open the putty.log file
  6. Look for the words, "Hi {your_github_user_name}! You've successfully authenticated, but GitHub does not provide shell access."

If your test succeeded, congratulations!  You can move on to the next step.  Otherwise, you will need to troubleshoot any error messages that got logged to the PuTTY log file before continuing.

My PuTTY log file includes a couple of previous failed attempts to connect to GitHub.

TortoiseHg Setup

If you made it this far, the hard part is done.  You're almost there!

Enable the hggit Extension

  1. Open TortoiseHg
  2. Go to File > Settings
  3. Click on Extensions in the nav pane
  4. Check the box next to [√] hggit
  5. Click [OK]
  6. Click [OK] to acknowledge the message about restarting TortoiseHg
  7. Close and re-open TortoiseHg

Clone an Existing Repository

  1. Create an empty folder in File Explorer
  2. Right-click inside the empty folder and choose TortoiseHg > Clone...
  3. In the Source combo box, enter the following: git+ssh://github/twinbasic/twinbasic.git/
  4. Click [Clone]

This will clone the twinBASIC GitHub repository which (at the time of writing) comprises only four small files (README.md, 2 issue templates, and FUNDING.yml).  You won't be able to push changes to this repository, but you will be able to push changes to a repository that you own on GitHub.

Use the following format for the path to the repository in TortoiseHg:

git+ssh://{saved_PuTTY_session_name}/{account_name}/{repository_name}

For example, here's my company's private access-modules repository:

We use the following path in TortoiseHg to connect to it:

git+ssh://github/gb-inc/access-modules/

Support for Multiple GitHub Profiles

Note that "github" in the connection path above refers to the saved PuTTY session with the same name that we created earlier.  If you had multiple GitHub profiles, each one could be created with their own set of keys and corresponding PuTTY saved session.

Then you could have, on the same machine, the following remote paths:

git+ssh://gh_bruce_wayne/wayne-ent/orphanage-crm/

git+ssh://gh_batman/gotham/vigilante-erp/

Conclusion

There you have it.  If you are like me, you can now use your beloved TortoiseHg while still collaborating with the rest of the development world on GitHub.

Because, really, what's the point of having cake if you can't eat it, too?

Image by Victoria_Borodinova from Pixabay

All original code samples by Mike Wolfe are licensed under CC BY 4.0