diff --git a/tests/samples/debdiff.diff b/tests/samples/debdiff.diff new file mode 100644 index 0000000..a53efe9 --- /dev/null +++ b/tests/samples/debdiff.diff @@ -0,0 +1,7 @@ +diff -u -N original/added.txt new/added.txt +--- original/added.txt 1970-01-01 01:00:00.000000000 +0100 ++++ new/added.txt 2025-03-26 12:42:27.672906377 +0000 +@@ -0,0 +1 @@ ++new file +Binary files Binary files /t/p1/a.png and /t/p2/a.png differ +Binary files Binary files /t/p1/b.png and /t/p2/b.png differ diff --git a/tests/test_parser.py b/tests/test_parser.py index 74afa43..5573540 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -257,30 +257,57 @@ def test_parse_diff_with_new_and_modified_binary_files(self): self.assertFalse(res[0].is_removed_file) self.assertTrue(res[0].is_added_file) self.assertFalse(res[0].is_binary_file) + self.assertEqual(res[0].diff_line_no, 1) # second file is added self.assertFalse(res[1].is_modified_file) self.assertFalse(res[1].is_removed_file) self.assertTrue(res[1].is_added_file) self.assertTrue(res[1].is_binary_file) + self.assertEqual(res[1].diff_line_no, 4) # third file is modified self.assertTrue(res[2].is_modified_file) self.assertFalse(res[2].is_removed_file) self.assertFalse(res[2].is_added_file) self.assertTrue(res[2].is_binary_file) + self.assertEqual(res[2].diff_line_no, 8) # fourth file is removed self.assertFalse(res[3].is_modified_file) self.assertTrue(res[3].is_removed_file) self.assertFalse(res[3].is_added_file) self.assertTrue(res[3].is_binary_file) + self.assertEqual(res[3].diff_line_no, 11) # fifth empty file is added self.assertFalse(res[4].is_modified_file) self.assertFalse(res[4].is_removed_file) self.assertTrue(res[4].is_added_file) self.assertFalse(res[4].is_binary_file) + self.assertEqual(res[4].diff_line_no, 15) + + def test_parse_diff_with_new_and_modified_binary_files_linenos(self): + """Parse debdiff output for a source debdiff with binary files.""" + utf8_file = os.path.join(self.samples_dir, 'samples/debdiff.diff') + with open(utf8_file, 'r') as diff_file: + res = PatchSet(diff_file) + + # three file in the patch + self.assertEqual(len(res), 3) + + # first file is new/added.txt + self.assertEqual(res[0].path, 'new/added.txt') + + # first file, first patch, first hunk diff_line_no is 5 + self.assertEqual(res[0][0][0].diff_line_no, 5) + self.assertEqual(res[0].diff_line_no, 3) + + # second file is /t/p2/a.png + self.assertEqual(res[1].path, '/t/p2/a.png') + + # How to know the second file line number? + self.assertEqual(res[1].diff_line_no, 6) def test_parse_round_trip_with_binary_files_in_diff(self): """Parse git diff with binary files though round trip""" diff --git a/unidiff/patch.py b/unidiff/patch.py index bee28fc..26772e7 100644 --- a/unidiff/patch.py +++ b/unidiff/patch.py @@ -235,11 +235,12 @@ def target(self): class PatchedFile(list): """Patch updated file, it is a list of Hunks.""" - def __init__(self, patch_info=None, source='', target='', + def __init__(self, diff_line_no=None, patch_info=None, source='', target='', source_timestamp=None, target_timestamp=None, is_binary_file=False): - # type: (Optional[PatchInfo], str, str, Optional[str], Optional[str], bool, bool) -> None + # type: (int, Optional[PatchInfo], str, str, Optional[str], Optional[str], bool, bool) -> None super(PatchedFile, self).__init__() + self.diff_line_no = diff_line_no self.patch_info = patch_info self.source_file = source self.source_timestamp = source_timestamp @@ -482,7 +483,7 @@ def _parse(self, diff, encoding, metadata_only): patch_info = None diff = enumerate(diff, 1) - for unused_diff_line_no, line in diff: + for diff_line_no, line in diff: if encoding is not None: line = line.decode(encoding) @@ -495,7 +496,7 @@ def _parse(self, diff, encoding, metadata_only): source_file = is_diff_git_header.group('source') target_file = is_diff_git_header.group('target') current_file = PatchedFile( - patch_info, source_file, target_file, None, None) + diff_line_no, patch_info, source_file, target_file, None, None) self.append(current_file) patch_info.append(line) continue @@ -542,6 +543,7 @@ def _parse(self, diff, encoding, metadata_only): if current_file is None: # add current file to PatchSet current_file = PatchedFile( + diff_line_no, patch_info, source_file, target_file, source_timestamp, target_timestamp) self.append(current_file) @@ -586,7 +588,8 @@ def _parse(self, diff, encoding, metadata_only): current_file.is_binary_file = True else: current_file = PatchedFile( - patch_info, source_file, target_file, is_binary_file=True) + diff_line_no, patch_info, source_file, target_file, + is_binary_file=True) self.append(current_file) patch_info = None current_file = None