comparison mercurial/patch.py @ 41631:74f53d3bd685

patch: accept second matcher that applies only to copy sources (API) See previous patch for motivation. Differential Revision: https://phab.mercurial-scm.org/D5893
author Martin von Zweigbergk <martinvonz@google.com>
date Wed, 06 Feb 2019 22:52:49 -0800
parents 035cae1d197f
children 3751595ec45e
comparison
equal deleted inserted replaced
41630:035cae1d197f 41631:74f53d3bd685
2238 diffallopts = diffutil.diffallopts 2238 diffallopts = diffutil.diffallopts
2239 difffeatureopts = diffutil.difffeatureopts 2239 difffeatureopts = diffutil.difffeatureopts
2240 2240
2241 def diff(repo, node1=None, node2=None, match=None, changes=None, 2241 def diff(repo, node1=None, node2=None, match=None, changes=None,
2242 opts=None, losedatafn=None, prefix='', relroot='', copy=None, 2242 opts=None, losedatafn=None, prefix='', relroot='', copy=None,
2243 hunksfilterfn=None): 2243 copysourcematch=None, hunksfilterfn=None):
2244 '''yields diff of changes to files between two nodes, or node and 2244 '''yields diff of changes to files between two nodes, or node and
2245 working directory. 2245 working directory.
2246 2246
2247 if node1 is None, use first dirstate parent instead. 2247 if node1 is None, use first dirstate parent instead.
2248 if node2 is None, compare node1 with working directory. 2248 if node2 is None, compare node1 with working directory.
2262 patterns that fall outside it will be ignored. 2262 patterns that fall outside it will be ignored.
2263 2263
2264 copy, if not empty, should contain mappings {dst@y: src@x} of copy 2264 copy, if not empty, should contain mappings {dst@y: src@x} of copy
2265 information. 2265 information.
2266 2266
2267 if copysourcematch is not None, then copy sources will be filtered by this
2268 matcher
2269
2267 hunksfilterfn, if not None, should be a function taking a filectx and 2270 hunksfilterfn, if not None, should be a function taking a filectx and
2268 hunks generator that may yield filtered hunks. 2271 hunks generator that may yield filtered hunks.
2269 ''' 2272 '''
2270 if not node1 and not node2: 2273 if not node1 and not node2:
2271 node1 = repo.dirstate.p1() 2274 node1 = repo.dirstate.p1()
2275 2278
2276 for fctx1, fctx2, hdr, hunks in diffhunks( 2279 for fctx1, fctx2, hdr, hunks in diffhunks(
2277 repo, ctx1=ctx1, ctx2=ctx2, 2280 repo, ctx1=ctx1, ctx2=ctx2,
2278 match=match, changes=changes, opts=opts, 2281 match=match, changes=changes, opts=opts,
2279 losedatafn=losedatafn, prefix=prefix, relroot=relroot, copy=copy, 2282 losedatafn=losedatafn, prefix=prefix, relroot=relroot, copy=copy,
2280 ): 2283 copysourcematch=copysourcematch):
2281 if hunksfilterfn is not None: 2284 if hunksfilterfn is not None:
2282 # If the file has been removed, fctx2 is None; but this should 2285 # If the file has been removed, fctx2 is None; but this should
2283 # not occur here since we catch removed files early in 2286 # not occur here since we catch removed files early in
2284 # logcmdutil.getlinerangerevs() for 'hg log -L'. 2287 # logcmdutil.getlinerangerevs() for 'hg log -L'.
2285 assert fctx2 is not None, \ 2288 assert fctx2 is not None, \
2290 yield '\n'.join(hdr) + '\n' 2293 yield '\n'.join(hdr) + '\n'
2291 if text: 2294 if text:
2292 yield text 2295 yield text
2293 2296
2294 def diffhunks(repo, ctx1, ctx2, match=None, changes=None, 2297 def diffhunks(repo, ctx1, ctx2, match=None, changes=None,
2295 opts=None, losedatafn=None, prefix='', relroot='', copy=None): 2298 opts=None, losedatafn=None, prefix='', relroot='', copy=None,
2299 copysourcematch=None):
2296 """Yield diff of changes to files in the form of (`header`, `hunks`) tuples 2300 """Yield diff of changes to files in the form of (`header`, `hunks`) tuples
2297 where `header` is a list of diff headers and `hunks` is an iterable of 2301 where `header` is a list of diff headers and `hunks` is an iterable of
2298 (`hunkrange`, `hunklines`) tuples. 2302 (`hunkrange`, `hunklines`) tuples.
2299 2303
2300 See diff() for the meaning of parameters. 2304 See diff() for the meaning of parameters.
2335 if copy is None: 2339 if copy is None:
2336 copy = {} 2340 copy = {}
2337 if opts.git or opts.upgrade: 2341 if opts.git or opts.upgrade:
2338 copy = copies.pathcopies(ctx1, ctx2, match=match) 2342 copy = copies.pathcopies(ctx1, ctx2, match=match)
2339 2343
2340 if relroot: 2344 if copysourcematch:
2341 # filter out copies where source side isn't inside the relative root 2345 # filter out copies where source side isn't inside the matcher
2342 # (copies.pathcopies() already filtered out the destination) 2346 # (copies.pathcopies() already filtered out the destination)
2343 copy = {dst: src for dst, src in copy.iteritems() 2347 copy = {dst: src for dst, src in copy.iteritems()
2344 if src.startswith(relroot)} 2348 if copysourcematch(src)}
2345 2349
2346 modifiedset = set(modified) 2350 modifiedset = set(modified)
2347 addedset = set(added) 2351 addedset = set(added)
2348 removedset = set(removed) 2352 removedset = set(removed)
2349 for f in modified: 2353 for f in modified: