ソースを参照

Simplify patch header handling.

Jelmer Vernooij 10 年 前
コミット
60d2a6c6f5
1 ファイル変更48 行追加53 行削除
  1. 48 53
      dulwich/patch.py

+ 48 - 53
dulwich/patch.py

@@ -115,6 +115,20 @@ def is_binary(content):
     return '\0' in content[:FIRST_FEW_BYTES]
 
 
+def shortid(hexsha):
+    if hexsha is None:
+        return "0" * 7
+    else:
+        return hexsha[:7]
+
+
+def patch_filename(p, root):
+    if p is None:
+        return "/dev/null"
+    else:
+        return root + "/" + p
+
+
 def write_object_diff(f, store, old_file, new_file, diff_binary=False):
     """Write the diff for an object.
 
@@ -129,12 +143,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
-    def shortid(hexsha):
-        if hexsha is None:
-            return "0" * 7
-        else:
-            return hexsha[:7]
-
+    old_path = patch_filename(old_path, "a")
+    new_path = patch_filename(new_path, "b")
     def content(mode, hexsha):
         if hexsha is None:
             return ''
@@ -148,27 +158,8 @@ def write_object_diff(f, store, old_file, new_file, diff_binary=False):
             return []
         else:
             return content.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")
+    f.writelines(gen_diff_header(
+        (old_path, new_path), (old_mode, new_mode), (old_id, new_id)))
     old_content = content(old_mode, old_id)
     new_content = content(new_mode, new_id)
     if not diff_binary and (is_binary(old_content) or is_binary(new_content)):
@@ -178,8 +169,32 @@ def write_object_diff(f, store, old_file, new_file, diff_binary=False):
             old_path, new_path))
 
 
+def gen_diff_header(paths, modes, shas):
+    """Write a blob diff header.
+
+    :param paths: Tuple with old and new path
+    :param modes: Tuple with old and new modes
+    :param shas: Tuple with old and new shas
+    """
+    (old_path, new_path) = paths
+    (old_mode, new_mode) = modes
+    (old_sha, new_sha) = shas
+    yield "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:
+                yield "old mode %o\n" % old_mode
+            yield "new mode %o\n" % new_mode
+        else:
+            yield "deleted mode %o\n" % old_mode
+    yield "index " + shortid(old_sha) + ".." + shortid(new_sha)
+    if new_mode is not None:
+        yield " %o" % new_mode
+    yield "\n"
+
+
 def write_blob_diff(f, old_file, new_file):
-    """Write diff file header.
+    """Write blob diff.
 
     :param f: File-like object to write to
     :param old_file: (path, mode, hexsha) tuple (None if nonexisting)
@@ -189,36 +204,16 @@ 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
-    def blob_id(blob):
-        if blob is None:
-            return "0" * 7
-        else:
-            return blob.id[:7]
+    old_path = patch_filename(old_path, "a")
+    new_path = patch_filename(new_path, "b")
     def lines(blob):
         if blob is not None:
             return blob.data.splitlines(True)
         else:
             return []
-    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" % (blob_id(old_blob), blob_id(new_blob)))
-    if new_mode is not None:
-        f.write(" %o" % new_mode)
-    f.write("\n")
+    f.writelines(gen_diff_header(
+        (old_path, new_path), (old_mode, new_mode),
+        (getattr(old_blob, "id", None), getattr(new_blob, "id", None))))
     old_contents = lines(old_blob)
     new_contents = lines(new_blob)
     f.writelines(unified_diff(old_contents, new_contents,