Using git with multiple identities
I want to keep my work and personal Github accounts separate. Here’s how I set that up:
Background
I’ve had a personal Github account – @rlipscombe – since 2010. In the past when I’ve needed to use Github for work, I’ve just used that account and added my work email to it.
This time, my work account is going to be managed by Corporate IT, and they’ve got more stringent security and sign-on requirements, and I don’t feel comfortable blurring that boundary, so I’m going to set up a separate Github account.
Because I still want to be able to access both my personal and work accounts from my work laptop, I need to set up git to manage multiple identities.
Create another SSH Key
Github doesn’t let you attach the same SSH public key to multiple accounts, so you’ll need to have one keypair per identity.
ssh-keygen -t ed25519 -f ~/.ssh/id_work -C "$USER@$(hostname)-Work"
Github has documentation for this process here, and you can add it to your new account by following the docs here.
My company requires that the SSH key be authorized for SSO, which is something I’ve never seen before, but it’s just a couple of clicks, so that’s easy enough.
Using the alternative SSH key
To use the new (non-default) SSH key, you need to use the GIT_SSH_COMMAND environment variable:
GIT_SSH_COMMAND='ssh -i ~/.ssh/id_work -o IdentitiesOnly=yes' git clone git@github.com:work-org/some-repo.git
I can see this getting very annoying very quickly.
I did some poking around on the Internet, and I can identify a few options, with varying effectiveness.
Use a separate SSH configuration, with a made up host name
Put something like this in your ~/.ssh/config file:
Host work.github.com
Hostname github.com
IdentityFile ~/.ssh/id_work
IdentitiesOnly yes
Then this will work:
git clone git@work.github.com:big-company/boring-crud.git
…and you can continue using your default identity otherwise. If you have multiple non-default identities, you can add extra prefixes:
# ...
Host personal.github.com
Hostname github.com
IdentityFile ~/.ssh/id_personal
IdentitiesOnly yes
git clone git@personal.github.com:you/exciting-side-project.git
That’s still a bit annoying, though, because you need to remember to add work. or personal. prefixes to select
between your two identities.
If you’re using the Code dropdown button in the Github UI, you have to remember to edit it every time. If someone sends you a repo URL in Slack, you have to remember to edit it, etc., etc.
Using includeIf
The idea here is that your ~/.gitconfig looks like this (the trailing slashes on the paths are required):
[includeIf "gitdir:~/Source/Work/"]
path = ~/Source/Work/.gitconfig
[includeIf "gitdir:~/Source/Personal/"]
path = ~/Source/Personal/.gitconfig
And then you have ~/Source/Work/.gitconfig that looks like this:
[core]
sshCommand = ssh -i ~/.ssh/id_work -o IdentitiesOnly=yes
…and so on, for each of your identities. It means that you need to keep your work-related and personal projects in
separate directories (until now, I just stuck everything in ~/Source).
Other rejected options
- Using something like
direnvto switch out theGIT_SSH_COMMANDenvironment variable when you change directories.- This would also work for the
GIT_AUTHOR_EMAIL,GIT_COMMITTER_EMAIL, etc. variables. - I rejected this because it would require all of my
.envrcfiles to remember to havesource_updirectives in them, and forgetting it just once would break things in weird ways.
- This would also work for the
- Replacing
git clonewith something that set the environment variable appropriately, and then setcore.sshCommandin the newly-checked-out.git/configfile.- git won’t let you replace built-in commands with aliases, so I’d have to use a shell alias or function.
- I rejected this because I thought it might be fragile.
- I was previously using https://github.com/DrVanScott/git-clone-init, but that only works to patch the configuration after you’ve cloned the repo.