comparison mercurial/patch.py @ 24433:f5f4dc115fb2

patch.diff: restrict matcher to relative root in certain cases Previously we'd request all results, then filter by relative root. This is clearly inefficient, so we now restrict the matcher to the relative root for certain easy cases. The particular case here is when the matcher matches all files. In that case we can simply create a matcher by the relative root. This is purely an optimization and has no impact on correctness.
author Siddharth Agarwal <sid0@fb.com>
date Tue, 17 Mar 2015 15:46:36 -0700
parents f2e1e097cda1
children a7f8e3584ef3
comparison
equal deleted inserted replaced
24432:e22248f6d257 24433:f5f4dc115fb2
2103 getfilectx = lrugetfilectx() 2103 getfilectx = lrugetfilectx()
2104 2104
2105 ctx1 = repo[node1] 2105 ctx1 = repo[node1]
2106 ctx2 = repo[node2] 2106 ctx2 = repo[node2]
2107 2107
2108 relfiltered = False
2109 if relroot != '' and match.always():
2110 # as a special case, create a new matcher with just the relroot
2111 pats = [relroot]
2112 match = scmutil.match(ctx2, pats, default='path')
2113 relfiltered = True
2114
2108 if not changes: 2115 if not changes:
2109 changes = repo.status(ctx1, ctx2, match=match) 2116 changes = repo.status(ctx1, ctx2, match=match)
2110 modified, added, removed = changes[:3] 2117 modified, added, removed = changes[:3]
2111 2118
2112 if not modified and not added and not removed: 2119 if not modified and not added and not removed:
2121 copy = {} 2128 copy = {}
2122 if opts.git or opts.upgrade: 2129 if opts.git or opts.upgrade:
2123 copy = copies.pathcopies(ctx1, ctx2) 2130 copy = copies.pathcopies(ctx1, ctx2)
2124 2131
2125 if relroot is not None: 2132 if relroot is not None:
2126 # XXX this would ideally be done in the matcher, but that is generally 2133 if not relfiltered:
2127 # meant to 'or' patterns, not 'and' them. In this case we need to 'and' 2134 # XXX this would ideally be done in the matcher, but that is
2128 # all the patterns from the matcher with relroot. 2135 # generally meant to 'or' patterns, not 'and' them. In this case we
2129 def filterrel(l): 2136 # need to 'and' all the patterns from the matcher with relroot.
2130 return [f for f in l if f.startswith(relroot)] 2137 def filterrel(l):
2131 modified = filterrel(modified) 2138 return [f for f in l if f.startswith(relroot)]
2132 added = filterrel(added) 2139 modified = filterrel(modified)
2133 removed = filterrel(removed) 2140 added = filterrel(added)
2141 removed = filterrel(removed)
2142 relfiltered = True
2134 # filter out copies where either side isn't inside the relative root 2143 # filter out copies where either side isn't inside the relative root
2135 copy = dict(((dst, src) for (dst, src) in copy.iteritems() 2144 copy = dict(((dst, src) for (dst, src) in copy.iteritems()
2136 if dst.startswith(relroot) 2145 if dst.startswith(relroot)
2137 and src.startswith(relroot))) 2146 and src.startswith(relroot)))
2138 2147