Klaus Elk Books

SSH and Git

How to setup SSH and git to handle multiple accounts

This page describes how to handle multiple git accounts using SSH on Windows. Note that mail accounts etc in the below codesnippets are not the real ones, but the process has been tested and works.

In most cases HTTPS is the easiest way to work with e.g., GitHub. However, if you have more than one account, HTTPS becomes a mess and may not work at all. You may have multiple accounts if you are e.g. working with your companys GitHub, but also contributing to an Open Source project using a private mail-address. Another example could be working on GitHub and GitLab.

The examples are created using Git Bash (the one installed with git on a windows PC). Some commands are the same in Power Shell, while others have 1:1 pendants.

The overall concepts

These are the basic steps:

One time operations:

More frequent operations (can be scripted):

Now follows an example where I work on a private project as well as on company projects on the same PC.

Generate key-pair - for each user-account.

The first key-pair I call personal to avoid mixing with private used in keys.Thus id_ed25519_personal_github is my private personal account key and id_ed25519_personal_github.pub is my public personal account key. Note that you don't see my keys anywhere here - only 'fingerprints' and hashes. I run all the code in git bash.

$ ssh-keygen -t ed25519 -C "kelk@mail.com" -f ~/.ssh/id_ed25519_personal_github
Generating public/private ed25519 key pair.
Enter passphrase for "/c/Users/kelk/.ssh/id_ed25519_personal_github" (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /c/Users/kelk/.ssh/id_ed25519_personal_github
Your public key has been saved in /c/Users/kelk/.ssh/id_ed25519_personal_github.pub
The key fingerprint is:
SHA256:nBsIGF5p+ZnIrNIkwZWNjRU4XHbdlCoBaJRv/WKeJeY kelk@mail.com
The key's randomart image is:
+--[ED25519 256]--+
|  oo+*=+ oo..    |
|   *O.=.o  o     |
|  o=o=... .      |
|. . o+ = o       |
|.. o.o.o=        |
| .  + += =       |
|.. .  = *        |
|..o    E         |
| .o.             |
+----[SHA256]-----+

Add PRIVATE key to SSH Agent

The private key is in the file that does not have the "pub" extension.

$ ssh-add ~/.ssh/id_ed25519_personal_github
Identity added: /c/Users/kelk/.ssh/id_ed25519_personal_github (kelk@mail.com)

ADD SSH (pub) key in GitHub - for relevant repos (just root)

Go to github.com, login, click on your profile image (top right corner) and go to settings. Find 'SSH and GPG keys'. Click, and then press green button 'New SSH key'. When asked, hand over the file with the "pub" extension.

Repeat all the above for the other account

I call it "work" in the sample code.

Create the switch-field for SSH and git

Create a new file for the switch-field for the repos and keys - here "C:\Users\kelk.ssh\config". Put in the details for the two accounts.Note that the 'Host github.com-personal' refers to github.com, while 'personal' is just a name I invented. This name is reused when setting up git in the next step.

# Personal GitHub account 
Host github.com-personal
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_personal_github.pub

# Work GitHub account 
Host github.com-work
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519.pub

Tell the repo which SSH-key and host it belongs to

In the repo for the personal work:

$ git remote set-url origin git@github.com-personal:personal_user/personal_repo.git

In the repo for the work work:

$ git remote set-url origin git@github.com-work:work_user/work_repo.git

Testing

Now test:

$ git push
Enumerating objects: 86, done.
Counting objects: 100% (86/86), done.
Delta compression using up to 8 threads
Compressing objects: 100% (73/73), done.
Writing objects: 100% (76/76), 4.68 MiB | 4.18 MiB/s, done.
Total 76 (delta 15), reused 0 (delta 0), pack-reused 0 (from 0)
remote: Resolving deltas: 100% (15/15), completed with 4 local objects.
To github.com-personal:personal_user/personal_repo.git
cdfb3fc..394f75f  master -> master

Make it reusable

I quickly learned that the agent closes down at various occasions. Thus, the keys and config are persisted in ~/.ssh, and the git config also stays, but the agent needs to get on the road again.

IF the authentication agent is not running, this is how you start it:

eval "$(ssh-agent -s)"

You can (off course) check the state and content of the agent with

ssh-add -l

In my case I needed to rerun (e.g. in startup-file):

ssh-add ~/.ssh/id_ed25519_personal_github 
ssh-add ~/.ssh/id_ed25519	

Testing again:

$ ssh-add -l
256 SHA256:nBsIGF5p+ZnIrNIkwZWNjRU4XHbdlCoBaJRv/WKeJeY kelk@mail.com (ED25519)
256 SHA256:8T2DQzgPy5QOsT35CwCRjiowqHa8ksfR+A9Or1KMO6M kelk@work.com (ED25519)

Setting it all up in .bash_profile

I have added the following code in .bash_profile - if you use Power Shell it is NOT the same:

#Is the SSH agent running? Presence of the file is NOT enough
env_file=~/.ssh/agent.env

agent_is_running() {
[ -f "$env_file" ] || return 1
source "$env_file" > /dev/null
[ -S "$SSH_AUTH_SOCK" ] && ps -p "$SSH_AGENT_PID" > /dev/null 2>&1
}

if ! agent_is_running; then
echo "Starting new ssh-agent..."
eval "$(ssh-agent -s | grep -v '^echo ')" > "$env_file"
source "$env_file" > /dev/null
fi

#Add keys if none are loaded (risking that one is and the other isn't
ssh-add -l > /dev/null || ssh-add ~/.ssh/id_ed25519  ~/.ssh/id_ed25519_personal_github

#Note that this can start multiple instances of ssh-agent - not really a problem

hint: In these scripts returning 1 is false and 0 is true 😃

Moving to another PC

I guess not everyone considers it safe to copy the keys - with the config - from one PC to another, by copying the contents of the ~/. ssh folder. But the fact that it works, proves that there is no other steps involved. The above defines all steps and all participants.Should you decide to copy a given setup, then don't forget the .bash_profile. The alternative is to make new keypairs, register the public ones at e.g., github and feed the new private ones to the ssh-agent.

Black Elk

© 2025 KlausElk.com