template: add shortest(node) template function
authorDurham Goode <durham@fb.com>
Fri, 17 Jan 2014 00:10:37 -0800
changeset 20369 9c6b86dd2ed2
parent 20368 cc00cd6c51c2
child 20370 aa51392da507
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 |
mercurial/templater.py
tests/test-command-template.t
--- a/mercurial/templater.py	Wed Feb 05 18:09:07 2014 -0600
+++ b/mercurial/templater.py	Fri Jan 17 00:10:37 2014 -0800
@@ -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,
 }
--- a/tests/test-command-template.t	Wed Feb 05 18:09:07 2014 -0600
+++ b/tests/test-command-template.t	Fri Jan 17 00:10:37 2014 -0800
@@ -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