Using git with multiple identities
I want to keep my work and personal Github accounts separate. Here’s how I set that up:
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"
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 firstname.lastname@example.org: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
Host work.github.com Hostname github.com IdentityFile ~/.ssh/id_work IdentitiesOnly yes
Then this will work:
git clone email@example.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 firstname.lastname@example.org:you/exciting-side-project.git
That’s still a bit annoying, though, because you need to remember to add
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.
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
Other rejected options
- Using something like
direnvto switch out the
GIT_SSH_COMMANDenvironment variable when you change directories.
- This would also work for the
GIT_COMMITTER_EMAIL, etc. variables.
- I rejected this because it would require all of my
.envrcfiles to remember to have
source_updirectives in them, and forgetting it just once would break things in weird ways.
- This would also work for the
git clonewith something that set the environment variable appropriately, and then set
core.sshCommandin the newly-checked-out
- 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.