Unison offer two features that make it more useful than rsync:
  • Multi-Way File Sync 
  • Detect Renames and Copies
  • Delta copies


Multi-Way File Sync 
Rsync is good at one-way synchronization. i.e. one to many. But when you need to sync multiple authoritative systems, i.e. many to many, you want to use unison. It allows you to merge changes.

Detect Renames and Copies (xferbycopying)
Another problem with rsync is that when you rename a file, it re-sends it. This is because a re-named file appears 'new' to the sync utility. Unison however, maintains a hash of every file you've synced and if there is already a local copy (i.e. the file before you renamed it), it will use that and do a 'local copy' rather than sending it. So a rename effectively is a local copy and a delete. Not perfect, but better than sending it across the wire.

Delta Copies
Unison uses it's own implementation of the rsync delta copy algorithm. However, for large files the authors recommend an option that wraps rsync itself as you can optimize it for large files. 


Unison can use config files in your ~/.unison folder. If you type 'unison' without any arguments, it will use the 'default.prf' file. Here is a sample

# Unison preferences file

# Here are the two server 'roots' i.e., the start of where we will pick out things to sync.
# The first root is local, and the other remote over ssh
root = /mnt/someFolder
root = ssh://allen@server.gattis.org//mnt/someFolder

# The 'path' is simply the name of a folder or file you want to sync. Notice the spaces are preserved. No not excape them.
path = A Folder Inside someFolder

# We're 'forcing' the first root to win all conflicts. This sort of negates the multi-way
# sync feature but it's just an example 
force = /mnt/someFolder

# This instructs unison to copy the contents of sym links, rather than the link itself
follow = Regex .*

# You can also ignore files and paths explicitly or pattern. See the 'Path specification' 
ignore = Name .AppleDouble
ignore = Name .DS_Store
ignore = Name .Parent
ignore = Name ._*

# Here we are invoking an external engine (rsync) when a file is over 10M, and passing it some arguments 
copythreshold = 10000
copyprog      = rsync --inplace
copyprogrest  = rsync --partial --inplace

Hostname is important. Unison builds a hash of all the files to determine what's changed (similar to md5sum with rsync, but faster). If you get repeated messages about '...first time being run...' you may have an error in your path