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:
- create one SSH key per account
- give each account its own SSH host alias
- point each repo remote to the right alias
- 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:
- one key per account
- one SSH alias per account
- the correct remote alias per repo
- the correct local Git identity using git
includeIfdirective
Once this is set, you can switch between personal and work repos without thinking about it.
Happy Git-ing!