Rsync filters are very useful for specifying exactly which files to sync or not.

It is particularly useful for syncing dotfiles to other systems. Sometimes we want to exclude files for certain systems like untrusted systems that others can access. We don’t want those systems to hold secrets.

It’s as simple as creating a file with the same name as a host containing the following:

P /some-secrets/
- /some-secrets/*
+ /.vimrc
- /**

Running the following command will sync .vimrc and delete everything else except the some-secrets directory.

rsync -auv --delete --delete-excluded --filter 'merge ./host' ~/ host:~/

The P rule “protects” the item from being deleted on the remote when using –delete and/or –delete-excluded. In the example we want to keep the some-secrets directory on the remote but not sync any items from our local machine to there. This is useful if the remote has its own set of secrets.

The + rule adds an item that’s permitted to be sent.

The - rule bans an item from being sent.

The term * matches a single path item.

The term ** matches an arbitrary path item of zero or more /.

When rsync finds a new item it will scan the filter rules from top to bottom, and the first found rule will be applied. Note that P rules will not exit the scan. P rules must come before exclusion or inclusion rule of the same item, otherwise the scan will exit before reaching P.