A semi-decentralized git workflow

So, for some ongoing projects I maintain what you might call a semi-decentralized, or a weakly-centralized, git workflow.

The basic set up is this. I have three repositories on which I might work on my projects: A home desktop, a laptop, and a virtual private server.

The VPS would be the obvious place to house a bare repository to act as a central server. Except, frequently enough, the VPS might also be one of the locations on which I want to work on the project. So, it usually is a full-fledged repo, with its own working directory, instead of just a bare repo. In that case, I could maintain a bare repo and then a working repo, but that doesn't seem to offer any increment of elegance over the way I do it now.

The laptop and the desktop, though, are where I tend to do a lot of work. Depending on the project, I might do more on one or the other, but usually I want to be able to work from either.

What I tend towards, then, is committing most of my work first to the branch 'main' on each system. I set the VPS as the remote 'origin' for the desktop and the laptop. On the VPS, in addition to its own working directory and main branch, I maintain separate branches each for the laptop and for the desktop. Then, alternately from one or the other of the laptop or the desktop I will push from its own main into the corresponding branch on the VPS.

One cannot push to a branch that is checked-out on the receiving end. This is usually why one pushes to a bare repo on the remote. When working on the VPS repo, I avoid working within either of these two branches. So, neither is usually ever checked out, and each is available to receive a push.

Once on the VPS I will merge or rebase into its main branch. This can be done nearly in parallel, through an interactive ssh session into the VPS, often in another tmux or GNU screen window. To close the loop, usually later when I've switched local machines (laptop for desktop or vice versa) I will fetch whatever changes back out to whichever of the laptop or desktop needs to be caught up, and merge or rebase into the main branch on that machine.

For example, on the VPS I'll get started with:

cd
mkdir cool-project-name
cd cool-project-name
git init

sitting at either the laptop or at the desktop, I'll issue the same commands, but then will add the VPS as a remote:

git remote add origin ssh://joe@myvps.example.com:6666/home/joe/cool-project-name

This is the fullest example, giving the remote username and a port number. One thing I've found particularly vexing about remote paths using ssh in git versus using, for instance, ssh or scp, is that the paths seem to need to be absolute (eg, starting from /home explicitly here) rather than relative to the specified user's remote home.

Configuring an ssh keypair between each pair of machines can make this all much more smooth.

Then, if sitting on the laptop, I'll go to work creating files. After the usual add and commit of new work, I will issue:

git push origin main:laptop

or from the destkop:

git push origin main:desktop

Then, I can decide where I want to merge. On the VPS, in the main branch, I can do:

git merge laptop

or

git merge desktop

Then, to close the loop, I'd go to the other non-VPS machine and pull down the changes:

git fetch

git merge origin/main

Which is to say, if the changes originated on the laptop, I'd fetch and merge into the desktop main, or vice versa.

In principle, and I suppose particularly if I have something more complex I want to try to sort out, I could, say, from the laptop issue:

git merge origin/desktop

but usually I do most of the merging on the VPS, which more often than not means pulling back down to either the laptop or the desktop system is a fast forward.

I don't pretend this is particular clean or advisable, but it's been working OK for me for some document collections I've been writing and maintaining for my own use. When these make it out into the world, they do so, for instance, in the form of this blog, so the raw revisions remain pretty much behind the scenes.

For some shared projects I do work through a gitolite instance I maintain, and some public and private GitHub repos, so I've got workflows that better suit all that, and which probably more closely match (or, at least, should more closely match) workflows described elsewhere and just in general are probably much better understood by others.

I don't know how idiosyncratic the approach above is, or if it is in some respects even unique. I figured I'd try to describe it here to help me get feedback on it, and in case it helps when talking to others about their git workflows and the possibilities distributed version control offers.

(modified Tue Nov 21 13:13:13 EST 2023 to add a missing cd command and to rename the original branch)

Pages