1
0
Fork 0
mirror of https://github.com/borgbackup/borg.git synced 2025-02-22 22:22:27 +00:00

add a --filter option replacing --changed/--unchanged

the problem here was that we do not just have changed and unchanged items,
but also a lot of items besides regular files which we just back up "as is" without
determining whether they are changed or not. thus, we can't support changed/unchanged
in a way users would expect them to work.

the A/M/U status only applies to the data content of regular files (compared to the index).
for all items, we ALWAYS save the metadata, there is no changed / not changed detection there.

thus, I replaced this with a --filter option where you can just specify which
status chars you want to see listed in the output.

E.g. --filter AM will only show regular files with A(dded) or M(odified) state, but nothing else.
Not giving --filter defaults to showing all items no matter what status they have.

Output is emitted via logger at info level, so it won't show up except if the logger is at that level.
This commit is contained in:
Thomas Waldmann 2015-12-02 02:55:59 +01:00
parent b09643e14f
commit 21bd01ef16
3 changed files with 19 additions and 22 deletions

View file

@ -74,12 +74,8 @@ def print_warning(self, msg, *args):
logger.warning(msg)
def print_file_status(self, status, path):
if status == 'U':
if self.unchanged:
print("%1s %s" % (status, remove_surrogates(path)), file=sys.stderr)
else:
if self.changed:
print("%1s %s" % (status, remove_surrogates(path)), file=sys.stderr)
if self.output_filter is None or status in self.output_filter:
logger.info("%1s %s", status, remove_surrogates(path))
def do_serve(self, args):
"""Start in server mode. This command is usually not used manually.
@ -128,6 +124,7 @@ def do_change_passphrase(self, args):
def do_create(self, args):
"""Create new archive"""
self.output_filter = args.output_filter
dry_run = args.dry_run
t0 = datetime.now()
if not dry_run:
@ -806,10 +803,8 @@ def build_parser(self, args=None, prog=None):
help="""toggle progress display while creating the archive, showing Original,
Compressed and Deduplicated sizes, followed by the Number of files seen
and the path being processed, default: %(default)s""")
subparser.add_argument('--changed', action='store_true', dest='changed', default=False,
help="""display which files were added to the archive""")
subparser.add_argument('--unchanged', action='store_true', dest='unchanged', default=False,
help="""display which files were *not* added to the archive""")
subparser.add_argument('--filter', dest='output_filter', metavar='STATUSCHARS',
help='only display items with the given status characters')
subparser.add_argument('-e', '--exclude', dest='excludes',
type=ExcludePattern, action='append',
metavar="PATTERN", help='exclude paths matching PATTERN')
@ -1186,8 +1181,6 @@ def parse_args(self, args=None):
def run(self, args):
os.umask(args.umask) # early, before opening files
self.lock_wait = args.lock_wait
self.changed = getattr(args, 'changed', False)
self.unchanged = getattr(args, 'unchanged', False)
RemoteRepository.remote_path = args.remote_path
RemoteRepository.umask = args.umask
setup_logging(level=args.log_level) # do not use loggers before this!

View file

@ -713,11 +713,11 @@ def test_file_status(self):
os.utime('input/file1', (now - 5, now - 5)) # 5 seconds ago
self.create_regular_file('file2', size=1024 * 80)
self.cmd('init', self.repository_location)
output = self.cmd('create', '--changed', '--unchanged', self.repository_location + '::test', 'input')
output = self.cmd('create', '-v', self.repository_location + '::test', 'input')
self.assert_in("A input/file1", output)
self.assert_in("A input/file2", output)
# should find first file as unmodified
output = self.cmd('create', '--changed', '--unchanged', self.repository_location + '::test1', 'input')
output = self.cmd('create', '-v', self.repository_location + '::test1', 'input')
self.assert_in("U input/file1", output)
# this is expected, although surprising, for why, see:
# http://borgbackup.readthedocs.org/en/latest/faq.html#i-am-seeing-a-added-status-for-a-unchanged-file
@ -736,15 +736,15 @@ def test_create_topical(self):
output = self.cmd('create', self.repository_location + '::test0', 'input')
self.assert_not_in('file1', output)
# should list the file as unchanged
output = self.cmd('create', '--unchanged', self.repository_location + '::test1', 'input')
output = self.cmd('create', '-v', '--filter=U', self.repository_location + '::test1', 'input')
self.assert_in('file1', output)
# should *not* list the file as changed
output = self.cmd('create', '--changed', self.repository_location + '::test2', 'input')
output = self.cmd('create', '-v', '--filter=AM', self.repository_location + '::test2', 'input')
self.assert_not_in('file1', output)
# change the file
self.create_regular_file('file1', size=1024 * 100)
# should list the file as changed
output = self.cmd('create', '--changed', self.repository_location + '::test3', 'input')
output = self.cmd('create', '-v', '--filter=AM', self.repository_location + '::test3', 'input')
self.assert_in('file1', output)
def test_cmdline_compatibility(self):

View file

@ -429,10 +429,14 @@ Here are misc. notes about topics that are maybe not covered in enough detail in
Item flags
~~~~~~~~~~
`borg create --changed` outputs a verbose list of all files, directories and other
file system items it considered, with the exception of unchanged files
(for this, also add `--unchanged`). For each item, it prefixes a single-letter
flag that indicates type and/or status of the item.
`borg create -v` outputs a verbose list of all files, directories and other
file system items it considered (no matter whether they had content changes
or not). For each item, it prefixes a single-letter flag that indicates type
and/or status of the item.
If you are interested only in a subset of that output, you can give e.g.
`--filter=AME` and it will only show regular files with A, M or E status (see
below).
A uppercase character represents the status of a regular file relative to the
"files" cache (not relative to the repo - this is an issue if the files cache
@ -441,7 +445,7 @@ chunks are stored. For 'U' all data chunks refer to already existing chunks.
- 'A' = regular file, added (see also :ref:`a_status_oddity` in the FAQ)
- 'M' = regular file, modified
- 'U' = regular file, unchanged (only if `--unchanged` is specified)
- 'U' = regular file, unchanged
- 'E' = regular file, an error happened while accessing/reading *this* file
A lowercase character means a file type other than a regular file,