Quellcode durchsuchen

Add submodule support in write_tree_diff.

Jelmer Vernooij vor 14 Jahren
Ursprung
Commit
6f5f462b34
2 geänderte Dateien mit 49 neuen und 14 gelöschten Zeilen
  1. 46 11
      dulwich/patch.py
  2. 3 3
      dulwich/tests/test_patch.py

+ 46 - 11
dulwich/patch.py

@@ -27,8 +27,8 @@ import rfc822
 import time
 
 from dulwich.objects import (
-    Blob,
     Commit,
+    S_ISGITLINK,
     )
 
 def write_commit_patch(f, commit, contents, progress, version=None):
@@ -103,6 +103,49 @@ def unified_diff(a, b, fromfile='', tofile='', n=3):
                     yield '+' + line
 
 
+def write_object_diff(f, store, (old_path, old_mode, old_id),
+                                (new_path, new_mode, new_id)):
+    """Write file contents diff.
+
+    """
+    def shortid(hexsha):
+        if hexsha is None:
+            return "0" * 7
+        else:
+            return hexsha[:7]
+    def lines(mode, hexsha):
+        if hexsha is None:
+            return []
+        elif S_ISGITLINK(mode):
+            return ["Submodule commit " + hexsha + "\n"]
+        else:
+            return store[hexsha].data.splitlines(True)
+    if old_path is None:
+        old_path = "/dev/null"
+    else:
+        old_path = "a/%s" % old_path
+    if new_path is None:
+        new_path = "/dev/null"
+    else:
+        new_path = "b/%s" % new_path
+    f.write("diff --git %s %s\n" % (old_path, new_path))
+    if old_mode != new_mode:
+        if new_mode is not None:
+            if old_mode is not None:
+                f.write("old mode %o\n" % old_mode)
+            f.write("new mode %o\n" % new_mode)
+        else:
+            f.write("deleted mode %o\n" % old_mode)
+    f.write("index %s..%s" % (shortid(old_id), shortid(new_id)))
+    if new_mode is not None:
+        f.write(" %o" % new_mode)
+    f.write("\n")
+    old_contents = lines(old_mode, old_id)
+    new_contents = lines(new_mode, new_id)
+    f.writelines(unified_diff(old_contents, new_contents,
+        old_path, new_path))
+
+
 def write_blob_diff(f, (old_path, old_mode, old_blob),
                        (new_path, new_mode, new_blob)):
     """Write diff file header.
@@ -156,16 +199,8 @@ def write_tree_diff(f, store, old_tree, new_tree):
     """
     changes = store.tree_changes(old_tree, new_tree)
     for (oldpath, newpath), (oldmode, newmode), (oldsha, newsha) in changes:
-        if oldsha is None:
-            old_blob = Blob.from_string("")
-        else:
-            old_blob = store[oldsha]
-        if newsha is None:
-            new_blob = Blob.from_string("")
-        else:
-            new_blob = store[newsha]
-        write_blob_diff(f, (oldpath, oldmode, old_blob),
-                           (newpath, newmode, new_blob))
+        write_object_diff(f, store, (oldpath, oldmode, oldsha),
+                                    (newpath, newmode, newsha))
 
 
 def git_am_patch_split(f):

+ 3 - 3
dulwich/tests/test_patch.py

@@ -270,7 +270,7 @@ class DiffTests(TestCase):
         self.assertEquals([
             'diff --git /dev/null b/added.txt',
             'new mode 644',
-            'index e69de29..76d4bb8 644',
+            'index 0000000..76d4bb8 644',
             '--- /dev/null',
             '+++ b/added.txt',
             '@@ -1,0 +1,1 @@',
@@ -285,7 +285,7 @@ class DiffTests(TestCase):
             '+added',
             'diff --git a/removed.txt /dev/null',
             'deleted mode 644',
-            'index 2c3f0b3..e69de29',
+            'index 2c3f0b3..0000000',
             '--- a/removed.txt',
             '+++ /dev/null',
             '@@ -1,1 +1,0 @@',
@@ -305,7 +305,7 @@ class DiffTests(TestCase):
         write_tree_diff(f, store, tree1.id, tree2.id)
         self.assertEquals([
             'diff --git a/asubmodule b/asubmodule',
-            'index e69de29..76d4bb8 160000 (submodule)',
+            'index 06d0bdd..cc97564 160000',
             '--- a/asubmodule',
             '+++ b/asubmodule',
             '@@ -1,1 +1,1 @@',