Bug 6752 - --force short description is misleading
Summary: --force short description is misleading
Alias: None
Product: rsync
Classification: Unclassified
Component: core (show other bugs)
Version: 3.0.6
Hardware: x64 Linux
: P3 normal (vote)
Target Milestone: ---
Assignee: Matt McCutchen
QA Contact: Rsync QA Contact
Depends on:
Reported: 2009-09-22 21:29 UTC by ciolfi
Modified: 2009-10-23 21:53 UTC (History)
0 users

See Also:

Fix the --force documentation (1.56 KB, patch)
2009-09-22 22:00 UTC, Matt McCutchen
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description ciolfi 2009-09-22 21:29:41 UTC
Run following script and you'll receive:

cannot delete non-empty directory: s1/CVS
delete non-empty directory: s1/CVS
cannot delete non-empty directory: s1

which conflicts with the doc on --force. Googling this also brings up a number of others with the same problem. The source of the problem is the exclude filter. 

-------------------- force_bug.sh -----

# Reproduction steps where --force doesn't force deletion.

rm -rf src dst

mkdir -p dst/s1/CVS
echo foo > dst/s1/CVS/Root

mkdir -p src/s2/foo.txt

rsync -az --filter='exclude, /**/CVS/Root' --filter='protect, /**/CVS/Root' --fo
rce --delete --delete-excluded src/ dst
Comment 1 Matt McCutchen 2009-09-22 21:50:25 UTC
The current behavior is correct according to the long description in the man page:

This option tells rsync to delete a non-empty directory when it is to be replaced by a non-directory.

The short documentation, "force deletion of dirs even if not empty", is misleading.  I suggest changing it to "OK to replace non-empty dirs with non-dirs" (just under the length limit).

ciolfi, if you don't want protected destination files to pin their ancestor directories, you need to use the "P" filter modifier.
Comment 2 Matt McCutchen 2009-09-22 22:00:56 UTC
Created attachment 4730 [details]
Fix the --force documentation

Note: This will cause a conflict in fileflags.diff.
Comment 3 Matt McCutchen 2009-09-22 22:08:16 UTC
Incidentally, I don't like the name --force; it is really inadequate as a description (or even reminder) of the associated behavior.  fileflags.diff renames the option to --force-delete, but that sounds stronger than --delete, which it isn't.  --replace-dirs is pretty good but doesn't cover the interaction with --delete-missing-args.  --clobber-dirs is better there but may be too silly.
Comment 4 ciolfi 2009-09-23 08:30:27 UTC
Thanks for the "p" modifier tip. That solves the problem. May I suggest that if you are updating the documentation that you also note that the "p" modifier can be applied to the protect rules. Here's the example that does work (which may be worth adding to a FAQ):

mkdir -p dst/s1/CVS
echo foo > dst/s1/CVS/Root

mkdir -p src/s2/foo.txt

rsync -az --filter='exclude /**/CVS/Root' --filter='protect,p /**/CVS/Root' --delete-excluded src/ dst

The scenario is that I'm copying a CVS source tree from a src location to a dst location. The contents of the CVS/Root file needs to be different in the destination, therefore we exclude them from the rsync transfer and after the rsync is complete create the desired CVS/Root files. On a 2nd rsync, we don't want the CVS/Root files touched, thus we use the protect rule. However, we need to use the p modifier for the protect rule such that we can delete the files when the directory tree is no longer present on the src side.