Mercurial > hg
changeset 25385:a26a55406c0a
revrange: build balanced tree of addsets from revisions (issue4565)
This reduces the stack depth from O(n) to O(log(n)). Therefore, repeated
-rREV options will never exceed the Python stack limit.
Currently it depends on private revset._combinesets() function. But at some
point, we'll be able to drop the old-style parser, and revrange() can be
completely rewritten without using _combinesets():
trees = [parse(s) for s in revs]
optimize(('or',) + trees) # combine trees and optimize at once
...
Blockers that prevent eliminating old-style parser:
- nullary ":" operator
- revrange(repo, [intrev, ...]), can be mapped to 'rev(%d)' ?
- revrange(repo, [binnode, ...]), should be banned ?
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sun, 24 May 2015 18:11:33 +0900 |
parents | 99d3ca7d67e4 |
children | a5a95642144b |
files | mercurial/scmutil.py tests/test-revset.t |
diffstat | 2 files changed, 14 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/scmutil.py Sun May 24 17:59:55 2015 +0900 +++ b/mercurial/scmutil.py Sun May 24 18:11:33 2015 +0900 @@ -709,7 +709,7 @@ return defval return repo[val].rev() - l = revset.baseset([]) + subsets = [] revsetaliases = [alias for (alias, _) in repo.ui.configitems("revsetalias")] @@ -725,7 +725,7 @@ raise error.RepoLookupError if isinstance(spec, int): - l = l + revset.baseset([spec]) + subsets.append(revset.baseset([spec])) continue if _revrangesep in spec: @@ -738,27 +738,21 @@ if end == nullrev and start < 0: start = nullrev rangeiter = repo.changelog.revs(start, end) - if not l: - # by far the most common case: revs = ["-1:0"] - l = revset.baseset(rangeiter) - continue - l = l + revset.baseset(rangeiter) + l = revset.baseset(rangeiter) + subsets.append(l) continue elif spec and spec in repo: # single unquoted rev rev = revfix(repo, spec, None) - l = l + revset.baseset([rev]) + subsets.append(revset.baseset([rev])) continue except error.RepoLookupError: pass # fall through to new-style queries if old-style fails m = revset.match(repo.ui, spec, repo) - if l: - l = l + m(repo) - else: - l = m(repo) + subsets.append(m(repo)) - return l + return revset._combinesets(subsets) def expandpats(pats): '''Expand bare globs when running on windows.
--- a/tests/test-revset.t Sun May 24 17:59:55 2015 +0900 +++ b/tests/test-revset.t Sun May 24 18:11:33 2015 +0900 @@ -1084,6 +1084,13 @@ 0 1 +test that repeated `-r` options never eat up stack (issue4565) +(uses `-r 0::1` to avoid possible optimization at old-style parser) + + $ hg log -T '{rev}\n' `python -c "for i in xrange(500): print '-r 0::1 ',"` + 0 + 1 + check that conversion to only works $ try --optimize '::3 - ::1' (minus