It would be very useful to have a way to traverse source dirs but only add them to the file list if a descendant is added to the file list. --prune-empty-dirs can do this, but it has two significant disadvantages:
- File-list entries are sent to the receiver even if they will later be pruned. This wastes bandwidth and unnecessarily leaks potentially private data.
- The single set of receiver-side filters is used for two unrelated tasks: protecting destination dirs from deletion and protecting source dirs from pruning. It should be possible to specify two independent sets of filters. This came up once on the list:
So I'd like to propose a new implementation of source pruning. (--prune-empty-dirs would remain for compatibility, but the man page would encourage users to move to the new implementation.) The "p" filter modifier, currently used to mark protect filters perishable, would gain a second meaning to mark "show" filters prunable. The analogue to the time-honored "--include='*/' --exclude='*' --prune-empty-dirs" combination would be "--filter='+p */' --exclude='*'" .
This is a new incarnation of my proposal a while ago for a "traverse" sender filter action:
Some things I neglected to mention:
- On second thought, overloading the "p" modifier is probably a bad idea because it becomes complicated to ensure that a client receiver will fail if the sender is too old to understand the new semantics. What would be another appropriate letter for the prunable modifier? "m", after --prune-empty-dirs, would conflict with my filter-attrs patch (bug 6197).
- At first, the prunable modifier would not work with incremental recursion. (That could be improved later as a separate enhancement.) If a prunable filter is found during parse_arguments, incremental recursion would simply be disabled. Otherwise, we count on the user to pass --no-i-r. If a run with incremental recursion is already underway and a prunable filter is found in a per-dir merge file, rsync would ignore the modifier with an FERROR_XFER.