Using Git with Multiple AccountsJanne Kemppainen |
Having to use multiple accounts with Git can be cumbersome from time to time. You need to make sure that your name and email match the account you want to use for each repository and you may need to type different credentials depending on the repo. In this post I'll show how to make your multi-account work with Git a pleasant experience.
These instructions aren't strictly specific to GitHub but I'm using that as an example. Also if you're new to Git and need a short introduction take a look at my post on Git essentials first.
Configure multiple SSH keys
There are two ways you can connect to GitHub, HTTPS and SSH. The first option uses your username and password and is generally simpler to set up. SSH requires that you configure authentication keys but it doesn't store your username and password unencrypted on your computer like git-credential-store does if you want Git to remember your credentials.
If you are using multiple GitHub accounts, for example one for private use and one for work, you need to configure SSH keys for each account separately. This is a requirement from GitHub, and if you tried to add an existing key to a second account you'd get the “Key is already in use” error message.
Note that if you're using a private GitHub Enterprise installation you won't necessarily need a separate SSH key for the public GitHub because they don't share authentication and are considered separate entities. Similarly, the same key should naturally work for GitLab or Bitbucket too.
To create a key for your account you need to use the
ssh-keygen command line tool:
>> ssh-keygen -t rsa -b 4096 -C "email@example.com"
The comment argument with your email address is optional and can be omitted. It is purely informational.
When you get the “Enter a file in which to save the key” prompt, type in a custom location such as
/Users/janne/.ssh/id_rsa_work. If you have for example multiple customers with a separate GitHub account for each one then you should probably include the customer name in the key filename to keep things organized.
After you have created the keys they need to be associated with the corresponding GitHub accounts. To add a SSH key log into your GitHub account and go to your account settings “SSH and GPG keys” section. Click “New SSH key” and copy the public key which is the file that has a
.pub extension to the input field. You can get the contents of the file for example by opening it in a text editor or with the
Next, we'll need a way for Git to know which key to use when interacting with a repository. This can be configured with the
~/.ssh/config file. Configure a host setting for each account that you want to use, for example like this:
Host github.com Hostname github.com User git IdentityFile ~/.ssh/id_rsa_personal Host github-work HostName github.com User git IdentityFile ~/.ssh/id_rsa_work
The host should be unique for each account so you can use
github.com for only one account, for example the one that you use the most. The others need to use something else such as
github-robot, and so on. The
HostName parameter should still always point to
github.com for all of them. You also need to set the correct
IdentityFile for each account.
Then when cloning the repositories you need to use the SSH method instead of HTTPS to the configured keys. The account that you configured with the
github.com host will work as is without the need to change anything.
For other accounts you'll need to edit the hostname in the clone command to match your configuration. For example with the above configuration you'd need to make your clone command look something like this:
>> git clone git@github-work:username/reponame.git
So instead of using
github.com you need to use
github-work to apply the correct identity file. After that you can use the repository normally.
Set correct email based on directory
Another thing that we need to configure is the email address to be used for the commits in each repository. Your global git configuration probably contains your personal email address but for work-related contributions you'll want to use the work email.
This can be configured on the repository level after cloning with a simple command:
>> git config user.email "firstname.lastname@example.org"
It works but you'll have to remember to do it each time you clone a new work-related repository. And if you forget the configuration you'll be making commits with the wrong identity. Therefore we'd better automate it!
Since version 2.13 Git has supported conditional configuration includes. It allows us to set up directory level Git configurations so that the correct settings are always applied. If you have all of your work code under the same directory such as
~/work you can create a special configuration in the
[user] name = Janne Kemppainen email = email@example.com [includeIf "gitdir:~/work/"] path = .gitconfig-work
The first part sets the global name and email address settings. These apply to all repositories unless explicitly overridden by local configurations. The
includeIf conditional configuration overrides these settings by loading configurations from a file called
~/.gitconfig-work which could look like this:
[user] name = Janne Kemppainen email = firstname.lastname@example.org
Now if you have a work repository such as
~/work/important-project you don't need to worry about the repository level configuration anymore. The conditional import will automatically switch to the correct name and email for all of your work repositories.
Use correct SSH keys automatically
Having to remember the correct custom hostname for each account while cloning a repository is still not the most convenient thing. Could we somehow use some conditional configuration to select the correct keys? Well, of course we can!
In the Git configuration there is the core.sshCommand setting that can be used to set a specific command instead of
ssh for fetch and push operations. If we combine this with the conditional configuration we get the best result that I could imagine.
All you need to do is to add the following configuration to your
[core] sshCommand = ssh -i ~/.ssh/id_rsa_work
As you probably guessed
-i is short for
identity_file. From now on all repositories in your
~/work directory will be using the work credentials automatically so you don't need to remember to change the hostname when cloning repositories.
Hopefully this has helped your Git workflow with multiple user accounts. How many accounts are you using? Tell me on Twitter!