back to main page

how I use syncthing

Syncthing is great, and mostly Just Werks, but some things about it aren’t entirely obvious.

Its unit of synchronization is a folder. Everything inside the folder gets synced to the equivalent folder on the other devices you choose to share it with. The other devices don’t have to name the folder the same way or put it in the same place on their filesystems, but the contents will still be mirrored.

dealing with nesting

Synced folders can’t be nested. That is, if you have a folder ~/docs that is a synced, you can’t have a folder inside it like ~/docs/work that is synced in some different way (e.g. to different devices or with different settings).

The solution is symlinks. Put your synced folders all in one place. I put mine in a folder ~/st, in a flat structure like this:

~/st/me
~/st/camera-sync
~/st/music
~/st/notes
~/st/film-and-tv

Then I put symlinks to those where I actually want them on my filesystem:

~/me -> ~/st/me
~/me/pics/camera-sync -> ~/st/camera-sync
~/me/music -> ~/st/music
~/me/docs/notes -> ~/st/notes
~/me/film-and-tv -> ~/st/film-and-tv

This way, I have granular control over what gets synced to where, while still having my files structured how I like. My phone has music, notes, and camera-sync, but it doesn’t get everything else in ~/me. My desktop has a bigger hard drive, so it syncs the large film-and-tv folder to my backup machine, but it doesn’t sync to my laptop or my phone.

On a machine where an “outer” folder is synced, but a “nested” folder isn’t, you’ll have a dead symlink. My laptop has a ~/me/film-and-tv symlink that points to a nonexistent ~/st/film-and-tv. You might find this annoying but I like the explicitness of it.

By the way, I don’t sync my entire home directory. So many programs have a habit of puking dotfiles and all kinds of other junk into the root of ~, stuff that I don’t want backed up or mirrored onto other machines. I put all the stuff I actually care about into ~/me, then symlink it to where I need. e.g. config I care about lives in ~/me/dotfiles then I manually put symlinks in ~/.config to point to them. You can use GNU stow to automate this but I’ve never gotten around to doing it.

ignore files

There is support for a .stignore file to prevent syncing of certain files (similar syntax as .gitignore), but the .stignore file itself doesn’t get synced. There’s a good reason for this, but it’s still an annoying compromise. If you need to share ignore lists across devices, you need to use a #include directive at the top of the ignorefile, like #include .stglobalignore, where .stglobalignore is a file that does get synced. I used this as a starting point. So then you need to manually put a .stignore file with the contents

#include .stglobalignore

into the root of each device’s sync folder.

Then if you want, you can put folder-specific ignores in another included file:

#include .stglobalignore
#include .stmeignore

dealing with git

One place where syncthing kinda falls over is in the handling of git repositories, and I’m not sure if it’s fixable given its design. tldr synchronizing a file is atomic but synchronizing a directory isn’t. Git repositories are basically databases implemented the old fashioned way, on the file system. The git program will get confused and upset if another program moves/replaces/deletes files in the .git repo while it’s in the middle of doing an operation like a commit. So the .git folder can get corrupted. AFAIK there isn’t really a way around this aside from ignoring .git folders entirely.

But that leads to another annoyance, which is that even though the .git folder is ignored, the working directory it belongs to isn’t. There isn’t a way to tell Syncthing to ignore a folder based on its contents rather than its name. So you can end up with your working directories synced but the underlying git repo not getting synced, which can be confusing.

What I end up doing is to put all my repositories into ~/me/projects, and put that whole folder in the ignore list. But I don’t find that a completely satisfactory solution because it means my most interesting files aren’t actually synced across devices. I often forget to push to remote, or I don’t bother to set up a remote repo in the first place. ¯\_(ツ)_/¯ I need to figure out a better solution here.