One of the limitations of folder-sync software like Dropbox and Syncthing is that it’s a bad idea to put git repositories in synced folders. In short, if there’s a sync conflict in a file, the conflicting files will be duplicated and the user will have to sort out which is the right file to use. Annoying, but tolerable if it happens only occasionally. However, if one of the conflicting files is somewhere in .git/objects/, then the repository could get unfixably corrupted.

Of course, if all you want from Git is a history of your changes, you don’t need to keep the git repo in your sync folder at all. You can keep your files in a synced folder, sync back and forth between all your computers, and then, periodically copy those files to an un-synced Git repository on one of your computers. Those copied files will look like changes to Git, and you can commit those changes as you see fit.

In practice

Let me show you how it works.

I have a web thing (I hate to call it a “website” since it’s not published anywhere) called Cool Dot Com Domain. It’s a Hugo-based site with a handful of opinions about things and a development diary for all my projects. When I started it, I wanted to be able to work on it from either my desktop or laptop without having to go through the formal steps of committing and pushing and pulling. As such, I put it in ~/Sync/Sites/cooldotcomdomain, where ~/Sync is synced by Syncthing.

Eventually I wanted to be able to dig through the site’s history in case I tried out, used, and abandoned a particularly cool CSS or Hugo-augmented Go template construct. I ended up making ~/Projects/Attic/Synced Elsewhere/cooldotcomdomain and added this to ~/Sync/Sites/cooldotcomdomain/Makefile:

ELSEWHERE = ${HOME}/Projects/Attic/Synced Elsewhere/cooldotcomdomain

.PHONY: backup

	rsync -rdhPc --perms --delete --delete-excluded \
	--filter="P .git" --filter="P .gitignore" --filter="- .src/" \
	-- . "${ELSEWHERE}"

Not familiar with rsync flags? In a nutshell, this copies everything to the Git repository while ensuring that .git/ and .gitignore are left alone. It also ensures that the src directories aren’t copied at all.

Now, when I want a backup of what’s in the site-slash-diary and I’m on my iMac, I just run make backup and rsync copies the site contents to the Git repo, where I can make the commits as fine- or coarse-grained as I please, without the commit cycle getting in the way of writing and changing things.



Hopefully this’ll be useful to you if you like easy sync for some of your projects yet still want a Git repository keeping track of changes. While I certainly don’t use this technique for all of my Git repos, it’s handy for less-formal setups where you don’t expect to have to git pull anything ever.