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:
- You want to use the right
user.name
anduser.email
depending on project - 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:
- You need to sign up for a second GitHub account, let’s call it
SecondIdentity
. - 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
. - Then upload the public key (
~/.ssh/id_rsa_second_identity.pub
) to yourSecondIdentity
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 calledHost 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!