mercurial/patch.py
changeset 45098 20a65e397943
parent 45072 a56ba57c837d
child 45154 10f48720ef95
--- a/mercurial/patch.py	Thu Jul 09 12:52:04 2020 +0200
+++ b/mercurial/patch.py	Mon Jul 06 15:31:53 2020 +0530
@@ -2922,6 +2922,18 @@
         yield f1, f2, copyop
 
 
+def _gitindex(text):
+    if not text:
+        text = b""
+    l = len(text)
+    s = hashutil.sha1(b'blob %d\0' % l)
+    s.update(text)
+    return hex(s.digest())
+
+
+_gitmode = {b'l': b'120000', b'x': b'100755', b'': b'100644'}
+
+
 def trydiff(
     repo,
     revs,
@@ -2944,14 +2956,6 @@
     pathfn is applied to every path in the diff output.
     '''
 
-    def gitindex(text):
-        if not text:
-            text = b""
-        l = len(text)
-        s = hashutil.sha1(b'blob %d\0' % l)
-        s.update(text)
-        return hex(s.digest())
-
     if opts.noprefix:
         aprefix = bprefix = b''
     else:
@@ -2968,8 +2972,6 @@
     date1 = dateutil.datestr(ctx1.date())
     date2 = dateutil.datestr(ctx2.date())
 
-    gitmode = {b'l': b'120000', b'x': b'100755', b'': b'100644'}
-
     if not pathfn:
         pathfn = lambda f: f
 
@@ -3023,11 +3025,11 @@
                 b'diff --git %s%s %s%s' % (aprefix, path1, bprefix, path2)
             )
             if not f1:  # added
-                header.append(b'new file mode %s' % gitmode[flag2])
+                header.append(b'new file mode %s' % _gitmode[flag2])
             elif not f2:  # removed
-                header.append(b'deleted file mode %s' % gitmode[flag1])
+                header.append(b'deleted file mode %s' % _gitmode[flag1])
             else:  # modified/copied/renamed
-                mode1, mode2 = gitmode[flag1], gitmode[flag2]
+                mode1, mode2 = _gitmode[flag1], _gitmode[flag2]
                 if mode1 != mode2:
                     header.append(b'old mode %s' % mode1)
                     header.append(b'new mode %s' % mode2)
@@ -3071,39 +3073,66 @@
             if fctx2 is not None:
                 content2 = fctx2.data()
 
-        if binary and opts.git and not opts.nobinary:
-            text = mdiff.b85diff(content1, content2)
-            if text:
-                header.append(
-                    b'index %s..%s' % (gitindex(content1), gitindex(content2))
+        data1 = (ctx1, fctx1, path1, flag1, content1, date1)
+        data2 = (ctx2, fctx2, path2, flag2, content2, date2)
+        yield diffcontent(data1, data2, header, binary, opts)
+
+
+def diffcontent(data1, data2, header, binary, opts):
+    """ diffs two versions of a file.
+
+    data1 and data2 are tuples containg:
+
+        * ctx: changeset for the file
+        * fctx: file context for that file
+        * path1: name of the file
+        * flag: flags of the file
+        * content: full content of the file (can be null in case of binary)
+        * date: date of the changeset
+
+    header: the patch header
+    binary: whether the any of the version of file is binary or not
+    opts:   user passed options
+
+    It exists as a separate function so that extensions like extdiff can wrap
+    it and use the file content directly.
+    """
+
+    ctx1, fctx1, path1, flag1, content1, date1 = data1
+    ctx2, fctx2, path2, flag2, content2, date2 = data2
+    if binary and opts.git and not opts.nobinary:
+        text = mdiff.b85diff(content1, content2)
+        if text:
+            header.append(
+                b'index %s..%s' % (_gitindex(content1), _gitindex(content2))
+            )
+        hunks = ((None, [text]),)
+    else:
+        if opts.git and opts.index > 0:
+            flag = flag1
+            if flag is None:
+                flag = flag2
+            header.append(
+                b'index %s..%s %s'
+                % (
+                    _gitindex(content1)[0 : opts.index],
+                    _gitindex(content2)[0 : opts.index],
+                    _gitmode[flag],
                 )
-            hunks = ((None, [text]),)
-        else:
-            if opts.git and opts.index > 0:
-                flag = flag1
-                if flag is None:
-                    flag = flag2
-                header.append(
-                    b'index %s..%s %s'
-                    % (
-                        gitindex(content1)[0 : opts.index],
-                        gitindex(content2)[0 : opts.index],
-                        gitmode[flag],
-                    )
-                )
-
-            uheaders, hunks = mdiff.unidiff(
-                content1,
-                date1,
-                content2,
-                date2,
-                path1,
-                path2,
-                binary=binary,
-                opts=opts,
             )
-            header.extend(uheaders)
-        yield fctx1, fctx2, header, hunks
+
+        uheaders, hunks = mdiff.unidiff(
+            content1,
+            date1,
+            content2,
+            date2,
+            path1,
+            path2,
+            binary=binary,
+            opts=opts,
+        )
+        header.extend(uheaders)
+    return fctx1, fctx2, header, hunks
 
 
 def diffstatsum(stats):