Patchwork [3,of,7,V2] namespaces: add nodemap property

mail settings
Submitter Sean Farley
Date Dec. 18, 2014, 9:10 p.m.
Message ID <430e5b84bcf084090939.1418937047@laptop.local>
Download mbox | patch
Permalink /patch/7175/
State Accepted
Headers show


Sean Farley - Dec. 18, 2014, 9:10 p.m.
# HG changeset patch
# User Sean Farley <>
# Date 1418631863 28800
#      Mon Dec 15 00:24:23 2014 -0800
# Node ID 430e5b84bcf084090939993ab9a05f342bbb85ed
# Parent  873ba6dc401458b59c14cec91b9729d36064b8e3
namespaces: add nodemap property

This patch adds a node-to-name map property to the namespace. This is necessary
because we cannot simply invert the name-to-node map because we do not assume
the name-to-node map to be unique (for example, consider named branches: many
nodes have one branch name).

The node-to-name is helpful in log commands where we are already iterating over
a set of nodes and want to display some kind of naming information to the user.


diff --git a/mercurial/ b/mercurial/
--- a/mercurial/
+++ b/mercurial/
@@ -15,22 +15,24 @@  class namespaces(object):
     provides an interface to register a generic many-to-many mapping between
     some (namespaced) names and nodes. The goal here is to control the
     pollution of jamming things into tags or bookmarks (in extension-land) and
     to simplify internal bits of mercurial: log output, tab completion, etc.
-    More precisely, we define a list of names (the namespace) and  a mapping of
-    names to nodes. This name mapping returns a list of nodes.
+    More precisely, we define a list of names (the namespace), a mapping of
+    names to nodes, and a mapping from nodes to names. Each mapping
+    returns a list of nodes.
     Furthermore, each name mapping will be passed a name to lookup which might
     not be in its domain. In this case, each method should return an empty list
     and not raise an error.
     We'll have a dictionary '_names' where each key is a namespace and
     its value is a dictionary of functions:
       'templatename': name to use for templating (usually the singular form
                       of the plural namespace name)
       'namemap': function that takes a name and returns a list of nodes
+      'nodemap': function that takes a node and returns a list of names
     _names_version = 0
     def __init__(self):
@@ -39,30 +41,36 @@  class namespaces(object):
         addns = self.addnamespace
         # we need current mercurial named objects (bookmarks, tags, and
         # branches) to be initialized somewhere, so that place is here
         addns("bookmarks", "bookmark",
-              lambda repo, name: tolist(repo._bookmarks.get(name)))
+              lambda repo, name: tolist(repo._bookmarks.get(name)),
+              lambda repo, name: repo.nodebookmarks(name))
         addns("tags", "tag",
-              lambda repo, name: tolist(repo._tagscache.tags.get(name)))
+              lambda repo, name: tolist(repo._tagscache.tags.get(name)),
+              lambda repo, name: repo.nodetags(name))
         addns("branches", "branch",
-              lambda repo, name: tolist(repo.branchtip(name)))
+              lambda repo, name: tolist(repo.branchtip(name)),
+              lambda repo, node: [repo[node].branch()])
-    def addnamespace(self, namespace, templatename, namemap, order=None):
+    def addnamespace(self, namespace, templatename, namemap, nodemap,
+                     order=None):
         register a namespace
         namespace: the name to be registered (in plural form)
         templatename: the name to use for templating
         namemap: function that inputs a node, output name(s)
+        nodemap: function that inputs a name, output node(s)
         order: optional argument to specify the order of namespaces
                (e.g. 'branches' should be listed before 'bookmarks')
         val = {'templatename': templatename,
-               'namemap': namemap}
+               'namemap': namemap,
+               'nodemap': nodemap}
         if order is not None:
             self._names.insert(order, namespace, val)
             self._names[namespace] = val