Merging excludes using ". FILE"

Wayne Davison wayned at
Tue Apr 27 06:09:07 GMT 2004

As I alluded to in an earlier email on the subject of excludes, I had
the idea of allowing a merge idiom (think "#include" in C) inside
rsync's current exclude/include system.  The idea is simple -- use the
prefix ". " (dot space) in front of a filename, and that file will be
incorporated into the contents of the current exclude/include rule(s).
As a further feature, if the name has no slashes in it, it is a
per-directory merge that is looked for in every directory that rsync
visits when traversing the hierarchy.  This allows a simpler version of
the --rsync-exclude=FILE suggestion (aka --perdir-exclude-from=FILE in
my modified patch) while also being more flexible (because you can
control where in the rules the merge happens).  To make this even
better, an advanced user can specify where the per-directory .cvsignore
file gets inserted into the rule order as well, using the same
dot-space idiom (by default it gets inserted after all user-supplied
rules if the user uses -C without telling us where to put the file).

Some examples:

    % rsync -av --exclude=". .excl" from/ to

    % cat foo
    # Early rules override all other rules:
    - *.o
    # Include high-priority, per-dir rules from ".excl":
    . .excl
    # Include global rules (just merged once):
    . /home/user/.rsync-excludes
    # We want each .cvsignore file's rules to go here:
    . .cvsignore
    # The lowest priority rules:
    + */
    + *.c
    - *
    % rsync -avC --exclude-from=foo from/ to

The use of ". .excl" tells rsync to look for the ".excl" file in every
directory we traverse, much like a .cvsignore file when using -C.
However, the rules are parsed one per line (not white-space separated),
can have +/- and '.' prefixes, can have comment-lines, and are inherited
by each dir's subdirectories (by default).  The default (when no +/-
prefix is supplied) can be either to exclude or to include, depending on
if the file was merged from an --exclude* or an --include* option.  (I
personally recommend always including a prefix, just to be clear, but
you can do as you like.)

A per-directory merge file can use the "!" token to clear out all the
parent dir's rules (not the global rules) and start fresh.  There can
also be more than one per-dir merge file going at a time, and the
per-dir merge files can add new ones as well (which causes that sub-tree
to look for the new per-dir merge file, but not any other portion of the

Yeah, this can get complicated, but only if you make it complicated.
The basic idea is pretty simple and the implementation was also quite
easy.  You'll find my patch for it in the "merge-exclude-file.diff"
file in the patches dir of CVS and the just-released rsync 2.6.1.  I'd
appreciate it if people would give this a look and let me know what
they think of the idea.


More information about the rsync mailing list