Read about our upcoming Code of Conduct on this issue

Commit 02d641d3 authored by Pulkit Goyal's avatar Pulkit Goyal
Browse files

patch: refactor content diffing part in separate fn so extensions can wrap

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.

Differential Revision: https://phab.mercurial-scm.org/D8685
parent dff208398ede
......@@ -2922,6 +2922,18 @@ def _filepairs(modified, added, removed, copy, opts):
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 @@ def trydiff(
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 @@ def trydiff(
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 @@ def trydiff(
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 @@ def trydiff(
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))
)
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],
)
)
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.
uheaders, hunks = mdiff.unidiff(
content1,
date1,
content2,
date2,
path1,
path2,
binary=binary,
opts=opts,
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))
)
header.extend(uheaders)
yield fctx1, fctx2, header, hunks
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)
return fctx1, fctx2, header, hunks
def diffstatsum(stats):
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment