Use multiple Git accounts from a single Linux machine

As developers, you must have used git & git based platforms like GitHub, GitLab, Bitbucket, etc. on a daily basis. Let's say you have your personal GitHub & GitLab accounts associated with your personal email id. Now, you join a company where you have been given a new official email id & you have to create new GitHub & GitLab account with that email id. Assume you have the following active accounts:

  1. github.com (you@gmail.com)
  2. gitlab.com (you@gmail.com)
  3. github.com (you@yourcompany.com)
  4. gitlab.yourcompany.com (you@yourcompany.com)

You can clearly not use a single SSH key for accessing all your repositories. Also in global .gitconfig file you can't create two user tags for both the email ids.

How to manage multiple SSH keys in Git Configs then?

Option 1 (meh!)

Create two users in your OS, one for Personal use & other for your Company. Switch your profile accordingly and code.

Option 2

A little setup as suggested below should enhance your user experience. Do as follows:

Generate keys

Generate two SSH keys. The following command will output 4 files, two with .pub extensions & two without extensions.

ssh-keygen -t rsa -b 4096 -C "your@gmail.com" -f "personal_id_rsa"  
ssh-keygen -t rsa -b 4096 -C "your@yourcompany.com" -f "yourcompany_id_rsa"  

NOTE: If you already have the keys then simply rename them appropriately.

Set SSH config

Open ~/.ssh/config file. If not found then create one. You can refer to the config keywords here.

Host github.com  
    HostName github.com
    IdentityFile ~/.ssh/personal_id_rsa

Host gitlab.com  
    HostName gitlab.com
    IdentityFile ~/.ssh/personal_id_rsa

Host yourcompany.github.com  
    HostName github.com
    IdentityFile ~/.ssh/yourcompany_id_rsa

Host gitlab.yourcompany.com  
    HostName gitlab.yourcompany.com
    IdentityFile ~/.ssh/yourcompany_id_rsa

In these entries HostName can be same, but you can't have the same Host patterns for two entries. This can be anything that makes sense to you. A sub-domain makes sense to me, and it's a format that I remember when cloning repositories.

Adding SSH keys to the platforms

  1. Go GitHub/GitLab settings & search for SSH tab.
  2. Here you can add your SSH keys.
  3. Click the New SSH key button, enter whatever you want for title and paste your key.
    • For personal accounts key is the contents of personal_id_rsa.pub file.
    • For company accounts key is the contents of yourcompany_id_rsa.pub file.

Cloning repositories

Personal projects can now be cloned by following the as usual method:

  • git clone git@github.com:personal/personal-github-project.git
  • git clone git@gitlab.com:personal/personal-gitlab-project.git

Your personalidrsa SSH key will verify your access.

For your company's GitLab projects, they can be used by following as usual methods because its a complete different host (gitlab.yourcompany.com).

  • git clone git@gitlab.yourcompany.com:yourcompany/yourcompany-gitlab-project.git

For the company's GitHub projects however, one alteration needs to be made. In a command like this:

  • git clone git@github.com:yourcompany/yourcompany-github-project.git

github.com should be replaced by yourcompany.github.com (or whatever matches the SSH rules you set up earlier).

  • git clone git@yourcompany.github.com:yourcompany/yourcompany-github-project.git

This will ensure that the yourcompanyidrsa SSH key is used to verify your identity with github.com or gitlab.yourcompany.com

Commit repositories

Git uses a username to associate commits with an identity.
To commit to any repository you must need a username set, either globally or for each repository separately.

To set it globally you have to edit ~/.gitconfig file.
Now the problem is you can set one username in .gitconfig file. But we have to set two different username here, one for personal repositories & another for company repositories.

With git 2.13 you get a feature called conditional includes.
Here the includeIf directive comes into play. Basically, with this directive, you can import an additional configuration file based on a condition being true.

So as per our problem description paste following in your ~/.gitconfig file:

[user]
    name = Your Name
    email = you@gmail.com
[includeIf "gitdir:~/Workspace/YourCompany/"]
    path = ~/.gitconfig-yourcompany
[commit]
    gpgSign = false
[gc]
    autoDetach = false

Then finally create ~/.gitconfig-yourcompany file & paste following:

[user]
    name = Your Name
    email = you@yourcompany.com

Now all your SSH keys & git configs are set. Now whenever you will create a project in ~/Workspace/YourCompany/ directory that will be associated with your company email id & in other places everything will be associated with your personal email id.

Hope this helps!