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
direnv
to switch out theGIT_SSH_COMMAND
environment 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
.envrc
files to remember to havesource_up
directives in them, and forgetting it just once would break things in weird ways.
- This would also work for the
- Replacing
git clone
with something that set the environment variable appropriately, and then setcore.sshCommand
in the newly-checked-out.git/config
file.- 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.