Two GitHub accounts, one machine

5 min read Original article ↗

tldr; Use one SSH key per GitHub account, add a host alias in ~/.ssh/config, and set user.name and user.email per repo.

Using two GitHub accounts on the same machine is something I have done many times but end up having to look up how every single time. So I am writing this as a reference for my future self when I eventually have to set it up again.

It’s never fun when:

  • Git pushes go through the wrong GitHub account
  • commits authored with the wrong name or email

Here’s how I deal with it:

  1. create one SSH key per account
  2. give each account its own SSH host alias
  3. point each repo remote to the right alias
  4. set the repo’s local Git user config

Once this is set, personal and work repos on the same machine just work without having to constantly reconfigure things.

# Generate separate SSH keys for each account

Start by creating dedicated SSH keys for the accounts you want to add.

Follow the prompts and give the keys a clear name.

~/.ssh/id_ed25519_personal
~/.ssh/id_ed25519_work

Then add the public keys to GitHub.

1cat ~/.ssh/id_ed25519_personal.pub
2cat ~/.ssh/id_ed25519_work.pub

Copy the output and paste it into GitHub: GitHub -> Settings -> SSH and GPG keys -> New SSH key

Once the public keys are copied, add the ssh keys to the ssh-agent:

1ssh-add ~/.ssh/id_ed25519_personal
2ssh-add ~/.ssh/id_ed25519_work

All done. The new key is ready to use.

# Add SSH host aliases

Create or update ~/.ssh/config with a custom host entry for the second account:

Host github-personal
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_personal

Host github-work
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_work

github-personal and github-work is not a real servers but just aliases. An alias tells SSH that:

  • when someone says github-work
  • connect to github.com
  • use this specific private key

You can also setup just one alias for work and default to using the personal account like this:

Host github-work
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_work

But I prefer explicit config and set them up separately. YMMV.

# Add or update the repo remote

Now whenever you clone a repo, use the right alias. If you already have existing repos, update the remote to point to the new alias.

For a new repo:

1git remote add origin git@github-personal:username/repo.git
2git remote add origin git@github-work:username/repo.git
3
4# without alias, the default would look like this
5git remote add origin [email protected]:username/repo.git

For an existing repo:

1git remote set-url origin git@github-personal:username/repo.git
2git remote set-url origin git@github-work:username/repo.git
3
4# without alias, the default would look like this
5git remote set-url origin [email protected]:username/repo.git

The first repo with the github-personal uses the personal GitHub SSH key while the second one uses the github-work alias and therefore the work key.

Remember to update the alias in the git url every time you clone a repo.

# Override Git user settings per repo

This part is separate from SSH and just as important. Even if auth is correct, Git can still create commits with the wrong author details if your repo is using a global identity. You don’t want send work commits under you personal git user identity (Eg. authored by cheesyburger).

You can manually set the local Git identity in each repo like this:

1git config user.name "Snotty Botty"
2git config user.email "[email protected]"
3
4# confirm the values
5git config --local --list

But I prefer setting up conditional Git user config based on directory structure. It’s easier to manage when you’re working across many repos.

Group personal repos under one directory, like ~/workspace-personal/, work repos under another, like ~/workspace-work/ and write a conditional Git config using includeIf directive.

Write your git config at ~/.config/git/config:

1[user]
2  name = Snotty Botty
3  email = [email protected]
4  # OPTIONAL: if you also want to sign commits using the ssh key
5  signingkey = ~/.ssh/github_personal.pub
6
7[includeIf "gitdir:~/workspace-work/"]
8  path = config-work

Then in ~/.config/git/config-work:

1[user]
2  name = Captain Awesome
3  email = [email protected]
4  # OPTIONAL: if you also want to sign commits using the ssh key
5  signingkey = ~/.ssh/github_work.pub

Now put all your work repos under ~/workspace-work/ and they will automatically inherit the Git user config at ~/.config/git/config-work

Note: Be mindful, local Git config always overrides global Git config. So if you have already set up local Git user config, you can remove them using this command per repo.

1# check
2git config --local --list
3
4# remove local config
5git config --local --unset user.name
6git config --local --unset user.email

You can use includeIf conditional user config even if you use a single GitHub account. You can author the commits in personal and work repos under different names.

# Wrapping up

If you want to use two GitHub accounts on one machine, these are the thumb rules:

  1. one key per account
  2. one SSH alias per account
  3. the correct remote alias per repo
  4. the correct local Git identity using git includeIf directive

Once this is set, you can switch between personal and work repos without thinking about it.

Happy Git-ing!