Skip to content

Commit

Permalink
Ensure that 0B changes are hidden from text diffs too.
Browse files Browse the repository at this point in the history
  • Loading branch information
cr1901 committed Aug 19, 2024
1 parent f7673e3 commit 4fe882c
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 17 deletions.
22 changes: 12 additions & 10 deletions src/borg/archiver.py
Original file line number Diff line number Diff line change
Expand Up @@ -1121,20 +1121,22 @@ def item_to_tarinfo(item, original_path):
def do_diff(self, args, repository, manifest, key, archive):
"""Diff contents of two archives"""

def print_json_output(diff, path):
def actual_change(j):
if j["type"] == "modified":
# It's useful to show 0 added and 0 removed for text output
# but for JSON this is essentially noise. Additionally, the
# JSON key is "changes", and this is not actually a change.
return not (j["added"] == 0 and j["removed"] == 0)
else:
return True
def actual_change(j):
if j["type"] != "modified":
return True
else:
# Added/removed keys will not exist if chunker params differ
# between the two archives. Err on the side of caution and assume
# a real modification in this case (short-circuiting retrieving
# non-existent keys.
return not {"added", "removed"} <= j.keys() or not (j["added"] == 0 and j["removed"] == 0)

def print_json_output(diff, path):
print(json.dumps({"path": path, "changes": [j for j, str in diff if actual_change(j)]}, sort_keys=True, cls=BorgJsonEncoder))

def print_text_output(diff, path):
print("{:<19} {}".format(' '.join([str for j, str in diff]), path))
print(diff)
print("{:<19} {}".format(' '.join([str for j, str in diff if actual_change(j)]), path))

print_output = print_json_output if args.json_lines else print_text_output

Expand Down
3 changes: 3 additions & 0 deletions src/borg/testsuite/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,9 @@ def assert_dirs_equal(self, dir1, dir2, **kwargs):
def assert_line_exists(self, lines, expected_regexpr):
assert any(re.search(expected_regexpr, line) for line in lines), f"no match for {expected_regexpr} in {lines}"

def assert_line_not_exists(self, lines, expected_regexpr):
assert not any(re.search(expected_regexpr, line) for line in lines), f"unexpected match for {expected_regexpr} in {lines}"

def _assert_dirs_equal_cmp(self, diff, ignore_flags=False, ignore_xattrs=False, ignore_ns=False):
self.assert_equal(diff.left_only, [])
self.assert_equal(diff.right_only, [])
Expand Down
16 changes: 9 additions & 7 deletions src/borg/testsuite/archiver.py
Original file line number Diff line number Diff line change
Expand Up @@ -4565,12 +4565,14 @@ def do_asserts(output, can_compare_ids, content_only=False):
change = '0 B' if can_compare_ids else '{:<19}'.format('modified')
self.assert_line_exists(lines, f"{change}.*input/empty")

# Show a 0 byte change for a file whose contents weren't modified
# for text output.
if content_only:
assert "input/file_touched" not in output
# Do not show a 0 byte change for a file whose contents weren't
# modified.
self.assert_line_not_exists(lines, '0 B.*input/file_touched')
if not content_only:
self.assert_line_exists(lines, "[cm]time:.*input/file_touched")
else:
self.assert_line_exists(lines, f"{change}.*input/file_touched")
# And if we're doing content-only, don't show the file at all.
assert "input/file_touched" not in output

if are_hardlinks_supported():
self.assert_line_exists(lines, f"{change}.*input/hardlink_contents_changed")
Expand Down Expand Up @@ -4620,8 +4622,8 @@ def get_changes(filename, data):
# File unchanged
assert not any(get_changes('input/file_unchanged', joutput))

# Do NOT show a 0 byte change for a file whose contents weren't
# modified for JSON output.
# Do not show a 0 byte change for a file whose contents weren't
# modified.
unexpected = {'type': 'modified', 'added': 0, 'removed': 0}
assert unexpected not in get_changes('input/file_touched', joutput)
if not content_only:
Expand Down

0 comments on commit 4fe882c

Please sign in to comment.