D5893: patch: accept second matcher that applies only to copy sources (API)

martinvonz (Martin von Zweigbergk) phabricator at mercurial-scm.org
Fri Feb 8 08:31:03 UTC 2019


martinvonz created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  See previous patch for motivation.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D5893

AFFECTED FILES
  mercurial/context.py
  mercurial/logcmdutil.py
  mercurial/patch.py

CHANGE DETAILS

diff --git a/mercurial/patch.py b/mercurial/patch.py
--- a/mercurial/patch.py
+++ b/mercurial/patch.py
@@ -2240,7 +2240,7 @@
 
 def diff(repo, node1=None, node2=None, match=None, changes=None,
          opts=None, losedatafn=None, prefix='', relroot='', copy=None,
-         hunksfilterfn=None):
+         copysourcematch=None, hunksfilterfn=None):
     '''yields diff of changes to files between two nodes, or node and
     working directory.
 
@@ -2264,6 +2264,9 @@
     copy, if not empty, should contain mappings {dst at y: src at x} of copy
     information.
 
+    if copysourcematch is not None, then copy sources will be filtered by this
+    matcher
+
     hunksfilterfn, if not None, should be a function taking a filectx and
     hunks generator that may yield filtered hunks.
     '''
@@ -2277,7 +2280,7 @@
             repo, ctx1=ctx1, ctx2=ctx2,
             match=match, changes=changes, opts=opts,
             losedatafn=losedatafn, prefix=prefix, relroot=relroot, copy=copy,
-    ):
+            copysourcematch=copysourcematch):
         if hunksfilterfn is not None:
             # If the file has been removed, fctx2 is None; but this should
             # not occur here since we catch removed files early in
@@ -2292,7 +2295,8 @@
             yield text
 
 def diffhunks(repo, ctx1, ctx2, match=None, changes=None,
-              opts=None, losedatafn=None, prefix='', relroot='', copy=None):
+              opts=None, losedatafn=None, prefix='', relroot='', copy=None,
+              copysourcematch=None):
     """Yield diff of changes to files in the form of (`header`, `hunks`) tuples
     where `header` is a list of diff headers and `hunks` is an iterable of
     (`hunkrange`, `hunklines`) tuples.
@@ -2337,11 +2341,11 @@
         if opts.git or opts.upgrade:
             copy = copies.pathcopies(ctx1, ctx2, match=match)
 
-    if relroot:
-        # filter out copies where source side isn't inside the relative root
+    if copysourcematch:
+        # filter out copies where source side isn't inside the matcher
         # (copies.pathcopies() already filtered out the destination)
         copy = {dst: src for dst, src in copy.iteritems()
-                if src.startswith(relroot)}
+                if copysourcematch(src)}
 
     modifiedset = set(modified)
     addedset = set(added)
diff --git a/mercurial/logcmdutil.py b/mercurial/logcmdutil.py
--- a/mercurial/logcmdutil.py
+++ b/mercurial/logcmdutil.py
@@ -64,6 +64,7 @@
         relroot = pathutil.canonpath(repo.root, repo.getcwd(), root)
     else:
         relroot = ''
+    copysourcematch = None
     if relroot != '':
         # XXX relative roots currently don't work if the root is within a
         # subrepo
@@ -76,15 +77,17 @@
 
         relrootmatch = scmutil.match(ctx2, pats=[relroot], default='path')
         match = matchmod.intersectmatchers(match, relrootmatch)
+        copysourcematch = relrootmatch
 
     if stat:
         diffopts = diffopts.copy(context=0, noprefix=False)
         width = 80
         if not ui.plain():
             width = ui.termwidth() - graphwidth
 
     chunks = ctx2.diff(ctx1, match, changes, opts=diffopts, prefix=prefix,
-                       relroot=relroot, hunksfilterfn=hunksfilterfn)
+                       relroot=relroot, copysourcematch=copysourcematch,
+                       hunksfilterfn=hunksfilterfn)
 
     if fp is not None or ui.canwritewithoutlabels():
         out = fp or ui
diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -295,15 +295,16 @@
 
     def diff(self, ctx2=None, match=None, changes=None, opts=None,
              losedatafn=None, prefix='', relroot='', copy=None,
-             hunksfilterfn=None):
+             copysourcematch=None, hunksfilterfn=None):
         """Returns a diff generator for the given contexts and matcher"""
         if ctx2 is None:
             ctx2 = self.p1()
         if ctx2 is not None:
             ctx2 = self._repo[ctx2]
         return patch.diff(self._repo, ctx2, self, match=match, changes=changes,
                           opts=opts, losedatafn=losedatafn, prefix=prefix,
                           relroot=relroot, copy=copy,
+                          copysourcematch=copysourcematch,
                           hunksfilterfn=hunksfilterfn)
 
     def dirs(self):



To: martinvonz, #hg-reviewers
Cc: mercurial-devel


More information about the Mercurial-devel mailing list