Managing Multiple Git Accounts Like a Pro
Table of Contents
Managing multiple SSH keys for connecting to different account on various git repositories hosting platform (eg. Github, Bitbucket or Gitlab) is very hard trust me. For each project you have to choose which SSH key you want to use and then enter email/password is too much.
First of all you can just use one SSH key for everything, SSH keys are used to verifying your identify. But make sure you have a different SSH key for each of your device (easier to decommission the device)
Problem statment
I am trying to commit to different accounts in Github from the same machine. I had two SSH keys for each account. It was hell.
Right now, I don’t need to think about anything.
Solution
Switching accounts on Github
You can switch between two accounts on Github
- Click on the profile icon
- Click on
Add Account
to add your secondary account
Now you can switch between both profiles easily
1. Setup for different profiles
Lets assume you want have two profiles on Github one for personal and one for work
In order to use two profiles, you need to create two main directories, one for personal and one for work. Now keep in mind to clone/create repos accordingly. Personal repos must go into personal folder and similarly for work repos
2. Generate SSH keys
ssh-keygen -t ed25519 -C "your_personal_email@example.com" -f ~/.ssh/<personal_key>
You can optionally add a passphrase
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 "your_personal_email@example.com" -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
Do this for you work mail
ssh-keygen -t ed25519 -C "your_personal_email@example.com" -f ~/.ssh/<work_key>
To update the passphrase for your SSH keys:
ssh-keygen -p -f ~/.ssh/<private_key>
3. Adding the SSH Keys
Now we need to add those keys we created to our system.
First let’s start the SSH agent
eval "$(ssh-agent -s)"
and then
ssh-add -K ~/.ssh/<personal_key>
ssh-add -K ~/.ssh/<work_key>
The -K
flag in ssh-add
is specific to macOS, and it adds the passphrase of the private key to the keychain. This means that once you’ve added the key to the keychain, you won’t be asked for the passphrase again when using the key.
4. Edit you SSH config
If you don’t have a SSH config inside ~/.ssh
, then create one using touch ~/.ssh/config
Edit it to the following
Host personal
HostName github.com
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/<personal_key>
Host work
HostName github.com
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/<work_key>
5. Add public keys to hosts
We will add the public key part of our keys to the right profiles on Github
To copy public key of the generated keys use this
pbcopy < ~/.ssh/<personal_key>.pub
or just output it and copy it
cat ~/.ssh/<personal_key>.pub
To add the public key part go here. Select Authentication Key and give a suitable Title.
Additionally if you want to sign your commits add the same public part again but this time as a Signing Key
6. Updating your gitconfigs
This is the most crucial part. We will be making custom .gitconfig
for each of our profile
Create dotfile inside each of those folders we created earlier, you can give any suitable name to those dotfile
This is how the final file structure should look like
/<some_folder>/
|__work/
|_.gitconfig-work
|__personal/
|_.gitconfig-personal
Now, copy these to the dotfiles and fill properly the values. If you are not signing key then remove it form the config.
# ~/<path_to_personal_folder>/.gitconfig.pers
[user]
email = your_personal_email@example.com
name = Your Name
signingkey = ~/.ssh/<personal_key>.pub
[core]
sshCommand = "ssh -i ~/.ssh/<personal_key>"
# ~/<path_to_work_folder>/.gitconfig.work
[user]
email = your_work_email@google.com
name = Your Name
signingkey = ~/.ssh/<work_key>.pub
[core]
sshCommand = "ssh -i ~/.ssh/<work_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, if you were using the SSH config file to use different SSH keys, you would need to create and remember an arbitrary prefix like first.github.com and then remember to use that domain each time you want to clone a repository with this account. This can be too much trouble.
7. Global Config Update
This is the magic part
Updating your global .gitconfig
, which is present at ~/.gitconfig
, i.e the home directory
[init]
defaultBranch = main
[gpg]
format = ssh
[commit]
gpgsign = true
[includeIf "gitdir:~/<path_to_work_folder>/"]
path = ~/<path_to_work_folder>/.gitconfig-work
[includeIf "gitdir:~/<path_to_personal_folder>/"]
path = ~/<path_to_work_folder>/.gitconfig-personal
[core]
excludesfile = ~/.gitignore
[init]
defaultBranch = main
- When you run git init, the default branch will be named main instead of the older default master.
[gpg]
format = ssh
- Tells Git to use SSH keys for GPG signing commits/tags.
[commit]
gpgsign = true
- Enables GPG/SSH signing for all commits by default. Ensures commit authenticity.
[includeIf "gitdir:~/<path_to_work_folder>/"]
path = ~/<path_to_work_folder>/.gitconfig-work
- If a Git repo exists inside <path_to_work_folder>, Git will include settings from .gitconfig-work file for that repo.
[includeIf "gitdir:~/<path_to_personal_folder>/"]
path = ~/<path_to_personal_folder>/.gitconfig-personal
- Similar to above, but for personal projects.
[core]
excludesfile = ~/.gitignore
- Specifies a global
.gitignore
file. Patterns in~/.gitignore
will be ignored by all repos.
Single Profile
If you just want to setup just a single account on Github then follow till Step 5, the update your global .gitconfig
as follows
[init]
defaultBranch = main
[gpg]
format = ssh
[commit]
gpgsign = true
[user]
email = your_personal_email@google.com
name = Your Name
signingkey = ~/.ssh/<personal_key>.pub
[core]
sshCommand = "ssh -i ~/.ssh/<personal_key>"
[core]
excludesfile = ~/.gitignore
Notes
- These steps are macOS specific in some cases, and will also work for Linux system.
- For windows, the steps are same just commands are different.
- This are my preferred config settings