[PATCH 2 of 4] diff: pass down line range information from changeset_printer to patch.diff()
Denis Laxalde
denis at laxalde.org
Wed Oct 4 11:04:00 EDT 2017
# HG changeset patch
# User Denis Laxalde <denis.laxalde at logilab.fr>
# Date 1507127862 -7200
# Wed Oct 04 16:37:42 2017 +0200
# Node ID f7b31d85dc0e7c7e60b85d0a7fd728a32ba210ea
# Parent 3d8ed7dafee4676b49922a3dde0edf1b1fad63ec
# Available At http://hg.logilab.org/users/dlaxalde/hg
# hg pull http://hg.logilab.org/users/dlaxalde/hg -r f7b31d85dc0e
# EXP-Topic followlines-cli
diff: pass down line range information from changeset_printer to patch.diff()
We add a 'lineranges' keyword argument in all functions of the call stack from
changeset_printer.show() to patch.diff(). This is a mapping from filename to
a list of line range tuples is used in patch.diff() to eliminate hunks not in
specified line range. This will be used in the "-L/--line-range" option of "hg
log" command introduced in the following changesets.
diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -1513,7 +1513,7 @@ def export(repo, revs, fntemplate='hg-%h
def diffordiffstat(ui, repo, diffopts, node1, node2, match,
changes=None, stat=False, fp=None, prefix='',
- root='', listsubrepos=False):
+ root='', listsubrepos=False, lineranges=None):
'''show diff or diffstat.'''
if fp is None:
write = ui.write
@@ -1541,14 +1541,16 @@ def diffordiffstat(ui, repo, diffopts, n
if not ui.plain():
width = ui.termwidth()
chunks = patch.diff(repo, node1, node2, match, changes, diffopts,
- prefix=prefix, relroot=relroot)
+ prefix=prefix, relroot=relroot,
+ lineranges=lineranges)
for chunk, label in patch.diffstatui(util.iterlines(chunks),
width=width):
write(chunk, label=label)
else:
for chunk, label in patch.diffui(repo, node1, node2, match,
changes, diffopts, prefix=prefix,
- relroot=relroot):
+ relroot=relroot,
+ lineranges=lineranges):
write(chunk, label=label)
if listsubrepos:
@@ -1610,16 +1612,16 @@ class changeset_printer(object):
if self.footer:
self.ui.write(self.footer)
- def show(self, ctx, copies=None, matchfn=None, **props):
+ def show(self, ctx, copies=None, matchfn=None, lineranges=None, **props):
props = pycompat.byteskwargs(props)
if self.buffered:
self.ui.pushbuffer(labeled=True)
- self._show(ctx, copies, matchfn, props)
+ self._show(ctx, copies, matchfn, props, lineranges)
self.hunk[ctx.rev()] = self.ui.popbuffer()
else:
- self._show(ctx, copies, matchfn, props)
-
- def _show(self, ctx, copies, matchfn, props):
+ self._show(ctx, copies, matchfn, props, lineranges)
+
+ def _show(self, ctx, copies, matchfn, props, lineranges):
'''show a single changeset or file revision'''
changenode = ctx.node()
rev = ctx.rev()
@@ -1730,13 +1732,13 @@ class changeset_printer(object):
label='log.summary')
self.ui.write("\n")
- self.showpatch(ctx, matchfn)
+ self.showpatch(ctx, matchfn, lineranges=lineranges)
def _exthook(self, ctx):
'''empty method used by extension as a hook point
'''
- def showpatch(self, ctx, matchfn):
+ def showpatch(self, ctx, matchfn, lineranges=None):
if not matchfn:
matchfn = self.matchfn
if matchfn:
@@ -1747,12 +1749,14 @@ class changeset_printer(object):
prev = ctx.p1().node()
if stat:
diffordiffstat(self.ui, self.repo, diffopts, prev, node,
- match=matchfn, stat=True)
+ match=matchfn, stat=True,
+ lineranges=lineranges)
if diff:
if stat:
self.ui.write("\n")
diffordiffstat(self.ui, self.repo, diffopts, prev, node,
- match=matchfn, stat=False)
+ match=matchfn, stat=False,
+ lineranges=lineranges)
self.ui.write("\n")
class jsonchangeset(changeset_printer):
@@ -1769,7 +1773,7 @@ class jsonchangeset(changeset_printer):
else:
self.ui.write("[]\n")
- def _show(self, ctx, copies, matchfn, props):
+ def _show(self, ctx, copies, matchfn, props, lineranges):
'''show a single changeset or file revision'''
rev = ctx.rev()
if rev is None:
@@ -1843,13 +1847,15 @@ class jsonchangeset(changeset_printer):
if stat:
self.ui.pushbuffer()
diffordiffstat(self.ui, self.repo, diffopts, prev, node,
- match=matchfn, stat=True)
+ match=matchfn, stat=True,
+ lineranges=lineranges)
self.ui.write((',\n "diffstat": "%s"')
% j(self.ui.popbuffer()))
if diff:
self.ui.pushbuffer()
diffordiffstat(self.ui, self.repo, diffopts, prev, node,
- match=matchfn, stat=False)
+ match=matchfn, stat=False,
+ lineranges=lineranges)
self.ui.write((',\n "diff": "%s"') % j(self.ui.popbuffer()))
self.ui.write("\n }")
@@ -1903,7 +1909,7 @@ class changeset_templater(changeset_prin
self.footer += templater.stringify(self.t(self._parts['docfooter']))
return super(changeset_templater, self).close()
- def _show(self, ctx, copies, matchfn, props):
+ def _show(self, ctx, copies, matchfn, props, lineranges):
'''show a single changeset or file revision'''
props = props.copy()
props.update(templatekw.keywords)
@@ -1935,7 +1941,7 @@ class changeset_templater(changeset_prin
# write changeset metadata, then patch if requested
key = self._parts[self._tref]
self.ui.write(templater.stringify(self.t(key, **props)))
- self.showpatch(ctx, matchfn)
+ self.showpatch(ctx, matchfn, lineranges=lineranges)
if self._parts['footer']:
if not self.footer:
diff --git a/mercurial/patch.py b/mercurial/patch.py
--- a/mercurial/patch.py
+++ b/mercurial/patch.py
@@ -2293,7 +2293,8 @@ def difffeatureopts(ui, opts=None, untru
return mdiff.diffopts(**pycompat.strkwargs(buildopts))
def diff(repo, node1=None, node2=None, match=None, changes=None,
- opts=None, losedatafn=None, prefix='', relroot='', copy=None):
+ opts=None, losedatafn=None, prefix='', relroot='', copy=None,
+ lineranges=None):
'''yields diff of changes to files between two nodes, or node and
working directory.
@@ -2315,11 +2316,23 @@ def diff(repo, node1=None, node2=None, m
patterns that fall outside it will be ignored.
copy, if not empty, should contain mappings {dst at y: src at x} of copy
- information.'''
+ information.
+
+ lineranges, if not None, must be a mapping from filename to line range
+ tuples and is used to filter diff hunks not in specified range.
+ '''
for hdr, hunks in diffhunks(repo, node1=node1, node2=node2, match=match,
changes=changes, opts=opts,
losedatafn=losedatafn, prefix=prefix,
relroot=relroot, copy=copy):
+ if lineranges is not None and hdr:
+ fname = header(hdr).filename()
+ flineranges = lineranges.get(fname)
+ if flineranges is not None:
+ hunks = (
+ (hr, lines) for hr, lines in hunks
+ if any(mdiff.hunkinrange(hr[2:], lr) for lr in flineranges)
+ )
text = ''.join(sum((list(hlines) for hrange, hlines in hunks), []))
if hdr and (text or len(hdr) > 1):
yield '\n'.join(hdr) + '\n'
More information about the Mercurial-devel
mailing list