I ran into an interesting issue this week on my Mac – but I imagine it would be the same on Linux too. I use GitHub with ssh key access and have two accounts there. One is personal and the other is used for work. The issue came up when I wanted to commit some changes to a work repo. I had managed to clone the public repo, but now when updating it, it kept throwing the error that my personal identity had no access to the Repo.

True. My personal identity did not have access to this repo, but I wanted to use my work identity but could not figure out how to set that up with git. Now, Macs are a very particular beast so their implementation of ssh may be a bit different from linux or Windows – but I think the solution I found works for other OSs too.
On the Mac, ssh keys are stored in the .ssh folder in the home directory (~/.ssh) and the ssh agent has to have the correct identity available to it. Let us say that my keys are called personal and work with the corresponding personal.pub and work.pub files stored in the .ssh directory. In case this is a bit confusing, you will need to read up a bit on ssh basics here (they use the ssh host option in their example).
ssh-add -L # lists the loaded identity
ssh-add -D # removes all identities from the agent
ssh-add <path> # adds an identity to the agent
Now the simplest way would be to remove all identities and then add the work identity as follows:
ssh-add -D
ssh-add ~/.ssh/work
A git push at this point would resolve the issue. If you are happy with this solution, then great – if you are lazy, but somewhat disciplined, another solution would be the one offered here.
In brief, the solution is based on maintaining a folder structure to separate the identities. Using the personal folder uses the personal identity and using the work folder uses the work identity. It does this by creating two identity-specific config files and in the main config file, using an IF statement called “includeIf” which chooses the correct config file. More examples of includeIf in use are here.
Example of the identity-specific config file named .gitconfig-personal
[user]
name = Kailash Kalyani
email = private@email.com
[core]
sshCommand = ssh -i ~/.ssh/personal #the path following -i points to your personal key
And in the .gitconfig file,
[includeIf "gitdir:~/code/work/"]
path = ~/.gitconfig-work
[includeIf "gitdir:~/code/personal/"]
path = ~/.gitconfig-personal
So, I tested this and at first, I got an error, but I realized that my ssh agent needed a purge, so I did
ssh-add -D #delete all identities in the agent
And that resolved the issue going forward. Cloned repositories could be easily moved into the personal or work folders since the repository-specific information is contained in the cloned folder.
There were several alternatives that I rejected to get to this solution. Here are two that I looked into:
Option 1:
One that was a completely useless diversion was git-credential-manager – reason was that I was using ssh to connect to git, had it been credentials like username and password, that may have been a better option – but it was not for me.
Option 2:
Using .ssh/config file – found the solution here.
Basically it is using a modified ssh config file.
# Account 1 - Default GitHub account
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/personal
IdentitiesOnly yes
# Account 2 - Second GitHub account
Host github-account2
HostName github.com
User git
IdentityFile ~/.ssh/work
IdentitiesOnly yes
and when using git clone, one needs to use the correct address:
# Clone with Account 1 (default):
git clone git@github.com:account1/repo-name.git
# Clone with Account 2:
git clone git@github-account2:account2/repo-name.git
Note: Use github-account2 as the host to ensure that account2’s SSH key (id_rsa_account2) is used.
So, to summarize, there were two potential options on resolving the challenge of using multiple ssh identities in git:
| git includeIf | ssh hosts | |
| Pros | Existing repositories will working without changes, as long as the repo is moved into the correct local folder. The setup is a one-time thing and no additional changes need to be made, except to maintain the folder structure. | Easy to manage on a repository basis, by ensuring that the correct host alias is used when cloning a repo or creating a new one. |
| Cons | Folder structuring may not meet your needs | The aliases need to be consciously used consistently to ensure correct function and behavior. |
I am for git includeIf for my use-case.
