revset: avoid over-aggresive optimizations of non-filtering functions (issue2549)
When limit, last, min and max were evaluated they worked on a reduced set in the
wrong way. Now they work on an unrestricted set (the whole repo) and get
limited later on.
--- a/mercurial/revset.py Sun May 01 17:35:05 2011 +0200
+++ b/mercurial/revset.py Sun May 01 17:35:05 2011 +0200
@@ -468,7 +468,9 @@
except ValueError:
# i18n: "limit" is a keyword
raise error.ParseError(_("limit expects a number"))
- return getset(repo, subset, l[0])[:lim]
+ ss = set(subset)
+ os = getset(repo, range(len(repo)), l[0])[:lim]
+ return [r for r in os if r in ss]
def last(repo, subset, x):
"""``last(set, n)``
@@ -482,15 +484,17 @@
except ValueError:
# i18n: "last" is a keyword
raise error.ParseError(_("last expects a number"))
- return getset(repo, subset, l[0])[-lim:]
+ ss = set(subset)
+ os = getset(repo, range(len(repo)), l[0])[-lim:]
+ return [r for r in os if r in ss]
def maxrev(repo, subset, x):
"""``max(set)``
Changeset with highest revision number in set.
"""
- s = getset(repo, subset, x)
- if s:
- m = max(s)
+ os = getset(repo, range(len(repo)), x)
+ if os:
+ m = max(os)
if m in subset:
return [m]
return []
@@ -508,9 +512,9 @@
"""``min(set)``
Changeset with lowest revision number in set.
"""
- s = getset(repo, subset, x)
- if s:
- m = min(s)
+ os = getset(repo, range(len(repo)), x)
+ if os:
+ m = min(os)
if m in subset:
return [m]
return []
--- a/tests/test-revset.t Sun May 01 17:35:05 2011 +0200
+++ b/tests/test-revset.t Sun May 01 17:35:05 2011 +0200
@@ -435,3 +435,11 @@
('func', ('symbol', 'reverse'), ('func', ('symbol', 'sort'), ('list', ('or', ('symbol', '2'), ('symbol', '3')), ('symbol', 'date'))))
3
2
+
+issue2549 - correct optimizations
+
+ $ log 'limit(1 or 2 or 3, 2) and not 2'
+ 1
+ $ log 'max(1 or 2) and not 2'
+ $ log 'min(1 or 2) and not 1'
+ $ log 'last(1 or 2, 1) and not 2'