[PATCH 1 of 2] template: add the nodetypes keyword to describe the local topology at the node

Gilles Moris gilles.moris at free.fr
Tue May 18 02:43:39 CDT 2010


# HG changeset patch
# User Gilles Moris <gilles.moris at free.fr>
# Date 1273478166 -7200
# Node ID 5a536ebb3f70b6b994fd5d0f9b26d0ef436f3ada
# Parent  c4c6cd66f34f006d334fce4626e9a1d66db7158b
template: add the nodetypes keyword to describe the local topology at the node

The new keyword will return a list of descriptors in:
"head"      a changeset with no children, possibly marked as "(closed)" by a
           'commit --close-branch'.
"branch head"
            a changeset with no children of the same branch, possibly closed.
"merge"     a changeset with two parents.
"branch merge"
            a changeset with two parents that belongs to different named
            branches.
"root"      a changeset with no parents.
"branch root"
            a changeset with no parents of its named branch.
"commit"    any other changeset with a parent and usually one or more children.

In case of branch merge, the direction of the merge will also be indicated:
"(foo -> bar)"
Multiple values can be returned, as a changeset can be at the same time a root
and a head, or a head and a merge.

diff -r c4c6cd66f34f -r 5a536ebb3f70 mercurial/help/templates.txt
--- a/mercurial/help/templates.txt	Thu Feb 12 22:55:51 2009 +0100
+++ b/mercurial/help/templates.txt	Mon May 10 09:56:06 2010 +0200
@@ -64,6 +64,22 @@
 
 :latesttagdistance: Integer. Longest path to the latest tag.
 
+:nodetypes: List of strings. Type of the node (head, merge, root, ...).
+    Possible values are:
+
+    :``head``: a changeset with no children, possibly marked as
+        ``(closed)`` by a 'commit --close-branch'.
+    :``branch head``: a changeset with no children of the same branch,
+        possibly closed.
+    :``merge``: a changeset with two parents.
+    :``branch merge``: a changeset with two parents that belongs to
+        different named branches.
+    :``root``: a changeset with no parents.
+    :``branch root``: a changeset with no parents of its named branch.
+    :``commit``: any other changeset with a parent and usually one or
+        more children.
+
+
 The "date" keyword does not produce human-readable output. If you
 want to use a date in your output, you can use a filter to process
 it. Filters are functions which return a string based on the input
diff -r c4c6cd66f34f -r 5a536ebb3f70 mercurial/templatekw.py
--- a/mercurial/templatekw.py	Thu Feb 12 22:55:51 2009 +0100
+++ b/mercurial/templatekw.py	Mon May 10 09:56:06 2010 +0200
@@ -5,7 +5,8 @@
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2 or any later version.
 
-from node import hex
+from node import hex, nullrev
+from i18n import _
 import encoding, patch, util, error
 
 def showlist(name, values, plural=None, **args):
@@ -141,6 +142,53 @@
 
     return getrenamed
 
+def getnodetypes(repo, ctx, cache):
+    if ctx.rev() == nullrev:
+        return []
+
+    if 'heads' not in cache:
+        cache['heads'] = repo.heads()
+    heads = cache['heads']
+    if 'branchheads' not in cache:
+        cache['branchheads'] = dict()
+    bheads = cache['branchheads']
+    branch = ctx.branch()
+    if branch not in bheads:
+        bheads[branch] = repo.branchheads(branch, closed=True)
+
+    lt = []
+    # detect heads
+    t = ""
+    if ctx.node() in heads:
+        t = _("head")
+    elif ctx.node() in bheads[branch]:
+        t = _("branch head (%s)") % branch
+    if t and ctx.extra().get('close'):
+        t += _(" (closed)")
+    if t:
+        lt.append(t)
+    # detect merges
+    parents = ctx.parents()
+    if len(parents) > 1:
+        if parents[0].branch() != parents[1].branch():
+            t = _("branch merge")
+            if parents[0].branch() == branch:
+                t += _(" (%s -> %s)") % (parents[1].branch(), branch)
+            elif parents[1].branch() == branch:
+                t += _(" (%s -> %s)") % (parents[0].branch(), branch)
+            lt.append(t)
+        else:
+            lt.append(_("merge"))
+    # detect roots
+    if len(parents) == 0 or parents[0].rev() == nullrev:
+        lt.append("root")
+    elif not [p for p in parents if p.branch() == branch]:
+        lt.append(_("branch root (%s)") % branch)
+    # default
+    if not lt:
+        lt.append(_("commit"))
+    return lt
+
 
 def showauthor(repo, ctx, templ, **args):
     return ctx.user()
@@ -234,6 +282,10 @@
 def showtags(**args):
     return showlist('tag', args['ctx'].tags(), **args)
 
+def shownodetypes(**args):
+    lt = getnodetypes(args['repo'], args['ctx'], args['cache'])
+    return showlist('nodetype', lt, **args)
+
 # keywords are callables like:
 # fn(repo, ctx, templ, cache, revcache, **args)
 # with:
@@ -261,5 +313,6 @@
     'node': shownode,
     'rev': showrev,
     'tags': showtags,
+    'nodetypes': shownodetypes,
 }
 
diff -r c4c6cd66f34f -r 5a536ebb3f70 tests/test-command-template
--- a/tests/test-command-template	Thu Feb 12 22:55:51 2009 +0100
+++ b/tests/test-command-template	Mon May 10 09:56:06 2010 +0200
@@ -103,7 +103,7 @@
 echo "# keys work"
 for key in author branches date desc file_adds file_dels file_mods \
         file_copies file_copies_switch files \
-        manifest node parents rev tags diffstat extras; do
+        manifest node parents rev tags diffstat nodetypes extras; do
     for mode in '' --verbose --debug; do
         hg log $mode --template "$key$mode: {$key}\n"
     done
diff -r c4c6cd66f34f -r 5a536ebb3f70 tests/test-command-template.out
--- a/tests/test-command-template.out	Thu Feb 12 22:55:51 2009 +0100
+++ b/tests/test-command-template.out	Mon May 10 09:56:06 2010 +0200
@@ -882,6 +882,33 @@
 diffstat--debug: 1: +4/-0
 diffstat--debug: 1: +2/-0
 diffstat--debug: 1: +1/-0
+nodetypes: head
+nodetypes: root
+nodetypes: head branch merge (foo -> default)
+nodetypes: commit
+nodetypes: branch head (foo) branch root (foo)
+nodetypes: commit
+nodetypes: commit
+nodetypes: commit
+nodetypes: root
+nodetypes--verbose: head
+nodetypes--verbose: root
+nodetypes--verbose: head branch merge (foo -> default)
+nodetypes--verbose: commit
+nodetypes--verbose: branch head (foo) branch root (foo)
+nodetypes--verbose: commit
+nodetypes--verbose: commit
+nodetypes--verbose: commit
+nodetypes--verbose: root
+nodetypes--debug: head
+nodetypes--debug: root
+nodetypes--debug: head branch merge (foo -> default)
+nodetypes--debug: commit
+nodetypes--debug: branch head (foo) branch root (foo)
+nodetypes--debug: commit
+nodetypes--debug: commit
+nodetypes--debug: commit
+nodetypes--debug: root
 extras: branch=default
 extras: branch=default
 extras: branch=default


More information about the Mercurial-devel mailing list