Patchwork [2,of,2,V2,relative-diff] patch.diff: add support for diffs relative to a subdirectory

login
register
mail settings
Submitter Siddharth Agarwal
Date March 23, 2015, 2:51 a.m.
Message ID <3b461162cb2541bb4c78.1427079118@devbig136.prn2.facebook.com>
Download mbox | patch
Permalink /patch/8220/
State Accepted
Commit f2e1e097cda166319350ef39928e2efab033b623
Headers show

Comments

Siddharth Agarwal - March 23, 2015, 2:51 a.m.
# HG changeset patch
# User Siddharth Agarwal <sid0@fb.com>
# Date 1426624884 25200
#      Tue Mar 17 13:41:24 2015 -0700
# Node ID 3b461162cb2541bb4c7856ac206a8ad6ab828789
# Parent  65f80a79101b818b3685121f7cfe3b29a8501494
patch.diff: add support for diffs relative to a subdirectory

For now this implementation is pretty naive -- it filters out files right
before passing them into trydiff. In upcoming patches we'll add some more
smarts.
Matt Mackall - March 23, 2015, 7:44 p.m.
On Sun, 2015-03-22 at 19:51 -0700, Siddharth Agarwal wrote:
> # HG changeset patch
> # User Siddharth Agarwal <sid0@fb.com>
> # Date 1426624884 25200
> #      Tue Mar 17 13:41:24 2015 -0700
> # Node ID 3b461162cb2541bb4c7856ac206a8ad6ab828789
> # Parent  65f80a79101b818b3685121f7cfe3b29a8501494
> patch.diff: add support for diffs relative to a subdirectory

These are queued for default, thanks.

Patch

diff --git a/mercurial/patch.py b/mercurial/patch.py
--- a/mercurial/patch.py
+++ b/mercurial/patch.py
@@ -2059,7 +2059,7 @@ 
     return mdiff.diffopts(**buildopts)
 
 def diff(repo, node1=None, node2=None, match=None, changes=None, opts=None,
-         losedatafn=None, prefix=''):
+         losedatafn=None, prefix='', relroot=''):
     '''yields diff of changes to files between two nodes, or node and
     working directory.
 
@@ -2076,7 +2076,9 @@ 
 
     prefix is a filename prefix that is prepended to all filenames on
     display (used for subrepos).
-    '''
+
+    relroot, if not empty, must be normalized with a trailing /. Any match
+    patterns that fall outside it will be ignored.'''
 
     if opts is None:
         opts = mdiff.defaultopts
@@ -2120,9 +2122,23 @@ 
     if opts.git or opts.upgrade:
         copy = copies.pathcopies(ctx1, ctx2)
 
+    if relroot is not None:
+        # XXX this would ideally be done in the matcher, but that is generally
+        # meant to 'or' patterns, not 'and' them. In this case we need to 'and'
+        # all the patterns from the matcher with relroot.
+        def filterrel(l):
+            return [f for f in l if f.startswith(relroot)]
+        modified = filterrel(modified)
+        added = filterrel(added)
+        removed = filterrel(removed)
+        # filter out copies where either side isn't inside the relative root
+        copy = dict(((dst, src) for (dst, src) in copy.iteritems()
+                     if dst.startswith(relroot)
+                     and src.startswith(relroot)))
+
     def difffn(opts, losedata):
         return trydiff(repo, revs, ctx1, ctx2, modified, added, removed,
-                       copy, getfilectx, opts, losedata, prefix, '')
+                       copy, getfilectx, opts, losedata, prefix, relroot)
     if opts.upgrade and not opts.git:
         try:
             def losedata(fn):