I'm looking for the best way to sync my home directory to and from a 120GB USB drive. The catch is that I use bind mounts (which I don't want to be followed) and hard links (which I do want to be preserved). Rsync can do this but it is one directional, whereas I have changes on both sides.

Unison looks like it can intelligently handle bidirectional synchronisation but I can't find any option to restrict it to one-filesystem or ignore bind-mounts and the documentation says "Unison does not understand hard links". However, by default unison uses rsync to do it's transfer. Is there a way to use rsync's understanding of hard links and bind mounts?

Alternatively can someone point me to an example of doing bidirectional synchronisation manually using rsync and diff? Or something similar?

Note: I've used FreeFileSync in the past but something went wrong and I nearly lost both my files and backup! It was possibly my fault but I'm now frightened of using FreeFileSync.

  • My "manually" I mean such as writing a custom script that uses diff or similar to find the changes and then rsync to make the changes. – Jesse the Wind Wanderer Sep 30 '18 at 7:16

I suspect that, using Unison alone, the answer to your question is no. In general it's difficult to tell Unison to sync or not sync files/directories with a property that can't be specified with some sort of pattern match on their name, like directories that are bind mounts or hard links in your case.

It's not quite correct to say "by default unison uses rsync to do it's transfer." Unison uses the same underlying algorithm/protocol as rsync, but uses its own implementation; the actual rsync executable is not called, so you can't appeal to features of the rsync executable, and you're not going to be able to solve your problem this way. Although if rsync can do it, then I imagine Unison could do it if someone were to write the feature.

Since, as you pointed out, Unison does not understand hard links, I think you're just out of luck there. You might be able to use an external program to cleverly ignore bind mounts though. You can use findmnt to list the directories that are bind mounts, and then insert the line ignore = Path /path/to/bind/mount in your Unison profile for each bind mount.

Also, since it looks like you're considering doing this manually with a script or something, you should be aware of inotify-tools.

  • Thanks Mike, obviously this isn't the answer I was hoping for but it's very well explained. So since I need to write a script or something to do this do you know of any example scripts that I could tweak? Surely I'm not the only person who wanted to sync two directory trees with both hardlinks and bind mounts in them. – Jesse the Wind Wanderer Oct 1 '18 at 15:38
  • @JessetheWindWanderer You are surely not. :) But unfortunately I don't know any such scripts. – Mike Pierce Oct 1 '18 at 17:55

You can ignore the bind mounts by simply giving Unison a view of the directory with without mount point by using a bind mount. Beware of mount propagation which if enabled (Systemd default) will propagate mount between bind mounts.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.