As is often the case, this is written for the search engines, because when I tried to find a solution to this problem, I couldn't find one. (Perhaps that was because I wasn't searching with the right keywords, or perhaps I would have found the solution had I been more persistent.) I also understand that very few people will encounter this "problem" (read: require, or desire, this crazy advanced configuration).
Because services like GitHub and BitBucket require each user account to have unique SSH keys, if you have multiple accounts on those services, it's necessary to generate multiple SSH keys.
First, we'll generate the keys.
$ ssh-keygen -t rsa -f github-user1 # key for user1
$ ssh-keygen -t rsa -f github-user2 # key for user2
Then we'll add each public key to each account in the GitHub or BitBucket web interface per usual. Now, we'll have two problems to solve: when we try to pull and push commits to GitHub or BitBucket, SSH doesn't know how to select the correct key file. That's easy: we'll create a user SSH configuration file (~/.ssh/config
) and create an entry like the one below.
Host github.com
IdentityFile ~/.ssh/github-user1
But how do we specify the user2 account? SSH allows us to create "fake" hostnames in its user configuration file. Think of them as domain "aliases."
Host user1.github.com
HostName github.com
IdentityFile ~/.ssh/github-user1
Host user2.github.com
HostName github.com
IdentityFile ~/.ssh/github-user2
We've now mapped each domain alias to each key. This comes with a trade-off: our git clone
commands and all other references to our GitHub and BitBucket repository URLs needs a slight modification. Here's the typical syntax:
$ git clone [email protected]:user1/repo.git
Below is the new syntax.
$ git clone [email protected]:user1/repo.git
Note the "user1.github.com" as the domain.
But this is cumbersome and inconvenient—and unacceptable. Luckily, git's url aliases come to the rescue. They allow us to substitute some portion of the URL to be cloned for something else. Here's an example:
[url "user1.github.com:user1"]
insteadOf = github.com:user1
What this does is substitute "github.com:user1" with "user1.github.com:user1" in the URL parameter of our git commands. A command like this:
$ git clone [email protected]:user1/repo.git
...is automagically translated into this:
$ git clone [email protected]:user1/repo.git
Yup, that's the same command we were trying to avoid running above—which we've successfully done. Git URL aliases live in ~/.gitconfig
, and you may add as many as you like.
(Power user tip: GitHub and BitBucket allow you to omit the ".git" extension from the repository name.)
above way of url aliases didn't work for me, i think it keeps on substituting and becomes something like this:
however, this worked: