D8685: patch: refactor content diffing part in separate fn so extensions can wrap
pulkit (Pulkit Goyal)
phabricator at mercurial-scm.org
Tue Jul 7 09:27:39 UTC 2020
pulkit created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.
REVISION SUMMARY
Right now extdiff uses it's own logic using archival to diff two versions of
file using external diff tools. This makes the extdiff functionality
non-extensible.
This series is an attempt to refactor core patch and diff functionality so that
extdiff can wrap and reuse it. This will help us in using external diffing tools
at more places and not just extdiff command only then.
REPOSITORY
rHG Mercurial
BRANCH
default
REVISION DETAIL
https://phab.mercurial-scm.org/D8685
AFFECTED FILES
mercurial/patch.py
CHANGE DETAILS
diff --git a/mercurial/patch.py b/mercurial/patch.py
--- a/mercurial/patch.py
+++ b/mercurial/patch.py
@@ -2918,6 +2918,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,
@@ -2940,14 +2952,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:
@@ -2964,8 +2968,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
@@ -3010,7 +3012,6 @@
(f1 and f2 and flag1 != flag2)
):
losedatafn(f2 or f1)
-
path1 = pathfn(f1 or f2)
path2 = pathfn(f2 or f1)
header = []
@@ -3019,11 +3020,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)
@@ -3067,39 +3068,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):
To: pulkit, #hg-reviewers
Cc: mercurial-patches, mercurial-devel
More information about the Mercurial-devel
mailing list