Setup Git for Multiple Git Servers

Photo by Yancy Min on Unsplash

Setup Git for Multiple Git Servers

In my personal experience, it is fairly easy to mixed git account when pushing changes

Company I worked at using self-hosted gitlab, while I'm using github for personal works. I interact with git servers using ssh-based method so I need to generate SSH Key as git identification method. I just can just generate one ~/.ssh/id_rsa file as usual but I want to use different keys for different git servers.

I don't know how it will affect security, but I want to use different for each one. Here I will show how to utilize SSH Config to achieve this.

Configure SSH

Let's say we have these two git accounts:

ServerNameEmail
GitlabJohn Doejohn.doe.work@something.io
GithubJohn Doejohn.doe.personal@gmail.com

First, we need to create SSH Keys for these account. We may generate keys as many as we want. File permission with code 600 means you and only you that can read and modify this files.

Creating necessary files and directory

  1. We should create a directory where SSH will look for our keys. By default it will stored in ~/.ssh, so if this directory doesn't exists we need to create it first. The easiest way is to use mkdir ~/.ssh command.

  2. Next we need to store our SSH config somewhere. Usually SSH configuration stored ~/.ssh/config, under the directory we just created. Create the file if it's not exists yet, can be using touch ~/.ssh/config. We'll secure this file using chmod with 600 file permission.

So complete commands would be:

mkdir ~/.ssh
touch ~/.ssh/config
chmod 600 ~/.ssh/config

Now, we want to generate SSH keys using ssh-keygen. The key will be 4096 bit long so we should add -b 4096 argument. Choose key name to your liking, in this example we will use key id_rsa_personal. And same as the config file we need to set permission for generated keys using chmod.

# Generate SSH Keys for personal
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa_personal
chmod 600 ~/.ssh/id_rsa_personal
chmod 600 ~/.ssh/id_rsa_personal.pub

Repeat this step to generate key for work, just replace the key name e.g. id_rsa_personal to id_rsa_work.

Now, ~/.ssh directory should have required files, try running ls -la ~/.ssh and we should see 5 files:

  1. config
  2. id_rsa_personal
  3. id_rsa_personal.pub
  4. id_rsa_work
  5. id_rsa_work.pub

Copy public keys content to your git server profile, set the title to be useful to identify which device you generate these keys:

You can use pbcopy to copy file content to clipboard, you can do paste on your git server SSH setting page.

pbcopy ~/.ssh/id_rsa_personal.pub

Remember to only copy the public key content, the one eith .pub file extensions, the other file is your secret key and you need to keep it secure and not share it to anyone.

Configure Git

Until this, we we wont be able to interact with git server because git will confuse which key to use. We need to configure git which we will explore in the next section.

Load different SSH Keys for different Git server

Now we need to tell the git on our machine which keys it needs to use when interacting with which git server. Open file ~/.ssh/config in your favorite text editor and add these line. Save the file.

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

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

Now we can perform git operation to Github or Gitlab since git now knows which keys to use.

Load different SSH Keys for different Git server

We already setup the git identification with SSH method. Now we want to configure git to use different account on each interaction, the most important one is commit. When you do commit, git will record name and email of the comitters. Here is example of git log output, notice the Author is user.name and user.email combined.

commit f471c512e3413ffe6ed8d2ccd6403c50eccac58b (HEAD -> master)
Author: John Doe <john.doe.work@something.io>
Date:   Tue Sep 28 09:41:49 2021 +0700

    Commit message here.

Since we have different emails for each git servers, we don't want to commit to work projects using personal information, or vice-versa. We can configure git to use different account on each directory. Say we can organize our project such as:

  1. ~/work, and
  2. ~/personal respectively.

Separate git configuration for work and personal

The plan is to create separate config into files, and the tell git to load them based on where the git command called from. Create 2 files in home directory.

  1. ~/.gitconfig-personal
  2. ~/.gitconfig-work

The content of each file should reflect your git credentials, for example the content of ~/.gitconfig-personal in this example would be:

[user]
name = John Doe
email = john.doe.work@gmail.com

Do the same with ~/.gitconfig-work and fill your work git user.name and user.email.

Git reads configurations from ~/.gitconfig file, not from the 2 files we just created, unless we tell git. Create the files if it doesn't exists using touch ~/.gitconfig. Edit the file and put the following lines.

[includeIf "gitdir:~/personal/"]
  path = .gitconfig-personal
[includeIf "gitdir:~/work/"]
  path = .gitconfig-work

The file content is self-explanatory. But just to make sure we understand, I'll explain. This tells git if we run git from any directory under ~/personal/, says ~/personal/my-blog, git will use ~/.gitconfig-personal file and use the content inside when doing operations e.g. to set Name and Email of commits.

Summary

In my personal experience, it is fairly easy to mixed git account when pushing changes. On my machine, I set global git to use my personal git account. Meanwhile related to work, as soon as I pulled new repository, I need to update git config for that project to not use my personal git. But people forget, several times I pulled a repo and pushed to work project using my global git account which is my personal info. Git won't care about this, but not with Gitlab and Github. Your work/commits will not appear in these website if you put wrong account when doing commit.

This workaround have been working for me so well and I don't worry anymore about committing my changes using different account.

Resources