Using Two git/GitHub Identities

5 min read Original article ↗

Kjetil JD

Working with more than one identity for git/GitHub is a bit of a hassle. Usually I can commit and push using my main GitHub identity on both my own and my clients’ projects. But, a couple of times, I have had requests to use a separate identity, for some reason or another. After a bit of research I have found an almost hassle-free solution.

There are two main issues with using more than one identity for git and GitHub:

  1. You want to use the right user.name and user.email depending on project
  2. For key-based authentication to work you need to use the right ssh-key for each identity

Earlier I have used manual procedures, or custom shell commands, to do this. This new approach I have found uses new(ish) features in git and a couple of ssh-tricks to solve the problem.

I have tested the procedure on macOS 10.13 (High Sierra), but it is likely to work in other *nix(-like) environments, too.

Pre-requirements

I assume you have a working git/GitHub-user. You are using OpenSSH and the normal git client, and the configurations are in your home directory: a .gitconfig-file and an .ssh-folder.

Your git version needs to be 2.15 or newer:

$ git --version
git version 2.15.1 (Apple Git-101)

Mine looks ok, if I needed to I could have installed a newer git-version e.g using Homebrew.

Next, I assume you have generated a public/private key-pair for ssh and uploaded your public key to GitHub.

You can check that your setup works, like this:

$ ssh git@github.com

GitHub should immediately reply:

Hi <your main identity username>! You’ve successfully authenticated, but GitHub does not provide shell access.
Connection to github.com closed.

I assume you have set your main git user.name and user.email globally, using:

$ git config --global user.name "<name for main identity>"
$ git config --global user.email "<email address for main identity>"

You can check by doing this (outside any git project-directory):

$ git config user.name
<name for your main identity should appear here>
$ git config user.email
<email address for your main identity should appear here>

Ok — with your main identity working, we’re ready to get your second identity in place.

A second git & GitHub identity

Our goal is to get another git & GitHub identity working, and not have to do anything when switching between projects.

Some obvious steps first:

  1. You need to sign up for a second GitHub account, let’s call it SecondIdentity.
  2. Then you need to generate a new set of ssh-keys, with a new name. I am assuming you store your second private key in ~/.ssh/id_rsa_second_identity.
  3. Then upload the public key (~/.ssh/id_rsa_second_identity.pub) to your SecondIdentity on GitHub, like you did with your main identity.
    It is important that your two GitHub accounts know you based on different public keys.

I am assuming that you can keep the projects that use your second identity in one common folder, let’s call it ~/Projects/second_identity.

Ok, let’s start on the less obvious stuff:

Make sure you have this in your ~/.ssh/config-file:

Include config.d/*         # bet you haven’t seen this before :)Host github.com
IdentityFile ~/.ssh/id_rsa # whatever your main identity
# private key file is called
Host github* # common settings
HostName github.com
User git # not a must but useful
AddKeysToAgent yes # really nice to have
IdentitiesOnly yes # a MUST for our scenario

Then you need a new file: ~/.ssh/config.d/second_identity with the following content — this file will be included by the Include-directive above:

Host github.com-SecondIdentity
IdentityFile ~/.ssh/id_rsa_second_identity

Now we need to set up user.name and user.email for Second Identity.

At the end of your ~/.gitconfig-file you must add (this is what requires git 2.15 or newer):

[includeIf "gitdir:~/Projects/second_identity/"]
path = ~/Projects/second_identity/.gitconfig-second_identity

And finally create the file: ~/Projects/second_identity/.gitconfig-second_identity with the appropriate content:

[user]
name = <name for your SECOND identity>
email = <email address for your SECOND identity>

If you have done all this you should be pretty much good to go, but let’s check.

Verifying the setup

This is what we expect from ssh:

$ ssh github.com 
Hi <your main identity username>! You’ve successfully authenticated, but GitHub does not provide shell access.
Connection to github.com closed.ssh

And:

$ ssh github.com-SecondIdentity
Hi <your SecondIdentity username>! You’ve successfully authenticated, but GitHub does not provide shell access.
Connection to github.com closed.

Yay!

When outside ~/Projects/second_identity/ you should still find that:

$ git config user.name
<name for your main identity should appear here>
$ git config user.email
<email address for your main identity should appear here>

To check that user.name and user.email is correct for SecondIdentity we first have to create (or clone) a repo inside the ~/Projects/second_identity/ folder.

Let’s create a repo:

$ cd ~/Projects/second_identity/
$ mkdir testrepo
$ cd testrepo
$ git init

Now we can check inside the testrepo-folder:

$ git config user.name
<name for your SECOND identity should appear here>
$ git config user.email
<email address for your SECOND identity should appear here>

And the final piece of the puzzle:

When you clone a repo for SecondIdentity (inside ~/Projects/second_identity/) you must replace github.com with github.com-SecondIdentity in the url, e.g:

$ git clone git@github.com-SecondIdentity:someorg/somerepo.git`

That way ssh will know that it should use the ssh-credentials for your SecondIdentity in this repo.

And that’s all!

… well almost …

As

noted — if you already had projects in your ~/Projects/second_identity/ folder you will need to update some configuration in those git repos. This one-liner will take care of that for you:

sed -i '' 's/git@github\.com:/git@github\.com-SecondIdentity/' ~/Projects/second_identity/*/.git/config

Kjetil JD is an experienced developer working for Kodemaker in Oslo, Norway. He is passionate about good code, better tests and awesome practices.

Press enter or click to view image in full size

Edit: fixed typo in ~/.ssh/config — it should say Include config.d/* not Include .config.d/*. Thanks to

for pointing out there was something wrong!

Edit 2: Addendum on pre-existing projects — Another thanks to

!