Using Host name patterns with SSH and Git


One of the things that has always confused me a bit when using SSH with git and GitHub is how do we manage multiple GitHub accounts so that they have different ssh keys? The answer lies in the SSH config file usually located at ~/.ssh/config.

Assuming that you already have multiple keys generated there are three bits of information that are important in the SSH config file:

  1. The Host entry. This can be any pattern you want, not just the actual hostname. This is they key part in making this all work. It is used along with the…
  2. HostName. This is the actual hostname that is connected to when you try to connect to the pattern given in Host.
  3. IdentityFile. This indicates which key to use when connecting to the given Host

When you attempt a connection to a git remote (in this particular case GitHub) such as git@github.com:jasonekratz/PyGithub.git (my fork of the PyGithub project) git will initiate an ssh connection. The ssh agent will attempt to match the @github.com portion with a Host entry in the SSH config. However, it doesn’t have to be a hostname, it can be any pattern you want. Here is how we solve the problem.

We’ll start by first creating the private account configuration. First create an entry similar to the following in your SSH config file:

Host github.com-jasonekratz
	HostName github.com
	User git
	IdentityFile ~/.ssh/

Notice that the Host entry is actually a pattern, not a real hostname. The HostName entry contains the actual hostname we want to connec t.

Now, when you clone a private repo you’d use the Host entry instead of just github.com. So instead of:

git clone git@github.com:jasonekratz/PyGithub.git

you’d use:

git@github.com-jasonekratz:jasonekratz/PyGithub.git.

You could also replace any existing remote references in your local repositories with the same format.

Now let’s create an entry for a work account. It’s basically the same thing but with a different Host pattern:

 Host github.com-jekwork
	HostName github.com
	User git
	IdentityFile ~/.ssh/

As before you could then clone using that work pattern in the remote reference:

git clone git@github.com-jekwork:jekwork/PyGithub.git

You could also replace any existing remote references in the local copy of your work repositories.

To get this working I initially found this link. There are some other handy hints in the comments of that gist including how to set an option in your global gitconfig so that you don’t even need to change the URLs!

From user https://gist.github.com/chiahsien:

Great guide, it helps me a lot!
And I can expand this guide with another trick.

In your /.gitconfig

[url "git@github.com-company:company_github_account/"]
insteadOf = git@github.com:company_github_account/

After this setting, you don't have to change URL manually every time when you want to clone repos.
%d bloggers like this: