I recently started a new job, and with it came a new problem. I had finished outfitting my work machine with all the niceties I normally enjoy – DropBox, Homebrew, MacVim, Xcode dev tools, rvm, node, my .vim directory, my .ssh keys, and some approximation of my usual .bash_profile, to name a few – when it came time to clone my first repo to work on. This employer uses GitHub.
Problem: I couldn’t clone it using ssh as I would normally. I made sure to generate a new key and upload the pubkey to GitHub, but I was getting the message:
ERROR: Repository not found. fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists.
I tried cloning the repo via http, and this worked but forced me to enter my GitHub credentials repeatedly, especially when pushing/pulling multiple branches. I could not stand for this! Github clearly recognized my rights to write, but failed to connect up my key to my account.
After a bit of runaround, confusion over who needed to manage my key (this was my first experience with GitHub organizations, which also have the concept of deploy keys, whatever they are) and reading through git and ssh verbose output to determine GitHub was accepting the wrong key, I finally hit upon the answer to the problem, apparently the only solution from what I’ve read: .ssh/configure – a config file I didn’t even have on my machine to begin with. The default config (on Mac running Mountain Lion) lives in /etc/ssh/config, and you can start by copying this file into your .ssh directory. There are lots of options – mostly commented out – and plenty of explanatory comments to go with them.
What wasn’t immediately clear to me from the comments in the file, or from the manpage for ssh, was exactly how Host directives work. Apparently a Host config groups a number of settings together for hostnames designated, but actually allows ssh (and through it, git) to treat these hostnames as aliases for real hostnames. So for my work project, I use a Host that chooses the specific IdentityFile I want for my second (work-only) GitHub account/key combo. Then I lie to git, setting the remote URL to a nonexistent hostname, which ssh will unravel and substitute for the real one.
Here’s what my .ssh/config file looks like:
Host github.com-workaccount HostName github.com User git IdentityFile ~/.ssh/work_rsa IdentitiesOnly yes
Now to change an existing repo’s remote URLs, you can either edit the .git/config file directly, or issue the following command (which is safer):
git remote set-url origin firstname.lastname@example.org:owner/project.git
After that you should be able to push changes with no problem.
It’s pretty sneaky, counterintuitive stuff, but I’m finally able to push/pull changes without being asked for my login 4 times. Hopefully this will come in handy for someone else.