Challenge with multiple GitHub accounts
There are several great articles giving advice on how to handle multiple GitHub accounts. The one I liked in particular has a pretty self-explanatory title: Automatically use correct SSH key for remote Git repo
I value the article for two main reasons:
- It helped me solve my problem with the authentication agent
- It gave me an idea of how to automate the process even further
Authentication Agent
If you are reading this, I’d assume you are way too familiar with ssh-add technicalities. The problem I failed to realise at first was a mere fact that the additional ssh key is not stored permanently. Once I restarted my laptop or even just the terminal, the key was gone and I was pulling my hair trying to understand why the heck I couldn’t push to the remote GitHub repo anymore (since I did add the damn key, right?!). Obviously, ssh-add -L or ssh-add -l give the ultimate proof of what identities is the agent aware of.
There is another superb blog post addressing specifically this issue. Once again, the title says it all: Permanently Add SSH key ssh-add. As a Mac user I simply relied on Keychain:
ssh-add -K ~/.ssh/id_rsa_PERSONAL
Automation
Once the identities are under control and your pushes start to work again, there is one tiny bit left to resolve. With multiple identities the hosts in GitHub SSH links need to be kept in sync with your local ssh config (~/.ssh/config). That requires changing the links manually. Here is what I mean:
GitHub says: git@github.com:YOU/YOUR_REPO.git
Your ssh config dictates:
Host personal HostName github.com User git Hostname github.com PreferredAuthentications publickey Port 22 IdentityFile ~/.ssh/id_rsa_PERSONAL
Therefore, if you want to see your pushes work, you have no choice but to change the provided link before you go and clone the repo:
git clone git@personal:YOU/YOUR_REPO.git
Smart, but tedious.
One obvious solution to this problem is to use a bash script which would do the appropriate adjustment and run the git clone on your behalf using the modified link. How would you do it though? The only distinction in the ssh config are different identities. Apart from that, all the specified hosts look the same.
Tom Atkins’ blog post gave me the idea of using comments as annotations. Tom suggests, let me quote:
#user1 account Host github.com-user1 .. #user2 account Host github.com-user2 ..
Here is how I adopted his approach in my own config file:
Host work HostName github.com User git Hostname github.com PreferredAuthentications publickey Port 22 IdentityFile ~/.ssh/id_rsa Host personal HostName github.com User git Hostname github.com PreferredAuthentications publickey Port 22 IdentityFile ~/.ssh/id_rsa_PERSONAL
As you can see, now I do have a direct mapping between my GitHub users and the relevant host names (work, personal). The script which swaps github.com for one of the two configured host names is still in its infancy. However, it works already (on my machine, LOL!). Check it out on GitHub.
Suppose I have a personal repo – a fork of one of the Coursera’s projects. instead of tweaking the ssh link by hand and running git clone, I rather keep the link as is and pass it to my script.
$./wrapper.sh git@github.com:zezutom/ExData_Plotting1.git
Checking the git config in the cloned project confirms the host name was replaced as expected:
$ cd ExData_Plotting1 $ cat .git/config [core] .. [remote "origin"] url = git@personal:zezutom/ExData_Plotting1.git fetch = +refs/heads/*:refs/remotes/origin/* [branch "master"] remote = origin merge = refs/heads/master
Thanks for reading and stay tuned. Next time, I will talk you through the script in detail.