##// END OF EJS Templates
templater: add "diff" template function...
FUJIWARA Katsunori -
r22434:40ce05b5 default
parent child Browse files
Show More
@@ -1,137 +1,139 b''
1 Mercurial allows you to customize output of commands through
1 Mercurial allows you to customize output of commands through
2 templates. You can either pass in a template or select an existing
2 templates. You can either pass in a template or select an existing
3 template-style from the command line, via the --template option.
3 template-style from the command line, via the --template option.
4
4
5 You can customize output for any "log-like" command: log,
5 You can customize output for any "log-like" command: log,
6 outgoing, incoming, tip, parents, and heads.
6 outgoing, incoming, tip, parents, and heads.
7
7
8 Some built-in styles are packaged with Mercurial. These can be listed
8 Some built-in styles are packaged with Mercurial. These can be listed
9 with :hg:`log --template list`. Example usage::
9 with :hg:`log --template list`. Example usage::
10
10
11 $ hg log -r1.0::1.1 --template changelog
11 $ hg log -r1.0::1.1 --template changelog
12
12
13 A template is a piece of text, with markup to invoke variable
13 A template is a piece of text, with markup to invoke variable
14 expansion::
14 expansion::
15
15
16 $ hg log -r1 --template "{node}\n"
16 $ hg log -r1 --template "{node}\n"
17 b56ce7b07c52de7d5fd79fb89701ea538af65746
17 b56ce7b07c52de7d5fd79fb89701ea538af65746
18
18
19 Strings in curly braces are called keywords. The availability of
19 Strings in curly braces are called keywords. The availability of
20 keywords depends on the exact context of the templater. These
20 keywords depends on the exact context of the templater. These
21 keywords are usually available for templating a log-like command:
21 keywords are usually available for templating a log-like command:
22
22
23 .. keywordsmarker
23 .. keywordsmarker
24
24
25 The "date" keyword does not produce human-readable output. If you
25 The "date" keyword does not produce human-readable output. If you
26 want to use a date in your output, you can use a filter to process
26 want to use a date in your output, you can use a filter to process
27 it. Filters are functions which return a string based on the input
27 it. Filters are functions which return a string based on the input
28 variable. Be sure to use the stringify filter first when you're
28 variable. Be sure to use the stringify filter first when you're
29 applying a string-input filter to a list-like input variable.
29 applying a string-input filter to a list-like input variable.
30 You can also use a chain of filters to get the desired output::
30 You can also use a chain of filters to get the desired output::
31
31
32 $ hg tip --template "{date|isodate}\n"
32 $ hg tip --template "{date|isodate}\n"
33 2008-08-21 18:22 +0000
33 2008-08-21 18:22 +0000
34
34
35 List of filters:
35 List of filters:
36
36
37 .. filtersmarker
37 .. filtersmarker
38
38
39 Note that a filter is nothing more than a function call, i.e.
39 Note that a filter is nothing more than a function call, i.e.
40 ``expr|filter`` is equivalent to ``filter(expr)``.
40 ``expr|filter`` is equivalent to ``filter(expr)``.
41
41
42 In addition to filters, there are some basic built-in functions:
42 In addition to filters, there are some basic built-in functions:
43
43
44 - date(date[, fmt])
44 - date(date[, fmt])
45
45
46 - diff([includepattern [, excludepattern]])
47
46 - fill(text[, width])
48 - fill(text[, width])
47
49
48 - get(dict, key)
50 - get(dict, key)
49
51
50 - if(expr, then[, else])
52 - if(expr, then[, else])
51
53
52 - ifcontains(expr, expr, then[, else])
54 - ifcontains(expr, expr, then[, else])
53
55
54 - ifeq(expr, expr, then[, else])
56 - ifeq(expr, expr, then[, else])
55
57
56 - join(list, sep)
58 - join(list, sep)
57
59
58 - label(label, expr)
60 - label(label, expr)
59
61
60 - pad(text, width[, fillchar, right])
62 - pad(text, width[, fillchar, right])
61
63
62 - revset(query[, formatargs])
64 - revset(query[, formatargs])
63
65
64 - rstdoc(text, style)
66 - rstdoc(text, style)
65
67
66 - shortest(node)
68 - shortest(node)
67
69
68 - startswith(string, text)
70 - startswith(string, text)
69
71
70 - strip(text[, chars])
72 - strip(text[, chars])
71
73
72 - sub(pat, repl, expr)
74 - sub(pat, repl, expr)
73
75
74 - word(number, text[, separator])
76 - word(number, text[, separator])
75
77
76 Also, for any expression that returns a list, there is a list operator:
78 Also, for any expression that returns a list, there is a list operator:
77
79
78 - expr % "{template}"
80 - expr % "{template}"
79
81
80 Some sample command line templates:
82 Some sample command line templates:
81
83
82 - Format lists, e.g. files::
84 - Format lists, e.g. files::
83
85
84 $ hg log -r 0 --template "files:\n{files % ' {file}\n'}"
86 $ hg log -r 0 --template "files:\n{files % ' {file}\n'}"
85
87
86 - Join the list of files with a ", "::
88 - Join the list of files with a ", "::
87
89
88 $ hg log -r 0 --template "files: {join(files, ', ')}\n"
90 $ hg log -r 0 --template "files: {join(files, ', ')}\n"
89
91
90 - Modify each line of a commit description::
92 - Modify each line of a commit description::
91
93
92 $ hg log --template "{splitlines(desc) % '**** {line}\n'}"
94 $ hg log --template "{splitlines(desc) % '**** {line}\n'}"
93
95
94 - Format date::
96 - Format date::
95
97
96 $ hg log -r 0 --template "{date(date, '%Y')}\n"
98 $ hg log -r 0 --template "{date(date, '%Y')}\n"
97
99
98 - Output the description set to a fill-width of 30::
100 - Output the description set to a fill-width of 30::
99
101
100 $ hg log -r 0 --template "{fill(desc, '30')}"
102 $ hg log -r 0 --template "{fill(desc, '30')}"
101
103
102 - Use a conditional to test for the default branch::
104 - Use a conditional to test for the default branch::
103
105
104 $ hg log -r 0 --template "{ifeq(branch, 'default', 'on the main branch',
106 $ hg log -r 0 --template "{ifeq(branch, 'default', 'on the main branch',
105 'on branch {branch}')}\n"
107 'on branch {branch}')}\n"
106
108
107 - Append a newline if not empty::
109 - Append a newline if not empty::
108
110
109 $ hg tip --template "{if(author, '{author}\n')}"
111 $ hg tip --template "{if(author, '{author}\n')}"
110
112
111 - Label the output for use with the color extension::
113 - Label the output for use with the color extension::
112
114
113 $ hg log -r 0 --template "{label('changeset.{phase}', node|short)}\n"
115 $ hg log -r 0 --template "{label('changeset.{phase}', node|short)}\n"
114
116
115 - Invert the firstline filter, i.e. everything but the first line::
117 - Invert the firstline filter, i.e. everything but the first line::
116
118
117 $ hg log -r 0 --template "{sub(r'^.*\n?\n?', '', desc)}\n"
119 $ hg log -r 0 --template "{sub(r'^.*\n?\n?', '', desc)}\n"
118
120
119 - Display the contents of the 'extra' field, one per line::
121 - Display the contents of the 'extra' field, one per line::
120
122
121 $ hg log -r 0 --template "{join(extras, '\n')}\n"
123 $ hg log -r 0 --template "{join(extras, '\n')}\n"
122
124
123 - Mark the current bookmark with '*'::
125 - Mark the current bookmark with '*'::
124
126
125 $ hg log --template "{bookmarks % '{bookmark}{ifeq(bookmark, current, \"*\")} '}\n"
127 $ hg log --template "{bookmarks % '{bookmark}{ifeq(bookmark, current, \"*\")} '}\n"
126
128
127 - Mark the working copy parent with '@'::
129 - Mark the working copy parent with '@'::
128
130
129 $ hg log --template "{ifcontains(rev, revset('.'), '@')}\n"
131 $ hg log --template "{ifcontains(rev, revset('.'), '@')}\n"
130
132
131 - Show only commit descriptions that start with "template"::
133 - Show only commit descriptions that start with "template"::
132
134
133 $ hg log --template "{startswith(\"template\", firstline(desc))}\n"
135 $ hg log --template "{startswith(\"template\", firstline(desc))}\n"
134
136
135 - Print the first word of each line of a commit message::
137 - Print the first word of each line of a commit message::
136
138
137 $ hg log --template "{word(\"0\", desc)}\n"
139 $ hg log --template "{word(\"0\", desc)}\n"
@@ -1,749 +1,767 b''
1 # templater.py - template expansion for output
1 # templater.py - template expansion for output
2 #
2 #
3 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from i18n import _
8 from i18n import _
9 import sys, os, re
9 import sys, os, re
10 import util, config, templatefilters, templatekw, parser, error
10 import util, config, templatefilters, templatekw, parser, error
11 import revset as revsetmod
11 import revset as revsetmod
12 import types
12 import types
13 import minirst
13 import minirst
14
14
15 # template parsing
15 # template parsing
16
16
17 elements = {
17 elements = {
18 "(": (20, ("group", 1, ")"), ("func", 1, ")")),
18 "(": (20, ("group", 1, ")"), ("func", 1, ")")),
19 ",": (2, None, ("list", 2)),
19 ",": (2, None, ("list", 2)),
20 "|": (5, None, ("|", 5)),
20 "|": (5, None, ("|", 5)),
21 "%": (6, None, ("%", 6)),
21 "%": (6, None, ("%", 6)),
22 ")": (0, None, None),
22 ")": (0, None, None),
23 "symbol": (0, ("symbol",), None),
23 "symbol": (0, ("symbol",), None),
24 "string": (0, ("string",), None),
24 "string": (0, ("string",), None),
25 "rawstring": (0, ("rawstring",), None),
25 "rawstring": (0, ("rawstring",), None),
26 "end": (0, None, None),
26 "end": (0, None, None),
27 }
27 }
28
28
29 def tokenizer(data):
29 def tokenizer(data):
30 program, start, end = data
30 program, start, end = data
31 pos = start
31 pos = start
32 while pos < end:
32 while pos < end:
33 c = program[pos]
33 c = program[pos]
34 if c.isspace(): # skip inter-token whitespace
34 if c.isspace(): # skip inter-token whitespace
35 pass
35 pass
36 elif c in "(,)%|": # handle simple operators
36 elif c in "(,)%|": # handle simple operators
37 yield (c, None, pos)
37 yield (c, None, pos)
38 elif (c in '"\'' or c == 'r' and
38 elif (c in '"\'' or c == 'r' and
39 program[pos:pos + 2] in ("r'", 'r"')): # handle quoted strings
39 program[pos:pos + 2] in ("r'", 'r"')): # handle quoted strings
40 if c == 'r':
40 if c == 'r':
41 pos += 1
41 pos += 1
42 c = program[pos]
42 c = program[pos]
43 decode = False
43 decode = False
44 else:
44 else:
45 decode = True
45 decode = True
46 pos += 1
46 pos += 1
47 s = pos
47 s = pos
48 while pos < end: # find closing quote
48 while pos < end: # find closing quote
49 d = program[pos]
49 d = program[pos]
50 if decode and d == '\\': # skip over escaped characters
50 if decode and d == '\\': # skip over escaped characters
51 pos += 2
51 pos += 2
52 continue
52 continue
53 if d == c:
53 if d == c:
54 if not decode:
54 if not decode:
55 yield ('rawstring', program[s:pos], s)
55 yield ('rawstring', program[s:pos], s)
56 break
56 break
57 yield ('string', program[s:pos], s)
57 yield ('string', program[s:pos], s)
58 break
58 break
59 pos += 1
59 pos += 1
60 else:
60 else:
61 raise error.ParseError(_("unterminated string"), s)
61 raise error.ParseError(_("unterminated string"), s)
62 elif c.isalnum() or c in '_':
62 elif c.isalnum() or c in '_':
63 s = pos
63 s = pos
64 pos += 1
64 pos += 1
65 while pos < end: # find end of symbol
65 while pos < end: # find end of symbol
66 d = program[pos]
66 d = program[pos]
67 if not (d.isalnum() or d == "_"):
67 if not (d.isalnum() or d == "_"):
68 break
68 break
69 pos += 1
69 pos += 1
70 sym = program[s:pos]
70 sym = program[s:pos]
71 yield ('symbol', sym, s)
71 yield ('symbol', sym, s)
72 pos -= 1
72 pos -= 1
73 elif c == '}':
73 elif c == '}':
74 pos += 1
74 pos += 1
75 break
75 break
76 else:
76 else:
77 raise error.ParseError(_("syntax error"), pos)
77 raise error.ParseError(_("syntax error"), pos)
78 pos += 1
78 pos += 1
79 yield ('end', None, pos)
79 yield ('end', None, pos)
80
80
81 def compiletemplate(tmpl, context, strtoken="string"):
81 def compiletemplate(tmpl, context, strtoken="string"):
82 parsed = []
82 parsed = []
83 pos, stop = 0, len(tmpl)
83 pos, stop = 0, len(tmpl)
84 p = parser.parser(tokenizer, elements)
84 p = parser.parser(tokenizer, elements)
85 while pos < stop:
85 while pos < stop:
86 n = tmpl.find('{', pos)
86 n = tmpl.find('{', pos)
87 if n < 0:
87 if n < 0:
88 parsed.append((strtoken, tmpl[pos:]))
88 parsed.append((strtoken, tmpl[pos:]))
89 break
89 break
90 if n > 0 and tmpl[n - 1] == '\\':
90 if n > 0 and tmpl[n - 1] == '\\':
91 # escaped
91 # escaped
92 parsed.append((strtoken, (tmpl[pos:n - 1] + "{")))
92 parsed.append((strtoken, (tmpl[pos:n - 1] + "{")))
93 pos = n + 1
93 pos = n + 1
94 continue
94 continue
95 if n > pos:
95 if n > pos:
96 parsed.append((strtoken, tmpl[pos:n]))
96 parsed.append((strtoken, tmpl[pos:n]))
97
97
98 pd = [tmpl, n + 1, stop]
98 pd = [tmpl, n + 1, stop]
99 parseres, pos = p.parse(pd)
99 parseres, pos = p.parse(pd)
100 parsed.append(parseres)
100 parsed.append(parseres)
101
101
102 return [compileexp(e, context) for e in parsed]
102 return [compileexp(e, context) for e in parsed]
103
103
104 def compileexp(exp, context):
104 def compileexp(exp, context):
105 t = exp[0]
105 t = exp[0]
106 if t in methods:
106 if t in methods:
107 return methods[t](exp, context)
107 return methods[t](exp, context)
108 raise error.ParseError(_("unknown method '%s'") % t)
108 raise error.ParseError(_("unknown method '%s'") % t)
109
109
110 # template evaluation
110 # template evaluation
111
111
112 def getsymbol(exp):
112 def getsymbol(exp):
113 if exp[0] == 'symbol':
113 if exp[0] == 'symbol':
114 return exp[1]
114 return exp[1]
115 raise error.ParseError(_("expected a symbol, got '%s'") % exp[0])
115 raise error.ParseError(_("expected a symbol, got '%s'") % exp[0])
116
116
117 def getlist(x):
117 def getlist(x):
118 if not x:
118 if not x:
119 return []
119 return []
120 if x[0] == 'list':
120 if x[0] == 'list':
121 return getlist(x[1]) + [x[2]]
121 return getlist(x[1]) + [x[2]]
122 return [x]
122 return [x]
123
123
124 def getfilter(exp, context):
124 def getfilter(exp, context):
125 f = getsymbol(exp)
125 f = getsymbol(exp)
126 if f not in context._filters:
126 if f not in context._filters:
127 raise error.ParseError(_("unknown function '%s'") % f)
127 raise error.ParseError(_("unknown function '%s'") % f)
128 return context._filters[f]
128 return context._filters[f]
129
129
130 def gettemplate(exp, context):
130 def gettemplate(exp, context):
131 if exp[0] == 'string' or exp[0] == 'rawstring':
131 if exp[0] == 'string' or exp[0] == 'rawstring':
132 return compiletemplate(exp[1], context, strtoken=exp[0])
132 return compiletemplate(exp[1], context, strtoken=exp[0])
133 if exp[0] == 'symbol':
133 if exp[0] == 'symbol':
134 return context._load(exp[1])
134 return context._load(exp[1])
135 raise error.ParseError(_("expected template specifier"))
135 raise error.ParseError(_("expected template specifier"))
136
136
137 def runstring(context, mapping, data):
137 def runstring(context, mapping, data):
138 return data.decode("string-escape")
138 return data.decode("string-escape")
139
139
140 def runrawstring(context, mapping, data):
140 def runrawstring(context, mapping, data):
141 return data
141 return data
142
142
143 def runsymbol(context, mapping, key):
143 def runsymbol(context, mapping, key):
144 v = mapping.get(key)
144 v = mapping.get(key)
145 if v is None:
145 if v is None:
146 v = context._defaults.get(key)
146 v = context._defaults.get(key)
147 if v is None:
147 if v is None:
148 try:
148 try:
149 v = context.process(key, mapping)
149 v = context.process(key, mapping)
150 except TemplateNotFound:
150 except TemplateNotFound:
151 v = ''
151 v = ''
152 if callable(v):
152 if callable(v):
153 return v(**mapping)
153 return v(**mapping)
154 if isinstance(v, types.GeneratorType):
154 if isinstance(v, types.GeneratorType):
155 v = list(v)
155 v = list(v)
156 mapping[key] = v
156 mapping[key] = v
157 return v
157 return v
158 return v
158 return v
159
159
160 def buildfilter(exp, context):
160 def buildfilter(exp, context):
161 func, data = compileexp(exp[1], context)
161 func, data = compileexp(exp[1], context)
162 filt = getfilter(exp[2], context)
162 filt = getfilter(exp[2], context)
163 return (runfilter, (func, data, filt))
163 return (runfilter, (func, data, filt))
164
164
165 def runfilter(context, mapping, data):
165 def runfilter(context, mapping, data):
166 func, data, filt = data
166 func, data, filt = data
167 try:
167 try:
168 return filt(func(context, mapping, data))
168 return filt(func(context, mapping, data))
169 except (ValueError, AttributeError, TypeError):
169 except (ValueError, AttributeError, TypeError):
170 if isinstance(data, tuple):
170 if isinstance(data, tuple):
171 dt = data[1]
171 dt = data[1]
172 else:
172 else:
173 dt = data
173 dt = data
174 raise util.Abort(_("template filter '%s' is not compatible with "
174 raise util.Abort(_("template filter '%s' is not compatible with "
175 "keyword '%s'") % (filt.func_name, dt))
175 "keyword '%s'") % (filt.func_name, dt))
176
176
177 def buildmap(exp, context):
177 def buildmap(exp, context):
178 func, data = compileexp(exp[1], context)
178 func, data = compileexp(exp[1], context)
179 ctmpl = gettemplate(exp[2], context)
179 ctmpl = gettemplate(exp[2], context)
180 return (runmap, (func, data, ctmpl))
180 return (runmap, (func, data, ctmpl))
181
181
182 def runtemplate(context, mapping, template):
182 def runtemplate(context, mapping, template):
183 for func, data in template:
183 for func, data in template:
184 yield func(context, mapping, data)
184 yield func(context, mapping, data)
185
185
186 def runmap(context, mapping, data):
186 def runmap(context, mapping, data):
187 func, data, ctmpl = data
187 func, data, ctmpl = data
188 d = func(context, mapping, data)
188 d = func(context, mapping, data)
189 if callable(d):
189 if callable(d):
190 d = d()
190 d = d()
191
191
192 lm = mapping.copy()
192 lm = mapping.copy()
193
193
194 for i in d:
194 for i in d:
195 if isinstance(i, dict):
195 if isinstance(i, dict):
196 lm.update(i)
196 lm.update(i)
197 lm['originalnode'] = mapping.get('node')
197 lm['originalnode'] = mapping.get('node')
198 yield runtemplate(context, lm, ctmpl)
198 yield runtemplate(context, lm, ctmpl)
199 else:
199 else:
200 # v is not an iterable of dicts, this happen when 'key'
200 # v is not an iterable of dicts, this happen when 'key'
201 # has been fully expanded already and format is useless.
201 # has been fully expanded already and format is useless.
202 # If so, return the expanded value.
202 # If so, return the expanded value.
203 yield i
203 yield i
204
204
205 def buildfunc(exp, context):
205 def buildfunc(exp, context):
206 n = getsymbol(exp[1])
206 n = getsymbol(exp[1])
207 args = [compileexp(x, context) for x in getlist(exp[2])]
207 args = [compileexp(x, context) for x in getlist(exp[2])]
208 if n in funcs:
208 if n in funcs:
209 f = funcs[n]
209 f = funcs[n]
210 return (f, args)
210 return (f, args)
211 if n in context._filters:
211 if n in context._filters:
212 if len(args) != 1:
212 if len(args) != 1:
213 raise error.ParseError(_("filter %s expects one argument") % n)
213 raise error.ParseError(_("filter %s expects one argument") % n)
214 f = context._filters[n]
214 f = context._filters[n]
215 return (runfilter, (args[0][0], args[0][1], f))
215 return (runfilter, (args[0][0], args[0][1], f))
216 raise error.ParseError(_("unknown function '%s'") % n)
216 raise error.ParseError(_("unknown function '%s'") % n)
217
217
218 def date(context, mapping, args):
218 def date(context, mapping, args):
219 if not (1 <= len(args) <= 2):
219 if not (1 <= len(args) <= 2):
220 raise error.ParseError(_("date expects one or two arguments"))
220 raise error.ParseError(_("date expects one or two arguments"))
221
221
222 date = args[0][0](context, mapping, args[0][1])
222 date = args[0][0](context, mapping, args[0][1])
223 if len(args) == 2:
223 if len(args) == 2:
224 fmt = stringify(args[1][0](context, mapping, args[1][1]))
224 fmt = stringify(args[1][0](context, mapping, args[1][1]))
225 return util.datestr(date, fmt)
225 return util.datestr(date, fmt)
226 return util.datestr(date)
226 return util.datestr(date)
227
227
228 def diff(context, mapping, args):
229 if len(args) > 2:
230 # i18n: "diff" is a keyword
231 raise error.ParseError(_("diff expects one, two or no arguments"))
232
233 def getpatterns(i):
234 if i < len(args):
235 s = args[i][1].strip()
236 if s:
237 return [s]
238 return []
239
240 ctx = mapping['ctx']
241 chunks = ctx.diff(match=ctx.match([], getpatterns(0), getpatterns(1)))
242
243 return ''.join(chunks)
244
228 def fill(context, mapping, args):
245 def fill(context, mapping, args):
229 if not (1 <= len(args) <= 4):
246 if not (1 <= len(args) <= 4):
230 raise error.ParseError(_("fill expects one to four arguments"))
247 raise error.ParseError(_("fill expects one to four arguments"))
231
248
232 text = stringify(args[0][0](context, mapping, args[0][1]))
249 text = stringify(args[0][0](context, mapping, args[0][1]))
233 width = 76
250 width = 76
234 initindent = ''
251 initindent = ''
235 hangindent = ''
252 hangindent = ''
236 if 2 <= len(args) <= 4:
253 if 2 <= len(args) <= 4:
237 try:
254 try:
238 width = int(stringify(args[1][0](context, mapping, args[1][1])))
255 width = int(stringify(args[1][0](context, mapping, args[1][1])))
239 except ValueError:
256 except ValueError:
240 raise error.ParseError(_("fill expects an integer width"))
257 raise error.ParseError(_("fill expects an integer width"))
241 try:
258 try:
242 initindent = stringify(_evalifliteral(args[2], context, mapping))
259 initindent = stringify(_evalifliteral(args[2], context, mapping))
243 hangindent = stringify(_evalifliteral(args[3], context, mapping))
260 hangindent = stringify(_evalifliteral(args[3], context, mapping))
244 except IndexError:
261 except IndexError:
245 pass
262 pass
246
263
247 return templatefilters.fill(text, width, initindent, hangindent)
264 return templatefilters.fill(text, width, initindent, hangindent)
248
265
249 def pad(context, mapping, args):
266 def pad(context, mapping, args):
250 """usage: pad(text, width, fillchar=' ', right=False)
267 """usage: pad(text, width, fillchar=' ', right=False)
251 """
268 """
252 if not (2 <= len(args) <= 4):
269 if not (2 <= len(args) <= 4):
253 raise error.ParseError(_("pad() expects two to four arguments"))
270 raise error.ParseError(_("pad() expects two to four arguments"))
254
271
255 width = int(args[1][1])
272 width = int(args[1][1])
256
273
257 text = stringify(args[0][0](context, mapping, args[0][1]))
274 text = stringify(args[0][0](context, mapping, args[0][1]))
258 if args[0][0] == runstring:
275 if args[0][0] == runstring:
259 text = stringify(runtemplate(context, mapping,
276 text = stringify(runtemplate(context, mapping,
260 compiletemplate(text, context)))
277 compiletemplate(text, context)))
261
278
262 right = False
279 right = False
263 fillchar = ' '
280 fillchar = ' '
264 if len(args) > 2:
281 if len(args) > 2:
265 fillchar = stringify(args[2][0](context, mapping, args[2][1]))
282 fillchar = stringify(args[2][0](context, mapping, args[2][1]))
266 if len(args) > 3:
283 if len(args) > 3:
267 right = util.parsebool(args[3][1])
284 right = util.parsebool(args[3][1])
268
285
269 if right:
286 if right:
270 return text.rjust(width, fillchar)
287 return text.rjust(width, fillchar)
271 else:
288 else:
272 return text.ljust(width, fillchar)
289 return text.ljust(width, fillchar)
273
290
274 def get(context, mapping, args):
291 def get(context, mapping, args):
275 if len(args) != 2:
292 if len(args) != 2:
276 # i18n: "get" is a keyword
293 # i18n: "get" is a keyword
277 raise error.ParseError(_("get() expects two arguments"))
294 raise error.ParseError(_("get() expects two arguments"))
278
295
279 dictarg = args[0][0](context, mapping, args[0][1])
296 dictarg = args[0][0](context, mapping, args[0][1])
280 if not util.safehasattr(dictarg, 'get'):
297 if not util.safehasattr(dictarg, 'get'):
281 # i18n: "get" is a keyword
298 # i18n: "get" is a keyword
282 raise error.ParseError(_("get() expects a dict as first argument"))
299 raise error.ParseError(_("get() expects a dict as first argument"))
283
300
284 key = args[1][0](context, mapping, args[1][1])
301 key = args[1][0](context, mapping, args[1][1])
285 yield dictarg.get(key)
302 yield dictarg.get(key)
286
303
287 def _evalifliteral(arg, context, mapping):
304 def _evalifliteral(arg, context, mapping):
288 t = stringify(arg[0](context, mapping, arg[1]))
305 t = stringify(arg[0](context, mapping, arg[1]))
289 if arg[0] == runstring or arg[0] == runrawstring:
306 if arg[0] == runstring or arg[0] == runrawstring:
290 yield runtemplate(context, mapping,
307 yield runtemplate(context, mapping,
291 compiletemplate(t, context, strtoken='rawstring'))
308 compiletemplate(t, context, strtoken='rawstring'))
292 else:
309 else:
293 yield t
310 yield t
294
311
295 def if_(context, mapping, args):
312 def if_(context, mapping, args):
296 if not (2 <= len(args) <= 3):
313 if not (2 <= len(args) <= 3):
297 # i18n: "if" is a keyword
314 # i18n: "if" is a keyword
298 raise error.ParseError(_("if expects two or three arguments"))
315 raise error.ParseError(_("if expects two or three arguments"))
299
316
300 test = stringify(args[0][0](context, mapping, args[0][1]))
317 test = stringify(args[0][0](context, mapping, args[0][1]))
301 if test:
318 if test:
302 yield _evalifliteral(args[1], context, mapping)
319 yield _evalifliteral(args[1], context, mapping)
303 elif len(args) == 3:
320 elif len(args) == 3:
304 yield _evalifliteral(args[2], context, mapping)
321 yield _evalifliteral(args[2], context, mapping)
305
322
306 def ifcontains(context, mapping, args):
323 def ifcontains(context, mapping, args):
307 if not (3 <= len(args) <= 4):
324 if not (3 <= len(args) <= 4):
308 # i18n: "ifcontains" is a keyword
325 # i18n: "ifcontains" is a keyword
309 raise error.ParseError(_("ifcontains expects three or four arguments"))
326 raise error.ParseError(_("ifcontains expects three or four arguments"))
310
327
311 item = stringify(args[0][0](context, mapping, args[0][1]))
328 item = stringify(args[0][0](context, mapping, args[0][1]))
312 items = args[1][0](context, mapping, args[1][1])
329 items = args[1][0](context, mapping, args[1][1])
313
330
314 # Iterating over items gives a formatted string, so we iterate
331 # Iterating over items gives a formatted string, so we iterate
315 # directly over the raw values.
332 # directly over the raw values.
316 if item in [i.values()[0] for i in items()]:
333 if item in [i.values()[0] for i in items()]:
317 yield _evalifliteral(args[2], context, mapping)
334 yield _evalifliteral(args[2], context, mapping)
318 elif len(args) == 4:
335 elif len(args) == 4:
319 yield _evalifliteral(args[3], context, mapping)
336 yield _evalifliteral(args[3], context, mapping)
320
337
321 def ifeq(context, mapping, args):
338 def ifeq(context, mapping, args):
322 if not (3 <= len(args) <= 4):
339 if not (3 <= len(args) <= 4):
323 # i18n: "ifeq" is a keyword
340 # i18n: "ifeq" is a keyword
324 raise error.ParseError(_("ifeq expects three or four arguments"))
341 raise error.ParseError(_("ifeq expects three or four arguments"))
325
342
326 test = stringify(args[0][0](context, mapping, args[0][1]))
343 test = stringify(args[0][0](context, mapping, args[0][1]))
327 match = stringify(args[1][0](context, mapping, args[1][1]))
344 match = stringify(args[1][0](context, mapping, args[1][1]))
328 if test == match:
345 if test == match:
329 yield _evalifliteral(args[2], context, mapping)
346 yield _evalifliteral(args[2], context, mapping)
330 elif len(args) == 4:
347 elif len(args) == 4:
331 yield _evalifliteral(args[3], context, mapping)
348 yield _evalifliteral(args[3], context, mapping)
332
349
333 def join(context, mapping, args):
350 def join(context, mapping, args):
334 if not (1 <= len(args) <= 2):
351 if not (1 <= len(args) <= 2):
335 # i18n: "join" is a keyword
352 # i18n: "join" is a keyword
336 raise error.ParseError(_("join expects one or two arguments"))
353 raise error.ParseError(_("join expects one or two arguments"))
337
354
338 joinset = args[0][0](context, mapping, args[0][1])
355 joinset = args[0][0](context, mapping, args[0][1])
339 if callable(joinset):
356 if callable(joinset):
340 jf = joinset.joinfmt
357 jf = joinset.joinfmt
341 joinset = [jf(x) for x in joinset()]
358 joinset = [jf(x) for x in joinset()]
342
359
343 joiner = " "
360 joiner = " "
344 if len(args) > 1:
361 if len(args) > 1:
345 joiner = stringify(args[1][0](context, mapping, args[1][1]))
362 joiner = stringify(args[1][0](context, mapping, args[1][1]))
346
363
347 first = True
364 first = True
348 for x in joinset:
365 for x in joinset:
349 if first:
366 if first:
350 first = False
367 first = False
351 else:
368 else:
352 yield joiner
369 yield joiner
353 yield x
370 yield x
354
371
355 def label(context, mapping, args):
372 def label(context, mapping, args):
356 if len(args) != 2:
373 if len(args) != 2:
357 # i18n: "label" is a keyword
374 # i18n: "label" is a keyword
358 raise error.ParseError(_("label expects two arguments"))
375 raise error.ParseError(_("label expects two arguments"))
359
376
360 # ignore args[0] (the label string) since this is supposed to be a a no-op
377 # ignore args[0] (the label string) since this is supposed to be a a no-op
361 yield _evalifliteral(args[1], context, mapping)
378 yield _evalifliteral(args[1], context, mapping)
362
379
363 def revset(context, mapping, args):
380 def revset(context, mapping, args):
364 """usage: revset(query[, formatargs...])
381 """usage: revset(query[, formatargs...])
365 """
382 """
366 if not len(args) > 0:
383 if not len(args) > 0:
367 # i18n: "revset" is a keyword
384 # i18n: "revset" is a keyword
368 raise error.ParseError(_("revset expects one or more arguments"))
385 raise error.ParseError(_("revset expects one or more arguments"))
369
386
370 raw = args[0][1]
387 raw = args[0][1]
371 ctx = mapping['ctx']
388 ctx = mapping['ctx']
372 repo = ctx._repo
389 repo = ctx._repo
373
390
374 def query(expr):
391 def query(expr):
375 m = revsetmod.match(repo.ui, expr)
392 m = revsetmod.match(repo.ui, expr)
376 return m(repo, revsetmod.spanset(repo))
393 return m(repo, revsetmod.spanset(repo))
377
394
378 if len(args) > 1:
395 if len(args) > 1:
379 formatargs = list([a[0](context, mapping, a[1]) for a in args[1:]])
396 formatargs = list([a[0](context, mapping, a[1]) for a in args[1:]])
380 revs = query(revsetmod.formatspec(raw, *formatargs))
397 revs = query(revsetmod.formatspec(raw, *formatargs))
381 revs = list([str(r) for r in revs])
398 revs = list([str(r) for r in revs])
382 else:
399 else:
383 revsetcache = mapping['cache'].setdefault("revsetcache", {})
400 revsetcache = mapping['cache'].setdefault("revsetcache", {})
384 if raw in revsetcache:
401 if raw in revsetcache:
385 revs = revsetcache[raw]
402 revs = revsetcache[raw]
386 else:
403 else:
387 revs = query(raw)
404 revs = query(raw)
388 revs = list([str(r) for r in revs])
405 revs = list([str(r) for r in revs])
389 revsetcache[raw] = revs
406 revsetcache[raw] = revs
390
407
391 return templatekw.showlist("revision", revs, **mapping)
408 return templatekw.showlist("revision", revs, **mapping)
392
409
393 def rstdoc(context, mapping, args):
410 def rstdoc(context, mapping, args):
394 if len(args) != 2:
411 if len(args) != 2:
395 # i18n: "rstdoc" is a keyword
412 # i18n: "rstdoc" is a keyword
396 raise error.ParseError(_("rstdoc expects two arguments"))
413 raise error.ParseError(_("rstdoc expects two arguments"))
397
414
398 text = stringify(args[0][0](context, mapping, args[0][1]))
415 text = stringify(args[0][0](context, mapping, args[0][1]))
399 style = stringify(args[1][0](context, mapping, args[1][1]))
416 style = stringify(args[1][0](context, mapping, args[1][1]))
400
417
401 return minirst.format(text, style=style, keep=['verbose'])
418 return minirst.format(text, style=style, keep=['verbose'])
402
419
403 def shortest(context, mapping, args):
420 def shortest(context, mapping, args):
404 """usage: shortest(node, minlength=4)
421 """usage: shortest(node, minlength=4)
405 """
422 """
406 if not (1 <= len(args) <= 2):
423 if not (1 <= len(args) <= 2):
407 raise error.ParseError(_("shortest() expects one or two arguments"))
424 raise error.ParseError(_("shortest() expects one or two arguments"))
408
425
409 node = stringify(args[0][0](context, mapping, args[0][1]))
426 node = stringify(args[0][0](context, mapping, args[0][1]))
410
427
411 minlength = 4
428 minlength = 4
412 if len(args) > 1:
429 if len(args) > 1:
413 minlength = int(args[1][1])
430 minlength = int(args[1][1])
414
431
415 cl = mapping['ctx']._repo.changelog
432 cl = mapping['ctx']._repo.changelog
416 def isvalid(test):
433 def isvalid(test):
417 try:
434 try:
418 try:
435 try:
419 cl.index.partialmatch(test)
436 cl.index.partialmatch(test)
420 except AttributeError:
437 except AttributeError:
421 # Pure mercurial doesn't support partialmatch on the index.
438 # Pure mercurial doesn't support partialmatch on the index.
422 # Fallback to the slow way.
439 # Fallback to the slow way.
423 if cl._partialmatch(test) is None:
440 if cl._partialmatch(test) is None:
424 return False
441 return False
425
442
426 try:
443 try:
427 i = int(test)
444 i = int(test)
428 # if we are a pure int, then starting with zero will not be
445 # if we are a pure int, then starting with zero will not be
429 # confused as a rev; or, obviously, if the int is larger than
446 # confused as a rev; or, obviously, if the int is larger than
430 # the value of the tip rev
447 # the value of the tip rev
431 if test[0] == '0' or i > len(cl):
448 if test[0] == '0' or i > len(cl):
432 return True
449 return True
433 return False
450 return False
434 except ValueError:
451 except ValueError:
435 return True
452 return True
436 except error.RevlogError:
453 except error.RevlogError:
437 return False
454 return False
438
455
439 shortest = node
456 shortest = node
440 startlength = max(6, minlength)
457 startlength = max(6, minlength)
441 length = startlength
458 length = startlength
442 while True:
459 while True:
443 test = node[:length]
460 test = node[:length]
444 if isvalid(test):
461 if isvalid(test):
445 shortest = test
462 shortest = test
446 if length == minlength or length > startlength:
463 if length == minlength or length > startlength:
447 return shortest
464 return shortest
448 length -= 1
465 length -= 1
449 else:
466 else:
450 length += 1
467 length += 1
451 if len(shortest) <= length:
468 if len(shortest) <= length:
452 return shortest
469 return shortest
453
470
454 def strip(context, mapping, args):
471 def strip(context, mapping, args):
455 if not (1 <= len(args) <= 2):
472 if not (1 <= len(args) <= 2):
456 raise error.ParseError(_("strip expects one or two arguments"))
473 raise error.ParseError(_("strip expects one or two arguments"))
457
474
458 text = stringify(args[0][0](context, mapping, args[0][1]))
475 text = stringify(args[0][0](context, mapping, args[0][1]))
459 if len(args) == 2:
476 if len(args) == 2:
460 chars = stringify(args[1][0](context, mapping, args[1][1]))
477 chars = stringify(args[1][0](context, mapping, args[1][1]))
461 return text.strip(chars)
478 return text.strip(chars)
462 return text.strip()
479 return text.strip()
463
480
464 def sub(context, mapping, args):
481 def sub(context, mapping, args):
465 if len(args) != 3:
482 if len(args) != 3:
466 # i18n: "sub" is a keyword
483 # i18n: "sub" is a keyword
467 raise error.ParseError(_("sub expects three arguments"))
484 raise error.ParseError(_("sub expects three arguments"))
468
485
469 pat = stringify(args[0][0](context, mapping, args[0][1]))
486 pat = stringify(args[0][0](context, mapping, args[0][1]))
470 rpl = stringify(args[1][0](context, mapping, args[1][1]))
487 rpl = stringify(args[1][0](context, mapping, args[1][1]))
471 src = stringify(_evalifliteral(args[2], context, mapping))
488 src = stringify(_evalifliteral(args[2], context, mapping))
472 yield re.sub(pat, rpl, src)
489 yield re.sub(pat, rpl, src)
473
490
474 def startswith(context, mapping, args):
491 def startswith(context, mapping, args):
475 if len(args) != 2:
492 if len(args) != 2:
476 # i18n: "startswith" is a keyword
493 # i18n: "startswith" is a keyword
477 raise error.ParseError(_("startswith expects two arguments"))
494 raise error.ParseError(_("startswith expects two arguments"))
478
495
479 patn = stringify(args[0][0](context, mapping, args[0][1]))
496 patn = stringify(args[0][0](context, mapping, args[0][1]))
480 text = stringify(args[1][0](context, mapping, args[1][1]))
497 text = stringify(args[1][0](context, mapping, args[1][1]))
481 if text.startswith(patn):
498 if text.startswith(patn):
482 return text
499 return text
483 return ''
500 return ''
484
501
485
502
486 def word(context, mapping, args):
503 def word(context, mapping, args):
487 """return nth word from a string"""
504 """return nth word from a string"""
488 if not (2 <= len(args) <= 3):
505 if not (2 <= len(args) <= 3):
489 # i18n: "word" is a keyword
506 # i18n: "word" is a keyword
490 raise error.ParseError(_("word expects two or three arguments, got %d")
507 raise error.ParseError(_("word expects two or three arguments, got %d")
491 % len(args))
508 % len(args))
492
509
493 num = int(stringify(args[0][0](context, mapping, args[0][1])))
510 num = int(stringify(args[0][0](context, mapping, args[0][1])))
494 text = stringify(args[1][0](context, mapping, args[1][1]))
511 text = stringify(args[1][0](context, mapping, args[1][1]))
495 if len(args) == 3:
512 if len(args) == 3:
496 splitter = stringify(args[2][0](context, mapping, args[2][1]))
513 splitter = stringify(args[2][0](context, mapping, args[2][1]))
497 else:
514 else:
498 splitter = None
515 splitter = None
499
516
500 tokens = text.split(splitter)
517 tokens = text.split(splitter)
501 if num >= len(tokens):
518 if num >= len(tokens):
502 return ''
519 return ''
503 else:
520 else:
504 return tokens[num]
521 return tokens[num]
505
522
506 methods = {
523 methods = {
507 "string": lambda e, c: (runstring, e[1]),
524 "string": lambda e, c: (runstring, e[1]),
508 "rawstring": lambda e, c: (runrawstring, e[1]),
525 "rawstring": lambda e, c: (runrawstring, e[1]),
509 "symbol": lambda e, c: (runsymbol, e[1]),
526 "symbol": lambda e, c: (runsymbol, e[1]),
510 "group": lambda e, c: compileexp(e[1], c),
527 "group": lambda e, c: compileexp(e[1], c),
511 # ".": buildmember,
528 # ".": buildmember,
512 "|": buildfilter,
529 "|": buildfilter,
513 "%": buildmap,
530 "%": buildmap,
514 "func": buildfunc,
531 "func": buildfunc,
515 }
532 }
516
533
517 funcs = {
534 funcs = {
518 "date": date,
535 "date": date,
536 "diff": diff,
519 "fill": fill,
537 "fill": fill,
520 "get": get,
538 "get": get,
521 "if": if_,
539 "if": if_,
522 "ifcontains": ifcontains,
540 "ifcontains": ifcontains,
523 "ifeq": ifeq,
541 "ifeq": ifeq,
524 "join": join,
542 "join": join,
525 "label": label,
543 "label": label,
526 "pad": pad,
544 "pad": pad,
527 "revset": revset,
545 "revset": revset,
528 "rstdoc": rstdoc,
546 "rstdoc": rstdoc,
529 "shortest": shortest,
547 "shortest": shortest,
530 "startswith": startswith,
548 "startswith": startswith,
531 "strip": strip,
549 "strip": strip,
532 "sub": sub,
550 "sub": sub,
533 "word": word,
551 "word": word,
534 }
552 }
535
553
536 # template engine
554 # template engine
537
555
538 path = ['templates', '../templates']
556 path = ['templates', '../templates']
539 stringify = templatefilters.stringify
557 stringify = templatefilters.stringify
540
558
541 def _flatten(thing):
559 def _flatten(thing):
542 '''yield a single stream from a possibly nested set of iterators'''
560 '''yield a single stream from a possibly nested set of iterators'''
543 if isinstance(thing, str):
561 if isinstance(thing, str):
544 yield thing
562 yield thing
545 elif not util.safehasattr(thing, '__iter__'):
563 elif not util.safehasattr(thing, '__iter__'):
546 if thing is not None:
564 if thing is not None:
547 yield str(thing)
565 yield str(thing)
548 else:
566 else:
549 for i in thing:
567 for i in thing:
550 if isinstance(i, str):
568 if isinstance(i, str):
551 yield i
569 yield i
552 elif not util.safehasattr(i, '__iter__'):
570 elif not util.safehasattr(i, '__iter__'):
553 if i is not None:
571 if i is not None:
554 yield str(i)
572 yield str(i)
555 elif i is not None:
573 elif i is not None:
556 for j in _flatten(i):
574 for j in _flatten(i):
557 yield j
575 yield j
558
576
559 def parsestring(s, quoted=True):
577 def parsestring(s, quoted=True):
560 '''parse a string using simple c-like syntax.
578 '''parse a string using simple c-like syntax.
561 string must be in quotes if quoted is True.'''
579 string must be in quotes if quoted is True.'''
562 if quoted:
580 if quoted:
563 if len(s) < 2 or s[0] != s[-1]:
581 if len(s) < 2 or s[0] != s[-1]:
564 raise SyntaxError(_('unmatched quotes'))
582 raise SyntaxError(_('unmatched quotes'))
565 return s[1:-1].decode('string_escape')
583 return s[1:-1].decode('string_escape')
566
584
567 return s.decode('string_escape')
585 return s.decode('string_escape')
568
586
569 class engine(object):
587 class engine(object):
570 '''template expansion engine.
588 '''template expansion engine.
571
589
572 template expansion works like this. a map file contains key=value
590 template expansion works like this. a map file contains key=value
573 pairs. if value is quoted, it is treated as string. otherwise, it
591 pairs. if value is quoted, it is treated as string. otherwise, it
574 is treated as name of template file.
592 is treated as name of template file.
575
593
576 templater is asked to expand a key in map. it looks up key, and
594 templater is asked to expand a key in map. it looks up key, and
577 looks for strings like this: {foo}. it expands {foo} by looking up
595 looks for strings like this: {foo}. it expands {foo} by looking up
578 foo in map, and substituting it. expansion is recursive: it stops
596 foo in map, and substituting it. expansion is recursive: it stops
579 when there is no more {foo} to replace.
597 when there is no more {foo} to replace.
580
598
581 expansion also allows formatting and filtering.
599 expansion also allows formatting and filtering.
582
600
583 format uses key to expand each item in list. syntax is
601 format uses key to expand each item in list. syntax is
584 {key%format}.
602 {key%format}.
585
603
586 filter uses function to transform value. syntax is
604 filter uses function to transform value. syntax is
587 {key|filter1|filter2|...}.'''
605 {key|filter1|filter2|...}.'''
588
606
589 def __init__(self, loader, filters={}, defaults={}):
607 def __init__(self, loader, filters={}, defaults={}):
590 self._loader = loader
608 self._loader = loader
591 self._filters = filters
609 self._filters = filters
592 self._defaults = defaults
610 self._defaults = defaults
593 self._cache = {}
611 self._cache = {}
594
612
595 def _load(self, t):
613 def _load(self, t):
596 '''load, parse, and cache a template'''
614 '''load, parse, and cache a template'''
597 if t not in self._cache:
615 if t not in self._cache:
598 self._cache[t] = compiletemplate(self._loader(t), self)
616 self._cache[t] = compiletemplate(self._loader(t), self)
599 return self._cache[t]
617 return self._cache[t]
600
618
601 def process(self, t, mapping):
619 def process(self, t, mapping):
602 '''Perform expansion. t is name of map element to expand.
620 '''Perform expansion. t is name of map element to expand.
603 mapping contains added elements for use during expansion. Is a
621 mapping contains added elements for use during expansion. Is a
604 generator.'''
622 generator.'''
605 return _flatten(runtemplate(self, mapping, self._load(t)))
623 return _flatten(runtemplate(self, mapping, self._load(t)))
606
624
607 engines = {'default': engine}
625 engines = {'default': engine}
608
626
609 def stylelist():
627 def stylelist():
610 paths = templatepath()
628 paths = templatepath()
611 if not paths:
629 if not paths:
612 return _('no templates found, try `hg debuginstall` for more info')
630 return _('no templates found, try `hg debuginstall` for more info')
613 dirlist = os.listdir(paths[0])
631 dirlist = os.listdir(paths[0])
614 stylelist = []
632 stylelist = []
615 for file in dirlist:
633 for file in dirlist:
616 split = file.split(".")
634 split = file.split(".")
617 if split[0] == "map-cmdline":
635 if split[0] == "map-cmdline":
618 stylelist.append(split[1])
636 stylelist.append(split[1])
619 return ", ".join(sorted(stylelist))
637 return ", ".join(sorted(stylelist))
620
638
621 class TemplateNotFound(util.Abort):
639 class TemplateNotFound(util.Abort):
622 pass
640 pass
623
641
624 class templater(object):
642 class templater(object):
625
643
626 def __init__(self, mapfile, filters={}, defaults={}, cache={},
644 def __init__(self, mapfile, filters={}, defaults={}, cache={},
627 minchunk=1024, maxchunk=65536):
645 minchunk=1024, maxchunk=65536):
628 '''set up template engine.
646 '''set up template engine.
629 mapfile is name of file to read map definitions from.
647 mapfile is name of file to read map definitions from.
630 filters is dict of functions. each transforms a value into another.
648 filters is dict of functions. each transforms a value into another.
631 defaults is dict of default map definitions.'''
649 defaults is dict of default map definitions.'''
632 self.mapfile = mapfile or 'template'
650 self.mapfile = mapfile or 'template'
633 self.cache = cache.copy()
651 self.cache = cache.copy()
634 self.map = {}
652 self.map = {}
635 self.base = (mapfile and os.path.dirname(mapfile)) or ''
653 self.base = (mapfile and os.path.dirname(mapfile)) or ''
636 self.filters = templatefilters.filters.copy()
654 self.filters = templatefilters.filters.copy()
637 self.filters.update(filters)
655 self.filters.update(filters)
638 self.defaults = defaults
656 self.defaults = defaults
639 self.minchunk, self.maxchunk = minchunk, maxchunk
657 self.minchunk, self.maxchunk = minchunk, maxchunk
640 self.ecache = {}
658 self.ecache = {}
641
659
642 if not mapfile:
660 if not mapfile:
643 return
661 return
644 if not os.path.exists(mapfile):
662 if not os.path.exists(mapfile):
645 raise util.Abort(_("style '%s' not found") % mapfile,
663 raise util.Abort(_("style '%s' not found") % mapfile,
646 hint=_("available styles: %s") % stylelist())
664 hint=_("available styles: %s") % stylelist())
647
665
648 conf = config.config()
666 conf = config.config()
649 conf.read(mapfile)
667 conf.read(mapfile)
650
668
651 for key, val in conf[''].items():
669 for key, val in conf[''].items():
652 if not val:
670 if not val:
653 raise SyntaxError(_('%s: missing value') % conf.source('', key))
671 raise SyntaxError(_('%s: missing value') % conf.source('', key))
654 if val[0] in "'\"":
672 if val[0] in "'\"":
655 try:
673 try:
656 self.cache[key] = parsestring(val)
674 self.cache[key] = parsestring(val)
657 except SyntaxError, inst:
675 except SyntaxError, inst:
658 raise SyntaxError('%s: %s' %
676 raise SyntaxError('%s: %s' %
659 (conf.source('', key), inst.args[0]))
677 (conf.source('', key), inst.args[0]))
660 else:
678 else:
661 val = 'default', val
679 val = 'default', val
662 if ':' in val[1]:
680 if ':' in val[1]:
663 val = val[1].split(':', 1)
681 val = val[1].split(':', 1)
664 self.map[key] = val[0], os.path.join(self.base, val[1])
682 self.map[key] = val[0], os.path.join(self.base, val[1])
665
683
666 def __contains__(self, key):
684 def __contains__(self, key):
667 return key in self.cache or key in self.map
685 return key in self.cache or key in self.map
668
686
669 def load(self, t):
687 def load(self, t):
670 '''Get the template for the given template name. Use a local cache.'''
688 '''Get the template for the given template name. Use a local cache.'''
671 if t not in self.cache:
689 if t not in self.cache:
672 try:
690 try:
673 self.cache[t] = util.readfile(self.map[t][1])
691 self.cache[t] = util.readfile(self.map[t][1])
674 except KeyError, inst:
692 except KeyError, inst:
675 raise TemplateNotFound(_('"%s" not in template map') %
693 raise TemplateNotFound(_('"%s" not in template map') %
676 inst.args[0])
694 inst.args[0])
677 except IOError, inst:
695 except IOError, inst:
678 raise IOError(inst.args[0], _('template file %s: %s') %
696 raise IOError(inst.args[0], _('template file %s: %s') %
679 (self.map[t][1], inst.args[1]))
697 (self.map[t][1], inst.args[1]))
680 return self.cache[t]
698 return self.cache[t]
681
699
682 def __call__(self, t, **mapping):
700 def __call__(self, t, **mapping):
683 ttype = t in self.map and self.map[t][0] or 'default'
701 ttype = t in self.map and self.map[t][0] or 'default'
684 if ttype not in self.ecache:
702 if ttype not in self.ecache:
685 self.ecache[ttype] = engines[ttype](self.load,
703 self.ecache[ttype] = engines[ttype](self.load,
686 self.filters, self.defaults)
704 self.filters, self.defaults)
687 proc = self.ecache[ttype]
705 proc = self.ecache[ttype]
688
706
689 stream = proc.process(t, mapping)
707 stream = proc.process(t, mapping)
690 if self.minchunk:
708 if self.minchunk:
691 stream = util.increasingchunks(stream, min=self.minchunk,
709 stream = util.increasingchunks(stream, min=self.minchunk,
692 max=self.maxchunk)
710 max=self.maxchunk)
693 return stream
711 return stream
694
712
695 def templatepath(name=None):
713 def templatepath(name=None):
696 '''return location of template file or directory (if no name).
714 '''return location of template file or directory (if no name).
697 returns None if not found.'''
715 returns None if not found.'''
698 normpaths = []
716 normpaths = []
699
717
700 # executable version (py2exe) doesn't support __file__
718 # executable version (py2exe) doesn't support __file__
701 if util.mainfrozen():
719 if util.mainfrozen():
702 module = sys.executable
720 module = sys.executable
703 else:
721 else:
704 module = __file__
722 module = __file__
705 for f in path:
723 for f in path:
706 if f.startswith('/'):
724 if f.startswith('/'):
707 p = f
725 p = f
708 else:
726 else:
709 fl = f.split('/')
727 fl = f.split('/')
710 p = os.path.join(os.path.dirname(module), *fl)
728 p = os.path.join(os.path.dirname(module), *fl)
711 if name:
729 if name:
712 p = os.path.join(p, name)
730 p = os.path.join(p, name)
713 if name and os.path.exists(p):
731 if name and os.path.exists(p):
714 return os.path.normpath(p)
732 return os.path.normpath(p)
715 elif os.path.isdir(p):
733 elif os.path.isdir(p):
716 normpaths.append(os.path.normpath(p))
734 normpaths.append(os.path.normpath(p))
717
735
718 return normpaths
736 return normpaths
719
737
720 def stylemap(styles, paths=None):
738 def stylemap(styles, paths=None):
721 """Return path to mapfile for a given style.
739 """Return path to mapfile for a given style.
722
740
723 Searches mapfile in the following locations:
741 Searches mapfile in the following locations:
724 1. templatepath/style/map
742 1. templatepath/style/map
725 2. templatepath/map-style
743 2. templatepath/map-style
726 3. templatepath/map
744 3. templatepath/map
727 """
745 """
728
746
729 if paths is None:
747 if paths is None:
730 paths = templatepath()
748 paths = templatepath()
731 elif isinstance(paths, str):
749 elif isinstance(paths, str):
732 paths = [paths]
750 paths = [paths]
733
751
734 if isinstance(styles, str):
752 if isinstance(styles, str):
735 styles = [styles]
753 styles = [styles]
736
754
737 for style in styles:
755 for style in styles:
738 if not style:
756 if not style:
739 continue
757 continue
740 locations = [os.path.join(style, 'map'), 'map-' + style]
758 locations = [os.path.join(style, 'map'), 'map-' + style]
741 locations.append('map')
759 locations.append('map')
742
760
743 for path in paths:
761 for path in paths:
744 for location in locations:
762 for location in locations:
745 mapfile = os.path.join(path, location)
763 mapfile = os.path.join(path, location)
746 if os.path.isfile(mapfile):
764 if os.path.isfile(mapfile):
747 return style, mapfile
765 return style, mapfile
748
766
749 raise RuntimeError("No hgweb templates found in %r" % paths)
767 raise RuntimeError("No hgweb templates found in %r" % paths)
@@ -1,2344 +1,2399 b''
1 $ hg init a
1 $ hg init a
2 $ cd a
2 $ cd a
3 $ echo a > a
3 $ echo a > a
4 $ hg add a
4 $ hg add a
5 $ echo line 1 > b
5 $ echo line 1 > b
6 $ echo line 2 >> b
6 $ echo line 2 >> b
7 $ hg commit -l b -d '1000000 0' -u 'User Name <user@hostname>'
7 $ hg commit -l b -d '1000000 0' -u 'User Name <user@hostname>'
8
8
9 $ hg add b
9 $ hg add b
10 $ echo other 1 > c
10 $ echo other 1 > c
11 $ echo other 2 >> c
11 $ echo other 2 >> c
12 $ echo >> c
12 $ echo >> c
13 $ echo other 3 >> c
13 $ echo other 3 >> c
14 $ hg commit -l c -d '1100000 0' -u 'A. N. Other <other@place>'
14 $ hg commit -l c -d '1100000 0' -u 'A. N. Other <other@place>'
15
15
16 $ hg add c
16 $ hg add c
17 $ hg commit -m 'no person' -d '1200000 0' -u 'other@place'
17 $ hg commit -m 'no person' -d '1200000 0' -u 'other@place'
18 $ echo c >> c
18 $ echo c >> c
19 $ hg commit -m 'no user, no domain' -d '1300000 0' -u 'person'
19 $ hg commit -m 'no user, no domain' -d '1300000 0' -u 'person'
20
20
21 $ echo foo > .hg/branch
21 $ echo foo > .hg/branch
22 $ hg commit -m 'new branch' -d '1400000 0' -u 'person'
22 $ hg commit -m 'new branch' -d '1400000 0' -u 'person'
23
23
24 $ hg co -q 3
24 $ hg co -q 3
25 $ echo other 4 >> d
25 $ echo other 4 >> d
26 $ hg add d
26 $ hg add d
27 $ hg commit -m 'new head' -d '1500000 0' -u 'person'
27 $ hg commit -m 'new head' -d '1500000 0' -u 'person'
28
28
29 $ hg merge -q foo
29 $ hg merge -q foo
30 $ hg commit -m 'merge' -d '1500001 0' -u 'person'
30 $ hg commit -m 'merge' -d '1500001 0' -u 'person'
31
31
32 Second branch starting at nullrev:
32 Second branch starting at nullrev:
33
33
34 $ hg update null
34 $ hg update null
35 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
35 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
36 $ echo second > second
36 $ echo second > second
37 $ hg add second
37 $ hg add second
38 $ hg commit -m second -d '1000000 0' -u 'User Name <user@hostname>'
38 $ hg commit -m second -d '1000000 0' -u 'User Name <user@hostname>'
39 created new head
39 created new head
40
40
41 $ echo third > third
41 $ echo third > third
42 $ hg add third
42 $ hg add third
43 $ hg mv second fourth
43 $ hg mv second fourth
44 $ hg commit -m third -d "2020-01-01 10:01"
44 $ hg commit -m third -d "2020-01-01 10:01"
45
45
46 $ hg log --template '{join(file_copies, ",\n")}\n' -r .
46 $ hg log --template '{join(file_copies, ",\n")}\n' -r .
47 fourth (second)
47 fourth (second)
48 $ hg log -T '{file_copies % "{source} -> {name}\n"}' -r .
48 $ hg log -T '{file_copies % "{source} -> {name}\n"}' -r .
49 second -> fourth
49 second -> fourth
50
50
51 Quoting for ui.logtemplate
51 Quoting for ui.logtemplate
52
52
53 $ hg tip --config "ui.logtemplate={rev}\n"
53 $ hg tip --config "ui.logtemplate={rev}\n"
54 8
54 8
55 $ hg tip --config "ui.logtemplate='{rev}\n'"
55 $ hg tip --config "ui.logtemplate='{rev}\n'"
56 8
56 8
57 $ hg tip --config 'ui.logtemplate="{rev}\n"'
57 $ hg tip --config 'ui.logtemplate="{rev}\n"'
58 8
58 8
59
59
60 Make sure user/global hgrc does not affect tests
60 Make sure user/global hgrc does not affect tests
61
61
62 $ echo '[ui]' > .hg/hgrc
62 $ echo '[ui]' > .hg/hgrc
63 $ echo 'logtemplate =' >> .hg/hgrc
63 $ echo 'logtemplate =' >> .hg/hgrc
64 $ echo 'style =' >> .hg/hgrc
64 $ echo 'style =' >> .hg/hgrc
65
65
66 Add some simple styles to settings
66 Add some simple styles to settings
67
67
68 $ echo '[templates]' >> .hg/hgrc
68 $ echo '[templates]' >> .hg/hgrc
69 $ printf 'simple = "{rev}\\n"\n' >> .hg/hgrc
69 $ printf 'simple = "{rev}\\n"\n' >> .hg/hgrc
70 $ printf 'simple2 = {rev}\\n\n' >> .hg/hgrc
70 $ printf 'simple2 = {rev}\\n\n' >> .hg/hgrc
71
71
72 $ hg log -l1 -Tsimple
72 $ hg log -l1 -Tsimple
73 8
73 8
74 $ hg log -l1 -Tsimple2
74 $ hg log -l1 -Tsimple2
75 8
75 8
76
76
77 Test templates and style maps in files:
77 Test templates and style maps in files:
78
78
79 $ echo "{rev}" > tmpl
79 $ echo "{rev}" > tmpl
80 $ hg log -l1 -T./tmpl
80 $ hg log -l1 -T./tmpl
81 8
81 8
82 $ hg log -l1 -Tblah/blah
82 $ hg log -l1 -Tblah/blah
83 blah/blah (no-eol)
83 blah/blah (no-eol)
84
84
85 $ printf 'changeset = "{rev}\\n"\n' > map-simple
85 $ printf 'changeset = "{rev}\\n"\n' > map-simple
86 $ hg log -l1 -T./map-simple
86 $ hg log -l1 -T./map-simple
87 8
87 8
88
88
89 Default style is like normal output:
89 Default style is like normal output:
90
90
91 $ hg log > log.out
91 $ hg log > log.out
92 $ hg log --style default > style.out
92 $ hg log --style default > style.out
93 $ cmp log.out style.out || diff -u log.out style.out
93 $ cmp log.out style.out || diff -u log.out style.out
94
94
95 $ hg log -v > log.out
95 $ hg log -v > log.out
96 $ hg log -v --style default > style.out
96 $ hg log -v --style default > style.out
97 $ cmp log.out style.out || diff -u log.out style.out
97 $ cmp log.out style.out || diff -u log.out style.out
98
98
99 $ hg log --debug > log.out
99 $ hg log --debug > log.out
100 $ hg log --debug --style default > style.out
100 $ hg log --debug --style default > style.out
101 $ cmp log.out style.out || diff -u log.out style.out
101 $ cmp log.out style.out || diff -u log.out style.out
102
102
103 Revision with no copies (used to print a traceback):
103 Revision with no copies (used to print a traceback):
104
104
105 $ hg tip -v --template '\n'
105 $ hg tip -v --template '\n'
106
106
107
107
108 Compact style works:
108 Compact style works:
109
109
110 $ hg log -Tcompact
110 $ hg log -Tcompact
111 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
111 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
112 third
112 third
113
113
114 7:-1 29114dbae42b 1970-01-12 13:46 +0000 user
114 7:-1 29114dbae42b 1970-01-12 13:46 +0000 user
115 second
115 second
116
116
117 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
117 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
118 merge
118 merge
119
119
120 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
120 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
121 new head
121 new head
122
122
123 4 bbe44766e73d 1970-01-17 04:53 +0000 person
123 4 bbe44766e73d 1970-01-17 04:53 +0000 person
124 new branch
124 new branch
125
125
126 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
126 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
127 no user, no domain
127 no user, no domain
128
128
129 2 97054abb4ab8 1970-01-14 21:20 +0000 other
129 2 97054abb4ab8 1970-01-14 21:20 +0000 other
130 no person
130 no person
131
131
132 1 b608e9d1a3f0 1970-01-13 17:33 +0000 other
132 1 b608e9d1a3f0 1970-01-13 17:33 +0000 other
133 other 1
133 other 1
134
134
135 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 user
135 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 user
136 line 1
136 line 1
137
137
138
138
139 $ hg log -v --style compact
139 $ hg log -v --style compact
140 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
140 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
141 third
141 third
142
142
143 7:-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
143 7:-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
144 second
144 second
145
145
146 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
146 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
147 merge
147 merge
148
148
149 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
149 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
150 new head
150 new head
151
151
152 4 bbe44766e73d 1970-01-17 04:53 +0000 person
152 4 bbe44766e73d 1970-01-17 04:53 +0000 person
153 new branch
153 new branch
154
154
155 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
155 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
156 no user, no domain
156 no user, no domain
157
157
158 2 97054abb4ab8 1970-01-14 21:20 +0000 other@place
158 2 97054abb4ab8 1970-01-14 21:20 +0000 other@place
159 no person
159 no person
160
160
161 1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
161 1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
162 other 1
162 other 1
163 other 2
163 other 2
164
164
165 other 3
165 other 3
166
166
167 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
167 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
168 line 1
168 line 1
169 line 2
169 line 2
170
170
171
171
172 $ hg log --debug --style compact
172 $ hg log --debug --style compact
173 8[tip]:7,-1 95c24699272e 2020-01-01 10:01 +0000 test
173 8[tip]:7,-1 95c24699272e 2020-01-01 10:01 +0000 test
174 third
174 third
175
175
176 7:-1,-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
176 7:-1,-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
177 second
177 second
178
178
179 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
179 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
180 merge
180 merge
181
181
182 5:3,-1 13207e5a10d9 1970-01-18 08:40 +0000 person
182 5:3,-1 13207e5a10d9 1970-01-18 08:40 +0000 person
183 new head
183 new head
184
184
185 4:3,-1 bbe44766e73d 1970-01-17 04:53 +0000 person
185 4:3,-1 bbe44766e73d 1970-01-17 04:53 +0000 person
186 new branch
186 new branch
187
187
188 3:2,-1 10e46f2dcbf4 1970-01-16 01:06 +0000 person
188 3:2,-1 10e46f2dcbf4 1970-01-16 01:06 +0000 person
189 no user, no domain
189 no user, no domain
190
190
191 2:1,-1 97054abb4ab8 1970-01-14 21:20 +0000 other@place
191 2:1,-1 97054abb4ab8 1970-01-14 21:20 +0000 other@place
192 no person
192 no person
193
193
194 1:0,-1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
194 1:0,-1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
195 other 1
195 other 1
196 other 2
196 other 2
197
197
198 other 3
198 other 3
199
199
200 0:-1,-1 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
200 0:-1,-1 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
201 line 1
201 line 1
202 line 2
202 line 2
203
203
204
204
205 Test xml styles:
205 Test xml styles:
206
206
207 $ hg log --style xml
207 $ hg log --style xml
208 <?xml version="1.0"?>
208 <?xml version="1.0"?>
209 <log>
209 <log>
210 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
210 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
211 <tag>tip</tag>
211 <tag>tip</tag>
212 <author email="test">test</author>
212 <author email="test">test</author>
213 <date>2020-01-01T10:01:00+00:00</date>
213 <date>2020-01-01T10:01:00+00:00</date>
214 <msg xml:space="preserve">third</msg>
214 <msg xml:space="preserve">third</msg>
215 </logentry>
215 </logentry>
216 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
216 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
217 <parent revision="-1" node="0000000000000000000000000000000000000000" />
217 <parent revision="-1" node="0000000000000000000000000000000000000000" />
218 <author email="user@hostname">User Name</author>
218 <author email="user@hostname">User Name</author>
219 <date>1970-01-12T13:46:40+00:00</date>
219 <date>1970-01-12T13:46:40+00:00</date>
220 <msg xml:space="preserve">second</msg>
220 <msg xml:space="preserve">second</msg>
221 </logentry>
221 </logentry>
222 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
222 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
223 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
223 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
224 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
224 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
225 <author email="person">person</author>
225 <author email="person">person</author>
226 <date>1970-01-18T08:40:01+00:00</date>
226 <date>1970-01-18T08:40:01+00:00</date>
227 <msg xml:space="preserve">merge</msg>
227 <msg xml:space="preserve">merge</msg>
228 </logentry>
228 </logentry>
229 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
229 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
230 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
230 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
231 <author email="person">person</author>
231 <author email="person">person</author>
232 <date>1970-01-18T08:40:00+00:00</date>
232 <date>1970-01-18T08:40:00+00:00</date>
233 <msg xml:space="preserve">new head</msg>
233 <msg xml:space="preserve">new head</msg>
234 </logentry>
234 </logentry>
235 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
235 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
236 <branch>foo</branch>
236 <branch>foo</branch>
237 <author email="person">person</author>
237 <author email="person">person</author>
238 <date>1970-01-17T04:53:20+00:00</date>
238 <date>1970-01-17T04:53:20+00:00</date>
239 <msg xml:space="preserve">new branch</msg>
239 <msg xml:space="preserve">new branch</msg>
240 </logentry>
240 </logentry>
241 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
241 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
242 <author email="person">person</author>
242 <author email="person">person</author>
243 <date>1970-01-16T01:06:40+00:00</date>
243 <date>1970-01-16T01:06:40+00:00</date>
244 <msg xml:space="preserve">no user, no domain</msg>
244 <msg xml:space="preserve">no user, no domain</msg>
245 </logentry>
245 </logentry>
246 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
246 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
247 <author email="other@place">other</author>
247 <author email="other@place">other</author>
248 <date>1970-01-14T21:20:00+00:00</date>
248 <date>1970-01-14T21:20:00+00:00</date>
249 <msg xml:space="preserve">no person</msg>
249 <msg xml:space="preserve">no person</msg>
250 </logentry>
250 </logentry>
251 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
251 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
252 <author email="other@place">A. N. Other</author>
252 <author email="other@place">A. N. Other</author>
253 <date>1970-01-13T17:33:20+00:00</date>
253 <date>1970-01-13T17:33:20+00:00</date>
254 <msg xml:space="preserve">other 1
254 <msg xml:space="preserve">other 1
255 other 2
255 other 2
256
256
257 other 3</msg>
257 other 3</msg>
258 </logentry>
258 </logentry>
259 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
259 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
260 <author email="user@hostname">User Name</author>
260 <author email="user@hostname">User Name</author>
261 <date>1970-01-12T13:46:40+00:00</date>
261 <date>1970-01-12T13:46:40+00:00</date>
262 <msg xml:space="preserve">line 1
262 <msg xml:space="preserve">line 1
263 line 2</msg>
263 line 2</msg>
264 </logentry>
264 </logentry>
265 </log>
265 </log>
266
266
267 $ hg log -v --style xml
267 $ hg log -v --style xml
268 <?xml version="1.0"?>
268 <?xml version="1.0"?>
269 <log>
269 <log>
270 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
270 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
271 <tag>tip</tag>
271 <tag>tip</tag>
272 <author email="test">test</author>
272 <author email="test">test</author>
273 <date>2020-01-01T10:01:00+00:00</date>
273 <date>2020-01-01T10:01:00+00:00</date>
274 <msg xml:space="preserve">third</msg>
274 <msg xml:space="preserve">third</msg>
275 <paths>
275 <paths>
276 <path action="A">fourth</path>
276 <path action="A">fourth</path>
277 <path action="A">third</path>
277 <path action="A">third</path>
278 <path action="R">second</path>
278 <path action="R">second</path>
279 </paths>
279 </paths>
280 <copies>
280 <copies>
281 <copy source="second">fourth</copy>
281 <copy source="second">fourth</copy>
282 </copies>
282 </copies>
283 </logentry>
283 </logentry>
284 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
284 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
285 <parent revision="-1" node="0000000000000000000000000000000000000000" />
285 <parent revision="-1" node="0000000000000000000000000000000000000000" />
286 <author email="user@hostname">User Name</author>
286 <author email="user@hostname">User Name</author>
287 <date>1970-01-12T13:46:40+00:00</date>
287 <date>1970-01-12T13:46:40+00:00</date>
288 <msg xml:space="preserve">second</msg>
288 <msg xml:space="preserve">second</msg>
289 <paths>
289 <paths>
290 <path action="A">second</path>
290 <path action="A">second</path>
291 </paths>
291 </paths>
292 </logentry>
292 </logentry>
293 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
293 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
294 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
294 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
295 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
295 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
296 <author email="person">person</author>
296 <author email="person">person</author>
297 <date>1970-01-18T08:40:01+00:00</date>
297 <date>1970-01-18T08:40:01+00:00</date>
298 <msg xml:space="preserve">merge</msg>
298 <msg xml:space="preserve">merge</msg>
299 <paths>
299 <paths>
300 </paths>
300 </paths>
301 </logentry>
301 </logentry>
302 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
302 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
303 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
303 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
304 <author email="person">person</author>
304 <author email="person">person</author>
305 <date>1970-01-18T08:40:00+00:00</date>
305 <date>1970-01-18T08:40:00+00:00</date>
306 <msg xml:space="preserve">new head</msg>
306 <msg xml:space="preserve">new head</msg>
307 <paths>
307 <paths>
308 <path action="A">d</path>
308 <path action="A">d</path>
309 </paths>
309 </paths>
310 </logentry>
310 </logentry>
311 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
311 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
312 <branch>foo</branch>
312 <branch>foo</branch>
313 <author email="person">person</author>
313 <author email="person">person</author>
314 <date>1970-01-17T04:53:20+00:00</date>
314 <date>1970-01-17T04:53:20+00:00</date>
315 <msg xml:space="preserve">new branch</msg>
315 <msg xml:space="preserve">new branch</msg>
316 <paths>
316 <paths>
317 </paths>
317 </paths>
318 </logentry>
318 </logentry>
319 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
319 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
320 <author email="person">person</author>
320 <author email="person">person</author>
321 <date>1970-01-16T01:06:40+00:00</date>
321 <date>1970-01-16T01:06:40+00:00</date>
322 <msg xml:space="preserve">no user, no domain</msg>
322 <msg xml:space="preserve">no user, no domain</msg>
323 <paths>
323 <paths>
324 <path action="M">c</path>
324 <path action="M">c</path>
325 </paths>
325 </paths>
326 </logentry>
326 </logentry>
327 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
327 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
328 <author email="other@place">other</author>
328 <author email="other@place">other</author>
329 <date>1970-01-14T21:20:00+00:00</date>
329 <date>1970-01-14T21:20:00+00:00</date>
330 <msg xml:space="preserve">no person</msg>
330 <msg xml:space="preserve">no person</msg>
331 <paths>
331 <paths>
332 <path action="A">c</path>
332 <path action="A">c</path>
333 </paths>
333 </paths>
334 </logentry>
334 </logentry>
335 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
335 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
336 <author email="other@place">A. N. Other</author>
336 <author email="other@place">A. N. Other</author>
337 <date>1970-01-13T17:33:20+00:00</date>
337 <date>1970-01-13T17:33:20+00:00</date>
338 <msg xml:space="preserve">other 1
338 <msg xml:space="preserve">other 1
339 other 2
339 other 2
340
340
341 other 3</msg>
341 other 3</msg>
342 <paths>
342 <paths>
343 <path action="A">b</path>
343 <path action="A">b</path>
344 </paths>
344 </paths>
345 </logentry>
345 </logentry>
346 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
346 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
347 <author email="user@hostname">User Name</author>
347 <author email="user@hostname">User Name</author>
348 <date>1970-01-12T13:46:40+00:00</date>
348 <date>1970-01-12T13:46:40+00:00</date>
349 <msg xml:space="preserve">line 1
349 <msg xml:space="preserve">line 1
350 line 2</msg>
350 line 2</msg>
351 <paths>
351 <paths>
352 <path action="A">a</path>
352 <path action="A">a</path>
353 </paths>
353 </paths>
354 </logentry>
354 </logentry>
355 </log>
355 </log>
356
356
357 $ hg log --debug --style xml
357 $ hg log --debug --style xml
358 <?xml version="1.0"?>
358 <?xml version="1.0"?>
359 <log>
359 <log>
360 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
360 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
361 <tag>tip</tag>
361 <tag>tip</tag>
362 <parent revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453" />
362 <parent revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453" />
363 <parent revision="-1" node="0000000000000000000000000000000000000000" />
363 <parent revision="-1" node="0000000000000000000000000000000000000000" />
364 <author email="test">test</author>
364 <author email="test">test</author>
365 <date>2020-01-01T10:01:00+00:00</date>
365 <date>2020-01-01T10:01:00+00:00</date>
366 <msg xml:space="preserve">third</msg>
366 <msg xml:space="preserve">third</msg>
367 <paths>
367 <paths>
368 <path action="A">fourth</path>
368 <path action="A">fourth</path>
369 <path action="A">third</path>
369 <path action="A">third</path>
370 <path action="R">second</path>
370 <path action="R">second</path>
371 </paths>
371 </paths>
372 <copies>
372 <copies>
373 <copy source="second">fourth</copy>
373 <copy source="second">fourth</copy>
374 </copies>
374 </copies>
375 <extra key="branch">default</extra>
375 <extra key="branch">default</extra>
376 </logentry>
376 </logentry>
377 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
377 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
378 <parent revision="-1" node="0000000000000000000000000000000000000000" />
378 <parent revision="-1" node="0000000000000000000000000000000000000000" />
379 <parent revision="-1" node="0000000000000000000000000000000000000000" />
379 <parent revision="-1" node="0000000000000000000000000000000000000000" />
380 <author email="user@hostname">User Name</author>
380 <author email="user@hostname">User Name</author>
381 <date>1970-01-12T13:46:40+00:00</date>
381 <date>1970-01-12T13:46:40+00:00</date>
382 <msg xml:space="preserve">second</msg>
382 <msg xml:space="preserve">second</msg>
383 <paths>
383 <paths>
384 <path action="A">second</path>
384 <path action="A">second</path>
385 </paths>
385 </paths>
386 <extra key="branch">default</extra>
386 <extra key="branch">default</extra>
387 </logentry>
387 </logentry>
388 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
388 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
389 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
389 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
390 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
390 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
391 <author email="person">person</author>
391 <author email="person">person</author>
392 <date>1970-01-18T08:40:01+00:00</date>
392 <date>1970-01-18T08:40:01+00:00</date>
393 <msg xml:space="preserve">merge</msg>
393 <msg xml:space="preserve">merge</msg>
394 <paths>
394 <paths>
395 </paths>
395 </paths>
396 <extra key="branch">default</extra>
396 <extra key="branch">default</extra>
397 </logentry>
397 </logentry>
398 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
398 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
399 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
399 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
400 <parent revision="-1" node="0000000000000000000000000000000000000000" />
400 <parent revision="-1" node="0000000000000000000000000000000000000000" />
401 <author email="person">person</author>
401 <author email="person">person</author>
402 <date>1970-01-18T08:40:00+00:00</date>
402 <date>1970-01-18T08:40:00+00:00</date>
403 <msg xml:space="preserve">new head</msg>
403 <msg xml:space="preserve">new head</msg>
404 <paths>
404 <paths>
405 <path action="A">d</path>
405 <path action="A">d</path>
406 </paths>
406 </paths>
407 <extra key="branch">default</extra>
407 <extra key="branch">default</extra>
408 </logentry>
408 </logentry>
409 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
409 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
410 <branch>foo</branch>
410 <branch>foo</branch>
411 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
411 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
412 <parent revision="-1" node="0000000000000000000000000000000000000000" />
412 <parent revision="-1" node="0000000000000000000000000000000000000000" />
413 <author email="person">person</author>
413 <author email="person">person</author>
414 <date>1970-01-17T04:53:20+00:00</date>
414 <date>1970-01-17T04:53:20+00:00</date>
415 <msg xml:space="preserve">new branch</msg>
415 <msg xml:space="preserve">new branch</msg>
416 <paths>
416 <paths>
417 </paths>
417 </paths>
418 <extra key="branch">foo</extra>
418 <extra key="branch">foo</extra>
419 </logentry>
419 </logentry>
420 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
420 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
421 <parent revision="2" node="97054abb4ab824450e9164180baf491ae0078465" />
421 <parent revision="2" node="97054abb4ab824450e9164180baf491ae0078465" />
422 <parent revision="-1" node="0000000000000000000000000000000000000000" />
422 <parent revision="-1" node="0000000000000000000000000000000000000000" />
423 <author email="person">person</author>
423 <author email="person">person</author>
424 <date>1970-01-16T01:06:40+00:00</date>
424 <date>1970-01-16T01:06:40+00:00</date>
425 <msg xml:space="preserve">no user, no domain</msg>
425 <msg xml:space="preserve">no user, no domain</msg>
426 <paths>
426 <paths>
427 <path action="M">c</path>
427 <path action="M">c</path>
428 </paths>
428 </paths>
429 <extra key="branch">default</extra>
429 <extra key="branch">default</extra>
430 </logentry>
430 </logentry>
431 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
431 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
432 <parent revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965" />
432 <parent revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965" />
433 <parent revision="-1" node="0000000000000000000000000000000000000000" />
433 <parent revision="-1" node="0000000000000000000000000000000000000000" />
434 <author email="other@place">other</author>
434 <author email="other@place">other</author>
435 <date>1970-01-14T21:20:00+00:00</date>
435 <date>1970-01-14T21:20:00+00:00</date>
436 <msg xml:space="preserve">no person</msg>
436 <msg xml:space="preserve">no person</msg>
437 <paths>
437 <paths>
438 <path action="A">c</path>
438 <path action="A">c</path>
439 </paths>
439 </paths>
440 <extra key="branch">default</extra>
440 <extra key="branch">default</extra>
441 </logentry>
441 </logentry>
442 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
442 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
443 <parent revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f" />
443 <parent revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f" />
444 <parent revision="-1" node="0000000000000000000000000000000000000000" />
444 <parent revision="-1" node="0000000000000000000000000000000000000000" />
445 <author email="other@place">A. N. Other</author>
445 <author email="other@place">A. N. Other</author>
446 <date>1970-01-13T17:33:20+00:00</date>
446 <date>1970-01-13T17:33:20+00:00</date>
447 <msg xml:space="preserve">other 1
447 <msg xml:space="preserve">other 1
448 other 2
448 other 2
449
449
450 other 3</msg>
450 other 3</msg>
451 <paths>
451 <paths>
452 <path action="A">b</path>
452 <path action="A">b</path>
453 </paths>
453 </paths>
454 <extra key="branch">default</extra>
454 <extra key="branch">default</extra>
455 </logentry>
455 </logentry>
456 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
456 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
457 <parent revision="-1" node="0000000000000000000000000000000000000000" />
457 <parent revision="-1" node="0000000000000000000000000000000000000000" />
458 <parent revision="-1" node="0000000000000000000000000000000000000000" />
458 <parent revision="-1" node="0000000000000000000000000000000000000000" />
459 <author email="user@hostname">User Name</author>
459 <author email="user@hostname">User Name</author>
460 <date>1970-01-12T13:46:40+00:00</date>
460 <date>1970-01-12T13:46:40+00:00</date>
461 <msg xml:space="preserve">line 1
461 <msg xml:space="preserve">line 1
462 line 2</msg>
462 line 2</msg>
463 <paths>
463 <paths>
464 <path action="A">a</path>
464 <path action="A">a</path>
465 </paths>
465 </paths>
466 <extra key="branch">default</extra>
466 <extra key="branch">default</extra>
467 </logentry>
467 </logentry>
468 </log>
468 </log>
469
469
470
470
471 Test JSON style:
471 Test JSON style:
472
472
473 $ hg log -k nosuch -Tjson
473 $ hg log -k nosuch -Tjson
474 []
474 []
475
475
476 $ hg log -qr . -Tjson
476 $ hg log -qr . -Tjson
477 [
477 [
478 {
478 {
479 "rev": 8,
479 "rev": 8,
480 "node": "95c24699272ef57d062b8bccc32c878bf841784a"
480 "node": "95c24699272ef57d062b8bccc32c878bf841784a"
481 }
481 }
482 ]
482 ]
483
483
484 $ hg log -vpr . -Tjson --stat
484 $ hg log -vpr . -Tjson --stat
485 [
485 [
486 {
486 {
487 "rev": 8,
487 "rev": 8,
488 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
488 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
489 "branch": "default",
489 "branch": "default",
490 "phase": "draft",
490 "phase": "draft",
491 "user": "test",
491 "user": "test",
492 "date": [1577872860, 0],
492 "date": [1577872860, 0],
493 "desc": "third",
493 "desc": "third",
494 "bookmarks": [],
494 "bookmarks": [],
495 "tags": ["tip"],
495 "tags": ["tip"],
496 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
496 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
497 "files": ["fourth", "second", "third"],
497 "files": ["fourth", "second", "third"],
498 "diffstat": " fourth | 1 +\n second | 1 -\n third | 1 +\n 3 files changed, 2 insertions(+), 1 deletions(-)\n",
498 "diffstat": " fourth | 1 +\n second | 1 -\n third | 1 +\n 3 files changed, 2 insertions(+), 1 deletions(-)\n",
499 "diff": "diff -r 29114dbae42b -r 95c24699272e fourth\n--- /dev/null\tThu Jan 01 00:00:00 1970 +0000\n+++ b/fourth\tWed Jan 01 10:01:00 2020 +0000\n@@ -0,0 +1,1 @@\n+second\ndiff -r 29114dbae42b -r 95c24699272e second\n--- a/second\tMon Jan 12 13:46:40 1970 +0000\n+++ /dev/null\tThu Jan 01 00:00:00 1970 +0000\n@@ -1,1 +0,0 @@\n-second\ndiff -r 29114dbae42b -r 95c24699272e third\n--- /dev/null\tThu Jan 01 00:00:00 1970 +0000\n+++ b/third\tWed Jan 01 10:01:00 2020 +0000\n@@ -0,0 +1,1 @@\n+third\n"
499 "diff": "diff -r 29114dbae42b -r 95c24699272e fourth\n--- /dev/null\tThu Jan 01 00:00:00 1970 +0000\n+++ b/fourth\tWed Jan 01 10:01:00 2020 +0000\n@@ -0,0 +1,1 @@\n+second\ndiff -r 29114dbae42b -r 95c24699272e second\n--- a/second\tMon Jan 12 13:46:40 1970 +0000\n+++ /dev/null\tThu Jan 01 00:00:00 1970 +0000\n@@ -1,1 +0,0 @@\n-second\ndiff -r 29114dbae42b -r 95c24699272e third\n--- /dev/null\tThu Jan 01 00:00:00 1970 +0000\n+++ b/third\tWed Jan 01 10:01:00 2020 +0000\n@@ -0,0 +1,1 @@\n+third\n"
500 }
500 }
501 ]
501 ]
502
502
503 $ hg log -T json
503 $ hg log -T json
504 [
504 [
505 {
505 {
506 "rev": 8,
506 "rev": 8,
507 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
507 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
508 "branch": "default",
508 "branch": "default",
509 "phase": "draft",
509 "phase": "draft",
510 "user": "test",
510 "user": "test",
511 "date": [1577872860, 0],
511 "date": [1577872860, 0],
512 "desc": "third",
512 "desc": "third",
513 "bookmarks": [],
513 "bookmarks": [],
514 "tags": ["tip"],
514 "tags": ["tip"],
515 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"]
515 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"]
516 },
516 },
517 {
517 {
518 "rev": 7,
518 "rev": 7,
519 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
519 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
520 "branch": "default",
520 "branch": "default",
521 "phase": "draft",
521 "phase": "draft",
522 "user": "User Name <user@hostname>",
522 "user": "User Name <user@hostname>",
523 "date": [1000000, 0],
523 "date": [1000000, 0],
524 "desc": "second",
524 "desc": "second",
525 "bookmarks": [],
525 "bookmarks": [],
526 "tags": [],
526 "tags": [],
527 "parents": ["0000000000000000000000000000000000000000"]
527 "parents": ["0000000000000000000000000000000000000000"]
528 },
528 },
529 {
529 {
530 "rev": 6,
530 "rev": 6,
531 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
531 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
532 "branch": "default",
532 "branch": "default",
533 "phase": "draft",
533 "phase": "draft",
534 "user": "person",
534 "user": "person",
535 "date": [1500001, 0],
535 "date": [1500001, 0],
536 "desc": "merge",
536 "desc": "merge",
537 "bookmarks": [],
537 "bookmarks": [],
538 "tags": [],
538 "tags": [],
539 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"]
539 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"]
540 },
540 },
541 {
541 {
542 "rev": 5,
542 "rev": 5,
543 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
543 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
544 "branch": "default",
544 "branch": "default",
545 "phase": "draft",
545 "phase": "draft",
546 "user": "person",
546 "user": "person",
547 "date": [1500000, 0],
547 "date": [1500000, 0],
548 "desc": "new head",
548 "desc": "new head",
549 "bookmarks": [],
549 "bookmarks": [],
550 "tags": [],
550 "tags": [],
551 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"]
551 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"]
552 },
552 },
553 {
553 {
554 "rev": 4,
554 "rev": 4,
555 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
555 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
556 "branch": "foo",
556 "branch": "foo",
557 "phase": "draft",
557 "phase": "draft",
558 "user": "person",
558 "user": "person",
559 "date": [1400000, 0],
559 "date": [1400000, 0],
560 "desc": "new branch",
560 "desc": "new branch",
561 "bookmarks": [],
561 "bookmarks": [],
562 "tags": [],
562 "tags": [],
563 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"]
563 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"]
564 },
564 },
565 {
565 {
566 "rev": 3,
566 "rev": 3,
567 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
567 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
568 "branch": "default",
568 "branch": "default",
569 "phase": "draft",
569 "phase": "draft",
570 "user": "person",
570 "user": "person",
571 "date": [1300000, 0],
571 "date": [1300000, 0],
572 "desc": "no user, no domain",
572 "desc": "no user, no domain",
573 "bookmarks": [],
573 "bookmarks": [],
574 "tags": [],
574 "tags": [],
575 "parents": ["97054abb4ab824450e9164180baf491ae0078465"]
575 "parents": ["97054abb4ab824450e9164180baf491ae0078465"]
576 },
576 },
577 {
577 {
578 "rev": 2,
578 "rev": 2,
579 "node": "97054abb4ab824450e9164180baf491ae0078465",
579 "node": "97054abb4ab824450e9164180baf491ae0078465",
580 "branch": "default",
580 "branch": "default",
581 "phase": "draft",
581 "phase": "draft",
582 "user": "other@place",
582 "user": "other@place",
583 "date": [1200000, 0],
583 "date": [1200000, 0],
584 "desc": "no person",
584 "desc": "no person",
585 "bookmarks": [],
585 "bookmarks": [],
586 "tags": [],
586 "tags": [],
587 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"]
587 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"]
588 },
588 },
589 {
589 {
590 "rev": 1,
590 "rev": 1,
591 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
591 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
592 "branch": "default",
592 "branch": "default",
593 "phase": "draft",
593 "phase": "draft",
594 "user": "A. N. Other <other@place>",
594 "user": "A. N. Other <other@place>",
595 "date": [1100000, 0],
595 "date": [1100000, 0],
596 "desc": "other 1\nother 2\n\nother 3",
596 "desc": "other 1\nother 2\n\nother 3",
597 "bookmarks": [],
597 "bookmarks": [],
598 "tags": [],
598 "tags": [],
599 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"]
599 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"]
600 },
600 },
601 {
601 {
602 "rev": 0,
602 "rev": 0,
603 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
603 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
604 "branch": "default",
604 "branch": "default",
605 "phase": "draft",
605 "phase": "draft",
606 "user": "User Name <user@hostname>",
606 "user": "User Name <user@hostname>",
607 "date": [1000000, 0],
607 "date": [1000000, 0],
608 "desc": "line 1\nline 2",
608 "desc": "line 1\nline 2",
609 "bookmarks": [],
609 "bookmarks": [],
610 "tags": [],
610 "tags": [],
611 "parents": ["0000000000000000000000000000000000000000"]
611 "parents": ["0000000000000000000000000000000000000000"]
612 }
612 }
613 ]
613 ]
614
614
615 $ hg heads -v -Tjson
615 $ hg heads -v -Tjson
616 [
616 [
617 {
617 {
618 "rev": 8,
618 "rev": 8,
619 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
619 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
620 "branch": "default",
620 "branch": "default",
621 "phase": "draft",
621 "phase": "draft",
622 "user": "test",
622 "user": "test",
623 "date": [1577872860, 0],
623 "date": [1577872860, 0],
624 "desc": "third",
624 "desc": "third",
625 "bookmarks": [],
625 "bookmarks": [],
626 "tags": ["tip"],
626 "tags": ["tip"],
627 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
627 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
628 "files": ["fourth", "second", "third"]
628 "files": ["fourth", "second", "third"]
629 },
629 },
630 {
630 {
631 "rev": 6,
631 "rev": 6,
632 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
632 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
633 "branch": "default",
633 "branch": "default",
634 "phase": "draft",
634 "phase": "draft",
635 "user": "person",
635 "user": "person",
636 "date": [1500001, 0],
636 "date": [1500001, 0],
637 "desc": "merge",
637 "desc": "merge",
638 "bookmarks": [],
638 "bookmarks": [],
639 "tags": [],
639 "tags": [],
640 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
640 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
641 "files": []
641 "files": []
642 },
642 },
643 {
643 {
644 "rev": 4,
644 "rev": 4,
645 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
645 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
646 "branch": "foo",
646 "branch": "foo",
647 "phase": "draft",
647 "phase": "draft",
648 "user": "person",
648 "user": "person",
649 "date": [1400000, 0],
649 "date": [1400000, 0],
650 "desc": "new branch",
650 "desc": "new branch",
651 "bookmarks": [],
651 "bookmarks": [],
652 "tags": [],
652 "tags": [],
653 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
653 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
654 "files": []
654 "files": []
655 }
655 }
656 ]
656 ]
657
657
658 $ hg log --debug -Tjson
658 $ hg log --debug -Tjson
659 [
659 [
660 {
660 {
661 "rev": 8,
661 "rev": 8,
662 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
662 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
663 "branch": "default",
663 "branch": "default",
664 "phase": "draft",
664 "phase": "draft",
665 "user": "test",
665 "user": "test",
666 "date": [1577872860, 0],
666 "date": [1577872860, 0],
667 "desc": "third",
667 "desc": "third",
668 "bookmarks": [],
668 "bookmarks": [],
669 "tags": ["tip"],
669 "tags": ["tip"],
670 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
670 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
671 "manifest": "94961b75a2da554b4df6fb599e5bfc7d48de0c64",
671 "manifest": "94961b75a2da554b4df6fb599e5bfc7d48de0c64",
672 "extra": {"branch": "default"},
672 "extra": {"branch": "default"},
673 "modified": [],
673 "modified": [],
674 "added": ["second"],
674 "added": ["second"],
675 "removed": ["fourth", "third"]
675 "removed": ["fourth", "third"]
676 },
676 },
677 {
677 {
678 "rev": 7,
678 "rev": 7,
679 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
679 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
680 "branch": "default",
680 "branch": "default",
681 "phase": "draft",
681 "phase": "draft",
682 "user": "User Name <user@hostname>",
682 "user": "User Name <user@hostname>",
683 "date": [1000000, 0],
683 "date": [1000000, 0],
684 "desc": "second",
684 "desc": "second",
685 "bookmarks": [],
685 "bookmarks": [],
686 "tags": [],
686 "tags": [],
687 "parents": ["0000000000000000000000000000000000000000"],
687 "parents": ["0000000000000000000000000000000000000000"],
688 "manifest": "f2dbc354b94e5ec0b4f10680ee0cee816101d0bf",
688 "manifest": "f2dbc354b94e5ec0b4f10680ee0cee816101d0bf",
689 "extra": {"branch": "default"},
689 "extra": {"branch": "default"},
690 "modified": [],
690 "modified": [],
691 "added": [],
691 "added": [],
692 "removed": ["second"]
692 "removed": ["second"]
693 },
693 },
694 {
694 {
695 "rev": 6,
695 "rev": 6,
696 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
696 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
697 "branch": "default",
697 "branch": "default",
698 "phase": "draft",
698 "phase": "draft",
699 "user": "person",
699 "user": "person",
700 "date": [1500001, 0],
700 "date": [1500001, 0],
701 "desc": "merge",
701 "desc": "merge",
702 "bookmarks": [],
702 "bookmarks": [],
703 "tags": [],
703 "tags": [],
704 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
704 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
705 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
705 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
706 "extra": {"branch": "default"},
706 "extra": {"branch": "default"},
707 "modified": [],
707 "modified": [],
708 "added": [],
708 "added": [],
709 "removed": []
709 "removed": []
710 },
710 },
711 {
711 {
712 "rev": 5,
712 "rev": 5,
713 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
713 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
714 "branch": "default",
714 "branch": "default",
715 "phase": "draft",
715 "phase": "draft",
716 "user": "person",
716 "user": "person",
717 "date": [1500000, 0],
717 "date": [1500000, 0],
718 "desc": "new head",
718 "desc": "new head",
719 "bookmarks": [],
719 "bookmarks": [],
720 "tags": [],
720 "tags": [],
721 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
721 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
722 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
722 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
723 "extra": {"branch": "default"},
723 "extra": {"branch": "default"},
724 "modified": [],
724 "modified": [],
725 "added": [],
725 "added": [],
726 "removed": ["d"]
726 "removed": ["d"]
727 },
727 },
728 {
728 {
729 "rev": 4,
729 "rev": 4,
730 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
730 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
731 "branch": "foo",
731 "branch": "foo",
732 "phase": "draft",
732 "phase": "draft",
733 "user": "person",
733 "user": "person",
734 "date": [1400000, 0],
734 "date": [1400000, 0],
735 "desc": "new branch",
735 "desc": "new branch",
736 "bookmarks": [],
736 "bookmarks": [],
737 "tags": [],
737 "tags": [],
738 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
738 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
739 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
739 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
740 "extra": {"branch": "foo"},
740 "extra": {"branch": "foo"},
741 "modified": [],
741 "modified": [],
742 "added": [],
742 "added": [],
743 "removed": []
743 "removed": []
744 },
744 },
745 {
745 {
746 "rev": 3,
746 "rev": 3,
747 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
747 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
748 "branch": "default",
748 "branch": "default",
749 "phase": "draft",
749 "phase": "draft",
750 "user": "person",
750 "user": "person",
751 "date": [1300000, 0],
751 "date": [1300000, 0],
752 "desc": "no user, no domain",
752 "desc": "no user, no domain",
753 "bookmarks": [],
753 "bookmarks": [],
754 "tags": [],
754 "tags": [],
755 "parents": ["97054abb4ab824450e9164180baf491ae0078465"],
755 "parents": ["97054abb4ab824450e9164180baf491ae0078465"],
756 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
756 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
757 "extra": {"branch": "default"},
757 "extra": {"branch": "default"},
758 "modified": ["c"],
758 "modified": ["c"],
759 "added": [],
759 "added": [],
760 "removed": []
760 "removed": []
761 },
761 },
762 {
762 {
763 "rev": 2,
763 "rev": 2,
764 "node": "97054abb4ab824450e9164180baf491ae0078465",
764 "node": "97054abb4ab824450e9164180baf491ae0078465",
765 "branch": "default",
765 "branch": "default",
766 "phase": "draft",
766 "phase": "draft",
767 "user": "other@place",
767 "user": "other@place",
768 "date": [1200000, 0],
768 "date": [1200000, 0],
769 "desc": "no person",
769 "desc": "no person",
770 "bookmarks": [],
770 "bookmarks": [],
771 "tags": [],
771 "tags": [],
772 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"],
772 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"],
773 "manifest": "6e0e82995c35d0d57a52aca8da4e56139e06b4b1",
773 "manifest": "6e0e82995c35d0d57a52aca8da4e56139e06b4b1",
774 "extra": {"branch": "default"},
774 "extra": {"branch": "default"},
775 "modified": [],
775 "modified": [],
776 "added": [],
776 "added": [],
777 "removed": ["c"]
777 "removed": ["c"]
778 },
778 },
779 {
779 {
780 "rev": 1,
780 "rev": 1,
781 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
781 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
782 "branch": "default",
782 "branch": "default",
783 "phase": "draft",
783 "phase": "draft",
784 "user": "A. N. Other <other@place>",
784 "user": "A. N. Other <other@place>",
785 "date": [1100000, 0],
785 "date": [1100000, 0],
786 "desc": "other 1\nother 2\n\nother 3",
786 "desc": "other 1\nother 2\n\nother 3",
787 "bookmarks": [],
787 "bookmarks": [],
788 "tags": [],
788 "tags": [],
789 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"],
789 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"],
790 "manifest": "4e8d705b1e53e3f9375e0e60dc7b525d8211fe55",
790 "manifest": "4e8d705b1e53e3f9375e0e60dc7b525d8211fe55",
791 "extra": {"branch": "default"},
791 "extra": {"branch": "default"},
792 "modified": [],
792 "modified": [],
793 "added": [],
793 "added": [],
794 "removed": ["b"]
794 "removed": ["b"]
795 },
795 },
796 {
796 {
797 "rev": 0,
797 "rev": 0,
798 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
798 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
799 "branch": "default",
799 "branch": "default",
800 "phase": "draft",
800 "phase": "draft",
801 "user": "User Name <user@hostname>",
801 "user": "User Name <user@hostname>",
802 "date": [1000000, 0],
802 "date": [1000000, 0],
803 "desc": "line 1\nline 2",
803 "desc": "line 1\nline 2",
804 "bookmarks": [],
804 "bookmarks": [],
805 "tags": [],
805 "tags": [],
806 "parents": ["0000000000000000000000000000000000000000"],
806 "parents": ["0000000000000000000000000000000000000000"],
807 "manifest": "a0c8bcbbb45c63b90b70ad007bf38961f64f2af0",
807 "manifest": "a0c8bcbbb45c63b90b70ad007bf38961f64f2af0",
808 "extra": {"branch": "default"},
808 "extra": {"branch": "default"},
809 "modified": [],
809 "modified": [],
810 "added": [],
810 "added": [],
811 "removed": ["a"]
811 "removed": ["a"]
812 }
812 }
813 ]
813 ]
814
814
815 Error if style not readable:
815 Error if style not readable:
816
816
817 #if unix-permissions no-root
817 #if unix-permissions no-root
818 $ touch q
818 $ touch q
819 $ chmod 0 q
819 $ chmod 0 q
820 $ hg log --style ./q
820 $ hg log --style ./q
821 abort: Permission denied: ./q
821 abort: Permission denied: ./q
822 [255]
822 [255]
823 #endif
823 #endif
824
824
825 Error if no style:
825 Error if no style:
826
826
827 $ hg log --style notexist
827 $ hg log --style notexist
828 abort: style 'notexist' not found
828 abort: style 'notexist' not found
829 (available styles: bisect, changelog, compact, default, phases, xml)
829 (available styles: bisect, changelog, compact, default, phases, xml)
830 [255]
830 [255]
831
831
832 $ hg log -T list
832 $ hg log -T list
833 available styles: bisect, changelog, compact, default, phases, xml
833 available styles: bisect, changelog, compact, default, phases, xml
834 abort: specify a template
834 abort: specify a template
835 [255]
835 [255]
836
836
837 Error if style missing key:
837 Error if style missing key:
838
838
839 $ echo 'q = q' > t
839 $ echo 'q = q' > t
840 $ hg log --style ./t
840 $ hg log --style ./t
841 abort: "changeset" not in template map
841 abort: "changeset" not in template map
842 [255]
842 [255]
843
843
844 Error if style missing value:
844 Error if style missing value:
845
845
846 $ echo 'changeset =' > t
846 $ echo 'changeset =' > t
847 $ hg log --style t
847 $ hg log --style t
848 abort: t:1: missing value
848 abort: t:1: missing value
849 [255]
849 [255]
850
850
851 Error if include fails:
851 Error if include fails:
852
852
853 $ echo 'changeset = q' >> t
853 $ echo 'changeset = q' >> t
854 #if unix-permissions no-root
854 #if unix-permissions no-root
855 $ hg log --style ./t
855 $ hg log --style ./t
856 abort: template file ./q: Permission denied
856 abort: template file ./q: Permission denied
857 [255]
857 [255]
858 $ rm q
858 $ rm q
859 #endif
859 #endif
860
860
861 Include works:
861 Include works:
862
862
863 $ echo '{rev}' > q
863 $ echo '{rev}' > q
864 $ hg log --style ./t
864 $ hg log --style ./t
865 8
865 8
866 7
866 7
867 6
867 6
868 5
868 5
869 4
869 4
870 3
870 3
871 2
871 2
872 1
872 1
873 0
873 0
874
874
875 Missing non-standard names give no error (backward compatibility):
875 Missing non-standard names give no error (backward compatibility):
876
876
877 $ echo "changeset = '{c}'" > t
877 $ echo "changeset = '{c}'" > t
878 $ hg log --style ./t
878 $ hg log --style ./t
879
879
880 Defining non-standard name works:
880 Defining non-standard name works:
881
881
882 $ cat <<EOF > t
882 $ cat <<EOF > t
883 > changeset = '{c}'
883 > changeset = '{c}'
884 > c = q
884 > c = q
885 > EOF
885 > EOF
886 $ hg log --style ./t
886 $ hg log --style ./t
887 8
887 8
888 7
888 7
889 6
889 6
890 5
890 5
891 4
891 4
892 3
892 3
893 2
893 2
894 1
894 1
895 0
895 0
896
896
897 ui.style works:
897 ui.style works:
898
898
899 $ echo '[ui]' > .hg/hgrc
899 $ echo '[ui]' > .hg/hgrc
900 $ echo 'style = t' >> .hg/hgrc
900 $ echo 'style = t' >> .hg/hgrc
901 $ hg log
901 $ hg log
902 8
902 8
903 7
903 7
904 6
904 6
905 5
905 5
906 4
906 4
907 3
907 3
908 2
908 2
909 1
909 1
910 0
910 0
911
911
912
912
913 Issue338:
913 Issue338:
914
914
915 $ hg log --style=changelog > changelog
915 $ hg log --style=changelog > changelog
916
916
917 $ cat changelog
917 $ cat changelog
918 2020-01-01 test <test>
918 2020-01-01 test <test>
919
919
920 * fourth, second, third:
920 * fourth, second, third:
921 third
921 third
922 [95c24699272e] [tip]
922 [95c24699272e] [tip]
923
923
924 1970-01-12 User Name <user@hostname>
924 1970-01-12 User Name <user@hostname>
925
925
926 * second:
926 * second:
927 second
927 second
928 [29114dbae42b]
928 [29114dbae42b]
929
929
930 1970-01-18 person <person>
930 1970-01-18 person <person>
931
931
932 * merge
932 * merge
933 [d41e714fe50d]
933 [d41e714fe50d]
934
934
935 * d:
935 * d:
936 new head
936 new head
937 [13207e5a10d9]
937 [13207e5a10d9]
938
938
939 1970-01-17 person <person>
939 1970-01-17 person <person>
940
940
941 * new branch
941 * new branch
942 [bbe44766e73d] <foo>
942 [bbe44766e73d] <foo>
943
943
944 1970-01-16 person <person>
944 1970-01-16 person <person>
945
945
946 * c:
946 * c:
947 no user, no domain
947 no user, no domain
948 [10e46f2dcbf4]
948 [10e46f2dcbf4]
949
949
950 1970-01-14 other <other@place>
950 1970-01-14 other <other@place>
951
951
952 * c:
952 * c:
953 no person
953 no person
954 [97054abb4ab8]
954 [97054abb4ab8]
955
955
956 1970-01-13 A. N. Other <other@place>
956 1970-01-13 A. N. Other <other@place>
957
957
958 * b:
958 * b:
959 other 1 other 2
959 other 1 other 2
960
960
961 other 3
961 other 3
962 [b608e9d1a3f0]
962 [b608e9d1a3f0]
963
963
964 1970-01-12 User Name <user@hostname>
964 1970-01-12 User Name <user@hostname>
965
965
966 * a:
966 * a:
967 line 1 line 2
967 line 1 line 2
968 [1e4e1b8f71e0]
968 [1e4e1b8f71e0]
969
969
970
970
971 Issue2130: xml output for 'hg heads' is malformed
971 Issue2130: xml output for 'hg heads' is malformed
972
972
973 $ hg heads --style changelog
973 $ hg heads --style changelog
974 2020-01-01 test <test>
974 2020-01-01 test <test>
975
975
976 * fourth, second, third:
976 * fourth, second, third:
977 third
977 third
978 [95c24699272e] [tip]
978 [95c24699272e] [tip]
979
979
980 1970-01-18 person <person>
980 1970-01-18 person <person>
981
981
982 * merge
982 * merge
983 [d41e714fe50d]
983 [d41e714fe50d]
984
984
985 1970-01-17 person <person>
985 1970-01-17 person <person>
986
986
987 * new branch
987 * new branch
988 [bbe44766e73d] <foo>
988 [bbe44766e73d] <foo>
989
989
990
990
991 Keys work:
991 Keys work:
992
992
993 $ for key in author branch branches date desc file_adds file_dels file_mods \
993 $ for key in author branch branches date desc file_adds file_dels file_mods \
994 > file_copies file_copies_switch files \
994 > file_copies file_copies_switch files \
995 > manifest node parents rev tags diffstat extras \
995 > manifest node parents rev tags diffstat extras \
996 > p1rev p2rev p1node p2node; do
996 > p1rev p2rev p1node p2node; do
997 > for mode in '' --verbose --debug; do
997 > for mode in '' --verbose --debug; do
998 > hg log $mode --template "$key$mode: {$key}\n"
998 > hg log $mode --template "$key$mode: {$key}\n"
999 > done
999 > done
1000 > done
1000 > done
1001 author: test
1001 author: test
1002 author: User Name <user@hostname>
1002 author: User Name <user@hostname>
1003 author: person
1003 author: person
1004 author: person
1004 author: person
1005 author: person
1005 author: person
1006 author: person
1006 author: person
1007 author: other@place
1007 author: other@place
1008 author: A. N. Other <other@place>
1008 author: A. N. Other <other@place>
1009 author: User Name <user@hostname>
1009 author: User Name <user@hostname>
1010 author--verbose: test
1010 author--verbose: test
1011 author--verbose: User Name <user@hostname>
1011 author--verbose: User Name <user@hostname>
1012 author--verbose: person
1012 author--verbose: person
1013 author--verbose: person
1013 author--verbose: person
1014 author--verbose: person
1014 author--verbose: person
1015 author--verbose: person
1015 author--verbose: person
1016 author--verbose: other@place
1016 author--verbose: other@place
1017 author--verbose: A. N. Other <other@place>
1017 author--verbose: A. N. Other <other@place>
1018 author--verbose: User Name <user@hostname>
1018 author--verbose: User Name <user@hostname>
1019 author--debug: test
1019 author--debug: test
1020 author--debug: User Name <user@hostname>
1020 author--debug: User Name <user@hostname>
1021 author--debug: person
1021 author--debug: person
1022 author--debug: person
1022 author--debug: person
1023 author--debug: person
1023 author--debug: person
1024 author--debug: person
1024 author--debug: person
1025 author--debug: other@place
1025 author--debug: other@place
1026 author--debug: A. N. Other <other@place>
1026 author--debug: A. N. Other <other@place>
1027 author--debug: User Name <user@hostname>
1027 author--debug: User Name <user@hostname>
1028 branch: default
1028 branch: default
1029 branch: default
1029 branch: default
1030 branch: default
1030 branch: default
1031 branch: default
1031 branch: default
1032 branch: foo
1032 branch: foo
1033 branch: default
1033 branch: default
1034 branch: default
1034 branch: default
1035 branch: default
1035 branch: default
1036 branch: default
1036 branch: default
1037 branch--verbose: default
1037 branch--verbose: default
1038 branch--verbose: default
1038 branch--verbose: default
1039 branch--verbose: default
1039 branch--verbose: default
1040 branch--verbose: default
1040 branch--verbose: default
1041 branch--verbose: foo
1041 branch--verbose: foo
1042 branch--verbose: default
1042 branch--verbose: default
1043 branch--verbose: default
1043 branch--verbose: default
1044 branch--verbose: default
1044 branch--verbose: default
1045 branch--verbose: default
1045 branch--verbose: default
1046 branch--debug: default
1046 branch--debug: default
1047 branch--debug: default
1047 branch--debug: default
1048 branch--debug: default
1048 branch--debug: default
1049 branch--debug: default
1049 branch--debug: default
1050 branch--debug: foo
1050 branch--debug: foo
1051 branch--debug: default
1051 branch--debug: default
1052 branch--debug: default
1052 branch--debug: default
1053 branch--debug: default
1053 branch--debug: default
1054 branch--debug: default
1054 branch--debug: default
1055 branches:
1055 branches:
1056 branches:
1056 branches:
1057 branches:
1057 branches:
1058 branches:
1058 branches:
1059 branches: foo
1059 branches: foo
1060 branches:
1060 branches:
1061 branches:
1061 branches:
1062 branches:
1062 branches:
1063 branches:
1063 branches:
1064 branches--verbose:
1064 branches--verbose:
1065 branches--verbose:
1065 branches--verbose:
1066 branches--verbose:
1066 branches--verbose:
1067 branches--verbose:
1067 branches--verbose:
1068 branches--verbose: foo
1068 branches--verbose: foo
1069 branches--verbose:
1069 branches--verbose:
1070 branches--verbose:
1070 branches--verbose:
1071 branches--verbose:
1071 branches--verbose:
1072 branches--verbose:
1072 branches--verbose:
1073 branches--debug:
1073 branches--debug:
1074 branches--debug:
1074 branches--debug:
1075 branches--debug:
1075 branches--debug:
1076 branches--debug:
1076 branches--debug:
1077 branches--debug: foo
1077 branches--debug: foo
1078 branches--debug:
1078 branches--debug:
1079 branches--debug:
1079 branches--debug:
1080 branches--debug:
1080 branches--debug:
1081 branches--debug:
1081 branches--debug:
1082 date: 1577872860.00
1082 date: 1577872860.00
1083 date: 1000000.00
1083 date: 1000000.00
1084 date: 1500001.00
1084 date: 1500001.00
1085 date: 1500000.00
1085 date: 1500000.00
1086 date: 1400000.00
1086 date: 1400000.00
1087 date: 1300000.00
1087 date: 1300000.00
1088 date: 1200000.00
1088 date: 1200000.00
1089 date: 1100000.00
1089 date: 1100000.00
1090 date: 1000000.00
1090 date: 1000000.00
1091 date--verbose: 1577872860.00
1091 date--verbose: 1577872860.00
1092 date--verbose: 1000000.00
1092 date--verbose: 1000000.00
1093 date--verbose: 1500001.00
1093 date--verbose: 1500001.00
1094 date--verbose: 1500000.00
1094 date--verbose: 1500000.00
1095 date--verbose: 1400000.00
1095 date--verbose: 1400000.00
1096 date--verbose: 1300000.00
1096 date--verbose: 1300000.00
1097 date--verbose: 1200000.00
1097 date--verbose: 1200000.00
1098 date--verbose: 1100000.00
1098 date--verbose: 1100000.00
1099 date--verbose: 1000000.00
1099 date--verbose: 1000000.00
1100 date--debug: 1577872860.00
1100 date--debug: 1577872860.00
1101 date--debug: 1000000.00
1101 date--debug: 1000000.00
1102 date--debug: 1500001.00
1102 date--debug: 1500001.00
1103 date--debug: 1500000.00
1103 date--debug: 1500000.00
1104 date--debug: 1400000.00
1104 date--debug: 1400000.00
1105 date--debug: 1300000.00
1105 date--debug: 1300000.00
1106 date--debug: 1200000.00
1106 date--debug: 1200000.00
1107 date--debug: 1100000.00
1107 date--debug: 1100000.00
1108 date--debug: 1000000.00
1108 date--debug: 1000000.00
1109 desc: third
1109 desc: third
1110 desc: second
1110 desc: second
1111 desc: merge
1111 desc: merge
1112 desc: new head
1112 desc: new head
1113 desc: new branch
1113 desc: new branch
1114 desc: no user, no domain
1114 desc: no user, no domain
1115 desc: no person
1115 desc: no person
1116 desc: other 1
1116 desc: other 1
1117 other 2
1117 other 2
1118
1118
1119 other 3
1119 other 3
1120 desc: line 1
1120 desc: line 1
1121 line 2
1121 line 2
1122 desc--verbose: third
1122 desc--verbose: third
1123 desc--verbose: second
1123 desc--verbose: second
1124 desc--verbose: merge
1124 desc--verbose: merge
1125 desc--verbose: new head
1125 desc--verbose: new head
1126 desc--verbose: new branch
1126 desc--verbose: new branch
1127 desc--verbose: no user, no domain
1127 desc--verbose: no user, no domain
1128 desc--verbose: no person
1128 desc--verbose: no person
1129 desc--verbose: other 1
1129 desc--verbose: other 1
1130 other 2
1130 other 2
1131
1131
1132 other 3
1132 other 3
1133 desc--verbose: line 1
1133 desc--verbose: line 1
1134 line 2
1134 line 2
1135 desc--debug: third
1135 desc--debug: third
1136 desc--debug: second
1136 desc--debug: second
1137 desc--debug: merge
1137 desc--debug: merge
1138 desc--debug: new head
1138 desc--debug: new head
1139 desc--debug: new branch
1139 desc--debug: new branch
1140 desc--debug: no user, no domain
1140 desc--debug: no user, no domain
1141 desc--debug: no person
1141 desc--debug: no person
1142 desc--debug: other 1
1142 desc--debug: other 1
1143 other 2
1143 other 2
1144
1144
1145 other 3
1145 other 3
1146 desc--debug: line 1
1146 desc--debug: line 1
1147 line 2
1147 line 2
1148 file_adds: fourth third
1148 file_adds: fourth third
1149 file_adds: second
1149 file_adds: second
1150 file_adds:
1150 file_adds:
1151 file_adds: d
1151 file_adds: d
1152 file_adds:
1152 file_adds:
1153 file_adds:
1153 file_adds:
1154 file_adds: c
1154 file_adds: c
1155 file_adds: b
1155 file_adds: b
1156 file_adds: a
1156 file_adds: a
1157 file_adds--verbose: fourth third
1157 file_adds--verbose: fourth third
1158 file_adds--verbose: second
1158 file_adds--verbose: second
1159 file_adds--verbose:
1159 file_adds--verbose:
1160 file_adds--verbose: d
1160 file_adds--verbose: d
1161 file_adds--verbose:
1161 file_adds--verbose:
1162 file_adds--verbose:
1162 file_adds--verbose:
1163 file_adds--verbose: c
1163 file_adds--verbose: c
1164 file_adds--verbose: b
1164 file_adds--verbose: b
1165 file_adds--verbose: a
1165 file_adds--verbose: a
1166 file_adds--debug: fourth third
1166 file_adds--debug: fourth third
1167 file_adds--debug: second
1167 file_adds--debug: second
1168 file_adds--debug:
1168 file_adds--debug:
1169 file_adds--debug: d
1169 file_adds--debug: d
1170 file_adds--debug:
1170 file_adds--debug:
1171 file_adds--debug:
1171 file_adds--debug:
1172 file_adds--debug: c
1172 file_adds--debug: c
1173 file_adds--debug: b
1173 file_adds--debug: b
1174 file_adds--debug: a
1174 file_adds--debug: a
1175 file_dels: second
1175 file_dels: second
1176 file_dels:
1176 file_dels:
1177 file_dels:
1177 file_dels:
1178 file_dels:
1178 file_dels:
1179 file_dels:
1179 file_dels:
1180 file_dels:
1180 file_dels:
1181 file_dels:
1181 file_dels:
1182 file_dels:
1182 file_dels:
1183 file_dels:
1183 file_dels:
1184 file_dels--verbose: second
1184 file_dels--verbose: second
1185 file_dels--verbose:
1185 file_dels--verbose:
1186 file_dels--verbose:
1186 file_dels--verbose:
1187 file_dels--verbose:
1187 file_dels--verbose:
1188 file_dels--verbose:
1188 file_dels--verbose:
1189 file_dels--verbose:
1189 file_dels--verbose:
1190 file_dels--verbose:
1190 file_dels--verbose:
1191 file_dels--verbose:
1191 file_dels--verbose:
1192 file_dels--verbose:
1192 file_dels--verbose:
1193 file_dels--debug: second
1193 file_dels--debug: second
1194 file_dels--debug:
1194 file_dels--debug:
1195 file_dels--debug:
1195 file_dels--debug:
1196 file_dels--debug:
1196 file_dels--debug:
1197 file_dels--debug:
1197 file_dels--debug:
1198 file_dels--debug:
1198 file_dels--debug:
1199 file_dels--debug:
1199 file_dels--debug:
1200 file_dels--debug:
1200 file_dels--debug:
1201 file_dels--debug:
1201 file_dels--debug:
1202 file_mods:
1202 file_mods:
1203 file_mods:
1203 file_mods:
1204 file_mods:
1204 file_mods:
1205 file_mods:
1205 file_mods:
1206 file_mods:
1206 file_mods:
1207 file_mods: c
1207 file_mods: c
1208 file_mods:
1208 file_mods:
1209 file_mods:
1209 file_mods:
1210 file_mods:
1210 file_mods:
1211 file_mods--verbose:
1211 file_mods--verbose:
1212 file_mods--verbose:
1212 file_mods--verbose:
1213 file_mods--verbose:
1213 file_mods--verbose:
1214 file_mods--verbose:
1214 file_mods--verbose:
1215 file_mods--verbose:
1215 file_mods--verbose:
1216 file_mods--verbose: c
1216 file_mods--verbose: c
1217 file_mods--verbose:
1217 file_mods--verbose:
1218 file_mods--verbose:
1218 file_mods--verbose:
1219 file_mods--verbose:
1219 file_mods--verbose:
1220 file_mods--debug:
1220 file_mods--debug:
1221 file_mods--debug:
1221 file_mods--debug:
1222 file_mods--debug:
1222 file_mods--debug:
1223 file_mods--debug:
1223 file_mods--debug:
1224 file_mods--debug:
1224 file_mods--debug:
1225 file_mods--debug: c
1225 file_mods--debug: c
1226 file_mods--debug:
1226 file_mods--debug:
1227 file_mods--debug:
1227 file_mods--debug:
1228 file_mods--debug:
1228 file_mods--debug:
1229 file_copies: fourth (second)
1229 file_copies: fourth (second)
1230 file_copies:
1230 file_copies:
1231 file_copies:
1231 file_copies:
1232 file_copies:
1232 file_copies:
1233 file_copies:
1233 file_copies:
1234 file_copies:
1234 file_copies:
1235 file_copies:
1235 file_copies:
1236 file_copies:
1236 file_copies:
1237 file_copies:
1237 file_copies:
1238 file_copies--verbose: fourth (second)
1238 file_copies--verbose: fourth (second)
1239 file_copies--verbose:
1239 file_copies--verbose:
1240 file_copies--verbose:
1240 file_copies--verbose:
1241 file_copies--verbose:
1241 file_copies--verbose:
1242 file_copies--verbose:
1242 file_copies--verbose:
1243 file_copies--verbose:
1243 file_copies--verbose:
1244 file_copies--verbose:
1244 file_copies--verbose:
1245 file_copies--verbose:
1245 file_copies--verbose:
1246 file_copies--verbose:
1246 file_copies--verbose:
1247 file_copies--debug: fourth (second)
1247 file_copies--debug: fourth (second)
1248 file_copies--debug:
1248 file_copies--debug:
1249 file_copies--debug:
1249 file_copies--debug:
1250 file_copies--debug:
1250 file_copies--debug:
1251 file_copies--debug:
1251 file_copies--debug:
1252 file_copies--debug:
1252 file_copies--debug:
1253 file_copies--debug:
1253 file_copies--debug:
1254 file_copies--debug:
1254 file_copies--debug:
1255 file_copies--debug:
1255 file_copies--debug:
1256 file_copies_switch:
1256 file_copies_switch:
1257 file_copies_switch:
1257 file_copies_switch:
1258 file_copies_switch:
1258 file_copies_switch:
1259 file_copies_switch:
1259 file_copies_switch:
1260 file_copies_switch:
1260 file_copies_switch:
1261 file_copies_switch:
1261 file_copies_switch:
1262 file_copies_switch:
1262 file_copies_switch:
1263 file_copies_switch:
1263 file_copies_switch:
1264 file_copies_switch:
1264 file_copies_switch:
1265 file_copies_switch--verbose:
1265 file_copies_switch--verbose:
1266 file_copies_switch--verbose:
1266 file_copies_switch--verbose:
1267 file_copies_switch--verbose:
1267 file_copies_switch--verbose:
1268 file_copies_switch--verbose:
1268 file_copies_switch--verbose:
1269 file_copies_switch--verbose:
1269 file_copies_switch--verbose:
1270 file_copies_switch--verbose:
1270 file_copies_switch--verbose:
1271 file_copies_switch--verbose:
1271 file_copies_switch--verbose:
1272 file_copies_switch--verbose:
1272 file_copies_switch--verbose:
1273 file_copies_switch--verbose:
1273 file_copies_switch--verbose:
1274 file_copies_switch--debug:
1274 file_copies_switch--debug:
1275 file_copies_switch--debug:
1275 file_copies_switch--debug:
1276 file_copies_switch--debug:
1276 file_copies_switch--debug:
1277 file_copies_switch--debug:
1277 file_copies_switch--debug:
1278 file_copies_switch--debug:
1278 file_copies_switch--debug:
1279 file_copies_switch--debug:
1279 file_copies_switch--debug:
1280 file_copies_switch--debug:
1280 file_copies_switch--debug:
1281 file_copies_switch--debug:
1281 file_copies_switch--debug:
1282 file_copies_switch--debug:
1282 file_copies_switch--debug:
1283 files: fourth second third
1283 files: fourth second third
1284 files: second
1284 files: second
1285 files:
1285 files:
1286 files: d
1286 files: d
1287 files:
1287 files:
1288 files: c
1288 files: c
1289 files: c
1289 files: c
1290 files: b
1290 files: b
1291 files: a
1291 files: a
1292 files--verbose: fourth second third
1292 files--verbose: fourth second third
1293 files--verbose: second
1293 files--verbose: second
1294 files--verbose:
1294 files--verbose:
1295 files--verbose: d
1295 files--verbose: d
1296 files--verbose:
1296 files--verbose:
1297 files--verbose: c
1297 files--verbose: c
1298 files--verbose: c
1298 files--verbose: c
1299 files--verbose: b
1299 files--verbose: b
1300 files--verbose: a
1300 files--verbose: a
1301 files--debug: fourth second third
1301 files--debug: fourth second third
1302 files--debug: second
1302 files--debug: second
1303 files--debug:
1303 files--debug:
1304 files--debug: d
1304 files--debug: d
1305 files--debug:
1305 files--debug:
1306 files--debug: c
1306 files--debug: c
1307 files--debug: c
1307 files--debug: c
1308 files--debug: b
1308 files--debug: b
1309 files--debug: a
1309 files--debug: a
1310 manifest: 6:94961b75a2da
1310 manifest: 6:94961b75a2da
1311 manifest: 5:f2dbc354b94e
1311 manifest: 5:f2dbc354b94e
1312 manifest: 4:4dc3def4f9b4
1312 manifest: 4:4dc3def4f9b4
1313 manifest: 4:4dc3def4f9b4
1313 manifest: 4:4dc3def4f9b4
1314 manifest: 3:cb5a1327723b
1314 manifest: 3:cb5a1327723b
1315 manifest: 3:cb5a1327723b
1315 manifest: 3:cb5a1327723b
1316 manifest: 2:6e0e82995c35
1316 manifest: 2:6e0e82995c35
1317 manifest: 1:4e8d705b1e53
1317 manifest: 1:4e8d705b1e53
1318 manifest: 0:a0c8bcbbb45c
1318 manifest: 0:a0c8bcbbb45c
1319 manifest--verbose: 6:94961b75a2da
1319 manifest--verbose: 6:94961b75a2da
1320 manifest--verbose: 5:f2dbc354b94e
1320 manifest--verbose: 5:f2dbc354b94e
1321 manifest--verbose: 4:4dc3def4f9b4
1321 manifest--verbose: 4:4dc3def4f9b4
1322 manifest--verbose: 4:4dc3def4f9b4
1322 manifest--verbose: 4:4dc3def4f9b4
1323 manifest--verbose: 3:cb5a1327723b
1323 manifest--verbose: 3:cb5a1327723b
1324 manifest--verbose: 3:cb5a1327723b
1324 manifest--verbose: 3:cb5a1327723b
1325 manifest--verbose: 2:6e0e82995c35
1325 manifest--verbose: 2:6e0e82995c35
1326 manifest--verbose: 1:4e8d705b1e53
1326 manifest--verbose: 1:4e8d705b1e53
1327 manifest--verbose: 0:a0c8bcbbb45c
1327 manifest--verbose: 0:a0c8bcbbb45c
1328 manifest--debug: 6:94961b75a2da554b4df6fb599e5bfc7d48de0c64
1328 manifest--debug: 6:94961b75a2da554b4df6fb599e5bfc7d48de0c64
1329 manifest--debug: 5:f2dbc354b94e5ec0b4f10680ee0cee816101d0bf
1329 manifest--debug: 5:f2dbc354b94e5ec0b4f10680ee0cee816101d0bf
1330 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
1330 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
1331 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
1331 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
1332 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
1332 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
1333 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
1333 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
1334 manifest--debug: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
1334 manifest--debug: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
1335 manifest--debug: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
1335 manifest--debug: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
1336 manifest--debug: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
1336 manifest--debug: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
1337 node: 95c24699272ef57d062b8bccc32c878bf841784a
1337 node: 95c24699272ef57d062b8bccc32c878bf841784a
1338 node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1338 node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1339 node: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1339 node: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1340 node: 13207e5a10d9fd28ec424934298e176197f2c67f
1340 node: 13207e5a10d9fd28ec424934298e176197f2c67f
1341 node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1341 node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1342 node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1342 node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1343 node: 97054abb4ab824450e9164180baf491ae0078465
1343 node: 97054abb4ab824450e9164180baf491ae0078465
1344 node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1344 node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1345 node: 1e4e1b8f71e05681d422154f5421e385fec3454f
1345 node: 1e4e1b8f71e05681d422154f5421e385fec3454f
1346 node--verbose: 95c24699272ef57d062b8bccc32c878bf841784a
1346 node--verbose: 95c24699272ef57d062b8bccc32c878bf841784a
1347 node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1347 node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1348 node--verbose: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1348 node--verbose: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1349 node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
1349 node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
1350 node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1350 node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1351 node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1351 node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1352 node--verbose: 97054abb4ab824450e9164180baf491ae0078465
1352 node--verbose: 97054abb4ab824450e9164180baf491ae0078465
1353 node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1353 node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1354 node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
1354 node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
1355 node--debug: 95c24699272ef57d062b8bccc32c878bf841784a
1355 node--debug: 95c24699272ef57d062b8bccc32c878bf841784a
1356 node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1356 node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1357 node--debug: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1357 node--debug: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1358 node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
1358 node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
1359 node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1359 node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1360 node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1360 node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1361 node--debug: 97054abb4ab824450e9164180baf491ae0078465
1361 node--debug: 97054abb4ab824450e9164180baf491ae0078465
1362 node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1362 node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1363 node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
1363 node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
1364 parents:
1364 parents:
1365 parents: -1:000000000000
1365 parents: -1:000000000000
1366 parents: 5:13207e5a10d9 4:bbe44766e73d
1366 parents: 5:13207e5a10d9 4:bbe44766e73d
1367 parents: 3:10e46f2dcbf4
1367 parents: 3:10e46f2dcbf4
1368 parents:
1368 parents:
1369 parents:
1369 parents:
1370 parents:
1370 parents:
1371 parents:
1371 parents:
1372 parents:
1372 parents:
1373 parents--verbose:
1373 parents--verbose:
1374 parents--verbose: -1:000000000000
1374 parents--verbose: -1:000000000000
1375 parents--verbose: 5:13207e5a10d9 4:bbe44766e73d
1375 parents--verbose: 5:13207e5a10d9 4:bbe44766e73d
1376 parents--verbose: 3:10e46f2dcbf4
1376 parents--verbose: 3:10e46f2dcbf4
1377 parents--verbose:
1377 parents--verbose:
1378 parents--verbose:
1378 parents--verbose:
1379 parents--verbose:
1379 parents--verbose:
1380 parents--verbose:
1380 parents--verbose:
1381 parents--verbose:
1381 parents--verbose:
1382 parents--debug: 7:29114dbae42b9f078cf2714dbe3a86bba8ec7453 -1:0000000000000000000000000000000000000000
1382 parents--debug: 7:29114dbae42b9f078cf2714dbe3a86bba8ec7453 -1:0000000000000000000000000000000000000000
1383 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
1383 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
1384 parents--debug: 5:13207e5a10d9fd28ec424934298e176197f2c67f 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
1384 parents--debug: 5:13207e5a10d9fd28ec424934298e176197f2c67f 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
1385 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
1385 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
1386 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
1386 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
1387 parents--debug: 2:97054abb4ab824450e9164180baf491ae0078465 -1:0000000000000000000000000000000000000000
1387 parents--debug: 2:97054abb4ab824450e9164180baf491ae0078465 -1:0000000000000000000000000000000000000000
1388 parents--debug: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965 -1:0000000000000000000000000000000000000000
1388 parents--debug: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965 -1:0000000000000000000000000000000000000000
1389 parents--debug: 0:1e4e1b8f71e05681d422154f5421e385fec3454f -1:0000000000000000000000000000000000000000
1389 parents--debug: 0:1e4e1b8f71e05681d422154f5421e385fec3454f -1:0000000000000000000000000000000000000000
1390 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
1390 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
1391 rev: 8
1391 rev: 8
1392 rev: 7
1392 rev: 7
1393 rev: 6
1393 rev: 6
1394 rev: 5
1394 rev: 5
1395 rev: 4
1395 rev: 4
1396 rev: 3
1396 rev: 3
1397 rev: 2
1397 rev: 2
1398 rev: 1
1398 rev: 1
1399 rev: 0
1399 rev: 0
1400 rev--verbose: 8
1400 rev--verbose: 8
1401 rev--verbose: 7
1401 rev--verbose: 7
1402 rev--verbose: 6
1402 rev--verbose: 6
1403 rev--verbose: 5
1403 rev--verbose: 5
1404 rev--verbose: 4
1404 rev--verbose: 4
1405 rev--verbose: 3
1405 rev--verbose: 3
1406 rev--verbose: 2
1406 rev--verbose: 2
1407 rev--verbose: 1
1407 rev--verbose: 1
1408 rev--verbose: 0
1408 rev--verbose: 0
1409 rev--debug: 8
1409 rev--debug: 8
1410 rev--debug: 7
1410 rev--debug: 7
1411 rev--debug: 6
1411 rev--debug: 6
1412 rev--debug: 5
1412 rev--debug: 5
1413 rev--debug: 4
1413 rev--debug: 4
1414 rev--debug: 3
1414 rev--debug: 3
1415 rev--debug: 2
1415 rev--debug: 2
1416 rev--debug: 1
1416 rev--debug: 1
1417 rev--debug: 0
1417 rev--debug: 0
1418 tags: tip
1418 tags: tip
1419 tags:
1419 tags:
1420 tags:
1420 tags:
1421 tags:
1421 tags:
1422 tags:
1422 tags:
1423 tags:
1423 tags:
1424 tags:
1424 tags:
1425 tags:
1425 tags:
1426 tags:
1426 tags:
1427 tags--verbose: tip
1427 tags--verbose: tip
1428 tags--verbose:
1428 tags--verbose:
1429 tags--verbose:
1429 tags--verbose:
1430 tags--verbose:
1430 tags--verbose:
1431 tags--verbose:
1431 tags--verbose:
1432 tags--verbose:
1432 tags--verbose:
1433 tags--verbose:
1433 tags--verbose:
1434 tags--verbose:
1434 tags--verbose:
1435 tags--verbose:
1435 tags--verbose:
1436 tags--debug: tip
1436 tags--debug: tip
1437 tags--debug:
1437 tags--debug:
1438 tags--debug:
1438 tags--debug:
1439 tags--debug:
1439 tags--debug:
1440 tags--debug:
1440 tags--debug:
1441 tags--debug:
1441 tags--debug:
1442 tags--debug:
1442 tags--debug:
1443 tags--debug:
1443 tags--debug:
1444 tags--debug:
1444 tags--debug:
1445 diffstat: 3: +2/-1
1445 diffstat: 3: +2/-1
1446 diffstat: 1: +1/-0
1446 diffstat: 1: +1/-0
1447 diffstat: 0: +0/-0
1447 diffstat: 0: +0/-0
1448 diffstat: 1: +1/-0
1448 diffstat: 1: +1/-0
1449 diffstat: 0: +0/-0
1449 diffstat: 0: +0/-0
1450 diffstat: 1: +1/-0
1450 diffstat: 1: +1/-0
1451 diffstat: 1: +4/-0
1451 diffstat: 1: +4/-0
1452 diffstat: 1: +2/-0
1452 diffstat: 1: +2/-0
1453 diffstat: 1: +1/-0
1453 diffstat: 1: +1/-0
1454 diffstat--verbose: 3: +2/-1
1454 diffstat--verbose: 3: +2/-1
1455 diffstat--verbose: 1: +1/-0
1455 diffstat--verbose: 1: +1/-0
1456 diffstat--verbose: 0: +0/-0
1456 diffstat--verbose: 0: +0/-0
1457 diffstat--verbose: 1: +1/-0
1457 diffstat--verbose: 1: +1/-0
1458 diffstat--verbose: 0: +0/-0
1458 diffstat--verbose: 0: +0/-0
1459 diffstat--verbose: 1: +1/-0
1459 diffstat--verbose: 1: +1/-0
1460 diffstat--verbose: 1: +4/-0
1460 diffstat--verbose: 1: +4/-0
1461 diffstat--verbose: 1: +2/-0
1461 diffstat--verbose: 1: +2/-0
1462 diffstat--verbose: 1: +1/-0
1462 diffstat--verbose: 1: +1/-0
1463 diffstat--debug: 3: +2/-1
1463 diffstat--debug: 3: +2/-1
1464 diffstat--debug: 1: +1/-0
1464 diffstat--debug: 1: +1/-0
1465 diffstat--debug: 0: +0/-0
1465 diffstat--debug: 0: +0/-0
1466 diffstat--debug: 1: +1/-0
1466 diffstat--debug: 1: +1/-0
1467 diffstat--debug: 0: +0/-0
1467 diffstat--debug: 0: +0/-0
1468 diffstat--debug: 1: +1/-0
1468 diffstat--debug: 1: +1/-0
1469 diffstat--debug: 1: +4/-0
1469 diffstat--debug: 1: +4/-0
1470 diffstat--debug: 1: +2/-0
1470 diffstat--debug: 1: +2/-0
1471 diffstat--debug: 1: +1/-0
1471 diffstat--debug: 1: +1/-0
1472 extras: branch=default
1472 extras: branch=default
1473 extras: branch=default
1473 extras: branch=default
1474 extras: branch=default
1474 extras: branch=default
1475 extras: branch=default
1475 extras: branch=default
1476 extras: branch=foo
1476 extras: branch=foo
1477 extras: branch=default
1477 extras: branch=default
1478 extras: branch=default
1478 extras: branch=default
1479 extras: branch=default
1479 extras: branch=default
1480 extras: branch=default
1480 extras: branch=default
1481 extras--verbose: branch=default
1481 extras--verbose: branch=default
1482 extras--verbose: branch=default
1482 extras--verbose: branch=default
1483 extras--verbose: branch=default
1483 extras--verbose: branch=default
1484 extras--verbose: branch=default
1484 extras--verbose: branch=default
1485 extras--verbose: branch=foo
1485 extras--verbose: branch=foo
1486 extras--verbose: branch=default
1486 extras--verbose: branch=default
1487 extras--verbose: branch=default
1487 extras--verbose: branch=default
1488 extras--verbose: branch=default
1488 extras--verbose: branch=default
1489 extras--verbose: branch=default
1489 extras--verbose: branch=default
1490 extras--debug: branch=default
1490 extras--debug: branch=default
1491 extras--debug: branch=default
1491 extras--debug: branch=default
1492 extras--debug: branch=default
1492 extras--debug: branch=default
1493 extras--debug: branch=default
1493 extras--debug: branch=default
1494 extras--debug: branch=foo
1494 extras--debug: branch=foo
1495 extras--debug: branch=default
1495 extras--debug: branch=default
1496 extras--debug: branch=default
1496 extras--debug: branch=default
1497 extras--debug: branch=default
1497 extras--debug: branch=default
1498 extras--debug: branch=default
1498 extras--debug: branch=default
1499 p1rev: 7
1499 p1rev: 7
1500 p1rev: -1
1500 p1rev: -1
1501 p1rev: 5
1501 p1rev: 5
1502 p1rev: 3
1502 p1rev: 3
1503 p1rev: 3
1503 p1rev: 3
1504 p1rev: 2
1504 p1rev: 2
1505 p1rev: 1
1505 p1rev: 1
1506 p1rev: 0
1506 p1rev: 0
1507 p1rev: -1
1507 p1rev: -1
1508 p1rev--verbose: 7
1508 p1rev--verbose: 7
1509 p1rev--verbose: -1
1509 p1rev--verbose: -1
1510 p1rev--verbose: 5
1510 p1rev--verbose: 5
1511 p1rev--verbose: 3
1511 p1rev--verbose: 3
1512 p1rev--verbose: 3
1512 p1rev--verbose: 3
1513 p1rev--verbose: 2
1513 p1rev--verbose: 2
1514 p1rev--verbose: 1
1514 p1rev--verbose: 1
1515 p1rev--verbose: 0
1515 p1rev--verbose: 0
1516 p1rev--verbose: -1
1516 p1rev--verbose: -1
1517 p1rev--debug: 7
1517 p1rev--debug: 7
1518 p1rev--debug: -1
1518 p1rev--debug: -1
1519 p1rev--debug: 5
1519 p1rev--debug: 5
1520 p1rev--debug: 3
1520 p1rev--debug: 3
1521 p1rev--debug: 3
1521 p1rev--debug: 3
1522 p1rev--debug: 2
1522 p1rev--debug: 2
1523 p1rev--debug: 1
1523 p1rev--debug: 1
1524 p1rev--debug: 0
1524 p1rev--debug: 0
1525 p1rev--debug: -1
1525 p1rev--debug: -1
1526 p2rev: -1
1526 p2rev: -1
1527 p2rev: -1
1527 p2rev: -1
1528 p2rev: 4
1528 p2rev: 4
1529 p2rev: -1
1529 p2rev: -1
1530 p2rev: -1
1530 p2rev: -1
1531 p2rev: -1
1531 p2rev: -1
1532 p2rev: -1
1532 p2rev: -1
1533 p2rev: -1
1533 p2rev: -1
1534 p2rev: -1
1534 p2rev: -1
1535 p2rev--verbose: -1
1535 p2rev--verbose: -1
1536 p2rev--verbose: -1
1536 p2rev--verbose: -1
1537 p2rev--verbose: 4
1537 p2rev--verbose: 4
1538 p2rev--verbose: -1
1538 p2rev--verbose: -1
1539 p2rev--verbose: -1
1539 p2rev--verbose: -1
1540 p2rev--verbose: -1
1540 p2rev--verbose: -1
1541 p2rev--verbose: -1
1541 p2rev--verbose: -1
1542 p2rev--verbose: -1
1542 p2rev--verbose: -1
1543 p2rev--verbose: -1
1543 p2rev--verbose: -1
1544 p2rev--debug: -1
1544 p2rev--debug: -1
1545 p2rev--debug: -1
1545 p2rev--debug: -1
1546 p2rev--debug: 4
1546 p2rev--debug: 4
1547 p2rev--debug: -1
1547 p2rev--debug: -1
1548 p2rev--debug: -1
1548 p2rev--debug: -1
1549 p2rev--debug: -1
1549 p2rev--debug: -1
1550 p2rev--debug: -1
1550 p2rev--debug: -1
1551 p2rev--debug: -1
1551 p2rev--debug: -1
1552 p2rev--debug: -1
1552 p2rev--debug: -1
1553 p1node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1553 p1node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1554 p1node: 0000000000000000000000000000000000000000
1554 p1node: 0000000000000000000000000000000000000000
1555 p1node: 13207e5a10d9fd28ec424934298e176197f2c67f
1555 p1node: 13207e5a10d9fd28ec424934298e176197f2c67f
1556 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1556 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1557 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1557 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1558 p1node: 97054abb4ab824450e9164180baf491ae0078465
1558 p1node: 97054abb4ab824450e9164180baf491ae0078465
1559 p1node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1559 p1node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1560 p1node: 1e4e1b8f71e05681d422154f5421e385fec3454f
1560 p1node: 1e4e1b8f71e05681d422154f5421e385fec3454f
1561 p1node: 0000000000000000000000000000000000000000
1561 p1node: 0000000000000000000000000000000000000000
1562 p1node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1562 p1node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1563 p1node--verbose: 0000000000000000000000000000000000000000
1563 p1node--verbose: 0000000000000000000000000000000000000000
1564 p1node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
1564 p1node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
1565 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1565 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1566 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1566 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1567 p1node--verbose: 97054abb4ab824450e9164180baf491ae0078465
1567 p1node--verbose: 97054abb4ab824450e9164180baf491ae0078465
1568 p1node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1568 p1node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1569 p1node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
1569 p1node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
1570 p1node--verbose: 0000000000000000000000000000000000000000
1570 p1node--verbose: 0000000000000000000000000000000000000000
1571 p1node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1571 p1node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1572 p1node--debug: 0000000000000000000000000000000000000000
1572 p1node--debug: 0000000000000000000000000000000000000000
1573 p1node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
1573 p1node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
1574 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1574 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1575 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1575 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1576 p1node--debug: 97054abb4ab824450e9164180baf491ae0078465
1576 p1node--debug: 97054abb4ab824450e9164180baf491ae0078465
1577 p1node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1577 p1node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1578 p1node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
1578 p1node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
1579 p1node--debug: 0000000000000000000000000000000000000000
1579 p1node--debug: 0000000000000000000000000000000000000000
1580 p2node: 0000000000000000000000000000000000000000
1580 p2node: 0000000000000000000000000000000000000000
1581 p2node: 0000000000000000000000000000000000000000
1581 p2node: 0000000000000000000000000000000000000000
1582 p2node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1582 p2node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1583 p2node: 0000000000000000000000000000000000000000
1583 p2node: 0000000000000000000000000000000000000000
1584 p2node: 0000000000000000000000000000000000000000
1584 p2node: 0000000000000000000000000000000000000000
1585 p2node: 0000000000000000000000000000000000000000
1585 p2node: 0000000000000000000000000000000000000000
1586 p2node: 0000000000000000000000000000000000000000
1586 p2node: 0000000000000000000000000000000000000000
1587 p2node: 0000000000000000000000000000000000000000
1587 p2node: 0000000000000000000000000000000000000000
1588 p2node: 0000000000000000000000000000000000000000
1588 p2node: 0000000000000000000000000000000000000000
1589 p2node--verbose: 0000000000000000000000000000000000000000
1589 p2node--verbose: 0000000000000000000000000000000000000000
1590 p2node--verbose: 0000000000000000000000000000000000000000
1590 p2node--verbose: 0000000000000000000000000000000000000000
1591 p2node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1591 p2node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1592 p2node--verbose: 0000000000000000000000000000000000000000
1592 p2node--verbose: 0000000000000000000000000000000000000000
1593 p2node--verbose: 0000000000000000000000000000000000000000
1593 p2node--verbose: 0000000000000000000000000000000000000000
1594 p2node--verbose: 0000000000000000000000000000000000000000
1594 p2node--verbose: 0000000000000000000000000000000000000000
1595 p2node--verbose: 0000000000000000000000000000000000000000
1595 p2node--verbose: 0000000000000000000000000000000000000000
1596 p2node--verbose: 0000000000000000000000000000000000000000
1596 p2node--verbose: 0000000000000000000000000000000000000000
1597 p2node--verbose: 0000000000000000000000000000000000000000
1597 p2node--verbose: 0000000000000000000000000000000000000000
1598 p2node--debug: 0000000000000000000000000000000000000000
1598 p2node--debug: 0000000000000000000000000000000000000000
1599 p2node--debug: 0000000000000000000000000000000000000000
1599 p2node--debug: 0000000000000000000000000000000000000000
1600 p2node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1600 p2node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1601 p2node--debug: 0000000000000000000000000000000000000000
1601 p2node--debug: 0000000000000000000000000000000000000000
1602 p2node--debug: 0000000000000000000000000000000000000000
1602 p2node--debug: 0000000000000000000000000000000000000000
1603 p2node--debug: 0000000000000000000000000000000000000000
1603 p2node--debug: 0000000000000000000000000000000000000000
1604 p2node--debug: 0000000000000000000000000000000000000000
1604 p2node--debug: 0000000000000000000000000000000000000000
1605 p2node--debug: 0000000000000000000000000000000000000000
1605 p2node--debug: 0000000000000000000000000000000000000000
1606 p2node--debug: 0000000000000000000000000000000000000000
1606 p2node--debug: 0000000000000000000000000000000000000000
1607
1607
1608 Filters work:
1608 Filters work:
1609
1609
1610 $ hg log --template '{author|domain}\n'
1610 $ hg log --template '{author|domain}\n'
1611
1611
1612 hostname
1612 hostname
1613
1613
1614
1614
1615
1615
1616
1616
1617 place
1617 place
1618 place
1618 place
1619 hostname
1619 hostname
1620
1620
1621 $ hg log --template '{author|person}\n'
1621 $ hg log --template '{author|person}\n'
1622 test
1622 test
1623 User Name
1623 User Name
1624 person
1624 person
1625 person
1625 person
1626 person
1626 person
1627 person
1627 person
1628 other
1628 other
1629 A. N. Other
1629 A. N. Other
1630 User Name
1630 User Name
1631
1631
1632 $ hg log --template '{author|user}\n'
1632 $ hg log --template '{author|user}\n'
1633 test
1633 test
1634 user
1634 user
1635 person
1635 person
1636 person
1636 person
1637 person
1637 person
1638 person
1638 person
1639 other
1639 other
1640 other
1640 other
1641 user
1641 user
1642
1642
1643 $ hg log --template '{date|date}\n'
1643 $ hg log --template '{date|date}\n'
1644 Wed Jan 01 10:01:00 2020 +0000
1644 Wed Jan 01 10:01:00 2020 +0000
1645 Mon Jan 12 13:46:40 1970 +0000
1645 Mon Jan 12 13:46:40 1970 +0000
1646 Sun Jan 18 08:40:01 1970 +0000
1646 Sun Jan 18 08:40:01 1970 +0000
1647 Sun Jan 18 08:40:00 1970 +0000
1647 Sun Jan 18 08:40:00 1970 +0000
1648 Sat Jan 17 04:53:20 1970 +0000
1648 Sat Jan 17 04:53:20 1970 +0000
1649 Fri Jan 16 01:06:40 1970 +0000
1649 Fri Jan 16 01:06:40 1970 +0000
1650 Wed Jan 14 21:20:00 1970 +0000
1650 Wed Jan 14 21:20:00 1970 +0000
1651 Tue Jan 13 17:33:20 1970 +0000
1651 Tue Jan 13 17:33:20 1970 +0000
1652 Mon Jan 12 13:46:40 1970 +0000
1652 Mon Jan 12 13:46:40 1970 +0000
1653
1653
1654 $ hg log --template '{date|isodate}\n'
1654 $ hg log --template '{date|isodate}\n'
1655 2020-01-01 10:01 +0000
1655 2020-01-01 10:01 +0000
1656 1970-01-12 13:46 +0000
1656 1970-01-12 13:46 +0000
1657 1970-01-18 08:40 +0000
1657 1970-01-18 08:40 +0000
1658 1970-01-18 08:40 +0000
1658 1970-01-18 08:40 +0000
1659 1970-01-17 04:53 +0000
1659 1970-01-17 04:53 +0000
1660 1970-01-16 01:06 +0000
1660 1970-01-16 01:06 +0000
1661 1970-01-14 21:20 +0000
1661 1970-01-14 21:20 +0000
1662 1970-01-13 17:33 +0000
1662 1970-01-13 17:33 +0000
1663 1970-01-12 13:46 +0000
1663 1970-01-12 13:46 +0000
1664
1664
1665 $ hg log --template '{date|isodatesec}\n'
1665 $ hg log --template '{date|isodatesec}\n'
1666 2020-01-01 10:01:00 +0000
1666 2020-01-01 10:01:00 +0000
1667 1970-01-12 13:46:40 +0000
1667 1970-01-12 13:46:40 +0000
1668 1970-01-18 08:40:01 +0000
1668 1970-01-18 08:40:01 +0000
1669 1970-01-18 08:40:00 +0000
1669 1970-01-18 08:40:00 +0000
1670 1970-01-17 04:53:20 +0000
1670 1970-01-17 04:53:20 +0000
1671 1970-01-16 01:06:40 +0000
1671 1970-01-16 01:06:40 +0000
1672 1970-01-14 21:20:00 +0000
1672 1970-01-14 21:20:00 +0000
1673 1970-01-13 17:33:20 +0000
1673 1970-01-13 17:33:20 +0000
1674 1970-01-12 13:46:40 +0000
1674 1970-01-12 13:46:40 +0000
1675
1675
1676 $ hg log --template '{date|rfc822date}\n'
1676 $ hg log --template '{date|rfc822date}\n'
1677 Wed, 01 Jan 2020 10:01:00 +0000
1677 Wed, 01 Jan 2020 10:01:00 +0000
1678 Mon, 12 Jan 1970 13:46:40 +0000
1678 Mon, 12 Jan 1970 13:46:40 +0000
1679 Sun, 18 Jan 1970 08:40:01 +0000
1679 Sun, 18 Jan 1970 08:40:01 +0000
1680 Sun, 18 Jan 1970 08:40:00 +0000
1680 Sun, 18 Jan 1970 08:40:00 +0000
1681 Sat, 17 Jan 1970 04:53:20 +0000
1681 Sat, 17 Jan 1970 04:53:20 +0000
1682 Fri, 16 Jan 1970 01:06:40 +0000
1682 Fri, 16 Jan 1970 01:06:40 +0000
1683 Wed, 14 Jan 1970 21:20:00 +0000
1683 Wed, 14 Jan 1970 21:20:00 +0000
1684 Tue, 13 Jan 1970 17:33:20 +0000
1684 Tue, 13 Jan 1970 17:33:20 +0000
1685 Mon, 12 Jan 1970 13:46:40 +0000
1685 Mon, 12 Jan 1970 13:46:40 +0000
1686
1686
1687 $ hg log --template '{desc|firstline}\n'
1687 $ hg log --template '{desc|firstline}\n'
1688 third
1688 third
1689 second
1689 second
1690 merge
1690 merge
1691 new head
1691 new head
1692 new branch
1692 new branch
1693 no user, no domain
1693 no user, no domain
1694 no person
1694 no person
1695 other 1
1695 other 1
1696 line 1
1696 line 1
1697
1697
1698 $ hg log --template '{node|short}\n'
1698 $ hg log --template '{node|short}\n'
1699 95c24699272e
1699 95c24699272e
1700 29114dbae42b
1700 29114dbae42b
1701 d41e714fe50d
1701 d41e714fe50d
1702 13207e5a10d9
1702 13207e5a10d9
1703 bbe44766e73d
1703 bbe44766e73d
1704 10e46f2dcbf4
1704 10e46f2dcbf4
1705 97054abb4ab8
1705 97054abb4ab8
1706 b608e9d1a3f0
1706 b608e9d1a3f0
1707 1e4e1b8f71e0
1707 1e4e1b8f71e0
1708
1708
1709 $ hg log --template '<changeset author="{author|xmlescape}"/>\n'
1709 $ hg log --template '<changeset author="{author|xmlescape}"/>\n'
1710 <changeset author="test"/>
1710 <changeset author="test"/>
1711 <changeset author="User Name &lt;user@hostname&gt;"/>
1711 <changeset author="User Name &lt;user@hostname&gt;"/>
1712 <changeset author="person"/>
1712 <changeset author="person"/>
1713 <changeset author="person"/>
1713 <changeset author="person"/>
1714 <changeset author="person"/>
1714 <changeset author="person"/>
1715 <changeset author="person"/>
1715 <changeset author="person"/>
1716 <changeset author="other@place"/>
1716 <changeset author="other@place"/>
1717 <changeset author="A. N. Other &lt;other@place&gt;"/>
1717 <changeset author="A. N. Other &lt;other@place&gt;"/>
1718 <changeset author="User Name &lt;user@hostname&gt;"/>
1718 <changeset author="User Name &lt;user@hostname&gt;"/>
1719
1719
1720 $ hg log --template '{rev}: {children}\n'
1720 $ hg log --template '{rev}: {children}\n'
1721 8:
1721 8:
1722 7: 8:95c24699272e
1722 7: 8:95c24699272e
1723 6:
1723 6:
1724 5: 6:d41e714fe50d
1724 5: 6:d41e714fe50d
1725 4: 6:d41e714fe50d
1725 4: 6:d41e714fe50d
1726 3: 4:bbe44766e73d 5:13207e5a10d9
1726 3: 4:bbe44766e73d 5:13207e5a10d9
1727 2: 3:10e46f2dcbf4
1727 2: 3:10e46f2dcbf4
1728 1: 2:97054abb4ab8
1728 1: 2:97054abb4ab8
1729 0: 1:b608e9d1a3f0
1729 0: 1:b608e9d1a3f0
1730
1730
1731 Formatnode filter works:
1731 Formatnode filter works:
1732
1732
1733 $ hg -q log -r 0 --template '{node|formatnode}\n'
1733 $ hg -q log -r 0 --template '{node|formatnode}\n'
1734 1e4e1b8f71e0
1734 1e4e1b8f71e0
1735
1735
1736 $ hg log -r 0 --template '{node|formatnode}\n'
1736 $ hg log -r 0 --template '{node|formatnode}\n'
1737 1e4e1b8f71e0
1737 1e4e1b8f71e0
1738
1738
1739 $ hg -v log -r 0 --template '{node|formatnode}\n'
1739 $ hg -v log -r 0 --template '{node|formatnode}\n'
1740 1e4e1b8f71e0
1740 1e4e1b8f71e0
1741
1741
1742 $ hg --debug log -r 0 --template '{node|formatnode}\n'
1742 $ hg --debug log -r 0 --template '{node|formatnode}\n'
1743 1e4e1b8f71e05681d422154f5421e385fec3454f
1743 1e4e1b8f71e05681d422154f5421e385fec3454f
1744
1744
1745 Age filter:
1745 Age filter:
1746
1746
1747 $ hg log --template '{date|age}\n' > /dev/null || exit 1
1747 $ hg log --template '{date|age}\n' > /dev/null || exit 1
1748
1748
1749 >>> from datetime import datetime, timedelta
1749 >>> from datetime import datetime, timedelta
1750 >>> fp = open('a', 'w')
1750 >>> fp = open('a', 'w')
1751 >>> n = datetime.now() + timedelta(366 * 7)
1751 >>> n = datetime.now() + timedelta(366 * 7)
1752 >>> fp.write('%d-%d-%d 00:00' % (n.year, n.month, n.day))
1752 >>> fp.write('%d-%d-%d 00:00' % (n.year, n.month, n.day))
1753 >>> fp.close()
1753 >>> fp.close()
1754 $ hg add a
1754 $ hg add a
1755 $ hg commit -m future -d "`cat a`"
1755 $ hg commit -m future -d "`cat a`"
1756
1756
1757 $ hg log -l1 --template '{date|age}\n'
1757 $ hg log -l1 --template '{date|age}\n'
1758 7 years from now
1758 7 years from now
1759
1759
1760 Error on syntax:
1760 Error on syntax:
1761
1761
1762 $ echo 'x = "f' >> t
1762 $ echo 'x = "f' >> t
1763 $ hg log
1763 $ hg log
1764 abort: t:3: unmatched quotes
1764 abort: t:3: unmatched quotes
1765 [255]
1765 [255]
1766
1766
1767 Behind the scenes, this will throw TypeError
1767 Behind the scenes, this will throw TypeError
1768
1768
1769 $ hg log -l 3 --template '{date|obfuscate}\n'
1769 $ hg log -l 3 --template '{date|obfuscate}\n'
1770 abort: template filter 'obfuscate' is not compatible with keyword 'date'
1770 abort: template filter 'obfuscate' is not compatible with keyword 'date'
1771 [255]
1771 [255]
1772
1772
1773 Behind the scenes, this will throw a ValueError
1773 Behind the scenes, this will throw a ValueError
1774
1774
1775 $ hg log -l 3 --template 'line: {desc|shortdate}\n'
1775 $ hg log -l 3 --template 'line: {desc|shortdate}\n'
1776 abort: template filter 'shortdate' is not compatible with keyword 'desc'
1776 abort: template filter 'shortdate' is not compatible with keyword 'desc'
1777 [255]
1777 [255]
1778
1778
1779 Behind the scenes, this will throw AttributeError
1779 Behind the scenes, this will throw AttributeError
1780
1780
1781 $ hg log -l 3 --template 'line: {date|escape}\n'
1781 $ hg log -l 3 --template 'line: {date|escape}\n'
1782 abort: template filter 'escape' is not compatible with keyword 'date'
1782 abort: template filter 'escape' is not compatible with keyword 'date'
1783 [255]
1783 [255]
1784
1784
1785 Behind the scenes, this will throw ValueError
1785 Behind the scenes, this will throw ValueError
1786
1786
1787 $ hg tip --template '{author|email|date}\n'
1787 $ hg tip --template '{author|email|date}\n'
1788 abort: template filter 'datefilter' is not compatible with keyword 'author'
1788 abort: template filter 'datefilter' is not compatible with keyword 'author'
1789 [255]
1789 [255]
1790
1790
1791 Thrown an error if a template function doesn't exist
1791 Thrown an error if a template function doesn't exist
1792
1792
1793 $ hg tip --template '{foo()}\n'
1793 $ hg tip --template '{foo()}\n'
1794 hg: parse error: unknown function 'foo'
1794 hg: parse error: unknown function 'foo'
1795 [255]
1795 [255]
1796
1796
1797 Test diff function:
1798
1799 $ hg diff -c 8
1800 diff -r 29114dbae42b -r 95c24699272e fourth
1801 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1802 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
1803 @@ -0,0 +1,1 @@
1804 +second
1805 diff -r 29114dbae42b -r 95c24699272e second
1806 --- a/second Mon Jan 12 13:46:40 1970 +0000
1807 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1808 @@ -1,1 +0,0 @@
1809 -second
1810 diff -r 29114dbae42b -r 95c24699272e third
1811 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1812 +++ b/third Wed Jan 01 10:01:00 2020 +0000
1813 @@ -0,0 +1,1 @@
1814 +third
1815
1816 $ hg log -r 8 -T "{diff()}"
1817 diff -r 29114dbae42b -r 95c24699272e fourth
1818 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1819 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
1820 @@ -0,0 +1,1 @@
1821 +second
1822 diff -r 29114dbae42b -r 95c24699272e second
1823 --- a/second Mon Jan 12 13:46:40 1970 +0000
1824 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1825 @@ -1,1 +0,0 @@
1826 -second
1827 diff -r 29114dbae42b -r 95c24699272e third
1828 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1829 +++ b/third Wed Jan 01 10:01:00 2020 +0000
1830 @@ -0,0 +1,1 @@
1831 +third
1832
1833 $ hg log -r 8 -T "{diff('glob:f*')}"
1834 diff -r 29114dbae42b -r 95c24699272e fourth
1835 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1836 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
1837 @@ -0,0 +1,1 @@
1838 +second
1839
1840 $ hg log -r 8 -T "{diff('', 'glob:f*')}"
1841 diff -r 29114dbae42b -r 95c24699272e second
1842 --- a/second Mon Jan 12 13:46:40 1970 +0000
1843 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1844 @@ -1,1 +0,0 @@
1845 -second
1846 diff -r 29114dbae42b -r 95c24699272e third
1847 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1848 +++ b/third Wed Jan 01 10:01:00 2020 +0000
1849 @@ -0,0 +1,1 @@
1850 +third
1851
1797 $ cd ..
1852 $ cd ..
1798
1853
1799
1854
1800 latesttag:
1855 latesttag:
1801
1856
1802 $ hg init latesttag
1857 $ hg init latesttag
1803 $ cd latesttag
1858 $ cd latesttag
1804
1859
1805 $ echo a > file
1860 $ echo a > file
1806 $ hg ci -Am a -d '0 0'
1861 $ hg ci -Am a -d '0 0'
1807 adding file
1862 adding file
1808
1863
1809 $ echo b >> file
1864 $ echo b >> file
1810 $ hg ci -m b -d '1 0'
1865 $ hg ci -m b -d '1 0'
1811
1866
1812 $ echo c >> head1
1867 $ echo c >> head1
1813 $ hg ci -Am h1c -d '2 0'
1868 $ hg ci -Am h1c -d '2 0'
1814 adding head1
1869 adding head1
1815
1870
1816 $ hg update -q 1
1871 $ hg update -q 1
1817 $ echo d >> head2
1872 $ echo d >> head2
1818 $ hg ci -Am h2d -d '3 0'
1873 $ hg ci -Am h2d -d '3 0'
1819 adding head2
1874 adding head2
1820 created new head
1875 created new head
1821
1876
1822 $ echo e >> head2
1877 $ echo e >> head2
1823 $ hg ci -m h2e -d '4 0'
1878 $ hg ci -m h2e -d '4 0'
1824
1879
1825 $ hg merge -q
1880 $ hg merge -q
1826 $ hg ci -m merge -d '5 -3600'
1881 $ hg ci -m merge -d '5 -3600'
1827
1882
1828 No tag set:
1883 No tag set:
1829
1884
1830 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1885 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1831 5: null+5
1886 5: null+5
1832 4: null+4
1887 4: null+4
1833 3: null+3
1888 3: null+3
1834 2: null+3
1889 2: null+3
1835 1: null+2
1890 1: null+2
1836 0: null+1
1891 0: null+1
1837
1892
1838 One common tag: longest path wins:
1893 One common tag: longest path wins:
1839
1894
1840 $ hg tag -r 1 -m t1 -d '6 0' t1
1895 $ hg tag -r 1 -m t1 -d '6 0' t1
1841 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1896 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1842 6: t1+4
1897 6: t1+4
1843 5: t1+3
1898 5: t1+3
1844 4: t1+2
1899 4: t1+2
1845 3: t1+1
1900 3: t1+1
1846 2: t1+1
1901 2: t1+1
1847 1: t1+0
1902 1: t1+0
1848 0: null+1
1903 0: null+1
1849
1904
1850 One ancestor tag: more recent wins:
1905 One ancestor tag: more recent wins:
1851
1906
1852 $ hg tag -r 2 -m t2 -d '7 0' t2
1907 $ hg tag -r 2 -m t2 -d '7 0' t2
1853 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1908 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1854 7: t2+3
1909 7: t2+3
1855 6: t2+2
1910 6: t2+2
1856 5: t2+1
1911 5: t2+1
1857 4: t1+2
1912 4: t1+2
1858 3: t1+1
1913 3: t1+1
1859 2: t2+0
1914 2: t2+0
1860 1: t1+0
1915 1: t1+0
1861 0: null+1
1916 0: null+1
1862
1917
1863 Two branch tags: more recent wins:
1918 Two branch tags: more recent wins:
1864
1919
1865 $ hg tag -r 3 -m t3 -d '8 0' t3
1920 $ hg tag -r 3 -m t3 -d '8 0' t3
1866 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1921 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1867 8: t3+5
1922 8: t3+5
1868 7: t3+4
1923 7: t3+4
1869 6: t3+3
1924 6: t3+3
1870 5: t3+2
1925 5: t3+2
1871 4: t3+1
1926 4: t3+1
1872 3: t3+0
1927 3: t3+0
1873 2: t2+0
1928 2: t2+0
1874 1: t1+0
1929 1: t1+0
1875 0: null+1
1930 0: null+1
1876
1931
1877 Merged tag overrides:
1932 Merged tag overrides:
1878
1933
1879 $ hg tag -r 5 -m t5 -d '9 0' t5
1934 $ hg tag -r 5 -m t5 -d '9 0' t5
1880 $ hg tag -r 3 -m at3 -d '10 0' at3
1935 $ hg tag -r 3 -m at3 -d '10 0' at3
1881 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1936 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1882 10: t5+5
1937 10: t5+5
1883 9: t5+4
1938 9: t5+4
1884 8: t5+3
1939 8: t5+3
1885 7: t5+2
1940 7: t5+2
1886 6: t5+1
1941 6: t5+1
1887 5: t5+0
1942 5: t5+0
1888 4: at3:t3+1
1943 4: at3:t3+1
1889 3: at3:t3+0
1944 3: at3:t3+0
1890 2: t2+0
1945 2: t2+0
1891 1: t1+0
1946 1: t1+0
1892 0: null+1
1947 0: null+1
1893
1948
1894 $ cd ..
1949 $ cd ..
1895
1950
1896
1951
1897 Style path expansion: issue1948 - ui.style option doesn't work on OSX
1952 Style path expansion: issue1948 - ui.style option doesn't work on OSX
1898 if it is a relative path
1953 if it is a relative path
1899
1954
1900 $ mkdir -p home/styles
1955 $ mkdir -p home/styles
1901
1956
1902 $ cat > home/styles/teststyle <<EOF
1957 $ cat > home/styles/teststyle <<EOF
1903 > changeset = 'test {rev}:{node|short}\n'
1958 > changeset = 'test {rev}:{node|short}\n'
1904 > EOF
1959 > EOF
1905
1960
1906 $ HOME=`pwd`/home; export HOME
1961 $ HOME=`pwd`/home; export HOME
1907
1962
1908 $ cat > latesttag/.hg/hgrc <<EOF
1963 $ cat > latesttag/.hg/hgrc <<EOF
1909 > [ui]
1964 > [ui]
1910 > style = ~/styles/teststyle
1965 > style = ~/styles/teststyle
1911 > EOF
1966 > EOF
1912
1967
1913 $ hg -R latesttag tip
1968 $ hg -R latesttag tip
1914 test 10:9b4a630e5f5f
1969 test 10:9b4a630e5f5f
1915
1970
1916 Test recursive showlist template (issue1989):
1971 Test recursive showlist template (issue1989):
1917
1972
1918 $ cat > style1989 <<EOF
1973 $ cat > style1989 <<EOF
1919 > changeset = '{file_mods}{manifest}{extras}'
1974 > changeset = '{file_mods}{manifest}{extras}'
1920 > file_mod = 'M|{author|person}\n'
1975 > file_mod = 'M|{author|person}\n'
1921 > manifest = '{rev},{author}\n'
1976 > manifest = '{rev},{author}\n'
1922 > extra = '{key}: {author}\n'
1977 > extra = '{key}: {author}\n'
1923 > EOF
1978 > EOF
1924
1979
1925 $ hg -R latesttag log -r tip --style=style1989
1980 $ hg -R latesttag log -r tip --style=style1989
1926 M|test
1981 M|test
1927 10,test
1982 10,test
1928 branch: test
1983 branch: test
1929
1984
1930 Test new-style inline templating:
1985 Test new-style inline templating:
1931
1986
1932 $ hg log -R latesttag -r tip --template 'modified files: {file_mods % " {file}\n"}\n'
1987 $ hg log -R latesttag -r tip --template 'modified files: {file_mods % " {file}\n"}\n'
1933 modified files: .hgtags
1988 modified files: .hgtags
1934
1989
1935 Test the sub function of templating for expansion:
1990 Test the sub function of templating for expansion:
1936
1991
1937 $ hg log -R latesttag -r 10 --template '{sub("[0-9]", "x", "{rev}")}\n'
1992 $ hg log -R latesttag -r 10 --template '{sub("[0-9]", "x", "{rev}")}\n'
1938 xx
1993 xx
1939
1994
1940 Test the strip function with chars specified:
1995 Test the strip function with chars specified:
1941
1996
1942 $ hg log -R latesttag --template '{desc}\n'
1997 $ hg log -R latesttag --template '{desc}\n'
1943 at3
1998 at3
1944 t5
1999 t5
1945 t3
2000 t3
1946 t2
2001 t2
1947 t1
2002 t1
1948 merge
2003 merge
1949 h2e
2004 h2e
1950 h2d
2005 h2d
1951 h1c
2006 h1c
1952 b
2007 b
1953 a
2008 a
1954
2009
1955 $ hg log -R latesttag --template '{strip(desc, "te")}\n'
2010 $ hg log -R latesttag --template '{strip(desc, "te")}\n'
1956 at3
2011 at3
1957 5
2012 5
1958 3
2013 3
1959 2
2014 2
1960 1
2015 1
1961 merg
2016 merg
1962 h2
2017 h2
1963 h2d
2018 h2d
1964 h1c
2019 h1c
1965 b
2020 b
1966 a
2021 a
1967
2022
1968 Test date format:
2023 Test date format:
1969
2024
1970 $ hg log -R latesttag --template 'date: {date(date, "%y %m %d %S %z")}\n'
2025 $ hg log -R latesttag --template 'date: {date(date, "%y %m %d %S %z")}\n'
1971 date: 70 01 01 10 +0000
2026 date: 70 01 01 10 +0000
1972 date: 70 01 01 09 +0000
2027 date: 70 01 01 09 +0000
1973 date: 70 01 01 08 +0000
2028 date: 70 01 01 08 +0000
1974 date: 70 01 01 07 +0000
2029 date: 70 01 01 07 +0000
1975 date: 70 01 01 06 +0000
2030 date: 70 01 01 06 +0000
1976 date: 70 01 01 05 +0100
2031 date: 70 01 01 05 +0100
1977 date: 70 01 01 04 +0000
2032 date: 70 01 01 04 +0000
1978 date: 70 01 01 03 +0000
2033 date: 70 01 01 03 +0000
1979 date: 70 01 01 02 +0000
2034 date: 70 01 01 02 +0000
1980 date: 70 01 01 01 +0000
2035 date: 70 01 01 01 +0000
1981 date: 70 01 01 00 +0000
2036 date: 70 01 01 00 +0000
1982
2037
1983 Test string escaping:
2038 Test string escaping:
1984
2039
1985 $ hg log -R latesttag -r 0 --template '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2040 $ hg log -R latesttag -r 0 --template '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
1986 >
2041 >
1987 <>\n<[>
2042 <>\n<[>
1988 <>\n<]>
2043 <>\n<]>
1989 <>\n<
2044 <>\n<
1990
2045
1991 "string-escape"-ed "\x5c\x786e" becomes r"\x6e" (once) or r"n" (twice)
2046 "string-escape"-ed "\x5c\x786e" becomes r"\x6e" (once) or r"n" (twice)
1992
2047
1993 $ hg log -R a -r 0 --template '{if("1", "\x5c\x786e", "NG")}\n'
2048 $ hg log -R a -r 0 --template '{if("1", "\x5c\x786e", "NG")}\n'
1994 \x6e
2049 \x6e
1995 $ hg log -R a -r 0 --template '{if("1", r"\x5c\x786e", "NG")}\n'
2050 $ hg log -R a -r 0 --template '{if("1", r"\x5c\x786e", "NG")}\n'
1996 \x5c\x786e
2051 \x5c\x786e
1997 $ hg log -R a -r 0 --template '{if("", "NG", "\x5c\x786e")}\n'
2052 $ hg log -R a -r 0 --template '{if("", "NG", "\x5c\x786e")}\n'
1998 \x6e
2053 \x6e
1999 $ hg log -R a -r 0 --template '{if("", "NG", r"\x5c\x786e")}\n'
2054 $ hg log -R a -r 0 --template '{if("", "NG", r"\x5c\x786e")}\n'
2000 \x5c\x786e
2055 \x5c\x786e
2001
2056
2002 $ hg log -R a -r 2 --template '{ifeq("no perso\x6e", desc, "\x5c\x786e", "NG")}\n'
2057 $ hg log -R a -r 2 --template '{ifeq("no perso\x6e", desc, "\x5c\x786e", "NG")}\n'
2003 \x6e
2058 \x6e
2004 $ hg log -R a -r 2 --template '{ifeq(r"no perso\x6e", desc, "NG", r"\x5c\x786e")}\n'
2059 $ hg log -R a -r 2 --template '{ifeq(r"no perso\x6e", desc, "NG", r"\x5c\x786e")}\n'
2005 \x5c\x786e
2060 \x5c\x786e
2006 $ hg log -R a -r 2 --template '{ifeq(desc, "no perso\x6e", "\x5c\x786e", "NG")}\n'
2061 $ hg log -R a -r 2 --template '{ifeq(desc, "no perso\x6e", "\x5c\x786e", "NG")}\n'
2007 \x6e
2062 \x6e
2008 $ hg log -R a -r 2 --template '{ifeq(desc, r"no perso\x6e", "NG", r"\x5c\x786e")}\n'
2063 $ hg log -R a -r 2 --template '{ifeq(desc, r"no perso\x6e", "NG", r"\x5c\x786e")}\n'
2009 \x5c\x786e
2064 \x5c\x786e
2010
2065
2011 $ hg log -R a -r 8 --template '{join(files, "\n")}\n'
2066 $ hg log -R a -r 8 --template '{join(files, "\n")}\n'
2012 fourth
2067 fourth
2013 second
2068 second
2014 third
2069 third
2015 $ hg log -R a -r 8 --template '{join(files, r"\n")}\n'
2070 $ hg log -R a -r 8 --template '{join(files, r"\n")}\n'
2016 fourth\nsecond\nthird
2071 fourth\nsecond\nthird
2017
2072
2018 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", "htm\x6c")}'
2073 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", "htm\x6c")}'
2019 <p>
2074 <p>
2020 1st
2075 1st
2021 </p>
2076 </p>
2022 <p>
2077 <p>
2023 2nd
2078 2nd
2024 </p>
2079 </p>
2025 $ hg log -R a -r 2 --template '{rstdoc(r"1st\n\n2nd", "html")}'
2080 $ hg log -R a -r 2 --template '{rstdoc(r"1st\n\n2nd", "html")}'
2026 <p>
2081 <p>
2027 1st\n\n2nd
2082 1st\n\n2nd
2028 </p>
2083 </p>
2029 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", r"htm\x6c")}'
2084 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", r"htm\x6c")}'
2030 1st
2085 1st
2031
2086
2032 2nd
2087 2nd
2033
2088
2034 $ hg log -R a -r 2 --template '{strip(desc, "\x6e")}\n'
2089 $ hg log -R a -r 2 --template '{strip(desc, "\x6e")}\n'
2035 o perso
2090 o perso
2036 $ hg log -R a -r 2 --template '{strip(desc, r"\x6e")}\n'
2091 $ hg log -R a -r 2 --template '{strip(desc, r"\x6e")}\n'
2037 no person
2092 no person
2038 $ hg log -R a -r 2 --template '{strip("no perso\x6e", "\x6e")}\n'
2093 $ hg log -R a -r 2 --template '{strip("no perso\x6e", "\x6e")}\n'
2039 o perso
2094 o perso
2040 $ hg log -R a -r 2 --template '{strip(r"no perso\x6e", r"\x6e")}\n'
2095 $ hg log -R a -r 2 --template '{strip(r"no perso\x6e", r"\x6e")}\n'
2041 no perso
2096 no perso
2042
2097
2043 $ hg log -R a -r 2 --template '{sub("\\x6e", "\x2d", desc)}\n'
2098 $ hg log -R a -r 2 --template '{sub("\\x6e", "\x2d", desc)}\n'
2044 -o perso-
2099 -o perso-
2045 $ hg log -R a -r 2 --template '{sub(r"\\x6e", "-", desc)}\n'
2100 $ hg log -R a -r 2 --template '{sub(r"\\x6e", "-", desc)}\n'
2046 no person
2101 no person
2047 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", desc)}\n'
2102 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", desc)}\n'
2048 \x2do perso\x2d
2103 \x2do perso\x2d
2049 $ hg log -R a -r 2 --template '{sub("n", "\x2d", "no perso\x6e")}\n'
2104 $ hg log -R a -r 2 --template '{sub("n", "\x2d", "no perso\x6e")}\n'
2050 -o perso-
2105 -o perso-
2051 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", r"no perso\x6e")}\n'
2106 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", r"no perso\x6e")}\n'
2052 \x2do perso\x6e
2107 \x2do perso\x6e
2053
2108
2054 $ hg log -R a -r 8 --template '{files % "{file}\n"}'
2109 $ hg log -R a -r 8 --template '{files % "{file}\n"}'
2055 fourth
2110 fourth
2056 second
2111 second
2057 third
2112 third
2058 $ hg log -R a -r 8 --template '{files % r"{file}\n"}\n'
2113 $ hg log -R a -r 8 --template '{files % r"{file}\n"}\n'
2059 fourth\nsecond\nthird\n
2114 fourth\nsecond\nthird\n
2060
2115
2061 Test string escaping in nested expression:
2116 Test string escaping in nested expression:
2062
2117
2063 $ hg log -R a -r 8 --template '{ifeq(r"\x6e", if("1", "\x5c\x786e"), join(files, "\x5c\x786e"))}\n'
2118 $ hg log -R a -r 8 --template '{ifeq(r"\x6e", if("1", "\x5c\x786e"), join(files, "\x5c\x786e"))}\n'
2064 fourth\x6esecond\x6ethird
2119 fourth\x6esecond\x6ethird
2065 $ hg log -R a -r 8 --template '{ifeq(if("1", r"\x6e"), "\x5c\x786e", join(files, "\x5c\x786e"))}\n'
2120 $ hg log -R a -r 8 --template '{ifeq(if("1", r"\x6e"), "\x5c\x786e", join(files, "\x5c\x786e"))}\n'
2066 fourth\x6esecond\x6ethird
2121 fourth\x6esecond\x6ethird
2067
2122
2068 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", "\x5c\x786e"))}\n'
2123 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", "\x5c\x786e"))}\n'
2069 fourth\x6esecond\x6ethird
2124 fourth\x6esecond\x6ethird
2070 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", r"\x5c\x786e"))}\n'
2125 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", r"\x5c\x786e"))}\n'
2071 fourth\x5c\x786esecond\x5c\x786ethird
2126 fourth\x5c\x786esecond\x5c\x786ethird
2072
2127
2073 $ hg log -R a -r 3:4 --template '{rev}:{sub(if("1", "\x6e"), ifeq(branch, "foo", r"\x5c\x786e", "\x5c\x786e"), desc)}\n'
2128 $ hg log -R a -r 3:4 --template '{rev}:{sub(if("1", "\x6e"), ifeq(branch, "foo", r"\x5c\x786e", "\x5c\x786e"), desc)}\n'
2074 3:\x6eo user, \x6eo domai\x6e
2129 3:\x6eo user, \x6eo domai\x6e
2075 4:\x5c\x786eew bra\x5c\x786ech
2130 4:\x5c\x786eew bra\x5c\x786ech
2076
2131
2077 Test recursive evaluation:
2132 Test recursive evaluation:
2078
2133
2079 $ hg init r
2134 $ hg init r
2080 $ cd r
2135 $ cd r
2081 $ echo a > a
2136 $ echo a > a
2082 $ hg ci -Am '{rev}'
2137 $ hg ci -Am '{rev}'
2083 adding a
2138 adding a
2084 $ hg log -r 0 --template '{if(rev, desc)}\n'
2139 $ hg log -r 0 --template '{if(rev, desc)}\n'
2085 {rev}
2140 {rev}
2086 $ hg log -r 0 --template '{if(rev, "{author} {rev}")}\n'
2141 $ hg log -r 0 --template '{if(rev, "{author} {rev}")}\n'
2087 test 0
2142 test 0
2088
2143
2089 $ hg branch -q 'text.{rev}'
2144 $ hg branch -q 'text.{rev}'
2090 $ echo aa >> aa
2145 $ echo aa >> aa
2091 $ hg ci -u '{node|short}' -m 'desc to be wrapped desc to be wrapped'
2146 $ hg ci -u '{node|short}' -m 'desc to be wrapped desc to be wrapped'
2092
2147
2093 $ hg log -l1 --template '{fill(desc, "20", author, branch)}'
2148 $ hg log -l1 --template '{fill(desc, "20", author, branch)}'
2094 {node|short}desc to
2149 {node|short}desc to
2095 text.{rev}be wrapped
2150 text.{rev}be wrapped
2096 text.{rev}desc to be
2151 text.{rev}desc to be
2097 text.{rev}wrapped (no-eol)
2152 text.{rev}wrapped (no-eol)
2098 $ hg log -l1 --template '{fill(desc, "20", "{node|short}:", "text.{rev}:")}'
2153 $ hg log -l1 --template '{fill(desc, "20", "{node|short}:", "text.{rev}:")}'
2099 bcc7ff960b8e:desc to
2154 bcc7ff960b8e:desc to
2100 text.1:be wrapped
2155 text.1:be wrapped
2101 text.1:desc to be
2156 text.1:desc to be
2102 text.1:wrapped (no-eol)
2157 text.1:wrapped (no-eol)
2103
2158
2104 $ hg log -l 1 --template '{sub(r"[0-9]", "-", author)}'
2159 $ hg log -l 1 --template '{sub(r"[0-9]", "-", author)}'
2105 {node|short} (no-eol)
2160 {node|short} (no-eol)
2106 $ hg log -l 1 --template '{sub(r"[0-9]", "-", "{node|short}")}'
2161 $ hg log -l 1 --template '{sub(r"[0-9]", "-", "{node|short}")}'
2107 bcc-ff---b-e (no-eol)
2162 bcc-ff---b-e (no-eol)
2108
2163
2109 $ cat >> .hg/hgrc <<EOF
2164 $ cat >> .hg/hgrc <<EOF
2110 > [extensions]
2165 > [extensions]
2111 > color=
2166 > color=
2112 > [color]
2167 > [color]
2113 > mode=ansi
2168 > mode=ansi
2114 > text.{rev} = red
2169 > text.{rev} = red
2115 > text.1 = green
2170 > text.1 = green
2116 > EOF
2171 > EOF
2117 $ hg log --color=always -l 1 --template '{label(branch, "text\n")}'
2172 $ hg log --color=always -l 1 --template '{label(branch, "text\n")}'
2118 \x1b[0;31mtext\x1b[0m (esc)
2173 \x1b[0;31mtext\x1b[0m (esc)
2119 $ hg log --color=always -l 1 --template '{label("text.{rev}", "text\n")}'
2174 $ hg log --color=always -l 1 --template '{label("text.{rev}", "text\n")}'
2120 \x1b[0;32mtext\x1b[0m (esc)
2175 \x1b[0;32mtext\x1b[0m (esc)
2121
2176
2122 Test branches inside if statement:
2177 Test branches inside if statement:
2123
2178
2124 $ hg log -r 0 --template '{if(branches, "yes", "no")}\n'
2179 $ hg log -r 0 --template '{if(branches, "yes", "no")}\n'
2125 no
2180 no
2126
2181
2127 Test shortest(node) function:
2182 Test shortest(node) function:
2128
2183
2129 $ echo b > b
2184 $ echo b > b
2130 $ hg ci -qAm b
2185 $ hg ci -qAm b
2131 $ hg log --template '{shortest(node)}\n'
2186 $ hg log --template '{shortest(node)}\n'
2132 e777
2187 e777
2133 bcc7
2188 bcc7
2134 f776
2189 f776
2135 $ hg log --template '{shortest(node, 10)}\n'
2190 $ hg log --template '{shortest(node, 10)}\n'
2136 e777603221
2191 e777603221
2137 bcc7ff960b
2192 bcc7ff960b
2138 f7769ec2ab
2193 f7769ec2ab
2139
2194
2140 Test pad function
2195 Test pad function
2141
2196
2142 $ hg log --template '{pad(rev, 20)} {author|user}\n'
2197 $ hg log --template '{pad(rev, 20)} {author|user}\n'
2143 2 test
2198 2 test
2144 1 {node|short}
2199 1 {node|short}
2145 0 test
2200 0 test
2146
2201
2147 $ hg log --template '{pad(rev, 20, " ", True)} {author|user}\n'
2202 $ hg log --template '{pad(rev, 20, " ", True)} {author|user}\n'
2148 2 test
2203 2 test
2149 1 {node|short}
2204 1 {node|short}
2150 0 test
2205 0 test
2151
2206
2152 $ hg log --template '{pad(rev, 20, "-", False)} {author|user}\n'
2207 $ hg log --template '{pad(rev, 20, "-", False)} {author|user}\n'
2153 2------------------- test
2208 2------------------- test
2154 1------------------- {node|short}
2209 1------------------- {node|short}
2155 0------------------- test
2210 0------------------- test
2156
2211
2157 Test ifcontains function
2212 Test ifcontains function
2158
2213
2159 $ hg log --template '{rev} {ifcontains("a", file_adds, "added a", "did not add a")}\n'
2214 $ hg log --template '{rev} {ifcontains("a", file_adds, "added a", "did not add a")}\n'
2160 2 did not add a
2215 2 did not add a
2161 1 did not add a
2216 1 did not add a
2162 0 added a
2217 0 added a
2163
2218
2164 Test revset function
2219 Test revset function
2165
2220
2166 $ hg log --template '{rev} {ifcontains(rev, revset("."), "current rev", "not current rev")}\n'
2221 $ hg log --template '{rev} {ifcontains(rev, revset("."), "current rev", "not current rev")}\n'
2167 2 current rev
2222 2 current rev
2168 1 not current rev
2223 1 not current rev
2169 0 not current rev
2224 0 not current rev
2170
2225
2171 $ hg log --template '{rev} {ifcontains(rev, revset(". + .^"), "match rev", "not match rev")}\n'
2226 $ hg log --template '{rev} {ifcontains(rev, revset(". + .^"), "match rev", "not match rev")}\n'
2172 2 match rev
2227 2 match rev
2173 1 match rev
2228 1 match rev
2174 0 not match rev
2229 0 not match rev
2175
2230
2176 $ hg log --template '{rev} Parents: {revset("parents(%s)", rev)}\n'
2231 $ hg log --template '{rev} Parents: {revset("parents(%s)", rev)}\n'
2177 2 Parents: 1
2232 2 Parents: 1
2178 1 Parents: 0
2233 1 Parents: 0
2179 0 Parents:
2234 0 Parents:
2180
2235
2181 $ cat >> .hg/hgrc <<EOF
2236 $ cat >> .hg/hgrc <<EOF
2182 > [revsetalias]
2237 > [revsetalias]
2183 > myparents(\$1) = parents(\$1)
2238 > myparents(\$1) = parents(\$1)
2184 > EOF
2239 > EOF
2185 $ hg log --template '{rev} Parents: {revset("myparents(%s)", rev)}\n'
2240 $ hg log --template '{rev} Parents: {revset("myparents(%s)", rev)}\n'
2186 2 Parents: 1
2241 2 Parents: 1
2187 1 Parents: 0
2242 1 Parents: 0
2188 0 Parents:
2243 0 Parents:
2189
2244
2190 $ hg log --template 'Rev: {rev}\n{revset("::%s", rev) % "Ancestor: {revision}\n"}\n'
2245 $ hg log --template 'Rev: {rev}\n{revset("::%s", rev) % "Ancestor: {revision}\n"}\n'
2191 Rev: 2
2246 Rev: 2
2192 Ancestor: 0
2247 Ancestor: 0
2193 Ancestor: 1
2248 Ancestor: 1
2194 Ancestor: 2
2249 Ancestor: 2
2195
2250
2196 Rev: 1
2251 Rev: 1
2197 Ancestor: 0
2252 Ancestor: 0
2198 Ancestor: 1
2253 Ancestor: 1
2199
2254
2200 Rev: 0
2255 Rev: 0
2201 Ancestor: 0
2256 Ancestor: 0
2202
2257
2203 Test current bookmark templating
2258 Test current bookmark templating
2204
2259
2205 $ hg book foo
2260 $ hg book foo
2206 $ hg book bar
2261 $ hg book bar
2207 $ hg log --template "{rev} {bookmarks % '{bookmark}{ifeq(bookmark, current, \"*\")} '}\n"
2262 $ hg log --template "{rev} {bookmarks % '{bookmark}{ifeq(bookmark, current, \"*\")} '}\n"
2208 2 bar* foo
2263 2 bar* foo
2209 1
2264 1
2210 0
2265 0
2211 $ hg log --template "{rev} {currentbookmark}\n"
2266 $ hg log --template "{rev} {currentbookmark}\n"
2212 2 bar
2267 2 bar
2213 1
2268 1
2214 0
2269 0
2215 $ hg bookmarks --inactive bar
2270 $ hg bookmarks --inactive bar
2216 $ hg log --template "{rev} {currentbookmark}\n"
2271 $ hg log --template "{rev} {currentbookmark}\n"
2217 2
2272 2
2218 1
2273 1
2219 0
2274 0
2220
2275
2221 Test stringify on sub expressions
2276 Test stringify on sub expressions
2222
2277
2223 $ cd ..
2278 $ cd ..
2224 $ hg log -R a -r 8 --template '{join(files, if("1", if("1", ", ")))}\n'
2279 $ hg log -R a -r 8 --template '{join(files, if("1", if("1", ", ")))}\n'
2225 fourth, second, third
2280 fourth, second, third
2226 $ hg log -R a -r 8 --template '{strip(if("1", if("1", "-abc-")), if("1", if("1", "-")))}\n'
2281 $ hg log -R a -r 8 --template '{strip(if("1", if("1", "-abc-")), if("1", if("1", "-")))}\n'
2227 abc
2282 abc
2228
2283
2229 Test splitlines
2284 Test splitlines
2230
2285
2231 $ hg log -Gv -R a --template "{splitlines(desc) % 'foo {line}\n'}"
2286 $ hg log -Gv -R a --template "{splitlines(desc) % 'foo {line}\n'}"
2232 @ foo future
2287 @ foo future
2233 |
2288 |
2234 o foo third
2289 o foo third
2235 |
2290 |
2236 o foo second
2291 o foo second
2237
2292
2238 o foo merge
2293 o foo merge
2239 |\
2294 |\
2240 | o foo new head
2295 | o foo new head
2241 | |
2296 | |
2242 o | foo new branch
2297 o | foo new branch
2243 |/
2298 |/
2244 o foo no user, no domain
2299 o foo no user, no domain
2245 |
2300 |
2246 o foo no person
2301 o foo no person
2247 |
2302 |
2248 o foo other 1
2303 o foo other 1
2249 | foo other 2
2304 | foo other 2
2250 | foo
2305 | foo
2251 | foo other 3
2306 | foo other 3
2252 o foo line 1
2307 o foo line 1
2253 foo line 2
2308 foo line 2
2254
2309
2255 Test startswith
2310 Test startswith
2256 $ hg log -Gv -R a --template "{startswith(desc)}"
2311 $ hg log -Gv -R a --template "{startswith(desc)}"
2257 hg: parse error: startswith expects two arguments
2312 hg: parse error: startswith expects two arguments
2258 [255]
2313 [255]
2259
2314
2260 $ hg log -Gv -R a --template "{startswith('line', desc)}"
2315 $ hg log -Gv -R a --template "{startswith('line', desc)}"
2261 @
2316 @
2262 |
2317 |
2263 o
2318 o
2264 |
2319 |
2265 o
2320 o
2266
2321
2267 o
2322 o
2268 |\
2323 |\
2269 | o
2324 | o
2270 | |
2325 | |
2271 o |
2326 o |
2272 |/
2327 |/
2273 o
2328 o
2274 |
2329 |
2275 o
2330 o
2276 |
2331 |
2277 o
2332 o
2278 |
2333 |
2279 o line 1
2334 o line 1
2280 line 2
2335 line 2
2281
2336
2282 Test bad template with better error message
2337 Test bad template with better error message
2283
2338
2284 $ hg log -Gv -R a --template '{desc|user()}'
2339 $ hg log -Gv -R a --template '{desc|user()}'
2285 hg: parse error: expected a symbol, got 'func'
2340 hg: parse error: expected a symbol, got 'func'
2286 [255]
2341 [255]
2287
2342
2288 Test word function (including index out of bounds graceful failure)
2343 Test word function (including index out of bounds graceful failure)
2289
2344
2290 $ hg log -Gv -R a --template "{word('1', desc)}"
2345 $ hg log -Gv -R a --template "{word('1', desc)}"
2291 @
2346 @
2292 |
2347 |
2293 o
2348 o
2294 |
2349 |
2295 o
2350 o
2296
2351
2297 o
2352 o
2298 |\
2353 |\
2299 | o head
2354 | o head
2300 | |
2355 | |
2301 o | branch
2356 o | branch
2302 |/
2357 |/
2303 o user,
2358 o user,
2304 |
2359 |
2305 o person
2360 o person
2306 |
2361 |
2307 o 1
2362 o 1
2308 |
2363 |
2309 o 1
2364 o 1
2310
2365
2311
2366
2312 Test word third parameter used as splitter
2367 Test word third parameter used as splitter
2313
2368
2314 $ hg log -Gv -R a --template "{word('0', desc, 'o')}"
2369 $ hg log -Gv -R a --template "{word('0', desc, 'o')}"
2315 @ future
2370 @ future
2316 |
2371 |
2317 o third
2372 o third
2318 |
2373 |
2319 o sec
2374 o sec
2320
2375
2321 o merge
2376 o merge
2322 |\
2377 |\
2323 | o new head
2378 | o new head
2324 | |
2379 | |
2325 o | new branch
2380 o | new branch
2326 |/
2381 |/
2327 o n
2382 o n
2328 |
2383 |
2329 o n
2384 o n
2330 |
2385 |
2331 o
2386 o
2332 |
2387 |
2333 o line 1
2388 o line 1
2334 line 2
2389 line 2
2335
2390
2336 Test word error messages for not enough and too many arguments
2391 Test word error messages for not enough and too many arguments
2337
2392
2338 $ hg log -Gv -R a --template "{word('0')}"
2393 $ hg log -Gv -R a --template "{word('0')}"
2339 hg: parse error: word expects two or three arguments, got 1
2394 hg: parse error: word expects two or three arguments, got 1
2340 [255]
2395 [255]
2341
2396
2342 $ hg log -Gv -R a --template "{word('0', desc, 'o', 'h', 'b', 'o', 'y')}"
2397 $ hg log -Gv -R a --template "{word('0', desc, 'o', 'h', 'b', 'o', 'y')}"
2343 hg: parse error: word expects two or three arguments, got 7
2398 hg: parse error: word expects two or three arguments, got 7
2344 [255]
2399 [255]
General Comments 0
You need to be logged in to leave comments. Login now