patch: avoid repeated binary checks if all files in a patch are text
Differential Revision: https://phab.mercurial-scm.org/D1940
--- a/mercurial/mdiff.py Thu Feb 01 10:29:24 2018 -0800
+++ b/mercurial/mdiff.py Thu Jan 25 22:40:19 2018 +0100
@@ -234,13 +234,16 @@
yield s, type
yield s1, '='
-def unidiff(a, ad, b, bd, fn1, fn2, opts=defaultopts):
+def unidiff(a, ad, b, bd, fn1, fn2, opts=defaultopts, check_binary=True):
"""Return a unified diff as a (headers, hunks) tuple.
If the diff is not null, `headers` is a list with unified diff header
lines "--- <original>" and "+++ <new>" and `hunks` is a generator yielding
(hunkrange, hunklines) coming from _unidiff().
Otherwise, `headers` and `hunks` are empty.
+
+ Setting `check_binary` to false will skip the binary check, i.e. when
+ it has been done in advance. Files are expected to be text in this case.
"""
def datetag(date, fn=None):
if not opts.git and not opts.nodates:
@@ -270,7 +273,7 @@
text += "\n\ No newline at end of file\n"
yield text
- if not opts.text and (util.binary(a) or util.binary(b)):
+ if not opts.text and check_binary and (util.binary(a) or util.binary(b)):
if a and b and len(a) == len(b) and a == b:
return sentinel
headerlines = []
--- a/mercurial/patch.py Thu Feb 01 10:29:24 2018 -0800
+++ b/mercurial/patch.py Thu Jan 25 22:40:19 2018 +0100
@@ -2698,8 +2698,13 @@
if opts.git or losedatafn:
flag2 = ctx2.flags(f2)
# if binary is True, output "summary" or "base85", but not "text diff"
- binary = not opts.text and any(f.isbinary()
- for f in [fctx1, fctx2] if f is not None)
+ if opts.text:
+ check_binary = True
+ binary = False
+ else:
+ check_binary = any(f.isbinary()
+ for f in [fctx1, fctx2] if f is not None)
+ binary = check_binary
if losedatafn and not opts.git:
if (binary or
@@ -2789,7 +2794,8 @@
uheaders, hunks = mdiff.unidiff(content1, date1,
content2, date2,
- path1, path2, opts=opts)
+ path1, path2, opts=opts,
+ check_binary=check_binary)
header.extend(uheaders)
yield fctx1, fctx2, header, hunks