[PATCH 2 of 3] template: add revset() template function
Durham Goode
durham at fb.com
Thu Feb 13 01:24:08 UTC 2014
# HG changeset patch
# User Durham Goode <durham at fb.com>
# Date 1392181452 28800
# Tue Feb 11 21:04:12 2014 -0800
# Node ID 19aa10a1eff30c475695a239e6dc540d2fc4d851
# Parent 6c4d00a49f4ce956b8aa60b1352739be3492af78
template: add revset() template function
Adds a template function that executes a revset and returns the list of
revisions as the result. It has the signature 'revset(query [, args...])'. The
args are optional and are applied to the query string using the standard
python string.format(args) pattern. This allows things like:
'{revset("parents({0})", rev)}' to produce the parents of each individual
commit in the log output. If no args are specified, the revset result is
cached for the duration of the templater; so it's better to not use args if
performance is a concern.
By itself, revset() can be used to print commit parents, print the common
ancestor of a commit with the main branch, etc.
It can be used with the ifcontains() function to do things like
'{ifcontains(rev, revset('.'), label(...), ...)}' to color the working copy
parent, to color certain branches, to color draft commits, etc.
diff --git a/mercurial/templater.py b/mercurial/templater.py
--- a/mercurial/templater.py
+++ b/mercurial/templater.py
@@ -7,7 +7,7 @@
from i18n import _
import sys, os, re
-import util, config, templatefilters, parser, error
+import util, config, templatefilters, templatekw, parser, error
import types
import minirst
@@ -356,6 +356,28 @@
# ignore args[0] (the label string) since this is supposed to be a a no-op
yield _evalifliteral(args[1], context, mapping)
+def revset(context, mapping, args):
+ raw = args[0][1]
+ ctx = mapping['ctx']
+ repo = ctx._repo
+
+ cacheable = True
+ if len(args) > 1:
+ formatargs = list([a[0](context, mapping, a[1]) for a in args[1:]])
+ raw = raw.format(*formatargs)
+ cacheable = False
+
+ revsetcache = mapping['cache'].setdefault("revsetcache", {})
+ if cacheable and raw in revsetcache:
+ revs = revsetcache[raw]
+ else:
+ revs = repo.revs(raw)
+ revs = list([str(r) for r in revs])
+ if cacheable:
+ revsetcache[raw] = revs
+
+ return templatekw.showlist("revision", revs, **mapping)
+
def rstdoc(context, mapping, args):
if len(args) != 2:
# i18n: "rstdoc" is a keyword
@@ -454,6 +476,7 @@
"join": join,
"label": label,
"pad": pad,
+ "revset": revset,
"rstdoc": rstdoc,
"shortest": shortest,
"strip": strip,
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
@@ -1657,3 +1657,22 @@
$ hg log --template '{rev} {ifcontains("a", file_adds, "added a", "did not add a")}\n'
1 did not add a
0 added a
+
+Test revset function
+
+ $ hg log --template '{rev} {ifcontains(rev, revset("."), "current rev", "not current rev")}\n'
+ 1 current rev
+ 0 not current rev
+
+ $ hg log --template '{rev} Parents: {revset("parents({0})", rev)}\n'
+ 1 Parents: 0
+ 0 Parents:
+
+ $ hg log --template 'Rev: {rev}\n{revset("::{0}", rev) % "Ancestor: {revision}\n"}\n'
+ Rev: 1
+ Ancestor: 0
+ Ancestor: 1
+
+ Rev: 0
+ Ancestor: 0
+
diff --git a/tests/test-module-imports.t b/tests/test-module-imports.t
--- a/tests/test-module-imports.t
+++ b/tests/test-module-imports.t
@@ -34,7 +34,7 @@
relative: discovery, error, hbisect, phases, util
mercurial/templater.py mixed imports
stdlib: parser
- relative: config, error, templatefilters, util
+ relative: config, error, templatefilters, templatekw, util
mercurial/ui.py mixed imports
stdlib: formatter
relative: config, error, scmutil, util
More information about the Mercurial-devel
mailing list