瀏覽代碼

remove -P (aka --prefix) option, fixes #6806

-a (aka --glob-archives) can be used for same purpose and is more powerful.
Thomas Waldmann 2 年之前
父節點
當前提交
6888d5dcb2
共有 7 個文件被更改,包括 26 次插入38 次删除
  1. 2 3
      docs/faq.rst
  2. 2 2
      docs/quickstart.rst
  3. 1 1
      docs/usage/delete.rst
  4. 3 3
      docs/usage/prune.rst
  5. 8 17
      src/borg/archiver.py
  6. 1 3
      src/borg/helpers/manifest.py
  7. 9 9
      src/borg/testsuite/archiver.py

+ 2 - 3
docs/faq.rst

@@ -402,11 +402,10 @@ different prefixes. For example, you could have a script that does::
 
 
 Then you would have two different prune calls with different policies::
 Then you would have two different prune calls with different policies::
 
 
-    borg prune --verbose --list -d 30 --prefix main-
-    borg prune --verbose --list -d 7  --prefix logs-
+    borg prune --verbose --list -d 30 -a 'main-*'
+    borg prune --verbose --list -d 7  -a 'logs-*'
 
 
 This will keep 7 days of logs and 30 days of everything else.
 This will keep 7 days of logs and 30 days of everything else.
-Borg also supports the ``--glob-archives`` parameter.
 
 
 How do I remove files from an existing backup?
 How do I remove files from an existing backup?
 ----------------------------------------------
 ----------------------------------------------

+ 2 - 2
docs/quickstart.rst

@@ -195,13 +195,13 @@ backed up and that the ``prune`` command is keeping and deleting the correct bac
     info "Pruning repository"
     info "Pruning repository"
 
 
     # Use the `prune` subcommand to maintain 7 daily, 4 weekly and 6 monthly
     # Use the `prune` subcommand to maintain 7 daily, 4 weekly and 6 monthly
-    # archives of THIS machine. The '{hostname}-' prefix is very important to
+    # archives of THIS machine. The '{hostname}-*' globbing is very important to
     # limit prune's operation to this machine's archives and not apply to
     # limit prune's operation to this machine's archives and not apply to
     # other machines' archives also:
     # other machines' archives also:
 
 
     borg prune                          \
     borg prune                          \
         --list                          \
         --list                          \
-        --prefix '{hostname}-'          \
+        --glob-archives '{hostname}-*'  \
         --show-rc                       \
         --show-rc                       \
         --keep-daily    7               \
         --keep-daily    7               \
         --keep-weekly   4               \
         --keep-weekly   4               \

+ 1 - 1
docs/usage/delete.rst

@@ -10,7 +10,7 @@ Examples
     $ borg compact
     $ borg compact
 
 
     # delete all archives whose names begin with the machine's hostname followed by "-"
     # delete all archives whose names begin with the machine's hostname followed by "-"
-    $ borg delete --prefix '{hostname}-'
+    $ borg delete -a '{hostname}-*'
 
 
     # delete all archives whose names contain "-2012-"
     # delete all archives whose names contain "-2012-"
     $ borg delete -a '*-2012-*'
     $ borg delete -a '*-2012-*'

+ 3 - 3
docs/usage/prune.rst

@@ -7,8 +7,8 @@ Be careful, prune is a potentially dangerous command, it will remove backup
 archives.
 archives.
 
 
 The default of prune is to apply to **all archives in the repository** unless
 The default of prune is to apply to **all archives in the repository** unless
-you restrict its operation to a subset of the archives using ``--prefix``.
-When using ``--prefix``, be careful to choose a good prefix - e.g. do not use a
+you restrict its operation to a subset of the archives using ``-a`` / ``--glob-archives``.
+When using ``-a``, be careful to choose a good pattern - e.g. do not use a
 prefix "foo" if you do not also want to match "foobar".
 prefix "foo" if you do not also want to match "foobar".
 
 
 It is strongly recommended to always run ``prune -v --list --dry-run ...``
 It is strongly recommended to always run ``prune -v --list --dry-run ...``
@@ -22,7 +22,7 @@ first so you will see what it would do without it actually doing anything.
 
 
     # Same as above but only apply to archive names starting with the hostname
     # Same as above but only apply to archive names starting with the hostname
     # of the machine followed by a "-" character:
     # of the machine followed by a "-" character:
