Github multiple accounts with same email

This article was originally published in our UncaughtException blog. Read this article in there by following this link.

Cover photo by Brina Blum on Unsplash.

I previously wrote about setting up multiple GitLab accounts, which works by relying mostly on SSH config files and using custom hosts as remotes for git repositories. You can read it by following this link: Setting up multiple GitLab accounts

The previous setup works, but I find it inconvenient having to use custom hosts when cloning repositories or for git remotes all the time, like:


git clone [email protected]:work/repository.git

I recently (almost) had to deal with the same scenario, on GitHub this time (hence the title), so I decided to check if I can achieve a better setup. Turns out that there’s a better way to do it — one that does not rely on custom hosts or modifying any SSH config file.

In this article, we are going to assume that we have two GitHub accounts, [email protected] and [email protected]. When working on work-related projects we want to commit and push our changes using our work account, while using our personal account for everything else.

We’re also going to assume that we’ve already defined global configs telling git to use our personal account. See this guide on how to do that.

Generate SSH keys for each user

GitHub does not allow us to use the same SSH key in multiple accounts, so we’ll have to create separate keys for each account. We can create SSH keys and add them to our SSH agent by following this guide from the GitHub Documentation.

Once we’re done, we will have two sets of SSH keys, e.g.:

  • ~/.ssh/id_rsa and ~/.ssh/ (let’s use this for our personal account)
  • ~/.ssh/work_key and ~/.ssh/

Now add the SSH keys to their corresponding GitHub accounts. This guide shows us how to do that.

Committing as the correct user

We then modify our ~/.gitconfig file to use our work account when we are inside a work-related repository. We are going to use “Conditional Includes” for that, which dynamically adds/removes configuration based on certain conditions. Let’s add the following snippet to our ~/.gitconfig file:

[includeIf "gitdir:/path/to/work/repository/"] [user] email = "[email protected]"

This makes git override our global configs and use [email protected] when committing changes inside the work repository. When in any other repository, our personal account will be used.

Do this for all work repositories

The way I personally structure my repositories on my file system is I place all work-related repositories inside the ~/work directory. This makes it easier to enable the configs above for all work-related repositories by just using the work directory in the includeIf directive:

[includeIf "gitdir:~/work/"]

Pushing as the correct user

When we push our commits now, they will be pushed to our personal GitHub account, even though we’ve already committed them using our work email. That’s because under the hood, git uses SSH, and SSH uses the id_rsa key by default. So when GitHub receives the push, it will try to determine which user pushed the commits based on the SSH key used, which will turn out to be our personal account.

We can resolve this by using the work_key SSH key when pushing to our work repositories. In SSH, this can be done through the -i flag, like so:

$ ssh -i ~/.ssh/work_key ...

We can configure git to use a custom SSH command like above by setting core.sshCommand. And since we only want to set it when we’re inside any work repository, we also conditionally include it inside the includeIf directive:

[includeIf "gitdir:/path/to/work/repository/"] [user] email = "[email protected]" [core] sshCommand = "ssh -i ~/.ssh/work_key"

These configs now make git commit using our work email, as well as make GitHub associate commits with our work account when we push them 🎉.


We’ve managed to configure git to use different configs when committing and associating these commits to different GitHub accounts when pushing, based on what repository we are performing those changes — and we used conditional includes in git’s config file to achieve that.

I like this way better than the previous setup since it’s more convenient to use (no more custom hosts) and all the config changes only affect git (no more changing of SSH config files).

If you deal with these multiple GitHub accounts in a different way, please feel free to share with us how you do it as well!

Disclaimer: although the title mentions GitHub, this cheat sheet is also applicable for the other major VCS platforms such as Gitlab and Bitbucket. Not using these? Don’t worry, you can still make great use of this cheat sheet to level up your .gitconfig game (look at step n°7).


Let’s imagine a scenario: you’ve just joined a new company, it’s your first day and you need to set up your new machine. The first thing you do is to rush to get your own GitHub SSH key and install it so you can still work on your hobby project.
A bit later that day, you are finally able to login to your organization repository and you now need to install this key as well to be able to start working.

This is where you realize it’s essential to know how to manage multiple Git configs on the same machine safely.

Want to set up this straight once and for all? We have you covered!
Take a look at the cheat sheet below! (you can also bookmark or share it)

One key insight from our State of Secrets Sprawl 2021 is that 85% of all the secrets we catch by live monitoring GitHub are exposed through developers’ personal repositories, and a large share of them are in fact corporate secrets.

Multiple hypotheses can explain why this happens. Of course, we cannot discard malicious behaviors, which include corporate resources hijacking and other shady motives. But the sheer scale of the phenomena hints at something else: we are convinced that most of this happens because error is human and misconfiguring Git is easy. You think that you are git push ing your work with your pro account (by the way, secrets should never enter any repo), while you’re actually using your personal one…

Furthermore, any Git repo has a memory that is not easy to rewrite (that’s a feature!). If you want an awesome cheat sheet for rewriting the Git history, check it out!

First things first: SSH or HTTPS?

Most VCS support authentication with SSH or HTTPS: to make things easier, always prefer using SSH where possible.
Git does not cache the user’s credentials by default, so with HTTPS, you need to re-enter them each time you perform a clone, push, or pull.
On the other hand, SSH is safer and, when set up correctly (which will be once you follow this guide), you can completely forget about it!

A quick reminder on how it works

When you hear about an SSH key, most of the time it’s a shortcut to refer to an SSH key pair, composed of a public and a private key, which are cryptographically linked.

The public key, as the name suggests, is openly distributed and shared with all parties. It is used to encrypt messages that can only be decrypted by its private counterpart.

For the connection to be secured, it is essential that the private key remains secret.

The strength of the entire connection lies in the fact that the private key is never revealed, as it is the only component capable of decrypting messages that were encrypted using its own public key.

Note that the SSH protocol uses a mix of asymmetric and symmetric encryption as well as hashing, and the former is not used to encrypt the entire SSH session. Instead, it is only used as a final step to authenticate the client before starting a session. You can learn more about the protocol here.


Now that you understand the basics of SSH, there is one simple rule to follow:

one SSH keypair = one Git config

The problem is now to manage safely multiple SSH keys and make sure you always use the appropriate one.
Let’s start from the beginning, generating a new key pair for your personal account:

1. Generate an SSH key

ssh-keygen -t ed25519 -C "[email protected]" -f ~/.ssh/<personal_key> 

ED25519 are recommended for security and performance, but RSA with a sufficient length is also a valid alternative:

ssh-keygen -t rsa -b 4096 -C "[email protected]" -f ~/.ssh/<personal_key> 

-C is for adding a comment, it can be anything but it will be helpful to know the email associated with your account
-f is to define a filename, and creating a key with a descriptive name will help you remember which key is used for which user/remote

2. Add a passphrase

Next, you will be prompted to add an (optional) passphrase. We recommend you do so because it adds an extra layer of security: if someone gains access to your computer, your keys will be compromised unless they are attached to a passphrase.

To update the passphrase for your SSH keys:

ssh-keygen -p -f ~/.ssh/<personnal_key>

You can check your newly created key with:

ls -la ~/.ssh

which should output <personal_key> and <personal_key>.pub.
By default, ssh searches for filenames of public keys looking like id_<algorithm>.pub, but in our case this is not a problem since we are going to specify what keys to use next.

3. Tell ssh-agent

We will use ssh-agent to securely save your passphrase. Make sure the ssh-agent is running and add your key (the -K option is to store the passphrase in your keychain, macOS only).

eval "$(ssh-agent -s)" && ssh-add -K ~/.ssh/<personal_key> 

4. Edit your SSH config

If you don’t have one, create an SSH config file
touch ~/.ssh/config and add the following contents to it:

Host * AddKeysToAgent yes UseKeychain yes IdentityFile ~/.ssh/<created_key>

Here we are setting Host to * for every key because we will use Git configs to select the appropriate SSH key based on profiles, which will give us a bit more flexibility (more on that later).

5. Copy the SSH public key

(<personal_key>.pub) to your VCS of choice (GitHub, GitLab or BitBucket etc…)


tr -d 'n' < ~/.ssh/<created_key>.pub | pbcopy


xclip -sel clip < ~/.ssh/<created_key>.pub


cat ~/.ssh/<created_key>.pub | clip

6. Structure your workspace for different profiles

Now, for each key pair (aka profile or account), we will create a .conf file to make sure that your individual repositories have the user settings overridden accordingly.
Let’s suppose your home directory is like that:

/myhome/ |__.gitconfig |__work/ |__personal/

We are going to create two overriding .gitconfigs for each dir like this:

/myhome/|__.gitconfig|__work/ ||__personal/ |_.gitconfig.pers

7. Set up your Git configs

# ~/personal/.gitconfig.pers [user]email = [email protected] = Your Name [github]user = “mynickname” [core]sshCommand = “ssh -i ~/.ssh/<personal_key>”
# ~/work/ [user]email = [email protected] = Your Name [github]user = “pro_name” [core]sshCommand = “ssh -i ~/.ssh/<professional_key>”

Here we tell Git which key to use by making explicit the SSH command (the -i option is for specifying an identity file or key). This gives us more control, for instance, imagine you have multiple accounts on the same host (like, if you were using the SSH config file to use different SSH keys, you would need to create and remember an arbitrary prefix like and then remember to use that domain each time you want to clone a repository with this account. In our opinion, it is less flexible and a bit cumbersome.

This is what you global .gitconfig can look like:

# ~/.gitconfig [includeIf “gitdir:~/personal/”] # include for all .git projects under personnal/ path = ~/personal/.gitconfig-pers [includeIf “gitdir:~/work/”]path = ~/work/.gitconfig-work [core]excludesfile = ~/.gitignore # valid everywhere

Of course, because many settings will probably be common to the two configurations (like your name or your editor preferences), you can set them here.

As a reminder, Git uses 3 overriding levels for configuration: system, global and local (project). More information here on config options.

To see a list of all config the options

man git-config

To check your activated config options

git config --list

8. Repeat for every account/profile

You can repeat these steps for all your VCS accounts and forget about it from now on!

You’re done!

you can now choose to, clone your repo, add or change your remote with:

git clone [email protected]<>:<username>/<repo_name>.git
git remote add origin [email protected]<>:<username>/<repo_name>.git
git remote set-url origin [email protected]<>:<username>/<repo_name>.git

Pro Tip: use the includeIf statement to setup platform-specific configs

[includeIf "gitdir:/Users"] path = ~/.gitconfig-macos[includeIf "gitdir:C:"] path = ~/.gitconfig-windows[includeIf "gitdir:/home"] path = ~/.gitconfig-linux

For more cheat sheets, subscribe to the blog below to receive them directly in your mailbox!

Written by Jane