# HG changeset patch # User Yuya Nishihara # Date 1497091302 -32400 # Node ID 3e6f9bff7e3fd919157984bf03fffcf64abd61c1 # Parent b36ec65ea5837aa7e4bbbc4ac8998075dfc178e1 revset: filter first/last members by __and__ operation This replaces 'if y in subset' with '& subset'. first(null) and last(wdir()) are fixed thanks to fullreposet.__and__. This also revealed that first() and last() don't follow the order of the input set. 'ls & subset' is valid only if the ordering requirement is 'define' or 'any'. No performance regression observed: revset #0: limit(0:9999, 100, 9000) 0) 0.001164 1) 0.001135 revset #2: 9000 & limit(0:9999, 100, 9000) 0) 0.001224 1) 0.001181 revset #3: last(0:9999, 100) 0) 0.000237 1) 0.000199 diff -r b36ec65ea583 -r 3e6f9bff7e3f mercurial/revset.py --- a/mercurial/revset.py Sat Jun 10 18:35:11 2017 +0900 +++ b/mercurial/revset.py Sat Jun 10 19:41:42 2017 +0900 @@ -1179,10 +1179,9 @@ y = next(it, None) if y is None: break - elif y in subset: - result.append(y) - return baseset(result, datarepr=('', - lim, ofs, subset, os)) + result.append(y) + ls = baseset(result, datarepr=('', lim, ofs, os)) + return ls & subset @predicate('last(set, [n])', safe=True) def last(repo, subset, x): @@ -1204,10 +1203,10 @@ y = next(it, None) if y is None: break - elif y in subset: - result.append(y) - return baseset(result[::-1], datarepr=('', - lim, subset, os)) + result.append(y) + ls = baseset(result, datarepr=('', lim, os)) + ls.reverse() + return ls & subset @predicate('max(set)', safe=True) def maxrev(repo, subset, x): diff -r b36ec65ea583 -r 3e6f9bff7e3f tests/test-revset.t --- a/tests/test-revset.t Sat Jun 10 18:35:11 2017 +0900 +++ b/tests/test-revset.t Sat Jun 10 19:41:42 2017 +0900 @@ -1016,6 +1016,50 @@ 8 9 +Test order of first/last revisions + + $ hg debugrevspec -s 'first(4:0, 3) & 3:' + * set: + >>, + > + 4 + 3 + + $ hg debugrevspec -s '3: & first(4:0, 3)' + * set: + >>, + > + 4 + 3 +BROKEN: should be '3 4' + + $ hg debugrevspec -s 'last(4:0, 3) & :1' + * set: + >>, + > + 1 + 0 + + $ hg debugrevspec -s ':1 & last(4:0, 3)' + * set: + >>, + > + 1 + 0 +BROKEN: should be '0 1' + Test matching $ log 'matching(6)' @@ -1230,10 +1274,10 @@ $ log 'reverse(null:)' | tail -2 0 -1 + $ log 'first(null:)' + -1 + $ log 'min(null:)' BROKEN: should be '-1' - $ log 'first(null:)' -BROKEN: should be '-1' - $ log 'min(null:)' $ log 'tip:null and all()' | tail -2 1 0 @@ -1295,9 +1339,9 @@ 9 $ log '(all() + wdir()) & max(. + wdir())' 2147483647 - $ log '(all() + wdir()) & first(wdir() + .)' + $ log 'first(wdir() + .)' 2147483647 - $ log '(all() + wdir()) & last(. + wdir())' + $ log 'last(. + wdir())' 2147483647 Test working-directory integer revision and node id @@ -1907,10 +1951,11 @@ follow) define) * set: - , - >> + >>, + > 1 $ try --optimize '2:0 & not last(0 + 2 + 1)' @@ -1946,7 +1991,6 @@ , >>>> 2 0 @@ -3573,7 +3617,6 @@ , >>, >> @@ -3630,7 +3673,6 @@ , >>, >>