-    $ borg prune -v --list --keep-daily=7 --keep-weekly=4 --prefix='{hostname}-'
+    $ borg prune -v --list --keep-daily=7 --keep-weekly=4 -a '{hostname}-*'
     # actually free disk space:
     # actually free disk space:
     $ borg compact
     $ borg compact
 
 

+ 8 - 17
src/borg/archiver.py

@@ -459,8 +459,8 @@ class Archiver:
                        env_var_override='BORG_CHECK_I_KNOW_WHAT_I_AM_DOING'):
                        env_var_override='BORG_CHECK_I_KNOW_WHAT_I_AM_DOING'):
                 return EXIT_ERROR
                 return EXIT_ERROR
         if args.repo_only and any(
         if args.repo_only and any(
-           (args.verify_data, args.first, args.last, args.prefix is not None, args.glob_archives)):
-            self.print_error("--repository-only contradicts --first, --last, --prefix, --glob-archives "
+           (args.verify_data, args.first, args.last, args.glob_archives)):
+            self.print_error("--repository-only contradicts --first, --last, -a / --glob-archives "
                              " and --verify-data arguments.")
                              " and --verify-data arguments.")
             return EXIT_ERROR
             return EXIT_ERROR
         if args.repair and args.max_duration:
         if args.repair and args.max_duration:
@@ -476,8 +476,6 @@ class Archiver:
         if not args.archives_only:
         if not args.archives_only:
             if not repository.check(repair=args.repair, save_space=args.save_space, max_duration=args.max_duration):
             if not repository.check(repair=args.repair, save_space=args.save_space, max_duration=args.max_duration):
                 return EXIT_WARNING
                 return EXIT_WARNING
-        if args.prefix is not None:
-            args.glob_archives = args.prefix + '*'
         if not args.repo_only and not ArchiveChecker().check(repository, repair=args.repair,
         if not args.repo_only and not ArchiveChecker().check(repository, repair=args.repair,
                 first=args.first, last=args.last, sort_by=args.sort_by or 'ts', glob=args.glob_archives,
                 first=args.first, last=args.last, sort_by=args.sort_by or 'ts', glob=args.glob_archives,
                 verify_data=args.verify_data, save_space=args.save_space):
                 verify_data=args.verify_data, save_space=args.save_space):
@@ -1757,8 +1755,6 @@ class Archiver:
                              '"keep-secondly", "keep-minutely", "keep-hourly", "keep-daily", '
                              '"keep-secondly", "keep-minutely", "keep-hourly", "keep-daily", '
                              '"keep-weekly", "keep-monthly" or "keep-yearly" settings must be specified.')
                              '"keep-weekly", "keep-monthly" or "keep-yearly" settings must be specified.')
             return self.exit_code
             return self.exit_code
-        if args.prefix is not None:
-            args.glob_archives = args.prefix + '*'
         checkpoint_re = r'\.checkpoint(\.\d+)?'
         checkpoint_re = r'\.checkpoint(\.\d+)?'
         archives_checkpoints = manifest.archives.list(glob=args.glob_archives,
         archives_checkpoints = manifest.archives.list(glob=args.glob_archives,
                                                       consider_checkpoints=True,
                                                       consider_checkpoints=True,
@@ -2652,7 +2648,7 @@ class Archiver:
         This allows you to share the same patterns between multiple repositories
         This allows you to share the same patterns between multiple repositories
         without needing to specify them on the command line.\n\n''')
         without needing to specify them on the command line.\n\n''')
     helptext['placeholders'] = textwrap.dedent('''
     helptext['placeholders'] = textwrap.dedent('''
-        Repository URLs, ``--name``, ``--prefix``, ``--glob-archives``, ``--comment``
+        Repository URLs, ``--name``, ``-a`` / ``--glob-archives``, ``--comment``
         and ``--remote-path`` values support these placeholders:
         and ``--remote-path`` values support these placeholders:
 
 
         {hostname}
         {hostname}
@@ -2698,7 +2694,7 @@ class Archiver:
 
 
             borg create /path/to/repo::{hostname}-{user}-{utcnow} ...
             borg create /path/to/repo::{hostname}-{user}-{utcnow} ...
             borg create /path/to/repo::{hostname}-{now:%Y-%m-%d_%H:%M:%S} ...
             borg create /path/to/repo::{hostname}-{now:%Y-%m-%d_%H:%M:%S} ...
-            borg prune --prefix '{hostname}-' ...
+            borg prune -a '{hostname}-*' ...
 
 
         .. note::
         .. note::
             systemd uses a difficult, non-standard syntax for command lines in unit files (refer to
             systemd uses a difficult, non-standard syntax for command lines in unit files (refer to
@@ -3091,13 +3087,10 @@ class Archiver:
             filters_group = subparser.add_argument_group('Archive filters',
             filters_group = subparser.add_argument_group('Archive filters',
                                                          'Archive filters can be applied to repository targets.')
                                                          'Archive filters can be applied to repository targets.')
             group = filters_group.add_mutually_exclusive_group()
             group = filters_group.add_mutually_exclusive_group()
-            group.add_argument('-P', '--prefix', metavar='PREFIX', dest='prefix', type=PrefixSpec, action=Highlander,
-                               help='only consider archive names starting with this prefix.')
             group.add_argument('-a', '--glob-archives', metavar='GLOB', dest='glob_archives',
             group.add_argument('-a', '--glob-archives', metavar='GLOB', dest='glob_archives',
                                type=GlobSpec, action=Highlander,
                                type=GlobSpec, action=Highlander,
                                help='only consider archive names matching the glob. '
                                help='only consider archive names matching the glob. '
-                                    'sh: rules apply, see "borg help patterns". '
-                                    '``--prefix`` and ``--glob-archives`` are mutually exclusive.')
+                                    'sh: rules apply, see "borg help patterns".')
 
 
             if sort_by:
             if sort_by:
                 sort_by_default = 'timestamp'
                 sort_by_default = 'timestamp'
@@ -3971,11 +3964,9 @@ class Archiver:
         that is how much your repository will shrink.
         that is how much your repository will shrink.
         Please note that the "All archives" stats refer to the state after deletion.
         Please note that the "All archives" stats refer to the state after deletion.
 
 
-        You can delete multiple archives by specifying their common prefix, if they
-        have one, using the ``--prefix PREFIX`` option. You can also specify a shell
-        pattern to match multiple archives using the ``--glob-archives GLOB`` option
-        (for more info on these patterns, see :ref:`borg_patterns`). Note that these
-        two options are mutually exclusive.
+        You can delete multiple archives by specifying a matching shell pattern,
+        using the ``--glob-archives GLOB`` option (for more info on these patterns,
+        see :ref:`borg_patterns`).
 
 
         Always first use ``--dry-run --list`` to see what would be deleted.
         Always first use ``--dry-run --list`` to see what would be deleted.
         """)
         """)

+ 1 - 3
src/borg/helpers/manifest.py

@@ -106,9 +106,7 @@ class Archives(abc.MutableMapping):
         name = getattr(args, 'name', None)
         name = getattr(args, 'name', None)
         consider_checkpoints = getattr(args, 'consider_checkpoints', None)
         consider_checkpoints = getattr(args, 'consider_checkpoints', None)
         if name is not None:
         if name is not None:
-            raise Error('Giving a specific name is incompatible with options --first, --last, --prefix, and --glob-archives, and --consider-checkpoints.')
-        if args.prefix is not None:
-            args.glob_archives = args.prefix + '*'
+            raise Error('Giving a specific name is incompatible with options --first, --last, -a / --glob-archives, and --consider-checkpoints.')
         return self.list(sort_by=args.sort_by.split(','), consider_checkpoints=consider_checkpoints, glob=args.glob_archives, first=args.first, last=args.last)
         return self.list(sort_by=args.sort_by.split(','), consider_checkpoints=consider_checkpoints, glob=args.glob_archives, first=args.first, last=args.last)
 
 
     def set_raw_dict(self, d):
     def set_raw_dict(self, d):

+ 9 - 9
src/borg/testsuite/archiver.py

@@ -1600,7 +1600,7 @@ class ArchiverTestCase(ArchiverTestCaseBase):
         self.cmd(f'--repo={self.repository_location}', 'create', 'another_test.2', 'input')
         self.cmd(f'--repo={self.repository_location}', 'create', 'another_test.2', 'input')
         self.cmd(f'--repo={self.repository_location}', 'extract', 'test', '--dry-run')
         self.cmd(f'--repo={self.repository_location}', 'extract', 'test', '--dry-run')
         self.cmd(f'--repo={self.repository_location}', 'extract', 'test.2', '--dry-run')
         self.cmd(f'--repo={self.repository_location}', 'extract', 'test.2', '--dry-run')
-        self.cmd(f'--repo={self.repository_location}', 'delete', '--prefix', 'another_')
+        self.cmd(f'--repo={self.repository_location}', 'delete', '--glob-archives', 'another_*')
         self.cmd(f'--repo={self.repository_location}', 'delete', '--last', '1')
         self.cmd(f'--repo={self.repository_location}', 'delete', '--last', '1')
         self.cmd(f'--repo={self.repository_location}', 'delete', '-a', 'test')
         self.cmd(f'--repo={self.repository_location}', 'delete', '-a', 'test')
         self.cmd(f'--repo={self.repository_location}', 'extract', 'test.2', '--dry-run')
         self.cmd(f'--repo={self.repository_location}', 'extract', 'test.2', '--dry-run')
@@ -2259,7 +2259,7 @@ class ArchiverTestCase(ArchiverTestCaseBase):
         self.cmd(f'--repo={self.repository_location}', 'create', 'foo-2015-08-12-20:00', src_dir)
         self.cmd(f'--repo={self.repository_location}', 'create', 'foo-2015-08-12-20:00', src_dir)
         self.cmd(f'--repo={self.repository_location}', 'create', 'bar-2015-08-12-10:00', src_dir)
         self.cmd(f'--repo={self.repository_location}', 'create', 'bar-2015-08-12-10:00', src_dir)
         self.cmd(f'--repo={self.repository_location}', 'create', 'bar-2015-08-12-20:00', src_dir)
         self.cmd(f'--repo={self.repository_location}', 'create', 'bar-2015-08-12-20:00', src_dir)
-        output = self.cmd(f'--repo={self.repository_location}', 'prune', '--list', '--dry-run', '--keep-daily=1', '--prefix=foo-')
+        output = self.cmd(f'--repo={self.repository_location}', 'prune', '--list', '--dry-run', '--keep-daily=1', '--glob-archives=foo-*')
         assert re.search(r'Keeping archive \(rule: daily #1\):\s+foo-2015-08-12-20:00', output)
         assert re.search(r'Keeping archive \(rule: daily #1\):\s+foo-2015-08-12-20:00', output)
         assert re.search(r'Would prune:\s+foo-2015-08-12-10:00', output)
         assert re.search(r'Would prune:\s+foo-2015-08-12-10:00', output)
         output = self.cmd(f'--repo={self.repository_location}', 'rlist')
         output = self.cmd(f'--repo={self.repository_location}', 'rlist')
@@ -2267,7 +2267,7 @@ class ArchiverTestCase(ArchiverTestCaseBase):
         self.assert_in('foo-2015-08-12-20:00', output)
         self.assert_in('foo-2015-08-12-20:00', output)
         self.assert_in('bar-2015-08-12-10:00', output)
         self.assert_in('bar-2015-08-12-10:00', output)
         self.assert_in('bar-2015-08-12-20:00', output)
         self.assert_in('bar-2015-08-12-20:00', output)
-        self.cmd(f'--repo={self.repository_location}', 'prune', '--keep-daily=1', '--prefix=foo-')
+        self.cmd(f'--repo={self.repository_location}', 'prune', '--keep-daily=1', '--glob-archives=foo-*')
         output = self.cmd(f'--repo={self.repository_location}', 'rlist')
         output = self.cmd(f'--repo={self.repository_location}', 'rlist')
         self.assert_not_in('foo-2015-08-12-10:00', output)
         self.assert_not_in('foo-2015-08-12-10:00', output)
         self.assert_in('foo-2015-08-12-20:00', output)
         self.assert_in('foo-2015-08-12-20:00', output)
@@ -2300,7 +2300,7 @@ class ArchiverTestCase(ArchiverTestCaseBase):
         self.cmd(f'--repo={self.repository_location}', 'create', 'test-1', src_dir)
         self.cmd(f'--repo={self.repository_location}', 'create', 'test-1', src_dir)
         self.cmd(f'--repo={self.repository_location}', 'create', 'something-else-than-test-1', src_dir)
         self.cmd(f'--repo={self.repository_location}', 'create', 'something-else-than-test-1', src_dir)
         self.cmd(f'--repo={self.repository_location}', 'create', 'test-2', src_dir)
         self.cmd(f'--repo={self.repository_location}', 'create', 'test-2', src_dir)
-        output = self.cmd(f'--repo={self.repository_location}', 'rlist', '--prefix=test-')
+        output = self.cmd(f'--repo={self.repository_location}', 'rlist', '--glob-archives=test-*')
         self.assert_in('test-1', output)
         self.assert_in('test-1', output)
         self.assert_in('test-2', output)
         self.assert_in('test-2', output)
         self.assert_not_in('something-else', output)
         self.assert_not_in('something-else', output)
@@ -2664,13 +2664,13 @@ class ArchiverTestCase(ArchiverTestCaseBase):
             assert sorted(os.listdir(os.path.join(mountpoint))) == ['arch11', 'arch12']
             assert sorted(os.listdir(os.path.join(mountpoint))) == ['arch11', 'arch12']
         with self.fuse_mount(self.repository_location, mountpoint, '--last=2', '--sort=name'):
         with self.fuse_mount(self.repository_location, mountpoint, '--last=2', '--sort=name'):
             assert sorted(os.listdir(os.path.join(mountpoint))) == ['arch21', 'arch22']
             assert sorted(os.listdir(os.path.join(mountpoint))) == ['arch21', 'arch22']
-        with self.fuse_mount(self.repository_location, mountpoint, '--prefix=arch1'):
+        with self.fuse_mount(self.repository_location, mountpoint, '--glob-archives=arch1*'):
             assert sorted(os.listdir(os.path.join(mountpoint))) == ['arch11', 'arch12']
             assert sorted(os.listdir(os.path.join(mountpoint))) == ['arch11', 'arch12']
-        with self.fuse_mount(self.repository_location, mountpoint, '--prefix=arch2'):
+        with self.fuse_mount(self.repository_location, mountpoint, '--glob-archives=arch2*'):
             assert sorted(os.listdir(os.path.join(mountpoint))) == ['arch21', 'arch22']
             assert sorted(os.listdir(os.path.join(mountpoint))) == ['arch21', 'arch22']
-        with self.fuse_mount(self.repository_location, mountpoint, '--prefix=arch'):
+        with self.fuse_mount(self.repository_location, mountpoint, '--glob-archives=arch*'):
             assert sorted(os.listdir(os.path.join(mountpoint))) == ['arch11', 'arch12', 'arch21', 'arch22']
             assert sorted(os.listdir(os.path.join(mountpoint))) == ['arch11', 'arch12', 'arch21', 'arch22']
-        with self.fuse_mount(self.repository_location, mountpoint, '--prefix=nope'):
+        with self.fuse_mount(self.repository_location, mountpoint, '--glob-archives=nope'):
             assert sorted(os.listdir(os.path.join(mountpoint))) == []
             assert sorted(os.listdir(os.path.join(mountpoint))) == []
 
 
     @unittest.skipUnless(llfuse, 'llfuse not installed')
     @unittest.skipUnless(llfuse, 'llfuse not installed')
@@ -3559,7 +3559,7 @@ class ArchiverCheckTestCase(ArchiverTestCaseBase):
         output = self.cmd(f'--repo={self.repository_location}', 'check', '-v', '--archives-only', exit_code=0)
         output = self.cmd(f'--repo={self.repository_location}', 'check', '-v', '--archives-only', exit_code=0)
         self.assert_not_in('Starting repository check', output)
         self.assert_not_in('Starting repository check', output)
         self.assert_in('Starting archive consistency check', output)
         self.assert_in('Starting archive consistency check', output)
-        output = self.cmd(f'--repo={self.repository_location}', 'check', '-v', '--archives-only', '--prefix=archive2', exit_code=0)
+        output = self.cmd(f'--repo={self.repository_location}', 'check', '-v', '--archives-only', '--glob-archives=archive2', exit_code=0)
         self.assert_not_in('archive1', output)
         self.assert_not_in('archive1', output)
         output = self.cmd(f'--repo={self.repository_location}', 'check', '-v', '--archives-only', '--first=1', exit_code=0)
         output = self.cmd(f'--repo={self.repository_location}', 'check', '-v', '--archives-only', '--first=1', exit_code=0)
         self.assert_in('archive1', output)
         self.assert_in('archive1', output)