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
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.
Limitations
-
If I’m ever away with my laptop and need to access the history of Cool Dot Com Domain, I’m going to have to retrieve it from my cloud-backup site. This would be unpleasant, but so far it hasn’t been an issue.
-
If I ever want to restore files as they were from the Git history into
~/Sync/Sites/cooldotcomdomain
, I’m going to have to do some manual copying or define a Makefile target to copy everything in the other direction.
Wrapup
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.