Repository: borgbackup/borg

Issue:
Documentation for "pf:" (path full-match) -- what is a "whole path"?
My backup script creates archives using relative paths -- essentially:

`cd /home; borg create /path/to/repo::my-files jonas`

I needed the script to find some files matching certain criteria and exclude them from the backup.  The pf pattern seemed best suited for this, and the current documentation for pf: patterns says:

> This pattern style is useful to match whole paths. This is kind of a pseudo pattern as it can not have any variable or unspecified parts - the full, precise path must be given. pf:/data/foo.txt matches /data/foo.txt only. 

This emphasizes "whole paths" and "the full, precise path", and gives an example using an absolute path.  To me this initially seemed to indicate very clearly that I need to use absolute paths (/home/jonas/whatever), but then nothing was matched/excluded.  

In hindsight I suppose I should have realized that a "full path" refers to what would have been stored in the archive, which is a "full" but *relative* path.  Still, maybe the documentation can be clarified (assuming I'm correct)?

(I might do it myself but right now I don't have the time.)


Discussion:
Please give a full script that reproduces your issue.
I'll take a look at writing a script that reproduces this, but first I'll try to clarify my description.

The examples at https://borgbackup.readthedocs.io/en/stable/usage/help.html#borg-help-patterns are written to create backups starting at an absolute path such as "/".  For example:

```bash
# Exclude '/home/user/file.o' but not '/home/user/file.odt':
$ borg create -e '*.o' backup /
```

Here the backup starts at "/".  In my case I *could* have chosen to start the backup of my home directory at /home/jonas:  borg create ... /path/to/backup/repo /home/jonas.

Instead I started my backup by doing essentially:

```bash
cd /home
borg create ... /path/to/backup/repo jonas
```

That is, I'm backing up the directory "jonas" which is a relative path.  In this case all file paths are (as far as I can tell) internally represented as relative paths as well:

```
jonas/.bashrc
jonas/devel
jonas/MyDocument.txt
```

These are the paths that are given to the Borg pattern matcher.  So if I want to include or exclude something from my backup using a pf: pattern, I do have to include the *whole* path -- but that refers to the whole *relative* path:

```
# Works as expected
pf:jonas/devel
```

If I specify full absolute paths, it won't work because the pattern matcher never sees those absolute paths:

```
# Won't work
pf:/home/jonas/devel
```

That I tried to use absolute paths is in many ways my own fault.  The documentation doesn't explicitly refer to absolute paths, only to "full paths".  But this might still be clarified.


Resolving patch:
diff --git a/src/borg/archiver.py b/src/borg/archiver.py
--- a/src/borg/archiver.py
+++ b/src/borg/archiver.py
@@ -1790,6 +1790,15 @@ def do_break_lock(self, args, repository):
 
     helptext = collections.OrderedDict()
     helptext['patterns'] = textwrap.dedent('''
+        The path/filenames used as input for the pattern matching start from the
+        currently active recursion root. You usually give the recursion root(s)
+        when invoking borg and these can be either relative or absolute paths.
+
+        So, when you give `relative/` as root, the paths going into the matcher
+        will look like `relative/.../file.ext`. When you give `/absolute/` as root,
+        they will look like `/absolute/.../file.ext`. This is meant when we talk
+        about "full path" below.
+
         File patterns support these styles: fnmatch, shell, regular expressions,
         path prefixes and path full-matches. By default, fnmatch is used for
         ``--exclude`` patterns and shell-style is used for the experimental ``--pattern``
@@ -1809,8 +1818,8 @@ def do_break_lock(self, args, repository):
             the path separator ('\\' for Windows and '/' on other systems) is not
             treated specially. Wrap meta-characters in brackets for a literal
             match (i.e. `[?]` to match the literal character `?`). For a path
-            to match a pattern, it must completely match from start to end, or
-            must match from the start to just before a path separator. Except
+            to match a pattern, the full path must match, or it must match
+            from the start of the full path to just before a path separator. Except
             for the root path, paths will never end in the path separator when
             matching is attempted.  Thus, if a given pattern ends in a path
             separator, a '\*' is appended before matching is attempted.
@@ -1824,7 +1833,7 @@ def do_break_lock(self, args, repository):
 
         Regular expressions, selector `re:`
             Regular expressions similar to those found in Perl are supported. Unlike
-            shell patterns regular expressions are not required to match the complete
+            shell patterns regular expressions are not required to match the full
             path and any substring match is sufficient. It is strongly recommended to
             anchor patterns to the start ('^'), to the end ('$') or both. Path
             separators ('\\' for Windows and '/' on other systems) in paths are
@@ -1834,13 +1843,13 @@ def do_break_lock(self, args, repository):
 
         Path prefix, selector `pp:`
             This pattern style is useful to match whole sub-directories. The pattern
-            `pp:/data/bar` matches `/data/bar` and everything therein.
+            `pp:root/somedir` matches `root/somedir` and everything therein.
 
         Path full-match, selector `pf:`
-            This pattern style is useful to match whole paths.
+            This pattern style is (only) useful to match full paths.
             This is kind of a pseudo pattern as it can not have any variable or
-            unspecified parts - the full, precise path must be given.
-            `pf:/data/foo.txt` matches `/data/foo.txt` only.
+            unspecified parts - the full path must be given.
+            `pf:root/file.ext` matches `root/file.txt` only.
 
             Implementation note: this is implemented via very time-efficient O(1)
             hashtable lookups (this means you can have huge amounts of such patterns
@@ -1923,7 +1932,16 @@ def do_break_lock(self, args, repository):
             considered first (in the order of appearance). Then patterns from ``--patterns-from``
             are added. Exclusion patterns from ``--exclude-from`` files are appended last.
 
-            An example ``--patterns-from`` file could look like that::
+            Examples::
+
+                # backup pics, but not the ones from 2018, except the good ones:
+                # note: using = is essential to avoid cmdline argument parsing issues.
+                borg create --pattern=+pics/2018/good --pattern=-pics/2018 repo::arch pics
+
+                # use a file with patterns:
+                borg create --patterns-from patterns.lst repo::arch
+
+            The patterns.lst file could look like that::
 
                 # "sh:" pattern style is the default, so the following line is not needed:
                 P sh


Test patch: