How to use different accounts and SSH keys on a per-git-repo basis
If you need to use more than one git account and SSH key, you’ll quickly run into the problem of per-repository configuration.
I was recently stuck having to migrate all my work repositories to a new, work-only account (thanks to a combination of auth changes and the lack of email configuration in Bitbucket).
Previously I’d used one Bitbucket account for everything, so had never had to do per-repository authentication in git. I found most tutorials skipped some detail or other, so this is the process that worked for me including the gotchas.
Create new SSH key
I didn’t want to share an SSH key across auth boundaries so I made a new one:
Remember to set a different filename, as you probably already have
id_rsa (here we’ll make it
id_rsa_user2 and pretend the first one was
id_rsa_user1 for ease of reference). Obviously set a good password too.
As it’s a new set of keys, ensure their permissions are correct:
$ chmod 600 ~/.ssh/id_rsa_user2 $ chmod 600 ~/.ssh/id_rsa_user2.pub
Finally, add the new key to your SSH agent:
$ ssh-add ~/.ssh/id_rsa_user2
Add the new public key to Bitbucket
In this case the config URL would be
https://bitbucket.org/account/user/user2/ssh-keys/. The only real trick here is being careful you put the right key into the right account.
Create SSH host aliases
You’ll need to create an alias for each key,
Host bitbucket.org-user1 HostName bitbucket.org User git IdentityFile ~/.ssh/id_rsa_user1 Host bitbucket.org-user2 HostName bitbucket.org User git IdentityFile ~/.ssh/id_rsa_user2
user2 are the Bitbucket usernames.
If config is a new file, you’ll need to set permissions:
$ chmod 600 ~/.ssh/config
Set URLs to use the aliases
For a new checkout, just clone via the alias and your remotes will be configured for you:
$ git clone origin firstname.lastname@example.org:foo/foo.git
For an existing checkout, update your remote URLs. You can check these with a verbose check:
$ git remote -v origin email@example.com:foo/foo.git (fetch) origin firstname.lastname@example.org:foo/foo.git (push)
To update the URL:
$ git remote set-url origin email@example.com:foo/foo.git
Configure user details per repo
Updating the name is optional, but you will need to set the appropriate email in each repo:
git config user.name "User One" git config user.email firstname.lastname@example.org
I found non-matching emails were rejected. That is, you can't claim to be using an email address attached to a different account.
What about other git hosts?
The process is the same regardless of git host, just sub in the URL as required.
All done - each repo should now work as normal, the most obvious side effect is having to add two keys when you start your SSH agent (on OSX you won't need to worry as keychain handles that for you). This process worked for me in OSX Terminal and Windows Subsystem for Linux (WSL).