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:

$ ssh-keygen

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, ~/.ssh/config:

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

Note that user1 and 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 git@bitbucket.org-user1:foo/foo.git

For an existing checkout, update your remote URLs. You can check these with a verbose check:

$ git remote -v
origin  git@bitbucket.org-user1:foo/foo.git (fetch)
origin  git@bitbucket.org-user1:foo/foo.git (push)

To update the URL:

$ git remote set-url origin git@bitbucket.org-user1: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 user1@example.com

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).