a problem I'm having with rsync-4.5.4

Wayne Davison wayned at users.sourceforge.net
Tue May 7 18:07:02 EST 2002


I think this statement in the man page is actually false:

  if the pattern starts with a / then it is matched against the start of
  the filename, otherwise it is matched against the end of the filename.

The code is written to just strchr() for any slash to make this
distinction.

Attached is my attempt to make things clearer.

..wayne..

---8<------8<------8<------8<---cut here--->8------>8------>8------>8---
Index: rsync.yo
--- rsync.yo	2002/05/06 19:02:44	1.98
+++ rsync.yo	2002/05/08 01:02:30
@@ -744,17 +744,27 @@
 The patterns can take several forms. The rules are:
 
 itemize(
-  it() if the pattern starts with a / then it is matched against the
-  start of the filename, otherwise it is matched against the end of
-  the filename.  Thus "/foo" would match a file called "foo" at the base of
-  the tree.  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.
-
-  it() if the pattern ends with a / then it will only match a
+  it() if the pattern ends with a '/' then it will only match a
   directory, not a file, link or device.
 
+  it() if a pattern does NOT contain a '/' (not counting a trailing '/'),
+  it is matched against the final component of the pathname.  In
+  otherwords, "foo" matches "foo", "dir/foo", "dir/path/foo", etc.  It does
+  not match "myfoo" or "foo/baz" (the latter since "foo" does not match
+  "baz").  For directories, "bar/" matches all directories named "bar"
+  anywhere in the tree.
+
+  it() alternately, if the pattern contains a '/' (not counting a trailing
+  '/') then it is matched against the full filename, including any leading
+  directory path, but ONLY the path info relative to the tree of what we're
+  sending.  In other words, if we're sending all files from inside /var,
+  then the path will not include the "/var" prefix, but might include
+  "spool/news".
+
+  it() a leading slash in the pattern is discarded, but after causing us to
+  match against the full filename.  Thus, "/foo" would match a name only in
+  the base directory.
+
   it() if the pattern contains a wildcard character from the set
   *?[ then expression matching is applied using the shell filename
   matching rules. Otherwise a simple string match is used.
@@ -762,13 +772,6 @@
   it() if the pattern includes a double asterisk "**" then all wildcards in
   the pattern will match slashes, otherwise they will stop at slashes.
 
-  it() if the pattern contains a / (not counting a trailing /) then it
-  is matched against the full filename, including any leading
-  directory. If the pattern doesn't contain a / then it is matched
-  only against the final component of the filename.  Again, remember
-  that the algorithm is applied recursively so "full filename" can 
-  actually be any portion of a path.
-
   it() if the pattern starts with "+ " (a plus followed by a space)
   then it is always considered an include pattern, even if specified as
   part of an exclude option. The "+ " part is discarded before matching.
@@ -779,6 +782,15 @@
 
   it() if the pattern is a single exclamation mark ! then the current
   include/exclude list is reset, removing all previously defined patterns.
+
+  it() all patterns are applied recursively to every file and directory,
+  one at a time as we descend the tree.  This means that you need to ensure
+  that your include rules include all the necessary parent directories to
+  get to the files that you wish to include.
+
+  it() the filenames we're matching do NOT start with a slash, so the
+  pattern "**/foo" does not match the same thing as "foo" (it omits the
+  file that would be matched by the pattern "/foo").
 )
 
 The +/- rules are most useful in exclude lists, allowing you to have a
@@ -797,10 +809,11 @@
   it() --exclude "*.o" would exclude all filenames matching *.o
   it() --exclude "/foo" would exclude a file in the base directory called foo
   it() --exclude "foo/" would exclude any directory called foo
-  it() --exclude "/foo/*/bar" would exclude any file called bar two
+  it() --exclude "foo/*/bar" would exclude any file called bar two
   levels below a base directory called foo
-  it() --exclude "/foo/**/bar" would exclude any file called bar two
+  it() --exclude "foo/**/bar" would exclude any file called bar two
   or more levels below a base directory called foo
+  it() --exclude "**/*.c" would exclude any .c file not in the base directory
   it() --include "*/" --include "*.c" --exclude "*" would include all 
   directories and C source files
   it() --include "foo/" --include "foo/bar.c" --exclude "*" would include
---8<------8<------8<------8<---cut here--->8------>8------>8------>8---





More information about the rsync mailing list