diff --git a/mercurial/namespaces.py b/mercurial/namespaces.py --- a/mercurial/namespaces.py +++ b/mercurial/namespaces.py @@ -95,21 +95,16 @@ def singlenode(self, repo, name): """ - Return the 'best' node for the given name. Best means the first node - in the first nonempty list returned by a name-to-nodes mapping function - in the defined precedence order. + Return the 'best' node for the given name. What's best is defined + by the namespace's singlenode() function. The first match returned by + a namespace in the defined precedence order is used. Raises a KeyError if there is no such node. """ for ns, v in self._names.iteritems(): - n = v.namemap(repo, name) + n = v.singlenode(repo, name) if n: - # return max revision number - if len(n) > 1: - cl = repo.changelog - maxrev = max(cl.rev(node) for node in n) - return cl.node(maxrev) - return n[0] + return n raise KeyError(_('no such name: %s') % name) class namespace(object): @@ -142,7 +137,7 @@ def __init__(self, name, templatename=None, logname=None, colorname=None, logfmt=None, listnames=None, namemap=None, nodemap=None, - deprecated=None, builtin=False): + deprecated=None, builtin=False, singlenode=None): """create a namespace name: the namespace to be registered (in plural form) @@ -158,6 +153,7 @@ nodemap: function that inputs a node, output name(s) deprecated: set of names to be masked for ordinary use builtin: whether namespace is implemented by core Mercurial + singlenode: function that inputs a name, output best node (or None) """ self.name = name self.templatename = templatename @@ -167,6 +163,18 @@ self.listnames = listnames self.namemap = namemap self.nodemap = nodemap + if not singlenode: + def singlenode(repo, name): + n = self.namemap(repo, name) + if n: + # return max revision number + if len(n) > 1: + cl = repo.changelog + maxrev = max(cl.rev(node) for node in n) + return cl.node(maxrev) + return n[0] + return None + self.singlenode = singlenode # if logname is not specified, use the template name as backup if self.logname is None: