diff: add a fast path to avoid loading binary contents
authorJun Wu <quark@fb.com>
Wed, 03 May 2017 23:50:41 -0700
changeset 32191 31f42e683321
parent 32190 0c67ab3d77d5
child 32192 76f938ec68a5
diff: add a fast path to avoid loading binary contents When diffing binary contents, with certain configs, we can show "Binary file <name> has changed" without actual content. That allows a fast path where we could avoid providing actual binary contents. Note: in that case we still need to test if two contents are the same, that's done by using "filectx.cmp", which could have its own fast path.
mercurial/patch.py
--- a/mercurial/patch.py	Fri May 05 17:20:32 2017 -0700
+++ b/mercurial/patch.py	Wed May 03 23:50:41 2017 -0700
@@ -2532,12 +2532,10 @@
         flag2 = None
         if f1:
             fctx1 = getfilectx(f1, ctx1)
-            content1 = fctx1.data()
             if opts.git or losedatafn:
                 flag1 = ctx1.flags(f1)
         if f2:
             fctx2 = getfilectx(f2, ctx2)
-            content2 = fctx2.data()
             if opts.git or losedatafn:
                 flag2 = ctx2.flags(f2)
         # if binary is True, output "summary" or "base85", but not "text diff"
@@ -2595,6 +2593,25 @@
         #  yes      | yes  *        *   *     | text diff | yes
         #  no       | *    *        *   *     | text diff | yes
         # [1]: hash(fctx.data()) is outputted. so fctx.data() cannot be faked
+        if binary and (not opts.git or (opts.git and opts.nobinary and not
+                                        opts.index)):
+            # fast path: no binary content will be displayed, content1 and
+            # content2 are only used for equivalent test. cmp() could have a
+            # fast path.
+            if fctx1 is not None:
+                content1 = b'\0'
+            if fctx2 is not None:
+                if fctx1 is not None and not fctx1.cmp(fctx2):
+                    content2 = b'\0' # not different
+                else:
+                    content2 = b'\0\0'
+        else:
+            # normal path: load contents
+            if fctx1 is not None:
+                content1 = fctx1.data()
+            if fctx2 is not None:
+                content2 = fctx2.data()
+
         if binary and opts.git and not opts.nobinary:
             text = mdiff.b85diff(content1, content2)
             if text: