Serverless git, really, it's possible!

November 10, 2018 • Tags: computers, english

Despite all the discursive bravado about how git is “decentralised” and “distributed”, I suspect the vast majority of its users in fact rely on a central… server, for lack of a better name, in one guise or another (e.g. github, bitucket, …). Including of course, me (I have a github account). But I also sync a lot of stuff between laptop and desktop via good old rsync scripts, and herein lies the problem: for some of the code I develop, I don’t necessarily want to throw it on github, at least not just yet. But I still want to have it duplicated on laptop and desktop (so I can work on it in both machines), and I want to use git to have versioning. Syncing .git folders via rsync, however, will likely turn the log into gibberish. Conundrum!

One attempt is to create, on one of the machines, what is called a “barebones” copy, which acts as sort of a surrogate for the centralised server. You then clone it into working copies, both on that machine and on the other one. For reasons that are beyond my current git knowledge, those barebones “repositories” cannot be used as working copies. I do know it is related to being able to do a git push: you can never ever push to working copy!

All that notwithstanding, working copies alone — without any barebones stuff — turn out to suffice for the task at hand. You need some way of accessing one machine from the other; I only tried with ssh. Place the code in one (and only one) of the machines (doesn’t matter which one, it will end up making no difference); let’s call it host1. One the folder which has the code — I assume it is /path/to/repo1 — do:

1
2
3
$ git init
$ git add .
$ git commit -a -m"initial commit"

On the other (host2), create the directory where to place the code (/path/to/repo2 below), and do the following:

1
2
3
4
5
$ git init
$ git pull user1@host1:/path/to/repo1
$ git remote add origin user1@host1:/path/to/repo1
$ git fetch
$ git branch --set-upstream-to=origin/master

In the original machine (host1), set the other as the origin:

1
2
3
$ git remote add origin user2@host2:/path/to/repo2
$ git fetch
$ git branch --set-upstream-to=origin/master

The reason you need to do git fetch before setting up branch tracking, insofar as I understand it, is that git pull just brings (pulls) content, not branch information. Hence the need for fetching beforehand. Incidently, it might also be more useful to sync the repositories doing first a fetch (rather then a pull), because you can then do a git diff HEAD origin/master to see the changes that are coming (it is a long command, hitting Tab might help ;-) ). If everything is OK, you can then do a git merge to, well, merge the branches. (git pull is basically a git fetch followed by a git merge.)

If you have your hosts configured in a ~/.ssh/config file (google it), you can use whatever names you assigned to the machines instead of user1@host1 and user2@host2. That’s it: the master branch in each copy now tracks the master branch of the other, so you can now do changes in one place, and just git pull them from the other (and of course, vice-versa). Obviously, this is not scalable, but (to me at least!) is useful nonetheless. And never forget the cardinal rule:

THOU SHALL NOT DO GIT PUSH! EVER!

November 21, 2018: added information about the need for git fetch.

November 30, 2018: corrected git diff command to use after git fetch.