Bug 11253 - --exclude=dir doesn't work with --files-from=
Summary: --exclude=dir doesn't work with --files-from=
Alias: None
Product: rsync
Classification: Unclassified
Component: core (show other bugs)
Version: 3.1.1
Hardware: All All
: P5 normal (vote)
Target Milestone: ---
Assignee: Wayne Davison
QA Contact: Rsync QA Contact
Depends on:
Reported: 2015-05-04 09:55 UTC by Vegard Nossum
Modified: 2015-05-04 17:50 UTC (History)
0 users

See Also:

Reproducer/test case (1.04 KB, application/x-shellscript)
2015-05-04 09:55 UTC, Vegard Nossum
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Vegard Nossum 2015-05-04 09:55:48 UTC
Created attachment 11015 [details]
Reproducer/test case

If I just pass --exclude=file or --exclude=dir to rsync, the file or dir is excluded correctly.

However, if you pass a list of files in --files-from= that includes the file I want to exclude, then only --exclude=file works as before; --exclude=dir doesn't seem to do anything at all.

As a workaround, I've found that --exclude=dir/** will actually exclude dir, as I originally wanted.

This behaviour is counter-intuitive to me; at the very least, I'd expect --exclude=dir to work the same as --exclude=file.

I've checked that the behaviour is present in latest git master. I've also included a simple reproducer script (uncomment 1 of the 4 rsync commands and run it to see the result of the transfer).
Comment 1 Wayne Davison 2015-05-04 17:32:42 UTC
Excludes don't affect args, just items that are found in recursion. A files-from list is the same as specifying all the names as args on the command-line, and thus are not affected.  Specifying an exclude of just the dir name matches only that dir itself, so when recursing inside the dir, that rule won't match anything.  If you don't want a particular arg to be included, you can filter it out of the files-from file.  Your exclude of dir/** (or dir/***) is also a good solve, as it tells rsync to affect the contents of a particular path.

One filter solution:

egrep -v '/dir(/|$)' files_from | rsync -aiv --files-from=- / /to/
Comment 2 Vegard Nossum 2015-05-04 17:50:21 UTC
(In reply to Wayne Davison from comment #1)

Thank you for the explanation.