comparison mercurial/patch.py @ 24417:f2e1e097cda1

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.
author Siddharth Agarwal <sid0@fb.com>
date Tue, 17 Mar 2015 13:41:24 -0700
parents f07047a506d1
children f5f4dc115fb2
comparison
equal deleted inserted replaced
24416:f07047a506d1 24417:f2e1e097cda1
2057 buildopts['noprefix'] = get('noprefix', forceplain=False) 2057 buildopts['noprefix'] = get('noprefix', forceplain=False)
2058 2058
2059 return mdiff.diffopts(**buildopts) 2059 return mdiff.diffopts(**buildopts)
2060 2060
2061 def diff(repo, node1=None, node2=None, match=None, changes=None, opts=None, 2061 def diff(repo, node1=None, node2=None, match=None, changes=None, opts=None,
2062 losedatafn=None, prefix=''): 2062 losedatafn=None, prefix='', relroot=''):
2063 '''yields diff of changes to files between two nodes, or node and 2063 '''yields diff of changes to files between two nodes, or node and
2064 working directory. 2064 working directory.
2065 2065
2066 if node1 is None, use first dirstate parent instead. 2066 if node1 is None, use first dirstate parent instead.
2067 if node2 is None, compare node1 with working directory. 2067 if node2 is None, compare node1 with working directory.
2074 to None, patches will always be upgraded to git format when 2074 to None, patches will always be upgraded to git format when
2075 necessary. 2075 necessary.
2076 2076
2077 prefix is a filename prefix that is prepended to all filenames on 2077 prefix is a filename prefix that is prepended to all filenames on
2078 display (used for subrepos). 2078 display (used for subrepos).
2079 ''' 2079
2080 relroot, if not empty, must be normalized with a trailing /. Any match
2081 patterns that fall outside it will be ignored.'''
2080 2082
2081 if opts is None: 2083 if opts is None:
2082 opts = mdiff.defaultopts 2084 opts = mdiff.defaultopts
2083 2085
2084 if not node1 and not node2: 2086 if not node1 and not node2:
2118 2120
2119 copy = {} 2121 copy = {}
2120 if opts.git or opts.upgrade: 2122 if opts.git or opts.upgrade:
2121 copy = copies.pathcopies(ctx1, ctx2) 2123 copy = copies.pathcopies(ctx1, ctx2)
2122 2124
2125 if relroot is not None:
2126 # XXX this would ideally be done in the matcher, but that is generally
2127 # meant to 'or' patterns, not 'and' them. In this case we need to 'and'
2128 # all the patterns from the matcher with relroot.
2129 def filterrel(l):
2130 return [f for f in l if f.startswith(relroot)]
2131 modified = filterrel(modified)
2132 added = filterrel(added)
2133 removed = filterrel(removed)
2134 # filter out copies where either side isn't inside the relative root
2135 copy = dict(((dst, src) for (dst, src) in copy.iteritems()
2136 if dst.startswith(relroot)
2137 and src.startswith(relroot)))
2138
2123 def difffn(opts, losedata): 2139 def difffn(opts, losedata):
2124 return trydiff(repo, revs, ctx1, ctx2, modified, added, removed, 2140 return trydiff(repo, revs, ctx1, ctx2, modified, added, removed,
2125 copy, getfilectx, opts, losedata, prefix, '') 2141 copy, getfilectx, opts, losedata, prefix, relroot)
2126 if opts.upgrade and not opts.git: 2142 if opts.upgrade and not opts.git:
2127 try: 2143 try:
2128 def losedata(fn): 2144 def losedata(fn):
2129 if not losedatafn or not losedatafn(fn=fn): 2145 if not losedatafn or not losedatafn(fn=fn):
2130 raise GitDiffRequired 2146 raise GitDiffRequired