# HG changeset patch # User Pierre-Yves David # Date 2015-06-17 02:47:46 # Node ID 5f87f2305ad05e6bf01f0a4973099e962203b953 # Parent 833fa28cd9494e966ee0299d3685e6080812b5d1 revset: translate node directly with changelog in 'head' Using 'repo[X]' is much slower because it creates a 'changectx' object and goes though multiple layers of code to do so. It is also error prone if there is tags, bookmarks, branch or other names that could map to a node hash and take precedence (user are wicked). This provides a significant performance boost on repository with a lot of heads. Benchmark result for a repo with 1181 heads. revset: head() plain min last reverse 0) 0.014853 0.014371 0.014350 0.015161 1) 0.001402 9% 0.000975 6% 0.000874 6% 0.001415 9% revset: head() - public() plain min last reverse 0) 0.015121 0.014420 0.014560 0.015028 1) 0.001674 11% 0.001109 7% 0.000980 6% 0.001693 11% revset: draft() and head() plain min last reverse 0) 0.015976 0.014490 0.014214 0.015892 1) 0.002335 14% 0.001018 7% 0.000887 6% 0.002340 14% The speed up is visible even when other more costly revset are in use revset: head() and author("mpm") plain min last reverse 0) 0.105419 0.090046 0.017169 0.108180 1) 0.090721 86% 0.077602 86% 0.003556 20% 0.093324 86% diff --git a/contrib/all-revsets.txt b/contrib/all-revsets.txt --- a/contrib/all-revsets.txt +++ b/contrib/all-revsets.txt @@ -118,3 +118,9 @@ roots((0:tip)::) # those two `roots(...)` inputs are close to what phase movement use. roots((tip~100::) - (tip~100::tip)) roots((0::) - (0::tip)) + +# Testing the behavior of "head()" in various situations +head() +head() - public() +draft() and head() +head() and author("mpm") diff --git a/mercurial/revset.py b/mercurial/revset.py --- a/mercurial/revset.py +++ b/mercurial/revset.py @@ -1107,8 +1107,9 @@ def head(repo, subset, x): # i18n: "head" is a keyword getargs(x, 0, 0, _("head takes no arguments")) hs = set() + cl = repo.changelog for b, ls in repo.branchmap().iteritems(): - hs.update(repo[h].rev() for h in ls) + hs.update(cl.rev(h) for h in ls) # XXX using a set to feed the baseset is wrong. Sets are not ordered. # This does not break because of other fullreposet misbehavior. # XXX We should not be using '.filter' here, but combines subset with '&'