From a4b6f30579bc46d88525b153e314aee6f5cbde79 Mon Sep 17 00:00:00 2001 From: Wayne Davison Date: Sat, 27 Mar 2004 18:25:41 +0000 Subject: [PATCH] Try to make the complexities of includes/excludes a little more clear. --- rsync.yo | 67 ++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 48 insertions(+), 19 deletions(-) diff --git a/rsync.yo b/rsync.yo index c7bd1c99..1e2f2c71 100644 --- a/rsync.yo +++ b/rsync.yo @@ -895,15 +895,45 @@ skipped. If it is an include pattern then that filename is not skipped. If no matching include/exclude pattern is found then the filename is not skipped. -The filenames matched against the exclude/include patterns -are relative to the destination directory, or "top -directory", so patterns should not include the path elements -of the source or destination directories. The only way in -which a pattern will match the absolute path of a file or -directory is if the source path is the root directory. +The filenames matched against the exclude/include patterns are relative +to the "root of the transfer". If you think of the transfer as a +subtree of names that are being sent from sender to receiver, the root +is where the tree starts to be duplicated in the destination directory. +This root governs where patterns that start with a / match (see below). + +Because the matching is relative to the transfer-root, changing the +trailing slash on the source path or changing your use of the --relative +option affects the path you need to use in your matching (in addition to +changing how much of the file tree is duplicated on the destination +system). The following examples demonstrate this. + +Let's say that we want to match a source filename that has an absolute +path of "/home/me/foo/bar", here is how the various command choices can +differ: + +verb( + Example cmd: rsync -a /home/me /dest + Source root: /home ("me" is part of transfer) + +/- pattern: /me/foo/bar + Target file: /dest/me/foo/bar + + Example cmd: rsync -a /home/me/ /dest + Source root: /home/me (due to trailing /) + +/- pattern: /foo/bar (note missing "me") + Target file: /dest/foo/bar + + Example cmd: rsync -a --relative /home/me/ /dest + Source root: /home/me + +/- pattern: /home/me/foo/bar (note full path) + Target file: /dest/home/me/foo/bar +) + +The easiest way to see what name you should include/exclude is to just +look at the output when using --verbose and put a / in front of the name +(use the --dry-run option if you're not yet ready to copy any files). Note that when used with -r (which is implied by -a), every subcomponent of -every path is visited from top down, so include/exclude patterns get +every path is visited from the top down, so include/exclude patterns get applied recursively to each subcomponent. Note also that the --include and --exclude options take one pattern @@ -918,16 +948,15 @@ itemize( start of the filename, otherwise it is matched against the end of the filename. This is the equivalent of a leading ^ in regular expressions. - Thus "/foo" would match a file called "foo" at the top of the - transferred tree. + Thus "/foo" would match a file called "foo" at the transfer-root + (see above for how this is different from the filesystem-root). On the other hand, "foo" would match any file called "foo" anywhere in the tree because the algorithm is applied recursively from top down; it behaves as if each path component gets a turn at being the end of the file name. - The leading / does not make the pattern an absolute pathname. it() if the pattern ends with a / then it will only match a - directory, not a file, link or device. + directory, not a file, link, or device. it() if the pattern contains a wildcard character from the set *?[ then expression matching is applied using the shell filename @@ -970,12 +999,12 @@ Here are some exclude/include examples: itemize( it() --exclude "*.o" would exclude all filenames matching *.o - it() --exclude "/foo" would exclude a file called foo in the top directory + it() --exclude "/foo" would exclude a file called foo in the transfer-root directory it() --exclude "foo/" would exclude any directory called foo it() --exclude "/foo/*/bar" would exclude any file called bar two - levels below a directory called foo in the top directory + levels below a directory called foo in the transfer-root directory it() --exclude "/foo/**/bar" would exclude any file called bar two - or more levels below a directory called foo in the top directory + or more levels below a directory called foo in the transfer-root directory it() --include "*/" --include "*.c" --exclude "*" would include all directories and C source files it() --include "foo/" --include "foo/bar.c" --exclude "*" would include @@ -1029,11 +1058,11 @@ once, instead of sending the same data to every host individually. Example: verb( -$ rsync --write-batch=pfx -a /source/dir/ /adest/dir/ -$ rcp pfx.rsync_* remote: -$ ssh remote rsync --read-batch=pfx -a /bdest/dir/ -# or alternatively -$ ssh remote ./pfx.rsync_argvs /bdest/dir/ + $ rsync --write-batch=pfx -a /source/dir/ /adest/dir/ + $ rcp pfx.rsync_* remote: + $ ssh remote rsync --read-batch=pfx -a /bdest/dir/ + # or alternatively + $ ssh remote ./pfx.rsync_argvs /bdest/dir/ ) In this example, rsync is used to update /adest/dir/ with /source/dir/ -- 2.34.1