In the INCLUDE/EXCLUDE PATTERN RULES section of the man page, it says the following:

if the pattern starts with a / then it is anchored to a particular spot in the hierarchy of files, otherwise it is matched against the end of the pathname. This is simi‐ lar to a leading ^ in regular expressions. Thus "/foo" would match a name of "foo" at either the "root of the transfer" (for a global rule) or in the merge-file’s direc‐ tory (for a per-directory rule). An unqualified "foo" would match a name of "foo" anywhere in the tree because the algorithm is applied recursively from the top down; it behaves as if each path component gets a turn at being the end of the filename. Even the unanchored "sub/foo" would match at any point in the hierarchy where a "foo" was found within a directory named "sub". See the section on ANCHORING INCLUDE/EXCLUDE PATTERNS for a full discussion of how to specify a pattern that matches at the root of the transfer.

How would one specify a per-directory rule? and what are the effects it would have?

  • 1
    To avoid confusion and/or ambiguity, can you provide an example of the situation you're considering, please. – roaima Sep 22 '18 at 16:36

Without a delete option, "per-directory rules" are only relevant on the sending side, so you can feel free to exclude the merge files themselves without affecting the transfer. For example:

rsync -av --filter='dir-merge /.rsync-filter' --exclude=.excl host:src/dir /dest 
rsync -av --filter='dir-merge /.rsync-filter' host:src/dir /dest 

--filter='dir-merge /.rsync-filter' This tells rsync to look for per-directory .rsync-filter files that have
been sprinkled through the hierarchy and use their rules to filter the files in the transfer. If -F is repeated, it is a shorthand for this rule:

However, if you want to do a delete on the receiving side AND you want some files to be excluded from being deleted, you need to be sure that the receiving side knows what files to exclude. The easiest way is to include the "per-directory merge files" in the transfer and use --delete-after, because this ensures that the receiving side gets all the same exclude rules as the sending side before it tries to delete anything:

rsync -avF --delete-after host:src/dir /dest 

However, if the files are not a part of the transfer, you need to either specify some global exclude rules (i.e. specified on the command line), or you need to maintain your own per-directory files on the receiving side. An example of the first is this (assume that the remote .rules files exclude themselves):

rsync -av --filter='remote .rules' --filter='remote /my/extra.rules'
   --delete host:src/dir /dest

In the above example the extra.rules file can affect both sides of the transfer, but (on the sending side) the rules are subservient to the rules merged from the .rules files because they were specified after the per-directory merge rule.

In one final example, the remote side is excluding the .rsync-filter files from the transfer, but we want to use our own .rsync-filter files to control what gets deleted on the receiving side. To do this we must specifically exclude the per-directory merge files (so that they don(cqt get deleted) and then put rules into the local files to control what else should not get deleted. Like one of these commands:

   rsync -av --filter=':e /.rsync-filter' --delete \
        host:src/dir /dest
    rsync -avFF --delete host:src/dir /dest

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.