Simplifying Your Multi-Account Git Setup

Using git and GitHub with multiple SSH keys on the same machine

Vasilii Trofimchuk
Better Programming

--

Photo by Diego Jock on Unsplash

Do you have a habit of changing hostnames when you clone git repositories to use the private key and username from the right account? You can make your life easier, save time, and free your mind for more impactful work by placing your local projects in per-account root folders and accordingly updating your git configurations. Read on to learn how.

Imagine you have two accounts on GitHub (or GitLab, or Bitbucket, or any other repository hosting):

  1. Account A — your work account, and
  2. Account B — your personal account

These two accounts have their unique usernames and they use their unique private keys. When working with the code in these repositories locally you need a way to specify what username and what private key to use for each repository. You have two options to make both accounts work on the same machine.

A Quick and Dirty Way

To let your local git know what names and private keys to use, you can create two ssh configurations in ~/.ssh/config, that will contain something like the following:

Host github-work
Hostname github.com
IdentityFile ~/.ssh/id_rsa_account_a
Host github-personal
Hostname github.com
IdentityFile ~/.ssh/id_rsa_account_b

Every time you clone a work or a personal repository you will need to manually change the remote host from github.com to github-work or to github-personal. Additionally, after cloning, you need to set up a related git username and git email to the one associated with the related account.

It would work great but sometimes you might forget to change the hostname causing local git to use the default account, or you accidentally set user.email to your personal email on your work project.

All in all, apart from wasting your time on every clone, you sometimes make a mistake and realize it only after a push to remote causing inconvenience to the rest of your team. Gladly there is a better way.

A Better Way

By putting a structure around how you store your projects locally, you can supercharge your development processes and forget about changing clone URLs forever.

Step 1: Split projects into two sub-directories

~/
workspaces/
account_a/
project_panda/
project_tiger/
project_swan/
account_b/
project_mice/
project_cricket/
project_elephant/

Step 2: Modify git configuration

For your Account A, add the following configuration.

Update ~/.gitconfig to conditionally include custom account configuration for project under ~/workspaces/account_a directory:

[includeIf "gitdir:~/workspaces/account_a/“]
path = ~/.gitconfig_account_a

Now create ~/.gitconfig_account_a file to set up your Account A username and email and point to the ssh configuration with the private key:

[core]
sshCommand="ssh -F ~/.ssh/config_account_a"
[user]
name = Account A Name
email = account.a.email@example.com

Finally, create ~/.ssh/config_account_a file to specify github username and private key:

Host github.com
Hostname github.com
IdentityFile ~/.ssh/id_rsa_account_a
IdentitiesOnly yes
User account_a_user_name

A similar configuration goes for Account B:

In ~/.gitconfig:

[includeIf "gitdir:~/workspaces/account_b/“]
path = ~/.gitconfig_account_b

In ~/.gitconfig_account_b:

[core]
sshCommand="ssh -F ~/.ssh/config_account_b"
[user]
name = Account B Name
email = account.b.email@example.com

Lastly, create ~/.ssh/config_account_b:

Host github.com
Hostname github.com
IdentityFile ~/.ssh/id_rsa_account_b
IdentitiesOnly yes
User account_b_user_name

Step 3: Update remotes

If you previously used remotes with modified hostnames (for example, github-work and github-personal), you can now revert it to the original hostname github.com:

git@github-work:awesome_you/project_panda.git -> git@github.com:awesome_you/project_panda.git

Once remotes are updated, try it out and see if it works.

Step 4: Try it out

Now, every time you want to clone a repository for one of your accounts, go to a respective directory and use git commands as usual. Here is an example for a project in Account A:

# cd ~/workspaces/account_a
# git clone git@github.com:awesome_you/project_panda.git
# cd project_panda
# git config --get user.email
account.a.email@example.com

And the following is an example for a project in Account B:

# cd ~/workspaces/account_b
# git clone git@github.com:awesome_you/project_mice.git
# cd project_mice
# git config --get user.email
account.b.email@example.com

As you can see, projects have been cloned using related credentials for respective accounts without the need to modify clone URLs.

Managing multiple git accounts for the same SCM hosting provider is tricky and requires some tweaks in the git configuration. While, undoubtedly, you can use modified hostnames for different accounts, the approach is prone to errors and accidental commits with a personal account to your work repo. To level up your development processes, split your projects in separate root directories locally, and forget about headaches caused by fixing the author on committed changes once and for all.

--

--

Engineering Lead @ Square, Co-Founder of Sygn — on a journey to create a frustration-free payment experience