It seems that under certain conditions, local filter rules where the pattern is anchored with '/' to prevent rule propagation to sub-directories leads to these rules being dropped entirely. The following simplified example demonstrates the problem: $ TESTDIR=/tmp/rsync-test $ mkdir -p $TESTDIR/{root/{a/b,b/a/c},dst} $ echo "- /a" > $TESTDIR/root/.rsync-filter The following fails to exclude $TESTDIR/root/a, despite the per-directory filter rule stating that sub-directory 'a' should not be considered: $ cd $TESTDIR/dst $ rsync -avvFFR $TESTDIR/root/ $TESTDIR/dst/ sending incremental file list [sender] hiding file /tmp/rsync-test/root/.rsync-filter because of pattern .rsync-filter delta-transmission disabled for local transfer or --whole-file /tmp/ /tmp/rsync-test/ /tmp/rsync-test/root/ /tmp/rsync-test/root/a/ /tmp/rsync-test/root/a/b/ /tmp/rsync-test/root/b/ /tmp/rsync-test/root/b/a/ /tmp/rsync-test/root/b/a/c/ total: matches=0 hash_hits=0 false_alarms=0 data=0 Running rsync without '-R' works as expected, and changing into a directory above $TESTDIR/root and using the relative path to $TESTDIR/root also seems to work without problems. We're running rsync version 2.6.9 protocol version 29, on Fedora7/x86_64 and CentOS5/{i686,x86_64}. The same behaviour appears in the latest version from CVS [3.0.0pre2 protocol version 30.PR12].
I can reproduce the problem in the latest CVS rsync. The problem appears to be that in rule_matches, rsync prepends an extra copy of the working directory to the rule pattern because the "name++;" on line 531 of exclude.c controverts the "*name != '/'" test on line 541.
Thanks for the analysis, Matt. I've fixed the bug in CVS. I verified the fix using your test case, Wolfgang, so thanks for the detailed report!