# [SCM] The rsync repository. - branch master updated

Rsync CVS commit messages rsync-cvs at lists.samba.org
Sun Jun 19 23:46:17 UTC 2022

The branch, master has been updated
via  defe2287 Improve the filter intro.
via  112bef11 Improve filter discussion.
via  b38780f3 Some proxy improvements (mainly).
via  5f33238f Some clarifications about transfer rules.
via  3592ac3c Include bsd/strings.h if it exists
via  c897b16f Fix minor typos (#327)
from  4f741add Fix configure's "signed char" check

https://git.samba.org/?p=rsync.git;a=shortlog;h=master

- Log -----------------------------------------------------------------
Author: Wayne Davison <wayne at opencoder.net>
Date:   Sun Jun 19 16:43:38 2022 -0700

Improve the filter intro.

Author: Wayne Davison <wayne at opencoder.net>
Date:   Sun Jun 19 13:53:28 2022 -0700

Improve filter discussion.

Author: Wayne Davison <wayne at opencoder.net>
Date:   Sun Jun 19 11:15:36 2022 -0700

Some proxy improvements (mainly).

commit 5f33238f0667af79608b80f5befec973c3fc5135
Author: Wayne Davison <wayne at opencoder.net>
Date:   Sun Jun 19 11:14:43 2022 -0700

Some clarifications about transfer rules.

commit 3592ac3c025da23b2dd291561ec6113940b9c11b
Author: Wayne Davison <wayne at opencoder.net>
Date:   Sun Jun 19 10:02:51 2022 -0700

Include bsd/strings.h if it exists

Some systems apparently put strlcpy() into a separate bsd/strings.h file
without putting the function into a separate library. Thus, configure
finds that the function exists for linking but the build does not have
the declaration (which rsync only supplies if it is also supplying its
own version of the function).

commit c897b16f3231b2c22110b3792ec63c4b269d57d6
Author: Yuri Chornoivan <yurchor at ukr.net>
Date:   Sun Jun 19 19:14:36 2022 +0300

Fix minor typos (#327)

-----------------------------------------------------------------------

Summary of changes:
checksum.c       |   2 +-
configure.ac     |   3 +-
rsync.1.md       | 502 +++++++++++++++++++++++++++++++++++--------------------
rsync.h          |   3 +
rsyncd.conf.5.md |  19 ++-
5 files changed, 337 insertions(+), 192 deletions(-)

Changeset truncated at 500 lines:

diff --git a/checksum.c b/checksum.c
index b723109c..178b0f50 100644
--- a/checksum.c
+++ b/checksum.c
@@ -574,7 +574,7 @@ void sum_update(const char *p, int32 len)
}

/* NOTE: all the callers of sum_end() pass in a pointer to a buffer that is
- * MAX_DIGEST_LEN in size, so even if the csum-len is shorter that that (i.e.
+ * MAX_DIGEST_LEN in size, so even if the csum-len is shorter than that (i.e.
* CSUM_MD4_ARCHAIC), we don't have to worry about limiting the data we write
* into the "sum" buffer. */
int sum_end(char *sum)
diff --git a/configure.ac b/configure.ac
index 37dbb18a..37241637 100644
--- a/configure.ac
+++ b/configure.ac
@@ -13,7 +13,8 @@ AC_CHECK_HEADERS(sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h \
netdb.h malloc.h float.h limits.h iconv.h libcharset.h langinfo.h mcheck.h \
sys/acl.h acl/libacl.h attr/xattr.h sys/xattr.h sys/extattr.h dl.h \
popt.h popt/popt.h linux/falloc.h netinet/in_systm.h netgroup.h \
-    zlib.h xxhash.h openssl/md4.h openssl/md5.h zstd.h lz4.h sys/file.h)
+    zlib.h xxhash.h openssl/md4.h openssl/md5.h zstd.h lz4.h sys/file.h \
+    bsd/string.h)
AC_CHECK_HEADERS([netinet/ip.h], [], [], [[#include <netinet/in.h>]])

diff --git a/rsync.1.md b/rsync.1.md
index 1e665982..9c149b31 100644
--- a/rsync.1.md
+++ b/rsync.1.md
@@ -512,6 +512,9 @@ shell's command-line parsing.  Also keep in mind that a leading tilde (~) in
a pathname is substituted by your shell, so make sure that you separate the
option name from the pathname using a space if you want the shell to expand it.

+[comment]: # (Some markup below uses a literal non-breakable space when a backtick string)
+[comment]: # (needs to contain a space since markdown strips spaces from the start/end)
+
[comment]: # (An OL starting at 0 is converted into a DL by the parser.)

0.  --help
@@ -788,7 +791,7 @@ option name from the pathname using a space if you want the shell to expand it.

In order to make [--delete](#opt) compatible with incremental recursion,
rsync 3.0.0 made [--delete-during](#opt) the default delete mode (which
-    was first first added in 2.6.4).
+    was first added in 2.6.4).

One side-effect of incremental recursion is that any missing
sub-directories inside a recursively-scanned directory are (by default)
@@ -943,9 +946,8 @@ option name from the pathname using a space if you want the shell to expand it.
directory where the destination has a file, the transfer would occur
regardless of the timestamps.

-    This option is a transfer rule, not an exclude, so it doesn't affect the
-    data that goes into the file-lists, and thus it doesn't affect deletions.
-    It just limits the files that the receiver requests to be transferred.
+    This option is a [TRANSFER RULE](#TRANSFER_RULES), so don't expect any
+    exclude side effects.

A caution for those that choose to combine [--inplace](#opt) with
--update: an interrupted transfer will leave behind a partial file on the
@@ -1164,7 +1166,7 @@ option name from the pathname using a space if you want the shell to expand it.
transfer, the client is the sender, so specifying the option directly
unmunges symlinks while specifying it as a remote option munges symlinks.

-    This option has no affect when sent to a daemon via [--remote-option](#opt)
+    This option has no effect when sent to a daemon via [--remote-option](#opt)
because the daemon configures whether it wants munged symlinks via its
"munge symlinks" parameter.

@@ -1728,9 +1730,8 @@ option name from the pathname using a space if you want the shell to expand it.
[--ignore-existing](#opt) option, no files will be updated (which can be
useful if all you want to do is delete extraneous files).

-    This option is a transfer rule, not an exclude, so it doesn't affect the
-    data that goes into the file-lists, and thus it doesn't affect deletions.
-    It just limits the files that the receiver requests to be transferred.
+    This option is a [TRANSFER RULE](#TRANSFER_RULES), so don't expect any
+    exclude side effects.

0.  --ignore-existing

@@ -1738,9 +1739,8 @@ option name from the pathname using a space if you want the shell to expand it.
destination (this does _not_ ignore existing directories, or nothing would
get done).  See also [--ignore-non-existing](#opt).

-    This option is a transfer rule, not an exclude, so it doesn't affect the
-    data that goes into the file-lists, and thus it doesn't affect deletions.
-    It just limits the files that the receiver requests to be transferred.
+    This option is a [TRANSFER RULE](#TRANSFER_RULES), so don't expect any
+    exclude side effects.

This option can be useful for those doing backups using the
[--link-dest](#opt) option when they need to continue a backup run that
@@ -1869,13 +1869,25 @@ option name from the pathname using a space if you want the shell to expand it.

0.  --delete-excluded

-    In addition to deleting the files on the receiving side that are not on the
-    sending side, this tells rsync to also delete any files on the receiving
-    side that are excluded (see [--exclude](#opt)).  See the [FILTER
-    RULES](#) section for a way to make individual exclusions behave this way
-    on the receiver, and for a way to protect files from --delete-excluded.
-    See [--delete](#opt) (which is implied) for more details on
-    file-deletion.
+    This option turns any unqualified exclude/include rules into server-side
+    rules that do not affect the receiver's deletions.
+
+    By default, an exclude or include has both a server-side effect (to "hide"
+    and "show" files when building the server's file list) and a receiver-side
+    effect (to "protect" and "risk" files when deletions are occuring).  Any
+    rule that has no modifier to specify what sides it is executed on will be
+    instead treated as if it were a server-side rule only, avoiding any
+    "protect" effects of the rules.
+
+    A rule can still apply to both sides even with this option specified if the
+    rule is given both the sender & receiver modifer letters (e.g., -f'-sr
+    foo').  Receiver-side protect/risk rules can also be explicitly specified
+    to limit the deletions.  This is saves you from having to edit a bunch of
+    -f'- foo' rules into -f'-s foo' or -f'H foo' rules (not to mention
+    the corresponding includes).
+
+    See the [FILTER RULES](#) section for more information.  See
+    [--delete](#opt) (which is implied) for more details on deletion.

0.  --ignore-missing-args

@@ -1936,9 +1948,8 @@ option name from the pathname using a space if you want the shell to expand it.
the numeric units or left unqualified to specify bytes.  Feel free to use a
fractional value along with the units, such as --max-size=1.5m.

-    This option is a transfer rule, not an exclude, so it doesn't affect the
-    data that goes into the file-lists, and thus it doesn't affect deletions.
-    It just limits the files that the receiver requests to be transferred.
+    This option is a [TRANSFER RULE](#TRANSFER_RULES), so don't expect any
+    exclude side effects.

The first letter of a units string can be B (bytes), K (kilo), M
(mega), G (giga), T (tera), or P (peta).  If the string is a single
@@ -2195,8 +2206,8 @@ option name from the pathname using a space if you want the shell to expand it.
0.  --exclude=PATTERN

This option is a simplified form of the [--filter](#opt) option that
-    defaults to an exclude rule and does not allow the full rule-parsing syntax
-    of normal filter rules.
+    specifies an exclude rule and does not allow the full rule-parsing syntax
+    of normal filter rules.  This is equivalent to specifying -f'- PATTERN'.

See the [FILTER RULES](#) section for detailed information on this option.

@@ -2207,13 +2218,20 @@ option name from the pathname using a space if you want the shell to expand it.
file are ignored, as are whole-line comments that start with ';' or '#'
(filename rules that contain those characters are unaffected).

+    If a line begins with "-Â " (dash, space) or "+Â " (plus, space), then
+    the type of rule is being explicitly specified as an exclude or an include
+    (respectively).  Any rules without such a prefix are taken to be an exclude.
+
+    If a line consists of just "!", then the current filter rules are cleared
+    before adding any further rules.
+
If _FILE_ is '-', the list will be read from standard input.

0.  --include=PATTERN

This option is a simplified form of the [--filter](#opt) option that
-    defaults to an include rule and does not allow the full rule-parsing syntax
-    of normal filter rules.
+    specifies an include rule and does not allow the full rule-parsing syntax
+    of normal filter rules.  This is equivalent to specifying -f'+ PATTERN'.

See the [FILTER RULES](#) section for detailed information on this option.

@@ -2224,6 +2242,13 @@ option name from the pathname using a space if you want the shell to expand it.
file are ignored, as are whole-line comments that start with ';' or '#'
(filename rules that contain those characters are unaffected).

+    If a line begins with "-Â " (dash, space) or "+Â " (plus, space), then
+    the type of rule is being explicitly specified as an exclude or an include
+    (respectively).  Any rules without such a prefix are taken to be an include.
+
+    If a line consists of just "!", then the current filter rules are cleared
+    before adding any further rules.
+
If _FILE_ is '-', the list will be read from standard input.

0.  --files-from=FILE
@@ -3012,7 +3037,7 @@ option name from the pathname using a space if you want the shell to expand it.
of "%i %n%L".  See the [--log-file-format](#opt) option if you wish to
override this.

-    Here's a example command that requests the remote side to log what is
+    Here's an example command that requests the remote side to log what is
happening:

>     rsync -av --remote-option=--log-file=/tmp/rlog src/ dest/
@@ -3250,10 +3275,8 @@ option name from the pathname using a space if you want the shell to expand it.
directories when the sending rsync is recursively scanning a hierarchy of
files using include/exclude/filter rules.

-    Note that the use of transfer rules, such as the [--min-size](#opt)
-    option, does not affect what goes into the file list, and thus does not
-    leave directories empty, even if none of the files in a directory match the
-    transfer rule.
+    This option can still leave empty directories on the receiving side if you
+    make use of [TRANSFER_RULES](#).

Because the file-list is actually being pruned, this option also affects
what directories get deleted when a delete is active.  However, keep in
@@ -3716,27 +3739,145 @@ The options allowed when starting an rsync daemon are as follows:

## FILTER RULES

-The filter rules allow for flexible selection of which files to transfer
-(include) and which files to skip (exclude).  The rules either directly specify
-include/exclude patterns or they specify a way to acquire more include/exclude
-patterns (e.g. to read them from a file).
-
-As the list of files/directories to transfer is built, rsync checks each name
-to be transferred against the list of include/exclude patterns in turn, and the
-first matching pattern is acted on: if it is an exclude pattern, then that file
-is skipped; if it is an include pattern then that filename is not skipped; if
-no matching pattern is found, then the filename is not skipped.
+The filter rules allow for custom control of several aspects of how files are
+handled:
+
+- Control which files the sending side puts into the file list that describes
+  the transfer hierarchy
+- Control which files the receiving side protects from deletion when the file
+  is not in the sender's file list
+- Control which extended attribute names are skipped when copying xattrs
+
+The rules are either directly specified via option arguments or they can be
+read in from one or more files.  The filter-rule files can even be a part of
+the hierarchy of files being copied, affecting different parts of the tree in
+different ways.
+
+### SIMPLE INCLUDE/EXCLUDE RULES
+
+We will first cover the basics of how include & exclude rules affect what files
+are transferred, ignoring any deletion side-effects.  Filter rules mainly
+affect the contents of directories that rsync is "recursing" into, but they can
+also affect a top-level item in the transfer that were specified as a argument.
+
+The default for any unmatched file/dir is for it to be included in the
+transfer, which puts the file/dir into the sender's file list.  The use of an
+exclude rule causes one or more matching files/dirs to be left out of the
+sender's file list.  An include rule can be used to limit the effect of an
+exclude rule that is matching too many files.
+
+The order of the rules is important because the first rule that matches is the
+one that takes effect.  Thus, if an early rule excludes a file, no include rule
+that comes after it can have any effect. This means that you must place any
+include overrides somewhere prior to the exclude that it is intended to limit.
+
+When a directory is excluded, all its contents and sub-contents are also
+excluded.  The sender doesn't scan through any of it at all, which can save a
+lot of time when skipping large unneeded sub-trees.
+
+It is also important to understand that the include/exclude rules are applied
+to every file and directory that the sender is recursing into. Thus, if you
+want a particular deep file to be included, you have to make sure that none of
+the directories that must be traversed on the way down to that file are
+excluded or else the file will never be discovered to be included. As an
+example, if the directory "a/path" was given as a transfer argument and you
+want to ensure that the file "a/path/down/deep/wanted.txt" is a part of the
+transfer, then the sender must not exclude the directories "a/path",
+"a/path/down", or "a/path/down/deep" as it makes it way scanning through
+the file tree.
+
+When you are working on the rules, it can be helpful to ask rsync to tell you
+what is being excluded/included and why.  Specifying --debug=FILTER or (when
+pulling files) -M--debug=FILTER turns on level 1 of the FILTER debug
+information that will output a message any time that a file or directory is
+included or excluded and which rule it matched.  Beginning in 3.2.4 it will
+also warn if a filter rule has trailing whitespace, since an exclude of "fooÂ "
+(with a trailing space) will not exclude a file named "foo".
+
+Exclude and include rules can specify wildcard [PATTERN MATCHING RULES](#)
+(similar to shell wilcards) that allow you to match things like a file suffix
+or a portion of a filename.
+
+A rule can be limited to only affecting a directory by putting a trailing slash
+onto the filename.
+
+### SIMPLE INCLUDE/EXCLUDE EXAMPLE
+
+With the following file tree created on the sending side:
+
+>     mkdir x/
+>     touch x/file.txt
+>     mkdir x/y/
+>     touch x/y/file.txt
+>     touch x/y/zzz.txt
+>     mkdir x/z/
+>     touch x/z/file.txt
+
+Then the following rsync command will transfer the file "x/y/file.txt" and
+the directories needed to hold it, resulting in the path "/tmp/x/y/file.txt"
+existing on the remote host:
+
+>     rsync -ai -f'+ x/' -f'+ x/y/' -f'+ x/y/file.txt' -f'- *' x host:/tmp/
+
+Aside: this copy could also have been accomplished using the [-R](#opt)
+option (though the 2 commands behave differently if deletions are enabled):
+
+>     rsync -aR x/y/file.txt host:/tmp/
+
+The following command does not need an include of the "x" directory because it
+is not a part of the transfer (note the traililng slash).  Running this command
+would copy just "/tmp/x/file.txt" because the "y" and "z" dirs get excluded:
+
+>     rsync -ai -f'+ file.txt' -f'- *' x/ host:/tmp/x/
+
+This command would omit the zzz.txt file while copying "x" and everything else
+it contains:
+
+>     rsync -aiv -f'- zzz.txt' x host:/tmp/
+
+### FILTER RULES WHEN DELETING
+
+By default a filter rule affects both the sender (as it creates its file list)
+and the receiver (as it creates its file lists for calculating deletions).  If
+no delete option is in effect, the receiver skips creating the delete-related
+file lists.  This two-sided default can be manually overridden so that you are
+only specifying sender rules or receiver rules, as described in the [FILTER
+RULES IN DEPTH](#) section.
+
+When deleting, an exclude protects a file from being removed on the receiving
+side while an include overrides that protection (putting the file at risk of
+deletion). The default is for a file to be at risk (its safety depends on it
+matching a corresponding file from the sender).
+
+An example of the two-sided exclude effect can be illustrated by the copying of
+a C development directory between 2 systems.  When doing a touch-up copy, you
+might want to skip copying the built executable and the .o files (sender
+hide) so that the receiving side can build their own and not lose any object
+files that are already correct (receiver protect).  For instance:
+
+>     rsync -ai --del -f'- *.o' -f'- cmd' src host:/dest/
+
+Note that using -f'-p *.o' is even better than -f'- *.o' if there is a
+chance that the directory structure may have changed.  The "p" modifier is
+discussed in [FILTER RULE MODIFIERS](#).
+
+One final note, if your shell doesn't mind unexpanded wildcards, you could
+simplify the typing of the filter options by using an underscore in place of
+the space and leaving off the quotes.  For instance, -f -_*.o -f -_cmd (and
+similar) could be used instead of the filter options above.

-Aside: because the interactions of filter rules can be complex, it is useful to
-use the --debug=FILTER option if things aren't working the way you expect.
-The level-1 output (the default if no level number is specified) mentions the
-filter rule that is first matched by each file in the transfer.  It also warns
-if a filter rule has trailing whitespace.  The level-2 output mentions a lot
-more filter events, including the definition of each rule and the handling of
-per-directory filter files.
-
-Rsync builds an ordered list of filter rules as specified on the command-line.
-Filter rules have the following syntax:
+### FILTER RULES IN DEPTH
+
+Rsync supports old-style include/exclude rules and new-style filter rules.  The
+older rules are specified using [--include](#opt) and [--exclude](#opt) as
+well as the [--include-from](#opt) and [--exclude-from](#opt). These are
+limited in behavior but they don't require a "-" or "+" prefix.  An old-style
+exclude rule is turned into a + name filter rule (with no modifiers) and an
+old-style include rule is turned into a - name filter rule (with no
+modifiers).
+
+Rsync builds an ordered list of filter rules as specified on the command-line
+and/or read-in from files.  New style filter rules have the following syntax:

>     RULE [PATTERN_OR_FILENAME]
>     RULE,MODIFIERS [PATTERN_OR_FILENAME]
@@ -3744,35 +3885,33 @@ Filter rules have the following syntax:
You have your choice of using either short or long RULE names, as described
below.  If you use a short-named rule, the ',' separating the RULE from the
MODIFIERS is optional.  The PATTERN or FILENAME that follows (when present)
-must come after either a single space or an underscore (\_).  Here are the
-available rule prefixes:
-
-0.  exclude, '-' specifies an exclude pattern.
-0.  include, '+' specifies an include pattern.
+must come after either a single space or an underscore (\_). Any additional
+spaces and/or undeerscore are considered to be a part of the pattern name.
+Here are the available rule prefixes:
+
+0.  exclude, '-' specifies an exclude pattern that (by default) is both a
+    hide and a protect.
+0.  include, '+' specifies an include pattern that (by default) is both a
+    show and a risk.
0.  merge, '.' specifies a merge-file to read for more rules.
0.  dir-merge, ':' specifies a per-directory merge-file.
0.  hide, 'H' specifies a pattern for hiding files from the transfer.
-0.  show, 'S' files that match the pattern are not hidden.
+    Equivalent to a sender-only exclude, so -f'H foo' could also be specified
+    as -f'-s foo'.
+0.  show, 'S' files that match the pattern are not hidden. Equivalent to a
+    sender-only include, so -f'S foo' could also be specified as -f'+s
+    foo'.
0.  protect, 'P' specifies a pattern for protecting files from deletion.
-0.  risk, 'R' files that match the pattern are not protected.
+    Equivalent to a receiver-only exclude, so -f'P foo' could also be
+    specified as -f'-r foo'.
+0.  risk, 'R' files that match the pattern are not protected. Equivalent to a
+    receiver-only include, so -f'P foo' could also be specified as -f'+r
+    foo'.
0.  clear, '!' clears the current include/exclude list (takes no arg)

-When rules are being read from a file, empty lines are ignored, as are
-whole-line comments that start with a '#' (filename rules that contain a hash
-are unaffected).
-
-[comment]: # (Remember that markdown strips spaces from start/end of  ...  sequences!)
-[comment]: # (Thus, the x  sequences below use a literal non-breakable space!)
-
-Note that the [--include](#opt) & [--exclude](#opt) command-line options do
-not allow the full range of rule parsing as described above -- they only allow
-the specification of include / exclude patterns plus a "!" token to clear the
-list (and the normal comment parsing when rules are read from a file).  If a
-pattern does not begin with "-Â " (dash, space) or "+Â " (plus, space), then
-the rule will be interpreted as if "+Â " (for an include option) or "-Â "
-(for an exclude option) were prefixed to the string.  A [--filter](#opt)
-option, on the other hand, must always contain either a short or long rule name
-at the start of the rule.
+When rules are being read from a file (using merge or dir-merge), empty lines
+are ignored, as are whole-line comments that start with a '#' (filename rules
+that contain a hash character are unaffected).

Note also that the [--filter](#opt), [--include](#opt), and
[--exclude](#opt) options take one rule/pattern each.  To add multiple ones,
@@ -3780,121 +3919,90 @@ you can repeat the options on the command-line, use the merge-file syntax of
the [--filter](#opt) option, or the [--include-from](#opt) /
[--exclude-from](#opt) options.

-## INCLUDE/EXCLUDE PATTERN RULES
-
-You can include and exclude files by specifying patterns using the "+", "-",
-etc. filter rules (as introduced in the [FILTER RULES](#) section above).  The
-include/exclude rules each specify a pattern that is matched against the names
-of the files that are going to be transferred.  These patterns can take several
-forms:
-
-- if the pattern starts with a / then it is anchored to a particular spot in
-  the hierarchy of files, otherwise it is matched against the end of the
-  pathname.  This is similar to a leading ^ in regular expressions.  Thus
-  /foo would match a name of "foo" at either the "root of the transfer" (for
-  a global rule) or in the merge-file's directory (for a per-directory rule).
-  An unqualified foo would match a name of "foo" anywhere in the tree because
-  the algorithm is applied recursively from the top down; it behaves as if each
-  path component gets a turn at being the end of the filename.  Even the
-  unanchored "sub/foo" would match at any point in the hierarchy where a "foo"
-  was found within a directory named "sub".  See the section on ANCHORING
-  INCLUDE/EXCLUDE PATTERNS for a full discussion of how to specify a pattern
-  that matches at the root of the transfer.
-- if the pattern ends with a / then it will only match a directory, not a
-  regular file, symlink, or device.
-- rsync chooses between doing a simple string match and wildcard matching by
-  checking if the pattern contains one of these three wildcard characters:
-  '*', '?', and '[' .
-- a '*' matches any path component, but it stops at slashes.
-- use '**' to match anything, including slashes.
-- a '?' matches any character except a slash (/).
-- a '[' introduces a character class, such as [a-z] or [[:alpha:]].
-- in a wildcard pattern, a backslash can be used to escape a wildcard
-  character, but it is matched literally when no wildcards are present.  This
-  means that there is an extra level of backslash removal when a pattern
-  contains wildcard characters compared to a pattern that has none.  e.g. if
-  you add a wildcard to "foo\bar" (which matches the backslash) you would
-  need to use "foo\\bar*" to avoid the "\b" becoming just "b".
-- if the pattern contains a / (not counting a trailing /) or a "**", then it
-  is matched against the full pathname, including any leading directories.  If
-  the pattern doesn't contain a / or a "**", then it is matched only against
-  the final component of the filename. (Remember that the algorithm is applied
-  recursively so "full filename" can actually be any portion of a path from the
-  starting directory on down.)
-- a trailing "dir_name/***" will match both the directory (as if "dir_name/"
+### PATTERN MATCHING RULES
+
+Most of the rules mentioned above take an argument that specifies what the rule
+should match.  If rsync is recursing through a directory hierarchy, keep in
+mind that each pattern is matched against the name of every directory in the
+descent path as rsync finds the filenames to send.
+
+The matching rules for the pattern argument take several forms:
+
+- If a pattern contains a / (not counting a trailing slash) or a "**"
+  (which can match a slash), then the pattern is matched against the full
+  pathname, including any leading directories within the transfer.  If the
+  pattern doesn't contain a / or a "**", then it is matched only against
+  the final component of the filename or pathname. For example, foo means
+  that the final path component must be "foo" while foo/bar would match the
+  last 2 elements of the path (as long as both elements are within the
+  transfer).
+- A pattern that ends with a / only matches a directory, not a regular file,
+  symlink, or device.
+- A pattern that starts with a / is anchored to the start of the transfer
+  path instead of the end.  For example, /foo or /foo/bar match only

--
The rsync repository.