Using Two git/GitHub Identities

Kjetil JD
4 min readApr 23, 2018

--

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 Ivan Bolhar 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.

Edit: fixed typo in ~/.ssh/config — it should say Include config.d/* not Include .config.d/*. Thanks to Ivan Bolhar for pointing out there was something wrong!

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

--

--

Kjetil JD

An experienced developer in Oslo, Norway. He is passionate about good code, better tests and awesome practices.