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 ----- #!/bin/csh # 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
The current behavior is correct according to the long description in the man page: --force 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.
Created attachment 4730 [details] Fix the --force documentation Note: This will cause a conflict in fileflags.diff.
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.
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. Thanks John