Mercurial > hg
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 |