Git Networking with SSH

It’s only been about a year since I started writing up some workspace configuration for C9 here: Starting out with C9 for development ? After fighting with it for about a week at work and getting very frustrated with what I could find on the internet, I’m back to document some more!

Git Network Integration

A selling point of git as version control is that you can have local copies of a repository everywhere without a single source of truth or “central repo”. But how do you manage that without making a giant mess? Usually there’s still a golden source. Say you’re working on someone’s open source project on github. You have your own clone of it, but if you’re working off master you’ll eventually run into some snags if you don’t keep it as a clean copy of the origin. I have many opinions on good workflows for git, but that’s a discussion for another day. 😛 However, this came up because I wanted to be able to pull changes back and forth between local copies without using a central server copy. I knew this should be possible with git remotes but ran into some real pains between Linux and Windows. If you want to do this just trust me when I say you want to go ahead and get an ssh server running on Windows, whether it be through OpenSSH Server natively in Windows or through Windows Subsystem for Linux.

Generate SSH Keys

It’s likely you have done this if you’ve set up a git repo, but first you’ll want to check if you have ssh keys already:

$ ls -lsa ~/.ssh

If you already have keys set up, they will show up as something like id_rsa and id_rsa.pub. If you do not have both, regenerate them. Run this to generate keys and follow the prompts on screen:

$ ssh-keygen -t rsa

SSH Configuration

This is incredibly powerful and I would never want to set up git remotes to anything on a local network without it. Imagine having several repositories that are all linked to the same user@hostname:port and you needed to change that at all? Oh, the horror! Instead, save yourself the trouble and just use a host config on each machine. Open your ssh config file:

$ vim ~/.ssh/config

Here’s an example of a full config in a couple of different cases. Sometimes you need to run your ssh server under something other than the default port of 22, so then the port needs to be specified:

Host foo
  HostName foo.bar.com
  User sarah

Host baz
  HostName baz.bar.com
  User sarah
  Port 5000

SSH Key Authentication

Oh how I wish I had looked into this long ago. Whenever looking for any configuration docs, it’s always a good idea to add DigitalOcean to your search string. Today I quickly found there how easy it can be to use your existing ssh keys to set up passwordless ssh login. You’ll need to run this command on each of your machines you want to link:

$ ssh-copy-id user@hostname:port

Even better, if you have set up the ssh config for this host like I’ve suggested, you can just use your host alias:

$ ssh-copy-id host

If you used something other than id_rsa, you may need to add -i with the identity filename.

Just like that, you can now ssh without passwords!

This is supposed to be about Git

Ok, but how do we use all of these things for git? This is where it gets fun. 😀 Whether your machines are on a local network or not, as long as you have ssh configured and working you are ready to connect your git repository copies!

On host “baz” from our ssh dummy configs:

$ git remote add ssh://foo/absolute/path/to/repo

If you don’t already know the absolute path, you can run the command pwd on the host from within the main folder of the repo.

To verify this worked:

$ git fetch foo

You can also see the full remote with this:

$ git remote -v

If this didn’t work and you messed up the path, you can always remove the remote and try again:

$ git remote remove foo

Repeat for your other host(s) and now your repository copies are linked!

The next problem that comes up is how to work between them but that’s personal preference between rebase and pull. For example, rebase would look like this with the remote and branch specified:

$ git rebase foo/master

I wouldn’t recommend using rebase until you’re very familiar with how it works but if you mess up, git reflog is your friend!

Leave a Reply

Your email address will not be published. Required fields are marked *