فهرست منبع

Ensure that 0B changes are hidden from text diffs too.

William D. Jones 9 ماه پیش
والد
کامیت
938e144f8b
3فایلهای تغییر یافته به همراه24 افزوده شده و 17 حذف شده
  1. 12 10
      src/borg/archiver.py
  2. 3 0
      src/borg/testsuite/__init__.py
  3. 9 7
      src/borg/testsuite/archiver.py

+ 12 - 10
src/borg/archiver.py

@@ -1121,20 +1121,22 @@ class Archiver:
     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":
+                # 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)
+            else:
+                # All other change types are indeed changes.
+                return True
 
+        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("{:<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
 

+ 3 - 0
src/borg/testsuite/__init__.py

@@ -191,6 +191,9 @@ class BaseTestCase(unittest.TestCase):
     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, [])

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

@@ -4565,12 +4565,14 @@ class DiffArchiverTestCase(ArchiverTestCaseBase):
             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")
@@ -4620,8 +4622,8 @@ class DiffArchiverTestCase(ArchiverTestCaseBase):
             # 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: