DEV Community

Bruce MacKenzie
Bruce MacKenzie

Posted on • Updated on

Managing Multiple Git Accounts on a single machine

Introduction

Suppose you want to work with git repositories whose remotes are authenticated with different user accounts. Maybe you have work and personal GitHub accounts, or you work with repositories from multiple hosting services like GitLab or Sourcehut.

The simplest solution is to clone the repositories using HTTPS (instead of SSH). But who wants to enter a username and password for every authenticated command? This post will demonstrate an SSH-based configuration for seamless operations.

Ready? Let's get into it.

Prerequisites

Your remote git accounts (e.g. with GitHub or GitLab) are configured for SSH authentication, and your machine is configured for SSH authentication with one of these accounts.

If not, refer to GitHub's website for setup instructions, or the instructions provided by the hosting service of your choice.

SSH Key Setup

SSH keys are stored in ~/.ssh/ as public/private key pairs. By default the files are named after the encryption algorithm; for RSA you will find:

id_rsa
id_rsa.pub
Enter fullscreen mode Exit fullscreen mode

or for ed25519:

id_ed25519
id_ed25519.pub
Enter fullscreen mode Exit fullscreen mode

Copy the second pair of keys you wish to authenticate with to ~/.ssh/. Give them a unique name to set them apart from the first pair, e.g.:

id_rsa -> id_rsa_gitlab
id_rsa.pub -> id_rsa_gitlab.pub
Enter fullscreen mode Exit fullscreen mode

Set correct file permissions for private and public key files:

chmod 600 id_rsa_gitlab # only owner can read/write
chmod 644 id_rsa_gitlab.pub # owner can read/write, everyone else can read
Enter fullscreen mode Exit fullscreen mode

Git Configuration at Repository Level

This setup is the simplest method.

git config core.sshCommand "ssh -o IdentitiesOnly=yes -i ~/.ssh/id_rsa_gitlab -F /dev/null"
Enter fullscreen mode Exit fullscreen mode

If you only require alternate authentication with a few repositories, this may be good enough. But if you want a single configuration that works across all repos in your user environment, continue reading below.

SSH Config Entry

To make this work with a single configuration in your user environment, we will use the SSH config.

Make SSH aware of the additional keys by editing ~/.ssh/config.

If the file doesn't exist create it first:

touch ~/.ssh/config
chmod 600 ~/.ssh/config
Enter fullscreen mode Exit fullscreen mode

Add Host entries to the file:

# GitHub account
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_rsa

# GitLab account
Host gitlab.com
HostName gitlab.com
User git
IdentityFile ~/.ssh/id_rsa_gitlab
Enter fullscreen mode Exit fullscreen mode

When performing SSH authentication, the correct keys are determined by matching the config entry with the user and host names in the repository's remote URL.

To confirm an existing repository is configured to use SSH check the remote origin URL:

git remote -v
Enter fullscreen mode Exit fullscreen mode

To change the remote URL run the command:

git remote set-url origin git@github.com:<user>/<repository>.git
Enter fullscreen mode Exit fullscreen mode

To do this with a new repository clone with the SSH - not HTTPS - URL:

git clone git@github.com:<user>/<repository>.git
Enter fullscreen mode Exit fullscreen mode

For example:

git clone git@github.com:bruc3mackenzi3/go-microservice-template.git
Enter fullscreen mode Exit fullscreen mode

Entries for the Same Host

The example above will not work if both accounts are with the same host. For this a host alias is required:

# Work GitHub account
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_rsa

# Personal GitHub account
Host github.com_personal
HostName github.com
User git
IdentityFile ~/.ssh/id_rsa
Enter fullscreen mode Exit fullscreen mode

github.com_personal is just an alias, anything will work here.

Now, with one of the commands provided above, clone or edit the remote origin URL to use the alias. E.g.:

git@github.com_personal:bruc3mackenzi3/go-microservice-template.git
Enter fullscreen mode Exit fullscreen mode

Optional - Configure User Name and Email

It's also a good idea to set the user name and email for the repository. Even though this isn't used in the authentication process, this information shows up in commits and is used by GitHub to associate with a user account. Since you're reading this article, chances are your global Git configuration is set to another account.

Before changing, you can check the current value by running:

git config user.email
Enter fullscreen mode Exit fullscreen mode

To set a different email:

git config user.email <your-github-account-email>
Enter fullscreen mode Exit fullscreen mode

Note this sets user.email in the repository configration file, .git/config. If you saw a different email prior, chances are it was set in the global configuration and is still present. It is this email that will continue to be used in other repositories, unless they also overwrite the global user.email value with their own configuration.

You can confirm this by getting all values for an option:

git config --get-all user.email
Enter fullscreen mode Exit fullscreen mode

Repeat the same for username with the same commands, by replacing user.email with user.name

  1. Verifying the configuration works To verify the setup is working, we need to perform a git operation that requires priveledged access to a repository. If you went with the cloning option in section #3, and that repo is private then you've already confirmed it's working! Another way to verify is by pushing a new branch:
git checkout -b test-ssh-config
git push --set-upstream origin test-ssh-config
Enter fullscreen mode Exit fullscreen mode

Conclusion

To explore this topic further, you can check out GitHub documentation on managing multiple accounts.

Thank you for checking out this post on improving development workflows with git repositories from different user accounts. I hope you find this configuration handy in creating a more seamless development experience. Happy git push'ing!

Top comments (0)