Browse Source

Do not use /dev/null in the "git diff" header line

The documentation
https://git-scm.com/docs/diff-format#_generating_patches_with_p indicates
that: "The a/ and b/ filenames are the same unless rename/copy is involved.
Especially, even for a creation or a deletion, /dev/null is not used in place
of the a/ or b/ filenames."

Update gen_diff_header to match the documentation and CGit behavior.

With this commit, the test applying the git diff using CGit now pass. The next
commit is an additional cleanup to match CGit behavior.
Boris Feld 6 years ago
parent
commit
0884ad4907
3 changed files with 31 additions and 18 deletions
  1. 21 8
      dulwich/patch.py
  2. 8 8
      dulwich/tests/test_patch.py
  3. 2 2
      dulwich/tests/test_porcelain.py

+ 21 - 8
dulwich/patch.py

@@ -185,8 +185,8 @@ def write_object_diff(f, store, old_file, new_file, diff_binary=False):
     """
     (old_path, old_mode, old_id) = old_file
     (new_path, new_mode, new_id) = new_file
-    old_path = patch_filename(old_path, b"a")
-    new_path = patch_filename(new_path, b"b")
+    patched_old_path = patch_filename(old_path, b"a")
+    patched_new_path = patch_filename(new_path, b"b")
 
     def content(mode, hexsha):
         if hexsha is None:
@@ -207,11 +207,17 @@ def write_object_diff(f, store, old_file, new_file, diff_binary=False):
     new_content = content(new_mode, new_id)
     if not diff_binary and (
             is_binary(old_content.data) or is_binary(new_content.data)):
-        f.write(b"Binary files " + old_path + b" and " + new_path +
-                b" differ\n")
+        binary_diff = (
+            b"Binary files "
+            + patched_old_path
+            + b" and "
+            + patched_new_path
+            + b" differ\n"
+        )
+        f.write(binary_diff)
     else:
         f.writelines(unified_diff(lines(old_content), lines(new_content),
-                     old_path, new_path))
+                     patched_old_path, patched_new_path))
 
 
 # TODO(jelmer): Support writing unicode, rather than bytes.
@@ -225,7 +231,14 @@ def gen_diff_header(paths, modes, shas):
     (old_path, new_path) = paths
     (old_mode, new_mode) = modes
     (old_sha, new_sha) = shas
+    if old_path is None and new_path is not None:
+        old_path = new_path
+    if new_path is None and old_path is not None:
+        new_path = old_path
+    old_path = patch_filename(old_path, b"a")
+    new_path = patch_filename(new_path, b"b")
     yield b"diff --git " + old_path + b" " + new_path + b"\n"
+
     if old_mode != new_mode:
         if new_mode is not None:
             if old_mode is not None:
@@ -251,8 +264,8 @@ def write_blob_diff(f, old_file, new_file):
     """
     (old_path, old_mode, old_blob) = old_file
     (new_path, new_mode, new_blob) = new_file
-    old_path = patch_filename(old_path, b"a")
-    new_path = patch_filename(new_path, b"b")
+    patched_old_path = patch_filename(old_path, b"a")
+    patched_new_path = patch_filename(new_path, b"b")
 
     def lines(blob):
         if blob is not None:
@@ -265,7 +278,7 @@ def write_blob_diff(f, old_file, new_file):
     old_contents = lines(old_blob)
     new_contents = lines(new_blob)
     f.writelines(unified_diff(old_contents, new_contents,
-                 old_path, new_path))
+                 patched_old_path, patched_new_path))
 
 
 def write_tree_diff(f, store, old_tree, new_tree, diff_binary=False):

+ 8 - 8
dulwich/tests/test_patch.py

@@ -276,7 +276,7 @@ class DiffTests(TestCase):
             f, (None, None, None),
             (b"bar.txt", 0o644, Blob.from_string(b"new\nsame\n")))
         self.assertEqual([
-             b'diff --git /dev/null b/bar.txt',
+             b'diff --git a/bar.txt b/bar.txt',
              b'new file mode 644',
              b'index 0000000..a116b51 644',
              b'--- /dev/null',
@@ -292,7 +292,7 @@ class DiffTests(TestCase):
             f, (b"bar.txt", 0o644, Blob.from_string(b"new\nsame\n")),
             (None, None, None))
         self.assertEqual([
-            b'diff --git a/bar.txt /dev/null',
+            b'diff --git a/bar.txt b/bar.txt',
             b'deleted file mode 644',
             b'index a116b51..0000000',
             b'--- a/bar.txt',
@@ -322,7 +322,7 @@ class DiffTests(TestCase):
             tree1, tree2, added, removed, changed1, changed2, unchanged]])
         write_tree_diff(f, store, tree1.id, tree2.id)
         self.assertEqual([
-            b'diff --git /dev/null b/added.txt',
+            b'diff --git a/added.txt b/added.txt',
             b'new file mode 644',
             b'index 0000000..76d4bb8 644',
             b'--- /dev/null',
@@ -337,7 +337,7 @@ class DiffTests(TestCase):
             b' unchanged',
             b'-removed',
             b'+added',
-            b'diff --git a/removed.txt /dev/null',
+            b'diff --git a/removed.txt b/removed.txt',
             b'deleted file mode 644',
             b'index 2c3f0b3..0000000',
             b'--- a/removed.txt',
@@ -394,7 +394,7 @@ class DiffTests(TestCase):
         write_object_diff(f, store, (None, None, None),
                                     (b"bar.txt", 0o644, b2.id))
         self.assertEqual([
-             b'diff --git /dev/null b/bar.txt',
+             b'diff --git a/bar.txt b/bar.txt',
              b'new file mode 644',
              b'index 0000000..a116b51 644',
              b'--- /dev/null',
@@ -412,7 +412,7 @@ class DiffTests(TestCase):
         write_object_diff(f, store, (b"bar.txt", 0o644, b1.id),
                                     (None, None, None))
         self.assertEqual([
-            b'diff --git a/bar.txt /dev/null',
+            b'diff --git a/bar.txt b/bar.txt',
             b'deleted file mode 644',
             b'index a116b51..0000000',
             b'--- a/bar.txt',
@@ -492,7 +492,7 @@ class DiffTests(TestCase):
         write_object_diff(f, store, (None, None, None),
                                     (b'bar.png', 0o644, b2.id))
         self.assertEqual([
-            b'diff --git /dev/null b/bar.png',
+            b'diff --git a/bar.png b/bar.png',
             b'new file mode 644',
             b'index 0000000..06364b7 644',
             b'Binary files /dev/null and b/bar.png differ'
@@ -510,7 +510,7 @@ class DiffTests(TestCase):
         write_object_diff(f, store, (b'foo.png', 0o644, b1.id),
                                     (None, None, None))
         self.assertEqual([
-            b'diff --git a/foo.png /dev/null',
+            b'diff --git a/foo.png b/foo.png',
             b'deleted file mode 644',
             b'index f73e47d..0000000',
             b'Binary files a/foo.png and /dev/null differ'

+ 2 - 2
dulwich/tests/test_porcelain.py

@@ -572,7 +572,7 @@ Date:   Fri Jan 01 2010 00:00:00 +0000
 
 Test message.
 
-diff --git /dev/null b/somename
+diff --git a/somename b/somename
 new file mode 100644
 index 0000000..ea5c7bf 100644
 --- /dev/null
@@ -609,7 +609,7 @@ Date:   Fri Jan 01 2010 00:00:00 +0000
 
 Test message.
 
-diff --git /dev/null b/somename
+diff --git a/somename b/somename
 new file mode 100644
 index 0000000..ea5c7bf 100644
 --- /dev/null