Re: [PATCH 3 of 4 v4] diff: pass a diff hunks filter function from changeset_printer to patch.diff()

2017-10-18 Thread Yuya Nishihara
On Tue, 17 Oct 2017 21:36:59 +0200, Denis Laxalde wrote:
> # HG changeset patch
> # User Denis Laxalde 
> # Date 1507293917 -7200
> #  Fri Oct 06 14:45:17 2017 +0200
> # Node ID 909a69f31ef323ded6fef8dd56fb44dc97f4cd89
> # Parent  c73893dd6cfb5693029f5d9dcf1d537197b40a4a
> # EXP-Topic followlines-cli
> diff: pass a diff hunks filter function from changeset_printer to patch.diff()

> diff --git a/mercurial/patch.py b/mercurial/patch.py
> --- a/mercurial/patch.py
> +++ b/mercurial/patch.py
> @@ -2296,7 +2296,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,
> + hunksfilterfn=None):
>  '''yields diff of changes to files between two nodes, or node and
>  working directory.
>  
> @@ -2318,12 +2319,18 @@ def diff(repo, node1=None, node2=None, m
>  patterns that fall outside it will be ignored.
>  
>  copy, if not empty, should contain mappings {dst@y: src@x} of copy
> -information.'''
> +information.
> +
> +hunksfilterfn, if not None, should be a function taking a filectx and
> +hunks generator that may yield filtered hunks.
> +'''
>  for fctx1, fctx2, hdr, hunks in diffhunks(
>  repo, node1=node1, node2=node2,
>  match=match, changes=changes, opts=opts,
>  losedatafn=losedatafn, prefix=prefix, relroot=relroot, copy=copy,
>  ):
> +if hunksfilterfn is not None:
> +hunks = hunksfilterfn(fctx2, hunks)

fctx2 may be None if the content is binary and (probably) f2 is a removed
file. I don't think that's the case now, but can you double check?
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 4 v4] diff: pass a diff hunks filter function from changeset_printer to patch.diff()

2017-10-17 Thread Denis Laxalde
# HG changeset patch
# User Denis Laxalde 
# Date 1507293917 -7200
#  Fri Oct 06 14:45:17 2017 +0200
# Node ID 909a69f31ef323ded6fef8dd56fb44dc97f4cd89
# Parent  c73893dd6cfb5693029f5d9dcf1d537197b40a4a
# EXP-Topic followlines-cli
diff: pass a diff hunks filter function from changeset_printer to patch.diff()

We add a 'hunksfilterfn' keyword argument in all functions of the call
stack from changeset_printer.show() to patch.diff(). This is a callable
that will be used to filter out hunks by line range and 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
@@ -1494,7 +1494,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, hunksfilterfn=None):
 '''show diff or diffstat.'''
 if fp is None:
 write = ui.write
@@ -1522,14 +1522,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,
+hunksfilterfn=hunksfilterfn)
 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,
+ hunksfilterfn=hunksfilterfn):
 write(chunk, label=label)
 
 if listsubrepos:
@@ -1591,16 +1593,17 @@ 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, hunksfilterfn=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, hunksfilterfn, props)
 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, hunksfilterfn, props)
+
+def _show(self, ctx, copies, matchfn, hunksfilterfn, props):
 '''show a single changeset or file revision'''
 changenode = ctx.node()
 rev = ctx.rev()
@@ -1711,13 +1714,13 @@ class changeset_printer(object):
   label='log.summary')
 self.ui.write("\n")
 
-self.showpatch(ctx, matchfn)
+self.showpatch(ctx, matchfn, hunksfilterfn=hunksfilterfn)
 
 def _exthook(self, ctx):
 '''empty method used by extension as a hook point
 '''
 
-def showpatch(self, ctx, matchfn):
+def showpatch(self, ctx, matchfn, hunksfilterfn=None):
 if not matchfn:
 matchfn = self.matchfn
 if matchfn:
@@ -1728,12 +1731,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,
+   hunksfilterfn=hunksfilterfn)
 if diff:
 if stat:
 self.ui.write("\n")
 diffordiffstat(self.ui, self.repo, diffopts, prev, node,
-   match=matchfn, stat=False)
+   match=matchfn, stat=False,
+   hunksfilterfn=hunksfilterfn)
 self.ui.write("\n")
 
 class jsonchangeset(changeset_printer):
@@ -1750,7 +1755,7 @@ class jsonchangeset(changeset_printer):
 else:
 self.ui.write("[]\n")
 
-def _show(self, ctx, copies, matchfn, props):
+def _show(self, ctx, copies, matchfn, hunksfilterfn, props):
 '''show a single changeset or file revision'''
 rev = ctx.rev()
 if rev is None:
@@ -1884,7 +1889,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,