Mercurial > public > mercurial-scm > hg
comparison mercurial/revset.py @ 12786:9aae04f4fcf6
revset: disable subset optimization for parents() and children() (issue2437)
For the boolean operators, the subset optimization works by calculating
the cheaper argument first, and passing the subset to the second
argument to restrict the revision domain. This works well for filtering
predicates.
But parents() don't work like a filter: it may return revisions outside the
specified set. So, combining it with boolean operators may easily yield
incorrect results. For instance, for the following revision graph:
0 -- 1
the expression '0 and parents(1)' should evaluate as follows:
0 and parents(1) ->
0 and 0 ->
0
But since [0] is passed to parents() as a subset, we get instead:
0 and parents(1 and 0) ->
0 and parents([]) ->
0 and [] ->
[]
This also affects children(), p1() and p2(), for the same reasons.
Predicates that call these (like heads()) are also affected.
We work around this issue by ignoring the subset when propagating
the call inside those predicates.
author | Wagner Bruna <wbruna@yahoo.com> |
---|---|
date | Fri, 15 Oct 2010 03:30:38 -0300 |
parents | 7e14e67e6622 |
children | 079a618ea89d |
comparison
equal
deleted
inserted
replaced
12785:c7d23b4ca4ba | 12786:9aae04f4fcf6 |
---|---|
191 return [r for r in subset if r == l] | 191 return [r for r in subset if r == l] |
192 | 192 |
193 def p1(repo, subset, x): | 193 def p1(repo, subset, x): |
194 ps = set() | 194 ps = set() |
195 cl = repo.changelog | 195 cl = repo.changelog |
196 for r in getset(repo, subset, x): | 196 for r in getset(repo, range(len(repo)), x): |
197 ps.add(cl.parentrevs(r)[0]) | 197 ps.add(cl.parentrevs(r)[0]) |
198 return [r for r in subset if r in ps] | 198 return [r for r in subset if r in ps] |
199 | 199 |
200 def p2(repo, subset, x): | 200 def p2(repo, subset, x): |
201 ps = set() | 201 ps = set() |
202 cl = repo.changelog | 202 cl = repo.changelog |
203 for r in getset(repo, subset, x): | 203 for r in getset(repo, range(len(repo)), x): |
204 ps.add(cl.parentrevs(r)[1]) | 204 ps.add(cl.parentrevs(r)[1]) |
205 return [r for r in subset if r in ps] | 205 return [r for r in subset if r in ps] |
206 | 206 |
207 def parents(repo, subset, x): | 207 def parents(repo, subset, x): |
208 ps = set() | 208 ps = set() |
209 cl = repo.changelog | 209 cl = repo.changelog |
210 for r in getset(repo, subset, x): | 210 for r in getset(repo, range(len(repo)), x): |
211 ps.update(cl.parentrevs(r)) | 211 ps.update(cl.parentrevs(r)) |
212 return [r for r in subset if r in ps] | 212 return [r for r in subset if r in ps] |
213 | 213 |
214 def maxrev(repo, subset, x): | 214 def maxrev(repo, subset, x): |
215 s = getset(repo, subset, x) | 215 s = getset(repo, subset, x) |
236 return getset(repo, subset, l[0])[:lim] | 236 return getset(repo, subset, l[0])[:lim] |
237 | 237 |
238 def children(repo, subset, x): | 238 def children(repo, subset, x): |
239 cs = set() | 239 cs = set() |
240 cl = repo.changelog | 240 cl = repo.changelog |
241 s = set(getset(repo, subset, x)) | 241 s = set(getset(repo, range(len(repo)), x)) |
242 for r in xrange(0, len(repo)): | 242 for r in xrange(0, len(repo)): |
243 for p in cl.parentrevs(r): | 243 for p in cl.parentrevs(r): |
244 if p in s: | 244 if p in s: |
245 cs.add(r) | 245 cs.add(r) |
246 return [r for r in subset if r in cs] | 246 return [r for r in subset if r in cs] |