diff --git a/contrib/revsetbenchmarks.txt b/contrib/revsetbenchmarks.txt --- a/contrib/revsetbenchmarks.txt +++ b/contrib/revsetbenchmarks.txt @@ -12,4 +12,5 @@ max(tip:0) min(0:tip) 0:: min(0::) +roots((tip~100::) - (tip~100::tip)) ::p1(p1(tip)):: diff --git a/mercurial/revset.py b/mercurial/revset.py --- a/mercurial/revset.py +++ b/mercurial/revset.py @@ -661,8 +661,18 @@ def _descendants(repo, subset, x, follow if not args: return baseset([]) s = _revdescendants(repo, args, followfirst) - a = set(args) - return subset.filter(lambda r: r in s or r in a) + + # Both sets need to be ascending in order to lazily return the union + # in the correct order. + args.ascending() + + subsetset = subset.set() + result = (orderedlazyset(s, subsetset.__contains__, ascending=True) + + orderedlazyset(args, subsetset.__contains__, ascending=True)) + + # Wrap result in a lazyset since it's an _addset, which doesn't implement + # all the necessary functions to be consumed by callers. + return orderedlazyset(result, lambda r: True, ascending=True) def descendants(repo, subset, x): """``descendants(set)`` diff --git a/tests/test-revset.t b/tests/test-revset.t --- a/tests/test-revset.t +++ b/tests/test-revset.t @@ -474,16 +474,6 @@ min: empty on unordered set 2 1 0 - $ log '1:: and reverse(all())' - 9 - 8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 $ log 'rev(5)' 5 $ log 'sort(limit(reverse(all()), 3))'