##// END OF EJS Templates
templatefilters: declare input type as bytes where appropriate...
Yuya Nishihara -
r37240:08e042f0 default
parent child Browse files
Show More
@@ -1,468 +1,468 b''
1 # hgweb/hgweb_mod.py - Web interface for a repository.
1 # hgweb/hgweb_mod.py - Web interface for a repository.
2 #
2 #
3 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
3 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
4 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
5 #
5 #
6 # This software may be used and distributed according to the terms of the
6 # This software may be used and distributed according to the terms of the
7 # GNU General Public License version 2 or any later version.
7 # GNU General Public License version 2 or any later version.
8
8
9 from __future__ import absolute_import
9 from __future__ import absolute_import
10
10
11 import contextlib
11 import contextlib
12 import os
12 import os
13
13
14 from .common import (
14 from .common import (
15 ErrorResponse,
15 ErrorResponse,
16 HTTP_BAD_REQUEST,
16 HTTP_BAD_REQUEST,
17 cspvalues,
17 cspvalues,
18 permhooks,
18 permhooks,
19 statusmessage,
19 statusmessage,
20 )
20 )
21
21
22 from .. import (
22 from .. import (
23 encoding,
23 encoding,
24 error,
24 error,
25 formatter,
25 formatter,
26 hg,
26 hg,
27 hook,
27 hook,
28 profiling,
28 profiling,
29 pycompat,
29 pycompat,
30 registrar,
30 registrar,
31 repoview,
31 repoview,
32 templatefilters,
32 templatefilters,
33 templater,
33 templater,
34 ui as uimod,
34 ui as uimod,
35 util,
35 util,
36 wireprotoserver,
36 wireprotoserver,
37 )
37 )
38
38
39 from . import (
39 from . import (
40 request as requestmod,
40 request as requestmod,
41 webcommands,
41 webcommands,
42 webutil,
42 webutil,
43 wsgicgi,
43 wsgicgi,
44 )
44 )
45
45
46 archivespecs = util.sortdict((
46 archivespecs = util.sortdict((
47 ('zip', ('application/zip', 'zip', '.zip', None)),
47 ('zip', ('application/zip', 'zip', '.zip', None)),
48 ('gz', ('application/x-gzip', 'tgz', '.tar.gz', None)),
48 ('gz', ('application/x-gzip', 'tgz', '.tar.gz', None)),
49 ('bz2', ('application/x-bzip2', 'tbz2', '.tar.bz2', None)),
49 ('bz2', ('application/x-bzip2', 'tbz2', '.tar.bz2', None)),
50 ))
50 ))
51
51
52 def getstyle(req, configfn, templatepath):
52 def getstyle(req, configfn, templatepath):
53 styles = (
53 styles = (
54 req.qsparams.get('style', None),
54 req.qsparams.get('style', None),
55 configfn('web', 'style'),
55 configfn('web', 'style'),
56 'paper',
56 'paper',
57 )
57 )
58 return styles, templater.stylemap(styles, templatepath)
58 return styles, templater.stylemap(styles, templatepath)
59
59
60 def makebreadcrumb(url, prefix=''):
60 def makebreadcrumb(url, prefix=''):
61 '''Return a 'URL breadcrumb' list
61 '''Return a 'URL breadcrumb' list
62
62
63 A 'URL breadcrumb' is a list of URL-name pairs,
63 A 'URL breadcrumb' is a list of URL-name pairs,
64 corresponding to each of the path items on a URL.
64 corresponding to each of the path items on a URL.
65 This can be used to create path navigation entries.
65 This can be used to create path navigation entries.
66 '''
66 '''
67 if url.endswith('/'):
67 if url.endswith('/'):
68 url = url[:-1]
68 url = url[:-1]
69 if prefix:
69 if prefix:
70 url = '/' + prefix + url
70 url = '/' + prefix + url
71 relpath = url
71 relpath = url
72 if relpath.startswith('/'):
72 if relpath.startswith('/'):
73 relpath = relpath[1:]
73 relpath = relpath[1:]
74
74
75 breadcrumb = []
75 breadcrumb = []
76 urlel = url
76 urlel = url
77 pathitems = [''] + relpath.split('/')
77 pathitems = [''] + relpath.split('/')
78 for pathel in reversed(pathitems):
78 for pathel in reversed(pathitems):
79 if not pathel or not urlel:
79 if not pathel or not urlel:
80 break
80 break
81 breadcrumb.append({'url': urlel, 'name': pathel})
81 breadcrumb.append({'url': urlel, 'name': pathel})
82 urlel = os.path.dirname(urlel)
82 urlel = os.path.dirname(urlel)
83 return reversed(breadcrumb)
83 return reversed(breadcrumb)
84
84
85 class requestcontext(object):
85 class requestcontext(object):
86 """Holds state/context for an individual request.
86 """Holds state/context for an individual request.
87
87
88 Servers can be multi-threaded. Holding state on the WSGI application
88 Servers can be multi-threaded. Holding state on the WSGI application
89 is prone to race conditions. Instances of this class exist to hold
89 is prone to race conditions. Instances of this class exist to hold
90 mutable and race-free state for requests.
90 mutable and race-free state for requests.
91 """
91 """
92 def __init__(self, app, repo, req, res):
92 def __init__(self, app, repo, req, res):
93 self.repo = repo
93 self.repo = repo
94 self.reponame = app.reponame
94 self.reponame = app.reponame
95 self.req = req
95 self.req = req
96 self.res = res
96 self.res = res
97
97
98 self.archivespecs = archivespecs
98 self.archivespecs = archivespecs
99
99
100 self.maxchanges = self.configint('web', 'maxchanges')
100 self.maxchanges = self.configint('web', 'maxchanges')
101 self.stripecount = self.configint('web', 'stripes')
101 self.stripecount = self.configint('web', 'stripes')
102 self.maxshortchanges = self.configint('web', 'maxshortchanges')
102 self.maxshortchanges = self.configint('web', 'maxshortchanges')
103 self.maxfiles = self.configint('web', 'maxfiles')
103 self.maxfiles = self.configint('web', 'maxfiles')
104 self.allowpull = self.configbool('web', 'allow-pull')
104 self.allowpull = self.configbool('web', 'allow-pull')
105
105
106 # we use untrusted=False to prevent a repo owner from using
106 # we use untrusted=False to prevent a repo owner from using
107 # web.templates in .hg/hgrc to get access to any file readable
107 # web.templates in .hg/hgrc to get access to any file readable
108 # by the user running the CGI script
108 # by the user running the CGI script
109 self.templatepath = self.config('web', 'templates', untrusted=False)
109 self.templatepath = self.config('web', 'templates', untrusted=False)
110
110
111 # This object is more expensive to build than simple config values.
111 # This object is more expensive to build than simple config values.
112 # It is shared across requests. The app will replace the object
112 # It is shared across requests. The app will replace the object
113 # if it is updated. Since this is a reference and nothing should
113 # if it is updated. Since this is a reference and nothing should
114 # modify the underlying object, it should be constant for the lifetime
114 # modify the underlying object, it should be constant for the lifetime
115 # of the request.
115 # of the request.
116 self.websubtable = app.websubtable
116 self.websubtable = app.websubtable
117
117
118 self.csp, self.nonce = cspvalues(self.repo.ui)
118 self.csp, self.nonce = cspvalues(self.repo.ui)
119
119
120 # Trust the settings from the .hg/hgrc files by default.
120 # Trust the settings from the .hg/hgrc files by default.
121 def config(self, section, name, default=uimod._unset, untrusted=True):
121 def config(self, section, name, default=uimod._unset, untrusted=True):
122 return self.repo.ui.config(section, name, default,
122 return self.repo.ui.config(section, name, default,
123 untrusted=untrusted)
123 untrusted=untrusted)
124
124
125 def configbool(self, section, name, default=uimod._unset, untrusted=True):
125 def configbool(self, section, name, default=uimod._unset, untrusted=True):
126 return self.repo.ui.configbool(section, name, default,
126 return self.repo.ui.configbool(section, name, default,
127 untrusted=untrusted)
127 untrusted=untrusted)
128
128
129 def configint(self, section, name, default=uimod._unset, untrusted=True):
129 def configint(self, section, name, default=uimod._unset, untrusted=True):
130 return self.repo.ui.configint(section, name, default,
130 return self.repo.ui.configint(section, name, default,
131 untrusted=untrusted)
131 untrusted=untrusted)
132
132
133 def configlist(self, section, name, default=uimod._unset, untrusted=True):
133 def configlist(self, section, name, default=uimod._unset, untrusted=True):
134 return self.repo.ui.configlist(section, name, default,
134 return self.repo.ui.configlist(section, name, default,
135 untrusted=untrusted)
135 untrusted=untrusted)
136
136
137 def archivelist(self, nodeid):
137 def archivelist(self, nodeid):
138 allowed = self.configlist('web', 'allow_archive')
138 allowed = self.configlist('web', 'allow_archive')
139 for typ, spec in self.archivespecs.iteritems():
139 for typ, spec in self.archivespecs.iteritems():
140 if typ in allowed or self.configbool('web', 'allow%s' % typ):
140 if typ in allowed or self.configbool('web', 'allow%s' % typ):
141 yield {'type': typ, 'extension': spec[2], 'node': nodeid}
141 yield {'type': typ, 'extension': spec[2], 'node': nodeid}
142
142
143 def templater(self, req):
143 def templater(self, req):
144 # determine scheme, port and server name
144 # determine scheme, port and server name
145 # this is needed to create absolute urls
145 # this is needed to create absolute urls
146 logourl = self.config('web', 'logourl')
146 logourl = self.config('web', 'logourl')
147 logoimg = self.config('web', 'logoimg')
147 logoimg = self.config('web', 'logoimg')
148 staticurl = (self.config('web', 'staticurl')
148 staticurl = (self.config('web', 'staticurl')
149 or req.apppath + '/static/')
149 or req.apppath + '/static/')
150 if not staticurl.endswith('/'):
150 if not staticurl.endswith('/'):
151 staticurl += '/'
151 staticurl += '/'
152
152
153 # some functions for the templater
153 # some functions for the templater
154
154
155 def motd(**map):
155 def motd(**map):
156 yield self.config('web', 'motd')
156 yield self.config('web', 'motd')
157
157
158 # figure out which style to use
158 # figure out which style to use
159
159
160 vars = {}
160 vars = {}
161 styles, (style, mapfile) = getstyle(req, self.config,
161 styles, (style, mapfile) = getstyle(req, self.config,
162 self.templatepath)
162 self.templatepath)
163 if style == styles[0]:
163 if style == styles[0]:
164 vars['style'] = style
164 vars['style'] = style
165
165
166 sessionvars = webutil.sessionvars(vars, '?')
166 sessionvars = webutil.sessionvars(vars, '?')
167
167
168 if not self.reponame:
168 if not self.reponame:
169 self.reponame = (self.config('web', 'name', '')
169 self.reponame = (self.config('web', 'name', '')
170 or req.reponame
170 or req.reponame
171 or req.apppath
171 or req.apppath
172 or self.repo.root)
172 or self.repo.root)
173
173
174 filters = {}
174 filters = {}
175 templatefilter = registrar.templatefilter(filters)
175 templatefilter = registrar.templatefilter(filters)
176 @templatefilter('websub')
176 @templatefilter('websub', intype=bytes)
177 def websubfilter(text):
177 def websubfilter(text):
178 return templatefilters.websub(text, self.websubtable)
178 return templatefilters.websub(text, self.websubtable)
179
179
180 # create the templater
180 # create the templater
181 # TODO: export all keywords: defaults = templatekw.keywords.copy()
181 # TODO: export all keywords: defaults = templatekw.keywords.copy()
182 defaults = {
182 defaults = {
183 'url': req.apppath + '/',
183 'url': req.apppath + '/',
184 'logourl': logourl,
184 'logourl': logourl,
185 'logoimg': logoimg,
185 'logoimg': logoimg,
186 'staticurl': staticurl,
186 'staticurl': staticurl,
187 'urlbase': req.advertisedbaseurl,
187 'urlbase': req.advertisedbaseurl,
188 'repo': self.reponame,
188 'repo': self.reponame,
189 'encoding': encoding.encoding,
189 'encoding': encoding.encoding,
190 'motd': motd,
190 'motd': motd,
191 'sessionvars': sessionvars,
191 'sessionvars': sessionvars,
192 'pathdef': makebreadcrumb(req.apppath),
192 'pathdef': makebreadcrumb(req.apppath),
193 'style': style,
193 'style': style,
194 'nonce': self.nonce,
194 'nonce': self.nonce,
195 }
195 }
196 tres = formatter.templateresources(self.repo.ui, self.repo)
196 tres = formatter.templateresources(self.repo.ui, self.repo)
197 tmpl = templater.templater.frommapfile(mapfile,
197 tmpl = templater.templater.frommapfile(mapfile,
198 filters=filters,
198 filters=filters,
199 defaults=defaults,
199 defaults=defaults,
200 resources=tres)
200 resources=tres)
201 return tmpl
201 return tmpl
202
202
203 def sendtemplate(self, name, **kwargs):
203 def sendtemplate(self, name, **kwargs):
204 """Helper function to send a response generated from a template."""
204 """Helper function to send a response generated from a template."""
205 kwargs = pycompat.byteskwargs(kwargs)
205 kwargs = pycompat.byteskwargs(kwargs)
206 self.res.setbodygen(self.tmpl.generate(name, kwargs))
206 self.res.setbodygen(self.tmpl.generate(name, kwargs))
207 return self.res.sendresponse()
207 return self.res.sendresponse()
208
208
209 class hgweb(object):
209 class hgweb(object):
210 """HTTP server for individual repositories.
210 """HTTP server for individual repositories.
211
211
212 Instances of this class serve HTTP responses for a particular
212 Instances of this class serve HTTP responses for a particular
213 repository.
213 repository.
214
214
215 Instances are typically used as WSGI applications.
215 Instances are typically used as WSGI applications.
216
216
217 Some servers are multi-threaded. On these servers, there may
217 Some servers are multi-threaded. On these servers, there may
218 be multiple active threads inside __call__.
218 be multiple active threads inside __call__.
219 """
219 """
220 def __init__(self, repo, name=None, baseui=None):
220 def __init__(self, repo, name=None, baseui=None):
221 if isinstance(repo, str):
221 if isinstance(repo, str):
222 if baseui:
222 if baseui:
223 u = baseui.copy()
223 u = baseui.copy()
224 else:
224 else:
225 u = uimod.ui.load()
225 u = uimod.ui.load()
226 r = hg.repository(u, repo)
226 r = hg.repository(u, repo)
227 else:
227 else:
228 # we trust caller to give us a private copy
228 # we trust caller to give us a private copy
229 r = repo
229 r = repo
230
230
231 r.ui.setconfig('ui', 'report_untrusted', 'off', 'hgweb')
231 r.ui.setconfig('ui', 'report_untrusted', 'off', 'hgweb')
232 r.baseui.setconfig('ui', 'report_untrusted', 'off', 'hgweb')
232 r.baseui.setconfig('ui', 'report_untrusted', 'off', 'hgweb')
233 r.ui.setconfig('ui', 'nontty', 'true', 'hgweb')
233 r.ui.setconfig('ui', 'nontty', 'true', 'hgweb')
234 r.baseui.setconfig('ui', 'nontty', 'true', 'hgweb')
234 r.baseui.setconfig('ui', 'nontty', 'true', 'hgweb')
235 # resolve file patterns relative to repo root
235 # resolve file patterns relative to repo root
236 r.ui.setconfig('ui', 'forcecwd', r.root, 'hgweb')
236 r.ui.setconfig('ui', 'forcecwd', r.root, 'hgweb')
237 r.baseui.setconfig('ui', 'forcecwd', r.root, 'hgweb')
237 r.baseui.setconfig('ui', 'forcecwd', r.root, 'hgweb')
238 # displaying bundling progress bar while serving feel wrong and may
238 # displaying bundling progress bar while serving feel wrong and may
239 # break some wsgi implementation.
239 # break some wsgi implementation.
240 r.ui.setconfig('progress', 'disable', 'true', 'hgweb')
240 r.ui.setconfig('progress', 'disable', 'true', 'hgweb')
241 r.baseui.setconfig('progress', 'disable', 'true', 'hgweb')
241 r.baseui.setconfig('progress', 'disable', 'true', 'hgweb')
242 self._repos = [hg.cachedlocalrepo(self._webifyrepo(r))]
242 self._repos = [hg.cachedlocalrepo(self._webifyrepo(r))]
243 self._lastrepo = self._repos[0]
243 self._lastrepo = self._repos[0]
244 hook.redirect(True)
244 hook.redirect(True)
245 self.reponame = name
245 self.reponame = name
246
246
247 def _webifyrepo(self, repo):
247 def _webifyrepo(self, repo):
248 repo = getwebview(repo)
248 repo = getwebview(repo)
249 self.websubtable = webutil.getwebsubs(repo)
249 self.websubtable = webutil.getwebsubs(repo)
250 return repo
250 return repo
251
251
252 @contextlib.contextmanager
252 @contextlib.contextmanager
253 def _obtainrepo(self):
253 def _obtainrepo(self):
254 """Obtain a repo unique to the caller.
254 """Obtain a repo unique to the caller.
255
255
256 Internally we maintain a stack of cachedlocalrepo instances
256 Internally we maintain a stack of cachedlocalrepo instances
257 to be handed out. If one is available, we pop it and return it,
257 to be handed out. If one is available, we pop it and return it,
258 ensuring it is up to date in the process. If one is not available,
258 ensuring it is up to date in the process. If one is not available,
259 we clone the most recently used repo instance and return it.
259 we clone the most recently used repo instance and return it.
260
260
261 It is currently possible for the stack to grow without bounds
261 It is currently possible for the stack to grow without bounds
262 if the server allows infinite threads. However, servers should
262 if the server allows infinite threads. However, servers should
263 have a thread limit, thus establishing our limit.
263 have a thread limit, thus establishing our limit.
264 """
264 """
265 if self._repos:
265 if self._repos:
266 cached = self._repos.pop()
266 cached = self._repos.pop()
267 r, created = cached.fetch()
267 r, created = cached.fetch()
268 else:
268 else:
269 cached = self._lastrepo.copy()
269 cached = self._lastrepo.copy()
270 r, created = cached.fetch()
270 r, created = cached.fetch()
271 if created:
271 if created:
272 r = self._webifyrepo(r)
272 r = self._webifyrepo(r)
273
273
274 self._lastrepo = cached
274 self._lastrepo = cached
275 self.mtime = cached.mtime
275 self.mtime = cached.mtime
276 try:
276 try:
277 yield r
277 yield r
278 finally:
278 finally:
279 self._repos.append(cached)
279 self._repos.append(cached)
280
280
281 def run(self):
281 def run(self):
282 """Start a server from CGI environment.
282 """Start a server from CGI environment.
283
283
284 Modern servers should be using WSGI and should avoid this
284 Modern servers should be using WSGI and should avoid this
285 method, if possible.
285 method, if possible.
286 """
286 """
287 if not encoding.environ.get('GATEWAY_INTERFACE',
287 if not encoding.environ.get('GATEWAY_INTERFACE',
288 '').startswith("CGI/1."):
288 '').startswith("CGI/1."):
289 raise RuntimeError("This function is only intended to be "
289 raise RuntimeError("This function is only intended to be "
290 "called while running as a CGI script.")
290 "called while running as a CGI script.")
291 wsgicgi.launch(self)
291 wsgicgi.launch(self)
292
292
293 def __call__(self, env, respond):
293 def __call__(self, env, respond):
294 """Run the WSGI application.
294 """Run the WSGI application.
295
295
296 This may be called by multiple threads.
296 This may be called by multiple threads.
297 """
297 """
298 req = requestmod.parserequestfromenv(env)
298 req = requestmod.parserequestfromenv(env)
299 res = requestmod.wsgiresponse(req, respond)
299 res = requestmod.wsgiresponse(req, respond)
300
300
301 return self.run_wsgi(req, res)
301 return self.run_wsgi(req, res)
302
302
303 def run_wsgi(self, req, res):
303 def run_wsgi(self, req, res):
304 """Internal method to run the WSGI application.
304 """Internal method to run the WSGI application.
305
305
306 This is typically only called by Mercurial. External consumers
306 This is typically only called by Mercurial. External consumers
307 should be using instances of this class as the WSGI application.
307 should be using instances of this class as the WSGI application.
308 """
308 """
309 with self._obtainrepo() as repo:
309 with self._obtainrepo() as repo:
310 profile = repo.ui.configbool('profiling', 'enabled')
310 profile = repo.ui.configbool('profiling', 'enabled')
311 with profiling.profile(repo.ui, enabled=profile):
311 with profiling.profile(repo.ui, enabled=profile):
312 for r in self._runwsgi(req, res, repo):
312 for r in self._runwsgi(req, res, repo):
313 yield r
313 yield r
314
314
315 def _runwsgi(self, req, res, repo):
315 def _runwsgi(self, req, res, repo):
316 rctx = requestcontext(self, repo, req, res)
316 rctx = requestcontext(self, repo, req, res)
317
317
318 # This state is global across all threads.
318 # This state is global across all threads.
319 encoding.encoding = rctx.config('web', 'encoding')
319 encoding.encoding = rctx.config('web', 'encoding')
320 rctx.repo.ui.environ = req.rawenv
320 rctx.repo.ui.environ = req.rawenv
321
321
322 if rctx.csp:
322 if rctx.csp:
323 # hgwebdir may have added CSP header. Since we generate our own,
323 # hgwebdir may have added CSP header. Since we generate our own,
324 # replace it.
324 # replace it.
325 res.headers['Content-Security-Policy'] = rctx.csp
325 res.headers['Content-Security-Policy'] = rctx.csp
326
326
327 # /api/* is reserved for various API implementations. Dispatch
327 # /api/* is reserved for various API implementations. Dispatch
328 # accordingly. But URL paths can conflict with subrepos and virtual
328 # accordingly. But URL paths can conflict with subrepos and virtual
329 # repos in hgwebdir. So until we have a workaround for this, only
329 # repos in hgwebdir. So until we have a workaround for this, only
330 # expose the URLs if the feature is enabled.
330 # expose the URLs if the feature is enabled.
331 apienabled = rctx.repo.ui.configbool('experimental', 'web.apiserver')
331 apienabled = rctx.repo.ui.configbool('experimental', 'web.apiserver')
332 if apienabled and req.dispatchparts and req.dispatchparts[0] == b'api':
332 if apienabled and req.dispatchparts and req.dispatchparts[0] == b'api':
333 wireprotoserver.handlewsgiapirequest(rctx, req, res,
333 wireprotoserver.handlewsgiapirequest(rctx, req, res,
334 self.check_perm)
334 self.check_perm)
335 return res.sendresponse()
335 return res.sendresponse()
336
336
337 handled = wireprotoserver.handlewsgirequest(
337 handled = wireprotoserver.handlewsgirequest(
338 rctx, req, res, self.check_perm)
338 rctx, req, res, self.check_perm)
339 if handled:
339 if handled:
340 return res.sendresponse()
340 return res.sendresponse()
341
341
342 # Old implementations of hgweb supported dispatching the request via
342 # Old implementations of hgweb supported dispatching the request via
343 # the initial query string parameter instead of using PATH_INFO.
343 # the initial query string parameter instead of using PATH_INFO.
344 # If PATH_INFO is present (signaled by ``req.dispatchpath`` having
344 # If PATH_INFO is present (signaled by ``req.dispatchpath`` having
345 # a value), we use it. Otherwise fall back to the query string.
345 # a value), we use it. Otherwise fall back to the query string.
346 if req.dispatchpath is not None:
346 if req.dispatchpath is not None:
347 query = req.dispatchpath
347 query = req.dispatchpath
348 else:
348 else:
349 query = req.querystring.partition('&')[0].partition(';')[0]
349 query = req.querystring.partition('&')[0].partition(';')[0]
350
350
351 # translate user-visible url structure to internal structure
351 # translate user-visible url structure to internal structure
352
352
353 args = query.split('/', 2)
353 args = query.split('/', 2)
354 if 'cmd' not in req.qsparams and args and args[0]:
354 if 'cmd' not in req.qsparams and args and args[0]:
355 cmd = args.pop(0)
355 cmd = args.pop(0)
356 style = cmd.rfind('-')
356 style = cmd.rfind('-')
357 if style != -1:
357 if style != -1:
358 req.qsparams['style'] = cmd[:style]
358 req.qsparams['style'] = cmd[:style]
359 cmd = cmd[style + 1:]
359 cmd = cmd[style + 1:]
360
360
361 # avoid accepting e.g. style parameter as command
361 # avoid accepting e.g. style parameter as command
362 if util.safehasattr(webcommands, cmd):
362 if util.safehasattr(webcommands, cmd):
363 req.qsparams['cmd'] = cmd
363 req.qsparams['cmd'] = cmd
364
364
365 if cmd == 'static':
365 if cmd == 'static':
366 req.qsparams['file'] = '/'.join(args)
366 req.qsparams['file'] = '/'.join(args)
367 else:
367 else:
368 if args and args[0]:
368 if args and args[0]:
369 node = args.pop(0).replace('%2F', '/')
369 node = args.pop(0).replace('%2F', '/')
370 req.qsparams['node'] = node
370 req.qsparams['node'] = node
371 if args:
371 if args:
372 if 'file' in req.qsparams:
372 if 'file' in req.qsparams:
373 del req.qsparams['file']
373 del req.qsparams['file']
374 for a in args:
374 for a in args:
375 req.qsparams.add('file', a)
375 req.qsparams.add('file', a)
376
376
377 ua = req.headers.get('User-Agent', '')
377 ua = req.headers.get('User-Agent', '')
378 if cmd == 'rev' and 'mercurial' in ua:
378 if cmd == 'rev' and 'mercurial' in ua:
379 req.qsparams['style'] = 'raw'
379 req.qsparams['style'] = 'raw'
380
380
381 if cmd == 'archive':
381 if cmd == 'archive':
382 fn = req.qsparams['node']
382 fn = req.qsparams['node']
383 for type_, spec in rctx.archivespecs.iteritems():
383 for type_, spec in rctx.archivespecs.iteritems():
384 ext = spec[2]
384 ext = spec[2]
385 if fn.endswith(ext):
385 if fn.endswith(ext):
386 req.qsparams['node'] = fn[:-len(ext)]
386 req.qsparams['node'] = fn[:-len(ext)]
387 req.qsparams['type'] = type_
387 req.qsparams['type'] = type_
388 else:
388 else:
389 cmd = req.qsparams.get('cmd', '')
389 cmd = req.qsparams.get('cmd', '')
390
390
391 # process the web interface request
391 # process the web interface request
392
392
393 try:
393 try:
394 rctx.tmpl = rctx.templater(req)
394 rctx.tmpl = rctx.templater(req)
395 ctype = rctx.tmpl.render('mimetype',
395 ctype = rctx.tmpl.render('mimetype',
396 {'encoding': encoding.encoding})
396 {'encoding': encoding.encoding})
397
397
398 # check read permissions non-static content
398 # check read permissions non-static content
399 if cmd != 'static':
399 if cmd != 'static':
400 self.check_perm(rctx, req, None)
400 self.check_perm(rctx, req, None)
401
401
402 if cmd == '':
402 if cmd == '':
403 req.qsparams['cmd'] = rctx.tmpl.render('default', {})
403 req.qsparams['cmd'] = rctx.tmpl.render('default', {})
404 cmd = req.qsparams['cmd']
404 cmd = req.qsparams['cmd']
405
405
406 # Don't enable caching if using a CSP nonce because then it wouldn't
406 # Don't enable caching if using a CSP nonce because then it wouldn't
407 # be a nonce.
407 # be a nonce.
408 if rctx.configbool('web', 'cache') and not rctx.nonce:
408 if rctx.configbool('web', 'cache') and not rctx.nonce:
409 tag = 'W/"%d"' % self.mtime
409 tag = 'W/"%d"' % self.mtime
410 if req.headers.get('If-None-Match') == tag:
410 if req.headers.get('If-None-Match') == tag:
411 res.status = '304 Not Modified'
411 res.status = '304 Not Modified'
412 # Response body not allowed on 304.
412 # Response body not allowed on 304.
413 res.setbodybytes('')
413 res.setbodybytes('')
414 return res.sendresponse()
414 return res.sendresponse()
415
415
416 res.headers['ETag'] = tag
416 res.headers['ETag'] = tag
417
417
418 if cmd not in webcommands.__all__:
418 if cmd not in webcommands.__all__:
419 msg = 'no such method: %s' % cmd
419 msg = 'no such method: %s' % cmd
420 raise ErrorResponse(HTTP_BAD_REQUEST, msg)
420 raise ErrorResponse(HTTP_BAD_REQUEST, msg)
421 else:
421 else:
422 # Set some globals appropriate for web handlers. Commands can
422 # Set some globals appropriate for web handlers. Commands can
423 # override easily enough.
423 # override easily enough.
424 res.status = '200 Script output follows'
424 res.status = '200 Script output follows'
425 res.headers['Content-Type'] = ctype
425 res.headers['Content-Type'] = ctype
426 return getattr(webcommands, cmd)(rctx)
426 return getattr(webcommands, cmd)(rctx)
427
427
428 except (error.LookupError, error.RepoLookupError) as err:
428 except (error.LookupError, error.RepoLookupError) as err:
429 msg = pycompat.bytestr(err)
429 msg = pycompat.bytestr(err)
430 if (util.safehasattr(err, 'name') and
430 if (util.safehasattr(err, 'name') and
431 not isinstance(err, error.ManifestLookupError)):
431 not isinstance(err, error.ManifestLookupError)):
432 msg = 'revision not found: %s' % err.name
432 msg = 'revision not found: %s' % err.name
433
433
434 res.status = '404 Not Found'
434 res.status = '404 Not Found'
435 res.headers['Content-Type'] = ctype
435 res.headers['Content-Type'] = ctype
436 return rctx.sendtemplate('error', error=msg)
436 return rctx.sendtemplate('error', error=msg)
437 except (error.RepoError, error.RevlogError) as e:
437 except (error.RepoError, error.RevlogError) as e:
438 res.status = '500 Internal Server Error'
438 res.status = '500 Internal Server Error'
439 res.headers['Content-Type'] = ctype
439 res.headers['Content-Type'] = ctype
440 return rctx.sendtemplate('error', error=pycompat.bytestr(e))
440 return rctx.sendtemplate('error', error=pycompat.bytestr(e))
441 except ErrorResponse as e:
441 except ErrorResponse as e:
442 res.status = statusmessage(e.code, pycompat.bytestr(e))
442 res.status = statusmessage(e.code, pycompat.bytestr(e))
443 res.headers['Content-Type'] = ctype
443 res.headers['Content-Type'] = ctype
444 return rctx.sendtemplate('error', error=pycompat.bytestr(e))
444 return rctx.sendtemplate('error', error=pycompat.bytestr(e))
445
445
446 def check_perm(self, rctx, req, op):
446 def check_perm(self, rctx, req, op):
447 for permhook in permhooks:
447 for permhook in permhooks:
448 permhook(rctx, req, op)
448 permhook(rctx, req, op)
449
449
450 def getwebview(repo):
450 def getwebview(repo):
451 """The 'web.view' config controls changeset filter to hgweb. Possible
451 """The 'web.view' config controls changeset filter to hgweb. Possible
452 values are ``served``, ``visible`` and ``all``. Default is ``served``.
452 values are ``served``, ``visible`` and ``all``. Default is ``served``.
453 The ``served`` filter only shows changesets that can be pulled from the
453 The ``served`` filter only shows changesets that can be pulled from the
454 hgweb instance. The``visible`` filter includes secret changesets but
454 hgweb instance. The``visible`` filter includes secret changesets but
455 still excludes "hidden" one.
455 still excludes "hidden" one.
456
456
457 See the repoview module for details.
457 See the repoview module for details.
458
458
459 The option has been around undocumented since Mercurial 2.5, but no
459 The option has been around undocumented since Mercurial 2.5, but no
460 user ever asked about it. So we better keep it undocumented for now."""
460 user ever asked about it. So we better keep it undocumented for now."""
461 # experimental config: web.view
461 # experimental config: web.view
462 viewconfig = repo.ui.config('web', 'view', untrusted=True)
462 viewconfig = repo.ui.config('web', 'view', untrusted=True)
463 if viewconfig == 'all':
463 if viewconfig == 'all':
464 return repo.unfiltered()
464 return repo.unfiltered()
465 elif viewconfig in repoview.filtertable:
465 elif viewconfig in repoview.filtertable:
466 return repo.filtered(viewconfig)
466 return repo.filtered(viewconfig)
467 else:
467 else:
468 return repo.filtered('served')
468 return repo.filtered('served')
@@ -1,436 +1,436 b''
1 # templatefilters.py - common template expansion filters
1 # templatefilters.py - common template expansion filters
2 #
2 #
3 # Copyright 2005-2008 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2008 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 __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import os
10 import os
11 import re
11 import re
12 import time
12 import time
13
13
14 from . import (
14 from . import (
15 encoding,
15 encoding,
16 error,
16 error,
17 node,
17 node,
18 pycompat,
18 pycompat,
19 registrar,
19 registrar,
20 templateutil,
20 templateutil,
21 url,
21 url,
22 util,
22 util,
23 )
23 )
24 from .utils import (
24 from .utils import (
25 dateutil,
25 dateutil,
26 stringutil,
26 stringutil,
27 )
27 )
28
28
29 urlerr = util.urlerr
29 urlerr = util.urlerr
30 urlreq = util.urlreq
30 urlreq = util.urlreq
31
31
32 if pycompat.ispy3:
32 if pycompat.ispy3:
33 long = int
33 long = int
34
34
35 # filters are callables like:
35 # filters are callables like:
36 # fn(obj)
36 # fn(obj)
37 # with:
37 # with:
38 # obj - object to be filtered (text, date, list and so on)
38 # obj - object to be filtered (text, date, list and so on)
39 filters = {}
39 filters = {}
40
40
41 templatefilter = registrar.templatefilter(filters)
41 templatefilter = registrar.templatefilter(filters)
42
42
43 @templatefilter('addbreaks')
43 @templatefilter('addbreaks', intype=bytes)
44 def addbreaks(text):
44 def addbreaks(text):
45 """Any text. Add an XHTML "<br />" tag before the end of
45 """Any text. Add an XHTML "<br />" tag before the end of
46 every line except the last.
46 every line except the last.
47 """
47 """
48 return text.replace('\n', '<br/>\n')
48 return text.replace('\n', '<br/>\n')
49
49
50 agescales = [("year", 3600 * 24 * 365, 'Y'),
50 agescales = [("year", 3600 * 24 * 365, 'Y'),
51 ("month", 3600 * 24 * 30, 'M'),
51 ("month", 3600 * 24 * 30, 'M'),
52 ("week", 3600 * 24 * 7, 'W'),
52 ("week", 3600 * 24 * 7, 'W'),
53 ("day", 3600 * 24, 'd'),
53 ("day", 3600 * 24, 'd'),
54 ("hour", 3600, 'h'),
54 ("hour", 3600, 'h'),
55 ("minute", 60, 'm'),
55 ("minute", 60, 'm'),
56 ("second", 1, 's')]
56 ("second", 1, 's')]
57
57
58 @templatefilter('age')
58 @templatefilter('age')
59 def age(date, abbrev=False):
59 def age(date, abbrev=False):
60 """Date. Returns a human-readable date/time difference between the
60 """Date. Returns a human-readable date/time difference between the
61 given date/time and the current date/time.
61 given date/time and the current date/time.
62 """
62 """
63
63
64 def plural(t, c):
64 def plural(t, c):
65 if c == 1:
65 if c == 1:
66 return t
66 return t
67 return t + "s"
67 return t + "s"
68 def fmt(t, c, a):
68 def fmt(t, c, a):
69 if abbrev:
69 if abbrev:
70 return "%d%s" % (c, a)
70 return "%d%s" % (c, a)
71 return "%d %s" % (c, plural(t, c))
71 return "%d %s" % (c, plural(t, c))
72
72
73 now = time.time()
73 now = time.time()
74 then = date[0]
74 then = date[0]
75 future = False
75 future = False
76 if then > now:
76 if then > now:
77 future = True
77 future = True
78 delta = max(1, int(then - now))
78 delta = max(1, int(then - now))
79 if delta > agescales[0][1] * 30:
79 if delta > agescales[0][1] * 30:
80 return 'in the distant future'
80 return 'in the distant future'
81 else:
81 else:
82 delta = max(1, int(now - then))
82 delta = max(1, int(now - then))
83 if delta > agescales[0][1] * 2:
83 if delta > agescales[0][1] * 2:
84 return dateutil.shortdate(date)
84 return dateutil.shortdate(date)
85
85
86 for t, s, a in agescales:
86 for t, s, a in agescales:
87 n = delta // s
87 n = delta // s
88 if n >= 2 or s == 1:
88 if n >= 2 or s == 1:
89 if future:
89 if future:
90 return '%s from now' % fmt(t, n, a)
90 return '%s from now' % fmt(t, n, a)
91 return '%s ago' % fmt(t, n, a)
91 return '%s ago' % fmt(t, n, a)
92
92
93 @templatefilter('basename')
93 @templatefilter('basename', intype=bytes)
94 def basename(path):
94 def basename(path):
95 """Any text. Treats the text as a path, and returns the last
95 """Any text. Treats the text as a path, and returns the last
96 component of the path after splitting by the path separator.
96 component of the path after splitting by the path separator.
97 For example, "foo/bar/baz" becomes "baz" and "foo/bar//" becomes "".
97 For example, "foo/bar/baz" becomes "baz" and "foo/bar//" becomes "".
98 """
98 """
99 return os.path.basename(path)
99 return os.path.basename(path)
100
100
101 @templatefilter('count')
101 @templatefilter('count')
102 def count(i):
102 def count(i):
103 """List or text. Returns the length as an integer."""
103 """List or text. Returns the length as an integer."""
104 return len(i)
104 return len(i)
105
105
106 @templatefilter('dirname')
106 @templatefilter('dirname', intype=bytes)
107 def dirname(path):
107 def dirname(path):
108 """Any text. Treats the text as a path, and strips the last
108 """Any text. Treats the text as a path, and strips the last
109 component of the path after splitting by the path separator.
109 component of the path after splitting by the path separator.
110 """
110 """
111 return os.path.dirname(path)
111 return os.path.dirname(path)
112
112
113 @templatefilter('domain')
113 @templatefilter('domain', intype=bytes)
114 def domain(author):
114 def domain(author):
115 """Any text. Finds the first string that looks like an email
115 """Any text. Finds the first string that looks like an email
116 address, and extracts just the domain component. Example: ``User
116 address, and extracts just the domain component. Example: ``User
117 <user@example.com>`` becomes ``example.com``.
117 <user@example.com>`` becomes ``example.com``.
118 """
118 """
119 f = author.find('@')
119 f = author.find('@')
120 if f == -1:
120 if f == -1:
121 return ''
121 return ''
122 author = author[f + 1:]
122 author = author[f + 1:]
123 f = author.find('>')
123 f = author.find('>')
124 if f >= 0:
124 if f >= 0:
125 author = author[:f]
125 author = author[:f]
126 return author
126 return author
127
127
128 @templatefilter('email')
128 @templatefilter('email', intype=bytes)
129 def email(text):
129 def email(text):
130 """Any text. Extracts the first string that looks like an email
130 """Any text. Extracts the first string that looks like an email
131 address. Example: ``User <user@example.com>`` becomes
131 address. Example: ``User <user@example.com>`` becomes
132 ``user@example.com``.
132 ``user@example.com``.
133 """
133 """
134 return stringutil.email(text)
134 return stringutil.email(text)
135
135
136 @templatefilter('escape')
136 @templatefilter('escape', intype=bytes)
137 def escape(text):
137 def escape(text):
138 """Any text. Replaces the special XML/XHTML characters "&", "<"
138 """Any text. Replaces the special XML/XHTML characters "&", "<"
139 and ">" with XML entities, and filters out NUL characters.
139 and ">" with XML entities, and filters out NUL characters.
140 """
140 """
141 return url.escape(text.replace('\0', ''), True)
141 return url.escape(text.replace('\0', ''), True)
142
142
143 para_re = None
143 para_re = None
144 space_re = None
144 space_re = None
145
145
146 def fill(text, width, initindent='', hangindent=''):
146 def fill(text, width, initindent='', hangindent=''):
147 '''fill many paragraphs with optional indentation.'''
147 '''fill many paragraphs with optional indentation.'''
148 global para_re, space_re
148 global para_re, space_re
149 if para_re is None:
149 if para_re is None:
150 para_re = re.compile('(\n\n|\n\\s*[-*]\\s*)', re.M)
150 para_re = re.compile('(\n\n|\n\\s*[-*]\\s*)', re.M)
151 space_re = re.compile(br' +')
151 space_re = re.compile(br' +')
152
152
153 def findparas():
153 def findparas():
154 start = 0
154 start = 0
155 while True:
155 while True:
156 m = para_re.search(text, start)
156 m = para_re.search(text, start)
157 if not m:
157 if not m:
158 uctext = encoding.unifromlocal(text[start:])
158 uctext = encoding.unifromlocal(text[start:])
159 w = len(uctext)
159 w = len(uctext)
160 while 0 < w and uctext[w - 1].isspace():
160 while 0 < w and uctext[w - 1].isspace():
161 w -= 1
161 w -= 1
162 yield (encoding.unitolocal(uctext[:w]),
162 yield (encoding.unitolocal(uctext[:w]),
163 encoding.unitolocal(uctext[w:]))
163 encoding.unitolocal(uctext[w:]))
164 break
164 break
165 yield text[start:m.start(0)], m.group(1)
165 yield text[start:m.start(0)], m.group(1)
166 start = m.end(1)
166 start = m.end(1)
167
167
168 return "".join([stringutil.wrap(space_re.sub(' ',
168 return "".join([stringutil.wrap(space_re.sub(' ',
169 stringutil.wrap(para, width)),
169 stringutil.wrap(para, width)),
170 width, initindent, hangindent) + rest
170 width, initindent, hangindent) + rest
171 for para, rest in findparas()])
171 for para, rest in findparas()])
172
172
173 @templatefilter('fill68')
173 @templatefilter('fill68', intype=bytes)
174 def fill68(text):
174 def fill68(text):
175 """Any text. Wraps the text to fit in 68 columns."""
175 """Any text. Wraps the text to fit in 68 columns."""
176 return fill(text, 68)
176 return fill(text, 68)
177
177
178 @templatefilter('fill76')
178 @templatefilter('fill76', intype=bytes)
179 def fill76(text):
179 def fill76(text):
180 """Any text. Wraps the text to fit in 76 columns."""
180 """Any text. Wraps the text to fit in 76 columns."""
181 return fill(text, 76)
181 return fill(text, 76)
182
182
183 @templatefilter('firstline')
183 @templatefilter('firstline', intype=bytes)
184 def firstline(text):
184 def firstline(text):
185 """Any text. Returns the first line of text."""
185 """Any text. Returns the first line of text."""
186 try:
186 try:
187 return text.splitlines(True)[0].rstrip('\r\n')
187 return text.splitlines(True)[0].rstrip('\r\n')
188 except IndexError:
188 except IndexError:
189 return ''
189 return ''
190
190
191 @templatefilter('hex')
191 @templatefilter('hex', intype=bytes)
192 def hexfilter(text):
192 def hexfilter(text):
193 """Any text. Convert a binary Mercurial node identifier into
193 """Any text. Convert a binary Mercurial node identifier into
194 its long hexadecimal representation.
194 its long hexadecimal representation.
195 """
195 """
196 return node.hex(text)
196 return node.hex(text)
197
197
198 @templatefilter('hgdate')
198 @templatefilter('hgdate')
199 def hgdate(text):
199 def hgdate(text):
200 """Date. Returns the date as a pair of numbers: "1157407993
200 """Date. Returns the date as a pair of numbers: "1157407993
201 25200" (Unix timestamp, timezone offset).
201 25200" (Unix timestamp, timezone offset).
202 """
202 """
203 return "%d %d" % text
203 return "%d %d" % text
204
204
205 @templatefilter('isodate')
205 @templatefilter('isodate')
206 def isodate(text):
206 def isodate(text):
207 """Date. Returns the date in ISO 8601 format: "2009-08-18 13:00
207 """Date. Returns the date in ISO 8601 format: "2009-08-18 13:00
208 +0200".
208 +0200".
209 """
209 """
210 return dateutil.datestr(text, '%Y-%m-%d %H:%M %1%2')
210 return dateutil.datestr(text, '%Y-%m-%d %H:%M %1%2')
211
211
212 @templatefilter('isodatesec')
212 @templatefilter('isodatesec')
213 def isodatesec(text):
213 def isodatesec(text):
214 """Date. Returns the date in ISO 8601 format, including
214 """Date. Returns the date in ISO 8601 format, including
215 seconds: "2009-08-18 13:00:13 +0200". See also the rfc3339date
215 seconds: "2009-08-18 13:00:13 +0200". See also the rfc3339date
216 filter.
216 filter.
217 """
217 """
218 return dateutil.datestr(text, '%Y-%m-%d %H:%M:%S %1%2')
218 return dateutil.datestr(text, '%Y-%m-%d %H:%M:%S %1%2')
219
219
220 def indent(text, prefix):
220 def indent(text, prefix):
221 '''indent each non-empty line of text after first with prefix.'''
221 '''indent each non-empty line of text after first with prefix.'''
222 lines = text.splitlines()
222 lines = text.splitlines()
223 num_lines = len(lines)
223 num_lines = len(lines)
224 endswithnewline = text[-1:] == '\n'
224 endswithnewline = text[-1:] == '\n'
225 def indenter():
225 def indenter():
226 for i in xrange(num_lines):
226 for i in xrange(num_lines):
227 l = lines[i]
227 l = lines[i]
228 if i and l.strip():
228 if i and l.strip():
229 yield prefix
229 yield prefix
230 yield l
230 yield l
231 if i < num_lines - 1 or endswithnewline:
231 if i < num_lines - 1 or endswithnewline:
232 yield '\n'
232 yield '\n'
233 return "".join(indenter())
233 return "".join(indenter())
234
234
235 @templatefilter('json')
235 @templatefilter('json')
236 def json(obj, paranoid=True):
236 def json(obj, paranoid=True):
237 if obj is None:
237 if obj is None:
238 return 'null'
238 return 'null'
239 elif obj is False:
239 elif obj is False:
240 return 'false'
240 return 'false'
241 elif obj is True:
241 elif obj is True:
242 return 'true'
242 return 'true'
243 elif isinstance(obj, (int, long, float)):
243 elif isinstance(obj, (int, long, float)):
244 return pycompat.bytestr(obj)
244 return pycompat.bytestr(obj)
245 elif isinstance(obj, bytes):
245 elif isinstance(obj, bytes):
246 return '"%s"' % encoding.jsonescape(obj, paranoid=paranoid)
246 return '"%s"' % encoding.jsonescape(obj, paranoid=paranoid)
247 elif isinstance(obj, str):
247 elif isinstance(obj, str):
248 # This branch is unreachable on Python 2, because bytes == str
248 # This branch is unreachable on Python 2, because bytes == str
249 # and we'll return in the next-earlier block in the elif
249 # and we'll return in the next-earlier block in the elif
250 # ladder. On Python 3, this helps us catch bugs before they
250 # ladder. On Python 3, this helps us catch bugs before they
251 # hurt someone.
251 # hurt someone.
252 raise error.ProgrammingError(
252 raise error.ProgrammingError(
253 'Mercurial only does output with bytes on Python 3: %r' % obj)
253 'Mercurial only does output with bytes on Python 3: %r' % obj)
254 elif util.safehasattr(obj, 'keys'):
254 elif util.safehasattr(obj, 'keys'):
255 out = ['"%s": %s' % (encoding.jsonescape(k, paranoid=paranoid),
255 out = ['"%s": %s' % (encoding.jsonescape(k, paranoid=paranoid),
256 json(v, paranoid))
256 json(v, paranoid))
257 for k, v in sorted(obj.iteritems())]
257 for k, v in sorted(obj.iteritems())]
258 return '{' + ', '.join(out) + '}'
258 return '{' + ', '.join(out) + '}'
259 elif util.safehasattr(obj, '__iter__'):
259 elif util.safehasattr(obj, '__iter__'):
260 out = [json(i, paranoid) for i in obj]
260 out = [json(i, paranoid) for i in obj]
261 return '[' + ', '.join(out) + ']'
261 return '[' + ', '.join(out) + ']'
262 else:
262 else:
263 raise TypeError('cannot encode type %s' % obj.__class__.__name__)
263 raise TypeError('cannot encode type %s' % obj.__class__.__name__)
264
264
265 @templatefilter('lower')
265 @templatefilter('lower', intype=bytes)
266 def lower(text):
266 def lower(text):
267 """Any text. Converts the text to lowercase."""
267 """Any text. Converts the text to lowercase."""
268 return encoding.lower(text)
268 return encoding.lower(text)
269
269
270 @templatefilter('nonempty')
270 @templatefilter('nonempty', intype=bytes)
271 def nonempty(text):
271 def nonempty(text):
272 """Any text. Returns '(none)' if the string is empty."""
272 """Any text. Returns '(none)' if the string is empty."""
273 return text or "(none)"
273 return text or "(none)"
274
274
275 @templatefilter('obfuscate')
275 @templatefilter('obfuscate', intype=bytes)
276 def obfuscate(text):
276 def obfuscate(text):
277 """Any text. Returns the input text rendered as a sequence of
277 """Any text. Returns the input text rendered as a sequence of
278 XML entities.
278 XML entities.
279 """
279 """
280 text = unicode(text, pycompat.sysstr(encoding.encoding), r'replace')
280 text = unicode(text, pycompat.sysstr(encoding.encoding), r'replace')
281 return ''.join(['&#%d;' % ord(c) for c in text])
281 return ''.join(['&#%d;' % ord(c) for c in text])
282
282
283 @templatefilter('permissions')
283 @templatefilter('permissions', intype=bytes)
284 def permissions(flags):
284 def permissions(flags):
285 if "l" in flags:
285 if "l" in flags:
286 return "lrwxrwxrwx"
286 return "lrwxrwxrwx"
287 if "x" in flags:
287 if "x" in flags:
288 return "-rwxr-xr-x"
288 return "-rwxr-xr-x"
289 return "-rw-r--r--"
289 return "-rw-r--r--"
290
290
291 @templatefilter('person')
291 @templatefilter('person', intype=bytes)
292 def person(author):
292 def person(author):
293 """Any text. Returns the name before an email address,
293 """Any text. Returns the name before an email address,
294 interpreting it as per RFC 5322.
294 interpreting it as per RFC 5322.
295 """
295 """
296 return stringutil.person(author)
296 return stringutil.person(author)
297
297
298 @templatefilter('revescape')
298 @templatefilter('revescape', intype=bytes)
299 def revescape(text):
299 def revescape(text):
300 """Any text. Escapes all "special" characters, except @.
300 """Any text. Escapes all "special" characters, except @.
301 Forward slashes are escaped twice to prevent web servers from prematurely
301 Forward slashes are escaped twice to prevent web servers from prematurely
302 unescaping them. For example, "@foo bar/baz" becomes "@foo%20bar%252Fbaz".
302 unescaping them. For example, "@foo bar/baz" becomes "@foo%20bar%252Fbaz".
303 """
303 """
304 return urlreq.quote(text, safe='/@').replace('/', '%252F')
304 return urlreq.quote(text, safe='/@').replace('/', '%252F')
305
305
306 @templatefilter('rfc3339date')
306 @templatefilter('rfc3339date')
307 def rfc3339date(text):
307 def rfc3339date(text):
308 """Date. Returns a date using the Internet date format
308 """Date. Returns a date using the Internet date format
309 specified in RFC 3339: "2009-08-18T13:00:13+02:00".
309 specified in RFC 3339: "2009-08-18T13:00:13+02:00".
310 """
310 """
311 return dateutil.datestr(text, "%Y-%m-%dT%H:%M:%S%1:%2")
311 return dateutil.datestr(text, "%Y-%m-%dT%H:%M:%S%1:%2")
312
312
313 @templatefilter('rfc822date')
313 @templatefilter('rfc822date')
314 def rfc822date(text):
314 def rfc822date(text):
315 """Date. Returns a date using the same format used in email
315 """Date. Returns a date using the same format used in email
316 headers: "Tue, 18 Aug 2009 13:00:13 +0200".
316 headers: "Tue, 18 Aug 2009 13:00:13 +0200".
317 """
317 """
318 return dateutil.datestr(text, "%a, %d %b %Y %H:%M:%S %1%2")
318 return dateutil.datestr(text, "%a, %d %b %Y %H:%M:%S %1%2")
319
319
320 @templatefilter('short')
320 @templatefilter('short', intype=bytes)
321 def short(text):
321 def short(text):
322 """Changeset hash. Returns the short form of a changeset hash,
322 """Changeset hash. Returns the short form of a changeset hash,
323 i.e. a 12 hexadecimal digit string.
323 i.e. a 12 hexadecimal digit string.
324 """
324 """
325 return text[:12]
325 return text[:12]
326
326
327 @templatefilter('shortbisect')
327 @templatefilter('shortbisect', intype=bytes)
328 def shortbisect(label):
328 def shortbisect(label):
329 """Any text. Treats `label` as a bisection status, and
329 """Any text. Treats `label` as a bisection status, and
330 returns a single-character representing the status (G: good, B: bad,
330 returns a single-character representing the status (G: good, B: bad,
331 S: skipped, U: untested, I: ignored). Returns single space if `text`
331 S: skipped, U: untested, I: ignored). Returns single space if `text`
332 is not a valid bisection status.
332 is not a valid bisection status.
333 """
333 """
334 if label:
334 if label:
335 return label[0:1].upper()
335 return label[0:1].upper()
336 return ' '
336 return ' '
337
337
338 @templatefilter('shortdate')
338 @templatefilter('shortdate')
339 def shortdate(text):
339 def shortdate(text):
340 """Date. Returns a date like "2006-09-18"."""
340 """Date. Returns a date like "2006-09-18"."""
341 return dateutil.shortdate(text)
341 return dateutil.shortdate(text)
342
342
343 @templatefilter('slashpath')
343 @templatefilter('slashpath', intype=bytes)
344 def slashpath(path):
344 def slashpath(path):
345 """Any text. Replaces the native path separator with slash."""
345 """Any text. Replaces the native path separator with slash."""
346 return util.pconvert(path)
346 return util.pconvert(path)
347
347
348 @templatefilter('splitlines')
348 @templatefilter('splitlines', intype=bytes)
349 def splitlines(text):
349 def splitlines(text):
350 """Any text. Split text into a list of lines."""
350 """Any text. Split text into a list of lines."""
351 return templateutil.hybridlist(text.splitlines(), name='line')
351 return templateutil.hybridlist(text.splitlines(), name='line')
352
352
353 @templatefilter('stringescape')
353 @templatefilter('stringescape', intype=bytes)
354 def stringescape(text):
354 def stringescape(text):
355 return stringutil.escapestr(text)
355 return stringutil.escapestr(text)
356
356
357 @templatefilter('stringify', intype=bytes)
357 @templatefilter('stringify', intype=bytes)
358 def stringify(thing):
358 def stringify(thing):
359 """Any type. Turns the value into text by converting values into
359 """Any type. Turns the value into text by converting values into
360 text and concatenating them.
360 text and concatenating them.
361 """
361 """
362 return thing # coerced by the intype
362 return thing # coerced by the intype
363
363
364 @templatefilter('stripdir')
364 @templatefilter('stripdir', intype=bytes)
365 def stripdir(text):
365 def stripdir(text):
366 """Treat the text as path and strip a directory level, if
366 """Treat the text as path and strip a directory level, if
367 possible. For example, "foo" and "foo/bar" becomes "foo".
367 possible. For example, "foo" and "foo/bar" becomes "foo".
368 """
368 """
369 dir = os.path.dirname(text)
369 dir = os.path.dirname(text)
370 if dir == "":
370 if dir == "":
371 return os.path.basename(text)
371 return os.path.basename(text)
372 else:
372 else:
373 return dir
373 return dir
374
374
375 @templatefilter('tabindent')
375 @templatefilter('tabindent', intype=bytes)
376 def tabindent(text):
376 def tabindent(text):
377 """Any text. Returns the text, with every non-empty line
377 """Any text. Returns the text, with every non-empty line
378 except the first starting with a tab character.
378 except the first starting with a tab character.
379 """
379 """
380 return indent(text, '\t')
380 return indent(text, '\t')
381
381
382 @templatefilter('upper')
382 @templatefilter('upper', intype=bytes)
383 def upper(text):
383 def upper(text):
384 """Any text. Converts the text to uppercase."""
384 """Any text. Converts the text to uppercase."""
385 return encoding.upper(text)
385 return encoding.upper(text)
386
386
387 @templatefilter('urlescape')
387 @templatefilter('urlescape', intype=bytes)
388 def urlescape(text):
388 def urlescape(text):
389 """Any text. Escapes all "special" characters. For example,
389 """Any text. Escapes all "special" characters. For example,
390 "foo bar" becomes "foo%20bar".
390 "foo bar" becomes "foo%20bar".
391 """
391 """
392 return urlreq.quote(text)
392 return urlreq.quote(text)
393
393
394 @templatefilter('user')
394 @templatefilter('user', intype=bytes)
395 def userfilter(text):
395 def userfilter(text):
396 """Any text. Returns a short representation of a user name or email
396 """Any text. Returns a short representation of a user name or email
397 address."""
397 address."""
398 return stringutil.shortuser(text)
398 return stringutil.shortuser(text)
399
399
400 @templatefilter('emailuser')
400 @templatefilter('emailuser', intype=bytes)
401 def emailuser(text):
401 def emailuser(text):
402 """Any text. Returns the user portion of an email address."""
402 """Any text. Returns the user portion of an email address."""
403 return stringutil.emailuser(text)
403 return stringutil.emailuser(text)
404
404
405 @templatefilter('utf8')
405 @templatefilter('utf8', intype=bytes)
406 def utf8(text):
406 def utf8(text):
407 """Any text. Converts from the local character encoding to UTF-8."""
407 """Any text. Converts from the local character encoding to UTF-8."""
408 return encoding.fromlocal(text)
408 return encoding.fromlocal(text)
409
409
410 @templatefilter('xmlescape')
410 @templatefilter('xmlescape', intype=bytes)
411 def xmlescape(text):
411 def xmlescape(text):
412 text = (text
412 text = (text
413 .replace('&', '&amp;')
413 .replace('&', '&amp;')
414 .replace('<', '&lt;')
414 .replace('<', '&lt;')
415 .replace('>', '&gt;')
415 .replace('>', '&gt;')
416 .replace('"', '&quot;')
416 .replace('"', '&quot;')
417 .replace("'", '&#39;')) # &apos; invalid in HTML
417 .replace("'", '&#39;')) # &apos; invalid in HTML
418 return re.sub('[\x00-\x08\x0B\x0C\x0E-\x1F]', ' ', text)
418 return re.sub('[\x00-\x08\x0B\x0C\x0E-\x1F]', ' ', text)
419
419
420 def websub(text, websubtable):
420 def websub(text, websubtable):
421 """:websub: Any text. Only applies to hgweb. Applies the regular
421 """:websub: Any text. Only applies to hgweb. Applies the regular
422 expression replacements defined in the websub section.
422 expression replacements defined in the websub section.
423 """
423 """
424 if websubtable:
424 if websubtable:
425 for regexp, format in websubtable:
425 for regexp, format in websubtable:
426 text = regexp.sub(format, text)
426 text = regexp.sub(format, text)
427 return text
427 return text
428
428
429 def loadfilter(ui, extname, registrarobj):
429 def loadfilter(ui, extname, registrarobj):
430 """Load template filter from specified registrarobj
430 """Load template filter from specified registrarobj
431 """
431 """
432 for name, func in registrarobj._table.iteritems():
432 for name, func in registrarobj._table.iteritems():
433 filters[name] = func
433 filters[name] = func
434
434
435 # tell hggettext to extract docstrings from these functions:
435 # tell hggettext to extract docstrings from these functions:
436 i18nfunctions = filters.values()
436 i18nfunctions = filters.values()
@@ -1,4843 +1,4843 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 Test arithmetic operators have the right precedence:
32 Test arithmetic operators have the right precedence:
33
33
34 $ hg log -l 1 -T '{date(date, "%Y") + 5 * 10} {date(date, "%Y") - 2 * 3}\n'
34 $ hg log -l 1 -T '{date(date, "%Y") + 5 * 10} {date(date, "%Y") - 2 * 3}\n'
35 2020 1964
35 2020 1964
36 $ hg log -l 1 -T '{date(date, "%Y") * 5 + 10} {date(date, "%Y") * 3 - 2}\n'
36 $ hg log -l 1 -T '{date(date, "%Y") * 5 + 10} {date(date, "%Y") * 3 - 2}\n'
37 9860 5908
37 9860 5908
38
38
39 Test division:
39 Test division:
40
40
41 $ hg debugtemplate -r0 -v '{5 / 2} {mod(5, 2)}\n'
41 $ hg debugtemplate -r0 -v '{5 / 2} {mod(5, 2)}\n'
42 (template
42 (template
43 (/
43 (/
44 (integer '5')
44 (integer '5')
45 (integer '2'))
45 (integer '2'))
46 (string ' ')
46 (string ' ')
47 (func
47 (func
48 (symbol 'mod')
48 (symbol 'mod')
49 (list
49 (list
50 (integer '5')
50 (integer '5')
51 (integer '2')))
51 (integer '2')))
52 (string '\n'))
52 (string '\n'))
53 2 1
53 2 1
54 $ hg debugtemplate -r0 -v '{5 / -2} {mod(5, -2)}\n'
54 $ hg debugtemplate -r0 -v '{5 / -2} {mod(5, -2)}\n'
55 (template
55 (template
56 (/
56 (/
57 (integer '5')
57 (integer '5')
58 (negate
58 (negate
59 (integer '2')))
59 (integer '2')))
60 (string ' ')
60 (string ' ')
61 (func
61 (func
62 (symbol 'mod')
62 (symbol 'mod')
63 (list
63 (list
64 (integer '5')
64 (integer '5')
65 (negate
65 (negate
66 (integer '2'))))
66 (integer '2'))))
67 (string '\n'))
67 (string '\n'))
68 -3 -1
68 -3 -1
69 $ hg debugtemplate -r0 -v '{-5 / 2} {mod(-5, 2)}\n'
69 $ hg debugtemplate -r0 -v '{-5 / 2} {mod(-5, 2)}\n'
70 (template
70 (template
71 (/
71 (/
72 (negate
72 (negate
73 (integer '5'))
73 (integer '5'))
74 (integer '2'))
74 (integer '2'))
75 (string ' ')
75 (string ' ')
76 (func
76 (func
77 (symbol 'mod')
77 (symbol 'mod')
78 (list
78 (list
79 (negate
79 (negate
80 (integer '5'))
80 (integer '5'))
81 (integer '2')))
81 (integer '2')))
82 (string '\n'))
82 (string '\n'))
83 -3 1
83 -3 1
84 $ hg debugtemplate -r0 -v '{-5 / -2} {mod(-5, -2)}\n'
84 $ hg debugtemplate -r0 -v '{-5 / -2} {mod(-5, -2)}\n'
85 (template
85 (template
86 (/
86 (/
87 (negate
87 (negate
88 (integer '5'))
88 (integer '5'))
89 (negate
89 (negate
90 (integer '2')))
90 (integer '2')))
91 (string ' ')
91 (string ' ')
92 (func
92 (func
93 (symbol 'mod')
93 (symbol 'mod')
94 (list
94 (list
95 (negate
95 (negate
96 (integer '5'))
96 (integer '5'))
97 (negate
97 (negate
98 (integer '2'))))
98 (integer '2'))))
99 (string '\n'))
99 (string '\n'))
100 2 -1
100 2 -1
101
101
102 Filters bind closer than arithmetic:
102 Filters bind closer than arithmetic:
103
103
104 $ hg debugtemplate -r0 -v '{revset(".")|count - 1}\n'
104 $ hg debugtemplate -r0 -v '{revset(".")|count - 1}\n'
105 (template
105 (template
106 (-
106 (-
107 (|
107 (|
108 (func
108 (func
109 (symbol 'revset')
109 (symbol 'revset')
110 (string '.'))
110 (string '.'))
111 (symbol 'count'))
111 (symbol 'count'))
112 (integer '1'))
112 (integer '1'))
113 (string '\n'))
113 (string '\n'))
114 0
114 0
115
115
116 But negate binds closer still:
116 But negate binds closer still:
117
117
118 $ hg debugtemplate -r0 -v '{1-3|stringify}\n'
118 $ hg debugtemplate -r0 -v '{1-3|stringify}\n'
119 (template
119 (template
120 (-
120 (-
121 (integer '1')
121 (integer '1')
122 (|
122 (|
123 (integer '3')
123 (integer '3')
124 (symbol 'stringify')))
124 (symbol 'stringify')))
125 (string '\n'))
125 (string '\n'))
126 hg: parse error: arithmetic only defined on integers
126 hg: parse error: arithmetic only defined on integers
127 [255]
127 [255]
128 $ hg debugtemplate -r0 -v '{-3|stringify}\n'
128 $ hg debugtemplate -r0 -v '{-3|stringify}\n'
129 (template
129 (template
130 (|
130 (|
131 (negate
131 (negate
132 (integer '3'))
132 (integer '3'))
133 (symbol 'stringify'))
133 (symbol 'stringify'))
134 (string '\n'))
134 (string '\n'))
135 -3
135 -3
136
136
137 Filters bind as close as map operator:
137 Filters bind as close as map operator:
138
138
139 $ hg debugtemplate -r0 -v '{desc|splitlines % "{line}\n"}'
139 $ hg debugtemplate -r0 -v '{desc|splitlines % "{line}\n"}'
140 (template
140 (template
141 (%
141 (%
142 (|
142 (|
143 (symbol 'desc')
143 (symbol 'desc')
144 (symbol 'splitlines'))
144 (symbol 'splitlines'))
145 (template
145 (template
146 (symbol 'line')
146 (symbol 'line')
147 (string '\n'))))
147 (string '\n'))))
148 line 1
148 line 1
149 line 2
149 line 2
150
150
151 Keyword arguments:
151 Keyword arguments:
152
152
153 $ hg debugtemplate -r0 -v '{foo=bar|baz}'
153 $ hg debugtemplate -r0 -v '{foo=bar|baz}'
154 (template
154 (template
155 (keyvalue
155 (keyvalue
156 (symbol 'foo')
156 (symbol 'foo')
157 (|
157 (|
158 (symbol 'bar')
158 (symbol 'bar')
159 (symbol 'baz'))))
159 (symbol 'baz'))))
160 hg: parse error: can't use a key-value pair in this context
160 hg: parse error: can't use a key-value pair in this context
161 [255]
161 [255]
162
162
163 $ hg debugtemplate '{pad("foo", width=10, left=true)}\n'
163 $ hg debugtemplate '{pad("foo", width=10, left=true)}\n'
164 foo
164 foo
165
165
166 Call function which takes named arguments by filter syntax:
166 Call function which takes named arguments by filter syntax:
167
167
168 $ hg debugtemplate '{" "|separate}'
168 $ hg debugtemplate '{" "|separate}'
169 $ hg debugtemplate '{("not", "an", "argument", "list")|separate}'
169 $ hg debugtemplate '{("not", "an", "argument", "list")|separate}'
170 hg: parse error: unknown method 'list'
170 hg: parse error: unknown method 'list'
171 [255]
171 [255]
172
172
173 Second branch starting at nullrev:
173 Second branch starting at nullrev:
174
174
175 $ hg update null
175 $ hg update null
176 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
176 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
177 $ echo second > second
177 $ echo second > second
178 $ hg add second
178 $ hg add second
179 $ hg commit -m second -d '1000000 0' -u 'User Name <user@hostname>'
179 $ hg commit -m second -d '1000000 0' -u 'User Name <user@hostname>'
180 created new head
180 created new head
181
181
182 $ echo third > third
182 $ echo third > third
183 $ hg add third
183 $ hg add third
184 $ hg mv second fourth
184 $ hg mv second fourth
185 $ hg commit -m third -d "2020-01-01 10:01"
185 $ hg commit -m third -d "2020-01-01 10:01"
186
186
187 $ hg log --template '{join(file_copies, ",\n")}\n' -r .
187 $ hg log --template '{join(file_copies, ",\n")}\n' -r .
188 fourth (second)
188 fourth (second)
189 $ hg log -T '{file_copies % "{source} -> {name}\n"}' -r .
189 $ hg log -T '{file_copies % "{source} -> {name}\n"}' -r .
190 second -> fourth
190 second -> fourth
191 $ hg log -T '{rev} {ifcontains("fourth", file_copies, "t", "f")}\n' -r .:7
191 $ hg log -T '{rev} {ifcontains("fourth", file_copies, "t", "f")}\n' -r .:7
192 8 t
192 8 t
193 7 f
193 7 f
194
194
195 Working-directory revision has special identifiers, though they are still
195 Working-directory revision has special identifiers, though they are still
196 experimental:
196 experimental:
197
197
198 $ hg log -r 'wdir()' -T '{rev}:{node}\n'
198 $ hg log -r 'wdir()' -T '{rev}:{node}\n'
199 2147483647:ffffffffffffffffffffffffffffffffffffffff
199 2147483647:ffffffffffffffffffffffffffffffffffffffff
200
200
201 Some keywords are invalid for working-directory revision, but they should
201 Some keywords are invalid for working-directory revision, but they should
202 never cause crash:
202 never cause crash:
203
203
204 $ hg log -r 'wdir()' -T '{manifest}\n'
204 $ hg log -r 'wdir()' -T '{manifest}\n'
205
205
206
206
207 Internal resources shouldn't be exposed (issue5699):
207 Internal resources shouldn't be exposed (issue5699):
208
208
209 $ hg log -r. -T '{cache}{ctx}{repo}{revcache}{templ}{ui}'
209 $ hg log -r. -T '{cache}{ctx}{repo}{revcache}{templ}{ui}'
210
210
211 Never crash on internal resource not available:
211 Never crash on internal resource not available:
212
212
213 $ hg --cwd .. debugtemplate '{"c0bebeef"|shortest}\n'
213 $ hg --cwd .. debugtemplate '{"c0bebeef"|shortest}\n'
214 abort: template resource not available: ctx
214 abort: template resource not available: ctx
215 [255]
215 [255]
216
216
217 $ hg config -T '{author}'
217 $ hg config -T '{author}'
218
218
219 Quoting for ui.logtemplate
219 Quoting for ui.logtemplate
220
220
221 $ hg tip --config "ui.logtemplate={rev}\n"
221 $ hg tip --config "ui.logtemplate={rev}\n"
222 8
222 8
223 $ hg tip --config "ui.logtemplate='{rev}\n'"
223 $ hg tip --config "ui.logtemplate='{rev}\n'"
224 8
224 8
225 $ hg tip --config 'ui.logtemplate="{rev}\n"'
225 $ hg tip --config 'ui.logtemplate="{rev}\n"'
226 8
226 8
227 $ hg tip --config 'ui.logtemplate=n{rev}\n'
227 $ hg tip --config 'ui.logtemplate=n{rev}\n'
228 n8
228 n8
229
229
230 Make sure user/global hgrc does not affect tests
230 Make sure user/global hgrc does not affect tests
231
231
232 $ echo '[ui]' > .hg/hgrc
232 $ echo '[ui]' > .hg/hgrc
233 $ echo 'logtemplate =' >> .hg/hgrc
233 $ echo 'logtemplate =' >> .hg/hgrc
234 $ echo 'style =' >> .hg/hgrc
234 $ echo 'style =' >> .hg/hgrc
235
235
236 Add some simple styles to settings
236 Add some simple styles to settings
237
237
238 $ cat <<'EOF' >> .hg/hgrc
238 $ cat <<'EOF' >> .hg/hgrc
239 > [templates]
239 > [templates]
240 > simple = "{rev}\n"
240 > simple = "{rev}\n"
241 > simple2 = {rev}\n
241 > simple2 = {rev}\n
242 > rev = "should not precede {rev} keyword\n"
242 > rev = "should not precede {rev} keyword\n"
243 > EOF
243 > EOF
244
244
245 $ hg log -l1 -Tsimple
245 $ hg log -l1 -Tsimple
246 8
246 8
247 $ hg log -l1 -Tsimple2
247 $ hg log -l1 -Tsimple2
248 8
248 8
249 $ hg log -l1 -Trev
249 $ hg log -l1 -Trev
250 should not precede 8 keyword
250 should not precede 8 keyword
251 $ hg log -l1 -T '{simple}'
251 $ hg log -l1 -T '{simple}'
252 8
252 8
253
253
254 Map file shouldn't see user templates:
254 Map file shouldn't see user templates:
255
255
256 $ cat <<EOF > tmpl
256 $ cat <<EOF > tmpl
257 > changeset = 'nothing expanded:{simple}\n'
257 > changeset = 'nothing expanded:{simple}\n'
258 > EOF
258 > EOF
259 $ hg log -l1 --style ./tmpl
259 $ hg log -l1 --style ./tmpl
260 nothing expanded:
260 nothing expanded:
261
261
262 Test templates and style maps in files:
262 Test templates and style maps in files:
263
263
264 $ echo "{rev}" > tmpl
264 $ echo "{rev}" > tmpl
265 $ hg log -l1 -T./tmpl
265 $ hg log -l1 -T./tmpl
266 8
266 8
267 $ hg log -l1 -Tblah/blah
267 $ hg log -l1 -Tblah/blah
268 blah/blah (no-eol)
268 blah/blah (no-eol)
269
269
270 $ printf 'changeset = "{rev}\\n"\n' > map-simple
270 $ printf 'changeset = "{rev}\\n"\n' > map-simple
271 $ hg log -l1 -T./map-simple
271 $ hg log -l1 -T./map-simple
272 8
272 8
273
273
274 a map file may have [templates] and [templatealias] sections:
274 a map file may have [templates] and [templatealias] sections:
275
275
276 $ cat <<'EOF' > map-simple
276 $ cat <<'EOF' > map-simple
277 > [templates]
277 > [templates]
278 > changeset = "{a}\n"
278 > changeset = "{a}\n"
279 > [templatealias]
279 > [templatealias]
280 > a = rev
280 > a = rev
281 > EOF
281 > EOF
282 $ hg log -l1 -T./map-simple
282 $ hg log -l1 -T./map-simple
283 8
283 8
284
284
285 so it can be included in hgrc
285 so it can be included in hgrc
286
286
287 $ cat <<'EOF' > myhgrc
287 $ cat <<'EOF' > myhgrc
288 > %include map-simple
288 > %include map-simple
289 > [templates]
289 > [templates]
290 > foo = "{changeset}"
290 > foo = "{changeset}"
291 > EOF
291 > EOF
292 $ HGRCPATH=./myhgrc hg log -l1 -Tfoo
292 $ HGRCPATH=./myhgrc hg log -l1 -Tfoo
293 8
293 8
294 $ HGRCPATH=./myhgrc hg log -l1 -T'{a}\n'
294 $ HGRCPATH=./myhgrc hg log -l1 -T'{a}\n'
295 8
295 8
296
296
297 Test template map inheritance
297 Test template map inheritance
298
298
299 $ echo "__base__ = map-cmdline.default" > map-simple
299 $ echo "__base__ = map-cmdline.default" > map-simple
300 $ printf 'cset = "changeset: ***{rev}***\\n"\n' >> map-simple
300 $ printf 'cset = "changeset: ***{rev}***\\n"\n' >> map-simple
301 $ hg log -l1 -T./map-simple
301 $ hg log -l1 -T./map-simple
302 changeset: ***8***
302 changeset: ***8***
303 tag: tip
303 tag: tip
304 user: test
304 user: test
305 date: Wed Jan 01 10:01:00 2020 +0000
305 date: Wed Jan 01 10:01:00 2020 +0000
306 summary: third
306 summary: third
307
307
308
308
309 Test docheader, docfooter and separator in template map
309 Test docheader, docfooter and separator in template map
310
310
311 $ cat <<'EOF' > map-myjson
311 $ cat <<'EOF' > map-myjson
312 > docheader = '\{\n'
312 > docheader = '\{\n'
313 > docfooter = '\n}\n'
313 > docfooter = '\n}\n'
314 > separator = ',\n'
314 > separator = ',\n'
315 > changeset = ' {dict(rev, node|short)|json}'
315 > changeset = ' {dict(rev, node|short)|json}'
316 > EOF
316 > EOF
317 $ hg log -l2 -T./map-myjson
317 $ hg log -l2 -T./map-myjson
318 {
318 {
319 {"node": "95c24699272e", "rev": 8},
319 {"node": "95c24699272e", "rev": 8},
320 {"node": "29114dbae42b", "rev": 7}
320 {"node": "29114dbae42b", "rev": 7}
321 }
321 }
322
322
323 Test docheader, docfooter and separator in [templates] section
323 Test docheader, docfooter and separator in [templates] section
324
324
325 $ cat <<'EOF' >> .hg/hgrc
325 $ cat <<'EOF' >> .hg/hgrc
326 > [templates]
326 > [templates]
327 > myjson = ' {dict(rev, node|short)|json}'
327 > myjson = ' {dict(rev, node|short)|json}'
328 > myjson:docheader = '\{\n'
328 > myjson:docheader = '\{\n'
329 > myjson:docfooter = '\n}\n'
329 > myjson:docfooter = '\n}\n'
330 > myjson:separator = ',\n'
330 > myjson:separator = ',\n'
331 > :docheader = 'should not be selected as a docheader for literal templates\n'
331 > :docheader = 'should not be selected as a docheader for literal templates\n'
332 > EOF
332 > EOF
333 $ hg log -l2 -Tmyjson
333 $ hg log -l2 -Tmyjson
334 {
334 {
335 {"node": "95c24699272e", "rev": 8},
335 {"node": "95c24699272e", "rev": 8},
336 {"node": "29114dbae42b", "rev": 7}
336 {"node": "29114dbae42b", "rev": 7}
337 }
337 }
338 $ hg log -l1 -T'{rev}\n'
338 $ hg log -l1 -T'{rev}\n'
339 8
339 8
340
340
341 Template should precede style option
341 Template should precede style option
342
342
343 $ hg log -l1 --style default -T '{rev}\n'
343 $ hg log -l1 --style default -T '{rev}\n'
344 8
344 8
345
345
346 Add a commit with empty description, to ensure that the templates
346 Add a commit with empty description, to ensure that the templates
347 below will omit the description line.
347 below will omit the description line.
348
348
349 $ echo c >> c
349 $ echo c >> c
350 $ hg add c
350 $ hg add c
351 $ hg commit -qm ' '
351 $ hg commit -qm ' '
352
352
353 Default style is like normal output. Phases style should be the same
353 Default style is like normal output. Phases style should be the same
354 as default style, except for extra phase lines.
354 as default style, except for extra phase lines.
355
355
356 $ hg log > log.out
356 $ hg log > log.out
357 $ hg log --style default > style.out
357 $ hg log --style default > style.out
358 $ cmp log.out style.out || diff -u log.out style.out
358 $ cmp log.out style.out || diff -u log.out style.out
359 $ hg log -T phases > phases.out
359 $ hg log -T phases > phases.out
360 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
360 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
361 +phase: draft
361 +phase: draft
362 +phase: draft
362 +phase: draft
363 +phase: draft
363 +phase: draft
364 +phase: draft
364 +phase: draft
365 +phase: draft
365 +phase: draft
366 +phase: draft
366 +phase: draft
367 +phase: draft
367 +phase: draft
368 +phase: draft
368 +phase: draft
369 +phase: draft
369 +phase: draft
370 +phase: draft
370 +phase: draft
371
371
372 $ hg log -v > log.out
372 $ hg log -v > log.out
373 $ hg log -v --style default > style.out
373 $ hg log -v --style default > style.out
374 $ cmp log.out style.out || diff -u log.out style.out
374 $ cmp log.out style.out || diff -u log.out style.out
375 $ hg log -v -T phases > phases.out
375 $ hg log -v -T phases > phases.out
376 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
376 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
377 +phase: draft
377 +phase: draft
378 +phase: draft
378 +phase: draft
379 +phase: draft
379 +phase: draft
380 +phase: draft
380 +phase: draft
381 +phase: draft
381 +phase: draft
382 +phase: draft
382 +phase: draft
383 +phase: draft
383 +phase: draft
384 +phase: draft
384 +phase: draft
385 +phase: draft
385 +phase: draft
386 +phase: draft
386 +phase: draft
387
387
388 $ hg log -q > log.out
388 $ hg log -q > log.out
389 $ hg log -q --style default > style.out
389 $ hg log -q --style default > style.out
390 $ cmp log.out style.out || diff -u log.out style.out
390 $ cmp log.out style.out || diff -u log.out style.out
391 $ hg log -q -T phases > phases.out
391 $ hg log -q -T phases > phases.out
392 $ cmp log.out phases.out || diff -u log.out phases.out
392 $ cmp log.out phases.out || diff -u log.out phases.out
393
393
394 $ hg log --debug > log.out
394 $ hg log --debug > log.out
395 $ hg log --debug --style default > style.out
395 $ hg log --debug --style default > style.out
396 $ cmp log.out style.out || diff -u log.out style.out
396 $ cmp log.out style.out || diff -u log.out style.out
397 $ hg log --debug -T phases > phases.out
397 $ hg log --debug -T phases > phases.out
398 $ cmp log.out phases.out || diff -u log.out phases.out
398 $ cmp log.out phases.out || diff -u log.out phases.out
399
399
400 Default style of working-directory revision should also be the same (but
400 Default style of working-directory revision should also be the same (but
401 date may change while running tests):
401 date may change while running tests):
402
402
403 $ hg log -r 'wdir()' | sed 's|^date:.*|date:|' > log.out
403 $ hg log -r 'wdir()' | sed 's|^date:.*|date:|' > log.out
404 $ hg log -r 'wdir()' --style default | sed 's|^date:.*|date:|' > style.out
404 $ hg log -r 'wdir()' --style default | sed 's|^date:.*|date:|' > style.out
405 $ cmp log.out style.out || diff -u log.out style.out
405 $ cmp log.out style.out || diff -u log.out style.out
406
406
407 $ hg log -r 'wdir()' -v | sed 's|^date:.*|date:|' > log.out
407 $ hg log -r 'wdir()' -v | sed 's|^date:.*|date:|' > log.out
408 $ hg log -r 'wdir()' -v --style default | sed 's|^date:.*|date:|' > style.out
408 $ hg log -r 'wdir()' -v --style default | sed 's|^date:.*|date:|' > style.out
409 $ cmp log.out style.out || diff -u log.out style.out
409 $ cmp log.out style.out || diff -u log.out style.out
410
410
411 $ hg log -r 'wdir()' -q > log.out
411 $ hg log -r 'wdir()' -q > log.out
412 $ hg log -r 'wdir()' -q --style default > style.out
412 $ hg log -r 'wdir()' -q --style default > style.out
413 $ cmp log.out style.out || diff -u log.out style.out
413 $ cmp log.out style.out || diff -u log.out style.out
414
414
415 $ hg log -r 'wdir()' --debug | sed 's|^date:.*|date:|' > log.out
415 $ hg log -r 'wdir()' --debug | sed 's|^date:.*|date:|' > log.out
416 $ hg log -r 'wdir()' --debug --style default \
416 $ hg log -r 'wdir()' --debug --style default \
417 > | sed 's|^date:.*|date:|' > style.out
417 > | sed 's|^date:.*|date:|' > style.out
418 $ cmp log.out style.out || diff -u log.out style.out
418 $ cmp log.out style.out || diff -u log.out style.out
419
419
420 Default style should also preserve color information (issue2866):
420 Default style should also preserve color information (issue2866):
421
421
422 $ cp $HGRCPATH $HGRCPATH-bak
422 $ cp $HGRCPATH $HGRCPATH-bak
423 $ cat <<EOF >> $HGRCPATH
423 $ cat <<EOF >> $HGRCPATH
424 > [extensions]
424 > [extensions]
425 > color=
425 > color=
426 > EOF
426 > EOF
427
427
428 $ hg --color=debug log > log.out
428 $ hg --color=debug log > log.out
429 $ hg --color=debug log --style default > style.out
429 $ hg --color=debug log --style default > style.out
430 $ cmp log.out style.out || diff -u log.out style.out
430 $ cmp log.out style.out || diff -u log.out style.out
431 $ hg --color=debug log -T phases > phases.out
431 $ hg --color=debug log -T phases > phases.out
432 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
432 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
433 +[log.phase|phase: draft]
433 +[log.phase|phase: draft]
434 +[log.phase|phase: draft]
434 +[log.phase|phase: draft]
435 +[log.phase|phase: draft]
435 +[log.phase|phase: draft]
436 +[log.phase|phase: draft]
436 +[log.phase|phase: draft]
437 +[log.phase|phase: draft]
437 +[log.phase|phase: draft]
438 +[log.phase|phase: draft]
438 +[log.phase|phase: draft]
439 +[log.phase|phase: draft]
439 +[log.phase|phase: draft]
440 +[log.phase|phase: draft]
440 +[log.phase|phase: draft]
441 +[log.phase|phase: draft]
441 +[log.phase|phase: draft]
442 +[log.phase|phase: draft]
442 +[log.phase|phase: draft]
443
443
444 $ hg --color=debug -v log > log.out
444 $ hg --color=debug -v log > log.out
445 $ hg --color=debug -v log --style default > style.out
445 $ hg --color=debug -v log --style default > style.out
446 $ cmp log.out style.out || diff -u log.out style.out
446 $ cmp log.out style.out || diff -u log.out style.out
447 $ hg --color=debug -v log -T phases > phases.out
447 $ hg --color=debug -v log -T phases > phases.out
448 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
448 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
449 +[log.phase|phase: draft]
449 +[log.phase|phase: draft]
450 +[log.phase|phase: draft]
450 +[log.phase|phase: draft]
451 +[log.phase|phase: draft]
451 +[log.phase|phase: draft]
452 +[log.phase|phase: draft]
452 +[log.phase|phase: draft]
453 +[log.phase|phase: draft]
453 +[log.phase|phase: draft]
454 +[log.phase|phase: draft]
454 +[log.phase|phase: draft]
455 +[log.phase|phase: draft]
455 +[log.phase|phase: draft]
456 +[log.phase|phase: draft]
456 +[log.phase|phase: draft]
457 +[log.phase|phase: draft]
457 +[log.phase|phase: draft]
458 +[log.phase|phase: draft]
458 +[log.phase|phase: draft]
459
459
460 $ hg --color=debug -q log > log.out
460 $ hg --color=debug -q log > log.out
461 $ hg --color=debug -q log --style default > style.out
461 $ hg --color=debug -q log --style default > style.out
462 $ cmp log.out style.out || diff -u log.out style.out
462 $ cmp log.out style.out || diff -u log.out style.out
463 $ hg --color=debug -q log -T phases > phases.out
463 $ hg --color=debug -q log -T phases > phases.out
464 $ cmp log.out phases.out || diff -u log.out phases.out
464 $ cmp log.out phases.out || diff -u log.out phases.out
465
465
466 $ hg --color=debug --debug log > log.out
466 $ hg --color=debug --debug log > log.out
467 $ hg --color=debug --debug log --style default > style.out
467 $ hg --color=debug --debug log --style default > style.out
468 $ cmp log.out style.out || diff -u log.out style.out
468 $ cmp log.out style.out || diff -u log.out style.out
469 $ hg --color=debug --debug log -T phases > phases.out
469 $ hg --color=debug --debug log -T phases > phases.out
470 $ cmp log.out phases.out || diff -u log.out phases.out
470 $ cmp log.out phases.out || diff -u log.out phases.out
471
471
472 $ mv $HGRCPATH-bak $HGRCPATH
472 $ mv $HGRCPATH-bak $HGRCPATH
473
473
474 Remove commit with empty commit message, so as to not pollute further
474 Remove commit with empty commit message, so as to not pollute further
475 tests.
475 tests.
476
476
477 $ hg --config extensions.strip= strip -q .
477 $ hg --config extensions.strip= strip -q .
478
478
479 Revision with no copies (used to print a traceback):
479 Revision with no copies (used to print a traceback):
480
480
481 $ hg tip -v --template '\n'
481 $ hg tip -v --template '\n'
482
482
483
483
484 Compact style works:
484 Compact style works:
485
485
486 $ hg log -Tcompact
486 $ hg log -Tcompact
487 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
487 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
488 third
488 third
489
489
490 7:-1 29114dbae42b 1970-01-12 13:46 +0000 user
490 7:-1 29114dbae42b 1970-01-12 13:46 +0000 user
491 second
491 second
492
492
493 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
493 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
494 merge
494 merge
495
495
496 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
496 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
497 new head
497 new head
498
498
499 4 bbe44766e73d 1970-01-17 04:53 +0000 person
499 4 bbe44766e73d 1970-01-17 04:53 +0000 person
500 new branch
500 new branch
501
501
502 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
502 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
503 no user, no domain
503 no user, no domain
504
504
505 2 97054abb4ab8 1970-01-14 21:20 +0000 other
505 2 97054abb4ab8 1970-01-14 21:20 +0000 other
506 no person
506 no person
507
507
508 1 b608e9d1a3f0 1970-01-13 17:33 +0000 other
508 1 b608e9d1a3f0 1970-01-13 17:33 +0000 other
509 other 1
509 other 1
510
510
511 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 user
511 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 user
512 line 1
512 line 1
513
513
514
514
515 $ hg log -v --style compact
515 $ hg log -v --style compact
516 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
516 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
517 third
517 third
518
518
519 7:-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
519 7:-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
520 second
520 second
521
521
522 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
522 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
523 merge
523 merge
524
524
525 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
525 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
526 new head
526 new head
527
527
528 4 bbe44766e73d 1970-01-17 04:53 +0000 person
528 4 bbe44766e73d 1970-01-17 04:53 +0000 person
529 new branch
529 new branch
530
530
531 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
531 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
532 no user, no domain
532 no user, no domain
533
533
534 2 97054abb4ab8 1970-01-14 21:20 +0000 other@place
534 2 97054abb4ab8 1970-01-14 21:20 +0000 other@place
535 no person
535 no person
536
536
537 1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
537 1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
538 other 1
538 other 1
539 other 2
539 other 2
540
540
541 other 3
541 other 3
542
542
543 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
543 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
544 line 1
544 line 1
545 line 2
545 line 2
546
546
547
547
548 $ hg log --debug --style compact
548 $ hg log --debug --style compact
549 8[tip]:7,-1 95c24699272e 2020-01-01 10:01 +0000 test
549 8[tip]:7,-1 95c24699272e 2020-01-01 10:01 +0000 test
550 third
550 third
551
551
552 7:-1,-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
552 7:-1,-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
553 second
553 second
554
554
555 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
555 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
556 merge
556 merge
557
557
558 5:3,-1 13207e5a10d9 1970-01-18 08:40 +0000 person
558 5:3,-1 13207e5a10d9 1970-01-18 08:40 +0000 person
559 new head
559 new head
560
560
561 4:3,-1 bbe44766e73d 1970-01-17 04:53 +0000 person
561 4:3,-1 bbe44766e73d 1970-01-17 04:53 +0000 person
562 new branch
562 new branch
563
563
564 3:2,-1 10e46f2dcbf4 1970-01-16 01:06 +0000 person
564 3:2,-1 10e46f2dcbf4 1970-01-16 01:06 +0000 person
565 no user, no domain
565 no user, no domain
566
566
567 2:1,-1 97054abb4ab8 1970-01-14 21:20 +0000 other@place
567 2:1,-1 97054abb4ab8 1970-01-14 21:20 +0000 other@place
568 no person
568 no person
569
569
570 1:0,-1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
570 1:0,-1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
571 other 1
571 other 1
572 other 2
572 other 2
573
573
574 other 3
574 other 3
575
575
576 0:-1,-1 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
576 0:-1,-1 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
577 line 1
577 line 1
578 line 2
578 line 2
579
579
580
580
581 Test xml styles:
581 Test xml styles:
582
582
583 $ hg log --style xml -r 'not all()'
583 $ hg log --style xml -r 'not all()'
584 <?xml version="1.0"?>
584 <?xml version="1.0"?>
585 <log>
585 <log>
586 </log>
586 </log>
587
587
588 $ hg log --style xml
588 $ hg log --style xml
589 <?xml version="1.0"?>
589 <?xml version="1.0"?>
590 <log>
590 <log>
591 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
591 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
592 <tag>tip</tag>
592 <tag>tip</tag>
593 <author email="test">test</author>
593 <author email="test">test</author>
594 <date>2020-01-01T10:01:00+00:00</date>
594 <date>2020-01-01T10:01:00+00:00</date>
595 <msg xml:space="preserve">third</msg>
595 <msg xml:space="preserve">third</msg>
596 </logentry>
596 </logentry>
597 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
597 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
598 <parent revision="-1" node="0000000000000000000000000000000000000000" />
598 <parent revision="-1" node="0000000000000000000000000000000000000000" />
599 <author email="user@hostname">User Name</author>
599 <author email="user@hostname">User Name</author>
600 <date>1970-01-12T13:46:40+00:00</date>
600 <date>1970-01-12T13:46:40+00:00</date>
601 <msg xml:space="preserve">second</msg>
601 <msg xml:space="preserve">second</msg>
602 </logentry>
602 </logentry>
603 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
603 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
604 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
604 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
605 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
605 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
606 <author email="person">person</author>
606 <author email="person">person</author>
607 <date>1970-01-18T08:40:01+00:00</date>
607 <date>1970-01-18T08:40:01+00:00</date>
608 <msg xml:space="preserve">merge</msg>
608 <msg xml:space="preserve">merge</msg>
609 </logentry>
609 </logentry>
610 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
610 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
611 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
611 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
612 <author email="person">person</author>
612 <author email="person">person</author>
613 <date>1970-01-18T08:40:00+00:00</date>
613 <date>1970-01-18T08:40:00+00:00</date>
614 <msg xml:space="preserve">new head</msg>
614 <msg xml:space="preserve">new head</msg>
615 </logentry>
615 </logentry>
616 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
616 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
617 <branch>foo</branch>
617 <branch>foo</branch>
618 <author email="person">person</author>
618 <author email="person">person</author>
619 <date>1970-01-17T04:53:20+00:00</date>
619 <date>1970-01-17T04:53:20+00:00</date>
620 <msg xml:space="preserve">new branch</msg>
620 <msg xml:space="preserve">new branch</msg>
621 </logentry>
621 </logentry>
622 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
622 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
623 <author email="person">person</author>
623 <author email="person">person</author>
624 <date>1970-01-16T01:06:40+00:00</date>
624 <date>1970-01-16T01:06:40+00:00</date>
625 <msg xml:space="preserve">no user, no domain</msg>
625 <msg xml:space="preserve">no user, no domain</msg>
626 </logentry>
626 </logentry>
627 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
627 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
628 <author email="other@place">other</author>
628 <author email="other@place">other</author>
629 <date>1970-01-14T21:20:00+00:00</date>
629 <date>1970-01-14T21:20:00+00:00</date>
630 <msg xml:space="preserve">no person</msg>
630 <msg xml:space="preserve">no person</msg>
631 </logentry>
631 </logentry>
632 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
632 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
633 <author email="other@place">A. N. Other</author>
633 <author email="other@place">A. N. Other</author>
634 <date>1970-01-13T17:33:20+00:00</date>
634 <date>1970-01-13T17:33:20+00:00</date>
635 <msg xml:space="preserve">other 1
635 <msg xml:space="preserve">other 1
636 other 2
636 other 2
637
637
638 other 3</msg>
638 other 3</msg>
639 </logentry>
639 </logentry>
640 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
640 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
641 <author email="user@hostname">User Name</author>
641 <author email="user@hostname">User Name</author>
642 <date>1970-01-12T13:46:40+00:00</date>
642 <date>1970-01-12T13:46:40+00:00</date>
643 <msg xml:space="preserve">line 1
643 <msg xml:space="preserve">line 1
644 line 2</msg>
644 line 2</msg>
645 </logentry>
645 </logentry>
646 </log>
646 </log>
647
647
648 $ hg log -v --style xml
648 $ hg log -v --style xml
649 <?xml version="1.0"?>
649 <?xml version="1.0"?>
650 <log>
650 <log>
651 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
651 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
652 <tag>tip</tag>
652 <tag>tip</tag>
653 <author email="test">test</author>
653 <author email="test">test</author>
654 <date>2020-01-01T10:01:00+00:00</date>
654 <date>2020-01-01T10:01:00+00:00</date>
655 <msg xml:space="preserve">third</msg>
655 <msg xml:space="preserve">third</msg>
656 <paths>
656 <paths>
657 <path action="A">fourth</path>
657 <path action="A">fourth</path>
658 <path action="A">third</path>
658 <path action="A">third</path>
659 <path action="R">second</path>
659 <path action="R">second</path>
660 </paths>
660 </paths>
661 <copies>
661 <copies>
662 <copy source="second">fourth</copy>
662 <copy source="second">fourth</copy>
663 </copies>
663 </copies>
664 </logentry>
664 </logentry>
665 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
665 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
666 <parent revision="-1" node="0000000000000000000000000000000000000000" />
666 <parent revision="-1" node="0000000000000000000000000000000000000000" />
667 <author email="user@hostname">User Name</author>
667 <author email="user@hostname">User Name</author>
668 <date>1970-01-12T13:46:40+00:00</date>
668 <date>1970-01-12T13:46:40+00:00</date>
669 <msg xml:space="preserve">second</msg>
669 <msg xml:space="preserve">second</msg>
670 <paths>
670 <paths>
671 <path action="A">second</path>
671 <path action="A">second</path>
672 </paths>
672 </paths>
673 </logentry>
673 </logentry>
674 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
674 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
675 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
675 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
676 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
676 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
677 <author email="person">person</author>
677 <author email="person">person</author>
678 <date>1970-01-18T08:40:01+00:00</date>
678 <date>1970-01-18T08:40:01+00:00</date>
679 <msg xml:space="preserve">merge</msg>
679 <msg xml:space="preserve">merge</msg>
680 <paths>
680 <paths>
681 </paths>
681 </paths>
682 </logentry>
682 </logentry>
683 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
683 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
684 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
684 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
685 <author email="person">person</author>
685 <author email="person">person</author>
686 <date>1970-01-18T08:40:00+00:00</date>
686 <date>1970-01-18T08:40:00+00:00</date>
687 <msg xml:space="preserve">new head</msg>
687 <msg xml:space="preserve">new head</msg>
688 <paths>
688 <paths>
689 <path action="A">d</path>
689 <path action="A">d</path>
690 </paths>
690 </paths>
691 </logentry>
691 </logentry>
692 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
692 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
693 <branch>foo</branch>
693 <branch>foo</branch>
694 <author email="person">person</author>
694 <author email="person">person</author>
695 <date>1970-01-17T04:53:20+00:00</date>
695 <date>1970-01-17T04:53:20+00:00</date>
696 <msg xml:space="preserve">new branch</msg>
696 <msg xml:space="preserve">new branch</msg>
697 <paths>
697 <paths>
698 </paths>
698 </paths>
699 </logentry>
699 </logentry>
700 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
700 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
701 <author email="person">person</author>
701 <author email="person">person</author>
702 <date>1970-01-16T01:06:40+00:00</date>
702 <date>1970-01-16T01:06:40+00:00</date>
703 <msg xml:space="preserve">no user, no domain</msg>
703 <msg xml:space="preserve">no user, no domain</msg>
704 <paths>
704 <paths>
705 <path action="M">c</path>
705 <path action="M">c</path>
706 </paths>
706 </paths>
707 </logentry>
707 </logentry>
708 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
708 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
709 <author email="other@place">other</author>
709 <author email="other@place">other</author>
710 <date>1970-01-14T21:20:00+00:00</date>
710 <date>1970-01-14T21:20:00+00:00</date>
711 <msg xml:space="preserve">no person</msg>
711 <msg xml:space="preserve">no person</msg>
712 <paths>
712 <paths>
713 <path action="A">c</path>
713 <path action="A">c</path>
714 </paths>
714 </paths>
715 </logentry>
715 </logentry>
716 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
716 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
717 <author email="other@place">A. N. Other</author>
717 <author email="other@place">A. N. Other</author>
718 <date>1970-01-13T17:33:20+00:00</date>
718 <date>1970-01-13T17:33:20+00:00</date>
719 <msg xml:space="preserve">other 1
719 <msg xml:space="preserve">other 1
720 other 2
720 other 2
721
721
722 other 3</msg>
722 other 3</msg>
723 <paths>
723 <paths>
724 <path action="A">b</path>
724 <path action="A">b</path>
725 </paths>
725 </paths>
726 </logentry>
726 </logentry>
727 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
727 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
728 <author email="user@hostname">User Name</author>
728 <author email="user@hostname">User Name</author>
729 <date>1970-01-12T13:46:40+00:00</date>
729 <date>1970-01-12T13:46:40+00:00</date>
730 <msg xml:space="preserve">line 1
730 <msg xml:space="preserve">line 1
731 line 2</msg>
731 line 2</msg>
732 <paths>
732 <paths>
733 <path action="A">a</path>
733 <path action="A">a</path>
734 </paths>
734 </paths>
735 </logentry>
735 </logentry>
736 </log>
736 </log>
737
737
738 $ hg log --debug --style xml
738 $ hg log --debug --style xml
739 <?xml version="1.0"?>
739 <?xml version="1.0"?>
740 <log>
740 <log>
741 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
741 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
742 <tag>tip</tag>
742 <tag>tip</tag>
743 <parent revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453" />
743 <parent revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453" />
744 <parent revision="-1" node="0000000000000000000000000000000000000000" />
744 <parent revision="-1" node="0000000000000000000000000000000000000000" />
745 <author email="test">test</author>
745 <author email="test">test</author>
746 <date>2020-01-01T10:01:00+00:00</date>
746 <date>2020-01-01T10:01:00+00:00</date>
747 <msg xml:space="preserve">third</msg>
747 <msg xml:space="preserve">third</msg>
748 <paths>
748 <paths>
749 <path action="A">fourth</path>
749 <path action="A">fourth</path>
750 <path action="A">third</path>
750 <path action="A">third</path>
751 <path action="R">second</path>
751 <path action="R">second</path>
752 </paths>
752 </paths>
753 <copies>
753 <copies>
754 <copy source="second">fourth</copy>
754 <copy source="second">fourth</copy>
755 </copies>
755 </copies>
756 <extra key="branch">default</extra>
756 <extra key="branch">default</extra>
757 </logentry>
757 </logentry>
758 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
758 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
759 <parent revision="-1" node="0000000000000000000000000000000000000000" />
759 <parent revision="-1" node="0000000000000000000000000000000000000000" />
760 <parent revision="-1" node="0000000000000000000000000000000000000000" />
760 <parent revision="-1" node="0000000000000000000000000000000000000000" />
761 <author email="user@hostname">User Name</author>
761 <author email="user@hostname">User Name</author>
762 <date>1970-01-12T13:46:40+00:00</date>
762 <date>1970-01-12T13:46:40+00:00</date>
763 <msg xml:space="preserve">second</msg>
763 <msg xml:space="preserve">second</msg>
764 <paths>
764 <paths>
765 <path action="A">second</path>
765 <path action="A">second</path>
766 </paths>
766 </paths>
767 <extra key="branch">default</extra>
767 <extra key="branch">default</extra>
768 </logentry>
768 </logentry>
769 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
769 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
770 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
770 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
771 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
771 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
772 <author email="person">person</author>
772 <author email="person">person</author>
773 <date>1970-01-18T08:40:01+00:00</date>
773 <date>1970-01-18T08:40:01+00:00</date>
774 <msg xml:space="preserve">merge</msg>
774 <msg xml:space="preserve">merge</msg>
775 <paths>
775 <paths>
776 </paths>
776 </paths>
777 <extra key="branch">default</extra>
777 <extra key="branch">default</extra>
778 </logentry>
778 </logentry>
779 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
779 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
780 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
780 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
781 <parent revision="-1" node="0000000000000000000000000000000000000000" />
781 <parent revision="-1" node="0000000000000000000000000000000000000000" />
782 <author email="person">person</author>
782 <author email="person">person</author>
783 <date>1970-01-18T08:40:00+00:00</date>
783 <date>1970-01-18T08:40:00+00:00</date>
784 <msg xml:space="preserve">new head</msg>
784 <msg xml:space="preserve">new head</msg>
785 <paths>
785 <paths>
786 <path action="A">d</path>
786 <path action="A">d</path>
787 </paths>
787 </paths>
788 <extra key="branch">default</extra>
788 <extra key="branch">default</extra>
789 </logentry>
789 </logentry>
790 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
790 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
791 <branch>foo</branch>
791 <branch>foo</branch>
792 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
792 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
793 <parent revision="-1" node="0000000000000000000000000000000000000000" />
793 <parent revision="-1" node="0000000000000000000000000000000000000000" />
794 <author email="person">person</author>
794 <author email="person">person</author>
795 <date>1970-01-17T04:53:20+00:00</date>
795 <date>1970-01-17T04:53:20+00:00</date>
796 <msg xml:space="preserve">new branch</msg>
796 <msg xml:space="preserve">new branch</msg>
797 <paths>
797 <paths>
798 </paths>
798 </paths>
799 <extra key="branch">foo</extra>
799 <extra key="branch">foo</extra>
800 </logentry>
800 </logentry>
801 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
801 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
802 <parent revision="2" node="97054abb4ab824450e9164180baf491ae0078465" />
802 <parent revision="2" node="97054abb4ab824450e9164180baf491ae0078465" />
803 <parent revision="-1" node="0000000000000000000000000000000000000000" />
803 <parent revision="-1" node="0000000000000000000000000000000000000000" />
804 <author email="person">person</author>
804 <author email="person">person</author>
805 <date>1970-01-16T01:06:40+00:00</date>
805 <date>1970-01-16T01:06:40+00:00</date>
806 <msg xml:space="preserve">no user, no domain</msg>
806 <msg xml:space="preserve">no user, no domain</msg>
807 <paths>
807 <paths>
808 <path action="M">c</path>
808 <path action="M">c</path>
809 </paths>
809 </paths>
810 <extra key="branch">default</extra>
810 <extra key="branch">default</extra>
811 </logentry>
811 </logentry>
812 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
812 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
813 <parent revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965" />
813 <parent revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965" />
814 <parent revision="-1" node="0000000000000000000000000000000000000000" />
814 <parent revision="-1" node="0000000000000000000000000000000000000000" />
815 <author email="other@place">other</author>
815 <author email="other@place">other</author>
816 <date>1970-01-14T21:20:00+00:00</date>
816 <date>1970-01-14T21:20:00+00:00</date>
817 <msg xml:space="preserve">no person</msg>
817 <msg xml:space="preserve">no person</msg>
818 <paths>
818 <paths>
819 <path action="A">c</path>
819 <path action="A">c</path>
820 </paths>
820 </paths>
821 <extra key="branch">default</extra>
821 <extra key="branch">default</extra>
822 </logentry>
822 </logentry>
823 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
823 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
824 <parent revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f" />
824 <parent revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f" />
825 <parent revision="-1" node="0000000000000000000000000000000000000000" />
825 <parent revision="-1" node="0000000000000000000000000000000000000000" />
826 <author email="other@place">A. N. Other</author>
826 <author email="other@place">A. N. Other</author>
827 <date>1970-01-13T17:33:20+00:00</date>
827 <date>1970-01-13T17:33:20+00:00</date>
828 <msg xml:space="preserve">other 1
828 <msg xml:space="preserve">other 1
829 other 2
829 other 2
830
830
831 other 3</msg>
831 other 3</msg>
832 <paths>
832 <paths>
833 <path action="A">b</path>
833 <path action="A">b</path>
834 </paths>
834 </paths>
835 <extra key="branch">default</extra>
835 <extra key="branch">default</extra>
836 </logentry>
836 </logentry>
837 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
837 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
838 <parent revision="-1" node="0000000000000000000000000000000000000000" />
838 <parent revision="-1" node="0000000000000000000000000000000000000000" />
839 <parent revision="-1" node="0000000000000000000000000000000000000000" />
839 <parent revision="-1" node="0000000000000000000000000000000000000000" />
840 <author email="user@hostname">User Name</author>
840 <author email="user@hostname">User Name</author>
841 <date>1970-01-12T13:46:40+00:00</date>
841 <date>1970-01-12T13:46:40+00:00</date>
842 <msg xml:space="preserve">line 1
842 <msg xml:space="preserve">line 1
843 line 2</msg>
843 line 2</msg>
844 <paths>
844 <paths>
845 <path action="A">a</path>
845 <path action="A">a</path>
846 </paths>
846 </paths>
847 <extra key="branch">default</extra>
847 <extra key="branch">default</extra>
848 </logentry>
848 </logentry>
849 </log>
849 </log>
850
850
851
851
852 Test JSON style:
852 Test JSON style:
853
853
854 $ hg log -k nosuch -Tjson
854 $ hg log -k nosuch -Tjson
855 []
855 []
856
856
857 $ hg log -qr . -Tjson
857 $ hg log -qr . -Tjson
858 [
858 [
859 {
859 {
860 "rev": 8,
860 "rev": 8,
861 "node": "95c24699272ef57d062b8bccc32c878bf841784a"
861 "node": "95c24699272ef57d062b8bccc32c878bf841784a"
862 }
862 }
863 ]
863 ]
864
864
865 $ hg log -vpr . -Tjson --stat
865 $ hg log -vpr . -Tjson --stat
866 [
866 [
867 {
867 {
868 "rev": 8,
868 "rev": 8,
869 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
869 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
870 "branch": "default",
870 "branch": "default",
871 "phase": "draft",
871 "phase": "draft",
872 "user": "test",
872 "user": "test",
873 "date": [1577872860, 0],
873 "date": [1577872860, 0],
874 "desc": "third",
874 "desc": "third",
875 "bookmarks": [],
875 "bookmarks": [],
876 "tags": ["tip"],
876 "tags": ["tip"],
877 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
877 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
878 "files": ["fourth", "second", "third"],
878 "files": ["fourth", "second", "third"],
879 "diffstat": " fourth | 1 +\n second | 1 -\n third | 1 +\n 3 files changed, 2 insertions(+), 1 deletions(-)\n",
879 "diffstat": " fourth | 1 +\n second | 1 -\n third | 1 +\n 3 files changed, 2 insertions(+), 1 deletions(-)\n",
880 "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"
880 "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"
881 }
881 }
882 ]
882 ]
883
883
884 honor --git but not format-breaking diffopts
884 honor --git but not format-breaking diffopts
885 $ hg --config diff.noprefix=True log --git -vpr . -Tjson
885 $ hg --config diff.noprefix=True log --git -vpr . -Tjson
886 [
886 [
887 {
887 {
888 "rev": 8,
888 "rev": 8,
889 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
889 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
890 "branch": "default",
890 "branch": "default",
891 "phase": "draft",
891 "phase": "draft",
892 "user": "test",
892 "user": "test",
893 "date": [1577872860, 0],
893 "date": [1577872860, 0],
894 "desc": "third",
894 "desc": "third",
895 "bookmarks": [],
895 "bookmarks": [],
896 "tags": ["tip"],
896 "tags": ["tip"],
897 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
897 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
898 "files": ["fourth", "second", "third"],
898 "files": ["fourth", "second", "third"],
899 "diff": "diff --git a/second b/fourth\nrename from second\nrename to fourth\ndiff --git a/third b/third\nnew file mode 100644\n--- /dev/null\n+++ b/third\n@@ -0,0 +1,1 @@\n+third\n"
899 "diff": "diff --git a/second b/fourth\nrename from second\nrename to fourth\ndiff --git a/third b/third\nnew file mode 100644\n--- /dev/null\n+++ b/third\n@@ -0,0 +1,1 @@\n+third\n"
900 }
900 }
901 ]
901 ]
902
902
903 $ hg log -T json
903 $ hg log -T json
904 [
904 [
905 {
905 {
906 "rev": 8,
906 "rev": 8,
907 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
907 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
908 "branch": "default",
908 "branch": "default",
909 "phase": "draft",
909 "phase": "draft",
910 "user": "test",
910 "user": "test",
911 "date": [1577872860, 0],
911 "date": [1577872860, 0],
912 "desc": "third",
912 "desc": "third",
913 "bookmarks": [],
913 "bookmarks": [],
914 "tags": ["tip"],
914 "tags": ["tip"],
915 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"]
915 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"]
916 },
916 },
917 {
917 {
918 "rev": 7,
918 "rev": 7,
919 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
919 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
920 "branch": "default",
920 "branch": "default",
921 "phase": "draft",
921 "phase": "draft",
922 "user": "User Name <user@hostname>",
922 "user": "User Name <user@hostname>",
923 "date": [1000000, 0],
923 "date": [1000000, 0],
924 "desc": "second",
924 "desc": "second",
925 "bookmarks": [],
925 "bookmarks": [],
926 "tags": [],
926 "tags": [],
927 "parents": ["0000000000000000000000000000000000000000"]
927 "parents": ["0000000000000000000000000000000000000000"]
928 },
928 },
929 {
929 {
930 "rev": 6,
930 "rev": 6,
931 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
931 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
932 "branch": "default",
932 "branch": "default",
933 "phase": "draft",
933 "phase": "draft",
934 "user": "person",
934 "user": "person",
935 "date": [1500001, 0],
935 "date": [1500001, 0],
936 "desc": "merge",
936 "desc": "merge",
937 "bookmarks": [],
937 "bookmarks": [],
938 "tags": [],
938 "tags": [],
939 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"]
939 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"]
940 },
940 },
941 {
941 {
942 "rev": 5,
942 "rev": 5,
943 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
943 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
944 "branch": "default",
944 "branch": "default",
945 "phase": "draft",
945 "phase": "draft",
946 "user": "person",
946 "user": "person",
947 "date": [1500000, 0],
947 "date": [1500000, 0],
948 "desc": "new head",
948 "desc": "new head",
949 "bookmarks": [],
949 "bookmarks": [],
950 "tags": [],
950 "tags": [],
951 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"]
951 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"]
952 },
952 },
953 {
953 {
954 "rev": 4,
954 "rev": 4,
955 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
955 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
956 "branch": "foo",
956 "branch": "foo",
957 "phase": "draft",
957 "phase": "draft",
958 "user": "person",
958 "user": "person",
959 "date": [1400000, 0],
959 "date": [1400000, 0],
960 "desc": "new branch",
960 "desc": "new branch",
961 "bookmarks": [],
961 "bookmarks": [],
962 "tags": [],
962 "tags": [],
963 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"]
963 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"]
964 },
964 },
965 {
965 {
966 "rev": 3,
966 "rev": 3,
967 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
967 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
968 "branch": "default",
968 "branch": "default",
969 "phase": "draft",
969 "phase": "draft",
970 "user": "person",
970 "user": "person",
971 "date": [1300000, 0],
971 "date": [1300000, 0],
972 "desc": "no user, no domain",
972 "desc": "no user, no domain",
973 "bookmarks": [],
973 "bookmarks": [],
974 "tags": [],
974 "tags": [],
975 "parents": ["97054abb4ab824450e9164180baf491ae0078465"]
975 "parents": ["97054abb4ab824450e9164180baf491ae0078465"]
976 },
976 },
977 {
977 {
978 "rev": 2,
978 "rev": 2,
979 "node": "97054abb4ab824450e9164180baf491ae0078465",
979 "node": "97054abb4ab824450e9164180baf491ae0078465",
980 "branch": "default",
980 "branch": "default",
981 "phase": "draft",
981 "phase": "draft",
982 "user": "other@place",
982 "user": "other@place",
983 "date": [1200000, 0],
983 "date": [1200000, 0],
984 "desc": "no person",
984 "desc": "no person",
985 "bookmarks": [],
985 "bookmarks": [],
986 "tags": [],
986 "tags": [],
987 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"]
987 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"]
988 },
988 },
989 {
989 {
990 "rev": 1,
990 "rev": 1,
991 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
991 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
992 "branch": "default",
992 "branch": "default",
993 "phase": "draft",
993 "phase": "draft",
994 "user": "A. N. Other <other@place>",
994 "user": "A. N. Other <other@place>",
995 "date": [1100000, 0],
995 "date": [1100000, 0],
996 "desc": "other 1\nother 2\n\nother 3",
996 "desc": "other 1\nother 2\n\nother 3",
997 "bookmarks": [],
997 "bookmarks": [],
998 "tags": [],
998 "tags": [],
999 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"]
999 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"]
1000 },
1000 },
1001 {
1001 {
1002 "rev": 0,
1002 "rev": 0,
1003 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
1003 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
1004 "branch": "default",
1004 "branch": "default",
1005 "phase": "draft",
1005 "phase": "draft",
1006 "user": "User Name <user@hostname>",
1006 "user": "User Name <user@hostname>",
1007 "date": [1000000, 0],
1007 "date": [1000000, 0],
1008 "desc": "line 1\nline 2",
1008 "desc": "line 1\nline 2",
1009 "bookmarks": [],
1009 "bookmarks": [],
1010 "tags": [],
1010 "tags": [],
1011 "parents": ["0000000000000000000000000000000000000000"]
1011 "parents": ["0000000000000000000000000000000000000000"]
1012 }
1012 }
1013 ]
1013 ]
1014
1014
1015 $ hg heads -v -Tjson
1015 $ hg heads -v -Tjson
1016 [
1016 [
1017 {
1017 {
1018 "rev": 8,
1018 "rev": 8,
1019 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
1019 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
1020 "branch": "default",
1020 "branch": "default",
1021 "phase": "draft",
1021 "phase": "draft",
1022 "user": "test",
1022 "user": "test",
1023 "date": [1577872860, 0],
1023 "date": [1577872860, 0],
1024 "desc": "third",
1024 "desc": "third",
1025 "bookmarks": [],
1025 "bookmarks": [],
1026 "tags": ["tip"],
1026 "tags": ["tip"],
1027 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
1027 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
1028 "files": ["fourth", "second", "third"]
1028 "files": ["fourth", "second", "third"]
1029 },
1029 },
1030 {
1030 {
1031 "rev": 6,
1031 "rev": 6,
1032 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
1032 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
1033 "branch": "default",
1033 "branch": "default",
1034 "phase": "draft",
1034 "phase": "draft",
1035 "user": "person",
1035 "user": "person",
1036 "date": [1500001, 0],
1036 "date": [1500001, 0],
1037 "desc": "merge",
1037 "desc": "merge",
1038 "bookmarks": [],
1038 "bookmarks": [],
1039 "tags": [],
1039 "tags": [],
1040 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
1040 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
1041 "files": []
1041 "files": []
1042 },
1042 },
1043 {
1043 {
1044 "rev": 4,
1044 "rev": 4,
1045 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
1045 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
1046 "branch": "foo",
1046 "branch": "foo",
1047 "phase": "draft",
1047 "phase": "draft",
1048 "user": "person",
1048 "user": "person",
1049 "date": [1400000, 0],
1049 "date": [1400000, 0],
1050 "desc": "new branch",
1050 "desc": "new branch",
1051 "bookmarks": [],
1051 "bookmarks": [],
1052 "tags": [],
1052 "tags": [],
1053 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
1053 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
1054 "files": []
1054 "files": []
1055 }
1055 }
1056 ]
1056 ]
1057
1057
1058 $ hg log --debug -Tjson
1058 $ hg log --debug -Tjson
1059 [
1059 [
1060 {
1060 {
1061 "rev": 8,
1061 "rev": 8,
1062 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
1062 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
1063 "branch": "default",
1063 "branch": "default",
1064 "phase": "draft",
1064 "phase": "draft",
1065 "user": "test",
1065 "user": "test",
1066 "date": [1577872860, 0],
1066 "date": [1577872860, 0],
1067 "desc": "third",
1067 "desc": "third",
1068 "bookmarks": [],
1068 "bookmarks": [],
1069 "tags": ["tip"],
1069 "tags": ["tip"],
1070 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
1070 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
1071 "manifest": "94961b75a2da554b4df6fb599e5bfc7d48de0c64",
1071 "manifest": "94961b75a2da554b4df6fb599e5bfc7d48de0c64",
1072 "extra": {"branch": "default"},
1072 "extra": {"branch": "default"},
1073 "modified": [],
1073 "modified": [],
1074 "added": ["fourth", "third"],
1074 "added": ["fourth", "third"],
1075 "removed": ["second"]
1075 "removed": ["second"]
1076 },
1076 },
1077 {
1077 {
1078 "rev": 7,
1078 "rev": 7,
1079 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
1079 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
1080 "branch": "default",
1080 "branch": "default",
1081 "phase": "draft",
1081 "phase": "draft",
1082 "user": "User Name <user@hostname>",
1082 "user": "User Name <user@hostname>",
1083 "date": [1000000, 0],
1083 "date": [1000000, 0],
1084 "desc": "second",
1084 "desc": "second",
1085 "bookmarks": [],
1085 "bookmarks": [],
1086 "tags": [],
1086 "tags": [],
1087 "parents": ["0000000000000000000000000000000000000000"],
1087 "parents": ["0000000000000000000000000000000000000000"],
1088 "manifest": "f2dbc354b94e5ec0b4f10680ee0cee816101d0bf",
1088 "manifest": "f2dbc354b94e5ec0b4f10680ee0cee816101d0bf",
1089 "extra": {"branch": "default"},
1089 "extra": {"branch": "default"},
1090 "modified": [],
1090 "modified": [],
1091 "added": ["second"],
1091 "added": ["second"],
1092 "removed": []
1092 "removed": []
1093 },
1093 },
1094 {
1094 {
1095 "rev": 6,
1095 "rev": 6,
1096 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
1096 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
1097 "branch": "default",
1097 "branch": "default",
1098 "phase": "draft",
1098 "phase": "draft",
1099 "user": "person",
1099 "user": "person",
1100 "date": [1500001, 0],
1100 "date": [1500001, 0],
1101 "desc": "merge",
1101 "desc": "merge",
1102 "bookmarks": [],
1102 "bookmarks": [],
1103 "tags": [],
1103 "tags": [],
1104 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
1104 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
1105 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
1105 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
1106 "extra": {"branch": "default"},
1106 "extra": {"branch": "default"},
1107 "modified": [],
1107 "modified": [],
1108 "added": [],
1108 "added": [],
1109 "removed": []
1109 "removed": []
1110 },
1110 },
1111 {
1111 {
1112 "rev": 5,
1112 "rev": 5,
1113 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
1113 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
1114 "branch": "default",
1114 "branch": "default",
1115 "phase": "draft",
1115 "phase": "draft",
1116 "user": "person",
1116 "user": "person",
1117 "date": [1500000, 0],
1117 "date": [1500000, 0],
1118 "desc": "new head",
1118 "desc": "new head",
1119 "bookmarks": [],
1119 "bookmarks": [],
1120 "tags": [],
1120 "tags": [],
1121 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
1121 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
1122 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
1122 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
1123 "extra": {"branch": "default"},
1123 "extra": {"branch": "default"},
1124 "modified": [],
1124 "modified": [],
1125 "added": ["d"],
1125 "added": ["d"],
1126 "removed": []
1126 "removed": []
1127 },
1127 },
1128 {
1128 {
1129 "rev": 4,
1129 "rev": 4,
1130 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
1130 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
1131 "branch": "foo",
1131 "branch": "foo",
1132 "phase": "draft",
1132 "phase": "draft",
1133 "user": "person",
1133 "user": "person",
1134 "date": [1400000, 0],
1134 "date": [1400000, 0],
1135 "desc": "new branch",
1135 "desc": "new branch",
1136 "bookmarks": [],
1136 "bookmarks": [],
1137 "tags": [],
1137 "tags": [],
1138 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
1138 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
1139 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
1139 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
1140 "extra": {"branch": "foo"},
1140 "extra": {"branch": "foo"},
1141 "modified": [],
1141 "modified": [],
1142 "added": [],
1142 "added": [],
1143 "removed": []
1143 "removed": []
1144 },
1144 },
1145 {
1145 {
1146 "rev": 3,
1146 "rev": 3,
1147 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
1147 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
1148 "branch": "default",
1148 "branch": "default",
1149 "phase": "draft",
1149 "phase": "draft",
1150 "user": "person",
1150 "user": "person",
1151 "date": [1300000, 0],
1151 "date": [1300000, 0],
1152 "desc": "no user, no domain",
1152 "desc": "no user, no domain",
1153 "bookmarks": [],
1153 "bookmarks": [],
1154 "tags": [],
1154 "tags": [],
1155 "parents": ["97054abb4ab824450e9164180baf491ae0078465"],
1155 "parents": ["97054abb4ab824450e9164180baf491ae0078465"],
1156 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
1156 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
1157 "extra": {"branch": "default"},
1157 "extra": {"branch": "default"},
1158 "modified": ["c"],
1158 "modified": ["c"],
1159 "added": [],
1159 "added": [],
1160 "removed": []
1160 "removed": []
1161 },
1161 },
1162 {
1162 {
1163 "rev": 2,
1163 "rev": 2,
1164 "node": "97054abb4ab824450e9164180baf491ae0078465",
1164 "node": "97054abb4ab824450e9164180baf491ae0078465",
1165 "branch": "default",
1165 "branch": "default",
1166 "phase": "draft",
1166 "phase": "draft",
1167 "user": "other@place",
1167 "user": "other@place",
1168 "date": [1200000, 0],
1168 "date": [1200000, 0],
1169 "desc": "no person",
1169 "desc": "no person",
1170 "bookmarks": [],
1170 "bookmarks": [],
1171 "tags": [],
1171 "tags": [],
1172 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"],
1172 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"],
1173 "manifest": "6e0e82995c35d0d57a52aca8da4e56139e06b4b1",
1173 "manifest": "6e0e82995c35d0d57a52aca8da4e56139e06b4b1",
1174 "extra": {"branch": "default"},
1174 "extra": {"branch": "default"},
1175 "modified": [],
1175 "modified": [],
1176 "added": ["c"],
1176 "added": ["c"],
1177 "removed": []
1177 "removed": []
1178 },
1178 },
1179 {
1179 {
1180 "rev": 1,
1180 "rev": 1,
1181 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
1181 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
1182 "branch": "default",
1182 "branch": "default",
1183 "phase": "draft",
1183 "phase": "draft",
1184 "user": "A. N. Other <other@place>",
1184 "user": "A. N. Other <other@place>",
1185 "date": [1100000, 0],
1185 "date": [1100000, 0],
1186 "desc": "other 1\nother 2\n\nother 3",
1186 "desc": "other 1\nother 2\n\nother 3",
1187 "bookmarks": [],
1187 "bookmarks": [],
1188 "tags": [],
1188 "tags": [],
1189 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"],
1189 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"],
1190 "manifest": "4e8d705b1e53e3f9375e0e60dc7b525d8211fe55",
1190 "manifest": "4e8d705b1e53e3f9375e0e60dc7b525d8211fe55",
1191 "extra": {"branch": "default"},
1191 "extra": {"branch": "default"},
1192 "modified": [],
1192 "modified": [],
1193 "added": ["b"],
1193 "added": ["b"],
1194 "removed": []
1194 "removed": []
1195 },
1195 },
1196 {
1196 {
1197 "rev": 0,
1197 "rev": 0,
1198 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
1198 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
1199 "branch": "default",
1199 "branch": "default",
1200 "phase": "draft",
1200 "phase": "draft",
1201 "user": "User Name <user@hostname>",
1201 "user": "User Name <user@hostname>",
1202 "date": [1000000, 0],
1202 "date": [1000000, 0],
1203 "desc": "line 1\nline 2",
1203 "desc": "line 1\nline 2",
1204 "bookmarks": [],
1204 "bookmarks": [],
1205 "tags": [],
1205 "tags": [],
1206 "parents": ["0000000000000000000000000000000000000000"],
1206 "parents": ["0000000000000000000000000000000000000000"],
1207 "manifest": "a0c8bcbbb45c63b90b70ad007bf38961f64f2af0",
1207 "manifest": "a0c8bcbbb45c63b90b70ad007bf38961f64f2af0",
1208 "extra": {"branch": "default"},
1208 "extra": {"branch": "default"},
1209 "modified": [],
1209 "modified": [],
1210 "added": ["a"],
1210 "added": ["a"],
1211 "removed": []
1211 "removed": []
1212 }
1212 }
1213 ]
1213 ]
1214
1214
1215 Error if style not readable:
1215 Error if style not readable:
1216
1216
1217 #if unix-permissions no-root
1217 #if unix-permissions no-root
1218 $ touch q
1218 $ touch q
1219 $ chmod 0 q
1219 $ chmod 0 q
1220 $ hg log --style ./q
1220 $ hg log --style ./q
1221 abort: Permission denied: ./q
1221 abort: Permission denied: ./q
1222 [255]
1222 [255]
1223 #endif
1223 #endif
1224
1224
1225 Error if no style:
1225 Error if no style:
1226
1226
1227 $ hg log --style notexist
1227 $ hg log --style notexist
1228 abort: style 'notexist' not found
1228 abort: style 'notexist' not found
1229 (available styles: bisect, changelog, compact, default, phases, show, status, xml)
1229 (available styles: bisect, changelog, compact, default, phases, show, status, xml)
1230 [255]
1230 [255]
1231
1231
1232 $ hg log -T list
1232 $ hg log -T list
1233 available styles: bisect, changelog, compact, default, phases, show, status, xml
1233 available styles: bisect, changelog, compact, default, phases, show, status, xml
1234 abort: specify a template
1234 abort: specify a template
1235 [255]
1235 [255]
1236
1236
1237 Error if style missing key:
1237 Error if style missing key:
1238
1238
1239 $ echo 'q = q' > t
1239 $ echo 'q = q' > t
1240 $ hg log --style ./t
1240 $ hg log --style ./t
1241 abort: "changeset" not in template map
1241 abort: "changeset" not in template map
1242 [255]
1242 [255]
1243
1243
1244 Error if style missing value:
1244 Error if style missing value:
1245
1245
1246 $ echo 'changeset =' > t
1246 $ echo 'changeset =' > t
1247 $ hg log --style t
1247 $ hg log --style t
1248 hg: parse error at t:1: missing value
1248 hg: parse error at t:1: missing value
1249 [255]
1249 [255]
1250
1250
1251 Error if include fails:
1251 Error if include fails:
1252
1252
1253 $ echo 'changeset = q' >> t
1253 $ echo 'changeset = q' >> t
1254 #if unix-permissions no-root
1254 #if unix-permissions no-root
1255 $ hg log --style ./t
1255 $ hg log --style ./t
1256 abort: template file ./q: Permission denied
1256 abort: template file ./q: Permission denied
1257 [255]
1257 [255]
1258 $ rm -f q
1258 $ rm -f q
1259 #endif
1259 #endif
1260
1260
1261 Include works:
1261 Include works:
1262
1262
1263 $ echo '{rev}' > q
1263 $ echo '{rev}' > q
1264 $ hg log --style ./t
1264 $ hg log --style ./t
1265 8
1265 8
1266 7
1266 7
1267 6
1267 6
1268 5
1268 5
1269 4
1269 4
1270 3
1270 3
1271 2
1271 2
1272 1
1272 1
1273 0
1273 0
1274
1274
1275 Check that recursive reference does not fall into RuntimeError (issue4758):
1275 Check that recursive reference does not fall into RuntimeError (issue4758):
1276
1276
1277 common mistake:
1277 common mistake:
1278
1278
1279 $ cat << EOF > issue4758
1279 $ cat << EOF > issue4758
1280 > changeset = '{changeset}\n'
1280 > changeset = '{changeset}\n'
1281 > EOF
1281 > EOF
1282 $ hg log --style ./issue4758
1282 $ hg log --style ./issue4758
1283 abort: recursive reference 'changeset' in template
1283 abort: recursive reference 'changeset' in template
1284 [255]
1284 [255]
1285
1285
1286 circular reference:
1286 circular reference:
1287
1287
1288 $ cat << EOF > issue4758
1288 $ cat << EOF > issue4758
1289 > changeset = '{foo}'
1289 > changeset = '{foo}'
1290 > foo = '{changeset}'
1290 > foo = '{changeset}'
1291 > EOF
1291 > EOF
1292 $ hg log --style ./issue4758
1292 $ hg log --style ./issue4758
1293 abort: recursive reference 'foo' in template
1293 abort: recursive reference 'foo' in template
1294 [255]
1294 [255]
1295
1295
1296 buildmap() -> gettemplate(), where no thunk was made:
1296 buildmap() -> gettemplate(), where no thunk was made:
1297
1297
1298 $ cat << EOF > issue4758
1298 $ cat << EOF > issue4758
1299 > changeset = '{files % changeset}\n'
1299 > changeset = '{files % changeset}\n'
1300 > EOF
1300 > EOF
1301 $ hg log --style ./issue4758
1301 $ hg log --style ./issue4758
1302 abort: recursive reference 'changeset' in template
1302 abort: recursive reference 'changeset' in template
1303 [255]
1303 [255]
1304
1304
1305 not a recursion if a keyword of the same name exists:
1305 not a recursion if a keyword of the same name exists:
1306
1306
1307 $ cat << EOF > issue4758
1307 $ cat << EOF > issue4758
1308 > changeset = '{tags % rev}'
1308 > changeset = '{tags % rev}'
1309 > rev = '{rev} {tag}\n'
1309 > rev = '{rev} {tag}\n'
1310 > EOF
1310 > EOF
1311 $ hg log --style ./issue4758 -r tip
1311 $ hg log --style ./issue4758 -r tip
1312 8 tip
1312 8 tip
1313
1313
1314 Check that {phase} works correctly on parents:
1314 Check that {phase} works correctly on parents:
1315
1315
1316 $ cat << EOF > parentphase
1316 $ cat << EOF > parentphase
1317 > changeset_debug = '{rev} ({phase}):{parents}\n'
1317 > changeset_debug = '{rev} ({phase}):{parents}\n'
1318 > parent = ' {rev} ({phase})'
1318 > parent = ' {rev} ({phase})'
1319 > EOF
1319 > EOF
1320 $ hg phase -r 5 --public
1320 $ hg phase -r 5 --public
1321 $ hg phase -r 7 --secret --force
1321 $ hg phase -r 7 --secret --force
1322 $ hg log --debug -G --style ./parentphase
1322 $ hg log --debug -G --style ./parentphase
1323 @ 8 (secret): 7 (secret) -1 (public)
1323 @ 8 (secret): 7 (secret) -1 (public)
1324 |
1324 |
1325 o 7 (secret): -1 (public) -1 (public)
1325 o 7 (secret): -1 (public) -1 (public)
1326
1326
1327 o 6 (draft): 5 (public) 4 (draft)
1327 o 6 (draft): 5 (public) 4 (draft)
1328 |\
1328 |\
1329 | o 5 (public): 3 (public) -1 (public)
1329 | o 5 (public): 3 (public) -1 (public)
1330 | |
1330 | |
1331 o | 4 (draft): 3 (public) -1 (public)
1331 o | 4 (draft): 3 (public) -1 (public)
1332 |/
1332 |/
1333 o 3 (public): 2 (public) -1 (public)
1333 o 3 (public): 2 (public) -1 (public)
1334 |
1334 |
1335 o 2 (public): 1 (public) -1 (public)
1335 o 2 (public): 1 (public) -1 (public)
1336 |
1336 |
1337 o 1 (public): 0 (public) -1 (public)
1337 o 1 (public): 0 (public) -1 (public)
1338 |
1338 |
1339 o 0 (public): -1 (public) -1 (public)
1339 o 0 (public): -1 (public) -1 (public)
1340
1340
1341
1341
1342 Missing non-standard names give no error (backward compatibility):
1342 Missing non-standard names give no error (backward compatibility):
1343
1343
1344 $ echo "changeset = '{c}'" > t
1344 $ echo "changeset = '{c}'" > t
1345 $ hg log --style ./t
1345 $ hg log --style ./t
1346
1346
1347 Defining non-standard name works:
1347 Defining non-standard name works:
1348
1348
1349 $ cat <<EOF > t
1349 $ cat <<EOF > t
1350 > changeset = '{c}'
1350 > changeset = '{c}'
1351 > c = q
1351 > c = q
1352 > EOF
1352 > EOF
1353 $ hg log --style ./t
1353 $ hg log --style ./t
1354 8
1354 8
1355 7
1355 7
1356 6
1356 6
1357 5
1357 5
1358 4
1358 4
1359 3
1359 3
1360 2
1360 2
1361 1
1361 1
1362 0
1362 0
1363
1363
1364 ui.style works:
1364 ui.style works:
1365
1365
1366 $ echo '[ui]' > .hg/hgrc
1366 $ echo '[ui]' > .hg/hgrc
1367 $ echo 'style = t' >> .hg/hgrc
1367 $ echo 'style = t' >> .hg/hgrc
1368 $ hg log
1368 $ hg log
1369 8
1369 8
1370 7
1370 7
1371 6
1371 6
1372 5
1372 5
1373 4
1373 4
1374 3
1374 3
1375 2
1375 2
1376 1
1376 1
1377 0
1377 0
1378
1378
1379
1379
1380 Issue338:
1380 Issue338:
1381
1381
1382 $ hg log --style=changelog > changelog
1382 $ hg log --style=changelog > changelog
1383
1383
1384 $ cat changelog
1384 $ cat changelog
1385 2020-01-01 test <test>
1385 2020-01-01 test <test>
1386
1386
1387 * fourth, second, third:
1387 * fourth, second, third:
1388 third
1388 third
1389 [95c24699272e] [tip]
1389 [95c24699272e] [tip]
1390
1390
1391 1970-01-12 User Name <user@hostname>
1391 1970-01-12 User Name <user@hostname>
1392
1392
1393 * second:
1393 * second:
1394 second
1394 second
1395 [29114dbae42b]
1395 [29114dbae42b]
1396
1396
1397 1970-01-18 person <person>
1397 1970-01-18 person <person>
1398
1398
1399 * merge
1399 * merge
1400 [d41e714fe50d]
1400 [d41e714fe50d]
1401
1401
1402 * d:
1402 * d:
1403 new head
1403 new head
1404 [13207e5a10d9]
1404 [13207e5a10d9]
1405
1405
1406 1970-01-17 person <person>
1406 1970-01-17 person <person>
1407
1407
1408 * new branch
1408 * new branch
1409 [bbe44766e73d] <foo>
1409 [bbe44766e73d] <foo>
1410
1410
1411 1970-01-16 person <person>
1411 1970-01-16 person <person>
1412
1412
1413 * c:
1413 * c:
1414 no user, no domain
1414 no user, no domain
1415 [10e46f2dcbf4]
1415 [10e46f2dcbf4]
1416
1416
1417 1970-01-14 other <other@place>
1417 1970-01-14 other <other@place>
1418
1418
1419 * c:
1419 * c:
1420 no person
1420 no person
1421 [97054abb4ab8]
1421 [97054abb4ab8]
1422
1422
1423 1970-01-13 A. N. Other <other@place>
1423 1970-01-13 A. N. Other <other@place>
1424
1424
1425 * b:
1425 * b:
1426 other 1 other 2
1426 other 1 other 2
1427
1427
1428 other 3
1428 other 3
1429 [b608e9d1a3f0]
1429 [b608e9d1a3f0]
1430
1430
1431 1970-01-12 User Name <user@hostname>
1431 1970-01-12 User Name <user@hostname>
1432
1432
1433 * a:
1433 * a:
1434 line 1 line 2
1434 line 1 line 2
1435 [1e4e1b8f71e0]
1435 [1e4e1b8f71e0]
1436
1436
1437
1437
1438 Issue2130: xml output for 'hg heads' is malformed
1438 Issue2130: xml output for 'hg heads' is malformed
1439
1439
1440 $ hg heads --style changelog
1440 $ hg heads --style changelog
1441 2020-01-01 test <test>
1441 2020-01-01 test <test>
1442
1442
1443 * fourth, second, third:
1443 * fourth, second, third:
1444 third
1444 third
1445 [95c24699272e] [tip]
1445 [95c24699272e] [tip]
1446
1446
1447 1970-01-18 person <person>
1447 1970-01-18 person <person>
1448
1448
1449 * merge
1449 * merge
1450 [d41e714fe50d]
1450 [d41e714fe50d]
1451
1451
1452 1970-01-17 person <person>
1452 1970-01-17 person <person>
1453
1453
1454 * new branch
1454 * new branch
1455 [bbe44766e73d] <foo>
1455 [bbe44766e73d] <foo>
1456
1456
1457
1457
1458 Keys work:
1458 Keys work:
1459
1459
1460 $ for key in author branch branches date desc file_adds file_dels file_mods \
1460 $ for key in author branch branches date desc file_adds file_dels file_mods \
1461 > file_copies file_copies_switch files \
1461 > file_copies file_copies_switch files \
1462 > manifest node parents rev tags diffstat extras \
1462 > manifest node parents rev tags diffstat extras \
1463 > p1rev p2rev p1node p2node; do
1463 > p1rev p2rev p1node p2node; do
1464 > for mode in '' --verbose --debug; do
1464 > for mode in '' --verbose --debug; do
1465 > hg log $mode --template "$key$mode: {$key}\n"
1465 > hg log $mode --template "$key$mode: {$key}\n"
1466 > done
1466 > done
1467 > done
1467 > done
1468 author: test
1468 author: test
1469 author: User Name <user@hostname>
1469 author: User Name <user@hostname>
1470 author: person
1470 author: person
1471 author: person
1471 author: person
1472 author: person
1472 author: person
1473 author: person
1473 author: person
1474 author: other@place
1474 author: other@place
1475 author: A. N. Other <other@place>
1475 author: A. N. Other <other@place>
1476 author: User Name <user@hostname>
1476 author: User Name <user@hostname>
1477 author--verbose: test
1477 author--verbose: test
1478 author--verbose: User Name <user@hostname>
1478 author--verbose: User Name <user@hostname>
1479 author--verbose: person
1479 author--verbose: person
1480 author--verbose: person
1480 author--verbose: person
1481 author--verbose: person
1481 author--verbose: person
1482 author--verbose: person
1482 author--verbose: person
1483 author--verbose: other@place
1483 author--verbose: other@place
1484 author--verbose: A. N. Other <other@place>
1484 author--verbose: A. N. Other <other@place>
1485 author--verbose: User Name <user@hostname>
1485 author--verbose: User Name <user@hostname>
1486 author--debug: test
1486 author--debug: test
1487 author--debug: User Name <user@hostname>
1487 author--debug: User Name <user@hostname>
1488 author--debug: person
1488 author--debug: person
1489 author--debug: person
1489 author--debug: person
1490 author--debug: person
1490 author--debug: person
1491 author--debug: person
1491 author--debug: person
1492 author--debug: other@place
1492 author--debug: other@place
1493 author--debug: A. N. Other <other@place>
1493 author--debug: A. N. Other <other@place>
1494 author--debug: User Name <user@hostname>
1494 author--debug: User Name <user@hostname>
1495 branch: default
1495 branch: default
1496 branch: default
1496 branch: default
1497 branch: default
1497 branch: default
1498 branch: default
1498 branch: default
1499 branch: foo
1499 branch: foo
1500 branch: default
1500 branch: default
1501 branch: default
1501 branch: default
1502 branch: default
1502 branch: default
1503 branch: default
1503 branch: default
1504 branch--verbose: default
1504 branch--verbose: default
1505 branch--verbose: default
1505 branch--verbose: default
1506 branch--verbose: default
1506 branch--verbose: default
1507 branch--verbose: default
1507 branch--verbose: default
1508 branch--verbose: foo
1508 branch--verbose: foo
1509 branch--verbose: default
1509 branch--verbose: default
1510 branch--verbose: default
1510 branch--verbose: default
1511 branch--verbose: default
1511 branch--verbose: default
1512 branch--verbose: default
1512 branch--verbose: default
1513 branch--debug: default
1513 branch--debug: default
1514 branch--debug: default
1514 branch--debug: default
1515 branch--debug: default
1515 branch--debug: default
1516 branch--debug: default
1516 branch--debug: default
1517 branch--debug: foo
1517 branch--debug: foo
1518 branch--debug: default
1518 branch--debug: default
1519 branch--debug: default
1519 branch--debug: default
1520 branch--debug: default
1520 branch--debug: default
1521 branch--debug: default
1521 branch--debug: default
1522 branches:
1522 branches:
1523 branches:
1523 branches:
1524 branches:
1524 branches:
1525 branches:
1525 branches:
1526 branches: foo
1526 branches: foo
1527 branches:
1527 branches:
1528 branches:
1528 branches:
1529 branches:
1529 branches:
1530 branches:
1530 branches:
1531 branches--verbose:
1531 branches--verbose:
1532 branches--verbose:
1532 branches--verbose:
1533 branches--verbose:
1533 branches--verbose:
1534 branches--verbose:
1534 branches--verbose:
1535 branches--verbose: foo
1535 branches--verbose: foo
1536 branches--verbose:
1536 branches--verbose:
1537 branches--verbose:
1537 branches--verbose:
1538 branches--verbose:
1538 branches--verbose:
1539 branches--verbose:
1539 branches--verbose:
1540 branches--debug:
1540 branches--debug:
1541 branches--debug:
1541 branches--debug:
1542 branches--debug:
1542 branches--debug:
1543 branches--debug:
1543 branches--debug:
1544 branches--debug: foo
1544 branches--debug: foo
1545 branches--debug:
1545 branches--debug:
1546 branches--debug:
1546 branches--debug:
1547 branches--debug:
1547 branches--debug:
1548 branches--debug:
1548 branches--debug:
1549 date: 1577872860.00
1549 date: 1577872860.00
1550 date: 1000000.00
1550 date: 1000000.00
1551 date: 1500001.00
1551 date: 1500001.00
1552 date: 1500000.00
1552 date: 1500000.00
1553 date: 1400000.00
1553 date: 1400000.00
1554 date: 1300000.00
1554 date: 1300000.00
1555 date: 1200000.00
1555 date: 1200000.00
1556 date: 1100000.00
1556 date: 1100000.00
1557 date: 1000000.00
1557 date: 1000000.00
1558 date--verbose: 1577872860.00
1558 date--verbose: 1577872860.00
1559 date--verbose: 1000000.00
1559 date--verbose: 1000000.00
1560 date--verbose: 1500001.00
1560 date--verbose: 1500001.00
1561 date--verbose: 1500000.00
1561 date--verbose: 1500000.00
1562 date--verbose: 1400000.00
1562 date--verbose: 1400000.00
1563 date--verbose: 1300000.00
1563 date--verbose: 1300000.00
1564 date--verbose: 1200000.00
1564 date--verbose: 1200000.00
1565 date--verbose: 1100000.00
1565 date--verbose: 1100000.00
1566 date--verbose: 1000000.00
1566 date--verbose: 1000000.00
1567 date--debug: 1577872860.00
1567 date--debug: 1577872860.00
1568 date--debug: 1000000.00
1568 date--debug: 1000000.00
1569 date--debug: 1500001.00
1569 date--debug: 1500001.00
1570 date--debug: 1500000.00
1570 date--debug: 1500000.00
1571 date--debug: 1400000.00
1571 date--debug: 1400000.00
1572 date--debug: 1300000.00
1572 date--debug: 1300000.00
1573 date--debug: 1200000.00
1573 date--debug: 1200000.00
1574 date--debug: 1100000.00
1574 date--debug: 1100000.00
1575 date--debug: 1000000.00
1575 date--debug: 1000000.00
1576 desc: third
1576 desc: third
1577 desc: second
1577 desc: second
1578 desc: merge
1578 desc: merge
1579 desc: new head
1579 desc: new head
1580 desc: new branch
1580 desc: new branch
1581 desc: no user, no domain
1581 desc: no user, no domain
1582 desc: no person
1582 desc: no person
1583 desc: other 1
1583 desc: other 1
1584 other 2
1584 other 2
1585
1585
1586 other 3
1586 other 3
1587 desc: line 1
1587 desc: line 1
1588 line 2
1588 line 2
1589 desc--verbose: third
1589 desc--verbose: third
1590 desc--verbose: second
1590 desc--verbose: second
1591 desc--verbose: merge
1591 desc--verbose: merge
1592 desc--verbose: new head
1592 desc--verbose: new head
1593 desc--verbose: new branch
1593 desc--verbose: new branch
1594 desc--verbose: no user, no domain
1594 desc--verbose: no user, no domain
1595 desc--verbose: no person
1595 desc--verbose: no person
1596 desc--verbose: other 1
1596 desc--verbose: other 1
1597 other 2
1597 other 2
1598
1598
1599 other 3
1599 other 3
1600 desc--verbose: line 1
1600 desc--verbose: line 1
1601 line 2
1601 line 2
1602 desc--debug: third
1602 desc--debug: third
1603 desc--debug: second
1603 desc--debug: second
1604 desc--debug: merge
1604 desc--debug: merge
1605 desc--debug: new head
1605 desc--debug: new head
1606 desc--debug: new branch
1606 desc--debug: new branch
1607 desc--debug: no user, no domain
1607 desc--debug: no user, no domain
1608 desc--debug: no person
1608 desc--debug: no person
1609 desc--debug: other 1
1609 desc--debug: other 1
1610 other 2
1610 other 2
1611
1611
1612 other 3
1612 other 3
1613 desc--debug: line 1
1613 desc--debug: line 1
1614 line 2
1614 line 2
1615 file_adds: fourth third
1615 file_adds: fourth third
1616 file_adds: second
1616 file_adds: second
1617 file_adds:
1617 file_adds:
1618 file_adds: d
1618 file_adds: d
1619 file_adds:
1619 file_adds:
1620 file_adds:
1620 file_adds:
1621 file_adds: c
1621 file_adds: c
1622 file_adds: b
1622 file_adds: b
1623 file_adds: a
1623 file_adds: a
1624 file_adds--verbose: fourth third
1624 file_adds--verbose: fourth third
1625 file_adds--verbose: second
1625 file_adds--verbose: second
1626 file_adds--verbose:
1626 file_adds--verbose:
1627 file_adds--verbose: d
1627 file_adds--verbose: d
1628 file_adds--verbose:
1628 file_adds--verbose:
1629 file_adds--verbose:
1629 file_adds--verbose:
1630 file_adds--verbose: c
1630 file_adds--verbose: c
1631 file_adds--verbose: b
1631 file_adds--verbose: b
1632 file_adds--verbose: a
1632 file_adds--verbose: a
1633 file_adds--debug: fourth third
1633 file_adds--debug: fourth third
1634 file_adds--debug: second
1634 file_adds--debug: second
1635 file_adds--debug:
1635 file_adds--debug:
1636 file_adds--debug: d
1636 file_adds--debug: d
1637 file_adds--debug:
1637 file_adds--debug:
1638 file_adds--debug:
1638 file_adds--debug:
1639 file_adds--debug: c
1639 file_adds--debug: c
1640 file_adds--debug: b
1640 file_adds--debug: b
1641 file_adds--debug: a
1641 file_adds--debug: a
1642 file_dels: second
1642 file_dels: second
1643 file_dels:
1643 file_dels:
1644 file_dels:
1644 file_dels:
1645 file_dels:
1645 file_dels:
1646 file_dels:
1646 file_dels:
1647 file_dels:
1647 file_dels:
1648 file_dels:
1648 file_dels:
1649 file_dels:
1649 file_dels:
1650 file_dels:
1650 file_dels:
1651 file_dels--verbose: second
1651 file_dels--verbose: second
1652 file_dels--verbose:
1652 file_dels--verbose:
1653 file_dels--verbose:
1653 file_dels--verbose:
1654 file_dels--verbose:
1654 file_dels--verbose:
1655 file_dels--verbose:
1655 file_dels--verbose:
1656 file_dels--verbose:
1656 file_dels--verbose:
1657 file_dels--verbose:
1657 file_dels--verbose:
1658 file_dels--verbose:
1658 file_dels--verbose:
1659 file_dels--verbose:
1659 file_dels--verbose:
1660 file_dels--debug: second
1660 file_dels--debug: second
1661 file_dels--debug:
1661 file_dels--debug:
1662 file_dels--debug:
1662 file_dels--debug:
1663 file_dels--debug:
1663 file_dels--debug:
1664 file_dels--debug:
1664 file_dels--debug:
1665 file_dels--debug:
1665 file_dels--debug:
1666 file_dels--debug:
1666 file_dels--debug:
1667 file_dels--debug:
1667 file_dels--debug:
1668 file_dels--debug:
1668 file_dels--debug:
1669 file_mods:
1669 file_mods:
1670 file_mods:
1670 file_mods:
1671 file_mods:
1671 file_mods:
1672 file_mods:
1672 file_mods:
1673 file_mods:
1673 file_mods:
1674 file_mods: c
1674 file_mods: c
1675 file_mods:
1675 file_mods:
1676 file_mods:
1676 file_mods:
1677 file_mods:
1677 file_mods:
1678 file_mods--verbose:
1678 file_mods--verbose:
1679 file_mods--verbose:
1679 file_mods--verbose:
1680 file_mods--verbose:
1680 file_mods--verbose:
1681 file_mods--verbose:
1681 file_mods--verbose:
1682 file_mods--verbose:
1682 file_mods--verbose:
1683 file_mods--verbose: c
1683 file_mods--verbose: c
1684 file_mods--verbose:
1684 file_mods--verbose:
1685 file_mods--verbose:
1685 file_mods--verbose:
1686 file_mods--verbose:
1686 file_mods--verbose:
1687 file_mods--debug:
1687 file_mods--debug:
1688 file_mods--debug:
1688 file_mods--debug:
1689 file_mods--debug:
1689 file_mods--debug:
1690 file_mods--debug:
1690 file_mods--debug:
1691 file_mods--debug:
1691 file_mods--debug:
1692 file_mods--debug: c
1692 file_mods--debug: c
1693 file_mods--debug:
1693 file_mods--debug:
1694 file_mods--debug:
1694 file_mods--debug:
1695 file_mods--debug:
1695 file_mods--debug:
1696 file_copies: fourth (second)
1696 file_copies: fourth (second)
1697 file_copies:
1697 file_copies:
1698 file_copies:
1698 file_copies:
1699 file_copies:
1699 file_copies:
1700 file_copies:
1700 file_copies:
1701 file_copies:
1701 file_copies:
1702 file_copies:
1702 file_copies:
1703 file_copies:
1703 file_copies:
1704 file_copies:
1704 file_copies:
1705 file_copies--verbose: fourth (second)
1705 file_copies--verbose: fourth (second)
1706 file_copies--verbose:
1706 file_copies--verbose:
1707 file_copies--verbose:
1707 file_copies--verbose:
1708 file_copies--verbose:
1708 file_copies--verbose:
1709 file_copies--verbose:
1709 file_copies--verbose:
1710 file_copies--verbose:
1710 file_copies--verbose:
1711 file_copies--verbose:
1711 file_copies--verbose:
1712 file_copies--verbose:
1712 file_copies--verbose:
1713 file_copies--verbose:
1713 file_copies--verbose:
1714 file_copies--debug: fourth (second)
1714 file_copies--debug: fourth (second)
1715 file_copies--debug:
1715 file_copies--debug:
1716 file_copies--debug:
1716 file_copies--debug:
1717 file_copies--debug:
1717 file_copies--debug:
1718 file_copies--debug:
1718 file_copies--debug:
1719 file_copies--debug:
1719 file_copies--debug:
1720 file_copies--debug:
1720 file_copies--debug:
1721 file_copies--debug:
1721 file_copies--debug:
1722 file_copies--debug:
1722 file_copies--debug:
1723 file_copies_switch:
1723 file_copies_switch:
1724 file_copies_switch:
1724 file_copies_switch:
1725 file_copies_switch:
1725 file_copies_switch:
1726 file_copies_switch:
1726 file_copies_switch:
1727 file_copies_switch:
1727 file_copies_switch:
1728 file_copies_switch:
1728 file_copies_switch:
1729 file_copies_switch:
1729 file_copies_switch:
1730 file_copies_switch:
1730 file_copies_switch:
1731 file_copies_switch:
1731 file_copies_switch:
1732 file_copies_switch--verbose:
1732 file_copies_switch--verbose:
1733 file_copies_switch--verbose:
1733 file_copies_switch--verbose:
1734 file_copies_switch--verbose:
1734 file_copies_switch--verbose:
1735 file_copies_switch--verbose:
1735 file_copies_switch--verbose:
1736 file_copies_switch--verbose:
1736 file_copies_switch--verbose:
1737 file_copies_switch--verbose:
1737 file_copies_switch--verbose:
1738 file_copies_switch--verbose:
1738 file_copies_switch--verbose:
1739 file_copies_switch--verbose:
1739 file_copies_switch--verbose:
1740 file_copies_switch--verbose:
1740 file_copies_switch--verbose:
1741 file_copies_switch--debug:
1741 file_copies_switch--debug:
1742 file_copies_switch--debug:
1742 file_copies_switch--debug:
1743 file_copies_switch--debug:
1743 file_copies_switch--debug:
1744 file_copies_switch--debug:
1744 file_copies_switch--debug:
1745 file_copies_switch--debug:
1745 file_copies_switch--debug:
1746 file_copies_switch--debug:
1746 file_copies_switch--debug:
1747 file_copies_switch--debug:
1747 file_copies_switch--debug:
1748 file_copies_switch--debug:
1748 file_copies_switch--debug:
1749 file_copies_switch--debug:
1749 file_copies_switch--debug:
1750 files: fourth second third
1750 files: fourth second third
1751 files: second
1751 files: second
1752 files:
1752 files:
1753 files: d
1753 files: d
1754 files:
1754 files:
1755 files: c
1755 files: c
1756 files: c
1756 files: c
1757 files: b
1757 files: b
1758 files: a
1758 files: a
1759 files--verbose: fourth second third
1759 files--verbose: fourth second third
1760 files--verbose: second
1760 files--verbose: second
1761 files--verbose:
1761 files--verbose:
1762 files--verbose: d
1762 files--verbose: d
1763 files--verbose:
1763 files--verbose:
1764 files--verbose: c
1764 files--verbose: c
1765 files--verbose: c
1765 files--verbose: c
1766 files--verbose: b
1766 files--verbose: b
1767 files--verbose: a
1767 files--verbose: a
1768 files--debug: fourth second third
1768 files--debug: fourth second third
1769 files--debug: second
1769 files--debug: second
1770 files--debug:
1770 files--debug:
1771 files--debug: d
1771 files--debug: d
1772 files--debug:
1772 files--debug:
1773 files--debug: c
1773 files--debug: c
1774 files--debug: c
1774 files--debug: c
1775 files--debug: b
1775 files--debug: b
1776 files--debug: a
1776 files--debug: a
1777 manifest: 6:94961b75a2da
1777 manifest: 6:94961b75a2da
1778 manifest: 5:f2dbc354b94e
1778 manifest: 5:f2dbc354b94e
1779 manifest: 4:4dc3def4f9b4
1779 manifest: 4:4dc3def4f9b4
1780 manifest: 4:4dc3def4f9b4
1780 manifest: 4:4dc3def4f9b4
1781 manifest: 3:cb5a1327723b
1781 manifest: 3:cb5a1327723b
1782 manifest: 3:cb5a1327723b
1782 manifest: 3:cb5a1327723b
1783 manifest: 2:6e0e82995c35
1783 manifest: 2:6e0e82995c35
1784 manifest: 1:4e8d705b1e53
1784 manifest: 1:4e8d705b1e53
1785 manifest: 0:a0c8bcbbb45c
1785 manifest: 0:a0c8bcbbb45c
1786 manifest--verbose: 6:94961b75a2da
1786 manifest--verbose: 6:94961b75a2da
1787 manifest--verbose: 5:f2dbc354b94e
1787 manifest--verbose: 5:f2dbc354b94e
1788 manifest--verbose: 4:4dc3def4f9b4
1788 manifest--verbose: 4:4dc3def4f9b4
1789 manifest--verbose: 4:4dc3def4f9b4
1789 manifest--verbose: 4:4dc3def4f9b4
1790 manifest--verbose: 3:cb5a1327723b
1790 manifest--verbose: 3:cb5a1327723b
1791 manifest--verbose: 3:cb5a1327723b
1791 manifest--verbose: 3:cb5a1327723b
1792 manifest--verbose: 2:6e0e82995c35
1792 manifest--verbose: 2:6e0e82995c35
1793 manifest--verbose: 1:4e8d705b1e53
1793 manifest--verbose: 1:4e8d705b1e53
1794 manifest--verbose: 0:a0c8bcbbb45c
1794 manifest--verbose: 0:a0c8bcbbb45c
1795 manifest--debug: 6:94961b75a2da554b4df6fb599e5bfc7d48de0c64
1795 manifest--debug: 6:94961b75a2da554b4df6fb599e5bfc7d48de0c64
1796 manifest--debug: 5:f2dbc354b94e5ec0b4f10680ee0cee816101d0bf
1796 manifest--debug: 5:f2dbc354b94e5ec0b4f10680ee0cee816101d0bf
1797 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
1797 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
1798 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
1798 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
1799 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
1799 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
1800 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
1800 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
1801 manifest--debug: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
1801 manifest--debug: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
1802 manifest--debug: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
1802 manifest--debug: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
1803 manifest--debug: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
1803 manifest--debug: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
1804 node: 95c24699272ef57d062b8bccc32c878bf841784a
1804 node: 95c24699272ef57d062b8bccc32c878bf841784a
1805 node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1805 node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1806 node: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1806 node: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1807 node: 13207e5a10d9fd28ec424934298e176197f2c67f
1807 node: 13207e5a10d9fd28ec424934298e176197f2c67f
1808 node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1808 node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1809 node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1809 node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1810 node: 97054abb4ab824450e9164180baf491ae0078465
1810 node: 97054abb4ab824450e9164180baf491ae0078465
1811 node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1811 node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1812 node: 1e4e1b8f71e05681d422154f5421e385fec3454f
1812 node: 1e4e1b8f71e05681d422154f5421e385fec3454f
1813 node--verbose: 95c24699272ef57d062b8bccc32c878bf841784a
1813 node--verbose: 95c24699272ef57d062b8bccc32c878bf841784a
1814 node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1814 node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1815 node--verbose: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1815 node--verbose: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1816 node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
1816 node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
1817 node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1817 node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1818 node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1818 node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1819 node--verbose: 97054abb4ab824450e9164180baf491ae0078465
1819 node--verbose: 97054abb4ab824450e9164180baf491ae0078465
1820 node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1820 node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1821 node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
1821 node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
1822 node--debug: 95c24699272ef57d062b8bccc32c878bf841784a
1822 node--debug: 95c24699272ef57d062b8bccc32c878bf841784a
1823 node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1823 node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1824 node--debug: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1824 node--debug: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1825 node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
1825 node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
1826 node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1826 node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1827 node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1827 node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1828 node--debug: 97054abb4ab824450e9164180baf491ae0078465
1828 node--debug: 97054abb4ab824450e9164180baf491ae0078465
1829 node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1829 node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1830 node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
1830 node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
1831 parents:
1831 parents:
1832 parents: -1:000000000000
1832 parents: -1:000000000000
1833 parents: 5:13207e5a10d9 4:bbe44766e73d
1833 parents: 5:13207e5a10d9 4:bbe44766e73d
1834 parents: 3:10e46f2dcbf4
1834 parents: 3:10e46f2dcbf4
1835 parents:
1835 parents:
1836 parents:
1836 parents:
1837 parents:
1837 parents:
1838 parents:
1838 parents:
1839 parents:
1839 parents:
1840 parents--verbose:
1840 parents--verbose:
1841 parents--verbose: -1:000000000000
1841 parents--verbose: -1:000000000000
1842 parents--verbose: 5:13207e5a10d9 4:bbe44766e73d
1842 parents--verbose: 5:13207e5a10d9 4:bbe44766e73d
1843 parents--verbose: 3:10e46f2dcbf4
1843 parents--verbose: 3:10e46f2dcbf4
1844 parents--verbose:
1844 parents--verbose:
1845 parents--verbose:
1845 parents--verbose:
1846 parents--verbose:
1846 parents--verbose:
1847 parents--verbose:
1847 parents--verbose:
1848 parents--verbose:
1848 parents--verbose:
1849 parents--debug: 7:29114dbae42b9f078cf2714dbe3a86bba8ec7453 -1:0000000000000000000000000000000000000000
1849 parents--debug: 7:29114dbae42b9f078cf2714dbe3a86bba8ec7453 -1:0000000000000000000000000000000000000000
1850 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
1850 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
1851 parents--debug: 5:13207e5a10d9fd28ec424934298e176197f2c67f 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
1851 parents--debug: 5:13207e5a10d9fd28ec424934298e176197f2c67f 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
1852 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
1852 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
1853 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
1853 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
1854 parents--debug: 2:97054abb4ab824450e9164180baf491ae0078465 -1:0000000000000000000000000000000000000000
1854 parents--debug: 2:97054abb4ab824450e9164180baf491ae0078465 -1:0000000000000000000000000000000000000000
1855 parents--debug: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965 -1:0000000000000000000000000000000000000000
1855 parents--debug: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965 -1:0000000000000000000000000000000000000000
1856 parents--debug: 0:1e4e1b8f71e05681d422154f5421e385fec3454f -1:0000000000000000000000000000000000000000
1856 parents--debug: 0:1e4e1b8f71e05681d422154f5421e385fec3454f -1:0000000000000000000000000000000000000000
1857 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
1857 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
1858 rev: 8
1858 rev: 8
1859 rev: 7
1859 rev: 7
1860 rev: 6
1860 rev: 6
1861 rev: 5
1861 rev: 5
1862 rev: 4
1862 rev: 4
1863 rev: 3
1863 rev: 3
1864 rev: 2
1864 rev: 2
1865 rev: 1
1865 rev: 1
1866 rev: 0
1866 rev: 0
1867 rev--verbose: 8
1867 rev--verbose: 8
1868 rev--verbose: 7
1868 rev--verbose: 7
1869 rev--verbose: 6
1869 rev--verbose: 6
1870 rev--verbose: 5
1870 rev--verbose: 5
1871 rev--verbose: 4
1871 rev--verbose: 4
1872 rev--verbose: 3
1872 rev--verbose: 3
1873 rev--verbose: 2
1873 rev--verbose: 2
1874 rev--verbose: 1
1874 rev--verbose: 1
1875 rev--verbose: 0
1875 rev--verbose: 0
1876 rev--debug: 8
1876 rev--debug: 8
1877 rev--debug: 7
1877 rev--debug: 7
1878 rev--debug: 6
1878 rev--debug: 6
1879 rev--debug: 5
1879 rev--debug: 5
1880 rev--debug: 4
1880 rev--debug: 4
1881 rev--debug: 3
1881 rev--debug: 3
1882 rev--debug: 2
1882 rev--debug: 2
1883 rev--debug: 1
1883 rev--debug: 1
1884 rev--debug: 0
1884 rev--debug: 0
1885 tags: tip
1885 tags: tip
1886 tags:
1886 tags:
1887 tags:
1887 tags:
1888 tags:
1888 tags:
1889 tags:
1889 tags:
1890 tags:
1890 tags:
1891 tags:
1891 tags:
1892 tags:
1892 tags:
1893 tags:
1893 tags:
1894 tags--verbose: tip
1894 tags--verbose: tip
1895 tags--verbose:
1895 tags--verbose:
1896 tags--verbose:
1896 tags--verbose:
1897 tags--verbose:
1897 tags--verbose:
1898 tags--verbose:
1898 tags--verbose:
1899 tags--verbose:
1899 tags--verbose:
1900 tags--verbose:
1900 tags--verbose:
1901 tags--verbose:
1901 tags--verbose:
1902 tags--verbose:
1902 tags--verbose:
1903 tags--debug: tip
1903 tags--debug: tip
1904 tags--debug:
1904 tags--debug:
1905 tags--debug:
1905 tags--debug:
1906 tags--debug:
1906 tags--debug:
1907 tags--debug:
1907 tags--debug:
1908 tags--debug:
1908 tags--debug:
1909 tags--debug:
1909 tags--debug:
1910 tags--debug:
1910 tags--debug:
1911 tags--debug:
1911 tags--debug:
1912 diffstat: 3: +2/-1
1912 diffstat: 3: +2/-1
1913 diffstat: 1: +1/-0
1913 diffstat: 1: +1/-0
1914 diffstat: 0: +0/-0
1914 diffstat: 0: +0/-0
1915 diffstat: 1: +1/-0
1915 diffstat: 1: +1/-0
1916 diffstat: 0: +0/-0
1916 diffstat: 0: +0/-0
1917 diffstat: 1: +1/-0
1917 diffstat: 1: +1/-0
1918 diffstat: 1: +4/-0
1918 diffstat: 1: +4/-0
1919 diffstat: 1: +2/-0
1919 diffstat: 1: +2/-0
1920 diffstat: 1: +1/-0
1920 diffstat: 1: +1/-0
1921 diffstat--verbose: 3: +2/-1
1921 diffstat--verbose: 3: +2/-1
1922 diffstat--verbose: 1: +1/-0
1922 diffstat--verbose: 1: +1/-0
1923 diffstat--verbose: 0: +0/-0
1923 diffstat--verbose: 0: +0/-0
1924 diffstat--verbose: 1: +1/-0
1924 diffstat--verbose: 1: +1/-0
1925 diffstat--verbose: 0: +0/-0
1925 diffstat--verbose: 0: +0/-0
1926 diffstat--verbose: 1: +1/-0
1926 diffstat--verbose: 1: +1/-0
1927 diffstat--verbose: 1: +4/-0
1927 diffstat--verbose: 1: +4/-0
1928 diffstat--verbose: 1: +2/-0
1928 diffstat--verbose: 1: +2/-0
1929 diffstat--verbose: 1: +1/-0
1929 diffstat--verbose: 1: +1/-0
1930 diffstat--debug: 3: +2/-1
1930 diffstat--debug: 3: +2/-1
1931 diffstat--debug: 1: +1/-0
1931 diffstat--debug: 1: +1/-0
1932 diffstat--debug: 0: +0/-0
1932 diffstat--debug: 0: +0/-0
1933 diffstat--debug: 1: +1/-0
1933 diffstat--debug: 1: +1/-0
1934 diffstat--debug: 0: +0/-0
1934 diffstat--debug: 0: +0/-0
1935 diffstat--debug: 1: +1/-0
1935 diffstat--debug: 1: +1/-0
1936 diffstat--debug: 1: +4/-0
1936 diffstat--debug: 1: +4/-0
1937 diffstat--debug: 1: +2/-0
1937 diffstat--debug: 1: +2/-0
1938 diffstat--debug: 1: +1/-0
1938 diffstat--debug: 1: +1/-0
1939 extras: branch=default
1939 extras: branch=default
1940 extras: branch=default
1940 extras: branch=default
1941 extras: branch=default
1941 extras: branch=default
1942 extras: branch=default
1942 extras: branch=default
1943 extras: branch=foo
1943 extras: branch=foo
1944 extras: branch=default
1944 extras: branch=default
1945 extras: branch=default
1945 extras: branch=default
1946 extras: branch=default
1946 extras: branch=default
1947 extras: branch=default
1947 extras: branch=default
1948 extras--verbose: branch=default
1948 extras--verbose: branch=default
1949 extras--verbose: branch=default
1949 extras--verbose: branch=default
1950 extras--verbose: branch=default
1950 extras--verbose: branch=default
1951 extras--verbose: branch=default
1951 extras--verbose: branch=default
1952 extras--verbose: branch=foo
1952 extras--verbose: branch=foo
1953 extras--verbose: branch=default
1953 extras--verbose: branch=default
1954 extras--verbose: branch=default
1954 extras--verbose: branch=default
1955 extras--verbose: branch=default
1955 extras--verbose: branch=default
1956 extras--verbose: branch=default
1956 extras--verbose: branch=default
1957 extras--debug: branch=default
1957 extras--debug: branch=default
1958 extras--debug: branch=default
1958 extras--debug: branch=default
1959 extras--debug: branch=default
1959 extras--debug: branch=default
1960 extras--debug: branch=default
1960 extras--debug: branch=default
1961 extras--debug: branch=foo
1961 extras--debug: branch=foo
1962 extras--debug: branch=default
1962 extras--debug: branch=default
1963 extras--debug: branch=default
1963 extras--debug: branch=default
1964 extras--debug: branch=default
1964 extras--debug: branch=default
1965 extras--debug: branch=default
1965 extras--debug: branch=default
1966 p1rev: 7
1966 p1rev: 7
1967 p1rev: -1
1967 p1rev: -1
1968 p1rev: 5
1968 p1rev: 5
1969 p1rev: 3
1969 p1rev: 3
1970 p1rev: 3
1970 p1rev: 3
1971 p1rev: 2
1971 p1rev: 2
1972 p1rev: 1
1972 p1rev: 1
1973 p1rev: 0
1973 p1rev: 0
1974 p1rev: -1
1974 p1rev: -1
1975 p1rev--verbose: 7
1975 p1rev--verbose: 7
1976 p1rev--verbose: -1
1976 p1rev--verbose: -1
1977 p1rev--verbose: 5
1977 p1rev--verbose: 5
1978 p1rev--verbose: 3
1978 p1rev--verbose: 3
1979 p1rev--verbose: 3
1979 p1rev--verbose: 3
1980 p1rev--verbose: 2
1980 p1rev--verbose: 2
1981 p1rev--verbose: 1
1981 p1rev--verbose: 1
1982 p1rev--verbose: 0
1982 p1rev--verbose: 0
1983 p1rev--verbose: -1
1983 p1rev--verbose: -1
1984 p1rev--debug: 7
1984 p1rev--debug: 7
1985 p1rev--debug: -1
1985 p1rev--debug: -1
1986 p1rev--debug: 5
1986 p1rev--debug: 5
1987 p1rev--debug: 3
1987 p1rev--debug: 3
1988 p1rev--debug: 3
1988 p1rev--debug: 3
1989 p1rev--debug: 2
1989 p1rev--debug: 2
1990 p1rev--debug: 1
1990 p1rev--debug: 1
1991 p1rev--debug: 0
1991 p1rev--debug: 0
1992 p1rev--debug: -1
1992 p1rev--debug: -1
1993 p2rev: -1
1993 p2rev: -1
1994 p2rev: -1
1994 p2rev: -1
1995 p2rev: 4
1995 p2rev: 4
1996 p2rev: -1
1996 p2rev: -1
1997 p2rev: -1
1997 p2rev: -1
1998 p2rev: -1
1998 p2rev: -1
1999 p2rev: -1
1999 p2rev: -1
2000 p2rev: -1
2000 p2rev: -1
2001 p2rev: -1
2001 p2rev: -1
2002 p2rev--verbose: -1
2002 p2rev--verbose: -1
2003 p2rev--verbose: -1
2003 p2rev--verbose: -1
2004 p2rev--verbose: 4
2004 p2rev--verbose: 4
2005 p2rev--verbose: -1
2005 p2rev--verbose: -1
2006 p2rev--verbose: -1
2006 p2rev--verbose: -1
2007 p2rev--verbose: -1
2007 p2rev--verbose: -1
2008 p2rev--verbose: -1
2008 p2rev--verbose: -1
2009 p2rev--verbose: -1
2009 p2rev--verbose: -1
2010 p2rev--verbose: -1
2010 p2rev--verbose: -1
2011 p2rev--debug: -1
2011 p2rev--debug: -1
2012 p2rev--debug: -1
2012 p2rev--debug: -1
2013 p2rev--debug: 4
2013 p2rev--debug: 4
2014 p2rev--debug: -1
2014 p2rev--debug: -1
2015 p2rev--debug: -1
2015 p2rev--debug: -1
2016 p2rev--debug: -1
2016 p2rev--debug: -1
2017 p2rev--debug: -1
2017 p2rev--debug: -1
2018 p2rev--debug: -1
2018 p2rev--debug: -1
2019 p2rev--debug: -1
2019 p2rev--debug: -1
2020 p1node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
2020 p1node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
2021 p1node: 0000000000000000000000000000000000000000
2021 p1node: 0000000000000000000000000000000000000000
2022 p1node: 13207e5a10d9fd28ec424934298e176197f2c67f
2022 p1node: 13207e5a10d9fd28ec424934298e176197f2c67f
2023 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
2023 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
2024 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
2024 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
2025 p1node: 97054abb4ab824450e9164180baf491ae0078465
2025 p1node: 97054abb4ab824450e9164180baf491ae0078465
2026 p1node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2026 p1node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2027 p1node: 1e4e1b8f71e05681d422154f5421e385fec3454f
2027 p1node: 1e4e1b8f71e05681d422154f5421e385fec3454f
2028 p1node: 0000000000000000000000000000000000000000
2028 p1node: 0000000000000000000000000000000000000000
2029 p1node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
2029 p1node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
2030 p1node--verbose: 0000000000000000000000000000000000000000
2030 p1node--verbose: 0000000000000000000000000000000000000000
2031 p1node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
2031 p1node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
2032 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
2032 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
2033 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
2033 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
2034 p1node--verbose: 97054abb4ab824450e9164180baf491ae0078465
2034 p1node--verbose: 97054abb4ab824450e9164180baf491ae0078465
2035 p1node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2035 p1node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2036 p1node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
2036 p1node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
2037 p1node--verbose: 0000000000000000000000000000000000000000
2037 p1node--verbose: 0000000000000000000000000000000000000000
2038 p1node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
2038 p1node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
2039 p1node--debug: 0000000000000000000000000000000000000000
2039 p1node--debug: 0000000000000000000000000000000000000000
2040 p1node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
2040 p1node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
2041 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
2041 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
2042 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
2042 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
2043 p1node--debug: 97054abb4ab824450e9164180baf491ae0078465
2043 p1node--debug: 97054abb4ab824450e9164180baf491ae0078465
2044 p1node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2044 p1node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2045 p1node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
2045 p1node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
2046 p1node--debug: 0000000000000000000000000000000000000000
2046 p1node--debug: 0000000000000000000000000000000000000000
2047 p2node: 0000000000000000000000000000000000000000
2047 p2node: 0000000000000000000000000000000000000000
2048 p2node: 0000000000000000000000000000000000000000
2048 p2node: 0000000000000000000000000000000000000000
2049 p2node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
2049 p2node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
2050 p2node: 0000000000000000000000000000000000000000
2050 p2node: 0000000000000000000000000000000000000000
2051 p2node: 0000000000000000000000000000000000000000
2051 p2node: 0000000000000000000000000000000000000000
2052 p2node: 0000000000000000000000000000000000000000
2052 p2node: 0000000000000000000000000000000000000000
2053 p2node: 0000000000000000000000000000000000000000
2053 p2node: 0000000000000000000000000000000000000000
2054 p2node: 0000000000000000000000000000000000000000
2054 p2node: 0000000000000000000000000000000000000000
2055 p2node: 0000000000000000000000000000000000000000
2055 p2node: 0000000000000000000000000000000000000000
2056 p2node--verbose: 0000000000000000000000000000000000000000
2056 p2node--verbose: 0000000000000000000000000000000000000000
2057 p2node--verbose: 0000000000000000000000000000000000000000
2057 p2node--verbose: 0000000000000000000000000000000000000000
2058 p2node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
2058 p2node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
2059 p2node--verbose: 0000000000000000000000000000000000000000
2059 p2node--verbose: 0000000000000000000000000000000000000000
2060 p2node--verbose: 0000000000000000000000000000000000000000
2060 p2node--verbose: 0000000000000000000000000000000000000000
2061 p2node--verbose: 0000000000000000000000000000000000000000
2061 p2node--verbose: 0000000000000000000000000000000000000000
2062 p2node--verbose: 0000000000000000000000000000000000000000
2062 p2node--verbose: 0000000000000000000000000000000000000000
2063 p2node--verbose: 0000000000000000000000000000000000000000
2063 p2node--verbose: 0000000000000000000000000000000000000000
2064 p2node--verbose: 0000000000000000000000000000000000000000
2064 p2node--verbose: 0000000000000000000000000000000000000000
2065 p2node--debug: 0000000000000000000000000000000000000000
2065 p2node--debug: 0000000000000000000000000000000000000000
2066 p2node--debug: 0000000000000000000000000000000000000000
2066 p2node--debug: 0000000000000000000000000000000000000000
2067 p2node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
2067 p2node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
2068 p2node--debug: 0000000000000000000000000000000000000000
2068 p2node--debug: 0000000000000000000000000000000000000000
2069 p2node--debug: 0000000000000000000000000000000000000000
2069 p2node--debug: 0000000000000000000000000000000000000000
2070 p2node--debug: 0000000000000000000000000000000000000000
2070 p2node--debug: 0000000000000000000000000000000000000000
2071 p2node--debug: 0000000000000000000000000000000000000000
2071 p2node--debug: 0000000000000000000000000000000000000000
2072 p2node--debug: 0000000000000000000000000000000000000000
2072 p2node--debug: 0000000000000000000000000000000000000000
2073 p2node--debug: 0000000000000000000000000000000000000000
2073 p2node--debug: 0000000000000000000000000000000000000000
2074
2074
2075 Filters work:
2075 Filters work:
2076
2076
2077 $ hg log --template '{author|domain}\n'
2077 $ hg log --template '{author|domain}\n'
2078
2078
2079 hostname
2079 hostname
2080
2080
2081
2081
2082
2082
2083
2083
2084 place
2084 place
2085 place
2085 place
2086 hostname
2086 hostname
2087
2087
2088 $ hg log --template '{author|person}\n'
2088 $ hg log --template '{author|person}\n'
2089 test
2089 test
2090 User Name
2090 User Name
2091 person
2091 person
2092 person
2092 person
2093 person
2093 person
2094 person
2094 person
2095 other
2095 other
2096 A. N. Other
2096 A. N. Other
2097 User Name
2097 User Name
2098
2098
2099 $ hg log --template '{author|user}\n'
2099 $ hg log --template '{author|user}\n'
2100 test
2100 test
2101 user
2101 user
2102 person
2102 person
2103 person
2103 person
2104 person
2104 person
2105 person
2105 person
2106 other
2106 other
2107 other
2107 other
2108 user
2108 user
2109
2109
2110 $ hg log --template '{date|date}\n'
2110 $ hg log --template '{date|date}\n'
2111 Wed Jan 01 10:01:00 2020 +0000
2111 Wed Jan 01 10:01:00 2020 +0000
2112 Mon Jan 12 13:46:40 1970 +0000
2112 Mon Jan 12 13:46:40 1970 +0000
2113 Sun Jan 18 08:40:01 1970 +0000
2113 Sun Jan 18 08:40:01 1970 +0000
2114 Sun Jan 18 08:40:00 1970 +0000
2114 Sun Jan 18 08:40:00 1970 +0000
2115 Sat Jan 17 04:53:20 1970 +0000
2115 Sat Jan 17 04:53:20 1970 +0000
2116 Fri Jan 16 01:06:40 1970 +0000
2116 Fri Jan 16 01:06:40 1970 +0000
2117 Wed Jan 14 21:20:00 1970 +0000
2117 Wed Jan 14 21:20:00 1970 +0000
2118 Tue Jan 13 17:33:20 1970 +0000
2118 Tue Jan 13 17:33:20 1970 +0000
2119 Mon Jan 12 13:46:40 1970 +0000
2119 Mon Jan 12 13:46:40 1970 +0000
2120
2120
2121 $ hg log --template '{date|isodate}\n'
2121 $ hg log --template '{date|isodate}\n'
2122 2020-01-01 10:01 +0000
2122 2020-01-01 10:01 +0000
2123 1970-01-12 13:46 +0000
2123 1970-01-12 13:46 +0000
2124 1970-01-18 08:40 +0000
2124 1970-01-18 08:40 +0000
2125 1970-01-18 08:40 +0000
2125 1970-01-18 08:40 +0000
2126 1970-01-17 04:53 +0000
2126 1970-01-17 04:53 +0000
2127 1970-01-16 01:06 +0000
2127 1970-01-16 01:06 +0000
2128 1970-01-14 21:20 +0000
2128 1970-01-14 21:20 +0000
2129 1970-01-13 17:33 +0000
2129 1970-01-13 17:33 +0000
2130 1970-01-12 13:46 +0000
2130 1970-01-12 13:46 +0000
2131
2131
2132 $ hg log --template '{date|isodatesec}\n'
2132 $ hg log --template '{date|isodatesec}\n'
2133 2020-01-01 10:01:00 +0000
2133 2020-01-01 10:01:00 +0000
2134 1970-01-12 13:46:40 +0000
2134 1970-01-12 13:46:40 +0000
2135 1970-01-18 08:40:01 +0000
2135 1970-01-18 08:40:01 +0000
2136 1970-01-18 08:40:00 +0000
2136 1970-01-18 08:40:00 +0000
2137 1970-01-17 04:53:20 +0000
2137 1970-01-17 04:53:20 +0000
2138 1970-01-16 01:06:40 +0000
2138 1970-01-16 01:06:40 +0000
2139 1970-01-14 21:20:00 +0000
2139 1970-01-14 21:20:00 +0000
2140 1970-01-13 17:33:20 +0000
2140 1970-01-13 17:33:20 +0000
2141 1970-01-12 13:46:40 +0000
2141 1970-01-12 13:46:40 +0000
2142
2142
2143 $ hg log --template '{date|rfc822date}\n'
2143 $ hg log --template '{date|rfc822date}\n'
2144 Wed, 01 Jan 2020 10:01:00 +0000
2144 Wed, 01 Jan 2020 10:01:00 +0000
2145 Mon, 12 Jan 1970 13:46:40 +0000
2145 Mon, 12 Jan 1970 13:46:40 +0000
2146 Sun, 18 Jan 1970 08:40:01 +0000
2146 Sun, 18 Jan 1970 08:40:01 +0000
2147 Sun, 18 Jan 1970 08:40:00 +0000
2147 Sun, 18 Jan 1970 08:40:00 +0000
2148 Sat, 17 Jan 1970 04:53:20 +0000
2148 Sat, 17 Jan 1970 04:53:20 +0000
2149 Fri, 16 Jan 1970 01:06:40 +0000
2149 Fri, 16 Jan 1970 01:06:40 +0000
2150 Wed, 14 Jan 1970 21:20:00 +0000
2150 Wed, 14 Jan 1970 21:20:00 +0000
2151 Tue, 13 Jan 1970 17:33:20 +0000
2151 Tue, 13 Jan 1970 17:33:20 +0000
2152 Mon, 12 Jan 1970 13:46:40 +0000
2152 Mon, 12 Jan 1970 13:46:40 +0000
2153
2153
2154 $ hg log --template '{desc|firstline}\n'
2154 $ hg log --template '{desc|firstline}\n'
2155 third
2155 third
2156 second
2156 second
2157 merge
2157 merge
2158 new head
2158 new head
2159 new branch
2159 new branch
2160 no user, no domain
2160 no user, no domain
2161 no person
2161 no person
2162 other 1
2162 other 1
2163 line 1
2163 line 1
2164
2164
2165 $ hg log --template '{node|short}\n'
2165 $ hg log --template '{node|short}\n'
2166 95c24699272e
2166 95c24699272e
2167 29114dbae42b
2167 29114dbae42b
2168 d41e714fe50d
2168 d41e714fe50d
2169 13207e5a10d9
2169 13207e5a10d9
2170 bbe44766e73d
2170 bbe44766e73d
2171 10e46f2dcbf4
2171 10e46f2dcbf4
2172 97054abb4ab8
2172 97054abb4ab8
2173 b608e9d1a3f0
2173 b608e9d1a3f0
2174 1e4e1b8f71e0
2174 1e4e1b8f71e0
2175
2175
2176 $ hg log --template '<changeset author="{author|xmlescape}"/>\n'
2176 $ hg log --template '<changeset author="{author|xmlescape}"/>\n'
2177 <changeset author="test"/>
2177 <changeset author="test"/>
2178 <changeset author="User Name &lt;user@hostname&gt;"/>
2178 <changeset author="User Name &lt;user@hostname&gt;"/>
2179 <changeset author="person"/>
2179 <changeset author="person"/>
2180 <changeset author="person"/>
2180 <changeset author="person"/>
2181 <changeset author="person"/>
2181 <changeset author="person"/>
2182 <changeset author="person"/>
2182 <changeset author="person"/>
2183 <changeset author="other@place"/>
2183 <changeset author="other@place"/>
2184 <changeset author="A. N. Other &lt;other@place&gt;"/>
2184 <changeset author="A. N. Other &lt;other@place&gt;"/>
2185 <changeset author="User Name &lt;user@hostname&gt;"/>
2185 <changeset author="User Name &lt;user@hostname&gt;"/>
2186
2186
2187 $ hg log --template '{rev}: {children}\n'
2187 $ hg log --template '{rev}: {children}\n'
2188 8:
2188 8:
2189 7: 8:95c24699272e
2189 7: 8:95c24699272e
2190 6:
2190 6:
2191 5: 6:d41e714fe50d
2191 5: 6:d41e714fe50d
2192 4: 6:d41e714fe50d
2192 4: 6:d41e714fe50d
2193 3: 4:bbe44766e73d 5:13207e5a10d9
2193 3: 4:bbe44766e73d 5:13207e5a10d9
2194 2: 3:10e46f2dcbf4
2194 2: 3:10e46f2dcbf4
2195 1: 2:97054abb4ab8
2195 1: 2:97054abb4ab8
2196 0: 1:b608e9d1a3f0
2196 0: 1:b608e9d1a3f0
2197
2197
2198 Formatnode filter works:
2198 Formatnode filter works:
2199
2199
2200 $ hg -q log -r 0 --template '{node|formatnode}\n'
2200 $ hg -q log -r 0 --template '{node|formatnode}\n'
2201 1e4e1b8f71e0
2201 1e4e1b8f71e0
2202
2202
2203 $ hg log -r 0 --template '{node|formatnode}\n'
2203 $ hg log -r 0 --template '{node|formatnode}\n'
2204 1e4e1b8f71e0
2204 1e4e1b8f71e0
2205
2205
2206 $ hg -v log -r 0 --template '{node|formatnode}\n'
2206 $ hg -v log -r 0 --template '{node|formatnode}\n'
2207 1e4e1b8f71e0
2207 1e4e1b8f71e0
2208
2208
2209 $ hg --debug log -r 0 --template '{node|formatnode}\n'
2209 $ hg --debug log -r 0 --template '{node|formatnode}\n'
2210 1e4e1b8f71e05681d422154f5421e385fec3454f
2210 1e4e1b8f71e05681d422154f5421e385fec3454f
2211
2211
2212 Age filter:
2212 Age filter:
2213
2213
2214 $ hg init unstable-hash
2214 $ hg init unstable-hash
2215 $ cd unstable-hash
2215 $ cd unstable-hash
2216 $ hg log --template '{date|age}\n' > /dev/null || exit 1
2216 $ hg log --template '{date|age}\n' > /dev/null || exit 1
2217
2217
2218 >>> from __future__ import absolute_import
2218 >>> from __future__ import absolute_import
2219 >>> import datetime
2219 >>> import datetime
2220 >>> fp = open('a', 'wb')
2220 >>> fp = open('a', 'wb')
2221 >>> n = datetime.datetime.now() + datetime.timedelta(366 * 7)
2221 >>> n = datetime.datetime.now() + datetime.timedelta(366 * 7)
2222 >>> fp.write(b'%d-%d-%d 00:00' % (n.year, n.month, n.day)) and None
2222 >>> fp.write(b'%d-%d-%d 00:00' % (n.year, n.month, n.day)) and None
2223 >>> fp.close()
2223 >>> fp.close()
2224 $ hg add a
2224 $ hg add a
2225 $ hg commit -m future -d "`cat a`"
2225 $ hg commit -m future -d "`cat a`"
2226
2226
2227 $ hg log -l1 --template '{date|age}\n'
2227 $ hg log -l1 --template '{date|age}\n'
2228 7 years from now
2228 7 years from now
2229
2229
2230 $ cd ..
2230 $ cd ..
2231 $ rm -rf unstable-hash
2231 $ rm -rf unstable-hash
2232
2232
2233 Filename filters:
2233 Filename filters:
2234
2234
2235 $ hg debugtemplate '{"foo/bar"|basename}|{"foo/"|basename}|{"foo"|basename}|\n'
2235 $ hg debugtemplate '{"foo/bar"|basename}|{"foo/"|basename}|{"foo"|basename}|\n'
2236 bar||foo|
2236 bar||foo|
2237 $ hg debugtemplate '{"foo/bar"|dirname}|{"foo/"|dirname}|{"foo"|dirname}|\n'
2237 $ hg debugtemplate '{"foo/bar"|dirname}|{"foo/"|dirname}|{"foo"|dirname}|\n'
2238 foo|foo||
2238 foo|foo||
2239 $ hg debugtemplate '{"foo/bar"|stripdir}|{"foo/"|stripdir}|{"foo"|stripdir}|\n'
2239 $ hg debugtemplate '{"foo/bar"|stripdir}|{"foo/"|stripdir}|{"foo"|stripdir}|\n'
2240 foo|foo|foo|
2240 foo|foo|foo|
2241
2241
2242 Add a dummy commit to make up for the instability of the above:
2242 Add a dummy commit to make up for the instability of the above:
2243
2243
2244 $ echo a > a
2244 $ echo a > a
2245 $ hg add a
2245 $ hg add a
2246 $ hg ci -m future
2246 $ hg ci -m future
2247
2247
2248 Count filter:
2248 Count filter:
2249
2249
2250 $ hg log -l1 --template '{node|count} {node|short|count}\n'
2250 $ hg log -l1 --template '{node|count} {node|short|count}\n'
2251 40 12
2251 40 12
2252
2252
2253 $ hg log -l1 --template '{revset("null^")|count} {revset(".")|count} {revset("0::3")|count}\n'
2253 $ hg log -l1 --template '{revset("null^")|count} {revset(".")|count} {revset("0::3")|count}\n'
2254 0 1 4
2254 0 1 4
2255
2255
2256 $ hg log -G --template '{rev}: children: {children|count}, \
2256 $ hg log -G --template '{rev}: children: {children|count}, \
2257 > tags: {tags|count}, file_adds: {file_adds|count}, \
2257 > tags: {tags|count}, file_adds: {file_adds|count}, \
2258 > ancestors: {revset("ancestors(%s)", rev)|count}'
2258 > ancestors: {revset("ancestors(%s)", rev)|count}'
2259 @ 9: children: 0, tags: 1, file_adds: 1, ancestors: 3
2259 @ 9: children: 0, tags: 1, file_adds: 1, ancestors: 3
2260 |
2260 |
2261 o 8: children: 1, tags: 0, file_adds: 2, ancestors: 2
2261 o 8: children: 1, tags: 0, file_adds: 2, ancestors: 2
2262 |
2262 |
2263 o 7: children: 1, tags: 0, file_adds: 1, ancestors: 1
2263 o 7: children: 1, tags: 0, file_adds: 1, ancestors: 1
2264
2264
2265 o 6: children: 0, tags: 0, file_adds: 0, ancestors: 7
2265 o 6: children: 0, tags: 0, file_adds: 0, ancestors: 7
2266 |\
2266 |\
2267 | o 5: children: 1, tags: 0, file_adds: 1, ancestors: 5
2267 | o 5: children: 1, tags: 0, file_adds: 1, ancestors: 5
2268 | |
2268 | |
2269 o | 4: children: 1, tags: 0, file_adds: 0, ancestors: 5
2269 o | 4: children: 1, tags: 0, file_adds: 0, ancestors: 5
2270 |/
2270 |/
2271 o 3: children: 2, tags: 0, file_adds: 0, ancestors: 4
2271 o 3: children: 2, tags: 0, file_adds: 0, ancestors: 4
2272 |
2272 |
2273 o 2: children: 1, tags: 0, file_adds: 1, ancestors: 3
2273 o 2: children: 1, tags: 0, file_adds: 1, ancestors: 3
2274 |
2274 |
2275 o 1: children: 1, tags: 0, file_adds: 1, ancestors: 2
2275 o 1: children: 1, tags: 0, file_adds: 1, ancestors: 2
2276 |
2276 |
2277 o 0: children: 1, tags: 0, file_adds: 1, ancestors: 1
2277 o 0: children: 1, tags: 0, file_adds: 1, ancestors: 1
2278
2278
2279
2279
2280 Upper/lower filters:
2280 Upper/lower filters:
2281
2281
2282 $ hg log -r0 --template '{branch|upper}\n'
2282 $ hg log -r0 --template '{branch|upper}\n'
2283 DEFAULT
2283 DEFAULT
2284 $ hg log -r0 --template '{author|lower}\n'
2284 $ hg log -r0 --template '{author|lower}\n'
2285 user name <user@hostname>
2285 user name <user@hostname>
2286 $ hg log -r0 --template '{date|upper}\n'
2286 $ hg log -r0 --template '{date|upper}\n'
2287 abort: template filter 'upper' is not compatible with keyword 'date'
2287 1000000.00
2288 [255]
2289
2288
2290 Add a commit that does all possible modifications at once
2289 Add a commit that does all possible modifications at once
2291
2290
2292 $ echo modify >> third
2291 $ echo modify >> third
2293 $ touch b
2292 $ touch b
2294 $ hg add b
2293 $ hg add b
2295 $ hg mv fourth fifth
2294 $ hg mv fourth fifth
2296 $ hg rm a
2295 $ hg rm a
2297 $ hg ci -m "Modify, add, remove, rename"
2296 $ hg ci -m "Modify, add, remove, rename"
2298
2297
2299 Check the status template
2298 Check the status template
2300
2299
2301 $ cat <<EOF >> $HGRCPATH
2300 $ cat <<EOF >> $HGRCPATH
2302 > [extensions]
2301 > [extensions]
2303 > color=
2302 > color=
2304 > EOF
2303 > EOF
2305
2304
2306 $ hg log -T status -r 10
2305 $ hg log -T status -r 10
2307 changeset: 10:0f9759ec227a
2306 changeset: 10:0f9759ec227a
2308 tag: tip
2307 tag: tip
2309 user: test
2308 user: test
2310 date: Thu Jan 01 00:00:00 1970 +0000
2309 date: Thu Jan 01 00:00:00 1970 +0000
2311 summary: Modify, add, remove, rename
2310 summary: Modify, add, remove, rename
2312 files:
2311 files:
2313 M third
2312 M third
2314 A b
2313 A b
2315 A fifth
2314 A fifth
2316 R a
2315 R a
2317 R fourth
2316 R fourth
2318
2317
2319 $ hg log -T status -C -r 10
2318 $ hg log -T status -C -r 10
2320 changeset: 10:0f9759ec227a
2319 changeset: 10:0f9759ec227a
2321 tag: tip
2320 tag: tip
2322 user: test
2321 user: test
2323 date: Thu Jan 01 00:00:00 1970 +0000
2322 date: Thu Jan 01 00:00:00 1970 +0000
2324 summary: Modify, add, remove, rename
2323 summary: Modify, add, remove, rename
2325 files:
2324 files:
2326 M third
2325 M third
2327 A b
2326 A b
2328 A fifth
2327 A fifth
2329 fourth
2328 fourth
2330 R a
2329 R a
2331 R fourth
2330 R fourth
2332
2331
2333 $ hg log -T status -C -r 10 -v
2332 $ hg log -T status -C -r 10 -v
2334 changeset: 10:0f9759ec227a
2333 changeset: 10:0f9759ec227a
2335 tag: tip
2334 tag: tip
2336 user: test
2335 user: test
2337 date: Thu Jan 01 00:00:00 1970 +0000
2336 date: Thu Jan 01 00:00:00 1970 +0000
2338 description:
2337 description:
2339 Modify, add, remove, rename
2338 Modify, add, remove, rename
2340
2339
2341 files:
2340 files:
2342 M third
2341 M third
2343 A b
2342 A b
2344 A fifth
2343 A fifth
2345 fourth
2344 fourth
2346 R a
2345 R a
2347 R fourth
2346 R fourth
2348
2347
2349 $ hg log -T status -C -r 10 --debug
2348 $ hg log -T status -C -r 10 --debug
2350 changeset: 10:0f9759ec227a4859c2014a345cd8a859022b7c6c
2349 changeset: 10:0f9759ec227a4859c2014a345cd8a859022b7c6c
2351 tag: tip
2350 tag: tip
2352 phase: secret
2351 phase: secret
2353 parent: 9:bf9dfba36635106d6a73ccc01e28b762da60e066
2352 parent: 9:bf9dfba36635106d6a73ccc01e28b762da60e066
2354 parent: -1:0000000000000000000000000000000000000000
2353 parent: -1:0000000000000000000000000000000000000000
2355 manifest: 8:89dd546f2de0a9d6d664f58d86097eb97baba567
2354 manifest: 8:89dd546f2de0a9d6d664f58d86097eb97baba567
2356 user: test
2355 user: test
2357 date: Thu Jan 01 00:00:00 1970 +0000
2356 date: Thu Jan 01 00:00:00 1970 +0000
2358 extra: branch=default
2357 extra: branch=default
2359 description:
2358 description:
2360 Modify, add, remove, rename
2359 Modify, add, remove, rename
2361
2360
2362 files:
2361 files:
2363 M third
2362 M third
2364 A b
2363 A b
2365 A fifth
2364 A fifth
2366 fourth
2365 fourth
2367 R a
2366 R a
2368 R fourth
2367 R fourth
2369
2368
2370 $ hg log -T status -C -r 10 --quiet
2369 $ hg log -T status -C -r 10 --quiet
2371 10:0f9759ec227a
2370 10:0f9759ec227a
2372 $ hg --color=debug log -T status -r 10
2371 $ hg --color=debug log -T status -r 10
2373 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2372 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2374 [log.tag|tag: tip]
2373 [log.tag|tag: tip]
2375 [log.user|user: test]
2374 [log.user|user: test]
2376 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2375 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2377 [log.summary|summary: Modify, add, remove, rename]
2376 [log.summary|summary: Modify, add, remove, rename]
2378 [ui.note log.files|files:]
2377 [ui.note log.files|files:]
2379 [status.modified|M third]
2378 [status.modified|M third]
2380 [status.added|A b]
2379 [status.added|A b]
2381 [status.added|A fifth]
2380 [status.added|A fifth]
2382 [status.removed|R a]
2381 [status.removed|R a]
2383 [status.removed|R fourth]
2382 [status.removed|R fourth]
2384
2383
2385 $ hg --color=debug log -T status -C -r 10
2384 $ hg --color=debug log -T status -C -r 10
2386 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2385 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2387 [log.tag|tag: tip]
2386 [log.tag|tag: tip]
2388 [log.user|user: test]
2387 [log.user|user: test]
2389 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2388 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2390 [log.summary|summary: Modify, add, remove, rename]
2389 [log.summary|summary: Modify, add, remove, rename]
2391 [ui.note log.files|files:]
2390 [ui.note log.files|files:]
2392 [status.modified|M third]
2391 [status.modified|M third]
2393 [status.added|A b]
2392 [status.added|A b]
2394 [status.added|A fifth]
2393 [status.added|A fifth]
2395 [status.copied| fourth]
2394 [status.copied| fourth]
2396 [status.removed|R a]
2395 [status.removed|R a]
2397 [status.removed|R fourth]
2396 [status.removed|R fourth]
2398
2397
2399 $ hg --color=debug log -T status -C -r 10 -v
2398 $ hg --color=debug log -T status -C -r 10 -v
2400 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2399 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2401 [log.tag|tag: tip]
2400 [log.tag|tag: tip]
2402 [log.user|user: test]
2401 [log.user|user: test]
2403 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2402 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2404 [ui.note log.description|description:]
2403 [ui.note log.description|description:]
2405 [ui.note log.description|Modify, add, remove, rename]
2404 [ui.note log.description|Modify, add, remove, rename]
2406
2405
2407 [ui.note log.files|files:]
2406 [ui.note log.files|files:]
2408 [status.modified|M third]
2407 [status.modified|M third]
2409 [status.added|A b]
2408 [status.added|A b]
2410 [status.added|A fifth]
2409 [status.added|A fifth]
2411 [status.copied| fourth]
2410 [status.copied| fourth]
2412 [status.removed|R a]
2411 [status.removed|R a]
2413 [status.removed|R fourth]
2412 [status.removed|R fourth]
2414
2413
2415 $ hg --color=debug log -T status -C -r 10 --debug
2414 $ hg --color=debug log -T status -C -r 10 --debug
2416 [log.changeset changeset.secret|changeset: 10:0f9759ec227a4859c2014a345cd8a859022b7c6c]
2415 [log.changeset changeset.secret|changeset: 10:0f9759ec227a4859c2014a345cd8a859022b7c6c]
2417 [log.tag|tag: tip]
2416 [log.tag|tag: tip]
2418 [log.phase|phase: secret]
2417 [log.phase|phase: secret]
2419 [log.parent changeset.secret|parent: 9:bf9dfba36635106d6a73ccc01e28b762da60e066]
2418 [log.parent changeset.secret|parent: 9:bf9dfba36635106d6a73ccc01e28b762da60e066]
2420 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2419 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2421 [ui.debug log.manifest|manifest: 8:89dd546f2de0a9d6d664f58d86097eb97baba567]
2420 [ui.debug log.manifest|manifest: 8:89dd546f2de0a9d6d664f58d86097eb97baba567]
2422 [log.user|user: test]
2421 [log.user|user: test]
2423 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2422 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2424 [ui.debug log.extra|extra: branch=default]
2423 [ui.debug log.extra|extra: branch=default]
2425 [ui.note log.description|description:]
2424 [ui.note log.description|description:]
2426 [ui.note log.description|Modify, add, remove, rename]
2425 [ui.note log.description|Modify, add, remove, rename]
2427
2426
2428 [ui.note log.files|files:]
2427 [ui.note log.files|files:]
2429 [status.modified|M third]
2428 [status.modified|M third]
2430 [status.added|A b]
2429 [status.added|A b]
2431 [status.added|A fifth]
2430 [status.added|A fifth]
2432 [status.copied| fourth]
2431 [status.copied| fourth]
2433 [status.removed|R a]
2432 [status.removed|R a]
2434 [status.removed|R fourth]
2433 [status.removed|R fourth]
2435
2434
2436 $ hg --color=debug log -T status -C -r 10 --quiet
2435 $ hg --color=debug log -T status -C -r 10 --quiet
2437 [log.node|10:0f9759ec227a]
2436 [log.node|10:0f9759ec227a]
2438
2437
2439 Check the bisect template
2438 Check the bisect template
2440
2439
2441 $ hg bisect -g 1
2440 $ hg bisect -g 1
2442 $ hg bisect -b 3 --noupdate
2441 $ hg bisect -b 3 --noupdate
2443 Testing changeset 2:97054abb4ab8 (2 changesets remaining, ~1 tests)
2442 Testing changeset 2:97054abb4ab8 (2 changesets remaining, ~1 tests)
2444 $ hg log -T bisect -r 0:4
2443 $ hg log -T bisect -r 0:4
2445 changeset: 0:1e4e1b8f71e0
2444 changeset: 0:1e4e1b8f71e0
2446 bisect: good (implicit)
2445 bisect: good (implicit)
2447 user: User Name <user@hostname>
2446 user: User Name <user@hostname>
2448 date: Mon Jan 12 13:46:40 1970 +0000
2447 date: Mon Jan 12 13:46:40 1970 +0000
2449 summary: line 1
2448 summary: line 1
2450
2449
2451 changeset: 1:b608e9d1a3f0
2450 changeset: 1:b608e9d1a3f0
2452 bisect: good
2451 bisect: good
2453 user: A. N. Other <other@place>
2452 user: A. N. Other <other@place>
2454 date: Tue Jan 13 17:33:20 1970 +0000
2453 date: Tue Jan 13 17:33:20 1970 +0000
2455 summary: other 1
2454 summary: other 1
2456
2455
2457 changeset: 2:97054abb4ab8
2456 changeset: 2:97054abb4ab8
2458 bisect: untested
2457 bisect: untested
2459 user: other@place
2458 user: other@place
2460 date: Wed Jan 14 21:20:00 1970 +0000
2459 date: Wed Jan 14 21:20:00 1970 +0000
2461 summary: no person
2460 summary: no person
2462
2461
2463 changeset: 3:10e46f2dcbf4
2462 changeset: 3:10e46f2dcbf4
2464 bisect: bad
2463 bisect: bad
2465 user: person
2464 user: person
2466 date: Fri Jan 16 01:06:40 1970 +0000
2465 date: Fri Jan 16 01:06:40 1970 +0000
2467 summary: no user, no domain
2466 summary: no user, no domain
2468
2467
2469 changeset: 4:bbe44766e73d
2468 changeset: 4:bbe44766e73d
2470 bisect: bad (implicit)
2469 bisect: bad (implicit)
2471 branch: foo
2470 branch: foo
2472 user: person
2471 user: person
2473 date: Sat Jan 17 04:53:20 1970 +0000
2472 date: Sat Jan 17 04:53:20 1970 +0000
2474 summary: new branch
2473 summary: new branch
2475
2474
2476 $ hg log --debug -T bisect -r 0:4
2475 $ hg log --debug -T bisect -r 0:4
2477 changeset: 0:1e4e1b8f71e05681d422154f5421e385fec3454f
2476 changeset: 0:1e4e1b8f71e05681d422154f5421e385fec3454f
2478 bisect: good (implicit)
2477 bisect: good (implicit)
2479 phase: public
2478 phase: public
2480 parent: -1:0000000000000000000000000000000000000000
2479 parent: -1:0000000000000000000000000000000000000000
2481 parent: -1:0000000000000000000000000000000000000000
2480 parent: -1:0000000000000000000000000000000000000000
2482 manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
2481 manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
2483 user: User Name <user@hostname>
2482 user: User Name <user@hostname>
2484 date: Mon Jan 12 13:46:40 1970 +0000
2483 date: Mon Jan 12 13:46:40 1970 +0000
2485 files+: a
2484 files+: a
2486 extra: branch=default
2485 extra: branch=default
2487 description:
2486 description:
2488 line 1
2487 line 1
2489 line 2
2488 line 2
2490
2489
2491
2490
2492 changeset: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2491 changeset: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2493 bisect: good
2492 bisect: good
2494 phase: public
2493 phase: public
2495 parent: 0:1e4e1b8f71e05681d422154f5421e385fec3454f
2494 parent: 0:1e4e1b8f71e05681d422154f5421e385fec3454f
2496 parent: -1:0000000000000000000000000000000000000000
2495 parent: -1:0000000000000000000000000000000000000000
2497 manifest: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
2496 manifest: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
2498 user: A. N. Other <other@place>
2497 user: A. N. Other <other@place>
2499 date: Tue Jan 13 17:33:20 1970 +0000
2498 date: Tue Jan 13 17:33:20 1970 +0000
2500 files+: b
2499 files+: b
2501 extra: branch=default
2500 extra: branch=default
2502 description:
2501 description:
2503 other 1
2502 other 1
2504 other 2
2503 other 2
2505
2504
2506 other 3
2505 other 3
2507
2506
2508
2507
2509 changeset: 2:97054abb4ab824450e9164180baf491ae0078465
2508 changeset: 2:97054abb4ab824450e9164180baf491ae0078465
2510 bisect: untested
2509 bisect: untested
2511 phase: public
2510 phase: public
2512 parent: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2511 parent: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2513 parent: -1:0000000000000000000000000000000000000000
2512 parent: -1:0000000000000000000000000000000000000000
2514 manifest: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
2513 manifest: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
2515 user: other@place
2514 user: other@place
2516 date: Wed Jan 14 21:20:00 1970 +0000
2515 date: Wed Jan 14 21:20:00 1970 +0000
2517 files+: c
2516 files+: c
2518 extra: branch=default
2517 extra: branch=default
2519 description:
2518 description:
2520 no person
2519 no person
2521
2520
2522
2521
2523 changeset: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47
2522 changeset: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47
2524 bisect: bad
2523 bisect: bad
2525 phase: public
2524 phase: public
2526 parent: 2:97054abb4ab824450e9164180baf491ae0078465
2525 parent: 2:97054abb4ab824450e9164180baf491ae0078465
2527 parent: -1:0000000000000000000000000000000000000000
2526 parent: -1:0000000000000000000000000000000000000000
2528 manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
2527 manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
2529 user: person
2528 user: person
2530 date: Fri Jan 16 01:06:40 1970 +0000
2529 date: Fri Jan 16 01:06:40 1970 +0000
2531 files: c
2530 files: c
2532 extra: branch=default
2531 extra: branch=default
2533 description:
2532 description:
2534 no user, no domain
2533 no user, no domain
2535
2534
2536
2535
2537 changeset: 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
2536 changeset: 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
2538 bisect: bad (implicit)
2537 bisect: bad (implicit)
2539 branch: foo
2538 branch: foo
2540 phase: draft
2539 phase: draft
2541 parent: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47
2540 parent: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47
2542 parent: -1:0000000000000000000000000000000000000000
2541 parent: -1:0000000000000000000000000000000000000000
2543 manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
2542 manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
2544 user: person
2543 user: person
2545 date: Sat Jan 17 04:53:20 1970 +0000
2544 date: Sat Jan 17 04:53:20 1970 +0000
2546 extra: branch=foo
2545 extra: branch=foo
2547 description:
2546 description:
2548 new branch
2547 new branch
2549
2548
2550
2549
2551 $ hg log -v -T bisect -r 0:4
2550 $ hg log -v -T bisect -r 0:4
2552 changeset: 0:1e4e1b8f71e0
2551 changeset: 0:1e4e1b8f71e0
2553 bisect: good (implicit)
2552 bisect: good (implicit)
2554 user: User Name <user@hostname>
2553 user: User Name <user@hostname>
2555 date: Mon Jan 12 13:46:40 1970 +0000
2554 date: Mon Jan 12 13:46:40 1970 +0000
2556 files: a
2555 files: a
2557 description:
2556 description:
2558 line 1
2557 line 1
2559 line 2
2558 line 2
2560
2559
2561
2560
2562 changeset: 1:b608e9d1a3f0
2561 changeset: 1:b608e9d1a3f0
2563 bisect: good
2562 bisect: good
2564 user: A. N. Other <other@place>
2563 user: A. N. Other <other@place>
2565 date: Tue Jan 13 17:33:20 1970 +0000
2564 date: Tue Jan 13 17:33:20 1970 +0000
2566 files: b
2565 files: b
2567 description:
2566 description:
2568 other 1
2567 other 1
2569 other 2
2568 other 2
2570
2569
2571 other 3
2570 other 3
2572
2571
2573
2572
2574 changeset: 2:97054abb4ab8
2573 changeset: 2:97054abb4ab8
2575 bisect: untested
2574 bisect: untested
2576 user: other@place
2575 user: other@place
2577 date: Wed Jan 14 21:20:00 1970 +0000
2576 date: Wed Jan 14 21:20:00 1970 +0000
2578 files: c
2577 files: c
2579 description:
2578 description:
2580 no person
2579 no person
2581
2580
2582
2581
2583 changeset: 3:10e46f2dcbf4
2582 changeset: 3:10e46f2dcbf4
2584 bisect: bad
2583 bisect: bad
2585 user: person
2584 user: person
2586 date: Fri Jan 16 01:06:40 1970 +0000
2585 date: Fri Jan 16 01:06:40 1970 +0000
2587 files: c
2586 files: c
2588 description:
2587 description:
2589 no user, no domain
2588 no user, no domain
2590
2589
2591
2590
2592 changeset: 4:bbe44766e73d
2591 changeset: 4:bbe44766e73d
2593 bisect: bad (implicit)
2592 bisect: bad (implicit)
2594 branch: foo
2593 branch: foo
2595 user: person
2594 user: person
2596 date: Sat Jan 17 04:53:20 1970 +0000
2595 date: Sat Jan 17 04:53:20 1970 +0000
2597 description:
2596 description:
2598 new branch
2597 new branch
2599
2598
2600
2599
2601 $ hg --color=debug log -T bisect -r 0:4
2600 $ hg --color=debug log -T bisect -r 0:4
2602 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e0]
2601 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e0]
2603 [log.bisect bisect.good|bisect: good (implicit)]
2602 [log.bisect bisect.good|bisect: good (implicit)]
2604 [log.user|user: User Name <user@hostname>]
2603 [log.user|user: User Name <user@hostname>]
2605 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2604 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2606 [log.summary|summary: line 1]
2605 [log.summary|summary: line 1]
2607
2606
2608 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0]
2607 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0]
2609 [log.bisect bisect.good|bisect: good]
2608 [log.bisect bisect.good|bisect: good]
2610 [log.user|user: A. N. Other <other@place>]
2609 [log.user|user: A. N. Other <other@place>]
2611 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2610 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2612 [log.summary|summary: other 1]
2611 [log.summary|summary: other 1]
2613
2612
2614 [log.changeset changeset.public|changeset: 2:97054abb4ab8]
2613 [log.changeset changeset.public|changeset: 2:97054abb4ab8]
2615 [log.bisect bisect.untested|bisect: untested]
2614 [log.bisect bisect.untested|bisect: untested]
2616 [log.user|user: other@place]
2615 [log.user|user: other@place]
2617 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2616 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2618 [log.summary|summary: no person]
2617 [log.summary|summary: no person]
2619
2618
2620 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4]
2619 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4]
2621 [log.bisect bisect.bad|bisect: bad]
2620 [log.bisect bisect.bad|bisect: bad]
2622 [log.user|user: person]
2621 [log.user|user: person]
2623 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2622 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2624 [log.summary|summary: no user, no domain]
2623 [log.summary|summary: no user, no domain]
2625
2624
2626 [log.changeset changeset.draft|changeset: 4:bbe44766e73d]
2625 [log.changeset changeset.draft|changeset: 4:bbe44766e73d]
2627 [log.bisect bisect.bad|bisect: bad (implicit)]
2626 [log.bisect bisect.bad|bisect: bad (implicit)]
2628 [log.branch|branch: foo]
2627 [log.branch|branch: foo]
2629 [log.user|user: person]
2628 [log.user|user: person]
2630 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2629 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2631 [log.summary|summary: new branch]
2630 [log.summary|summary: new branch]
2632
2631
2633 $ hg --color=debug log --debug -T bisect -r 0:4
2632 $ hg --color=debug log --debug -T bisect -r 0:4
2634 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e05681d422154f5421e385fec3454f]
2633 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e05681d422154f5421e385fec3454f]
2635 [log.bisect bisect.good|bisect: good (implicit)]
2634 [log.bisect bisect.good|bisect: good (implicit)]
2636 [log.phase|phase: public]
2635 [log.phase|phase: public]
2637 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2636 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2638 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2637 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2639 [ui.debug log.manifest|manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0]
2638 [ui.debug log.manifest|manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0]
2640 [log.user|user: User Name <user@hostname>]
2639 [log.user|user: User Name <user@hostname>]
2641 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2640 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2642 [ui.debug log.files|files+: a]
2641 [ui.debug log.files|files+: a]
2643 [ui.debug log.extra|extra: branch=default]
2642 [ui.debug log.extra|extra: branch=default]
2644 [ui.note log.description|description:]
2643 [ui.note log.description|description:]
2645 [ui.note log.description|line 1
2644 [ui.note log.description|line 1
2646 line 2]
2645 line 2]
2647
2646
2648
2647
2649 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965]
2648 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965]
2650 [log.bisect bisect.good|bisect: good]
2649 [log.bisect bisect.good|bisect: good]
2651 [log.phase|phase: public]
2650 [log.phase|phase: public]
2652 [log.parent changeset.public|parent: 0:1e4e1b8f71e05681d422154f5421e385fec3454f]
2651 [log.parent changeset.public|parent: 0:1e4e1b8f71e05681d422154f5421e385fec3454f]
2653 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2652 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2654 [ui.debug log.manifest|manifest: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55]
2653 [ui.debug log.manifest|manifest: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55]
2655 [log.user|user: A. N. Other <other@place>]
2654 [log.user|user: A. N. Other <other@place>]
2656 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2655 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2657 [ui.debug log.files|files+: b]
2656 [ui.debug log.files|files+: b]
2658 [ui.debug log.extra|extra: branch=default]
2657 [ui.debug log.extra|extra: branch=default]
2659 [ui.note log.description|description:]
2658 [ui.note log.description|description:]
2660 [ui.note log.description|other 1
2659 [ui.note log.description|other 1
2661 other 2
2660 other 2
2662
2661
2663 other 3]
2662 other 3]
2664
2663
2665
2664
2666 [log.changeset changeset.public|changeset: 2:97054abb4ab824450e9164180baf491ae0078465]
2665 [log.changeset changeset.public|changeset: 2:97054abb4ab824450e9164180baf491ae0078465]
2667 [log.bisect bisect.untested|bisect: untested]
2666 [log.bisect bisect.untested|bisect: untested]
2668 [log.phase|phase: public]
2667 [log.phase|phase: public]
2669 [log.parent changeset.public|parent: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965]
2668 [log.parent changeset.public|parent: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965]
2670 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2669 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2671 [ui.debug log.manifest|manifest: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1]
2670 [ui.debug log.manifest|manifest: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1]
2672 [log.user|user: other@place]
2671 [log.user|user: other@place]
2673 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2672 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2674 [ui.debug log.files|files+: c]
2673 [ui.debug log.files|files+: c]
2675 [ui.debug log.extra|extra: branch=default]
2674 [ui.debug log.extra|extra: branch=default]
2676 [ui.note log.description|description:]
2675 [ui.note log.description|description:]
2677 [ui.note log.description|no person]
2676 [ui.note log.description|no person]
2678
2677
2679
2678
2680 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47]
2679 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47]
2681 [log.bisect bisect.bad|bisect: bad]
2680 [log.bisect bisect.bad|bisect: bad]
2682 [log.phase|phase: public]
2681 [log.phase|phase: public]
2683 [log.parent changeset.public|parent: 2:97054abb4ab824450e9164180baf491ae0078465]
2682 [log.parent changeset.public|parent: 2:97054abb4ab824450e9164180baf491ae0078465]
2684 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2683 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2685 [ui.debug log.manifest|manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc]
2684 [ui.debug log.manifest|manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc]
2686 [log.user|user: person]
2685 [log.user|user: person]
2687 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2686 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2688 [ui.debug log.files|files: c]
2687 [ui.debug log.files|files: c]
2689 [ui.debug log.extra|extra: branch=default]
2688 [ui.debug log.extra|extra: branch=default]
2690 [ui.note log.description|description:]
2689 [ui.note log.description|description:]
2691 [ui.note log.description|no user, no domain]
2690 [ui.note log.description|no user, no domain]
2692
2691
2693
2692
2694 [log.changeset changeset.draft|changeset: 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74]
2693 [log.changeset changeset.draft|changeset: 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74]
2695 [log.bisect bisect.bad|bisect: bad (implicit)]
2694 [log.bisect bisect.bad|bisect: bad (implicit)]
2696 [log.branch|branch: foo]
2695 [log.branch|branch: foo]
2697 [log.phase|phase: draft]
2696 [log.phase|phase: draft]
2698 [log.parent changeset.public|parent: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47]
2697 [log.parent changeset.public|parent: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47]
2699 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2698 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2700 [ui.debug log.manifest|manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc]
2699 [ui.debug log.manifest|manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc]
2701 [log.user|user: person]
2700 [log.user|user: person]
2702 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2701 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2703 [ui.debug log.extra|extra: branch=foo]
2702 [ui.debug log.extra|extra: branch=foo]
2704 [ui.note log.description|description:]
2703 [ui.note log.description|description:]
2705 [ui.note log.description|new branch]
2704 [ui.note log.description|new branch]
2706
2705
2707
2706
2708 $ hg --color=debug log -v -T bisect -r 0:4
2707 $ hg --color=debug log -v -T bisect -r 0:4
2709 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e0]
2708 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e0]
2710 [log.bisect bisect.good|bisect: good (implicit)]
2709 [log.bisect bisect.good|bisect: good (implicit)]
2711 [log.user|user: User Name <user@hostname>]
2710 [log.user|user: User Name <user@hostname>]
2712 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2711 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2713 [ui.note log.files|files: a]
2712 [ui.note log.files|files: a]
2714 [ui.note log.description|description:]
2713 [ui.note log.description|description:]
2715 [ui.note log.description|line 1
2714 [ui.note log.description|line 1
2716 line 2]
2715 line 2]
2717
2716
2718
2717
2719 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0]
2718 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0]
2720 [log.bisect bisect.good|bisect: good]
2719 [log.bisect bisect.good|bisect: good]
2721 [log.user|user: A. N. Other <other@place>]
2720 [log.user|user: A. N. Other <other@place>]
2722 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2721 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2723 [ui.note log.files|files: b]
2722 [ui.note log.files|files: b]
2724 [ui.note log.description|description:]
2723 [ui.note log.description|description:]
2725 [ui.note log.description|other 1
2724 [ui.note log.description|other 1
2726 other 2
2725 other 2
2727
2726
2728 other 3]
2727 other 3]
2729
2728
2730
2729
2731 [log.changeset changeset.public|changeset: 2:97054abb4ab8]
2730 [log.changeset changeset.public|changeset: 2:97054abb4ab8]
2732 [log.bisect bisect.untested|bisect: untested]
2731 [log.bisect bisect.untested|bisect: untested]
2733 [log.user|user: other@place]
2732 [log.user|user: other@place]
2734 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2733 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2735 [ui.note log.files|files: c]
2734 [ui.note log.files|files: c]
2736 [ui.note log.description|description:]
2735 [ui.note log.description|description:]
2737 [ui.note log.description|no person]
2736 [ui.note log.description|no person]
2738
2737
2739
2738
2740 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4]
2739 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4]
2741 [log.bisect bisect.bad|bisect: bad]
2740 [log.bisect bisect.bad|bisect: bad]
2742 [log.user|user: person]
2741 [log.user|user: person]
2743 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2742 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2744 [ui.note log.files|files: c]
2743 [ui.note log.files|files: c]
2745 [ui.note log.description|description:]
2744 [ui.note log.description|description:]
2746 [ui.note log.description|no user, no domain]
2745 [ui.note log.description|no user, no domain]
2747
2746
2748
2747
2749 [log.changeset changeset.draft|changeset: 4:bbe44766e73d]
2748 [log.changeset changeset.draft|changeset: 4:bbe44766e73d]
2750 [log.bisect bisect.bad|bisect: bad (implicit)]
2749 [log.bisect bisect.bad|bisect: bad (implicit)]
2751 [log.branch|branch: foo]
2750 [log.branch|branch: foo]
2752 [log.user|user: person]
2751 [log.user|user: person]
2753 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2752 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2754 [ui.note log.description|description:]
2753 [ui.note log.description|description:]
2755 [ui.note log.description|new branch]
2754 [ui.note log.description|new branch]
2756
2755
2757
2756
2758 $ hg bisect --reset
2757 $ hg bisect --reset
2759
2758
2760 Error on syntax:
2759 Error on syntax:
2761
2760
2762 $ echo 'x = "f' >> t
2761 $ echo 'x = "f' >> t
2763 $ hg log
2762 $ hg log
2764 hg: parse error at t:3: unmatched quotes
2763 hg: parse error at t:3: unmatched quotes
2765 [255]
2764 [255]
2766
2765
2767 $ hg log -T '{date'
2766 $ hg log -T '{date'
2768 hg: parse error at 1: unterminated template expansion
2767 hg: parse error at 1: unterminated template expansion
2769 ({date
2768 ({date
2770 ^ here)
2769 ^ here)
2771 [255]
2770 [255]
2772 $ hg log -T '{date(}'
2771 $ hg log -T '{date(}'
2773 hg: parse error at 6: not a prefix: end
2772 hg: parse error at 6: not a prefix: end
2774 ({date(}
2773 ({date(}
2775 ^ here)
2774 ^ here)
2776 [255]
2775 [255]
2777 $ hg log -T '{date)}'
2776 $ hg log -T '{date)}'
2778 hg: parse error at 5: invalid token
2777 hg: parse error at 5: invalid token
2779 ({date)}
2778 ({date)}
2780 ^ here)
2779 ^ here)
2781 [255]
2780 [255]
2782 $ hg log -T '{date date}'
2781 $ hg log -T '{date date}'
2783 hg: parse error at 6: invalid token
2782 hg: parse error at 6: invalid token
2784 ({date date}
2783 ({date date}
2785 ^ here)
2784 ^ here)
2786 [255]
2785 [255]
2787
2786
2788 $ hg log -T '{}'
2787 $ hg log -T '{}'
2789 hg: parse error at 1: not a prefix: end
2788 hg: parse error at 1: not a prefix: end
2790 ({}
2789 ({}
2791 ^ here)
2790 ^ here)
2792 [255]
2791 [255]
2793 $ hg debugtemplate -v '{()}'
2792 $ hg debugtemplate -v '{()}'
2794 (template
2793 (template
2795 (group
2794 (group
2796 None))
2795 None))
2797 hg: parse error: missing argument
2796 hg: parse error: missing argument
2798 [255]
2797 [255]
2799
2798
2800 Behind the scenes, this will throw TypeError
2799 Behind the scenes, this would throw TypeError without intype=bytes
2801
2800
2802 $ hg log -l 3 --template '{date|obfuscate}\n'
2801 $ hg log -l 3 --template '{date|obfuscate}\n'
2803 abort: template filter 'obfuscate' is not compatible with keyword 'date'
2802 &#48;&#46;&#48;&#48;
2804 [255]
2803 &#48;&#46;&#48;&#48;
2804 &#49;&#53;&#55;&#55;&#56;&#55;&#50;&#56;&#54;&#48;&#46;&#48;&#48;
2805
2805
2806 Behind the scenes, this will throw a ValueError
2806 Behind the scenes, this will throw a ValueError
2807
2807
2808 $ hg log -l 3 --template 'line: {desc|shortdate}\n'
2808 $ hg log -l 3 --template 'line: {desc|shortdate}\n'
2809 abort: template filter 'shortdate' is not compatible with keyword 'desc'
2809 abort: template filter 'shortdate' is not compatible with keyword 'desc'
2810 [255]
2810 [255]
2811
2811
2812 Behind the scenes, this will throw AttributeError
2812 Behind the scenes, this would throw AttributeError without intype=bytes
2813
2813
2814 $ hg log -l 3 --template 'line: {date|escape}\n'
2814 $ hg log -l 3 --template 'line: {date|escape}\n'
2815 abort: template filter 'escape' is not compatible with keyword 'date'
2815 line: 0.00
2816 [255]
2816 line: 0.00
2817 line: 1577872860.00
2817
2818
2818 $ hg log -l 3 --template 'line: {extras|localdate}\n'
2819 $ hg log -l 3 --template 'line: {extras|localdate}\n'
2819 hg: parse error: localdate expects a date information
2820 hg: parse error: localdate expects a date information
2820 [255]
2821 [255]
2821
2822
2822 Behind the scenes, this will throw ValueError
2823 Behind the scenes, this will throw ValueError
2823
2824
2824 $ hg tip --template '{author|email|date}\n'
2825 $ hg tip --template '{author|email|date}\n'
2825 hg: parse error: date expects a date information
2826 hg: parse error: date expects a date information
2826 [255]
2827 [255]
2827
2828
2828 $ hg tip -T '{author|email|shortdate}\n'
2829 $ hg tip -T '{author|email|shortdate}\n'
2829 abort: template filter 'shortdate' is not compatible with keyword 'author'
2830 abort: template filter 'shortdate' is not compatible with keyword 'author'
2830 [255]
2831 [255]
2831
2832
2832 $ hg tip -T '{get(extras, "branch")|shortdate}\n'
2833 $ hg tip -T '{get(extras, "branch")|shortdate}\n'
2833 abort: incompatible use of template filter 'shortdate'
2834 abort: incompatible use of template filter 'shortdate'
2834 [255]
2835 [255]
2835
2836
2836 Error in nested template:
2837 Error in nested template:
2837
2838
2838 $ hg log -T '{"date'
2839 $ hg log -T '{"date'
2839 hg: parse error at 2: unterminated string
2840 hg: parse error at 2: unterminated string
2840 ({"date
2841 ({"date
2841 ^ here)
2842 ^ here)
2842 [255]
2843 [255]
2843
2844
2844 $ hg log -T '{"foo{date|?}"}'
2845 $ hg log -T '{"foo{date|?}"}'
2845 hg: parse error at 11: syntax error
2846 hg: parse error at 11: syntax error
2846 ({"foo{date|?}"}
2847 ({"foo{date|?}"}
2847 ^ here)
2848 ^ here)
2848 [255]
2849 [255]
2849
2850
2850 Thrown an error if a template function doesn't exist
2851 Thrown an error if a template function doesn't exist
2851
2852
2852 $ hg tip --template '{foo()}\n'
2853 $ hg tip --template '{foo()}\n'
2853 hg: parse error: unknown function 'foo'
2854 hg: parse error: unknown function 'foo'
2854 [255]
2855 [255]
2855
2856
2856 Pass generator object created by template function to filter
2857 Pass generator object created by template function to filter
2857
2858
2858 $ hg log -l 1 --template '{if(author, author)|user}\n'
2859 $ hg log -l 1 --template '{if(author, author)|user}\n'
2859 test
2860 test
2860
2861
2861 Test index keyword:
2862 Test index keyword:
2862
2863
2863 $ hg log -l 2 -T '{index + 10}{files % " {index}:{file}"}\n'
2864 $ hg log -l 2 -T '{index + 10}{files % " {index}:{file}"}\n'
2864 10 0:a 1:b 2:fifth 3:fourth 4:third
2865 10 0:a 1:b 2:fifth 3:fourth 4:third
2865 11 0:a
2866 11 0:a
2866
2867
2867 $ hg branches -T '{index} {branch}\n'
2868 $ hg branches -T '{index} {branch}\n'
2868 0 default
2869 0 default
2869 1 foo
2870 1 foo
2870
2871
2871 Test diff function:
2872 Test diff function:
2872
2873
2873 $ hg diff -c 8
2874 $ hg diff -c 8
2874 diff -r 29114dbae42b -r 95c24699272e fourth
2875 diff -r 29114dbae42b -r 95c24699272e fourth
2875 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2876 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2876 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2877 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2877 @@ -0,0 +1,1 @@
2878 @@ -0,0 +1,1 @@
2878 +second
2879 +second
2879 diff -r 29114dbae42b -r 95c24699272e second
2880 diff -r 29114dbae42b -r 95c24699272e second
2880 --- a/second Mon Jan 12 13:46:40 1970 +0000
2881 --- a/second Mon Jan 12 13:46:40 1970 +0000
2881 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2882 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2882 @@ -1,1 +0,0 @@
2883 @@ -1,1 +0,0 @@
2883 -second
2884 -second
2884 diff -r 29114dbae42b -r 95c24699272e third
2885 diff -r 29114dbae42b -r 95c24699272e third
2885 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2886 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2886 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2887 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2887 @@ -0,0 +1,1 @@
2888 @@ -0,0 +1,1 @@
2888 +third
2889 +third
2889
2890
2890 $ hg log -r 8 -T "{diff()}"
2891 $ hg log -r 8 -T "{diff()}"
2891 diff -r 29114dbae42b -r 95c24699272e fourth
2892 diff -r 29114dbae42b -r 95c24699272e fourth
2892 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2893 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2893 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2894 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2894 @@ -0,0 +1,1 @@
2895 @@ -0,0 +1,1 @@
2895 +second
2896 +second
2896 diff -r 29114dbae42b -r 95c24699272e second
2897 diff -r 29114dbae42b -r 95c24699272e second
2897 --- a/second Mon Jan 12 13:46:40 1970 +0000
2898 --- a/second Mon Jan 12 13:46:40 1970 +0000
2898 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2899 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2899 @@ -1,1 +0,0 @@
2900 @@ -1,1 +0,0 @@
2900 -second
2901 -second
2901 diff -r 29114dbae42b -r 95c24699272e third
2902 diff -r 29114dbae42b -r 95c24699272e third
2902 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2903 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2903 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2904 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2904 @@ -0,0 +1,1 @@
2905 @@ -0,0 +1,1 @@
2905 +third
2906 +third
2906
2907
2907 $ hg log -r 8 -T "{diff('glob:f*')}"
2908 $ hg log -r 8 -T "{diff('glob:f*')}"
2908 diff -r 29114dbae42b -r 95c24699272e fourth
2909 diff -r 29114dbae42b -r 95c24699272e fourth
2909 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2910 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2910 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2911 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2911 @@ -0,0 +1,1 @@
2912 @@ -0,0 +1,1 @@
2912 +second
2913 +second
2913
2914
2914 $ hg log -r 8 -T "{diff('', 'glob:f*')}"
2915 $ hg log -r 8 -T "{diff('', 'glob:f*')}"
2915 diff -r 29114dbae42b -r 95c24699272e second
2916 diff -r 29114dbae42b -r 95c24699272e second
2916 --- a/second Mon Jan 12 13:46:40 1970 +0000
2917 --- a/second Mon Jan 12 13:46:40 1970 +0000
2917 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2918 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2918 @@ -1,1 +0,0 @@
2919 @@ -1,1 +0,0 @@
2919 -second
2920 -second
2920 diff -r 29114dbae42b -r 95c24699272e third
2921 diff -r 29114dbae42b -r 95c24699272e third
2921 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2922 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2922 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2923 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2923 @@ -0,0 +1,1 @@
2924 @@ -0,0 +1,1 @@
2924 +third
2925 +third
2925
2926
2926 $ hg log -r 8 -T "{diff('FOURTH'|lower)}"
2927 $ hg log -r 8 -T "{diff('FOURTH'|lower)}"
2927 diff -r 29114dbae42b -r 95c24699272e fourth
2928 diff -r 29114dbae42b -r 95c24699272e fourth
2928 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2929 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2929 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2930 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2930 @@ -0,0 +1,1 @@
2931 @@ -0,0 +1,1 @@
2931 +second
2932 +second
2932
2933
2933 ui verbosity:
2934 ui verbosity:
2934
2935
2935 $ hg log -l1 -T '{verbosity}\n'
2936 $ hg log -l1 -T '{verbosity}\n'
2936
2937
2937 $ hg log -l1 -T '{verbosity}\n' --debug
2938 $ hg log -l1 -T '{verbosity}\n' --debug
2938 debug
2939 debug
2939 $ hg log -l1 -T '{verbosity}\n' --quiet
2940 $ hg log -l1 -T '{verbosity}\n' --quiet
2940 quiet
2941 quiet
2941 $ hg log -l1 -T '{verbosity}\n' --verbose
2942 $ hg log -l1 -T '{verbosity}\n' --verbose
2942 verbose
2943 verbose
2943
2944
2944 $ cd ..
2945 $ cd ..
2945
2946
2946
2947
2947 latesttag:
2948 latesttag:
2948
2949
2949 $ hg init latesttag
2950 $ hg init latesttag
2950 $ cd latesttag
2951 $ cd latesttag
2951
2952
2952 $ echo a > file
2953 $ echo a > file
2953 $ hg ci -Am a -d '0 0'
2954 $ hg ci -Am a -d '0 0'
2954 adding file
2955 adding file
2955
2956
2956 $ echo b >> file
2957 $ echo b >> file
2957 $ hg ci -m b -d '1 0'
2958 $ hg ci -m b -d '1 0'
2958
2959
2959 $ echo c >> head1
2960 $ echo c >> head1
2960 $ hg ci -Am h1c -d '2 0'
2961 $ hg ci -Am h1c -d '2 0'
2961 adding head1
2962 adding head1
2962
2963
2963 $ hg update -q 1
2964 $ hg update -q 1
2964 $ echo d >> head2
2965 $ echo d >> head2
2965 $ hg ci -Am h2d -d '3 0'
2966 $ hg ci -Am h2d -d '3 0'
2966 adding head2
2967 adding head2
2967 created new head
2968 created new head
2968
2969
2969 $ echo e >> head2
2970 $ echo e >> head2
2970 $ hg ci -m h2e -d '4 0'
2971 $ hg ci -m h2e -d '4 0'
2971
2972
2972 $ hg merge -q
2973 $ hg merge -q
2973 $ hg ci -m merge -d '5 -3600'
2974 $ hg ci -m merge -d '5 -3600'
2974
2975
2975 No tag set:
2976 No tag set:
2976
2977
2977 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
2978 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
2978 @ 5: null+5
2979 @ 5: null+5
2979 |\
2980 |\
2980 | o 4: null+4
2981 | o 4: null+4
2981 | |
2982 | |
2982 | o 3: null+3
2983 | o 3: null+3
2983 | |
2984 | |
2984 o | 2: null+3
2985 o | 2: null+3
2985 |/
2986 |/
2986 o 1: null+2
2987 o 1: null+2
2987 |
2988 |
2988 o 0: null+1
2989 o 0: null+1
2989
2990
2990
2991
2991 One common tag: longest path wins for {latesttagdistance}:
2992 One common tag: longest path wins for {latesttagdistance}:
2992
2993
2993 $ hg tag -r 1 -m t1 -d '6 0' t1
2994 $ hg tag -r 1 -m t1 -d '6 0' t1
2994 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
2995 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
2995 @ 6: t1+4
2996 @ 6: t1+4
2996 |
2997 |
2997 o 5: t1+3
2998 o 5: t1+3
2998 |\
2999 |\
2999 | o 4: t1+2
3000 | o 4: t1+2
3000 | |
3001 | |
3001 | o 3: t1+1
3002 | o 3: t1+1
3002 | |
3003 | |
3003 o | 2: t1+1
3004 o | 2: t1+1
3004 |/
3005 |/
3005 o 1: t1+0
3006 o 1: t1+0
3006 |
3007 |
3007 o 0: null+1
3008 o 0: null+1
3008
3009
3009
3010
3010 One ancestor tag: closest wins:
3011 One ancestor tag: closest wins:
3011
3012
3012 $ hg tag -r 2 -m t2 -d '7 0' t2
3013 $ hg tag -r 2 -m t2 -d '7 0' t2
3013 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
3014 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
3014 @ 7: t2+3
3015 @ 7: t2+3
3015 |
3016 |
3016 o 6: t2+2
3017 o 6: t2+2
3017 |
3018 |
3018 o 5: t2+1
3019 o 5: t2+1
3019 |\
3020 |\
3020 | o 4: t1+2
3021 | o 4: t1+2
3021 | |
3022 | |
3022 | o 3: t1+1
3023 | o 3: t1+1
3023 | |
3024 | |
3024 o | 2: t2+0
3025 o | 2: t2+0
3025 |/
3026 |/
3026 o 1: t1+0
3027 o 1: t1+0
3027 |
3028 |
3028 o 0: null+1
3029 o 0: null+1
3029
3030
3030
3031
3031 Two branch tags: more recent wins if same number of changes:
3032 Two branch tags: more recent wins if same number of changes:
3032
3033
3033 $ hg tag -r 3 -m t3 -d '8 0' t3
3034 $ hg tag -r 3 -m t3 -d '8 0' t3
3034 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
3035 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
3035 @ 8: t3+5
3036 @ 8: t3+5
3036 |
3037 |
3037 o 7: t3+4
3038 o 7: t3+4
3038 |
3039 |
3039 o 6: t3+3
3040 o 6: t3+3
3040 |
3041 |
3041 o 5: t3+2
3042 o 5: t3+2
3042 |\
3043 |\
3043 | o 4: t3+1
3044 | o 4: t3+1
3044 | |
3045 | |
3045 | o 3: t3+0
3046 | o 3: t3+0
3046 | |
3047 | |
3047 o | 2: t2+0
3048 o | 2: t2+0
3048 |/
3049 |/
3049 o 1: t1+0
3050 o 1: t1+0
3050 |
3051 |
3051 o 0: null+1
3052 o 0: null+1
3052
3053
3053
3054
3054 Two branch tags: fewest changes wins:
3055 Two branch tags: fewest changes wins:
3055
3056
3056 $ hg tag -r 4 -m t4 -d '4 0' t4 # older than t2, but should not matter
3057 $ hg tag -r 4 -m t4 -d '4 0' t4 # older than t2, but should not matter
3057 $ hg log -G --template "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
3058 $ hg log -G --template "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
3058 @ 9: t4+5,6
3059 @ 9: t4+5,6
3059 |
3060 |
3060 o 8: t4+4,5
3061 o 8: t4+4,5
3061 |
3062 |
3062 o 7: t4+3,4
3063 o 7: t4+3,4
3063 |
3064 |
3064 o 6: t4+2,3
3065 o 6: t4+2,3
3065 |
3066 |
3066 o 5: t4+1,2
3067 o 5: t4+1,2
3067 |\
3068 |\
3068 | o 4: t4+0,0
3069 | o 4: t4+0,0
3069 | |
3070 | |
3070 | o 3: t3+0,0
3071 | o 3: t3+0,0
3071 | |
3072 | |
3072 o | 2: t2+0,0
3073 o | 2: t2+0,0
3073 |/
3074 |/
3074 o 1: t1+0,0
3075 o 1: t1+0,0
3075 |
3076 |
3076 o 0: null+1,1
3077 o 0: null+1,1
3077
3078
3078
3079
3079 Merged tag overrides:
3080 Merged tag overrides:
3080
3081
3081 $ hg tag -r 5 -m t5 -d '9 0' t5
3082 $ hg tag -r 5 -m t5 -d '9 0' t5
3082 $ hg tag -r 3 -m at3 -d '10 0' at3
3083 $ hg tag -r 3 -m at3 -d '10 0' at3
3083 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
3084 $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
3084 @ 11: t5+6
3085 @ 11: t5+6
3085 |
3086 |
3086 o 10: t5+5
3087 o 10: t5+5
3087 |
3088 |
3088 o 9: t5+4
3089 o 9: t5+4
3089 |
3090 |
3090 o 8: t5+3
3091 o 8: t5+3
3091 |
3092 |
3092 o 7: t5+2
3093 o 7: t5+2
3093 |
3094 |
3094 o 6: t5+1
3095 o 6: t5+1
3095 |
3096 |
3096 o 5: t5+0
3097 o 5: t5+0
3097 |\
3098 |\
3098 | o 4: t4+0
3099 | o 4: t4+0
3099 | |
3100 | |
3100 | o 3: at3:t3+0
3101 | o 3: at3:t3+0
3101 | |
3102 | |
3102 o | 2: t2+0
3103 o | 2: t2+0
3103 |/
3104 |/
3104 o 1: t1+0
3105 o 1: t1+0
3105 |
3106 |
3106 o 0: null+1
3107 o 0: null+1
3107
3108
3108
3109
3109 $ hg log -G --template "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
3110 $ hg log -G --template "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
3110 @ 11: t5+6,6
3111 @ 11: t5+6,6
3111 |
3112 |
3112 o 10: t5+5,5
3113 o 10: t5+5,5
3113 |
3114 |
3114 o 9: t5+4,4
3115 o 9: t5+4,4
3115 |
3116 |
3116 o 8: t5+3,3
3117 o 8: t5+3,3
3117 |
3118 |
3118 o 7: t5+2,2
3119 o 7: t5+2,2
3119 |
3120 |
3120 o 6: t5+1,1
3121 o 6: t5+1,1
3121 |
3122 |
3122 o 5: t5+0,0
3123 o 5: t5+0,0
3123 |\
3124 |\
3124 | o 4: t4+0,0
3125 | o 4: t4+0,0
3125 | |
3126 | |
3126 | o 3: at3+0,0 t3+0,0
3127 | o 3: at3+0,0 t3+0,0
3127 | |
3128 | |
3128 o | 2: t2+0,0
3129 o | 2: t2+0,0
3129 |/
3130 |/
3130 o 1: t1+0,0
3131 o 1: t1+0,0
3131 |
3132 |
3132 o 0: null+1,1
3133 o 0: null+1,1
3133
3134
3134
3135
3135 $ hg log -G --template "{rev}: {latesttag('re:^t[13]$') % '{tag}, C: {changes}, D: {distance}'}\n"
3136 $ hg log -G --template "{rev}: {latesttag('re:^t[13]$') % '{tag}, C: {changes}, D: {distance}'}\n"
3136 @ 11: t3, C: 9, D: 8
3137 @ 11: t3, C: 9, D: 8
3137 |
3138 |
3138 o 10: t3, C: 8, D: 7
3139 o 10: t3, C: 8, D: 7
3139 |
3140 |
3140 o 9: t3, C: 7, D: 6
3141 o 9: t3, C: 7, D: 6
3141 |
3142 |
3142 o 8: t3, C: 6, D: 5
3143 o 8: t3, C: 6, D: 5
3143 |
3144 |
3144 o 7: t3, C: 5, D: 4
3145 o 7: t3, C: 5, D: 4
3145 |
3146 |
3146 o 6: t3, C: 4, D: 3
3147 o 6: t3, C: 4, D: 3
3147 |
3148 |
3148 o 5: t3, C: 3, D: 2
3149 o 5: t3, C: 3, D: 2
3149 |\
3150 |\
3150 | o 4: t3, C: 1, D: 1
3151 | o 4: t3, C: 1, D: 1
3151 | |
3152 | |
3152 | o 3: t3, C: 0, D: 0
3153 | o 3: t3, C: 0, D: 0
3153 | |
3154 | |
3154 o | 2: t1, C: 1, D: 1
3155 o | 2: t1, C: 1, D: 1
3155 |/
3156 |/
3156 o 1: t1, C: 0, D: 0
3157 o 1: t1, C: 0, D: 0
3157 |
3158 |
3158 o 0: null, C: 1, D: 1
3159 o 0: null, C: 1, D: 1
3159
3160
3160
3161
3161 $ cd ..
3162 $ cd ..
3162
3163
3163
3164
3164 Style path expansion: issue1948 - ui.style option doesn't work on OSX
3165 Style path expansion: issue1948 - ui.style option doesn't work on OSX
3165 if it is a relative path
3166 if it is a relative path
3166
3167
3167 $ mkdir -p home/styles
3168 $ mkdir -p home/styles
3168
3169
3169 $ cat > home/styles/teststyle <<EOF
3170 $ cat > home/styles/teststyle <<EOF
3170 > changeset = 'test {rev}:{node|short}\n'
3171 > changeset = 'test {rev}:{node|short}\n'
3171 > EOF
3172 > EOF
3172
3173
3173 $ HOME=`pwd`/home; export HOME
3174 $ HOME=`pwd`/home; export HOME
3174
3175
3175 $ cat > latesttag/.hg/hgrc <<EOF
3176 $ cat > latesttag/.hg/hgrc <<EOF
3176 > [ui]
3177 > [ui]
3177 > style = ~/styles/teststyle
3178 > style = ~/styles/teststyle
3178 > EOF
3179 > EOF
3179
3180
3180 $ hg -R latesttag tip
3181 $ hg -R latesttag tip
3181 test 11:97e5943b523a
3182 test 11:97e5943b523a
3182
3183
3183 Test recursive showlist template (issue1989):
3184 Test recursive showlist template (issue1989):
3184
3185
3185 $ cat > style1989 <<EOF
3186 $ cat > style1989 <<EOF
3186 > changeset = '{file_mods}{manifest}{extras}'
3187 > changeset = '{file_mods}{manifest}{extras}'
3187 > file_mod = 'M|{author|person}\n'
3188 > file_mod = 'M|{author|person}\n'
3188 > manifest = '{rev},{author}\n'
3189 > manifest = '{rev},{author}\n'
3189 > extra = '{key}: {author}\n'
3190 > extra = '{key}: {author}\n'
3190 > EOF
3191 > EOF
3191
3192
3192 $ hg -R latesttag log -r tip --style=style1989
3193 $ hg -R latesttag log -r tip --style=style1989
3193 M|test
3194 M|test
3194 11,test
3195 11,test
3195 branch: test
3196 branch: test
3196
3197
3197 Test new-style inline templating:
3198 Test new-style inline templating:
3198
3199
3199 $ hg log -R latesttag -r tip --template 'modified files: {file_mods % " {file}\n"}\n'
3200 $ hg log -R latesttag -r tip --template 'modified files: {file_mods % " {file}\n"}\n'
3200 modified files: .hgtags
3201 modified files: .hgtags
3201
3202
3202
3203
3203 $ hg log -R latesttag -r tip -T '{rev % "a"}\n'
3204 $ hg log -R latesttag -r tip -T '{rev % "a"}\n'
3204 hg: parse error: keyword 'rev' is not iterable
3205 hg: parse error: keyword 'rev' is not iterable
3205 [255]
3206 [255]
3206 $ hg log -R latesttag -r tip -T '{get(extras, "unknown") % "a"}\n'
3207 $ hg log -R latesttag -r tip -T '{get(extras, "unknown") % "a"}\n'
3207 hg: parse error: None is not iterable
3208 hg: parse error: None is not iterable
3208 [255]
3209 [255]
3209
3210
3210 Test new-style inline templating of non-list/dict type:
3211 Test new-style inline templating of non-list/dict type:
3211
3212
3212 $ hg log -R latesttag -r tip -T '{manifest}\n'
3213 $ hg log -R latesttag -r tip -T '{manifest}\n'
3213 11:2bc6e9006ce2
3214 11:2bc6e9006ce2
3214 $ hg log -R latesttag -r tip -T 'string length: {manifest|count}\n'
3215 $ hg log -R latesttag -r tip -T 'string length: {manifest|count}\n'
3215 string length: 15
3216 string length: 15
3216 $ hg log -R latesttag -r tip -T '{manifest % "{rev}:{node}"}\n'
3217 $ hg log -R latesttag -r tip -T '{manifest % "{rev}:{node}"}\n'
3217 11:2bc6e9006ce29882383a22d39fd1f4e66dd3e2fc
3218 11:2bc6e9006ce29882383a22d39fd1f4e66dd3e2fc
3218
3219
3219 $ hg log -R latesttag -r tip -T '{get(extras, "branch") % "{key}: {value}\n"}'
3220 $ hg log -R latesttag -r tip -T '{get(extras, "branch") % "{key}: {value}\n"}'
3220 branch: default
3221 branch: default
3221 $ hg log -R latesttag -r tip -T '{get(extras, "unknown") % "{key}\n"}'
3222 $ hg log -R latesttag -r tip -T '{get(extras, "unknown") % "{key}\n"}'
3222 hg: parse error: None is not iterable
3223 hg: parse error: None is not iterable
3223 [255]
3224 [255]
3224 $ hg log -R latesttag -r tip -T '{min(extras) % "{key}: {value}\n"}'
3225 $ hg log -R latesttag -r tip -T '{min(extras) % "{key}: {value}\n"}'
3225 branch: default
3226 branch: default
3226 $ hg log -R latesttag -l1 -T '{min(revset("0:9")) % "{rev}:{node|short}\n"}'
3227 $ hg log -R latesttag -l1 -T '{min(revset("0:9")) % "{rev}:{node|short}\n"}'
3227 0:ce3cec86e6c2
3228 0:ce3cec86e6c2
3228 $ hg log -R latesttag -l1 -T '{max(revset("0:9")) % "{rev}:{node|short}\n"}'
3229 $ hg log -R latesttag -l1 -T '{max(revset("0:9")) % "{rev}:{node|short}\n"}'
3229 9:fbc7cd862e9c
3230 9:fbc7cd862e9c
3230
3231
3231 Test manifest/get() can be join()-ed as before, though it's silly:
3232 Test manifest/get() can be join()-ed as before, though it's silly:
3232
3233
3233 $ hg log -R latesttag -r tip -T '{join(manifest, "")}\n'
3234 $ hg log -R latesttag -r tip -T '{join(manifest, "")}\n'
3234 11:2bc6e9006ce2
3235 11:2bc6e9006ce2
3235 $ hg log -R latesttag -r tip -T '{join(get(extras, "branch"), "")}\n'
3236 $ hg log -R latesttag -r tip -T '{join(get(extras, "branch"), "")}\n'
3236 default
3237 default
3237
3238
3238 Test min/max of integers
3239 Test min/max of integers
3239
3240
3240 $ hg log -R latesttag -l1 -T '{min(revset("9:10"))}\n'
3241 $ hg log -R latesttag -l1 -T '{min(revset("9:10"))}\n'
3241 9
3242 9
3242 $ hg log -R latesttag -l1 -T '{max(revset("9:10"))}\n'
3243 $ hg log -R latesttag -l1 -T '{max(revset("9:10"))}\n'
3243 10
3244 10
3244
3245
3245 Test min/max of if() result
3246 Test min/max of if() result
3246
3247
3247 $ cd latesttag
3248 $ cd latesttag
3248 $ hg log -l1 -T '{min(if(true, revset("9:10"), ""))}\n'
3249 $ hg log -l1 -T '{min(if(true, revset("9:10"), ""))}\n'
3249 9
3250 9
3250 $ hg log -l1 -T '{max(if(false, "", revset("9:10")))}\n'
3251 $ hg log -l1 -T '{max(if(false, "", revset("9:10")))}\n'
3251 10
3252 10
3252 $ hg log -l1 -T '{min(ifcontains("a", "aa", revset("9:10"), ""))}\n'
3253 $ hg log -l1 -T '{min(ifcontains("a", "aa", revset("9:10"), ""))}\n'
3253 9
3254 9
3254 $ hg log -l1 -T '{max(ifcontains("a", "bb", "", revset("9:10")))}\n'
3255 $ hg log -l1 -T '{max(ifcontains("a", "bb", "", revset("9:10")))}\n'
3255 10
3256 10
3256 $ hg log -l1 -T '{min(ifeq(0, 0, revset("9:10"), ""))}\n'
3257 $ hg log -l1 -T '{min(ifeq(0, 0, revset("9:10"), ""))}\n'
3257 9
3258 9
3258 $ hg log -l1 -T '{max(ifeq(0, 1, "", revset("9:10")))}\n'
3259 $ hg log -l1 -T '{max(ifeq(0, 1, "", revset("9:10")))}\n'
3259 10
3260 10
3260 $ cd ..
3261 $ cd ..
3261
3262
3262 Test laziness of if() then/else clause
3263 Test laziness of if() then/else clause
3263
3264
3264 $ hg debugtemplate '{count(0)}'
3265 $ hg debugtemplate '{count(0)}'
3265 abort: incompatible use of template filter 'count'
3266 abort: incompatible use of template filter 'count'
3266 [255]
3267 [255]
3267 $ hg debugtemplate '{if(true, "", count(0))}'
3268 $ hg debugtemplate '{if(true, "", count(0))}'
3268 $ hg debugtemplate '{if(false, count(0), "")}'
3269 $ hg debugtemplate '{if(false, count(0), "")}'
3269 $ hg debugtemplate '{ifcontains("a", "aa", "", count(0))}'
3270 $ hg debugtemplate '{ifcontains("a", "aa", "", count(0))}'
3270 $ hg debugtemplate '{ifcontains("a", "bb", count(0), "")}'
3271 $ hg debugtemplate '{ifcontains("a", "bb", count(0), "")}'
3271 $ hg debugtemplate '{ifeq(0, 0, "", count(0))}'
3272 $ hg debugtemplate '{ifeq(0, 0, "", count(0))}'
3272 $ hg debugtemplate '{ifeq(0, 1, count(0), "")}'
3273 $ hg debugtemplate '{ifeq(0, 1, count(0), "")}'
3273
3274
3274 Test dot operator precedence:
3275 Test dot operator precedence:
3275
3276
3276 $ hg debugtemplate -R latesttag -r0 -v '{manifest.node|short}\n'
3277 $ hg debugtemplate -R latesttag -r0 -v '{manifest.node|short}\n'
3277 (template
3278 (template
3278 (|
3279 (|
3279 (.
3280 (.
3280 (symbol 'manifest')
3281 (symbol 'manifest')
3281 (symbol 'node'))
3282 (symbol 'node'))
3282 (symbol 'short'))
3283 (symbol 'short'))
3283 (string '\n'))
3284 (string '\n'))
3284 89f4071fec70
3285 89f4071fec70
3285
3286
3286 (the following examples are invalid, but seem natural in parsing POV)
3287 (the following examples are invalid, but seem natural in parsing POV)
3287
3288
3288 $ hg debugtemplate -R latesttag -r0 -v '{foo|bar.baz}\n' 2> /dev/null
3289 $ hg debugtemplate -R latesttag -r0 -v '{foo|bar.baz}\n' 2> /dev/null
3289 (template
3290 (template
3290 (|
3291 (|
3291 (symbol 'foo')
3292 (symbol 'foo')
3292 (.
3293 (.
3293 (symbol 'bar')
3294 (symbol 'bar')
3294 (symbol 'baz')))
3295 (symbol 'baz')))
3295 (string '\n'))
3296 (string '\n'))
3296 [255]
3297 [255]
3297 $ hg debugtemplate -R latesttag -r0 -v '{foo.bar()}\n' 2> /dev/null
3298 $ hg debugtemplate -R latesttag -r0 -v '{foo.bar()}\n' 2> /dev/null
3298 (template
3299 (template
3299 (.
3300 (.
3300 (symbol 'foo')
3301 (symbol 'foo')
3301 (func
3302 (func
3302 (symbol 'bar')
3303 (symbol 'bar')
3303 None))
3304 None))
3304 (string '\n'))
3305 (string '\n'))
3305 [255]
3306 [255]
3306
3307
3307 Test evaluation of dot operator:
3308 Test evaluation of dot operator:
3308
3309
3309 $ hg log -R latesttag -l1 -T '{min(revset("0:9")).node}\n'
3310 $ hg log -R latesttag -l1 -T '{min(revset("0:9")).node}\n'
3310 ce3cec86e6c26bd9bdfc590a6b92abc9680f1796
3311 ce3cec86e6c26bd9bdfc590a6b92abc9680f1796
3311 $ hg log -R latesttag -r0 -T '{extras.branch}\n'
3312 $ hg log -R latesttag -r0 -T '{extras.branch}\n'
3312 default
3313 default
3313
3314
3314 $ hg log -R latesttag -l1 -T '{author.invalid}\n'
3315 $ hg log -R latesttag -l1 -T '{author.invalid}\n'
3315 hg: parse error: keyword 'author' has no member
3316 hg: parse error: keyword 'author' has no member
3316 [255]
3317 [255]
3317 $ hg log -R latesttag -l1 -T '{min("abc").invalid}\n'
3318 $ hg log -R latesttag -l1 -T '{min("abc").invalid}\n'
3318 hg: parse error: 'a' has no member
3319 hg: parse error: 'a' has no member
3319 [255]
3320 [255]
3320
3321
3321 Test the sub function of templating for expansion:
3322 Test the sub function of templating for expansion:
3322
3323
3323 $ hg log -R latesttag -r 10 --template '{sub("[0-9]", "x", "{rev}")}\n'
3324 $ hg log -R latesttag -r 10 --template '{sub("[0-9]", "x", "{rev}")}\n'
3324 xx
3325 xx
3325
3326
3326 $ hg log -R latesttag -r 10 -T '{sub("[", "x", rev)}\n'
3327 $ hg log -R latesttag -r 10 -T '{sub("[", "x", rev)}\n'
3327 hg: parse error: sub got an invalid pattern: [
3328 hg: parse error: sub got an invalid pattern: [
3328 [255]
3329 [255]
3329 $ hg log -R latesttag -r 10 -T '{sub("[0-9]", r"\1", rev)}\n'
3330 $ hg log -R latesttag -r 10 -T '{sub("[0-9]", r"\1", rev)}\n'
3330 hg: parse error: sub got an invalid replacement: \1
3331 hg: parse error: sub got an invalid replacement: \1
3331 [255]
3332 [255]
3332
3333
3333 Test the strip function with chars specified:
3334 Test the strip function with chars specified:
3334
3335
3335 $ hg log -R latesttag --template '{desc}\n'
3336 $ hg log -R latesttag --template '{desc}\n'
3336 at3
3337 at3
3337 t5
3338 t5
3338 t4
3339 t4
3339 t3
3340 t3
3340 t2
3341 t2
3341 t1
3342 t1
3342 merge
3343 merge
3343 h2e
3344 h2e
3344 h2d
3345 h2d
3345 h1c
3346 h1c
3346 b
3347 b
3347 a
3348 a
3348
3349
3349 $ hg log -R latesttag --template '{strip(desc, "te")}\n'
3350 $ hg log -R latesttag --template '{strip(desc, "te")}\n'
3350 at3
3351 at3
3351 5
3352 5
3352 4
3353 4
3353 3
3354 3
3354 2
3355 2
3355 1
3356 1
3356 merg
3357 merg
3357 h2
3358 h2
3358 h2d
3359 h2d
3359 h1c
3360 h1c
3360 b
3361 b
3361 a
3362 a
3362
3363
3363 Test date format:
3364 Test date format:
3364
3365
3365 $ hg log -R latesttag --template 'date: {date(date, "%y %m %d %S %z")}\n'
3366 $ hg log -R latesttag --template 'date: {date(date, "%y %m %d %S %z")}\n'
3366 date: 70 01 01 10 +0000
3367 date: 70 01 01 10 +0000
3367 date: 70 01 01 09 +0000
3368 date: 70 01 01 09 +0000
3368 date: 70 01 01 04 +0000
3369 date: 70 01 01 04 +0000
3369 date: 70 01 01 08 +0000
3370 date: 70 01 01 08 +0000
3370 date: 70 01 01 07 +0000
3371 date: 70 01 01 07 +0000
3371 date: 70 01 01 06 +0000
3372 date: 70 01 01 06 +0000
3372 date: 70 01 01 05 +0100
3373 date: 70 01 01 05 +0100
3373 date: 70 01 01 04 +0000
3374 date: 70 01 01 04 +0000
3374 date: 70 01 01 03 +0000
3375 date: 70 01 01 03 +0000
3375 date: 70 01 01 02 +0000
3376 date: 70 01 01 02 +0000
3376 date: 70 01 01 01 +0000
3377 date: 70 01 01 01 +0000
3377 date: 70 01 01 00 +0000
3378 date: 70 01 01 00 +0000
3378
3379
3379 Test invalid date:
3380 Test invalid date:
3380
3381
3381 $ hg log -R latesttag -T '{date(rev)}\n'
3382 $ hg log -R latesttag -T '{date(rev)}\n'
3382 hg: parse error: date expects a date information
3383 hg: parse error: date expects a date information
3383 [255]
3384 [255]
3384
3385
3385 Test integer literal:
3386 Test integer literal:
3386
3387
3387 $ hg debugtemplate -v '{(0)}\n'
3388 $ hg debugtemplate -v '{(0)}\n'
3388 (template
3389 (template
3389 (group
3390 (group
3390 (integer '0'))
3391 (integer '0'))
3391 (string '\n'))
3392 (string '\n'))
3392 0
3393 0
3393 $ hg debugtemplate -v '{(123)}\n'
3394 $ hg debugtemplate -v '{(123)}\n'
3394 (template
3395 (template
3395 (group
3396 (group
3396 (integer '123'))
3397 (integer '123'))
3397 (string '\n'))
3398 (string '\n'))
3398 123
3399 123
3399 $ hg debugtemplate -v '{(-4)}\n'
3400 $ hg debugtemplate -v '{(-4)}\n'
3400 (template
3401 (template
3401 (group
3402 (group
3402 (negate
3403 (negate
3403 (integer '4')))
3404 (integer '4')))
3404 (string '\n'))
3405 (string '\n'))
3405 -4
3406 -4
3406 $ hg debugtemplate '{(-)}\n'
3407 $ hg debugtemplate '{(-)}\n'
3407 hg: parse error at 3: not a prefix: )
3408 hg: parse error at 3: not a prefix: )
3408 ({(-)}\n
3409 ({(-)}\n
3409 ^ here)
3410 ^ here)
3410 [255]
3411 [255]
3411 $ hg debugtemplate '{(-a)}\n'
3412 $ hg debugtemplate '{(-a)}\n'
3412 hg: parse error: negation needs an integer argument
3413 hg: parse error: negation needs an integer argument
3413 [255]
3414 [255]
3414
3415
3415 top-level integer literal is interpreted as symbol (i.e. variable name):
3416 top-level integer literal is interpreted as symbol (i.e. variable name):
3416
3417
3417 $ hg debugtemplate -D 1=one -v '{1}\n'
3418 $ hg debugtemplate -D 1=one -v '{1}\n'
3418 (template
3419 (template
3419 (integer '1')
3420 (integer '1')
3420 (string '\n'))
3421 (string '\n'))
3421 one
3422 one
3422 $ hg debugtemplate -D 1=one -v '{if("t", "{1}")}\n'
3423 $ hg debugtemplate -D 1=one -v '{if("t", "{1}")}\n'
3423 (template
3424 (template
3424 (func
3425 (func
3425 (symbol 'if')
3426 (symbol 'if')
3426 (list
3427 (list
3427 (string 't')
3428 (string 't')
3428 (template
3429 (template
3429 (integer '1'))))
3430 (integer '1'))))
3430 (string '\n'))
3431 (string '\n'))
3431 one
3432 one
3432 $ hg debugtemplate -D 1=one -v '{1|stringify}\n'
3433 $ hg debugtemplate -D 1=one -v '{1|stringify}\n'
3433 (template
3434 (template
3434 (|
3435 (|
3435 (integer '1')
3436 (integer '1')
3436 (symbol 'stringify'))
3437 (symbol 'stringify'))
3437 (string '\n'))
3438 (string '\n'))
3438 one
3439 one
3439
3440
3440 unless explicit symbol is expected:
3441 unless explicit symbol is expected:
3441
3442
3442 $ hg log -Ra -r0 -T '{desc|1}\n'
3443 $ hg log -Ra -r0 -T '{desc|1}\n'
3443 hg: parse error: expected a symbol, got 'integer'
3444 hg: parse error: expected a symbol, got 'integer'
3444 [255]
3445 [255]
3445 $ hg log -Ra -r0 -T '{1()}\n'
3446 $ hg log -Ra -r0 -T '{1()}\n'
3446 hg: parse error: expected a symbol, got 'integer'
3447 hg: parse error: expected a symbol, got 'integer'
3447 [255]
3448 [255]
3448
3449
3449 Test string literal:
3450 Test string literal:
3450
3451
3451 $ hg debugtemplate -Ra -r0 -v '{"string with no template fragment"}\n'
3452 $ hg debugtemplate -Ra -r0 -v '{"string with no template fragment"}\n'
3452 (template
3453 (template
3453 (string 'string with no template fragment')
3454 (string 'string with no template fragment')
3454 (string '\n'))
3455 (string '\n'))
3455 string with no template fragment
3456 string with no template fragment
3456 $ hg debugtemplate -Ra -r0 -v '{"template: {rev}"}\n'
3457 $ hg debugtemplate -Ra -r0 -v '{"template: {rev}"}\n'
3457 (template
3458 (template
3458 (template
3459 (template
3459 (string 'template: ')
3460 (string 'template: ')
3460 (symbol 'rev'))
3461 (symbol 'rev'))
3461 (string '\n'))
3462 (string '\n'))
3462 template: 0
3463 template: 0
3463 $ hg debugtemplate -Ra -r0 -v '{r"rawstring: {rev}"}\n'
3464 $ hg debugtemplate -Ra -r0 -v '{r"rawstring: {rev}"}\n'
3464 (template
3465 (template
3465 (string 'rawstring: {rev}')
3466 (string 'rawstring: {rev}')
3466 (string '\n'))
3467 (string '\n'))
3467 rawstring: {rev}
3468 rawstring: {rev}
3468 $ hg debugtemplate -Ra -r0 -v '{files % r"rawstring: {file}"}\n'
3469 $ hg debugtemplate -Ra -r0 -v '{files % r"rawstring: {file}"}\n'
3469 (template
3470 (template
3470 (%
3471 (%
3471 (symbol 'files')
3472 (symbol 'files')
3472 (string 'rawstring: {file}'))
3473 (string 'rawstring: {file}'))
3473 (string '\n'))
3474 (string '\n'))
3474 rawstring: {file}
3475 rawstring: {file}
3475
3476
3476 Test string escaping:
3477 Test string escaping:
3477
3478
3478 $ hg log -R latesttag -r 0 --template '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
3479 $ hg log -R latesttag -r 0 --template '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
3479 >
3480 >
3480 <>\n<[>
3481 <>\n<[>
3481 <>\n<]>
3482 <>\n<]>
3482 <>\n<
3483 <>\n<
3483
3484
3484 $ hg log -R latesttag -r 0 \
3485 $ hg log -R latesttag -r 0 \
3485 > --config ui.logtemplate='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
3486 > --config ui.logtemplate='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
3486 >
3487 >
3487 <>\n<[>
3488 <>\n<[>
3488 <>\n<]>
3489 <>\n<]>
3489 <>\n<
3490 <>\n<
3490
3491
3491 $ hg log -R latesttag -r 0 -T esc \
3492 $ hg log -R latesttag -r 0 -T esc \
3492 > --config templates.esc='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
3493 > --config templates.esc='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
3493 >
3494 >
3494 <>\n<[>
3495 <>\n<[>
3495 <>\n<]>
3496 <>\n<]>
3496 <>\n<
3497 <>\n<
3497
3498
3498 $ cat <<'EOF' > esctmpl
3499 $ cat <<'EOF' > esctmpl
3499 > changeset = '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
3500 > changeset = '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
3500 > EOF
3501 > EOF
3501 $ hg log -R latesttag -r 0 --style ./esctmpl
3502 $ hg log -R latesttag -r 0 --style ./esctmpl
3502 >
3503 >
3503 <>\n<[>
3504 <>\n<[>
3504 <>\n<]>
3505 <>\n<]>
3505 <>\n<
3506 <>\n<
3506
3507
3507 Test string escaping of quotes:
3508 Test string escaping of quotes:
3508
3509
3509 $ hg log -Ra -r0 -T '{"\""}\n'
3510 $ hg log -Ra -r0 -T '{"\""}\n'
3510 "
3511 "
3511 $ hg log -Ra -r0 -T '{"\\\""}\n'
3512 $ hg log -Ra -r0 -T '{"\\\""}\n'
3512 \"
3513 \"
3513 $ hg log -Ra -r0 -T '{r"\""}\n'
3514 $ hg log -Ra -r0 -T '{r"\""}\n'
3514 \"
3515 \"
3515 $ hg log -Ra -r0 -T '{r"\\\""}\n'
3516 $ hg log -Ra -r0 -T '{r"\\\""}\n'
3516 \\\"
3517 \\\"
3517
3518
3518
3519
3519 $ hg log -Ra -r0 -T '{"\""}\n'
3520 $ hg log -Ra -r0 -T '{"\""}\n'
3520 "
3521 "
3521 $ hg log -Ra -r0 -T '{"\\\""}\n'
3522 $ hg log -Ra -r0 -T '{"\\\""}\n'
3522 \"
3523 \"
3523 $ hg log -Ra -r0 -T '{r"\""}\n'
3524 $ hg log -Ra -r0 -T '{r"\""}\n'
3524 \"
3525 \"
3525 $ hg log -Ra -r0 -T '{r"\\\""}\n'
3526 $ hg log -Ra -r0 -T '{r"\\\""}\n'
3526 \\\"
3527 \\\"
3527
3528
3528 Test exception in quoted template. single backslash before quotation mark is
3529 Test exception in quoted template. single backslash before quotation mark is
3529 stripped before parsing:
3530 stripped before parsing:
3530
3531
3531 $ cat <<'EOF' > escquotetmpl
3532 $ cat <<'EOF' > escquotetmpl
3532 > changeset = "\" \\" \\\" \\\\" {files % \"{file}\"}\n"
3533 > changeset = "\" \\" \\\" \\\\" {files % \"{file}\"}\n"
3533 > EOF
3534 > EOF
3534 $ cd latesttag
3535 $ cd latesttag
3535 $ hg log -r 2 --style ../escquotetmpl
3536 $ hg log -r 2 --style ../escquotetmpl
3536 " \" \" \\" head1
3537 " \" \" \\" head1
3537
3538
3538 $ hg log -r 2 -T esc --config templates.esc='"{\"valid\"}\n"'
3539 $ hg log -r 2 -T esc --config templates.esc='"{\"valid\"}\n"'
3539 valid
3540 valid
3540 $ hg log -r 2 -T esc --config templates.esc="'"'{\'"'"'valid\'"'"'}\n'"'"
3541 $ hg log -r 2 -T esc --config templates.esc="'"'{\'"'"'valid\'"'"'}\n'"'"
3541 valid
3542 valid
3542
3543
3543 Test compatibility with 2.9.2-3.4 of escaped quoted strings in nested
3544 Test compatibility with 2.9.2-3.4 of escaped quoted strings in nested
3544 _evalifliteral() templates (issue4733):
3545 _evalifliteral() templates (issue4733):
3545
3546
3546 $ hg log -r 2 -T '{if(rev, "\"{rev}")}\n'
3547 $ hg log -r 2 -T '{if(rev, "\"{rev}")}\n'
3547 "2
3548 "2
3548 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\"{rev}\")}")}\n'
3549 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\"{rev}\")}")}\n'
3549 "2
3550 "2
3550 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\"{rev}\\\")}\")}")}\n'
3551 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\"{rev}\\\")}\")}")}\n'
3551 "2
3552 "2
3552
3553
3553 $ hg log -r 2 -T '{if(rev, "\\\"")}\n'
3554 $ hg log -r 2 -T '{if(rev, "\\\"")}\n'
3554 \"
3555 \"
3555 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\\\\\"\")}")}\n'
3556 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\\\\\"\")}")}\n'
3556 \"
3557 \"
3557 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
3558 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
3558 \"
3559 \"
3559
3560
3560 $ hg log -r 2 -T '{if(rev, r"\\\"")}\n'
3561 $ hg log -r 2 -T '{if(rev, r"\\\"")}\n'
3561 \\\"
3562 \\\"
3562 $ hg log -r 2 -T '{if(rev, "{if(rev, r\"\\\\\\\"\")}")}\n'
3563 $ hg log -r 2 -T '{if(rev, "{if(rev, r\"\\\\\\\"\")}")}\n'
3563 \\\"
3564 \\\"
3564 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, r\\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
3565 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, r\\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
3565 \\\"
3566 \\\"
3566
3567
3567 escaped single quotes and errors:
3568 escaped single quotes and errors:
3568
3569
3569 $ hg log -r 2 -T "{if(rev, '{if(rev, \'foo\')}')}"'\n'
3570 $ hg log -r 2 -T "{if(rev, '{if(rev, \'foo\')}')}"'\n'
3570 foo
3571 foo
3571 $ hg log -r 2 -T "{if(rev, '{if(rev, r\'foo\')}')}"'\n'
3572 $ hg log -r 2 -T "{if(rev, '{if(rev, r\'foo\')}')}"'\n'
3572 foo
3573 foo
3573 $ hg log -r 2 -T '{if(rev, "{if(rev, \")}")}\n'
3574 $ hg log -r 2 -T '{if(rev, "{if(rev, \")}")}\n'
3574 hg: parse error at 21: unterminated string
3575 hg: parse error at 21: unterminated string
3575 ({if(rev, "{if(rev, \")}")}\n
3576 ({if(rev, "{if(rev, \")}")}\n
3576 ^ here)
3577 ^ here)
3577 [255]
3578 [255]
3578 $ hg log -r 2 -T '{if(rev, \"\\"")}\n'
3579 $ hg log -r 2 -T '{if(rev, \"\\"")}\n'
3579 hg: parse error: trailing \ in string
3580 hg: parse error: trailing \ in string
3580 [255]
3581 [255]
3581 $ hg log -r 2 -T '{if(rev, r\"\\"")}\n'
3582 $ hg log -r 2 -T '{if(rev, r\"\\"")}\n'
3582 hg: parse error: trailing \ in string
3583 hg: parse error: trailing \ in string
3583 [255]
3584 [255]
3584
3585
3585 $ cd ..
3586 $ cd ..
3586
3587
3587 Test leading backslashes:
3588 Test leading backslashes:
3588
3589
3589 $ cd latesttag
3590 $ cd latesttag
3590 $ hg log -r 2 -T '\{rev} {files % "\{file}"}\n'
3591 $ hg log -r 2 -T '\{rev} {files % "\{file}"}\n'
3591 {rev} {file}
3592 {rev} {file}
3592 $ hg log -r 2 -T '\\{rev} {files % "\\{file}"}\n'
3593 $ hg log -r 2 -T '\\{rev} {files % "\\{file}"}\n'
3593 \2 \head1
3594 \2 \head1
3594 $ hg log -r 2 -T '\\\{rev} {files % "\\\{file}"}\n'
3595 $ hg log -r 2 -T '\\\{rev} {files % "\\\{file}"}\n'
3595 \{rev} \{file}
3596 \{rev} \{file}
3596 $ cd ..
3597 $ cd ..
3597
3598
3598 Test leading backslashes in "if" expression (issue4714):
3599 Test leading backslashes in "if" expression (issue4714):
3599
3600
3600 $ cd latesttag
3601 $ cd latesttag
3601 $ hg log -r 2 -T '{if("1", "\{rev}")} {if("1", r"\{rev}")}\n'
3602 $ hg log -r 2 -T '{if("1", "\{rev}")} {if("1", r"\{rev}")}\n'
3602 {rev} \{rev}
3603 {rev} \{rev}
3603 $ hg log -r 2 -T '{if("1", "\\{rev}")} {if("1", r"\\{rev}")}\n'
3604 $ hg log -r 2 -T '{if("1", "\\{rev}")} {if("1", r"\\{rev}")}\n'
3604 \2 \\{rev}
3605 \2 \\{rev}
3605 $ hg log -r 2 -T '{if("1", "\\\{rev}")} {if("1", r"\\\{rev}")}\n'
3606 $ hg log -r 2 -T '{if("1", "\\\{rev}")} {if("1", r"\\\{rev}")}\n'
3606 \{rev} \\\{rev}
3607 \{rev} \\\{rev}
3607 $ cd ..
3608 $ cd ..
3608
3609
3609 "string-escape"-ed "\x5c\x786e" becomes r"\x6e" (once) or r"n" (twice)
3610 "string-escape"-ed "\x5c\x786e" becomes r"\x6e" (once) or r"n" (twice)
3610
3611
3611 $ hg log -R a -r 0 --template '{if("1", "\x5c\x786e", "NG")}\n'
3612 $ hg log -R a -r 0 --template '{if("1", "\x5c\x786e", "NG")}\n'
3612 \x6e
3613 \x6e
3613 $ hg log -R a -r 0 --template '{if("1", r"\x5c\x786e", "NG")}\n'
3614 $ hg log -R a -r 0 --template '{if("1", r"\x5c\x786e", "NG")}\n'
3614 \x5c\x786e
3615 \x5c\x786e
3615 $ hg log -R a -r 0 --template '{if("", "NG", "\x5c\x786e")}\n'
3616 $ hg log -R a -r 0 --template '{if("", "NG", "\x5c\x786e")}\n'
3616 \x6e
3617 \x6e
3617 $ hg log -R a -r 0 --template '{if("", "NG", r"\x5c\x786e")}\n'
3618 $ hg log -R a -r 0 --template '{if("", "NG", r"\x5c\x786e")}\n'
3618 \x5c\x786e
3619 \x5c\x786e
3619
3620
3620 $ hg log -R a -r 2 --template '{ifeq("no perso\x6e", desc, "\x5c\x786e", "NG")}\n'
3621 $ hg log -R a -r 2 --template '{ifeq("no perso\x6e", desc, "\x5c\x786e", "NG")}\n'
3621 \x6e
3622 \x6e
3622 $ hg log -R a -r 2 --template '{ifeq(r"no perso\x6e", desc, "NG", r"\x5c\x786e")}\n'
3623 $ hg log -R a -r 2 --template '{ifeq(r"no perso\x6e", desc, "NG", r"\x5c\x786e")}\n'
3623 \x5c\x786e
3624 \x5c\x786e
3624 $ hg log -R a -r 2 --template '{ifeq(desc, "no perso\x6e", "\x5c\x786e", "NG")}\n'
3625 $ hg log -R a -r 2 --template '{ifeq(desc, "no perso\x6e", "\x5c\x786e", "NG")}\n'
3625 \x6e
3626 \x6e
3626 $ hg log -R a -r 2 --template '{ifeq(desc, r"no perso\x6e", "NG", r"\x5c\x786e")}\n'
3627 $ hg log -R a -r 2 --template '{ifeq(desc, r"no perso\x6e", "NG", r"\x5c\x786e")}\n'
3627 \x5c\x786e
3628 \x5c\x786e
3628
3629
3629 $ hg log -R a -r 8 --template '{join(files, "\n")}\n'
3630 $ hg log -R a -r 8 --template '{join(files, "\n")}\n'
3630 fourth
3631 fourth
3631 second
3632 second
3632 third
3633 third
3633 $ hg log -R a -r 8 --template '{join(files, r"\n")}\n'
3634 $ hg log -R a -r 8 --template '{join(files, r"\n")}\n'
3634 fourth\nsecond\nthird
3635 fourth\nsecond\nthird
3635
3636
3636 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", "htm\x6c")}'
3637 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", "htm\x6c")}'
3637 <p>
3638 <p>
3638 1st
3639 1st
3639 </p>
3640 </p>
3640 <p>
3641 <p>
3641 2nd
3642 2nd
3642 </p>
3643 </p>
3643 $ hg log -R a -r 2 --template '{rstdoc(r"1st\n\n2nd", "html")}'
3644 $ hg log -R a -r 2 --template '{rstdoc(r"1st\n\n2nd", "html")}'
3644 <p>
3645 <p>
3645 1st\n\n2nd
3646 1st\n\n2nd
3646 </p>
3647 </p>
3647 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", r"htm\x6c")}'
3648 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", r"htm\x6c")}'
3648 1st
3649 1st
3649
3650
3650 2nd
3651 2nd
3651
3652
3652 $ hg log -R a -r 2 --template '{strip(desc, "\x6e")}\n'
3653 $ hg log -R a -r 2 --template '{strip(desc, "\x6e")}\n'
3653 o perso
3654 o perso
3654 $ hg log -R a -r 2 --template '{strip(desc, r"\x6e")}\n'
3655 $ hg log -R a -r 2 --template '{strip(desc, r"\x6e")}\n'
3655 no person
3656 no person
3656 $ hg log -R a -r 2 --template '{strip("no perso\x6e", "\x6e")}\n'
3657 $ hg log -R a -r 2 --template '{strip("no perso\x6e", "\x6e")}\n'
3657 o perso
3658 o perso
3658 $ hg log -R a -r 2 --template '{strip(r"no perso\x6e", r"\x6e")}\n'
3659 $ hg log -R a -r 2 --template '{strip(r"no perso\x6e", r"\x6e")}\n'
3659 no perso
3660 no perso
3660
3661
3661 $ hg log -R a -r 2 --template '{sub("\\x6e", "\x2d", desc)}\n'
3662 $ hg log -R a -r 2 --template '{sub("\\x6e", "\x2d", desc)}\n'
3662 -o perso-
3663 -o perso-
3663 $ hg log -R a -r 2 --template '{sub(r"\\x6e", "-", desc)}\n'
3664 $ hg log -R a -r 2 --template '{sub(r"\\x6e", "-", desc)}\n'
3664 no person
3665 no person
3665 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", desc)}\n'
3666 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", desc)}\n'
3666 \x2do perso\x2d
3667 \x2do perso\x2d
3667 $ hg log -R a -r 2 --template '{sub("n", "\x2d", "no perso\x6e")}\n'
3668 $ hg log -R a -r 2 --template '{sub("n", "\x2d", "no perso\x6e")}\n'
3668 -o perso-
3669 -o perso-
3669 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", r"no perso\x6e")}\n'
3670 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", r"no perso\x6e")}\n'
3670 \x2do perso\x6e
3671 \x2do perso\x6e
3671
3672
3672 $ hg log -R a -r 8 --template '{files % "{file}\n"}'
3673 $ hg log -R a -r 8 --template '{files % "{file}\n"}'
3673 fourth
3674 fourth
3674 second
3675 second
3675 third
3676 third
3676
3677
3677 Test string escaping in nested expression:
3678 Test string escaping in nested expression:
3678
3679
3679 $ hg log -R a -r 8 --template '{ifeq(r"\x6e", if("1", "\x5c\x786e"), join(files, "\x5c\x786e"))}\n'
3680 $ hg log -R a -r 8 --template '{ifeq(r"\x6e", if("1", "\x5c\x786e"), join(files, "\x5c\x786e"))}\n'
3680 fourth\x6esecond\x6ethird
3681 fourth\x6esecond\x6ethird
3681 $ hg log -R a -r 8 --template '{ifeq(if("1", r"\x6e"), "\x5c\x786e", join(files, "\x5c\x786e"))}\n'
3682 $ hg log -R a -r 8 --template '{ifeq(if("1", r"\x6e"), "\x5c\x786e", join(files, "\x5c\x786e"))}\n'
3682 fourth\x6esecond\x6ethird
3683 fourth\x6esecond\x6ethird
3683
3684
3684 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", "\x5c\x786e"))}\n'
3685 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", "\x5c\x786e"))}\n'
3685 fourth\x6esecond\x6ethird
3686 fourth\x6esecond\x6ethird
3686 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", r"\x5c\x786e"))}\n'
3687 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", r"\x5c\x786e"))}\n'
3687 fourth\x5c\x786esecond\x5c\x786ethird
3688 fourth\x5c\x786esecond\x5c\x786ethird
3688
3689
3689 $ hg log -R a -r 3:4 --template '{rev}:{sub(if("1", "\x6e"), ifeq(branch, "foo", r"\x5c\x786e", "\x5c\x786e"), desc)}\n'
3690 $ hg log -R a -r 3:4 --template '{rev}:{sub(if("1", "\x6e"), ifeq(branch, "foo", r"\x5c\x786e", "\x5c\x786e"), desc)}\n'
3690 3:\x6eo user, \x6eo domai\x6e
3691 3:\x6eo user, \x6eo domai\x6e
3691 4:\x5c\x786eew bra\x5c\x786ech
3692 4:\x5c\x786eew bra\x5c\x786ech
3692
3693
3693 Test quotes in nested expression are evaluated just like a $(command)
3694 Test quotes in nested expression are evaluated just like a $(command)
3694 substitution in POSIX shells:
3695 substitution in POSIX shells:
3695
3696
3696 $ hg log -R a -r 8 -T '{"{"{rev}:{node|short}"}"}\n'
3697 $ hg log -R a -r 8 -T '{"{"{rev}:{node|short}"}"}\n'
3697 8:95c24699272e
3698 8:95c24699272e
3698 $ hg log -R a -r 8 -T '{"{"\{{rev}} \"{node|short}\""}"}\n'
3699 $ hg log -R a -r 8 -T '{"{"\{{rev}} \"{node|short}\""}"}\n'
3699 {8} "95c24699272e"
3700 {8} "95c24699272e"
3700
3701
3701 Test recursive evaluation:
3702 Test recursive evaluation:
3702
3703
3703 $ hg init r
3704 $ hg init r
3704 $ cd r
3705 $ cd r
3705 $ echo a > a
3706 $ echo a > a
3706 $ hg ci -Am '{rev}'
3707 $ hg ci -Am '{rev}'
3707 adding a
3708 adding a
3708 $ hg log -r 0 --template '{if(rev, desc)}\n'
3709 $ hg log -r 0 --template '{if(rev, desc)}\n'
3709 {rev}
3710 {rev}
3710 $ hg log -r 0 --template '{if(rev, "{author} {rev}")}\n'
3711 $ hg log -r 0 --template '{if(rev, "{author} {rev}")}\n'
3711 test 0
3712 test 0
3712
3713
3713 $ hg branch -q 'text.{rev}'
3714 $ hg branch -q 'text.{rev}'
3714 $ echo aa >> aa
3715 $ echo aa >> aa
3715 $ hg ci -u '{node|short}' -m 'desc to be wrapped desc to be wrapped'
3716 $ hg ci -u '{node|short}' -m 'desc to be wrapped desc to be wrapped'
3716
3717
3717 $ hg log -l1 --template '{fill(desc, "20", author, branch)}'
3718 $ hg log -l1 --template '{fill(desc, "20", author, branch)}'
3718 {node|short}desc to
3719 {node|short}desc to
3719 text.{rev}be wrapped
3720 text.{rev}be wrapped
3720 text.{rev}desc to be
3721 text.{rev}desc to be
3721 text.{rev}wrapped (no-eol)
3722 text.{rev}wrapped (no-eol)
3722 $ hg log -l1 --template '{fill(desc, "20", "{node|short}:", "text.{rev}:")}'
3723 $ hg log -l1 --template '{fill(desc, "20", "{node|short}:", "text.{rev}:")}'
3723 bcc7ff960b8e:desc to
3724 bcc7ff960b8e:desc to
3724 text.1:be wrapped
3725 text.1:be wrapped
3725 text.1:desc to be
3726 text.1:desc to be
3726 text.1:wrapped (no-eol)
3727 text.1:wrapped (no-eol)
3727 $ hg log -l1 -T '{fill(desc, date, "", "")}\n'
3728 $ hg log -l1 -T '{fill(desc, date, "", "")}\n'
3728 hg: parse error: fill expects an integer width
3729 hg: parse error: fill expects an integer width
3729 [255]
3730 [255]
3730
3731
3731 $ COLUMNS=25 hg log -l1 --template '{fill(desc, termwidth, "{node|short}:", "termwidth.{rev}:")}'
3732 $ COLUMNS=25 hg log -l1 --template '{fill(desc, termwidth, "{node|short}:", "termwidth.{rev}:")}'
3732 bcc7ff960b8e:desc to be
3733 bcc7ff960b8e:desc to be
3733 termwidth.1:wrapped desc
3734 termwidth.1:wrapped desc
3734 termwidth.1:to be wrapped (no-eol)
3735 termwidth.1:to be wrapped (no-eol)
3735
3736
3736 $ hg log -l 1 --template '{sub(r"[0-9]", "-", author)}'
3737 $ hg log -l 1 --template '{sub(r"[0-9]", "-", author)}'
3737 {node|short} (no-eol)
3738 {node|short} (no-eol)
3738 $ hg log -l 1 --template '{sub(r"[0-9]", "-", "{node|short}")}'
3739 $ hg log -l 1 --template '{sub(r"[0-9]", "-", "{node|short}")}'
3739 bcc-ff---b-e (no-eol)
3740 bcc-ff---b-e (no-eol)
3740
3741
3741 $ cat >> .hg/hgrc <<EOF
3742 $ cat >> .hg/hgrc <<EOF
3742 > [extensions]
3743 > [extensions]
3743 > color=
3744 > color=
3744 > [color]
3745 > [color]
3745 > mode=ansi
3746 > mode=ansi
3746 > text.{rev} = red
3747 > text.{rev} = red
3747 > text.1 = green
3748 > text.1 = green
3748 > EOF
3749 > EOF
3749 $ hg log --color=always -l 1 --template '{label(branch, "text\n")}'
3750 $ hg log --color=always -l 1 --template '{label(branch, "text\n")}'
3750 \x1b[0;31mtext\x1b[0m (esc)
3751 \x1b[0;31mtext\x1b[0m (esc)
3751 $ hg log --color=always -l 1 --template '{label("text.{rev}", "text\n")}'
3752 $ hg log --color=always -l 1 --template '{label("text.{rev}", "text\n")}'
3752 \x1b[0;32mtext\x1b[0m (esc)
3753 \x1b[0;32mtext\x1b[0m (esc)
3753
3754
3754 color effect can be specified without quoting:
3755 color effect can be specified without quoting:
3755
3756
3756 $ hg log --color=always -l 1 --template '{label(red, "text\n")}'
3757 $ hg log --color=always -l 1 --template '{label(red, "text\n")}'
3757 \x1b[0;31mtext\x1b[0m (esc)
3758 \x1b[0;31mtext\x1b[0m (esc)
3758
3759
3759 color effects can be nested (issue5413)
3760 color effects can be nested (issue5413)
3760
3761
3761 $ hg debugtemplate --color=always \
3762 $ hg debugtemplate --color=always \
3762 > '{label(red, "red{label(magenta, "ma{label(cyan, "cyan")}{label(yellow, "yellow")}genta")}")}\n'
3763 > '{label(red, "red{label(magenta, "ma{label(cyan, "cyan")}{label(yellow, "yellow")}genta")}")}\n'
3763 \x1b[0;31mred\x1b[0;35mma\x1b[0;36mcyan\x1b[0m\x1b[0;31m\x1b[0;35m\x1b[0;33myellow\x1b[0m\x1b[0;31m\x1b[0;35mgenta\x1b[0m (esc)
3764 \x1b[0;31mred\x1b[0;35mma\x1b[0;36mcyan\x1b[0m\x1b[0;31m\x1b[0;35m\x1b[0;33myellow\x1b[0m\x1b[0;31m\x1b[0;35mgenta\x1b[0m (esc)
3764
3765
3765 pad() should interact well with color codes (issue5416)
3766 pad() should interact well with color codes (issue5416)
3766
3767
3767 $ hg debugtemplate --color=always \
3768 $ hg debugtemplate --color=always \
3768 > '{pad(label(red, "red"), 5, label(cyan, "-"))}\n'
3769 > '{pad(label(red, "red"), 5, label(cyan, "-"))}\n'
3769 \x1b[0;31mred\x1b[0m\x1b[0;36m-\x1b[0m\x1b[0;36m-\x1b[0m (esc)
3770 \x1b[0;31mred\x1b[0m\x1b[0;36m-\x1b[0m\x1b[0;36m-\x1b[0m (esc)
3770
3771
3771 label should be no-op if color is disabled:
3772 label should be no-op if color is disabled:
3772
3773
3773 $ hg log --color=never -l 1 --template '{label(red, "text\n")}'
3774 $ hg log --color=never -l 1 --template '{label(red, "text\n")}'
3774 text
3775 text
3775 $ hg log --config extensions.color=! -l 1 --template '{label(red, "text\n")}'
3776 $ hg log --config extensions.color=! -l 1 --template '{label(red, "text\n")}'
3776 text
3777 text
3777
3778
3778 Test branches inside if statement:
3779 Test branches inside if statement:
3779
3780
3780 $ hg log -r 0 --template '{if(branches, "yes", "no")}\n'
3781 $ hg log -r 0 --template '{if(branches, "yes", "no")}\n'
3781 no
3782 no
3782
3783
3783 Test dict constructor:
3784 Test dict constructor:
3784
3785
3785 $ hg log -r 0 -T '{dict(y=node|short, x=rev)}\n'
3786 $ hg log -r 0 -T '{dict(y=node|short, x=rev)}\n'
3786 y=f7769ec2ab97 x=0
3787 y=f7769ec2ab97 x=0
3787 $ hg log -r 0 -T '{dict(x=rev, y=node|short) % "{key}={value}\n"}'
3788 $ hg log -r 0 -T '{dict(x=rev, y=node|short) % "{key}={value}\n"}'
3788 x=0
3789 x=0
3789 y=f7769ec2ab97
3790 y=f7769ec2ab97
3790 $ hg log -r 0 -T '{dict(x=rev, y=node|short)|json}\n'
3791 $ hg log -r 0 -T '{dict(x=rev, y=node|short)|json}\n'
3791 {"x": 0, "y": "f7769ec2ab97"}
3792 {"x": 0, "y": "f7769ec2ab97"}
3792 $ hg log -r 0 -T '{dict()|json}\n'
3793 $ hg log -r 0 -T '{dict()|json}\n'
3793 {}
3794 {}
3794
3795
3795 $ hg log -r 0 -T '{dict(rev, node=node|short)}\n'
3796 $ hg log -r 0 -T '{dict(rev, node=node|short)}\n'
3796 rev=0 node=f7769ec2ab97
3797 rev=0 node=f7769ec2ab97
3797 $ hg log -r 0 -T '{dict(rev, node|short)}\n'
3798 $ hg log -r 0 -T '{dict(rev, node|short)}\n'
3798 rev=0 node=f7769ec2ab97
3799 rev=0 node=f7769ec2ab97
3799
3800
3800 $ hg log -r 0 -T '{dict(rev, rev=rev)}\n'
3801 $ hg log -r 0 -T '{dict(rev, rev=rev)}\n'
3801 hg: parse error: duplicated dict key 'rev' inferred
3802 hg: parse error: duplicated dict key 'rev' inferred
3802 [255]
3803 [255]
3803 $ hg log -r 0 -T '{dict(node, node|short)}\n'
3804 $ hg log -r 0 -T '{dict(node, node|short)}\n'
3804 hg: parse error: duplicated dict key 'node' inferred
3805 hg: parse error: duplicated dict key 'node' inferred
3805 [255]
3806 [255]
3806 $ hg log -r 0 -T '{dict(1 + 2)}'
3807 $ hg log -r 0 -T '{dict(1 + 2)}'
3807 hg: parse error: dict key cannot be inferred
3808 hg: parse error: dict key cannot be inferred
3808 [255]
3809 [255]
3809
3810
3810 $ hg log -r 0 -T '{dict(x=rev, x=node)}'
3811 $ hg log -r 0 -T '{dict(x=rev, x=node)}'
3811 hg: parse error: dict got multiple values for keyword argument 'x'
3812 hg: parse error: dict got multiple values for keyword argument 'x'
3812 [255]
3813 [255]
3813
3814
3814 Test get function:
3815 Test get function:
3815
3816
3816 $ hg log -r 0 --template '{get(extras, "branch")}\n'
3817 $ hg log -r 0 --template '{get(extras, "branch")}\n'
3817 default
3818 default
3818 $ hg log -r 0 --template '{get(extras, "br{"anch"}")}\n'
3819 $ hg log -r 0 --template '{get(extras, "br{"anch"}")}\n'
3819 default
3820 default
3820 $ hg log -r 0 --template '{get(files, "should_fail")}\n'
3821 $ hg log -r 0 --template '{get(files, "should_fail")}\n'
3821 hg: parse error: get() expects a dict as first argument
3822 hg: parse error: get() expects a dict as first argument
3822 [255]
3823 [255]
3823
3824
3824 Test json filter applied to hybrid object:
3825 Test json filter applied to hybrid object:
3825
3826
3826 $ hg log -r0 -T '{files|json}\n'
3827 $ hg log -r0 -T '{files|json}\n'
3827 ["a"]
3828 ["a"]
3828 $ hg log -r0 -T '{extras|json}\n'
3829 $ hg log -r0 -T '{extras|json}\n'
3829 {"branch": "default"}
3830 {"branch": "default"}
3830
3831
3831 Test localdate(date, tz) function:
3832 Test localdate(date, tz) function:
3832
3833
3833 $ TZ=JST-09 hg log -r0 -T '{date|localdate|isodate}\n'
3834 $ TZ=JST-09 hg log -r0 -T '{date|localdate|isodate}\n'
3834 1970-01-01 09:00 +0900
3835 1970-01-01 09:00 +0900
3835 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "UTC")|isodate}\n'
3836 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "UTC")|isodate}\n'
3836 1970-01-01 00:00 +0000
3837 1970-01-01 00:00 +0000
3837 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "blahUTC")|isodate}\n'
3838 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "blahUTC")|isodate}\n'
3838 hg: parse error: localdate expects a timezone
3839 hg: parse error: localdate expects a timezone
3839 [255]
3840 [255]
3840 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "+0200")|isodate}\n'
3841 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "+0200")|isodate}\n'
3841 1970-01-01 02:00 +0200
3842 1970-01-01 02:00 +0200
3842 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "0")|isodate}\n'
3843 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "0")|isodate}\n'
3843 1970-01-01 00:00 +0000
3844 1970-01-01 00:00 +0000
3844 $ TZ=JST-09 hg log -r0 -T '{localdate(date, 0)|isodate}\n'
3845 $ TZ=JST-09 hg log -r0 -T '{localdate(date, 0)|isodate}\n'
3845 1970-01-01 00:00 +0000
3846 1970-01-01 00:00 +0000
3846 $ hg log -r0 -T '{localdate(date, "invalid")|isodate}\n'
3847 $ hg log -r0 -T '{localdate(date, "invalid")|isodate}\n'
3847 hg: parse error: localdate expects a timezone
3848 hg: parse error: localdate expects a timezone
3848 [255]
3849 [255]
3849 $ hg log -r0 -T '{localdate(date, date)|isodate}\n'
3850 $ hg log -r0 -T '{localdate(date, date)|isodate}\n'
3850 hg: parse error: localdate expects a timezone
3851 hg: parse error: localdate expects a timezone
3851 [255]
3852 [255]
3852
3853
3853 Test shortest(node) function:
3854 Test shortest(node) function:
3854
3855
3855 $ echo b > b
3856 $ echo b > b
3856 $ hg ci -qAm b
3857 $ hg ci -qAm b
3857 $ hg log --template '{shortest(node)}\n'
3858 $ hg log --template '{shortest(node)}\n'
3858 e777
3859 e777
3859 bcc7
3860 bcc7
3860 f776
3861 f776
3861 $ hg log --template '{shortest(node, 10)}\n'
3862 $ hg log --template '{shortest(node, 10)}\n'
3862 e777603221
3863 e777603221
3863 bcc7ff960b
3864 bcc7ff960b
3864 f7769ec2ab
3865 f7769ec2ab
3865 $ hg log --template '{node|shortest}\n' -l1
3866 $ hg log --template '{node|shortest}\n' -l1
3866 e777
3867 e777
3867
3868
3868 $ hg log -r 0 -T '{shortest(node, "1{"0"}")}\n'
3869 $ hg log -r 0 -T '{shortest(node, "1{"0"}")}\n'
3869 f7769ec2ab
3870 f7769ec2ab
3870 $ hg log -r 0 -T '{shortest(node, "not an int")}\n'
3871 $ hg log -r 0 -T '{shortest(node, "not an int")}\n'
3871 hg: parse error: shortest() expects an integer minlength
3872 hg: parse error: shortest() expects an integer minlength
3872 [255]
3873 [255]
3873
3874
3874 $ hg log -r 'wdir()' -T '{node|shortest}\n'
3875 $ hg log -r 'wdir()' -T '{node|shortest}\n'
3875 ffff
3876 ffff
3876
3877
3877 $ cd ..
3878 $ cd ..
3878
3879
3879 Test shortest(node) with the repo having short hash collision:
3880 Test shortest(node) with the repo having short hash collision:
3880
3881
3881 $ hg init hashcollision
3882 $ hg init hashcollision
3882 $ cd hashcollision
3883 $ cd hashcollision
3883 $ cat <<EOF >> .hg/hgrc
3884 $ cat <<EOF >> .hg/hgrc
3884 > [experimental]
3885 > [experimental]
3885 > evolution.createmarkers=True
3886 > evolution.createmarkers=True
3886 > EOF
3887 > EOF
3887 $ echo 0 > a
3888 $ echo 0 > a
3888 $ hg ci -qAm 0
3889 $ hg ci -qAm 0
3889 $ for i in 17 129 248 242 480 580 617 1057 2857 4025; do
3890 $ for i in 17 129 248 242 480 580 617 1057 2857 4025; do
3890 > hg up -q 0
3891 > hg up -q 0
3891 > echo $i > a
3892 > echo $i > a
3892 > hg ci -qm $i
3893 > hg ci -qm $i
3893 > done
3894 > done
3894 $ hg up -q null
3895 $ hg up -q null
3895 $ hg log -r0: -T '{rev}:{node}\n'
3896 $ hg log -r0: -T '{rev}:{node}\n'
3896 0:b4e73ffab476aa0ee32ed81ca51e07169844bc6a
3897 0:b4e73ffab476aa0ee32ed81ca51e07169844bc6a
3897 1:11424df6dc1dd4ea255eae2b58eaca7831973bbc
3898 1:11424df6dc1dd4ea255eae2b58eaca7831973bbc
3898 2:11407b3f1b9c3e76a79c1ec5373924df096f0499
3899 2:11407b3f1b9c3e76a79c1ec5373924df096f0499
3899 3:11dd92fe0f39dfdaacdaa5f3997edc533875cfc4
3900 3:11dd92fe0f39dfdaacdaa5f3997edc533875cfc4
3900 4:10776689e627b465361ad5c296a20a487e153ca4
3901 4:10776689e627b465361ad5c296a20a487e153ca4
3901 5:a00be79088084cb3aff086ab799f8790e01a976b
3902 5:a00be79088084cb3aff086ab799f8790e01a976b
3902 6:a0b0acd79b4498d0052993d35a6a748dd51d13e6
3903 6:a0b0acd79b4498d0052993d35a6a748dd51d13e6
3903 7:a0457b3450b8e1b778f1163b31a435802987fe5d
3904 7:a0457b3450b8e1b778f1163b31a435802987fe5d
3904 8:c56256a09cd28e5764f32e8e2810d0f01e2e357a
3905 8:c56256a09cd28e5764f32e8e2810d0f01e2e357a
3905 9:c5623987d205cd6d9d8389bfc40fff9dbb670b48
3906 9:c5623987d205cd6d9d8389bfc40fff9dbb670b48
3906 10:c562ddd9c94164376c20b86b0b4991636a3bf84f
3907 10:c562ddd9c94164376c20b86b0b4991636a3bf84f
3907 $ hg debugobsolete a00be79088084cb3aff086ab799f8790e01a976b
3908 $ hg debugobsolete a00be79088084cb3aff086ab799f8790e01a976b
3908 obsoleted 1 changesets
3909 obsoleted 1 changesets
3909 $ hg debugobsolete c5623987d205cd6d9d8389bfc40fff9dbb670b48
3910 $ hg debugobsolete c5623987d205cd6d9d8389bfc40fff9dbb670b48
3910 obsoleted 1 changesets
3911 obsoleted 1 changesets
3911 $ hg debugobsolete c562ddd9c94164376c20b86b0b4991636a3bf84f
3912 $ hg debugobsolete c562ddd9c94164376c20b86b0b4991636a3bf84f
3912 obsoleted 1 changesets
3913 obsoleted 1 changesets
3913
3914
3914 nodes starting with '11' (we don't have the revision number '11' though)
3915 nodes starting with '11' (we don't have the revision number '11' though)
3915
3916
3916 $ hg log -r 1:3 -T '{rev}:{shortest(node, 0)}\n'
3917 $ hg log -r 1:3 -T '{rev}:{shortest(node, 0)}\n'
3917 1:1142
3918 1:1142
3918 2:1140
3919 2:1140
3919 3:11d
3920 3:11d
3920
3921
3921 '5:a00' is hidden, but still we have two nodes starting with 'a0'
3922 '5:a00' is hidden, but still we have two nodes starting with 'a0'
3922
3923
3923 $ hg log -r 6:7 -T '{rev}:{shortest(node, 0)}\n'
3924 $ hg log -r 6:7 -T '{rev}:{shortest(node, 0)}\n'
3924 6:a0b
3925 6:a0b
3925 7:a04
3926 7:a04
3926
3927
3927 node '10' conflicts with the revision number '10' even if it is hidden
3928 node '10' conflicts with the revision number '10' even if it is hidden
3928 (we could exclude hidden revision numbers, but currently we don't)
3929 (we could exclude hidden revision numbers, but currently we don't)
3929
3930
3930 $ hg log -r 4 -T '{rev}:{shortest(node, 0)}\n'
3931 $ hg log -r 4 -T '{rev}:{shortest(node, 0)}\n'
3931 4:107
3932 4:107
3932 $ hg log -r 4 -T '{rev}:{shortest(node, 0)}\n' --hidden
3933 $ hg log -r 4 -T '{rev}:{shortest(node, 0)}\n' --hidden
3933 4:107
3934 4:107
3934
3935
3935 node 'c562' should be unique if the other 'c562' nodes are hidden
3936 node 'c562' should be unique if the other 'c562' nodes are hidden
3936 (but we don't try the slow path to filter out hidden nodes for now)
3937 (but we don't try the slow path to filter out hidden nodes for now)
3937
3938
3938 $ hg log -r 8 -T '{rev}:{node|shortest}\n'
3939 $ hg log -r 8 -T '{rev}:{node|shortest}\n'
3939 8:c5625
3940 8:c5625
3940 $ hg log -r 8:10 -T '{rev}:{node|shortest}\n' --hidden
3941 $ hg log -r 8:10 -T '{rev}:{node|shortest}\n' --hidden
3941 8:c5625
3942 8:c5625
3942 9:c5623
3943 9:c5623
3943 10:c562d
3944 10:c562d
3944
3945
3945 $ cd ..
3946 $ cd ..
3946
3947
3947 Test pad function
3948 Test pad function
3948
3949
3949 $ cd r
3950 $ cd r
3950
3951
3951 $ hg log --template '{pad(rev, 20)} {author|user}\n'
3952 $ hg log --template '{pad(rev, 20)} {author|user}\n'
3952 2 test
3953 2 test
3953 1 {node|short}
3954 1 {node|short}
3954 0 test
3955 0 test
3955
3956
3956 $ hg log --template '{pad(rev, 20, " ", True)} {author|user}\n'
3957 $ hg log --template '{pad(rev, 20, " ", True)} {author|user}\n'
3957 2 test
3958 2 test
3958 1 {node|short}
3959 1 {node|short}
3959 0 test
3960 0 test
3960
3961
3961 $ hg log --template '{pad(rev, 20, "-", False)} {author|user}\n'
3962 $ hg log --template '{pad(rev, 20, "-", False)} {author|user}\n'
3962 2------------------- test
3963 2------------------- test
3963 1------------------- {node|short}
3964 1------------------- {node|short}
3964 0------------------- test
3965 0------------------- test
3965
3966
3966 Test template string in pad function
3967 Test template string in pad function
3967
3968
3968 $ hg log -r 0 -T '{pad("\{{rev}}", 10)} {author|user}\n'
3969 $ hg log -r 0 -T '{pad("\{{rev}}", 10)} {author|user}\n'
3969 {0} test
3970 {0} test
3970
3971
3971 $ hg log -r 0 -T '{pad(r"\{rev}", 10)} {author|user}\n'
3972 $ hg log -r 0 -T '{pad(r"\{rev}", 10)} {author|user}\n'
3972 \{rev} test
3973 \{rev} test
3973
3974
3974 Test width argument passed to pad function
3975 Test width argument passed to pad function
3975
3976
3976 $ hg log -r 0 -T '{pad(rev, "1{"0"}")} {author|user}\n'
3977 $ hg log -r 0 -T '{pad(rev, "1{"0"}")} {author|user}\n'
3977 0 test
3978 0 test
3978 $ hg log -r 0 -T '{pad(rev, "not an int")}\n'
3979 $ hg log -r 0 -T '{pad(rev, "not an int")}\n'
3979 hg: parse error: pad() expects an integer width
3980 hg: parse error: pad() expects an integer width
3980 [255]
3981 [255]
3981
3982
3982 Test invalid fillchar passed to pad function
3983 Test invalid fillchar passed to pad function
3983
3984
3984 $ hg log -r 0 -T '{pad(rev, 10, "")}\n'
3985 $ hg log -r 0 -T '{pad(rev, 10, "")}\n'
3985 hg: parse error: pad() expects a single fill character
3986 hg: parse error: pad() expects a single fill character
3986 [255]
3987 [255]
3987 $ hg log -r 0 -T '{pad(rev, 10, "--")}\n'
3988 $ hg log -r 0 -T '{pad(rev, 10, "--")}\n'
3988 hg: parse error: pad() expects a single fill character
3989 hg: parse error: pad() expects a single fill character
3989 [255]
3990 [255]
3990
3991
3991 Test boolean argument passed to pad function
3992 Test boolean argument passed to pad function
3992
3993
3993 no crash
3994 no crash
3994
3995
3995 $ hg log -r 0 -T '{pad(rev, 10, "-", "f{"oo"}")}\n'
3996 $ hg log -r 0 -T '{pad(rev, 10, "-", "f{"oo"}")}\n'
3996 ---------0
3997 ---------0
3997
3998
3998 string/literal
3999 string/literal
3999
4000
4000 $ hg log -r 0 -T '{pad(rev, 10, "-", "false")}\n'
4001 $ hg log -r 0 -T '{pad(rev, 10, "-", "false")}\n'
4001 ---------0
4002 ---------0
4002 $ hg log -r 0 -T '{pad(rev, 10, "-", false)}\n'
4003 $ hg log -r 0 -T '{pad(rev, 10, "-", false)}\n'
4003 0---------
4004 0---------
4004 $ hg log -r 0 -T '{pad(rev, 10, "-", "")}\n'
4005 $ hg log -r 0 -T '{pad(rev, 10, "-", "")}\n'
4005 0---------
4006 0---------
4006
4007
4007 unknown keyword is evaluated to ''
4008 unknown keyword is evaluated to ''
4008
4009
4009 $ hg log -r 0 -T '{pad(rev, 10, "-", unknownkeyword)}\n'
4010 $ hg log -r 0 -T '{pad(rev, 10, "-", unknownkeyword)}\n'
4010 0---------
4011 0---------
4011
4012
4012 Test separate function
4013 Test separate function
4013
4014
4014 $ hg log -r 0 -T '{separate("-", "", "a", "b", "", "", "c", "")}\n'
4015 $ hg log -r 0 -T '{separate("-", "", "a", "b", "", "", "c", "")}\n'
4015 a-b-c
4016 a-b-c
4016 $ hg log -r 0 -T '{separate(" ", "{rev}:{node|short}", author|user, branch)}\n'
4017 $ hg log -r 0 -T '{separate(" ", "{rev}:{node|short}", author|user, branch)}\n'
4017 0:f7769ec2ab97 test default
4018 0:f7769ec2ab97 test default
4018 $ hg log -r 0 --color=always -T '{separate(" ", "a", label(red, "b"), "c", label(red, ""), "d")}\n'
4019 $ hg log -r 0 --color=always -T '{separate(" ", "a", label(red, "b"), "c", label(red, ""), "d")}\n'
4019 a \x1b[0;31mb\x1b[0m c d (esc)
4020 a \x1b[0;31mb\x1b[0m c d (esc)
4020
4021
4021 Test boolean expression/literal passed to if function
4022 Test boolean expression/literal passed to if function
4022
4023
4023 $ hg log -r 0 -T '{if(rev, "rev 0 is True")}\n'
4024 $ hg log -r 0 -T '{if(rev, "rev 0 is True")}\n'
4024 rev 0 is True
4025 rev 0 is True
4025 $ hg log -r 0 -T '{if(0, "literal 0 is True as well")}\n'
4026 $ hg log -r 0 -T '{if(0, "literal 0 is True as well")}\n'
4026 literal 0 is True as well
4027 literal 0 is True as well
4027 $ hg log -r 0 -T '{if("", "", "empty string is False")}\n'
4028 $ hg log -r 0 -T '{if("", "", "empty string is False")}\n'
4028 empty string is False
4029 empty string is False
4029 $ hg log -r 0 -T '{if(revset(r"0 - 0"), "", "empty list is False")}\n'
4030 $ hg log -r 0 -T '{if(revset(r"0 - 0"), "", "empty list is False")}\n'
4030 empty list is False
4031 empty list is False
4031 $ hg log -r 0 -T '{if(true, "true is True")}\n'
4032 $ hg log -r 0 -T '{if(true, "true is True")}\n'
4032 true is True
4033 true is True
4033 $ hg log -r 0 -T '{if(false, "", "false is False")}\n'
4034 $ hg log -r 0 -T '{if(false, "", "false is False")}\n'
4034 false is False
4035 false is False
4035 $ hg log -r 0 -T '{if("false", "non-empty string is True")}\n'
4036 $ hg log -r 0 -T '{if("false", "non-empty string is True")}\n'
4036 non-empty string is True
4037 non-empty string is True
4037
4038
4038 Test ifcontains function
4039 Test ifcontains function
4039
4040
4040 $ hg log --template '{rev} {ifcontains(rev, "2 two 0", "is in the string", "is not")}\n'
4041 $ hg log --template '{rev} {ifcontains(rev, "2 two 0", "is in the string", "is not")}\n'
4041 2 is in the string
4042 2 is in the string
4042 1 is not
4043 1 is not
4043 0 is in the string
4044 0 is in the string
4044
4045
4045 $ hg log -T '{rev} {ifcontains(rev, "2 two{" 0"}", "is in the string", "is not")}\n'
4046 $ hg log -T '{rev} {ifcontains(rev, "2 two{" 0"}", "is in the string", "is not")}\n'
4046 2 is in the string
4047 2 is in the string
4047 1 is not
4048 1 is not
4048 0 is in the string
4049 0 is in the string
4049
4050
4050 $ hg log --template '{rev} {ifcontains("a", file_adds, "added a", "did not add a")}\n'
4051 $ hg log --template '{rev} {ifcontains("a", file_adds, "added a", "did not add a")}\n'
4051 2 did not add a
4052 2 did not add a
4052 1 did not add a
4053 1 did not add a
4053 0 added a
4054 0 added a
4054
4055
4055 $ hg log --debug -T '{rev}{ifcontains(1, parents, " is parent of 1")}\n'
4056 $ hg log --debug -T '{rev}{ifcontains(1, parents, " is parent of 1")}\n'
4056 2 is parent of 1
4057 2 is parent of 1
4057 1
4058 1
4058 0
4059 0
4059
4060
4060 Test revset function
4061 Test revset function
4061
4062
4062 $ hg log --template '{rev} {ifcontains(rev, revset("."), "current rev", "not current rev")}\n'
4063 $ hg log --template '{rev} {ifcontains(rev, revset("."), "current rev", "not current rev")}\n'
4063 2 current rev
4064 2 current rev
4064 1 not current rev
4065 1 not current rev
4065 0 not current rev
4066 0 not current rev
4066
4067
4067 $ hg log --template '{rev} {ifcontains(rev, revset(". + .^"), "match rev", "not match rev")}\n'
4068 $ hg log --template '{rev} {ifcontains(rev, revset(". + .^"), "match rev", "not match rev")}\n'
4068 2 match rev
4069 2 match rev
4069 1 match rev
4070 1 match rev
4070 0 not match rev
4071 0 not match rev
4071
4072
4072 $ hg log -T '{ifcontains(desc, revset(":"), "", "type not match")}\n' -l1
4073 $ hg log -T '{ifcontains(desc, revset(":"), "", "type not match")}\n' -l1
4073 type not match
4074 type not match
4074
4075
4075 $ hg log --template '{rev} Parents: {revset("parents(%s)", rev)}\n'
4076 $ hg log --template '{rev} Parents: {revset("parents(%s)", rev)}\n'
4076 2 Parents: 1
4077 2 Parents: 1
4077 1 Parents: 0
4078 1 Parents: 0
4078 0 Parents:
4079 0 Parents:
4079
4080
4080 $ cat >> .hg/hgrc <<EOF
4081 $ cat >> .hg/hgrc <<EOF
4081 > [revsetalias]
4082 > [revsetalias]
4082 > myparents(\$1) = parents(\$1)
4083 > myparents(\$1) = parents(\$1)
4083 > EOF
4084 > EOF
4084 $ hg log --template '{rev} Parents: {revset("myparents(%s)", rev)}\n'
4085 $ hg log --template '{rev} Parents: {revset("myparents(%s)", rev)}\n'
4085 2 Parents: 1
4086 2 Parents: 1
4086 1 Parents: 0
4087 1 Parents: 0
4087 0 Parents:
4088 0 Parents:
4088
4089
4089 $ hg log --template 'Rev: {rev}\n{revset("::%s", rev) % "Ancestor: {revision}\n"}\n'
4090 $ hg log --template 'Rev: {rev}\n{revset("::%s", rev) % "Ancestor: {revision}\n"}\n'
4090 Rev: 2
4091 Rev: 2
4091 Ancestor: 0
4092 Ancestor: 0
4092 Ancestor: 1
4093 Ancestor: 1
4093 Ancestor: 2
4094 Ancestor: 2
4094
4095
4095 Rev: 1
4096 Rev: 1
4096 Ancestor: 0
4097 Ancestor: 0
4097 Ancestor: 1
4098 Ancestor: 1
4098
4099
4099 Rev: 0
4100 Rev: 0
4100 Ancestor: 0
4101 Ancestor: 0
4101
4102
4102 $ hg log --template '{revset("TIP"|lower)}\n' -l1
4103 $ hg log --template '{revset("TIP"|lower)}\n' -l1
4103 2
4104 2
4104
4105
4105 $ hg log -T '{revset("%s", "t{"ip"}")}\n' -l1
4106 $ hg log -T '{revset("%s", "t{"ip"}")}\n' -l1
4106 2
4107 2
4107
4108
4108 a list template is evaluated for each item of revset/parents
4109 a list template is evaluated for each item of revset/parents
4109
4110
4110 $ hg log -T '{rev} p: {revset("p1(%s)", rev) % "{rev}:{node|short}"}\n'
4111 $ hg log -T '{rev} p: {revset("p1(%s)", rev) % "{rev}:{node|short}"}\n'
4111 2 p: 1:bcc7ff960b8e
4112 2 p: 1:bcc7ff960b8e
4112 1 p: 0:f7769ec2ab97
4113 1 p: 0:f7769ec2ab97
4113 0 p:
4114 0 p:
4114
4115
4115 $ hg log --debug -T '{rev} p:{parents % " {rev}:{node|short}"}\n'
4116 $ hg log --debug -T '{rev} p:{parents % " {rev}:{node|short}"}\n'
4116 2 p: 1:bcc7ff960b8e -1:000000000000
4117 2 p: 1:bcc7ff960b8e -1:000000000000
4117 1 p: 0:f7769ec2ab97 -1:000000000000
4118 1 p: 0:f7769ec2ab97 -1:000000000000
4118 0 p: -1:000000000000 -1:000000000000
4119 0 p: -1:000000000000 -1:000000000000
4119
4120
4120 therefore, 'revcache' should be recreated for each rev
4121 therefore, 'revcache' should be recreated for each rev
4121
4122
4122 $ hg log -T '{rev} {file_adds}\np {revset("p1(%s)", rev) % "{file_adds}"}\n'
4123 $ hg log -T '{rev} {file_adds}\np {revset("p1(%s)", rev) % "{file_adds}"}\n'
4123 2 aa b
4124 2 aa b
4124 p
4125 p
4125 1
4126 1
4126 p a
4127 p a
4127 0 a
4128 0 a
4128 p
4129 p
4129
4130
4130 $ hg log --debug -T '{rev} {file_adds}\np {parents % "{file_adds}"}\n'
4131 $ hg log --debug -T '{rev} {file_adds}\np {parents % "{file_adds}"}\n'
4131 2 aa b
4132 2 aa b
4132 p
4133 p
4133 1
4134 1
4134 p a
4135 p a
4135 0 a
4136 0 a
4136 p
4137 p
4137
4138
4138 a revset item must be evaluated as an integer revision, not an offset from tip
4139 a revset item must be evaluated as an integer revision, not an offset from tip
4139
4140
4140 $ hg log -l 1 -T '{revset("null") % "{rev}:{node|short}"}\n'
4141 $ hg log -l 1 -T '{revset("null") % "{rev}:{node|short}"}\n'
4141 -1:000000000000
4142 -1:000000000000
4142 $ hg log -l 1 -T '{revset("%s", "null") % "{rev}:{node|short}"}\n'
4143 $ hg log -l 1 -T '{revset("%s", "null") % "{rev}:{node|short}"}\n'
4143 -1:000000000000
4144 -1:000000000000
4144
4145
4145 join() should pick '{rev}' from revset items:
4146 join() should pick '{rev}' from revset items:
4146
4147
4147 $ hg log -R ../a -T '{join(revset("parents(%d)", rev), ", ")}\n' -r6
4148 $ hg log -R ../a -T '{join(revset("parents(%d)", rev), ", ")}\n' -r6
4148 4, 5
4149 4, 5
4149
4150
4150 on the other hand, parents are formatted as '{rev}:{node|formatnode}' by
4151 on the other hand, parents are formatted as '{rev}:{node|formatnode}' by
4151 default. join() should agree with the default formatting:
4152 default. join() should agree with the default formatting:
4152
4153
4153 $ hg log -R ../a -T '{join(parents, ", ")}\n' -r6
4154 $ hg log -R ../a -T '{join(parents, ", ")}\n' -r6
4154 5:13207e5a10d9, 4:bbe44766e73d
4155 5:13207e5a10d9, 4:bbe44766e73d
4155
4156
4156 $ hg log -R ../a -T '{join(parents, ",\n")}\n' -r6 --debug
4157 $ hg log -R ../a -T '{join(parents, ",\n")}\n' -r6 --debug
4157 5:13207e5a10d9fd28ec424934298e176197f2c67f,
4158 5:13207e5a10d9fd28ec424934298e176197f2c67f,
4158 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
4159 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
4159
4160
4160 Invalid arguments passed to revset()
4161 Invalid arguments passed to revset()
4161
4162
4162 $ hg log -T '{revset("%whatever", 0)}\n'
4163 $ hg log -T '{revset("%whatever", 0)}\n'
4163 hg: parse error: unexpected revspec format character w
4164 hg: parse error: unexpected revspec format character w
4164 [255]
4165 [255]
4165 $ hg log -T '{revset("%lwhatever", files)}\n'
4166 $ hg log -T '{revset("%lwhatever", files)}\n'
4166 hg: parse error: unexpected revspec format character w
4167 hg: parse error: unexpected revspec format character w
4167 [255]
4168 [255]
4168 $ hg log -T '{revset("%s %s", 0)}\n'
4169 $ hg log -T '{revset("%s %s", 0)}\n'
4169 hg: parse error: missing argument for revspec
4170 hg: parse error: missing argument for revspec
4170 [255]
4171 [255]
4171 $ hg log -T '{revset("", 0)}\n'
4172 $ hg log -T '{revset("", 0)}\n'
4172 hg: parse error: too many revspec arguments specified
4173 hg: parse error: too many revspec arguments specified
4173 [255]
4174 [255]
4174 $ hg log -T '{revset("%s", 0, 1)}\n'
4175 $ hg log -T '{revset("%s", 0, 1)}\n'
4175 hg: parse error: too many revspec arguments specified
4176 hg: parse error: too many revspec arguments specified
4176 [255]
4177 [255]
4177 $ hg log -T '{revset("%", 0)}\n'
4178 $ hg log -T '{revset("%", 0)}\n'
4178 hg: parse error: incomplete revspec format character
4179 hg: parse error: incomplete revspec format character
4179 [255]
4180 [255]
4180 $ hg log -T '{revset("%l", 0)}\n'
4181 $ hg log -T '{revset("%l", 0)}\n'
4181 hg: parse error: incomplete revspec format character
4182 hg: parse error: incomplete revspec format character
4182 [255]
4183 [255]
4183 $ hg log -T '{revset("%d", 'foo')}\n'
4184 $ hg log -T '{revset("%d", 'foo')}\n'
4184 hg: parse error: invalid argument for revspec
4185 hg: parse error: invalid argument for revspec
4185 [255]
4186 [255]
4186 $ hg log -T '{revset("%ld", files)}\n'
4187 $ hg log -T '{revset("%ld", files)}\n'
4187 hg: parse error: invalid argument for revspec
4188 hg: parse error: invalid argument for revspec
4188 [255]
4189 [255]
4189 $ hg log -T '{revset("%ls", 0)}\n'
4190 $ hg log -T '{revset("%ls", 0)}\n'
4190 hg: parse error: invalid argument for revspec
4191 hg: parse error: invalid argument for revspec
4191 [255]
4192 [255]
4192 $ hg log -T '{revset("%b", 'foo')}\n'
4193 $ hg log -T '{revset("%b", 'foo')}\n'
4193 hg: parse error: invalid argument for revspec
4194 hg: parse error: invalid argument for revspec
4194 [255]
4195 [255]
4195 $ hg log -T '{revset("%lb", files)}\n'
4196 $ hg log -T '{revset("%lb", files)}\n'
4196 hg: parse error: invalid argument for revspec
4197 hg: parse error: invalid argument for revspec
4197 [255]
4198 [255]
4198 $ hg log -T '{revset("%r", 0)}\n'
4199 $ hg log -T '{revset("%r", 0)}\n'
4199 hg: parse error: invalid argument for revspec
4200 hg: parse error: invalid argument for revspec
4200 [255]
4201 [255]
4201
4202
4202 Test 'originalnode'
4203 Test 'originalnode'
4203
4204
4204 $ hg log -r 1 -T '{revset("null") % "{node|short} {originalnode|short}"}\n'
4205 $ hg log -r 1 -T '{revset("null") % "{node|short} {originalnode|short}"}\n'
4205 000000000000 bcc7ff960b8e
4206 000000000000 bcc7ff960b8e
4206 $ hg log -r 0 -T '{manifest % "{node} {originalnode}"}\n'
4207 $ hg log -r 0 -T '{manifest % "{node} {originalnode}"}\n'
4207 a0c8bcbbb45c63b90b70ad007bf38961f64f2af0 f7769ec2ab975ad19684098ad1ffd9b81ecc71a1
4208 a0c8bcbbb45c63b90b70ad007bf38961f64f2af0 f7769ec2ab975ad19684098ad1ffd9b81ecc71a1
4208
4209
4209 Test files function
4210 Test files function
4210
4211
4211 $ hg log -T "{rev}\n{join(files('*'), '\n')}\n"
4212 $ hg log -T "{rev}\n{join(files('*'), '\n')}\n"
4212 2
4213 2
4213 a
4214 a
4214 aa
4215 aa
4215 b
4216 b
4216 1
4217 1
4217 a
4218 a
4218 0
4219 0
4219 a
4220 a
4220
4221
4221 $ hg log -T "{rev}\n{join(files('aa'), '\n')}\n"
4222 $ hg log -T "{rev}\n{join(files('aa'), '\n')}\n"
4222 2
4223 2
4223 aa
4224 aa
4224 1
4225 1
4225
4226
4226 0
4227 0
4227
4228
4228
4229
4229 Test relpath function
4230 Test relpath function
4230
4231
4231 $ hg log -r0 -T '{files % "{file|relpath}\n"}'
4232 $ hg log -r0 -T '{files % "{file|relpath}\n"}'
4232 a
4233 a
4233 $ cd ..
4234 $ cd ..
4234 $ hg log -R r -r0 -T '{files % "{file|relpath}\n"}'
4235 $ hg log -R r -r0 -T '{files % "{file|relpath}\n"}'
4235 r/a
4236 r/a
4236 $ cd r
4237 $ cd r
4237
4238
4238 Test active bookmark templating
4239 Test active bookmark templating
4239
4240
4240 $ hg book foo
4241 $ hg book foo
4241 $ hg book bar
4242 $ hg book bar
4242 $ hg log --template "{rev} {bookmarks % '{bookmark}{ifeq(bookmark, active, \"*\")} '}\n"
4243 $ hg log --template "{rev} {bookmarks % '{bookmark}{ifeq(bookmark, active, \"*\")} '}\n"
4243 2 bar* foo
4244 2 bar* foo
4244 1
4245 1
4245 0
4246 0
4246 $ hg log --template "{rev} {activebookmark}\n"
4247 $ hg log --template "{rev} {activebookmark}\n"
4247 2 bar
4248 2 bar
4248 1
4249 1
4249 0
4250 0
4250 $ hg bookmarks --inactive bar
4251 $ hg bookmarks --inactive bar
4251 $ hg log --template "{rev} {activebookmark}\n"
4252 $ hg log --template "{rev} {activebookmark}\n"
4252 2
4253 2
4253 1
4254 1
4254 0
4255 0
4255 $ hg book -r1 baz
4256 $ hg book -r1 baz
4256 $ hg log --template "{rev} {join(bookmarks, ' ')}\n"
4257 $ hg log --template "{rev} {join(bookmarks, ' ')}\n"
4257 2 bar foo
4258 2 bar foo
4258 1 baz
4259 1 baz
4259 0
4260 0
4260 $ hg log --template "{rev} {ifcontains('foo', bookmarks, 't', 'f')}\n"
4261 $ hg log --template "{rev} {ifcontains('foo', bookmarks, 't', 'f')}\n"
4261 2 t
4262 2 t
4262 1 f
4263 1 f
4263 0 f
4264 0 f
4264
4265
4265 Test namespaces dict
4266 Test namespaces dict
4266
4267
4267 $ hg --config extensions.revnamesext=$TESTDIR/revnamesext.py log -T '{rev}\n{namespaces % " {namespace} color={colorname} builtin={builtin}\n {join(names, ",")}\n"}\n'
4268 $ hg --config extensions.revnamesext=$TESTDIR/revnamesext.py log -T '{rev}\n{namespaces % " {namespace} color={colorname} builtin={builtin}\n {join(names, ",")}\n"}\n'
4268 2
4269 2
4269 bookmarks color=bookmark builtin=True
4270 bookmarks color=bookmark builtin=True
4270 bar,foo
4271 bar,foo
4271 tags color=tag builtin=True
4272 tags color=tag builtin=True
4272 tip
4273 tip
4273 branches color=branch builtin=True
4274 branches color=branch builtin=True
4274 text.{rev}
4275 text.{rev}
4275 revnames color=revname builtin=False
4276 revnames color=revname builtin=False
4276 r2
4277 r2
4277
4278
4278 1
4279 1
4279 bookmarks color=bookmark builtin=True
4280 bookmarks color=bookmark builtin=True
4280 baz
4281 baz
4281 tags color=tag builtin=True
4282 tags color=tag builtin=True
4282
4283
4283 branches color=branch builtin=True
4284 branches color=branch builtin=True
4284 text.{rev}
4285 text.{rev}
4285 revnames color=revname builtin=False
4286 revnames color=revname builtin=False
4286 r1
4287 r1
4287
4288
4288 0
4289 0
4289 bookmarks color=bookmark builtin=True
4290 bookmarks color=bookmark builtin=True
4290
4291
4291 tags color=tag builtin=True
4292 tags color=tag builtin=True
4292
4293
4293 branches color=branch builtin=True
4294 branches color=branch builtin=True
4294 default
4295 default
4295 revnames color=revname builtin=False
4296 revnames color=revname builtin=False
4296 r0
4297 r0
4297
4298
4298 $ hg log -r2 -T '{namespaces % "{namespace}: {names}\n"}'
4299 $ hg log -r2 -T '{namespaces % "{namespace}: {names}\n"}'
4299 bookmarks: bar foo
4300 bookmarks: bar foo
4300 tags: tip
4301 tags: tip
4301 branches: text.{rev}
4302 branches: text.{rev}
4302 $ hg log -r2 -T '{namespaces % "{namespace}:\n{names % " {name}\n"}"}'
4303 $ hg log -r2 -T '{namespaces % "{namespace}:\n{names % " {name}\n"}"}'
4303 bookmarks:
4304 bookmarks:
4304 bar
4305 bar
4305 foo
4306 foo
4306 tags:
4307 tags:
4307 tip
4308 tip
4308 branches:
4309 branches:
4309 text.{rev}
4310 text.{rev}
4310 $ hg log -r2 -T '{get(namespaces, "bookmarks") % "{name}\n"}'
4311 $ hg log -r2 -T '{get(namespaces, "bookmarks") % "{name}\n"}'
4311 bar
4312 bar
4312 foo
4313 foo
4313 $ hg log -r2 -T '{namespaces.bookmarks % "{bookmark}\n"}'
4314 $ hg log -r2 -T '{namespaces.bookmarks % "{bookmark}\n"}'
4314 bar
4315 bar
4315 foo
4316 foo
4316
4317
4317 Test stringify on sub expressions
4318 Test stringify on sub expressions
4318
4319
4319 $ cd ..
4320 $ cd ..
4320 $ hg log -R a -r 8 --template '{join(files, if("1", if("1", ", ")))}\n'
4321 $ hg log -R a -r 8 --template '{join(files, if("1", if("1", ", ")))}\n'
4321 fourth, second, third
4322 fourth, second, third
4322 $ hg log -R a -r 8 --template '{strip(if("1", if("1", "-abc-")), if("1", if("1", "-")))}\n'
4323 $ hg log -R a -r 8 --template '{strip(if("1", if("1", "-abc-")), if("1", if("1", "-")))}\n'
4323 abc
4324 abc
4324
4325
4325 Test splitlines
4326 Test splitlines
4326
4327
4327 $ hg log -Gv -R a --template "{splitlines(desc) % 'foo {line}\n'}"
4328 $ hg log -Gv -R a --template "{splitlines(desc) % 'foo {line}\n'}"
4328 @ foo Modify, add, remove, rename
4329 @ foo Modify, add, remove, rename
4329 |
4330 |
4330 o foo future
4331 o foo future
4331 |
4332 |
4332 o foo third
4333 o foo third
4333 |
4334 |
4334 o foo second
4335 o foo second
4335
4336
4336 o foo merge
4337 o foo merge
4337 |\
4338 |\
4338 | o foo new head
4339 | o foo new head
4339 | |
4340 | |
4340 o | foo new branch
4341 o | foo new branch
4341 |/
4342 |/
4342 o foo no user, no domain
4343 o foo no user, no domain
4343 |
4344 |
4344 o foo no person
4345 o foo no person
4345 |
4346 |
4346 o foo other 1
4347 o foo other 1
4347 | foo other 2
4348 | foo other 2
4348 | foo
4349 | foo
4349 | foo other 3
4350 | foo other 3
4350 o foo line 1
4351 o foo line 1
4351 foo line 2
4352 foo line 2
4352
4353
4353 $ hg log -R a -r0 -T '{desc|splitlines}\n'
4354 $ hg log -R a -r0 -T '{desc|splitlines}\n'
4354 line 1 line 2
4355 line 1 line 2
4355 $ hg log -R a -r0 -T '{join(desc|splitlines, "|")}\n'
4356 $ hg log -R a -r0 -T '{join(desc|splitlines, "|")}\n'
4356 line 1|line 2
4357 line 1|line 2
4357
4358
4358 Test startswith
4359 Test startswith
4359 $ hg log -Gv -R a --template "{startswith(desc)}"
4360 $ hg log -Gv -R a --template "{startswith(desc)}"
4360 hg: parse error: startswith expects two arguments
4361 hg: parse error: startswith expects two arguments
4361 [255]
4362 [255]
4362
4363
4363 $ hg log -Gv -R a --template "{startswith('line', desc)}"
4364 $ hg log -Gv -R a --template "{startswith('line', desc)}"
4364 @
4365 @
4365 |
4366 |
4366 o
4367 o
4367 |
4368 |
4368 o
4369 o
4369 |
4370 |
4370 o
4371 o
4371
4372
4372 o
4373 o
4373 |\
4374 |\
4374 | o
4375 | o
4375 | |
4376 | |
4376 o |
4377 o |
4377 |/
4378 |/
4378 o
4379 o
4379 |
4380 |
4380 o
4381 o
4381 |
4382 |
4382 o
4383 o
4383 |
4384 |
4384 o line 1
4385 o line 1
4385 line 2
4386 line 2
4386
4387
4387 Test bad template with better error message
4388 Test bad template with better error message
4388
4389
4389 $ hg log -Gv -R a --template '{desc|user()}'
4390 $ hg log -Gv -R a --template '{desc|user()}'
4390 hg: parse error: expected a symbol, got 'func'
4391 hg: parse error: expected a symbol, got 'func'
4391 [255]
4392 [255]
4392
4393
4393 Test word function (including index out of bounds graceful failure)
4394 Test word function (including index out of bounds graceful failure)
4394
4395
4395 $ hg log -Gv -R a --template "{word('1', desc)}"
4396 $ hg log -Gv -R a --template "{word('1', desc)}"
4396 @ add,
4397 @ add,
4397 |
4398 |
4398 o
4399 o
4399 |
4400 |
4400 o
4401 o
4401 |
4402 |
4402 o
4403 o
4403
4404
4404 o
4405 o
4405 |\
4406 |\
4406 | o head
4407 | o head
4407 | |
4408 | |
4408 o | branch
4409 o | branch
4409 |/
4410 |/
4410 o user,
4411 o user,
4411 |
4412 |
4412 o person
4413 o person
4413 |
4414 |
4414 o 1
4415 o 1
4415 |
4416 |
4416 o 1
4417 o 1
4417
4418
4418
4419
4419 Test word third parameter used as splitter
4420 Test word third parameter used as splitter
4420
4421
4421 $ hg log -Gv -R a --template "{word('0', desc, 'o')}"
4422 $ hg log -Gv -R a --template "{word('0', desc, 'o')}"
4422 @ M
4423 @ M
4423 |
4424 |
4424 o future
4425 o future
4425 |
4426 |
4426 o third
4427 o third
4427 |
4428 |
4428 o sec
4429 o sec
4429
4430
4430 o merge
4431 o merge
4431 |\
4432 |\
4432 | o new head
4433 | o new head
4433 | |
4434 | |
4434 o | new branch
4435 o | new branch
4435 |/
4436 |/
4436 o n
4437 o n
4437 |
4438 |
4438 o n
4439 o n
4439 |
4440 |
4440 o
4441 o
4441 |
4442 |
4442 o line 1
4443 o line 1
4443 line 2
4444 line 2
4444
4445
4445 Test word error messages for not enough and too many arguments
4446 Test word error messages for not enough and too many arguments
4446
4447
4447 $ hg log -Gv -R a --template "{word('0')}"
4448 $ hg log -Gv -R a --template "{word('0')}"
4448 hg: parse error: word expects two or three arguments, got 1
4449 hg: parse error: word expects two or three arguments, got 1
4449 [255]
4450 [255]
4450
4451
4451 $ hg log -Gv -R a --template "{word('0', desc, 'o', 'h', 'b', 'o', 'y')}"
4452 $ hg log -Gv -R a --template "{word('0', desc, 'o', 'h', 'b', 'o', 'y')}"
4452 hg: parse error: word expects two or three arguments, got 7
4453 hg: parse error: word expects two or three arguments, got 7
4453 [255]
4454 [255]
4454
4455
4455 Test word for integer literal
4456 Test word for integer literal
4456
4457
4457 $ hg log -R a --template "{word(2, desc)}\n" -r0
4458 $ hg log -R a --template "{word(2, desc)}\n" -r0
4458 line
4459 line
4459
4460
4460 Test word for invalid numbers
4461 Test word for invalid numbers
4461
4462
4462 $ hg log -Gv -R a --template "{word('a', desc)}"
4463 $ hg log -Gv -R a --template "{word('a', desc)}"
4463 hg: parse error: word expects an integer index
4464 hg: parse error: word expects an integer index
4464 [255]
4465 [255]
4465
4466
4466 Test word for out of range
4467 Test word for out of range
4467
4468
4468 $ hg log -R a --template "{word(10000, desc)}"
4469 $ hg log -R a --template "{word(10000, desc)}"
4469 $ hg log -R a --template "{word(-10000, desc)}"
4470 $ hg log -R a --template "{word(-10000, desc)}"
4470
4471
4471 Test indent and not adding to empty lines
4472 Test indent and not adding to empty lines
4472
4473
4473 $ hg log -T "-----\n{indent(desc, '>> ', ' > ')}\n" -r 0:1 -R a
4474 $ hg log -T "-----\n{indent(desc, '>> ', ' > ')}\n" -r 0:1 -R a
4474 -----
4475 -----
4475 > line 1
4476 > line 1
4476 >> line 2
4477 >> line 2
4477 -----
4478 -----
4478 > other 1
4479 > other 1
4479 >> other 2
4480 >> other 2
4480
4481
4481 >> other 3
4482 >> other 3
4482
4483
4483 Test with non-strings like dates
4484 Test with non-strings like dates
4484
4485
4485 $ hg log -T "{indent(date, ' ')}\n" -r 2:3 -R a
4486 $ hg log -T "{indent(date, ' ')}\n" -r 2:3 -R a
4486 1200000.00
4487 1200000.00
4487 1300000.00
4488 1300000.00
4488
4489
4489 Test broken string escapes:
4490 Test broken string escapes:
4490
4491
4491 $ hg log -T "bogus\\" -R a
4492 $ hg log -T "bogus\\" -R a
4492 hg: parse error: trailing \ in string
4493 hg: parse error: trailing \ in string
4493 [255]
4494 [255]
4494 $ hg log -T "\\xy" -R a
4495 $ hg log -T "\\xy" -R a
4495 hg: parse error: invalid \x escape* (glob)
4496 hg: parse error: invalid \x escape* (glob)
4496 [255]
4497 [255]
4497
4498
4498 json filter should escape HTML tags so that the output can be embedded in hgweb:
4499 json filter should escape HTML tags so that the output can be embedded in hgweb:
4499
4500
4500 $ hg log -T "{'<foo@example.org>'|json}\n" -R a -l1
4501 $ hg log -T "{'<foo@example.org>'|json}\n" -R a -l1
4501 "\u003cfoo@example.org\u003e"
4502 "\u003cfoo@example.org\u003e"
4502
4503
4503 Templater supports aliases of symbol and func() styles:
4504 Templater supports aliases of symbol and func() styles:
4504
4505
4505 $ hg clone -q a aliases
4506 $ hg clone -q a aliases
4506 $ cd aliases
4507 $ cd aliases
4507 $ cat <<EOF >> .hg/hgrc
4508 $ cat <<EOF >> .hg/hgrc
4508 > [templatealias]
4509 > [templatealias]
4509 > r = rev
4510 > r = rev
4510 > rn = "{r}:{node|short}"
4511 > rn = "{r}:{node|short}"
4511 > status(c, files) = files % "{c} {file}\n"
4512 > status(c, files) = files % "{c} {file}\n"
4512 > utcdate(d) = localdate(d, "UTC")
4513 > utcdate(d) = localdate(d, "UTC")
4513 > EOF
4514 > EOF
4514
4515
4515 $ hg debugtemplate -vr0 '{rn} {utcdate(date)|isodate}\n'
4516 $ hg debugtemplate -vr0 '{rn} {utcdate(date)|isodate}\n'
4516 (template
4517 (template
4517 (symbol 'rn')
4518 (symbol 'rn')
4518 (string ' ')
4519 (string ' ')
4519 (|
4520 (|
4520 (func
4521 (func
4521 (symbol 'utcdate')
4522 (symbol 'utcdate')
4522 (symbol 'date'))
4523 (symbol 'date'))
4523 (symbol 'isodate'))
4524 (symbol 'isodate'))
4524 (string '\n'))
4525 (string '\n'))
4525 * expanded:
4526 * expanded:
4526 (template
4527 (template
4527 (template
4528 (template
4528 (symbol 'rev')
4529 (symbol 'rev')
4529 (string ':')
4530 (string ':')
4530 (|
4531 (|
4531 (symbol 'node')
4532 (symbol 'node')
4532 (symbol 'short')))
4533 (symbol 'short')))
4533 (string ' ')
4534 (string ' ')
4534 (|
4535 (|
4535 (func
4536 (func
4536 (symbol 'localdate')
4537 (symbol 'localdate')
4537 (list
4538 (list
4538 (symbol 'date')
4539 (symbol 'date')
4539 (string 'UTC')))
4540 (string 'UTC')))
4540 (symbol 'isodate'))
4541 (symbol 'isodate'))
4541 (string '\n'))
4542 (string '\n'))
4542 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
4543 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
4543
4544
4544 $ hg debugtemplate -vr0 '{status("A", file_adds)}'
4545 $ hg debugtemplate -vr0 '{status("A", file_adds)}'
4545 (template
4546 (template
4546 (func
4547 (func
4547 (symbol 'status')
4548 (symbol 'status')
4548 (list
4549 (list
4549 (string 'A')
4550 (string 'A')
4550 (symbol 'file_adds'))))
4551 (symbol 'file_adds'))))
4551 * expanded:
4552 * expanded:
4552 (template
4553 (template
4553 (%
4554 (%
4554 (symbol 'file_adds')
4555 (symbol 'file_adds')
4555 (template
4556 (template
4556 (string 'A')
4557 (string 'A')
4557 (string ' ')
4558 (string ' ')
4558 (symbol 'file')
4559 (symbol 'file')
4559 (string '\n'))))
4560 (string '\n'))))
4560 A a
4561 A a
4561
4562
4562 A unary function alias can be called as a filter:
4563 A unary function alias can be called as a filter:
4563
4564
4564 $ hg debugtemplate -vr0 '{date|utcdate|isodate}\n'
4565 $ hg debugtemplate -vr0 '{date|utcdate|isodate}\n'
4565 (template
4566 (template
4566 (|
4567 (|
4567 (|
4568 (|
4568 (symbol 'date')
4569 (symbol 'date')
4569 (symbol 'utcdate'))
4570 (symbol 'utcdate'))
4570 (symbol 'isodate'))
4571 (symbol 'isodate'))
4571 (string '\n'))
4572 (string '\n'))
4572 * expanded:
4573 * expanded:
4573 (template
4574 (template
4574 (|
4575 (|
4575 (func
4576 (func
4576 (symbol 'localdate')
4577 (symbol 'localdate')
4577 (list
4578 (list
4578 (symbol 'date')
4579 (symbol 'date')
4579 (string 'UTC')))
4580 (string 'UTC')))
4580 (symbol 'isodate'))
4581 (symbol 'isodate'))
4581 (string '\n'))
4582 (string '\n'))
4582 1970-01-12 13:46 +0000
4583 1970-01-12 13:46 +0000
4583
4584
4584 Aliases should be applied only to command arguments and templates in hgrc.
4585 Aliases should be applied only to command arguments and templates in hgrc.
4585 Otherwise, our stock styles and web templates could be corrupted:
4586 Otherwise, our stock styles and web templates could be corrupted:
4586
4587
4587 $ hg log -r0 -T '{rn} {utcdate(date)|isodate}\n'
4588 $ hg log -r0 -T '{rn} {utcdate(date)|isodate}\n'
4588 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
4589 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
4589
4590
4590 $ hg log -r0 --config ui.logtemplate='"{rn} {utcdate(date)|isodate}\n"'
4591 $ hg log -r0 --config ui.logtemplate='"{rn} {utcdate(date)|isodate}\n"'
4591 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
4592 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
4592
4593
4593 $ cat <<EOF > tmpl
4594 $ cat <<EOF > tmpl
4594 > changeset = 'nothing expanded:{rn}\n'
4595 > changeset = 'nothing expanded:{rn}\n'
4595 > EOF
4596 > EOF
4596 $ hg log -r0 --style ./tmpl
4597 $ hg log -r0 --style ./tmpl
4597 nothing expanded:
4598 nothing expanded:
4598
4599
4599 Aliases in formatter:
4600 Aliases in formatter:
4600
4601
4601 $ hg branches -T '{pad(branch, 7)} {rn}\n'
4602 $ hg branches -T '{pad(branch, 7)} {rn}\n'
4602 default 6:d41e714fe50d
4603 default 6:d41e714fe50d
4603 foo 4:bbe44766e73d
4604 foo 4:bbe44766e73d
4604
4605
4605 Aliases should honor HGPLAIN:
4606 Aliases should honor HGPLAIN:
4606
4607
4607 $ HGPLAIN= hg log -r0 -T 'nothing expanded:{rn}\n'
4608 $ HGPLAIN= hg log -r0 -T 'nothing expanded:{rn}\n'
4608 nothing expanded:
4609 nothing expanded:
4609 $ HGPLAINEXCEPT=templatealias hg log -r0 -T '{rn}\n'
4610 $ HGPLAINEXCEPT=templatealias hg log -r0 -T '{rn}\n'
4610 0:1e4e1b8f71e0
4611 0:1e4e1b8f71e0
4611
4612
4612 Unparsable alias:
4613 Unparsable alias:
4613
4614
4614 $ hg debugtemplate --config templatealias.bad='x(' -v '{bad}'
4615 $ hg debugtemplate --config templatealias.bad='x(' -v '{bad}'
4615 (template
4616 (template
4616 (symbol 'bad'))
4617 (symbol 'bad'))
4617 abort: bad definition of template alias "bad": at 2: not a prefix: end
4618 abort: bad definition of template alias "bad": at 2: not a prefix: end
4618 [255]
4619 [255]
4619 $ hg log --config templatealias.bad='x(' -T '{bad}'
4620 $ hg log --config templatealias.bad='x(' -T '{bad}'
4620 abort: bad definition of template alias "bad": at 2: not a prefix: end
4621 abort: bad definition of template alias "bad": at 2: not a prefix: end
4621 [255]
4622 [255]
4622
4623
4623 $ cd ..
4624 $ cd ..
4624
4625
4625 Set up repository for non-ascii encoding tests:
4626 Set up repository for non-ascii encoding tests:
4626
4627
4627 $ hg init nonascii
4628 $ hg init nonascii
4628 $ cd nonascii
4629 $ cd nonascii
4629 $ $PYTHON <<EOF
4630 $ $PYTHON <<EOF
4630 > open('latin1', 'wb').write(b'\xe9')
4631 > open('latin1', 'wb').write(b'\xe9')
4631 > open('utf-8', 'wb').write(b'\xc3\xa9')
4632 > open('utf-8', 'wb').write(b'\xc3\xa9')
4632 > EOF
4633 > EOF
4633 $ HGENCODING=utf-8 hg branch -q `cat utf-8`
4634 $ HGENCODING=utf-8 hg branch -q `cat utf-8`
4634 $ HGENCODING=utf-8 hg ci -qAm "non-ascii branch: `cat utf-8`" utf-8
4635 $ HGENCODING=utf-8 hg ci -qAm "non-ascii branch: `cat utf-8`" utf-8
4635
4636
4636 json filter should try round-trip conversion to utf-8:
4637 json filter should try round-trip conversion to utf-8:
4637
4638
4638 $ HGENCODING=ascii hg log -T "{branch|json}\n" -r0
4639 $ HGENCODING=ascii hg log -T "{branch|json}\n" -r0
4639 "\u00e9"
4640 "\u00e9"
4640 $ HGENCODING=ascii hg log -T "{desc|json}\n" -r0
4641 $ HGENCODING=ascii hg log -T "{desc|json}\n" -r0
4641 "non-ascii branch: \u00e9"
4642 "non-ascii branch: \u00e9"
4642
4643
4643 json filter takes input as utf-8b:
4644 json filter takes input as utf-8b:
4644
4645
4645 $ HGENCODING=ascii hg log -T "{'`cat utf-8`'|json}\n" -l1
4646 $ HGENCODING=ascii hg log -T "{'`cat utf-8`'|json}\n" -l1
4646 "\u00e9"
4647 "\u00e9"
4647 $ HGENCODING=ascii hg log -T "{'`cat latin1`'|json}\n" -l1
4648 $ HGENCODING=ascii hg log -T "{'`cat latin1`'|json}\n" -l1
4648 "\udce9"
4649 "\udce9"
4649
4650
4650 utf8 filter:
4651 utf8 filter:
4651
4652
4652 $ HGENCODING=ascii hg log -T "round-trip: {branch|utf8|hex}\n" -r0
4653 $ HGENCODING=ascii hg log -T "round-trip: {branch|utf8|hex}\n" -r0
4653 round-trip: c3a9
4654 round-trip: c3a9
4654 $ HGENCODING=latin1 hg log -T "decoded: {'`cat latin1`'|utf8|hex}\n" -l1
4655 $ HGENCODING=latin1 hg log -T "decoded: {'`cat latin1`'|utf8|hex}\n" -l1
4655 decoded: c3a9
4656 decoded: c3a9
4656 $ HGENCODING=ascii hg log -T "replaced: {'`cat latin1`'|utf8|hex}\n" -l1
4657 $ HGENCODING=ascii hg log -T "replaced: {'`cat latin1`'|utf8|hex}\n" -l1
4657 abort: decoding near * (glob)
4658 abort: decoding near * (glob)
4658 [255]
4659 [255]
4659 $ hg log -T "invalid type: {rev|utf8}\n" -r0
4660 $ hg log -T "coerced to string: {rev|utf8}\n" -r0
4660 abort: template filter 'utf8' is not compatible with keyword 'rev'
4661 coerced to string: 0
4661 [255]
4662
4662
4663 pad width:
4663 pad width:
4664
4664
4665 $ HGENCODING=utf-8 hg debugtemplate "{pad('`cat utf-8`', 2, '-')}\n"
4665 $ HGENCODING=utf-8 hg debugtemplate "{pad('`cat utf-8`', 2, '-')}\n"
4666 \xc3\xa9- (esc)
4666 \xc3\xa9- (esc)
4667
4667
4668 $ cd ..
4668 $ cd ..
4669
4669
4670 Test that template function in extension is registered as expected
4670 Test that template function in extension is registered as expected
4671
4671
4672 $ cd a
4672 $ cd a
4673
4673
4674 $ cat <<EOF > $TESTTMP/customfunc.py
4674 $ cat <<EOF > $TESTTMP/customfunc.py
4675 > from mercurial import registrar
4675 > from mercurial import registrar
4676 >
4676 >
4677 > templatefunc = registrar.templatefunc()
4677 > templatefunc = registrar.templatefunc()
4678 >
4678 >
4679 > @templatefunc(b'custom()')
4679 > @templatefunc(b'custom()')
4680 > def custom(context, mapping, args):
4680 > def custom(context, mapping, args):
4681 > return b'custom'
4681 > return b'custom'
4682 > EOF
4682 > EOF
4683 $ cat <<EOF > .hg/hgrc
4683 $ cat <<EOF > .hg/hgrc
4684 > [extensions]
4684 > [extensions]
4685 > customfunc = $TESTTMP/customfunc.py
4685 > customfunc = $TESTTMP/customfunc.py
4686 > EOF
4686 > EOF
4687
4687
4688 $ hg log -r . -T "{custom()}\n" --config customfunc.enabled=true
4688 $ hg log -r . -T "{custom()}\n" --config customfunc.enabled=true
4689 custom
4689 custom
4690
4690
4691 $ cd ..
4691 $ cd ..
4692
4692
4693 Test 'graphwidth' in 'hg log' on various topologies. The key here is that the
4693 Test 'graphwidth' in 'hg log' on various topologies. The key here is that the
4694 printed graphwidths 3, 5, 7, etc. should all line up in their respective
4694 printed graphwidths 3, 5, 7, etc. should all line up in their respective
4695 columns. We don't care about other aspects of the graph rendering here.
4695 columns. We don't care about other aspects of the graph rendering here.
4696
4696
4697 $ hg init graphwidth
4697 $ hg init graphwidth
4698 $ cd graphwidth
4698 $ cd graphwidth
4699
4699
4700 $ wrappabletext="a a a a a a a a a a a a"
4700 $ wrappabletext="a a a a a a a a a a a a"
4701
4701
4702 $ printf "first\n" > file
4702 $ printf "first\n" > file
4703 $ hg add file
4703 $ hg add file
4704 $ hg commit -m "$wrappabletext"
4704 $ hg commit -m "$wrappabletext"
4705
4705
4706 $ printf "first\nsecond\n" > file
4706 $ printf "first\nsecond\n" > file
4707 $ hg commit -m "$wrappabletext"
4707 $ hg commit -m "$wrappabletext"
4708
4708
4709 $ hg checkout 0
4709 $ hg checkout 0
4710 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
4710 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
4711 $ printf "third\nfirst\n" > file
4711 $ printf "third\nfirst\n" > file
4712 $ hg commit -m "$wrappabletext"
4712 $ hg commit -m "$wrappabletext"
4713 created new head
4713 created new head
4714
4714
4715 $ hg merge
4715 $ hg merge
4716 merging file
4716 merging file
4717 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
4717 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
4718 (branch merge, don't forget to commit)
4718 (branch merge, don't forget to commit)
4719
4719
4720 $ hg log --graph -T "{graphwidth}"
4720 $ hg log --graph -T "{graphwidth}"
4721 @ 3
4721 @ 3
4722 |
4722 |
4723 | @ 5
4723 | @ 5
4724 |/
4724 |/
4725 o 3
4725 o 3
4726
4726
4727 $ hg commit -m "$wrappabletext"
4727 $ hg commit -m "$wrappabletext"
4728
4728
4729 $ hg log --graph -T "{graphwidth}"
4729 $ hg log --graph -T "{graphwidth}"
4730 @ 5
4730 @ 5
4731 |\
4731 |\
4732 | o 5
4732 | o 5
4733 | |
4733 | |
4734 o | 5
4734 o | 5
4735 |/
4735 |/
4736 o 3
4736 o 3
4737
4737
4738
4738
4739 $ hg checkout 0
4739 $ hg checkout 0
4740 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
4740 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
4741 $ printf "third\nfirst\nsecond\n" > file
4741 $ printf "third\nfirst\nsecond\n" > file
4742 $ hg commit -m "$wrappabletext"
4742 $ hg commit -m "$wrappabletext"
4743 created new head
4743 created new head
4744
4744
4745 $ hg log --graph -T "{graphwidth}"
4745 $ hg log --graph -T "{graphwidth}"
4746 @ 3
4746 @ 3
4747 |
4747 |
4748 | o 7
4748 | o 7
4749 | |\
4749 | |\
4750 +---o 7
4750 +---o 7
4751 | |
4751 | |
4752 | o 5
4752 | o 5
4753 |/
4753 |/
4754 o 3
4754 o 3
4755
4755
4756
4756
4757 $ hg log --graph -T "{graphwidth}" -r 3
4757 $ hg log --graph -T "{graphwidth}" -r 3
4758 o 5
4758 o 5
4759 |\
4759 |\
4760 ~ ~
4760 ~ ~
4761
4761
4762 $ hg log --graph -T "{graphwidth}" -r 1
4762 $ hg log --graph -T "{graphwidth}" -r 1
4763 o 3
4763 o 3
4764 |
4764 |
4765 ~
4765 ~
4766
4766
4767 $ hg merge
4767 $ hg merge
4768 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
4768 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
4769 (branch merge, don't forget to commit)
4769 (branch merge, don't forget to commit)
4770 $ hg commit -m "$wrappabletext"
4770 $ hg commit -m "$wrappabletext"
4771
4771
4772 $ printf "seventh\n" >> file
4772 $ printf "seventh\n" >> file
4773 $ hg commit -m "$wrappabletext"
4773 $ hg commit -m "$wrappabletext"
4774
4774
4775 $ hg log --graph -T "{graphwidth}"
4775 $ hg log --graph -T "{graphwidth}"
4776 @ 3
4776 @ 3
4777 |
4777 |
4778 o 5
4778 o 5
4779 |\
4779 |\
4780 | o 5
4780 | o 5
4781 | |
4781 | |
4782 o | 7
4782 o | 7
4783 |\ \
4783 |\ \
4784 | o | 7
4784 | o | 7
4785 | |/
4785 | |/
4786 o / 5
4786 o / 5
4787 |/
4787 |/
4788 o 3
4788 o 3
4789
4789
4790
4790
4791 The point of graphwidth is to allow wrapping that accounts for the space taken
4791 The point of graphwidth is to allow wrapping that accounts for the space taken
4792 by the graph.
4792 by the graph.
4793
4793
4794 $ COLUMNS=10 hg log --graph -T "{fill(desc, termwidth - graphwidth)}"
4794 $ COLUMNS=10 hg log --graph -T "{fill(desc, termwidth - graphwidth)}"
4795 @ a a a a
4795 @ a a a a
4796 | a a a a
4796 | a a a a
4797 | a a a a
4797 | a a a a
4798 o a a a
4798 o a a a
4799 |\ a a a
4799 |\ a a a
4800 | | a a a
4800 | | a a a
4801 | | a a a
4801 | | a a a
4802 | o a a a
4802 | o a a a
4803 | | a a a
4803 | | a a a
4804 | | a a a
4804 | | a a a
4805 | | a a a
4805 | | a a a
4806 o | a a
4806 o | a a
4807 |\ \ a a
4807 |\ \ a a
4808 | | | a a
4808 | | | a a
4809 | | | a a
4809 | | | a a
4810 | | | a a
4810 | | | a a
4811 | | | a a
4811 | | | a a
4812 | o | a a
4812 | o | a a
4813 | |/ a a
4813 | |/ a a
4814 | | a a
4814 | | a a
4815 | | a a
4815 | | a a
4816 | | a a
4816 | | a a
4817 | | a a
4817 | | a a
4818 o | a a a
4818 o | a a a
4819 |/ a a a
4819 |/ a a a
4820 | a a a
4820 | a a a
4821 | a a a
4821 | a a a
4822 o a a a a
4822 o a a a a
4823 a a a a
4823 a a a a
4824 a a a a
4824 a a a a
4825
4825
4826 Something tricky happens when there are elided nodes; the next drawn row of
4826 Something tricky happens when there are elided nodes; the next drawn row of
4827 edges can be more than one column wider, but the graph width only increases by
4827 edges can be more than one column wider, but the graph width only increases by
4828 one column. The remaining columns are added in between the nodes.
4828 one column. The remaining columns are added in between the nodes.
4829
4829
4830 $ hg log --graph -T "{graphwidth}" -r "0|2|4|5"
4830 $ hg log --graph -T "{graphwidth}" -r "0|2|4|5"
4831 o 5
4831 o 5
4832 |\
4832 |\
4833 | \
4833 | \
4834 | :\
4834 | :\
4835 o : : 7
4835 o : : 7
4836 :/ /
4836 :/ /
4837 : o 5
4837 : o 5
4838 :/
4838 :/
4839 o 3
4839 o 3
4840
4840
4841
4841
4842 $ cd ..
4842 $ cd ..
4843
4843
General Comments 0
You need to be logged in to leave comments. Login now