[PATCH 1 of 2 V2] template: add shortest(node) template function

Durham Goode durham at fb.com
Tue Feb 4 21:56:38 CST 2014


# HG changeset patch
# User Durham Goode <durham at fb.com>
# Date 1389946237 28800
#      Fri Jan 17 00:10:37 2014 -0800
# Node ID bc85372a73c4f09e12d7ef8b7ac1f7dfcb1a5108
# Parent  ec5d4287a4269bc939e203c975af8585570404c6
template: add shortest(node) template function

Adds a '{shortest(node)}' template function that results in the shortest hex node
that uniquely identifies the changeset at that time. The minimum length can be
specified as an optional second argument and defaults to 4.

This is useful for producing prettier log output, like so:

@  durham  shortestnode
|  77cf    template: add pad function for padding output
|
o  durham
|  b183    template: add shortestnode keyword
|
o  pierre-yves @
|  6545    backout: add a message after backout that need manual commit
|
| o  durham   manifestcache
|/   93f0    manifest cache
|
| o  durham   catperf
| |  c765    cat: increase perf when catting single files
| |
| o  durham
|/   9c53    changectx: increase perf of walk function
|

diff --git a/mercurial/templater.py b/mercurial/templater.py
--- a/mercurial/templater.py
+++ b/mercurial/templater.py
@@ -328,6 +328,45 @@
 
     return minirst.format(text, style=style, keep=['verbose'])
 
+def shortest(context, mapping, args):
+    """usage: shortest(node, minlength=4)
+    """
+    if not (1 <= len(args) <= 2):
+        raise error.ParseError(_("shortest() expects one or two arguments"))
+
+    node = stringify(args[0][0](context, mapping, args[0][1]))
+
+    minlength = 4
+    if len(args) > 1:
+        minlength = int(args[1][1])
+
+    cl = mapping['ctx']._repo.changelog
+    def isvalid(test):
+        try:
+            cl.index.partialmatch(test)
+            try:
+                int(test)
+                return False
+            except ValueError:
+                return True
+        except error.RevlogError:
+            return False
+
+    shortest = node
+    startlength = max(6, minlength)
+    length = startlength
+    while True:
+        test = node[:length]
+        if isvalid(test):
+            shortest = test
+            if length == minlength or length > startlength:
+                return shortest
+            length -= 1
+        else:
+            length += 1
+            if len(shortest) <= length:
+                return shortest
+
 def strip(context, mapping, args):
     if not (1 <= len(args) <= 2):
         raise error.ParseError(_("strip expects one or two arguments"))
@@ -369,6 +408,7 @@
     "join": join,
     "label": label,
     "rstdoc": rstdoc,
+    "shortest": shortest,
     "strip": strip,
     "sub": sub,
 }
diff --git a/tests/test-command-template.t b/tests/test-command-template.t
--- a/tests/test-command-template.t
+++ b/tests/test-command-template.t
@@ -1626,3 +1626,14 @@
 
   $ hg log -r 0 --template '{if(branches, "yes", "no")}\n'
   no
+
+Test shortest(node) function:
+
+  $ echo b > b
+  $ hg ci -qAm b
+  $ hg log --template '{shortest(node)}\n'
+  d97c
+  f776
+  $ hg log --template '{shortest(node, 10)}\n'
+  d97c383ae3
+  f7769ec2ab


More information about the Mercurial-devel mailing list