##// END OF EJS Templates
ui: drop template aliases by HGPLAIN...
Yuya Nishihara -
r28958:77e566fe default
parent child Browse files
Show More
@@ -1,109 +1,111 b''
1 HG
1 HG
2 Path to the 'hg' executable, automatically passed when running
2 Path to the 'hg' executable, automatically passed when running
3 hooks, extensions or external tools. If unset or empty, this is
3 hooks, extensions or external tools. If unset or empty, this is
4 the hg executable's name if it's frozen, or an executable named
4 the hg executable's name if it's frozen, or an executable named
5 'hg' (with %PATHEXT% [defaulting to COM/EXE/BAT/CMD] extensions on
5 'hg' (with %PATHEXT% [defaulting to COM/EXE/BAT/CMD] extensions on
6 Windows) is searched.
6 Windows) is searched.
7
7
8 HGEDITOR
8 HGEDITOR
9 This is the name of the editor to run when committing. See EDITOR.
9 This is the name of the editor to run when committing. See EDITOR.
10
10
11 (deprecated, use configuration file)
11 (deprecated, use configuration file)
12
12
13 HGENCODING
13 HGENCODING
14 This overrides the default locale setting detected by Mercurial.
14 This overrides the default locale setting detected by Mercurial.
15 This setting is used to convert data including usernames,
15 This setting is used to convert data including usernames,
16 changeset descriptions, tag names, and branches. This setting can
16 changeset descriptions, tag names, and branches. This setting can
17 be overridden with the --encoding command-line option.
17 be overridden with the --encoding command-line option.
18
18
19 HGENCODINGMODE
19 HGENCODINGMODE
20 This sets Mercurial's behavior for handling unknown characters
20 This sets Mercurial's behavior for handling unknown characters
21 while transcoding user input. The default is "strict", which
21 while transcoding user input. The default is "strict", which
22 causes Mercurial to abort if it can't map a character. Other
22 causes Mercurial to abort if it can't map a character. Other
23 settings include "replace", which replaces unknown characters, and
23 settings include "replace", which replaces unknown characters, and
24 "ignore", which drops them. This setting can be overridden with
24 "ignore", which drops them. This setting can be overridden with
25 the --encodingmode command-line option.
25 the --encodingmode command-line option.
26
26
27 HGENCODINGAMBIGUOUS
27 HGENCODINGAMBIGUOUS
28 This sets Mercurial's behavior for handling characters with
28 This sets Mercurial's behavior for handling characters with
29 "ambiguous" widths like accented Latin characters with East Asian
29 "ambiguous" widths like accented Latin characters with East Asian
30 fonts. By default, Mercurial assumes ambiguous characters are
30 fonts. By default, Mercurial assumes ambiguous characters are
31 narrow, set this variable to "wide" if such characters cause
31 narrow, set this variable to "wide" if such characters cause
32 formatting problems.
32 formatting problems.
33
33
34 HGMERGE
34 HGMERGE
35 An executable to use for resolving merge conflicts. The program
35 An executable to use for resolving merge conflicts. The program
36 will be executed with three arguments: local file, remote file,
36 will be executed with three arguments: local file, remote file,
37 ancestor file.
37 ancestor file.
38
38
39 (deprecated, use configuration file)
39 (deprecated, use configuration file)
40
40
41 HGRCPATH
41 HGRCPATH
42 A list of files or directories to search for configuration
42 A list of files or directories to search for configuration
43 files. Item separator is ":" on Unix, ";" on Windows. If HGRCPATH
43 files. Item separator is ":" on Unix, ";" on Windows. If HGRCPATH
44 is not set, platform default search path is used. If empty, only
44 is not set, platform default search path is used. If empty, only
45 the .hg/hgrc from the current repository is read.
45 the .hg/hgrc from the current repository is read.
46
46
47 For each element in HGRCPATH:
47 For each element in HGRCPATH:
48
48
49 - if it's a directory, all files ending with .rc are added
49 - if it's a directory, all files ending with .rc are added
50 - otherwise, the file itself will be added
50 - otherwise, the file itself will be added
51
51
52 HGPLAIN
52 HGPLAIN
53 When set, this disables any configuration settings that might
53 When set, this disables any configuration settings that might
54 change Mercurial's default output. This includes encoding,
54 change Mercurial's default output. This includes encoding,
55 defaults, verbose mode, debug mode, quiet mode, tracebacks, and
55 defaults, verbose mode, debug mode, quiet mode, tracebacks, and
56 localization. This can be useful when scripting against Mercurial
56 localization. This can be useful when scripting against Mercurial
57 in the face of existing user configuration.
57 in the face of existing user configuration.
58
58
59 Equivalent options set via command line flags or environment
59 Equivalent options set via command line flags or environment
60 variables are not overridden.
60 variables are not overridden.
61
61
62 HGPLAINEXCEPT
62 HGPLAINEXCEPT
63 This is a comma-separated list of features to preserve when
63 This is a comma-separated list of features to preserve when
64 HGPLAIN is enabled. Currently the following values are supported:
64 HGPLAIN is enabled. Currently the following values are supported:
65
65
66 ``alias``
66 ``alias``
67 Don't remove aliases.
67 Don't remove aliases.
68 ``i18n``
68 ``i18n``
69 Preserve internationalization.
69 Preserve internationalization.
70 ``revsetalias``
70 ``revsetalias``
71 Don't remove revset aliases.
71 Don't remove revset aliases.
72 ``templatealias``
73 Don't remove template aliases.
72 ``progress``
74 ``progress``
73 Don't hide progress output.
75 Don't hide progress output.
74
76
75 Setting HGPLAINEXCEPT to anything (even an empty string) will
77 Setting HGPLAINEXCEPT to anything (even an empty string) will
76 enable plain mode.
78 enable plain mode.
77
79
78 HGUSER
80 HGUSER
79 This is the string used as the author of a commit. If not set,
81 This is the string used as the author of a commit. If not set,
80 available values will be considered in this order:
82 available values will be considered in this order:
81
83
82 - HGUSER (deprecated)
84 - HGUSER (deprecated)
83 - configuration files from the HGRCPATH
85 - configuration files from the HGRCPATH
84 - EMAIL
86 - EMAIL
85 - interactive prompt
87 - interactive prompt
86 - LOGNAME (with ``@hostname`` appended)
88 - LOGNAME (with ``@hostname`` appended)
87
89
88 (deprecated, use configuration file)
90 (deprecated, use configuration file)
89
91
90 EMAIL
92 EMAIL
91 May be used as the author of a commit; see HGUSER.
93 May be used as the author of a commit; see HGUSER.
92
94
93 LOGNAME
95 LOGNAME
94 May be used as the author of a commit; see HGUSER.
96 May be used as the author of a commit; see HGUSER.
95
97
96 VISUAL
98 VISUAL
97 This is the name of the editor to use when committing. See EDITOR.
99 This is the name of the editor to use when committing. See EDITOR.
98
100
99 EDITOR
101 EDITOR
100 Sometimes Mercurial needs to open a text file in an editor for a
102 Sometimes Mercurial needs to open a text file in an editor for a
101 user to modify, for example when writing commit messages. The
103 user to modify, for example when writing commit messages. The
102 editor it uses is determined by looking at the environment
104 editor it uses is determined by looking at the environment
103 variables HGEDITOR, VISUAL and EDITOR, in that order. The first
105 variables HGEDITOR, VISUAL and EDITOR, in that order. The first
104 non-empty one is chosen. If all of them are empty, the editor
106 non-empty one is chosen. If all of them are empty, the editor
105 defaults to 'vi'.
107 defaults to 'vi'.
106
108
107 PYTHONPATH
109 PYTHONPATH
108 This is used by Python to find imported modules and may need to be
110 This is used by Python to find imported modules and may need to be
109 set appropriately if this Mercurial is not installed system-wide.
111 set appropriately if this Mercurial is not installed system-wide.
@@ -1,1338 +1,1341 b''
1 # ui.py - user interface bits for mercurial
1 # ui.py - user interface bits for mercurial
2 #
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 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 errno
10 import errno
11 import getpass
11 import getpass
12 import inspect
12 import inspect
13 import os
13 import os
14 import re
14 import re
15 import socket
15 import socket
16 import sys
16 import sys
17 import tempfile
17 import tempfile
18 import traceback
18 import traceback
19
19
20 from .i18n import _
20 from .i18n import _
21 from .node import hex
21 from .node import hex
22
22
23 from . import (
23 from . import (
24 config,
24 config,
25 error,
25 error,
26 formatter,
26 formatter,
27 progress,
27 progress,
28 scmutil,
28 scmutil,
29 util,
29 util,
30 )
30 )
31
31
32 samplehgrcs = {
32 samplehgrcs = {
33 'user':
33 'user':
34 """# example user config (see "hg help config" for more info)
34 """# example user config (see "hg help config" for more info)
35 [ui]
35 [ui]
36 # name and email, e.g.
36 # name and email, e.g.
37 # username = Jane Doe <jdoe@example.com>
37 # username = Jane Doe <jdoe@example.com>
38 username =
38 username =
39
39
40 [extensions]
40 [extensions]
41 # uncomment these lines to enable some popular extensions
41 # uncomment these lines to enable some popular extensions
42 # (see "hg help extensions" for more info)
42 # (see "hg help extensions" for more info)
43 #
43 #
44 # pager =
44 # pager =
45 # color =""",
45 # color =""",
46
46
47 'cloned':
47 'cloned':
48 """# example repository config (see "hg help config" for more info)
48 """# example repository config (see "hg help config" for more info)
49 [paths]
49 [paths]
50 default = %s
50 default = %s
51
51
52 # path aliases to other clones of this repo in URLs or filesystem paths
52 # path aliases to other clones of this repo in URLs or filesystem paths
53 # (see "hg help config.paths" for more info)
53 # (see "hg help config.paths" for more info)
54 #
54 #
55 # default-push = ssh://jdoe@example.net/hg/jdoes-fork
55 # default-push = ssh://jdoe@example.net/hg/jdoes-fork
56 # my-fork = ssh://jdoe@example.net/hg/jdoes-fork
56 # my-fork = ssh://jdoe@example.net/hg/jdoes-fork
57 # my-clone = /home/jdoe/jdoes-clone
57 # my-clone = /home/jdoe/jdoes-clone
58
58
59 [ui]
59 [ui]
60 # name and email (local to this repository, optional), e.g.
60 # name and email (local to this repository, optional), e.g.
61 # username = Jane Doe <jdoe@example.com>
61 # username = Jane Doe <jdoe@example.com>
62 """,
62 """,
63
63
64 'local':
64 'local':
65 """# example repository config (see "hg help config" for more info)
65 """# example repository config (see "hg help config" for more info)
66 [paths]
66 [paths]
67 # path aliases to other clones of this repo in URLs or filesystem paths
67 # path aliases to other clones of this repo in URLs or filesystem paths
68 # (see "hg help config.paths" for more info)
68 # (see "hg help config.paths" for more info)
69 #
69 #
70 # default = http://example.com/hg/example-repo
70 # default = http://example.com/hg/example-repo
71 # default-push = ssh://jdoe@example.net/hg/jdoes-fork
71 # default-push = ssh://jdoe@example.net/hg/jdoes-fork
72 # my-fork = ssh://jdoe@example.net/hg/jdoes-fork
72 # my-fork = ssh://jdoe@example.net/hg/jdoes-fork
73 # my-clone = /home/jdoe/jdoes-clone
73 # my-clone = /home/jdoe/jdoes-clone
74
74
75 [ui]
75 [ui]
76 # name and email (local to this repository, optional), e.g.
76 # name and email (local to this repository, optional), e.g.
77 # username = Jane Doe <jdoe@example.com>
77 # username = Jane Doe <jdoe@example.com>
78 """,
78 """,
79
79
80 'global':
80 'global':
81 """# example system-wide hg config (see "hg help config" for more info)
81 """# example system-wide hg config (see "hg help config" for more info)
82
82
83 [extensions]
83 [extensions]
84 # uncomment these lines to enable some popular extensions
84 # uncomment these lines to enable some popular extensions
85 # (see "hg help extensions" for more info)
85 # (see "hg help extensions" for more info)
86 #
86 #
87 # blackbox =
87 # blackbox =
88 # color =
88 # color =
89 # pager =""",
89 # pager =""",
90 }
90 }
91
91
92 class ui(object):
92 class ui(object):
93 def __init__(self, src=None):
93 def __init__(self, src=None):
94 # _buffers: used for temporary capture of output
94 # _buffers: used for temporary capture of output
95 self._buffers = []
95 self._buffers = []
96 # 3-tuple describing how each buffer in the stack behaves.
96 # 3-tuple describing how each buffer in the stack behaves.
97 # Values are (capture stderr, capture subprocesses, apply labels).
97 # Values are (capture stderr, capture subprocesses, apply labels).
98 self._bufferstates = []
98 self._bufferstates = []
99 # When a buffer is active, defines whether we are expanding labels.
99 # When a buffer is active, defines whether we are expanding labels.
100 # This exists to prevent an extra list lookup.
100 # This exists to prevent an extra list lookup.
101 self._bufferapplylabels = None
101 self._bufferapplylabels = None
102 self.quiet = self.verbose = self.debugflag = self.tracebackflag = False
102 self.quiet = self.verbose = self.debugflag = self.tracebackflag = False
103 self._reportuntrusted = True
103 self._reportuntrusted = True
104 self._ocfg = config.config() # overlay
104 self._ocfg = config.config() # overlay
105 self._tcfg = config.config() # trusted
105 self._tcfg = config.config() # trusted
106 self._ucfg = config.config() # untrusted
106 self._ucfg = config.config() # untrusted
107 self._trustusers = set()
107 self._trustusers = set()
108 self._trustgroups = set()
108 self._trustgroups = set()
109 self.callhooks = True
109 self.callhooks = True
110
110
111 if src:
111 if src:
112 self.fout = src.fout
112 self.fout = src.fout
113 self.ferr = src.ferr
113 self.ferr = src.ferr
114 self.fin = src.fin
114 self.fin = src.fin
115
115
116 self._tcfg = src._tcfg.copy()
116 self._tcfg = src._tcfg.copy()
117 self._ucfg = src._ucfg.copy()
117 self._ucfg = src._ucfg.copy()
118 self._ocfg = src._ocfg.copy()
118 self._ocfg = src._ocfg.copy()
119 self._trustusers = src._trustusers.copy()
119 self._trustusers = src._trustusers.copy()
120 self._trustgroups = src._trustgroups.copy()
120 self._trustgroups = src._trustgroups.copy()
121 self.environ = src.environ
121 self.environ = src.environ
122 self.callhooks = src.callhooks
122 self.callhooks = src.callhooks
123 self.fixconfig()
123 self.fixconfig()
124 else:
124 else:
125 self.fout = sys.stdout
125 self.fout = sys.stdout
126 self.ferr = sys.stderr
126 self.ferr = sys.stderr
127 self.fin = sys.stdin
127 self.fin = sys.stdin
128
128
129 # shared read-only environment
129 # shared read-only environment
130 self.environ = os.environ
130 self.environ = os.environ
131 # we always trust global config files
131 # we always trust global config files
132 for f in scmutil.rcpath():
132 for f in scmutil.rcpath():
133 self.readconfig(f, trust=True)
133 self.readconfig(f, trust=True)
134
134
135 def copy(self):
135 def copy(self):
136 return self.__class__(self)
136 return self.__class__(self)
137
137
138 def formatter(self, topic, opts):
138 def formatter(self, topic, opts):
139 return formatter.formatter(self, topic, opts)
139 return formatter.formatter(self, topic, opts)
140
140
141 def _trusted(self, fp, f):
141 def _trusted(self, fp, f):
142 st = util.fstat(fp)
142 st = util.fstat(fp)
143 if util.isowner(st):
143 if util.isowner(st):
144 return True
144 return True
145
145
146 tusers, tgroups = self._trustusers, self._trustgroups
146 tusers, tgroups = self._trustusers, self._trustgroups
147 if '*' in tusers or '*' in tgroups:
147 if '*' in tusers or '*' in tgroups:
148 return True
148 return True
149
149
150 user = util.username(st.st_uid)
150 user = util.username(st.st_uid)
151 group = util.groupname(st.st_gid)
151 group = util.groupname(st.st_gid)
152 if user in tusers or group in tgroups or user == util.username():
152 if user in tusers or group in tgroups or user == util.username():
153 return True
153 return True
154
154
155 if self._reportuntrusted:
155 if self._reportuntrusted:
156 self.warn(_('not trusting file %s from untrusted '
156 self.warn(_('not trusting file %s from untrusted '
157 'user %s, group %s\n') % (f, user, group))
157 'user %s, group %s\n') % (f, user, group))
158 return False
158 return False
159
159
160 def readconfig(self, filename, root=None, trust=False,
160 def readconfig(self, filename, root=None, trust=False,
161 sections=None, remap=None):
161 sections=None, remap=None):
162 try:
162 try:
163 fp = open(filename)
163 fp = open(filename)
164 except IOError:
164 except IOError:
165 if not sections: # ignore unless we were looking for something
165 if not sections: # ignore unless we were looking for something
166 return
166 return
167 raise
167 raise
168
168
169 cfg = config.config()
169 cfg = config.config()
170 trusted = sections or trust or self._trusted(fp, filename)
170 trusted = sections or trust or self._trusted(fp, filename)
171
171
172 try:
172 try:
173 cfg.read(filename, fp, sections=sections, remap=remap)
173 cfg.read(filename, fp, sections=sections, remap=remap)
174 fp.close()
174 fp.close()
175 except error.ConfigError as inst:
175 except error.ConfigError as inst:
176 if trusted:
176 if trusted:
177 raise
177 raise
178 self.warn(_("ignored: %s\n") % str(inst))
178 self.warn(_("ignored: %s\n") % str(inst))
179
179
180 if self.plain():
180 if self.plain():
181 for k in ('debug', 'fallbackencoding', 'quiet', 'slash',
181 for k in ('debug', 'fallbackencoding', 'quiet', 'slash',
182 'logtemplate', 'statuscopies', 'style',
182 'logtemplate', 'statuscopies', 'style',
183 'traceback', 'verbose'):
183 'traceback', 'verbose'):
184 if k in cfg['ui']:
184 if k in cfg['ui']:
185 del cfg['ui'][k]
185 del cfg['ui'][k]
186 for k, v in cfg.items('defaults'):
186 for k, v in cfg.items('defaults'):
187 del cfg['defaults'][k]
187 del cfg['defaults'][k]
188 # Don't remove aliases from the configuration if in the exceptionlist
188 # Don't remove aliases from the configuration if in the exceptionlist
189 if self.plain('alias'):
189 if self.plain('alias'):
190 for k, v in cfg.items('alias'):
190 for k, v in cfg.items('alias'):
191 del cfg['alias'][k]
191 del cfg['alias'][k]
192 if self.plain('revsetalias'):
192 if self.plain('revsetalias'):
193 for k, v in cfg.items('revsetalias'):
193 for k, v in cfg.items('revsetalias'):
194 del cfg['revsetalias'][k]
194 del cfg['revsetalias'][k]
195 if self.plain('templatealias'):
196 for k, v in cfg.items('templatealias'):
197 del cfg['templatealias'][k]
195
198
196 if trusted:
199 if trusted:
197 self._tcfg.update(cfg)
200 self._tcfg.update(cfg)
198 self._tcfg.update(self._ocfg)
201 self._tcfg.update(self._ocfg)
199 self._ucfg.update(cfg)
202 self._ucfg.update(cfg)
200 self._ucfg.update(self._ocfg)
203 self._ucfg.update(self._ocfg)
201
204
202 if root is None:
205 if root is None:
203 root = os.path.expanduser('~')
206 root = os.path.expanduser('~')
204 self.fixconfig(root=root)
207 self.fixconfig(root=root)
205
208
206 def fixconfig(self, root=None, section=None):
209 def fixconfig(self, root=None, section=None):
207 if section in (None, 'paths'):
210 if section in (None, 'paths'):
208 # expand vars and ~
211 # expand vars and ~
209 # translate paths relative to root (or home) into absolute paths
212 # translate paths relative to root (or home) into absolute paths
210 root = root or os.getcwd()
213 root = root or os.getcwd()
211 for c in self._tcfg, self._ucfg, self._ocfg:
214 for c in self._tcfg, self._ucfg, self._ocfg:
212 for n, p in c.items('paths'):
215 for n, p in c.items('paths'):
213 if not p:
216 if not p:
214 continue
217 continue
215 if '%%' in p:
218 if '%%' in p:
216 self.warn(_("(deprecated '%%' in path %s=%s from %s)\n")
219 self.warn(_("(deprecated '%%' in path %s=%s from %s)\n")
217 % (n, p, self.configsource('paths', n)))
220 % (n, p, self.configsource('paths', n)))
218 p = p.replace('%%', '%')
221 p = p.replace('%%', '%')
219 p = util.expandpath(p)
222 p = util.expandpath(p)
220 if not util.hasscheme(p) and not os.path.isabs(p):
223 if not util.hasscheme(p) and not os.path.isabs(p):
221 p = os.path.normpath(os.path.join(root, p))
224 p = os.path.normpath(os.path.join(root, p))
222 c.set("paths", n, p)
225 c.set("paths", n, p)
223
226
224 if section in (None, 'ui'):
227 if section in (None, 'ui'):
225 # update ui options
228 # update ui options
226 self.debugflag = self.configbool('ui', 'debug')
229 self.debugflag = self.configbool('ui', 'debug')
227 self.verbose = self.debugflag or self.configbool('ui', 'verbose')
230 self.verbose = self.debugflag or self.configbool('ui', 'verbose')
228 self.quiet = not self.debugflag and self.configbool('ui', 'quiet')
231 self.quiet = not self.debugflag and self.configbool('ui', 'quiet')
229 if self.verbose and self.quiet:
232 if self.verbose and self.quiet:
230 self.quiet = self.verbose = False
233 self.quiet = self.verbose = False
231 self._reportuntrusted = self.debugflag or self.configbool("ui",
234 self._reportuntrusted = self.debugflag or self.configbool("ui",
232 "report_untrusted", True)
235 "report_untrusted", True)
233 self.tracebackflag = self.configbool('ui', 'traceback', False)
236 self.tracebackflag = self.configbool('ui', 'traceback', False)
234
237
235 if section in (None, 'trusted'):
238 if section in (None, 'trusted'):
236 # update trust information
239 # update trust information
237 self._trustusers.update(self.configlist('trusted', 'users'))
240 self._trustusers.update(self.configlist('trusted', 'users'))
238 self._trustgroups.update(self.configlist('trusted', 'groups'))
241 self._trustgroups.update(self.configlist('trusted', 'groups'))
239
242
240 def backupconfig(self, section, item):
243 def backupconfig(self, section, item):
241 return (self._ocfg.backup(section, item),
244 return (self._ocfg.backup(section, item),
242 self._tcfg.backup(section, item),
245 self._tcfg.backup(section, item),
243 self._ucfg.backup(section, item),)
246 self._ucfg.backup(section, item),)
244 def restoreconfig(self, data):
247 def restoreconfig(self, data):
245 self._ocfg.restore(data[0])
248 self._ocfg.restore(data[0])
246 self._tcfg.restore(data[1])
249 self._tcfg.restore(data[1])
247 self._ucfg.restore(data[2])
250 self._ucfg.restore(data[2])
248
251
249 def setconfig(self, section, name, value, source=''):
252 def setconfig(self, section, name, value, source=''):
250 for cfg in (self._ocfg, self._tcfg, self._ucfg):
253 for cfg in (self._ocfg, self._tcfg, self._ucfg):
251 cfg.set(section, name, value, source)
254 cfg.set(section, name, value, source)
252 self.fixconfig(section=section)
255 self.fixconfig(section=section)
253
256
254 def _data(self, untrusted):
257 def _data(self, untrusted):
255 return untrusted and self._ucfg or self._tcfg
258 return untrusted and self._ucfg or self._tcfg
256
259
257 def configsource(self, section, name, untrusted=False):
260 def configsource(self, section, name, untrusted=False):
258 return self._data(untrusted).source(section, name) or 'none'
261 return self._data(untrusted).source(section, name) or 'none'
259
262
260 def config(self, section, name, default=None, untrusted=False):
263 def config(self, section, name, default=None, untrusted=False):
261 if isinstance(name, list):
264 if isinstance(name, list):
262 alternates = name
265 alternates = name
263 else:
266 else:
264 alternates = [name]
267 alternates = [name]
265
268
266 for n in alternates:
269 for n in alternates:
267 value = self._data(untrusted).get(section, n, None)
270 value = self._data(untrusted).get(section, n, None)
268 if value is not None:
271 if value is not None:
269 name = n
272 name = n
270 break
273 break
271 else:
274 else:
272 value = default
275 value = default
273
276
274 if self.debugflag and not untrusted and self._reportuntrusted:
277 if self.debugflag and not untrusted and self._reportuntrusted:
275 for n in alternates:
278 for n in alternates:
276 uvalue = self._ucfg.get(section, n)
279 uvalue = self._ucfg.get(section, n)
277 if uvalue is not None and uvalue != value:
280 if uvalue is not None and uvalue != value:
278 self.debug("ignoring untrusted configuration option "
281 self.debug("ignoring untrusted configuration option "
279 "%s.%s = %s\n" % (section, n, uvalue))
282 "%s.%s = %s\n" % (section, n, uvalue))
280 return value
283 return value
281
284
282 def configsuboptions(self, section, name, default=None, untrusted=False):
285 def configsuboptions(self, section, name, default=None, untrusted=False):
283 """Get a config option and all sub-options.
286 """Get a config option and all sub-options.
284
287
285 Some config options have sub-options that are declared with the
288 Some config options have sub-options that are declared with the
286 format "key:opt = value". This method is used to return the main
289 format "key:opt = value". This method is used to return the main
287 option and all its declared sub-options.
290 option and all its declared sub-options.
288
291
289 Returns a 2-tuple of ``(option, sub-options)``, where `sub-options``
292 Returns a 2-tuple of ``(option, sub-options)``, where `sub-options``
290 is a dict of defined sub-options where keys and values are strings.
293 is a dict of defined sub-options where keys and values are strings.
291 """
294 """
292 data = self._data(untrusted)
295 data = self._data(untrusted)
293 main = data.get(section, name, default)
296 main = data.get(section, name, default)
294 if self.debugflag and not untrusted and self._reportuntrusted:
297 if self.debugflag and not untrusted and self._reportuntrusted:
295 uvalue = self._ucfg.get(section, name)
298 uvalue = self._ucfg.get(section, name)
296 if uvalue is not None and uvalue != main:
299 if uvalue is not None and uvalue != main:
297 self.debug('ignoring untrusted configuration option '
300 self.debug('ignoring untrusted configuration option '
298 '%s.%s = %s\n' % (section, name, uvalue))
301 '%s.%s = %s\n' % (section, name, uvalue))
299
302
300 sub = {}
303 sub = {}
301 prefix = '%s:' % name
304 prefix = '%s:' % name
302 for k, v in data.items(section):
305 for k, v in data.items(section):
303 if k.startswith(prefix):
306 if k.startswith(prefix):
304 sub[k[len(prefix):]] = v
307 sub[k[len(prefix):]] = v
305
308
306 if self.debugflag and not untrusted and self._reportuntrusted:
309 if self.debugflag and not untrusted and self._reportuntrusted:
307 for k, v in sub.items():
310 for k, v in sub.items():
308 uvalue = self._ucfg.get(section, '%s:%s' % (name, k))
311 uvalue = self._ucfg.get(section, '%s:%s' % (name, k))
309 if uvalue is not None and uvalue != v:
312 if uvalue is not None and uvalue != v:
310 self.debug('ignoring untrusted configuration option '
313 self.debug('ignoring untrusted configuration option '
311 '%s:%s.%s = %s\n' % (section, name, k, uvalue))
314 '%s:%s.%s = %s\n' % (section, name, k, uvalue))
312
315
313 return main, sub
316 return main, sub
314
317
315 def configpath(self, section, name, default=None, untrusted=False):
318 def configpath(self, section, name, default=None, untrusted=False):
316 'get a path config item, expanded relative to repo root or config file'
319 'get a path config item, expanded relative to repo root or config file'
317 v = self.config(section, name, default, untrusted)
320 v = self.config(section, name, default, untrusted)
318 if v is None:
321 if v is None:
319 return None
322 return None
320 if not os.path.isabs(v) or "://" not in v:
323 if not os.path.isabs(v) or "://" not in v:
321 src = self.configsource(section, name, untrusted)
324 src = self.configsource(section, name, untrusted)
322 if ':' in src:
325 if ':' in src:
323 base = os.path.dirname(src.rsplit(':')[0])
326 base = os.path.dirname(src.rsplit(':')[0])
324 v = os.path.join(base, os.path.expanduser(v))
327 v = os.path.join(base, os.path.expanduser(v))
325 return v
328 return v
326
329
327 def configbool(self, section, name, default=False, untrusted=False):
330 def configbool(self, section, name, default=False, untrusted=False):
328 """parse a configuration element as a boolean
331 """parse a configuration element as a boolean
329
332
330 >>> u = ui(); s = 'foo'
333 >>> u = ui(); s = 'foo'
331 >>> u.setconfig(s, 'true', 'yes')
334 >>> u.setconfig(s, 'true', 'yes')
332 >>> u.configbool(s, 'true')
335 >>> u.configbool(s, 'true')
333 True
336 True
334 >>> u.setconfig(s, 'false', 'no')
337 >>> u.setconfig(s, 'false', 'no')
335 >>> u.configbool(s, 'false')
338 >>> u.configbool(s, 'false')
336 False
339 False
337 >>> u.configbool(s, 'unknown')
340 >>> u.configbool(s, 'unknown')
338 False
341 False
339 >>> u.configbool(s, 'unknown', True)
342 >>> u.configbool(s, 'unknown', True)
340 True
343 True
341 >>> u.setconfig(s, 'invalid', 'somevalue')
344 >>> u.setconfig(s, 'invalid', 'somevalue')
342 >>> u.configbool(s, 'invalid')
345 >>> u.configbool(s, 'invalid')
343 Traceback (most recent call last):
346 Traceback (most recent call last):
344 ...
347 ...
345 ConfigError: foo.invalid is not a boolean ('somevalue')
348 ConfigError: foo.invalid is not a boolean ('somevalue')
346 """
349 """
347
350
348 v = self.config(section, name, None, untrusted)
351 v = self.config(section, name, None, untrusted)
349 if v is None:
352 if v is None:
350 return default
353 return default
351 if isinstance(v, bool):
354 if isinstance(v, bool):
352 return v
355 return v
353 b = util.parsebool(v)
356 b = util.parsebool(v)
354 if b is None:
357 if b is None:
355 raise error.ConfigError(_("%s.%s is not a boolean ('%s')")
358 raise error.ConfigError(_("%s.%s is not a boolean ('%s')")
356 % (section, name, v))
359 % (section, name, v))
357 return b
360 return b
358
361
359 def configint(self, section, name, default=None, untrusted=False):
362 def configint(self, section, name, default=None, untrusted=False):
360 """parse a configuration element as an integer
363 """parse a configuration element as an integer
361
364
362 >>> u = ui(); s = 'foo'
365 >>> u = ui(); s = 'foo'
363 >>> u.setconfig(s, 'int1', '42')
366 >>> u.setconfig(s, 'int1', '42')
364 >>> u.configint(s, 'int1')
367 >>> u.configint(s, 'int1')
365 42
368 42
366 >>> u.setconfig(s, 'int2', '-42')
369 >>> u.setconfig(s, 'int2', '-42')
367 >>> u.configint(s, 'int2')
370 >>> u.configint(s, 'int2')
368 -42
371 -42
369 >>> u.configint(s, 'unknown', 7)
372 >>> u.configint(s, 'unknown', 7)
370 7
373 7
371 >>> u.setconfig(s, 'invalid', 'somevalue')
374 >>> u.setconfig(s, 'invalid', 'somevalue')
372 >>> u.configint(s, 'invalid')
375 >>> u.configint(s, 'invalid')
373 Traceback (most recent call last):
376 Traceback (most recent call last):
374 ...
377 ...
375 ConfigError: foo.invalid is not an integer ('somevalue')
378 ConfigError: foo.invalid is not an integer ('somevalue')
376 """
379 """
377
380
378 v = self.config(section, name, None, untrusted)
381 v = self.config(section, name, None, untrusted)
379 if v is None:
382 if v is None:
380 return default
383 return default
381 try:
384 try:
382 return int(v)
385 return int(v)
383 except ValueError:
386 except ValueError:
384 raise error.ConfigError(_("%s.%s is not an integer ('%s')")
387 raise error.ConfigError(_("%s.%s is not an integer ('%s')")
385 % (section, name, v))
388 % (section, name, v))
386
389
387 def configbytes(self, section, name, default=0, untrusted=False):
390 def configbytes(self, section, name, default=0, untrusted=False):
388 """parse a configuration element as a quantity in bytes
391 """parse a configuration element as a quantity in bytes
389
392
390 Units can be specified as b (bytes), k or kb (kilobytes), m or
393 Units can be specified as b (bytes), k or kb (kilobytes), m or
391 mb (megabytes), g or gb (gigabytes).
394 mb (megabytes), g or gb (gigabytes).
392
395
393 >>> u = ui(); s = 'foo'
396 >>> u = ui(); s = 'foo'
394 >>> u.setconfig(s, 'val1', '42')
397 >>> u.setconfig(s, 'val1', '42')
395 >>> u.configbytes(s, 'val1')
398 >>> u.configbytes(s, 'val1')
396 42
399 42
397 >>> u.setconfig(s, 'val2', '42.5 kb')
400 >>> u.setconfig(s, 'val2', '42.5 kb')
398 >>> u.configbytes(s, 'val2')
401 >>> u.configbytes(s, 'val2')
399 43520
402 43520
400 >>> u.configbytes(s, 'unknown', '7 MB')
403 >>> u.configbytes(s, 'unknown', '7 MB')
401 7340032
404 7340032
402 >>> u.setconfig(s, 'invalid', 'somevalue')
405 >>> u.setconfig(s, 'invalid', 'somevalue')
403 >>> u.configbytes(s, 'invalid')
406 >>> u.configbytes(s, 'invalid')
404 Traceback (most recent call last):
407 Traceback (most recent call last):
405 ...
408 ...
406 ConfigError: foo.invalid is not a byte quantity ('somevalue')
409 ConfigError: foo.invalid is not a byte quantity ('somevalue')
407 """
410 """
408
411
409 value = self.config(section, name)
412 value = self.config(section, name)
410 if value is None:
413 if value is None:
411 if not isinstance(default, str):
414 if not isinstance(default, str):
412 return default
415 return default
413 value = default
416 value = default
414 try:
417 try:
415 return util.sizetoint(value)
418 return util.sizetoint(value)
416 except error.ParseError:
419 except error.ParseError:
417 raise error.ConfigError(_("%s.%s is not a byte quantity ('%s')")
420 raise error.ConfigError(_("%s.%s is not a byte quantity ('%s')")
418 % (section, name, value))
421 % (section, name, value))
419
422
420 def configlist(self, section, name, default=None, untrusted=False):
423 def configlist(self, section, name, default=None, untrusted=False):
421 """parse a configuration element as a list of comma/space separated
424 """parse a configuration element as a list of comma/space separated
422 strings
425 strings
423
426
424 >>> u = ui(); s = 'foo'
427 >>> u = ui(); s = 'foo'
425 >>> u.setconfig(s, 'list1', 'this,is "a small" ,test')
428 >>> u.setconfig(s, 'list1', 'this,is "a small" ,test')
426 >>> u.configlist(s, 'list1')
429 >>> u.configlist(s, 'list1')
427 ['this', 'is', 'a small', 'test']
430 ['this', 'is', 'a small', 'test']
428 """
431 """
429
432
430 def _parse_plain(parts, s, offset):
433 def _parse_plain(parts, s, offset):
431 whitespace = False
434 whitespace = False
432 while offset < len(s) and (s[offset].isspace() or s[offset] == ','):
435 while offset < len(s) and (s[offset].isspace() or s[offset] == ','):
433 whitespace = True
436 whitespace = True
434 offset += 1
437 offset += 1
435 if offset >= len(s):
438 if offset >= len(s):
436 return None, parts, offset
439 return None, parts, offset
437 if whitespace:
440 if whitespace:
438 parts.append('')
441 parts.append('')
439 if s[offset] == '"' and not parts[-1]:
442 if s[offset] == '"' and not parts[-1]:
440 return _parse_quote, parts, offset + 1
443 return _parse_quote, parts, offset + 1
441 elif s[offset] == '"' and parts[-1][-1] == '\\':
444 elif s[offset] == '"' and parts[-1][-1] == '\\':
442 parts[-1] = parts[-1][:-1] + s[offset]
445 parts[-1] = parts[-1][:-1] + s[offset]
443 return _parse_plain, parts, offset + 1
446 return _parse_plain, parts, offset + 1
444 parts[-1] += s[offset]
447 parts[-1] += s[offset]
445 return _parse_plain, parts, offset + 1
448 return _parse_plain, parts, offset + 1
446
449
447 def _parse_quote(parts, s, offset):
450 def _parse_quote(parts, s, offset):
448 if offset < len(s) and s[offset] == '"': # ""
451 if offset < len(s) and s[offset] == '"': # ""
449 parts.append('')
452 parts.append('')
450 offset += 1
453 offset += 1
451 while offset < len(s) and (s[offset].isspace() or
454 while offset < len(s) and (s[offset].isspace() or
452 s[offset] == ','):
455 s[offset] == ','):
453 offset += 1
456 offset += 1
454 return _parse_plain, parts, offset
457 return _parse_plain, parts, offset
455
458
456 while offset < len(s) and s[offset] != '"':
459 while offset < len(s) and s[offset] != '"':
457 if (s[offset] == '\\' and offset + 1 < len(s)
460 if (s[offset] == '\\' and offset + 1 < len(s)
458 and s[offset + 1] == '"'):
461 and s[offset + 1] == '"'):
459 offset += 1
462 offset += 1
460 parts[-1] += '"'
463 parts[-1] += '"'
461 else:
464 else:
462 parts[-1] += s[offset]
465 parts[-1] += s[offset]
463 offset += 1
466 offset += 1
464
467
465 if offset >= len(s):
468 if offset >= len(s):
466 real_parts = _configlist(parts[-1])
469 real_parts = _configlist(parts[-1])
467 if not real_parts:
470 if not real_parts:
468 parts[-1] = '"'
471 parts[-1] = '"'
469 else:
472 else:
470 real_parts[0] = '"' + real_parts[0]
473 real_parts[0] = '"' + real_parts[0]
471 parts = parts[:-1]
474 parts = parts[:-1]
472 parts.extend(real_parts)
475 parts.extend(real_parts)
473 return None, parts, offset
476 return None, parts, offset
474
477
475 offset += 1
478 offset += 1
476 while offset < len(s) and s[offset] in [' ', ',']:
479 while offset < len(s) and s[offset] in [' ', ',']:
477 offset += 1
480 offset += 1
478
481
479 if offset < len(s):
482 if offset < len(s):
480 if offset + 1 == len(s) and s[offset] == '"':
483 if offset + 1 == len(s) and s[offset] == '"':
481 parts[-1] += '"'
484 parts[-1] += '"'
482 offset += 1
485 offset += 1
483 else:
486 else:
484 parts.append('')
487 parts.append('')
485 else:
488 else:
486 return None, parts, offset
489 return None, parts, offset
487
490
488 return _parse_plain, parts, offset
491 return _parse_plain, parts, offset
489
492
490 def _configlist(s):
493 def _configlist(s):
491 s = s.rstrip(' ,')
494 s = s.rstrip(' ,')
492 if not s:
495 if not s:
493 return []
496 return []
494 parser, parts, offset = _parse_plain, [''], 0
497 parser, parts, offset = _parse_plain, [''], 0
495 while parser:
498 while parser:
496 parser, parts, offset = parser(parts, s, offset)
499 parser, parts, offset = parser(parts, s, offset)
497 return parts
500 return parts
498
501
499 result = self.config(section, name, untrusted=untrusted)
502 result = self.config(section, name, untrusted=untrusted)
500 if result is None:
503 if result is None:
501 result = default or []
504 result = default or []
502 if isinstance(result, basestring):
505 if isinstance(result, basestring):
503 result = _configlist(result.lstrip(' ,\n'))
506 result = _configlist(result.lstrip(' ,\n'))
504 if result is None:
507 if result is None:
505 result = default or []
508 result = default or []
506 return result
509 return result
507
510
508 def hasconfig(self, section, name, untrusted=False):
511 def hasconfig(self, section, name, untrusted=False):
509 return self._data(untrusted).hasitem(section, name)
512 return self._data(untrusted).hasitem(section, name)
510
513
511 def has_section(self, section, untrusted=False):
514 def has_section(self, section, untrusted=False):
512 '''tell whether section exists in config.'''
515 '''tell whether section exists in config.'''
513 return section in self._data(untrusted)
516 return section in self._data(untrusted)
514
517
515 def configitems(self, section, untrusted=False, ignoresub=False):
518 def configitems(self, section, untrusted=False, ignoresub=False):
516 items = self._data(untrusted).items(section)
519 items = self._data(untrusted).items(section)
517 if ignoresub:
520 if ignoresub:
518 newitems = {}
521 newitems = {}
519 for k, v in items:
522 for k, v in items:
520 if ':' not in k:
523 if ':' not in k:
521 newitems[k] = v
524 newitems[k] = v
522 items = newitems.items()
525 items = newitems.items()
523 if self.debugflag and not untrusted and self._reportuntrusted:
526 if self.debugflag and not untrusted and self._reportuntrusted:
524 for k, v in self._ucfg.items(section):
527 for k, v in self._ucfg.items(section):
525 if self._tcfg.get(section, k) != v:
528 if self._tcfg.get(section, k) != v:
526 self.debug("ignoring untrusted configuration option "
529 self.debug("ignoring untrusted configuration option "
527 "%s.%s = %s\n" % (section, k, v))
530 "%s.%s = %s\n" % (section, k, v))
528 return items
531 return items
529
532
530 def walkconfig(self, untrusted=False):
533 def walkconfig(self, untrusted=False):
531 cfg = self._data(untrusted)
534 cfg = self._data(untrusted)
532 for section in cfg.sections():
535 for section in cfg.sections():
533 for name, value in self.configitems(section, untrusted):
536 for name, value in self.configitems(section, untrusted):
534 yield section, name, value
537 yield section, name, value
535
538
536 def plain(self, feature=None):
539 def plain(self, feature=None):
537 '''is plain mode active?
540 '''is plain mode active?
538
541
539 Plain mode means that all configuration variables which affect
542 Plain mode means that all configuration variables which affect
540 the behavior and output of Mercurial should be
543 the behavior and output of Mercurial should be
541 ignored. Additionally, the output should be stable,
544 ignored. Additionally, the output should be stable,
542 reproducible and suitable for use in scripts or applications.
545 reproducible and suitable for use in scripts or applications.
543
546
544 The only way to trigger plain mode is by setting either the
547 The only way to trigger plain mode is by setting either the
545 `HGPLAIN' or `HGPLAINEXCEPT' environment variables.
548 `HGPLAIN' or `HGPLAINEXCEPT' environment variables.
546
549
547 The return value can either be
550 The return value can either be
548 - False if HGPLAIN is not set, or feature is in HGPLAINEXCEPT
551 - False if HGPLAIN is not set, or feature is in HGPLAINEXCEPT
549 - True otherwise
552 - True otherwise
550 '''
553 '''
551 if 'HGPLAIN' not in os.environ and 'HGPLAINEXCEPT' not in os.environ:
554 if 'HGPLAIN' not in os.environ and 'HGPLAINEXCEPT' not in os.environ:
552 return False
555 return False
553 exceptions = os.environ.get('HGPLAINEXCEPT', '').strip().split(',')
556 exceptions = os.environ.get('HGPLAINEXCEPT', '').strip().split(',')
554 if feature and exceptions:
557 if feature and exceptions:
555 return feature not in exceptions
558 return feature not in exceptions
556 return True
559 return True
557
560
558 def username(self):
561 def username(self):
559 """Return default username to be used in commits.
562 """Return default username to be used in commits.
560
563
561 Searched in this order: $HGUSER, [ui] section of hgrcs, $EMAIL
564 Searched in this order: $HGUSER, [ui] section of hgrcs, $EMAIL
562 and stop searching if one of these is set.
565 and stop searching if one of these is set.
563 If not found and ui.askusername is True, ask the user, else use
566 If not found and ui.askusername is True, ask the user, else use
564 ($LOGNAME or $USER or $LNAME or $USERNAME) + "@full.hostname".
567 ($LOGNAME or $USER or $LNAME or $USERNAME) + "@full.hostname".
565 """
568 """
566 user = os.environ.get("HGUSER")
569 user = os.environ.get("HGUSER")
567 if user is None:
570 if user is None:
568 user = self.config("ui", ["username", "user"])
571 user = self.config("ui", ["username", "user"])
569 if user is not None:
572 if user is not None:
570 user = os.path.expandvars(user)
573 user = os.path.expandvars(user)
571 if user is None:
574 if user is None:
572 user = os.environ.get("EMAIL")
575 user = os.environ.get("EMAIL")
573 if user is None and self.configbool("ui", "askusername"):
576 if user is None and self.configbool("ui", "askusername"):
574 user = self.prompt(_("enter a commit username:"), default=None)
577 user = self.prompt(_("enter a commit username:"), default=None)
575 if user is None and not self.interactive():
578 if user is None and not self.interactive():
576 try:
579 try:
577 user = '%s@%s' % (util.getuser(), socket.getfqdn())
580 user = '%s@%s' % (util.getuser(), socket.getfqdn())
578 self.warn(_("no username found, using '%s' instead\n") % user)
581 self.warn(_("no username found, using '%s' instead\n") % user)
579 except KeyError:
582 except KeyError:
580 pass
583 pass
581 if not user:
584 if not user:
582 raise error.Abort(_('no username supplied'),
585 raise error.Abort(_('no username supplied'),
583 hint=_('use "hg config --edit" '
586 hint=_('use "hg config --edit" '
584 'to set your username'))
587 'to set your username'))
585 if "\n" in user:
588 if "\n" in user:
586 raise error.Abort(_("username %s contains a newline\n")
589 raise error.Abort(_("username %s contains a newline\n")
587 % repr(user))
590 % repr(user))
588 return user
591 return user
589
592
590 def shortuser(self, user):
593 def shortuser(self, user):
591 """Return a short representation of a user name or email address."""
594 """Return a short representation of a user name or email address."""
592 if not self.verbose:
595 if not self.verbose:
593 user = util.shortuser(user)
596 user = util.shortuser(user)
594 return user
597 return user
595
598
596 def expandpath(self, loc, default=None):
599 def expandpath(self, loc, default=None):
597 """Return repository location relative to cwd or from [paths]"""
600 """Return repository location relative to cwd or from [paths]"""
598 try:
601 try:
599 p = self.paths.getpath(loc)
602 p = self.paths.getpath(loc)
600 if p:
603 if p:
601 return p.rawloc
604 return p.rawloc
602 except error.RepoError:
605 except error.RepoError:
603 pass
606 pass
604
607
605 if default:
608 if default:
606 try:
609 try:
607 p = self.paths.getpath(default)
610 p = self.paths.getpath(default)
608 if p:
611 if p:
609 return p.rawloc
612 return p.rawloc
610 except error.RepoError:
613 except error.RepoError:
611 pass
614 pass
612
615
613 return loc
616 return loc
614
617
615 @util.propertycache
618 @util.propertycache
616 def paths(self):
619 def paths(self):
617 return paths(self)
620 return paths(self)
618
621
619 def pushbuffer(self, error=False, subproc=False, labeled=False):
622 def pushbuffer(self, error=False, subproc=False, labeled=False):
620 """install a buffer to capture standard output of the ui object
623 """install a buffer to capture standard output of the ui object
621
624
622 If error is True, the error output will be captured too.
625 If error is True, the error output will be captured too.
623
626
624 If subproc is True, output from subprocesses (typically hooks) will be
627 If subproc is True, output from subprocesses (typically hooks) will be
625 captured too.
628 captured too.
626
629
627 If labeled is True, any labels associated with buffered
630 If labeled is True, any labels associated with buffered
628 output will be handled. By default, this has no effect
631 output will be handled. By default, this has no effect
629 on the output returned, but extensions and GUI tools may
632 on the output returned, but extensions and GUI tools may
630 handle this argument and returned styled output. If output
633 handle this argument and returned styled output. If output
631 is being buffered so it can be captured and parsed or
634 is being buffered so it can be captured and parsed or
632 processed, labeled should not be set to True.
635 processed, labeled should not be set to True.
633 """
636 """
634 self._buffers.append([])
637 self._buffers.append([])
635 self._bufferstates.append((error, subproc, labeled))
638 self._bufferstates.append((error, subproc, labeled))
636 self._bufferapplylabels = labeled
639 self._bufferapplylabels = labeled
637
640
638 def popbuffer(self):
641 def popbuffer(self):
639 '''pop the last buffer and return the buffered output'''
642 '''pop the last buffer and return the buffered output'''
640 self._bufferstates.pop()
643 self._bufferstates.pop()
641 if self._bufferstates:
644 if self._bufferstates:
642 self._bufferapplylabels = self._bufferstates[-1][2]
645 self._bufferapplylabels = self._bufferstates[-1][2]
643 else:
646 else:
644 self._bufferapplylabels = None
647 self._bufferapplylabels = None
645
648
646 return "".join(self._buffers.pop())
649 return "".join(self._buffers.pop())
647
650
648 def write(self, *args, **opts):
651 def write(self, *args, **opts):
649 '''write args to output
652 '''write args to output
650
653
651 By default, this method simply writes to the buffer or stdout,
654 By default, this method simply writes to the buffer or stdout,
652 but extensions or GUI tools may override this method,
655 but extensions or GUI tools may override this method,
653 write_err(), popbuffer(), and label() to style output from
656 write_err(), popbuffer(), and label() to style output from
654 various parts of hg.
657 various parts of hg.
655
658
656 An optional keyword argument, "label", can be passed in.
659 An optional keyword argument, "label", can be passed in.
657 This should be a string containing label names separated by
660 This should be a string containing label names separated by
658 space. Label names take the form of "topic.type". For example,
661 space. Label names take the form of "topic.type". For example,
659 ui.debug() issues a label of "ui.debug".
662 ui.debug() issues a label of "ui.debug".
660
663
661 When labeling output for a specific command, a label of
664 When labeling output for a specific command, a label of
662 "cmdname.type" is recommended. For example, status issues
665 "cmdname.type" is recommended. For example, status issues
663 a label of "status.modified" for modified files.
666 a label of "status.modified" for modified files.
664 '''
667 '''
665 if self._buffers and not opts.get('prompt', False):
668 if self._buffers and not opts.get('prompt', False):
666 self._buffers[-1].extend(a for a in args)
669 self._buffers[-1].extend(a for a in args)
667 else:
670 else:
668 self._progclear()
671 self._progclear()
669 for a in args:
672 for a in args:
670 self.fout.write(a)
673 self.fout.write(a)
671
674
672 def write_err(self, *args, **opts):
675 def write_err(self, *args, **opts):
673 self._progclear()
676 self._progclear()
674 try:
677 try:
675 if self._bufferstates and self._bufferstates[-1][0]:
678 if self._bufferstates and self._bufferstates[-1][0]:
676 return self.write(*args, **opts)
679 return self.write(*args, **opts)
677 if not getattr(self.fout, 'closed', False):
680 if not getattr(self.fout, 'closed', False):
678 self.fout.flush()
681 self.fout.flush()
679 for a in args:
682 for a in args:
680 self.ferr.write(a)
683 self.ferr.write(a)
681 # stderr may be buffered under win32 when redirected to files,
684 # stderr may be buffered under win32 when redirected to files,
682 # including stdout.
685 # including stdout.
683 if not getattr(self.ferr, 'closed', False):
686 if not getattr(self.ferr, 'closed', False):
684 self.ferr.flush()
687 self.ferr.flush()
685 except IOError as inst:
688 except IOError as inst:
686 if inst.errno not in (errno.EPIPE, errno.EIO, errno.EBADF):
689 if inst.errno not in (errno.EPIPE, errno.EIO, errno.EBADF):
687 raise
690 raise
688
691
689 def flush(self):
692 def flush(self):
690 try: self.fout.flush()
693 try: self.fout.flush()
691 except (IOError, ValueError): pass
694 except (IOError, ValueError): pass
692 try: self.ferr.flush()
695 try: self.ferr.flush()
693 except (IOError, ValueError): pass
696 except (IOError, ValueError): pass
694
697
695 def _isatty(self, fh):
698 def _isatty(self, fh):
696 if self.configbool('ui', 'nontty', False):
699 if self.configbool('ui', 'nontty', False):
697 return False
700 return False
698 return util.isatty(fh)
701 return util.isatty(fh)
699
702
700 def interface(self, feature):
703 def interface(self, feature):
701 """what interface to use for interactive console features?
704 """what interface to use for interactive console features?
702
705
703 The interface is controlled by the value of `ui.interface` but also by
706 The interface is controlled by the value of `ui.interface` but also by
704 the value of feature-specific configuration. For example:
707 the value of feature-specific configuration. For example:
705
708
706 ui.interface.histedit = text
709 ui.interface.histedit = text
707 ui.interface.chunkselector = curses
710 ui.interface.chunkselector = curses
708
711
709 Here the features are "histedit" and "chunkselector".
712 Here the features are "histedit" and "chunkselector".
710
713
711 The configuration above means that the default interfaces for commands
714 The configuration above means that the default interfaces for commands
712 is curses, the interface for histedit is text and the interface for
715 is curses, the interface for histedit is text and the interface for
713 selecting chunk is crecord (the best curses interface available).
716 selecting chunk is crecord (the best curses interface available).
714
717
715 Consider the following exemple:
718 Consider the following exemple:
716 ui.interface = curses
719 ui.interface = curses
717 ui.interface.histedit = text
720 ui.interface.histedit = text
718
721
719 Then histedit will use the text interface and chunkselector will use
722 Then histedit will use the text interface and chunkselector will use
720 the default curses interface (crecord at the moment).
723 the default curses interface (crecord at the moment).
721 """
724 """
722 alldefaults = frozenset(["text", "curses"])
725 alldefaults = frozenset(["text", "curses"])
723
726
724 featureinterfaces = {
727 featureinterfaces = {
725 "chunkselector": [
728 "chunkselector": [
726 "text",
729 "text",
727 "curses",
730 "curses",
728 ]
731 ]
729 }
732 }
730
733
731 # Feature-specific interface
734 # Feature-specific interface
732 if feature not in featureinterfaces.keys():
735 if feature not in featureinterfaces.keys():
733 # Programming error, not user error
736 # Programming error, not user error
734 raise ValueError("Unknown feature requested %s" % feature)
737 raise ValueError("Unknown feature requested %s" % feature)
735
738
736 availableinterfaces = frozenset(featureinterfaces[feature])
739 availableinterfaces = frozenset(featureinterfaces[feature])
737 if alldefaults > availableinterfaces:
740 if alldefaults > availableinterfaces:
738 # Programming error, not user error. We need a use case to
741 # Programming error, not user error. We need a use case to
739 # define the right thing to do here.
742 # define the right thing to do here.
740 raise ValueError(
743 raise ValueError(
741 "Feature %s does not handle all default interfaces" %
744 "Feature %s does not handle all default interfaces" %
742 feature)
745 feature)
743
746
744 if self.plain():
747 if self.plain():
745 return "text"
748 return "text"
746
749
747 # Default interface for all the features
750 # Default interface for all the features
748 defaultinterface = "text"
751 defaultinterface = "text"
749 i = self.config("ui", "interface", None)
752 i = self.config("ui", "interface", None)
750 if i in alldefaults:
753 if i in alldefaults:
751 defaultinterface = i
754 defaultinterface = i
752
755
753 choseninterface = defaultinterface
756 choseninterface = defaultinterface
754 f = self.config("ui", "interface.%s" % feature, None)
757 f = self.config("ui", "interface.%s" % feature, None)
755 if f in availableinterfaces:
758 if f in availableinterfaces:
756 choseninterface = f
759 choseninterface = f
757
760
758 if i is not None and defaultinterface != i:
761 if i is not None and defaultinterface != i:
759 if f is not None:
762 if f is not None:
760 self.warn(_("invalid value for ui.interface: %s\n") %
763 self.warn(_("invalid value for ui.interface: %s\n") %
761 (i,))
764 (i,))
762 else:
765 else:
763 self.warn(_("invalid value for ui.interface: %s (using %s)\n") %
766 self.warn(_("invalid value for ui.interface: %s (using %s)\n") %
764 (i, choseninterface))
767 (i, choseninterface))
765 if f is not None and choseninterface != f:
768 if f is not None and choseninterface != f:
766 self.warn(_("invalid value for ui.interface.%s: %s (using %s)\n") %
769 self.warn(_("invalid value for ui.interface.%s: %s (using %s)\n") %
767 (feature, f, choseninterface))
770 (feature, f, choseninterface))
768
771
769 return choseninterface
772 return choseninterface
770
773
771 def interactive(self):
774 def interactive(self):
772 '''is interactive input allowed?
775 '''is interactive input allowed?
773
776
774 An interactive session is a session where input can be reasonably read
777 An interactive session is a session where input can be reasonably read
775 from `sys.stdin'. If this function returns false, any attempt to read
778 from `sys.stdin'. If this function returns false, any attempt to read
776 from stdin should fail with an error, unless a sensible default has been
779 from stdin should fail with an error, unless a sensible default has been
777 specified.
780 specified.
778
781
779 Interactiveness is triggered by the value of the `ui.interactive'
782 Interactiveness is triggered by the value of the `ui.interactive'
780 configuration variable or - if it is unset - when `sys.stdin' points
783 configuration variable or - if it is unset - when `sys.stdin' points
781 to a terminal device.
784 to a terminal device.
782
785
783 This function refers to input only; for output, see `ui.formatted()'.
786 This function refers to input only; for output, see `ui.formatted()'.
784 '''
787 '''
785 i = self.configbool("ui", "interactive", None)
788 i = self.configbool("ui", "interactive", None)
786 if i is None:
789 if i is None:
787 # some environments replace stdin without implementing isatty
790 # some environments replace stdin without implementing isatty
788 # usually those are non-interactive
791 # usually those are non-interactive
789 return self._isatty(self.fin)
792 return self._isatty(self.fin)
790
793
791 return i
794 return i
792
795
793 def termwidth(self):
796 def termwidth(self):
794 '''how wide is the terminal in columns?
797 '''how wide is the terminal in columns?
795 '''
798 '''
796 if 'COLUMNS' in os.environ:
799 if 'COLUMNS' in os.environ:
797 try:
800 try:
798 return int(os.environ['COLUMNS'])
801 return int(os.environ['COLUMNS'])
799 except ValueError:
802 except ValueError:
800 pass
803 pass
801 return util.termwidth()
804 return util.termwidth()
802
805
803 def formatted(self):
806 def formatted(self):
804 '''should formatted output be used?
807 '''should formatted output be used?
805
808
806 It is often desirable to format the output to suite the output medium.
809 It is often desirable to format the output to suite the output medium.
807 Examples of this are truncating long lines or colorizing messages.
810 Examples of this are truncating long lines or colorizing messages.
808 However, this is not often not desirable when piping output into other
811 However, this is not often not desirable when piping output into other
809 utilities, e.g. `grep'.
812 utilities, e.g. `grep'.
810
813
811 Formatted output is triggered by the value of the `ui.formatted'
814 Formatted output is triggered by the value of the `ui.formatted'
812 configuration variable or - if it is unset - when `sys.stdout' points
815 configuration variable or - if it is unset - when `sys.stdout' points
813 to a terminal device. Please note that `ui.formatted' should be
816 to a terminal device. Please note that `ui.formatted' should be
814 considered an implementation detail; it is not intended for use outside
817 considered an implementation detail; it is not intended for use outside
815 Mercurial or its extensions.
818 Mercurial or its extensions.
816
819
817 This function refers to output only; for input, see `ui.interactive()'.
820 This function refers to output only; for input, see `ui.interactive()'.
818 This function always returns false when in plain mode, see `ui.plain()'.
821 This function always returns false when in plain mode, see `ui.plain()'.
819 '''
822 '''
820 if self.plain():
823 if self.plain():
821 return False
824 return False
822
825
823 i = self.configbool("ui", "formatted", None)
826 i = self.configbool("ui", "formatted", None)
824 if i is None:
827 if i is None:
825 # some environments replace stdout without implementing isatty
828 # some environments replace stdout without implementing isatty
826 # usually those are non-interactive
829 # usually those are non-interactive
827 return self._isatty(self.fout)
830 return self._isatty(self.fout)
828
831
829 return i
832 return i
830
833
831 def _readline(self, prompt=''):
834 def _readline(self, prompt=''):
832 if self._isatty(self.fin):
835 if self._isatty(self.fin):
833 try:
836 try:
834 # magically add command line editing support, where
837 # magically add command line editing support, where
835 # available
838 # available
836 import readline
839 import readline
837 # force demandimport to really load the module
840 # force demandimport to really load the module
838 readline.read_history_file
841 readline.read_history_file
839 # windows sometimes raises something other than ImportError
842 # windows sometimes raises something other than ImportError
840 except Exception:
843 except Exception:
841 pass
844 pass
842
845
843 # call write() so output goes through subclassed implementation
846 # call write() so output goes through subclassed implementation
844 # e.g. color extension on Windows
847 # e.g. color extension on Windows
845 self.write(prompt, prompt=True)
848 self.write(prompt, prompt=True)
846
849
847 # instead of trying to emulate raw_input, swap (self.fin,
850 # instead of trying to emulate raw_input, swap (self.fin,
848 # self.fout) with (sys.stdin, sys.stdout)
851 # self.fout) with (sys.stdin, sys.stdout)
849 oldin = sys.stdin
852 oldin = sys.stdin
850 oldout = sys.stdout
853 oldout = sys.stdout
851 sys.stdin = self.fin
854 sys.stdin = self.fin
852 sys.stdout = self.fout
855 sys.stdout = self.fout
853 # prompt ' ' must exist; otherwise readline may delete entire line
856 # prompt ' ' must exist; otherwise readline may delete entire line
854 # - http://bugs.python.org/issue12833
857 # - http://bugs.python.org/issue12833
855 line = raw_input(' ')
858 line = raw_input(' ')
856 sys.stdin = oldin
859 sys.stdin = oldin
857 sys.stdout = oldout
860 sys.stdout = oldout
858
861
859 # When stdin is in binary mode on Windows, it can cause
862 # When stdin is in binary mode on Windows, it can cause
860 # raw_input() to emit an extra trailing carriage return
863 # raw_input() to emit an extra trailing carriage return
861 if os.linesep == '\r\n' and line and line[-1] == '\r':
864 if os.linesep == '\r\n' and line and line[-1] == '\r':
862 line = line[:-1]
865 line = line[:-1]
863 return line
866 return line
864
867
865 def prompt(self, msg, default="y"):
868 def prompt(self, msg, default="y"):
866 """Prompt user with msg, read response.
869 """Prompt user with msg, read response.
867 If ui is not interactive, the default is returned.
870 If ui is not interactive, the default is returned.
868 """
871 """
869 if not self.interactive():
872 if not self.interactive():
870 self.write(msg, ' ', default or '', "\n")
873 self.write(msg, ' ', default or '', "\n")
871 return default
874 return default
872 try:
875 try:
873 r = self._readline(self.label(msg, 'ui.prompt'))
876 r = self._readline(self.label(msg, 'ui.prompt'))
874 if not r:
877 if not r:
875 r = default
878 r = default
876 if self.configbool('ui', 'promptecho'):
879 if self.configbool('ui', 'promptecho'):
877 self.write(r, "\n")
880 self.write(r, "\n")
878 return r
881 return r
879 except EOFError:
882 except EOFError:
880 raise error.ResponseExpected()
883 raise error.ResponseExpected()
881
884
882 @staticmethod
885 @staticmethod
883 def extractchoices(prompt):
886 def extractchoices(prompt):
884 """Extract prompt message and list of choices from specified prompt.
887 """Extract prompt message and list of choices from specified prompt.
885
888
886 This returns tuple "(message, choices)", and "choices" is the
889 This returns tuple "(message, choices)", and "choices" is the
887 list of tuple "(response character, text without &)".
890 list of tuple "(response character, text without &)".
888
891
889 >>> ui.extractchoices("awake? $$ &Yes $$ &No")
892 >>> ui.extractchoices("awake? $$ &Yes $$ &No")
890 ('awake? ', [('y', 'Yes'), ('n', 'No')])
893 ('awake? ', [('y', 'Yes'), ('n', 'No')])
891 >>> ui.extractchoices("line\\nbreak? $$ &Yes $$ &No")
894 >>> ui.extractchoices("line\\nbreak? $$ &Yes $$ &No")
892 ('line\\nbreak? ', [('y', 'Yes'), ('n', 'No')])
895 ('line\\nbreak? ', [('y', 'Yes'), ('n', 'No')])
893 >>> ui.extractchoices("want lots of $$money$$?$$Ye&s$$N&o")
896 >>> ui.extractchoices("want lots of $$money$$?$$Ye&s$$N&o")
894 ('want lots of $$money$$?', [('s', 'Yes'), ('o', 'No')])
897 ('want lots of $$money$$?', [('s', 'Yes'), ('o', 'No')])
895 """
898 """
896
899
897 # Sadly, the prompt string may have been built with a filename
900 # Sadly, the prompt string may have been built with a filename
898 # containing "$$" so let's try to find the first valid-looking
901 # containing "$$" so let's try to find the first valid-looking
899 # prompt to start parsing. Sadly, we also can't rely on
902 # prompt to start parsing. Sadly, we also can't rely on
900 # choices containing spaces, ASCII, or basically anything
903 # choices containing spaces, ASCII, or basically anything
901 # except an ampersand followed by a character.
904 # except an ampersand followed by a character.
902 m = re.match(r'(?s)(.+?)\$\$([^\$]*&[^ \$].*)', prompt)
905 m = re.match(r'(?s)(.+?)\$\$([^\$]*&[^ \$].*)', prompt)
903 msg = m.group(1)
906 msg = m.group(1)
904 choices = [p.strip(' ') for p in m.group(2).split('$$')]
907 choices = [p.strip(' ') for p in m.group(2).split('$$')]
905 return (msg,
908 return (msg,
906 [(s[s.index('&') + 1].lower(), s.replace('&', '', 1))
909 [(s[s.index('&') + 1].lower(), s.replace('&', '', 1))
907 for s in choices])
910 for s in choices])
908
911
909 def promptchoice(self, prompt, default=0):
912 def promptchoice(self, prompt, default=0):
910 """Prompt user with a message, read response, and ensure it matches
913 """Prompt user with a message, read response, and ensure it matches
911 one of the provided choices. The prompt is formatted as follows:
914 one of the provided choices. The prompt is formatted as follows:
912
915
913 "would you like fries with that (Yn)? $$ &Yes $$ &No"
916 "would you like fries with that (Yn)? $$ &Yes $$ &No"
914
917
915 The index of the choice is returned. Responses are case
918 The index of the choice is returned. Responses are case
916 insensitive. If ui is not interactive, the default is
919 insensitive. If ui is not interactive, the default is
917 returned.
920 returned.
918 """
921 """
919
922
920 msg, choices = self.extractchoices(prompt)
923 msg, choices = self.extractchoices(prompt)
921 resps = [r for r, t in choices]
924 resps = [r for r, t in choices]
922 while True:
925 while True:
923 r = self.prompt(msg, resps[default])
926 r = self.prompt(msg, resps[default])
924 if r.lower() in resps:
927 if r.lower() in resps:
925 return resps.index(r.lower())
928 return resps.index(r.lower())
926 self.write(_("unrecognized response\n"))
929 self.write(_("unrecognized response\n"))
927
930
928 def getpass(self, prompt=None, default=None):
931 def getpass(self, prompt=None, default=None):
929 if not self.interactive():
932 if not self.interactive():
930 return default
933 return default
931 try:
934 try:
932 self.write_err(self.label(prompt or _('password: '), 'ui.prompt'))
935 self.write_err(self.label(prompt or _('password: '), 'ui.prompt'))
933 # disable getpass() only if explicitly specified. it's still valid
936 # disable getpass() only if explicitly specified. it's still valid
934 # to interact with tty even if fin is not a tty.
937 # to interact with tty even if fin is not a tty.
935 if self.configbool('ui', 'nontty'):
938 if self.configbool('ui', 'nontty'):
936 return self.fin.readline().rstrip('\n')
939 return self.fin.readline().rstrip('\n')
937 else:
940 else:
938 return getpass.getpass('')
941 return getpass.getpass('')
939 except EOFError:
942 except EOFError:
940 raise error.ResponseExpected()
943 raise error.ResponseExpected()
941 def status(self, *msg, **opts):
944 def status(self, *msg, **opts):
942 '''write status message to output (if ui.quiet is False)
945 '''write status message to output (if ui.quiet is False)
943
946
944 This adds an output label of "ui.status".
947 This adds an output label of "ui.status".
945 '''
948 '''
946 if not self.quiet:
949 if not self.quiet:
947 opts['label'] = opts.get('label', '') + ' ui.status'
950 opts['label'] = opts.get('label', '') + ' ui.status'
948 self.write(*msg, **opts)
951 self.write(*msg, **opts)
949 def warn(self, *msg, **opts):
952 def warn(self, *msg, **opts):
950 '''write warning message to output (stderr)
953 '''write warning message to output (stderr)
951
954
952 This adds an output label of "ui.warning".
955 This adds an output label of "ui.warning".
953 '''
956 '''
954 opts['label'] = opts.get('label', '') + ' ui.warning'
957 opts['label'] = opts.get('label', '') + ' ui.warning'
955 self.write_err(*msg, **opts)
958 self.write_err(*msg, **opts)
956 def note(self, *msg, **opts):
959 def note(self, *msg, **opts):
957 '''write note to output (if ui.verbose is True)
960 '''write note to output (if ui.verbose is True)
958
961
959 This adds an output label of "ui.note".
962 This adds an output label of "ui.note".
960 '''
963 '''
961 if self.verbose:
964 if self.verbose:
962 opts['label'] = opts.get('label', '') + ' ui.note'
965 opts['label'] = opts.get('label', '') + ' ui.note'
963 self.write(*msg, **opts)
966 self.write(*msg, **opts)
964 def debug(self, *msg, **opts):
967 def debug(self, *msg, **opts):
965 '''write debug message to output (if ui.debugflag is True)
968 '''write debug message to output (if ui.debugflag is True)
966
969
967 This adds an output label of "ui.debug".
970 This adds an output label of "ui.debug".
968 '''
971 '''
969 if self.debugflag:
972 if self.debugflag:
970 opts['label'] = opts.get('label', '') + ' ui.debug'
973 opts['label'] = opts.get('label', '') + ' ui.debug'
971 self.write(*msg, **opts)
974 self.write(*msg, **opts)
972
975
973 def edit(self, text, user, extra=None, editform=None, pending=None):
976 def edit(self, text, user, extra=None, editform=None, pending=None):
974 extra_defaults = {
977 extra_defaults = {
975 'prefix': 'editor',
978 'prefix': 'editor',
976 'suffix': '.txt',
979 'suffix': '.txt',
977 }
980 }
978 if extra is not None:
981 if extra is not None:
979 extra_defaults.update(extra)
982 extra_defaults.update(extra)
980 extra = extra_defaults
983 extra = extra_defaults
981 (fd, name) = tempfile.mkstemp(prefix='hg-' + extra['prefix'] + '-',
984 (fd, name) = tempfile.mkstemp(prefix='hg-' + extra['prefix'] + '-',
982 suffix=extra['suffix'], text=True)
985 suffix=extra['suffix'], text=True)
983 try:
986 try:
984 f = os.fdopen(fd, "w")
987 f = os.fdopen(fd, "w")
985 f.write(text)
988 f.write(text)
986 f.close()
989 f.close()
987
990
988 environ = {'HGUSER': user}
991 environ = {'HGUSER': user}
989 if 'transplant_source' in extra:
992 if 'transplant_source' in extra:
990 environ.update({'HGREVISION': hex(extra['transplant_source'])})
993 environ.update({'HGREVISION': hex(extra['transplant_source'])})
991 for label in ('intermediate-source', 'source', 'rebase_source'):
994 for label in ('intermediate-source', 'source', 'rebase_source'):
992 if label in extra:
995 if label in extra:
993 environ.update({'HGREVISION': extra[label]})
996 environ.update({'HGREVISION': extra[label]})
994 break
997 break
995 if editform:
998 if editform:
996 environ.update({'HGEDITFORM': editform})
999 environ.update({'HGEDITFORM': editform})
997 if pending:
1000 if pending:
998 environ.update({'HG_PENDING': pending})
1001 environ.update({'HG_PENDING': pending})
999
1002
1000 editor = self.geteditor()
1003 editor = self.geteditor()
1001
1004
1002 self.system("%s \"%s\"" % (editor, name),
1005 self.system("%s \"%s\"" % (editor, name),
1003 environ=environ,
1006 environ=environ,
1004 onerr=error.Abort, errprefix=_("edit failed"))
1007 onerr=error.Abort, errprefix=_("edit failed"))
1005
1008
1006 f = open(name)
1009 f = open(name)
1007 t = f.read()
1010 t = f.read()
1008 f.close()
1011 f.close()
1009 finally:
1012 finally:
1010 os.unlink(name)
1013 os.unlink(name)
1011
1014
1012 return t
1015 return t
1013
1016
1014 def system(self, cmd, environ=None, cwd=None, onerr=None, errprefix=None):
1017 def system(self, cmd, environ=None, cwd=None, onerr=None, errprefix=None):
1015 '''execute shell command with appropriate output stream. command
1018 '''execute shell command with appropriate output stream. command
1016 output will be redirected if fout is not stdout.
1019 output will be redirected if fout is not stdout.
1017 '''
1020 '''
1018 out = self.fout
1021 out = self.fout
1019 if any(s[1] for s in self._bufferstates):
1022 if any(s[1] for s in self._bufferstates):
1020 out = self
1023 out = self
1021 return util.system(cmd, environ=environ, cwd=cwd, onerr=onerr,
1024 return util.system(cmd, environ=environ, cwd=cwd, onerr=onerr,
1022 errprefix=errprefix, out=out)
1025 errprefix=errprefix, out=out)
1023
1026
1024 def traceback(self, exc=None, force=False):
1027 def traceback(self, exc=None, force=False):
1025 '''print exception traceback if traceback printing enabled or forced.
1028 '''print exception traceback if traceback printing enabled or forced.
1026 only to call in exception handler. returns true if traceback
1029 only to call in exception handler. returns true if traceback
1027 printed.'''
1030 printed.'''
1028 if self.tracebackflag or force:
1031 if self.tracebackflag or force:
1029 if exc is None:
1032 if exc is None:
1030 exc = sys.exc_info()
1033 exc = sys.exc_info()
1031 cause = getattr(exc[1], 'cause', None)
1034 cause = getattr(exc[1], 'cause', None)
1032
1035
1033 if cause is not None:
1036 if cause is not None:
1034 causetb = traceback.format_tb(cause[2])
1037 causetb = traceback.format_tb(cause[2])
1035 exctb = traceback.format_tb(exc[2])
1038 exctb = traceback.format_tb(exc[2])
1036 exconly = traceback.format_exception_only(cause[0], cause[1])
1039 exconly = traceback.format_exception_only(cause[0], cause[1])
1037
1040
1038 # exclude frame where 'exc' was chained and rethrown from exctb
1041 # exclude frame where 'exc' was chained and rethrown from exctb
1039 self.write_err('Traceback (most recent call last):\n',
1042 self.write_err('Traceback (most recent call last):\n',
1040 ''.join(exctb[:-1]),
1043 ''.join(exctb[:-1]),
1041 ''.join(causetb),
1044 ''.join(causetb),
1042 ''.join(exconly))
1045 ''.join(exconly))
1043 else:
1046 else:
1044 output = traceback.format_exception(exc[0], exc[1], exc[2])
1047 output = traceback.format_exception(exc[0], exc[1], exc[2])
1045 self.write_err(''.join(output))
1048 self.write_err(''.join(output))
1046 return self.tracebackflag or force
1049 return self.tracebackflag or force
1047
1050
1048 def geteditor(self):
1051 def geteditor(self):
1049 '''return editor to use'''
1052 '''return editor to use'''
1050 if sys.platform == 'plan9':
1053 if sys.platform == 'plan9':
1051 # vi is the MIPS instruction simulator on Plan 9. We
1054 # vi is the MIPS instruction simulator on Plan 9. We
1052 # instead default to E to plumb commit messages to
1055 # instead default to E to plumb commit messages to
1053 # avoid confusion.
1056 # avoid confusion.
1054 editor = 'E'
1057 editor = 'E'
1055 else:
1058 else:
1056 editor = 'vi'
1059 editor = 'vi'
1057 return (os.environ.get("HGEDITOR") or
1060 return (os.environ.get("HGEDITOR") or
1058 self.config("ui", "editor") or
1061 self.config("ui", "editor") or
1059 os.environ.get("VISUAL") or
1062 os.environ.get("VISUAL") or
1060 os.environ.get("EDITOR", editor))
1063 os.environ.get("EDITOR", editor))
1061
1064
1062 @util.propertycache
1065 @util.propertycache
1063 def _progbar(self):
1066 def _progbar(self):
1064 """setup the progbar singleton to the ui object"""
1067 """setup the progbar singleton to the ui object"""
1065 if (self.quiet or self.debugflag
1068 if (self.quiet or self.debugflag
1066 or self.configbool('progress', 'disable', False)
1069 or self.configbool('progress', 'disable', False)
1067 or not progress.shouldprint(self)):
1070 or not progress.shouldprint(self)):
1068 return None
1071 return None
1069 return getprogbar(self)
1072 return getprogbar(self)
1070
1073
1071 def _progclear(self):
1074 def _progclear(self):
1072 """clear progress bar output if any. use it before any output"""
1075 """clear progress bar output if any. use it before any output"""
1073 if '_progbar' not in vars(self): # nothing loaded yet
1076 if '_progbar' not in vars(self): # nothing loaded yet
1074 return
1077 return
1075 if self._progbar is not None and self._progbar.printed:
1078 if self._progbar is not None and self._progbar.printed:
1076 self._progbar.clear()
1079 self._progbar.clear()
1077
1080
1078 def progress(self, topic, pos, item="", unit="", total=None):
1081 def progress(self, topic, pos, item="", unit="", total=None):
1079 '''show a progress message
1082 '''show a progress message
1080
1083
1081 By default a textual progress bar will be displayed if an operation
1084 By default a textual progress bar will be displayed if an operation
1082 takes too long. 'topic' is the current operation, 'item' is a
1085 takes too long. 'topic' is the current operation, 'item' is a
1083 non-numeric marker of the current position (i.e. the currently
1086 non-numeric marker of the current position (i.e. the currently
1084 in-process file), 'pos' is the current numeric position (i.e.
1087 in-process file), 'pos' is the current numeric position (i.e.
1085 revision, bytes, etc.), unit is a corresponding unit label,
1088 revision, bytes, etc.), unit is a corresponding unit label,
1086 and total is the highest expected pos.
1089 and total is the highest expected pos.
1087
1090
1088 Multiple nested topics may be active at a time.
1091 Multiple nested topics may be active at a time.
1089
1092
1090 All topics should be marked closed by setting pos to None at
1093 All topics should be marked closed by setting pos to None at
1091 termination.
1094 termination.
1092 '''
1095 '''
1093 if self._progbar is not None:
1096 if self._progbar is not None:
1094 self._progbar.progress(topic, pos, item=item, unit=unit,
1097 self._progbar.progress(topic, pos, item=item, unit=unit,
1095 total=total)
1098 total=total)
1096 if pos is None or not self.configbool('progress', 'debug'):
1099 if pos is None or not self.configbool('progress', 'debug'):
1097 return
1100 return
1098
1101
1099 if unit:
1102 if unit:
1100 unit = ' ' + unit
1103 unit = ' ' + unit
1101 if item:
1104 if item:
1102 item = ' ' + item
1105 item = ' ' + item
1103
1106
1104 if total:
1107 if total:
1105 pct = 100.0 * pos / total
1108 pct = 100.0 * pos / total
1106 self.debug('%s:%s %s/%s%s (%4.2f%%)\n'
1109 self.debug('%s:%s %s/%s%s (%4.2f%%)\n'
1107 % (topic, item, pos, total, unit, pct))
1110 % (topic, item, pos, total, unit, pct))
1108 else:
1111 else:
1109 self.debug('%s:%s %s%s\n' % (topic, item, pos, unit))
1112 self.debug('%s:%s %s%s\n' % (topic, item, pos, unit))
1110
1113
1111 def log(self, service, *msg, **opts):
1114 def log(self, service, *msg, **opts):
1112 '''hook for logging facility extensions
1115 '''hook for logging facility extensions
1113
1116
1114 service should be a readily-identifiable subsystem, which will
1117 service should be a readily-identifiable subsystem, which will
1115 allow filtering.
1118 allow filtering.
1116
1119
1117 *msg should be a newline-terminated format string to log, and
1120 *msg should be a newline-terminated format string to log, and
1118 then any values to %-format into that format string.
1121 then any values to %-format into that format string.
1119
1122
1120 **opts currently has no defined meanings.
1123 **opts currently has no defined meanings.
1121 '''
1124 '''
1122
1125
1123 def label(self, msg, label):
1126 def label(self, msg, label):
1124 '''style msg based on supplied label
1127 '''style msg based on supplied label
1125
1128
1126 Like ui.write(), this just returns msg unchanged, but extensions
1129 Like ui.write(), this just returns msg unchanged, but extensions
1127 and GUI tools can override it to allow styling output without
1130 and GUI tools can override it to allow styling output without
1128 writing it.
1131 writing it.
1129
1132
1130 ui.write(s, 'label') is equivalent to
1133 ui.write(s, 'label') is equivalent to
1131 ui.write(ui.label(s, 'label')).
1134 ui.write(ui.label(s, 'label')).
1132 '''
1135 '''
1133 return msg
1136 return msg
1134
1137
1135 def develwarn(self, msg, stacklevel=1):
1138 def develwarn(self, msg, stacklevel=1):
1136 """issue a developer warning message
1139 """issue a developer warning message
1137
1140
1138 Use 'stacklevel' to report the offender some layers further up in the
1141 Use 'stacklevel' to report the offender some layers further up in the
1139 stack.
1142 stack.
1140 """
1143 """
1141 msg = 'devel-warn: ' + msg
1144 msg = 'devel-warn: ' + msg
1142 stacklevel += 1 # get in develwarn
1145 stacklevel += 1 # get in develwarn
1143 if self.tracebackflag:
1146 if self.tracebackflag:
1144 util.debugstacktrace(msg, stacklevel, self.ferr, self.fout)
1147 util.debugstacktrace(msg, stacklevel, self.ferr, self.fout)
1145 self.log('develwarn', '%s at:\n%s' %
1148 self.log('develwarn', '%s at:\n%s' %
1146 (msg, ''.join(util.getstackframes(stacklevel))))
1149 (msg, ''.join(util.getstackframes(stacklevel))))
1147 else:
1150 else:
1148 curframe = inspect.currentframe()
1151 curframe = inspect.currentframe()
1149 calframe = inspect.getouterframes(curframe, 2)
1152 calframe = inspect.getouterframes(curframe, 2)
1150 self.write_err('%s at: %s:%s (%s)\n'
1153 self.write_err('%s at: %s:%s (%s)\n'
1151 % ((msg,) + calframe[stacklevel][1:4]))
1154 % ((msg,) + calframe[stacklevel][1:4]))
1152 self.log('develwarn', '%s at: %s:%s (%s)\n',
1155 self.log('develwarn', '%s at: %s:%s (%s)\n',
1153 msg, *calframe[stacklevel][1:4])
1156 msg, *calframe[stacklevel][1:4])
1154
1157
1155 def deprecwarn(self, msg, version):
1158 def deprecwarn(self, msg, version):
1156 """issue a deprecation warning
1159 """issue a deprecation warning
1157
1160
1158 - msg: message explaining what is deprecated and how to upgrade,
1161 - msg: message explaining what is deprecated and how to upgrade,
1159 - version: last version where the API will be supported,
1162 - version: last version where the API will be supported,
1160 """
1163 """
1161 msg += ("\n(compatibility will be dropped after Mercurial-%s,"
1164 msg += ("\n(compatibility will be dropped after Mercurial-%s,"
1162 " update your code.)") % version
1165 " update your code.)") % version
1163 self.develwarn(msg, stacklevel=2)
1166 self.develwarn(msg, stacklevel=2)
1164
1167
1165 class paths(dict):
1168 class paths(dict):
1166 """Represents a collection of paths and their configs.
1169 """Represents a collection of paths and their configs.
1167
1170
1168 Data is initially derived from ui instances and the config files they have
1171 Data is initially derived from ui instances and the config files they have
1169 loaded.
1172 loaded.
1170 """
1173 """
1171 def __init__(self, ui):
1174 def __init__(self, ui):
1172 dict.__init__(self)
1175 dict.__init__(self)
1173
1176
1174 for name, loc in ui.configitems('paths', ignoresub=True):
1177 for name, loc in ui.configitems('paths', ignoresub=True):
1175 # No location is the same as not existing.
1178 # No location is the same as not existing.
1176 if not loc:
1179 if not loc:
1177 continue
1180 continue
1178 loc, sub = ui.configsuboptions('paths', name)
1181 loc, sub = ui.configsuboptions('paths', name)
1179 self[name] = path(ui, name, rawloc=loc, suboptions=sub)
1182 self[name] = path(ui, name, rawloc=loc, suboptions=sub)
1180
1183
1181 def getpath(self, name, default=None):
1184 def getpath(self, name, default=None):
1182 """Return a ``path`` from a string, falling back to default.
1185 """Return a ``path`` from a string, falling back to default.
1183
1186
1184 ``name`` can be a named path or locations. Locations are filesystem
1187 ``name`` can be a named path or locations. Locations are filesystem
1185 paths or URIs.
1188 paths or URIs.
1186
1189
1187 Returns None if ``name`` is not a registered path, a URI, or a local
1190 Returns None if ``name`` is not a registered path, a URI, or a local
1188 path to a repo.
1191 path to a repo.
1189 """
1192 """
1190 # Only fall back to default if no path was requested.
1193 # Only fall back to default if no path was requested.
1191 if name is None:
1194 if name is None:
1192 if not default:
1195 if not default:
1193 default = ()
1196 default = ()
1194 elif not isinstance(default, (tuple, list)):
1197 elif not isinstance(default, (tuple, list)):
1195 default = (default,)
1198 default = (default,)
1196 for k in default:
1199 for k in default:
1197 try:
1200 try:
1198 return self[k]
1201 return self[k]
1199 except KeyError:
1202 except KeyError:
1200 continue
1203 continue
1201 return None
1204 return None
1202
1205
1203 # Most likely empty string.
1206 # Most likely empty string.
1204 # This may need to raise in the future.
1207 # This may need to raise in the future.
1205 if not name:
1208 if not name:
1206 return None
1209 return None
1207
1210
1208 try:
1211 try:
1209 return self[name]
1212 return self[name]
1210 except KeyError:
1213 except KeyError:
1211 # Try to resolve as a local path or URI.
1214 # Try to resolve as a local path or URI.
1212 try:
1215 try:
1213 # We don't pass sub-options in, so no need to pass ui instance.
1216 # We don't pass sub-options in, so no need to pass ui instance.
1214 return path(None, None, rawloc=name)
1217 return path(None, None, rawloc=name)
1215 except ValueError:
1218 except ValueError:
1216 raise error.RepoError(_('repository %s does not exist') %
1219 raise error.RepoError(_('repository %s does not exist') %
1217 name)
1220 name)
1218
1221
1219 _pathsuboptions = {}
1222 _pathsuboptions = {}
1220
1223
1221 def pathsuboption(option, attr):
1224 def pathsuboption(option, attr):
1222 """Decorator used to declare a path sub-option.
1225 """Decorator used to declare a path sub-option.
1223
1226
1224 Arguments are the sub-option name and the attribute it should set on
1227 Arguments are the sub-option name and the attribute it should set on
1225 ``path`` instances.
1228 ``path`` instances.
1226
1229
1227 The decorated function will receive as arguments a ``ui`` instance,
1230 The decorated function will receive as arguments a ``ui`` instance,
1228 ``path`` instance, and the string value of this option from the config.
1231 ``path`` instance, and the string value of this option from the config.
1229 The function should return the value that will be set on the ``path``
1232 The function should return the value that will be set on the ``path``
1230 instance.
1233 instance.
1231
1234
1232 This decorator can be used to perform additional verification of
1235 This decorator can be used to perform additional verification of
1233 sub-options and to change the type of sub-options.
1236 sub-options and to change the type of sub-options.
1234 """
1237 """
1235 def register(func):
1238 def register(func):
1236 _pathsuboptions[option] = (attr, func)
1239 _pathsuboptions[option] = (attr, func)
1237 return func
1240 return func
1238 return register
1241 return register
1239
1242
1240 @pathsuboption('pushurl', 'pushloc')
1243 @pathsuboption('pushurl', 'pushloc')
1241 def pushurlpathoption(ui, path, value):
1244 def pushurlpathoption(ui, path, value):
1242 u = util.url(value)
1245 u = util.url(value)
1243 # Actually require a URL.
1246 # Actually require a URL.
1244 if not u.scheme:
1247 if not u.scheme:
1245 ui.warn(_('(paths.%s:pushurl not a URL; ignoring)\n') % path.name)
1248 ui.warn(_('(paths.%s:pushurl not a URL; ignoring)\n') % path.name)
1246 return None
1249 return None
1247
1250
1248 # Don't support the #foo syntax in the push URL to declare branch to
1251 # Don't support the #foo syntax in the push URL to declare branch to
1249 # push.
1252 # push.
1250 if u.fragment:
1253 if u.fragment:
1251 ui.warn(_('("#fragment" in paths.%s:pushurl not supported; '
1254 ui.warn(_('("#fragment" in paths.%s:pushurl not supported; '
1252 'ignoring)\n') % path.name)
1255 'ignoring)\n') % path.name)
1253 u.fragment = None
1256 u.fragment = None
1254
1257
1255 return str(u)
1258 return str(u)
1256
1259
1257 class path(object):
1260 class path(object):
1258 """Represents an individual path and its configuration."""
1261 """Represents an individual path and its configuration."""
1259
1262
1260 def __init__(self, ui, name, rawloc=None, suboptions=None):
1263 def __init__(self, ui, name, rawloc=None, suboptions=None):
1261 """Construct a path from its config options.
1264 """Construct a path from its config options.
1262
1265
1263 ``ui`` is the ``ui`` instance the path is coming from.
1266 ``ui`` is the ``ui`` instance the path is coming from.
1264 ``name`` is the symbolic name of the path.
1267 ``name`` is the symbolic name of the path.
1265 ``rawloc`` is the raw location, as defined in the config.
1268 ``rawloc`` is the raw location, as defined in the config.
1266 ``pushloc`` is the raw locations pushes should be made to.
1269 ``pushloc`` is the raw locations pushes should be made to.
1267
1270
1268 If ``name`` is not defined, we require that the location be a) a local
1271 If ``name`` is not defined, we require that the location be a) a local
1269 filesystem path with a .hg directory or b) a URL. If not,
1272 filesystem path with a .hg directory or b) a URL. If not,
1270 ``ValueError`` is raised.
1273 ``ValueError`` is raised.
1271 """
1274 """
1272 if not rawloc:
1275 if not rawloc:
1273 raise ValueError('rawloc must be defined')
1276 raise ValueError('rawloc must be defined')
1274
1277
1275 # Locations may define branches via syntax <base>#<branch>.
1278 # Locations may define branches via syntax <base>#<branch>.
1276 u = util.url(rawloc)
1279 u = util.url(rawloc)
1277 branch = None
1280 branch = None
1278 if u.fragment:
1281 if u.fragment:
1279 branch = u.fragment
1282 branch = u.fragment
1280 u.fragment = None
1283 u.fragment = None
1281
1284
1282 self.url = u
1285 self.url = u
1283 self.branch = branch
1286 self.branch = branch
1284
1287
1285 self.name = name
1288 self.name = name
1286 self.rawloc = rawloc
1289 self.rawloc = rawloc
1287 self.loc = str(u)
1290 self.loc = str(u)
1288
1291
1289 # When given a raw location but not a symbolic name, validate the
1292 # When given a raw location but not a symbolic name, validate the
1290 # location is valid.
1293 # location is valid.
1291 if not name and not u.scheme and not self._isvalidlocalpath(self.loc):
1294 if not name and not u.scheme and not self._isvalidlocalpath(self.loc):
1292 raise ValueError('location is not a URL or path to a local '
1295 raise ValueError('location is not a URL or path to a local '
1293 'repo: %s' % rawloc)
1296 'repo: %s' % rawloc)
1294
1297
1295 suboptions = suboptions or {}
1298 suboptions = suboptions or {}
1296
1299
1297 # Now process the sub-options. If a sub-option is registered, its
1300 # Now process the sub-options. If a sub-option is registered, its
1298 # attribute will always be present. The value will be None if there
1301 # attribute will always be present. The value will be None if there
1299 # was no valid sub-option.
1302 # was no valid sub-option.
1300 for suboption, (attr, func) in _pathsuboptions.iteritems():
1303 for suboption, (attr, func) in _pathsuboptions.iteritems():
1301 if suboption not in suboptions:
1304 if suboption not in suboptions:
1302 setattr(self, attr, None)
1305 setattr(self, attr, None)
1303 continue
1306 continue
1304
1307
1305 value = func(ui, self, suboptions[suboption])
1308 value = func(ui, self, suboptions[suboption])
1306 setattr(self, attr, value)
1309 setattr(self, attr, value)
1307
1310
1308 def _isvalidlocalpath(self, path):
1311 def _isvalidlocalpath(self, path):
1309 """Returns True if the given path is a potentially valid repository.
1312 """Returns True if the given path is a potentially valid repository.
1310 This is its own function so that extensions can change the definition of
1313 This is its own function so that extensions can change the definition of
1311 'valid' in this case (like when pulling from a git repo into a hg
1314 'valid' in this case (like when pulling from a git repo into a hg
1312 one)."""
1315 one)."""
1313 return os.path.isdir(os.path.join(path, '.hg'))
1316 return os.path.isdir(os.path.join(path, '.hg'))
1314
1317
1315 @property
1318 @property
1316 def suboptions(self):
1319 def suboptions(self):
1317 """Return sub-options and their values for this path.
1320 """Return sub-options and their values for this path.
1318
1321
1319 This is intended to be used for presentation purposes.
1322 This is intended to be used for presentation purposes.
1320 """
1323 """
1321 d = {}
1324 d = {}
1322 for subopt, (attr, _func) in _pathsuboptions.iteritems():
1325 for subopt, (attr, _func) in _pathsuboptions.iteritems():
1323 value = getattr(self, attr)
1326 value = getattr(self, attr)
1324 if value is not None:
1327 if value is not None:
1325 d[subopt] = value
1328 d[subopt] = value
1326 return d
1329 return d
1327
1330
1328 # we instantiate one globally shared progress bar to avoid
1331 # we instantiate one globally shared progress bar to avoid
1329 # competing progress bars when multiple UI objects get created
1332 # competing progress bars when multiple UI objects get created
1330 _progresssingleton = None
1333 _progresssingleton = None
1331
1334
1332 def getprogbar(ui):
1335 def getprogbar(ui):
1333 global _progresssingleton
1336 global _progresssingleton
1334 if _progresssingleton is None:
1337 if _progresssingleton is None:
1335 # passing 'ui' object to the singleton is fishy,
1338 # passing 'ui' object to the singleton is fishy,
1336 # this is how the extension used to work but feel free to rework it.
1339 # this is how the extension used to work but feel free to rework it.
1337 _progresssingleton = progress.progbar(ui)
1340 _progresssingleton = progress.progbar(ui)
1338 return _progresssingleton
1341 return _progresssingleton
@@ -1,3833 +1,3840 b''
1 $ hg init a
1 $ hg init a
2 $ cd a
2 $ cd a
3 $ echo a > a
3 $ echo a > a
4 $ hg add a
4 $ hg add a
5 $ echo line 1 > b
5 $ echo line 1 > b
6 $ echo line 2 >> b
6 $ echo line 2 >> b
7 $ hg commit -l b -d '1000000 0' -u 'User Name <user@hostname>'
7 $ hg commit -l b -d '1000000 0' -u 'User Name <user@hostname>'
8
8
9 $ hg add b
9 $ hg add b
10 $ echo other 1 > c
10 $ echo other 1 > c
11 $ echo other 2 >> c
11 $ echo other 2 >> c
12 $ echo >> c
12 $ echo >> c
13 $ echo other 3 >> c
13 $ echo other 3 >> c
14 $ hg commit -l c -d '1100000 0' -u 'A. N. Other <other@place>'
14 $ hg commit -l c -d '1100000 0' -u 'A. N. Other <other@place>'
15
15
16 $ hg add c
16 $ hg add c
17 $ hg commit -m 'no person' -d '1200000 0' -u 'other@place'
17 $ hg commit -m 'no person' -d '1200000 0' -u 'other@place'
18 $ echo c >> c
18 $ echo c >> c
19 $ hg commit -m 'no user, no domain' -d '1300000 0' -u 'person'
19 $ hg commit -m 'no user, no domain' -d '1300000 0' -u 'person'
20
20
21 $ echo foo > .hg/branch
21 $ echo foo > .hg/branch
22 $ hg commit -m 'new branch' -d '1400000 0' -u 'person'
22 $ hg commit -m 'new branch' -d '1400000 0' -u 'person'
23
23
24 $ hg co -q 3
24 $ hg co -q 3
25 $ echo other 4 >> d
25 $ echo other 4 >> d
26 $ hg add d
26 $ hg add d
27 $ hg commit -m 'new head' -d '1500000 0' -u 'person'
27 $ hg commit -m 'new head' -d '1500000 0' -u 'person'
28
28
29 $ hg merge -q foo
29 $ hg merge -q foo
30 $ hg commit -m 'merge' -d '1500001 0' -u 'person'
30 $ hg commit -m 'merge' -d '1500001 0' -u 'person'
31
31
32 Second branch starting at nullrev:
32 Second branch starting at nullrev:
33
33
34 $ hg update null
34 $ hg update null
35 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
35 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
36 $ echo second > second
36 $ echo second > second
37 $ hg add second
37 $ hg add second
38 $ hg commit -m second -d '1000000 0' -u 'User Name <user@hostname>'
38 $ hg commit -m second -d '1000000 0' -u 'User Name <user@hostname>'
39 created new head
39 created new head
40
40
41 $ echo third > third
41 $ echo third > third
42 $ hg add third
42 $ hg add third
43 $ hg mv second fourth
43 $ hg mv second fourth
44 $ hg commit -m third -d "2020-01-01 10:01"
44 $ hg commit -m third -d "2020-01-01 10:01"
45
45
46 $ hg log --template '{join(file_copies, ",\n")}\n' -r .
46 $ hg log --template '{join(file_copies, ",\n")}\n' -r .
47 fourth (second)
47 fourth (second)
48 $ hg log -T '{file_copies % "{source} -> {name}\n"}' -r .
48 $ hg log -T '{file_copies % "{source} -> {name}\n"}' -r .
49 second -> fourth
49 second -> fourth
50 $ hg log -T '{rev} {ifcontains("fourth", file_copies, "t", "f")}\n' -r .:7
50 $ hg log -T '{rev} {ifcontains("fourth", file_copies, "t", "f")}\n' -r .:7
51 8 t
51 8 t
52 7 f
52 7 f
53
53
54 Working-directory revision has special identifiers, though they are still
54 Working-directory revision has special identifiers, though they are still
55 experimental:
55 experimental:
56
56
57 $ hg log -r 'wdir()' -T '{rev}:{node}\n'
57 $ hg log -r 'wdir()' -T '{rev}:{node}\n'
58 2147483647:ffffffffffffffffffffffffffffffffffffffff
58 2147483647:ffffffffffffffffffffffffffffffffffffffff
59
59
60 Some keywords are invalid for working-directory revision, but they should
60 Some keywords are invalid for working-directory revision, but they should
61 never cause crash:
61 never cause crash:
62
62
63 $ hg log -r 'wdir()' -T '{manifest}\n'
63 $ hg log -r 'wdir()' -T '{manifest}\n'
64
64
65
65
66 Quoting for ui.logtemplate
66 Quoting for ui.logtemplate
67
67
68 $ hg tip --config "ui.logtemplate={rev}\n"
68 $ hg tip --config "ui.logtemplate={rev}\n"
69 8
69 8
70 $ hg tip --config "ui.logtemplate='{rev}\n'"
70 $ hg tip --config "ui.logtemplate='{rev}\n'"
71 8
71 8
72 $ hg tip --config 'ui.logtemplate="{rev}\n"'
72 $ hg tip --config 'ui.logtemplate="{rev}\n"'
73 8
73 8
74 $ hg tip --config 'ui.logtemplate=n{rev}\n'
74 $ hg tip --config 'ui.logtemplate=n{rev}\n'
75 n8
75 n8
76
76
77 Make sure user/global hgrc does not affect tests
77 Make sure user/global hgrc does not affect tests
78
78
79 $ echo '[ui]' > .hg/hgrc
79 $ echo '[ui]' > .hg/hgrc
80 $ echo 'logtemplate =' >> .hg/hgrc
80 $ echo 'logtemplate =' >> .hg/hgrc
81 $ echo 'style =' >> .hg/hgrc
81 $ echo 'style =' >> .hg/hgrc
82
82
83 Add some simple styles to settings
83 Add some simple styles to settings
84
84
85 $ echo '[templates]' >> .hg/hgrc
85 $ echo '[templates]' >> .hg/hgrc
86 $ printf 'simple = "{rev}\\n"\n' >> .hg/hgrc
86 $ printf 'simple = "{rev}\\n"\n' >> .hg/hgrc
87 $ printf 'simple2 = {rev}\\n\n' >> .hg/hgrc
87 $ printf 'simple2 = {rev}\\n\n' >> .hg/hgrc
88
88
89 $ hg log -l1 -Tsimple
89 $ hg log -l1 -Tsimple
90 8
90 8
91 $ hg log -l1 -Tsimple2
91 $ hg log -l1 -Tsimple2
92 8
92 8
93
93
94 Test templates and style maps in files:
94 Test templates and style maps in files:
95
95
96 $ echo "{rev}" > tmpl
96 $ echo "{rev}" > tmpl
97 $ hg log -l1 -T./tmpl
97 $ hg log -l1 -T./tmpl
98 8
98 8
99 $ hg log -l1 -Tblah/blah
99 $ hg log -l1 -Tblah/blah
100 blah/blah (no-eol)
100 blah/blah (no-eol)
101
101
102 $ printf 'changeset = "{rev}\\n"\n' > map-simple
102 $ printf 'changeset = "{rev}\\n"\n' > map-simple
103 $ hg log -l1 -T./map-simple
103 $ hg log -l1 -T./map-simple
104 8
104 8
105
105
106 Template should precede style option
106 Template should precede style option
107
107
108 $ hg log -l1 --style default -T '{rev}\n'
108 $ hg log -l1 --style default -T '{rev}\n'
109 8
109 8
110
110
111 Add a commit with empty description, to ensure that the templates
111 Add a commit with empty description, to ensure that the templates
112 below will omit the description line.
112 below will omit the description line.
113
113
114 $ echo c >> c
114 $ echo c >> c
115 $ hg add c
115 $ hg add c
116 $ hg commit -qm ' '
116 $ hg commit -qm ' '
117
117
118 Default style is like normal output. Phases style should be the same
118 Default style is like normal output. Phases style should be the same
119 as default style, except for extra phase lines.
119 as default style, except for extra phase lines.
120
120
121 $ hg log > log.out
121 $ hg log > log.out
122 $ hg log --style default > style.out
122 $ hg log --style default > style.out
123 $ cmp log.out style.out || diff -u log.out style.out
123 $ cmp log.out style.out || diff -u log.out style.out
124 $ hg log -T phases > phases.out
124 $ hg log -T phases > phases.out
125 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
125 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
126 +phase: draft
126 +phase: draft
127 +phase: draft
127 +phase: draft
128 +phase: draft
128 +phase: draft
129 +phase: draft
129 +phase: draft
130 +phase: draft
130 +phase: draft
131 +phase: draft
131 +phase: draft
132 +phase: draft
132 +phase: draft
133 +phase: draft
133 +phase: draft
134 +phase: draft
134 +phase: draft
135 +phase: draft
135 +phase: draft
136
136
137 $ hg log -v > log.out
137 $ hg log -v > log.out
138 $ hg log -v --style default > style.out
138 $ hg log -v --style default > style.out
139 $ cmp log.out style.out || diff -u log.out style.out
139 $ cmp log.out style.out || diff -u log.out style.out
140 $ hg log -v -T phases > phases.out
140 $ hg log -v -T phases > phases.out
141 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
141 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
142 +phase: draft
142 +phase: draft
143 +phase: draft
143 +phase: draft
144 +phase: draft
144 +phase: draft
145 +phase: draft
145 +phase: draft
146 +phase: draft
146 +phase: draft
147 +phase: draft
147 +phase: draft
148 +phase: draft
148 +phase: draft
149 +phase: draft
149 +phase: draft
150 +phase: draft
150 +phase: draft
151 +phase: draft
151 +phase: draft
152
152
153 $ hg log -q > log.out
153 $ hg log -q > log.out
154 $ hg log -q --style default > style.out
154 $ hg log -q --style default > style.out
155 $ cmp log.out style.out || diff -u log.out style.out
155 $ cmp log.out style.out || diff -u log.out style.out
156 $ hg log -q -T phases > phases.out
156 $ hg log -q -T phases > phases.out
157 $ cmp log.out phases.out || diff -u log.out phases.out
157 $ cmp log.out phases.out || diff -u log.out phases.out
158
158
159 $ hg log --debug > log.out
159 $ hg log --debug > log.out
160 $ hg log --debug --style default > style.out
160 $ hg log --debug --style default > style.out
161 $ cmp log.out style.out || diff -u log.out style.out
161 $ cmp log.out style.out || diff -u log.out style.out
162 $ hg log --debug -T phases > phases.out
162 $ hg log --debug -T phases > phases.out
163 $ cmp log.out phases.out || diff -u log.out phases.out
163 $ cmp log.out phases.out || diff -u log.out phases.out
164
164
165 Default style of working-directory revision should also be the same (but
165 Default style of working-directory revision should also be the same (but
166 date may change while running tests):
166 date may change while running tests):
167
167
168 $ hg log -r 'wdir()' | sed 's|^date:.*|date:|' > log.out
168 $ hg log -r 'wdir()' | sed 's|^date:.*|date:|' > log.out
169 $ hg log -r 'wdir()' --style default | sed 's|^date:.*|date:|' > style.out
169 $ hg log -r 'wdir()' --style default | sed 's|^date:.*|date:|' > style.out
170 $ cmp log.out style.out || diff -u log.out style.out
170 $ cmp log.out style.out || diff -u log.out style.out
171
171
172 $ hg log -r 'wdir()' -v | sed 's|^date:.*|date:|' > log.out
172 $ hg log -r 'wdir()' -v | sed 's|^date:.*|date:|' > log.out
173 $ hg log -r 'wdir()' -v --style default | sed 's|^date:.*|date:|' > style.out
173 $ hg log -r 'wdir()' -v --style default | sed 's|^date:.*|date:|' > style.out
174 $ cmp log.out style.out || diff -u log.out style.out
174 $ cmp log.out style.out || diff -u log.out style.out
175
175
176 $ hg log -r 'wdir()' -q > log.out
176 $ hg log -r 'wdir()' -q > log.out
177 $ hg log -r 'wdir()' -q --style default > style.out
177 $ hg log -r 'wdir()' -q --style default > style.out
178 $ cmp log.out style.out || diff -u log.out style.out
178 $ cmp log.out style.out || diff -u log.out style.out
179
179
180 $ hg log -r 'wdir()' --debug | sed 's|^date:.*|date:|' > log.out
180 $ hg log -r 'wdir()' --debug | sed 's|^date:.*|date:|' > log.out
181 $ hg log -r 'wdir()' --debug --style default \
181 $ hg log -r 'wdir()' --debug --style default \
182 > | sed 's|^date:.*|date:|' > style.out
182 > | sed 's|^date:.*|date:|' > style.out
183 $ cmp log.out style.out || diff -u log.out style.out
183 $ cmp log.out style.out || diff -u log.out style.out
184
184
185 Default style should also preserve color information (issue2866):
185 Default style should also preserve color information (issue2866):
186
186
187 $ cp $HGRCPATH $HGRCPATH-bak
187 $ cp $HGRCPATH $HGRCPATH-bak
188 $ cat <<EOF >> $HGRCPATH
188 $ cat <<EOF >> $HGRCPATH
189 > [extensions]
189 > [extensions]
190 > color=
190 > color=
191 > EOF
191 > EOF
192
192
193 $ hg --color=debug log > log.out
193 $ hg --color=debug log > log.out
194 $ hg --color=debug log --style default > style.out
194 $ hg --color=debug log --style default > style.out
195 $ cmp log.out style.out || diff -u log.out style.out
195 $ cmp log.out style.out || diff -u log.out style.out
196 $ hg --color=debug log -T phases > phases.out
196 $ hg --color=debug log -T phases > phases.out
197 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
197 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
198 +[log.phase|phase: draft]
198 +[log.phase|phase: draft]
199 +[log.phase|phase: draft]
199 +[log.phase|phase: draft]
200 +[log.phase|phase: draft]
200 +[log.phase|phase: draft]
201 +[log.phase|phase: draft]
201 +[log.phase|phase: draft]
202 +[log.phase|phase: draft]
202 +[log.phase|phase: draft]
203 +[log.phase|phase: draft]
203 +[log.phase|phase: draft]
204 +[log.phase|phase: draft]
204 +[log.phase|phase: draft]
205 +[log.phase|phase: draft]
205 +[log.phase|phase: draft]
206 +[log.phase|phase: draft]
206 +[log.phase|phase: draft]
207 +[log.phase|phase: draft]
207 +[log.phase|phase: draft]
208
208
209 $ hg --color=debug -v log > log.out
209 $ hg --color=debug -v log > log.out
210 $ hg --color=debug -v log --style default > style.out
210 $ hg --color=debug -v log --style default > style.out
211 $ cmp log.out style.out || diff -u log.out style.out
211 $ cmp log.out style.out || diff -u log.out style.out
212 $ hg --color=debug -v log -T phases > phases.out
212 $ hg --color=debug -v log -T phases > phases.out
213 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
213 $ diff -U 0 log.out phases.out | egrep -v '^---|^\+\+\+|^@@'
214 +[log.phase|phase: draft]
214 +[log.phase|phase: draft]
215 +[log.phase|phase: draft]
215 +[log.phase|phase: draft]
216 +[log.phase|phase: draft]
216 +[log.phase|phase: draft]
217 +[log.phase|phase: draft]
217 +[log.phase|phase: draft]
218 +[log.phase|phase: draft]
218 +[log.phase|phase: draft]
219 +[log.phase|phase: draft]
219 +[log.phase|phase: draft]
220 +[log.phase|phase: draft]
220 +[log.phase|phase: draft]
221 +[log.phase|phase: draft]
221 +[log.phase|phase: draft]
222 +[log.phase|phase: draft]
222 +[log.phase|phase: draft]
223 +[log.phase|phase: draft]
223 +[log.phase|phase: draft]
224
224
225 $ hg --color=debug -q log > log.out
225 $ hg --color=debug -q log > log.out
226 $ hg --color=debug -q log --style default > style.out
226 $ hg --color=debug -q log --style default > style.out
227 $ cmp log.out style.out || diff -u log.out style.out
227 $ cmp log.out style.out || diff -u log.out style.out
228 $ hg --color=debug -q log -T phases > phases.out
228 $ hg --color=debug -q log -T phases > phases.out
229 $ cmp log.out phases.out || diff -u log.out phases.out
229 $ cmp log.out phases.out || diff -u log.out phases.out
230
230
231 $ hg --color=debug --debug log > log.out
231 $ hg --color=debug --debug log > log.out
232 $ hg --color=debug --debug log --style default > style.out
232 $ hg --color=debug --debug log --style default > style.out
233 $ cmp log.out style.out || diff -u log.out style.out
233 $ cmp log.out style.out || diff -u log.out style.out
234 $ hg --color=debug --debug log -T phases > phases.out
234 $ hg --color=debug --debug log -T phases > phases.out
235 $ cmp log.out phases.out || diff -u log.out phases.out
235 $ cmp log.out phases.out || diff -u log.out phases.out
236
236
237 $ mv $HGRCPATH-bak $HGRCPATH
237 $ mv $HGRCPATH-bak $HGRCPATH
238
238
239 Remove commit with empty commit message, so as to not pollute further
239 Remove commit with empty commit message, so as to not pollute further
240 tests.
240 tests.
241
241
242 $ hg --config extensions.strip= strip -q .
242 $ hg --config extensions.strip= strip -q .
243
243
244 Revision with no copies (used to print a traceback):
244 Revision with no copies (used to print a traceback):
245
245
246 $ hg tip -v --template '\n'
246 $ hg tip -v --template '\n'
247
247
248
248
249 Compact style works:
249 Compact style works:
250
250
251 $ hg log -Tcompact
251 $ hg log -Tcompact
252 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
252 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
253 third
253 third
254
254
255 7:-1 29114dbae42b 1970-01-12 13:46 +0000 user
255 7:-1 29114dbae42b 1970-01-12 13:46 +0000 user
256 second
256 second
257
257
258 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
258 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
259 merge
259 merge
260
260
261 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
261 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
262 new head
262 new head
263
263
264 4 bbe44766e73d 1970-01-17 04:53 +0000 person
264 4 bbe44766e73d 1970-01-17 04:53 +0000 person
265 new branch
265 new branch
266
266
267 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
267 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
268 no user, no domain
268 no user, no domain
269
269
270 2 97054abb4ab8 1970-01-14 21:20 +0000 other
270 2 97054abb4ab8 1970-01-14 21:20 +0000 other
271 no person
271 no person
272
272
273 1 b608e9d1a3f0 1970-01-13 17:33 +0000 other
273 1 b608e9d1a3f0 1970-01-13 17:33 +0000 other
274 other 1
274 other 1
275
275
276 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 user
276 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 user
277 line 1
277 line 1
278
278
279
279
280 $ hg log -v --style compact
280 $ hg log -v --style compact
281 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
281 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
282 third
282 third
283
283
284 7:-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
284 7:-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
285 second
285 second
286
286
287 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
287 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
288 merge
288 merge
289
289
290 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
290 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
291 new head
291 new head
292
292
293 4 bbe44766e73d 1970-01-17 04:53 +0000 person
293 4 bbe44766e73d 1970-01-17 04:53 +0000 person
294 new branch
294 new branch
295
295
296 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
296 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
297 no user, no domain
297 no user, no domain
298
298
299 2 97054abb4ab8 1970-01-14 21:20 +0000 other@place
299 2 97054abb4ab8 1970-01-14 21:20 +0000 other@place
300 no person
300 no person
301
301
302 1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
302 1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
303 other 1
303 other 1
304 other 2
304 other 2
305
305
306 other 3
306 other 3
307
307
308 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
308 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
309 line 1
309 line 1
310 line 2
310 line 2
311
311
312
312
313 $ hg log --debug --style compact
313 $ hg log --debug --style compact
314 8[tip]:7,-1 95c24699272e 2020-01-01 10:01 +0000 test
314 8[tip]:7,-1 95c24699272e 2020-01-01 10:01 +0000 test
315 third
315 third
316
316
317 7:-1,-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
317 7:-1,-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
318 second
318 second
319
319
320 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
320 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
321 merge
321 merge
322
322
323 5:3,-1 13207e5a10d9 1970-01-18 08:40 +0000 person
323 5:3,-1 13207e5a10d9 1970-01-18 08:40 +0000 person
324 new head
324 new head
325
325
326 4:3,-1 bbe44766e73d 1970-01-17 04:53 +0000 person
326 4:3,-1 bbe44766e73d 1970-01-17 04:53 +0000 person
327 new branch
327 new branch
328
328
329 3:2,-1 10e46f2dcbf4 1970-01-16 01:06 +0000 person
329 3:2,-1 10e46f2dcbf4 1970-01-16 01:06 +0000 person
330 no user, no domain
330 no user, no domain
331
331
332 2:1,-1 97054abb4ab8 1970-01-14 21:20 +0000 other@place
332 2:1,-1 97054abb4ab8 1970-01-14 21:20 +0000 other@place
333 no person
333 no person
334
334
335 1:0,-1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
335 1:0,-1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
336 other 1
336 other 1
337 other 2
337 other 2
338
338
339 other 3
339 other 3
340
340
341 0:-1,-1 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
341 0:-1,-1 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
342 line 1
342 line 1
343 line 2
343 line 2
344
344
345
345
346 Test xml styles:
346 Test xml styles:
347
347
348 $ hg log --style xml -r 'not all()'
348 $ hg log --style xml -r 'not all()'
349 <?xml version="1.0"?>
349 <?xml version="1.0"?>
350 <log>
350 <log>
351 </log>
351 </log>
352
352
353 $ hg log --style xml
353 $ hg log --style xml
354 <?xml version="1.0"?>
354 <?xml version="1.0"?>
355 <log>
355 <log>
356 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
356 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
357 <tag>tip</tag>
357 <tag>tip</tag>
358 <author email="test">test</author>
358 <author email="test">test</author>
359 <date>2020-01-01T10:01:00+00:00</date>
359 <date>2020-01-01T10:01:00+00:00</date>
360 <msg xml:space="preserve">third</msg>
360 <msg xml:space="preserve">third</msg>
361 </logentry>
361 </logentry>
362 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
362 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
363 <parent revision="-1" node="0000000000000000000000000000000000000000" />
363 <parent revision="-1" node="0000000000000000000000000000000000000000" />
364 <author email="user@hostname">User Name</author>
364 <author email="user@hostname">User Name</author>
365 <date>1970-01-12T13:46:40+00:00</date>
365 <date>1970-01-12T13:46:40+00:00</date>
366 <msg xml:space="preserve">second</msg>
366 <msg xml:space="preserve">second</msg>
367 </logentry>
367 </logentry>
368 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
368 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
369 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
369 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
370 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
370 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
371 <author email="person">person</author>
371 <author email="person">person</author>
372 <date>1970-01-18T08:40:01+00:00</date>
372 <date>1970-01-18T08:40:01+00:00</date>
373 <msg xml:space="preserve">merge</msg>
373 <msg xml:space="preserve">merge</msg>
374 </logentry>
374 </logentry>
375 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
375 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
376 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
376 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
377 <author email="person">person</author>
377 <author email="person">person</author>
378 <date>1970-01-18T08:40:00+00:00</date>
378 <date>1970-01-18T08:40:00+00:00</date>
379 <msg xml:space="preserve">new head</msg>
379 <msg xml:space="preserve">new head</msg>
380 </logentry>
380 </logentry>
381 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
381 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
382 <branch>foo</branch>
382 <branch>foo</branch>
383 <author email="person">person</author>
383 <author email="person">person</author>
384 <date>1970-01-17T04:53:20+00:00</date>
384 <date>1970-01-17T04:53:20+00:00</date>
385 <msg xml:space="preserve">new branch</msg>
385 <msg xml:space="preserve">new branch</msg>
386 </logentry>
386 </logentry>
387 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
387 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
388 <author email="person">person</author>
388 <author email="person">person</author>
389 <date>1970-01-16T01:06:40+00:00</date>
389 <date>1970-01-16T01:06:40+00:00</date>
390 <msg xml:space="preserve">no user, no domain</msg>
390 <msg xml:space="preserve">no user, no domain</msg>
391 </logentry>
391 </logentry>
392 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
392 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
393 <author email="other@place">other</author>
393 <author email="other@place">other</author>
394 <date>1970-01-14T21:20:00+00:00</date>
394 <date>1970-01-14T21:20:00+00:00</date>
395 <msg xml:space="preserve">no person</msg>
395 <msg xml:space="preserve">no person</msg>
396 </logentry>
396 </logentry>
397 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
397 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
398 <author email="other@place">A. N. Other</author>
398 <author email="other@place">A. N. Other</author>
399 <date>1970-01-13T17:33:20+00:00</date>
399 <date>1970-01-13T17:33:20+00:00</date>
400 <msg xml:space="preserve">other 1
400 <msg xml:space="preserve">other 1
401 other 2
401 other 2
402
402
403 other 3</msg>
403 other 3</msg>
404 </logentry>
404 </logentry>
405 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
405 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
406 <author email="user@hostname">User Name</author>
406 <author email="user@hostname">User Name</author>
407 <date>1970-01-12T13:46:40+00:00</date>
407 <date>1970-01-12T13:46:40+00:00</date>
408 <msg xml:space="preserve">line 1
408 <msg xml:space="preserve">line 1
409 line 2</msg>
409 line 2</msg>
410 </logentry>
410 </logentry>
411 </log>
411 </log>
412
412
413 $ hg log -v --style xml
413 $ hg log -v --style xml
414 <?xml version="1.0"?>
414 <?xml version="1.0"?>
415 <log>
415 <log>
416 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
416 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
417 <tag>tip</tag>
417 <tag>tip</tag>
418 <author email="test">test</author>
418 <author email="test">test</author>
419 <date>2020-01-01T10:01:00+00:00</date>
419 <date>2020-01-01T10:01:00+00:00</date>
420 <msg xml:space="preserve">third</msg>
420 <msg xml:space="preserve">third</msg>
421 <paths>
421 <paths>
422 <path action="A">fourth</path>
422 <path action="A">fourth</path>
423 <path action="A">third</path>
423 <path action="A">third</path>
424 <path action="R">second</path>
424 <path action="R">second</path>
425 </paths>
425 </paths>
426 <copies>
426 <copies>
427 <copy source="second">fourth</copy>
427 <copy source="second">fourth</copy>
428 </copies>
428 </copies>
429 </logentry>
429 </logentry>
430 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
430 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
431 <parent revision="-1" node="0000000000000000000000000000000000000000" />
431 <parent revision="-1" node="0000000000000000000000000000000000000000" />
432 <author email="user@hostname">User Name</author>
432 <author email="user@hostname">User Name</author>
433 <date>1970-01-12T13:46:40+00:00</date>
433 <date>1970-01-12T13:46:40+00:00</date>
434 <msg xml:space="preserve">second</msg>
434 <msg xml:space="preserve">second</msg>
435 <paths>
435 <paths>
436 <path action="A">second</path>
436 <path action="A">second</path>
437 </paths>
437 </paths>
438 </logentry>
438 </logentry>
439 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
439 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
440 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
440 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
441 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
441 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
442 <author email="person">person</author>
442 <author email="person">person</author>
443 <date>1970-01-18T08:40:01+00:00</date>
443 <date>1970-01-18T08:40:01+00:00</date>
444 <msg xml:space="preserve">merge</msg>
444 <msg xml:space="preserve">merge</msg>
445 <paths>
445 <paths>
446 </paths>
446 </paths>
447 </logentry>
447 </logentry>
448 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
448 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
449 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
449 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
450 <author email="person">person</author>
450 <author email="person">person</author>
451 <date>1970-01-18T08:40:00+00:00</date>
451 <date>1970-01-18T08:40:00+00:00</date>
452 <msg xml:space="preserve">new head</msg>
452 <msg xml:space="preserve">new head</msg>
453 <paths>
453 <paths>
454 <path action="A">d</path>
454 <path action="A">d</path>
455 </paths>
455 </paths>
456 </logentry>
456 </logentry>
457 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
457 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
458 <branch>foo</branch>
458 <branch>foo</branch>
459 <author email="person">person</author>
459 <author email="person">person</author>
460 <date>1970-01-17T04:53:20+00:00</date>
460 <date>1970-01-17T04:53:20+00:00</date>
461 <msg xml:space="preserve">new branch</msg>
461 <msg xml:space="preserve">new branch</msg>
462 <paths>
462 <paths>
463 </paths>
463 </paths>
464 </logentry>
464 </logentry>
465 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
465 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
466 <author email="person">person</author>
466 <author email="person">person</author>
467 <date>1970-01-16T01:06:40+00:00</date>
467 <date>1970-01-16T01:06:40+00:00</date>
468 <msg xml:space="preserve">no user, no domain</msg>
468 <msg xml:space="preserve">no user, no domain</msg>
469 <paths>
469 <paths>
470 <path action="M">c</path>
470 <path action="M">c</path>
471 </paths>
471 </paths>
472 </logentry>
472 </logentry>
473 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
473 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
474 <author email="other@place">other</author>
474 <author email="other@place">other</author>
475 <date>1970-01-14T21:20:00+00:00</date>
475 <date>1970-01-14T21:20:00+00:00</date>
476 <msg xml:space="preserve">no person</msg>
476 <msg xml:space="preserve">no person</msg>
477 <paths>
477 <paths>
478 <path action="A">c</path>
478 <path action="A">c</path>
479 </paths>
479 </paths>
480 </logentry>
480 </logentry>
481 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
481 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
482 <author email="other@place">A. N. Other</author>
482 <author email="other@place">A. N. Other</author>
483 <date>1970-01-13T17:33:20+00:00</date>
483 <date>1970-01-13T17:33:20+00:00</date>
484 <msg xml:space="preserve">other 1
484 <msg xml:space="preserve">other 1
485 other 2
485 other 2
486
486
487 other 3</msg>
487 other 3</msg>
488 <paths>
488 <paths>
489 <path action="A">b</path>
489 <path action="A">b</path>
490 </paths>
490 </paths>
491 </logentry>
491 </logentry>
492 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
492 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
493 <author email="user@hostname">User Name</author>
493 <author email="user@hostname">User Name</author>
494 <date>1970-01-12T13:46:40+00:00</date>
494 <date>1970-01-12T13:46:40+00:00</date>
495 <msg xml:space="preserve">line 1
495 <msg xml:space="preserve">line 1
496 line 2</msg>
496 line 2</msg>
497 <paths>
497 <paths>
498 <path action="A">a</path>
498 <path action="A">a</path>
499 </paths>
499 </paths>
500 </logentry>
500 </logentry>
501 </log>
501 </log>
502
502
503 $ hg log --debug --style xml
503 $ hg log --debug --style xml
504 <?xml version="1.0"?>
504 <?xml version="1.0"?>
505 <log>
505 <log>
506 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
506 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
507 <tag>tip</tag>
507 <tag>tip</tag>
508 <parent revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453" />
508 <parent revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453" />
509 <parent revision="-1" node="0000000000000000000000000000000000000000" />
509 <parent revision="-1" node="0000000000000000000000000000000000000000" />
510 <author email="test">test</author>
510 <author email="test">test</author>
511 <date>2020-01-01T10:01:00+00:00</date>
511 <date>2020-01-01T10:01:00+00:00</date>
512 <msg xml:space="preserve">third</msg>
512 <msg xml:space="preserve">third</msg>
513 <paths>
513 <paths>
514 <path action="A">fourth</path>
514 <path action="A">fourth</path>
515 <path action="A">third</path>
515 <path action="A">third</path>
516 <path action="R">second</path>
516 <path action="R">second</path>
517 </paths>
517 </paths>
518 <copies>
518 <copies>
519 <copy source="second">fourth</copy>
519 <copy source="second">fourth</copy>
520 </copies>
520 </copies>
521 <extra key="branch">default</extra>
521 <extra key="branch">default</extra>
522 </logentry>
522 </logentry>
523 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
523 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
524 <parent revision="-1" node="0000000000000000000000000000000000000000" />
524 <parent revision="-1" node="0000000000000000000000000000000000000000" />
525 <parent revision="-1" node="0000000000000000000000000000000000000000" />
525 <parent revision="-1" node="0000000000000000000000000000000000000000" />
526 <author email="user@hostname">User Name</author>
526 <author email="user@hostname">User Name</author>
527 <date>1970-01-12T13:46:40+00:00</date>
527 <date>1970-01-12T13:46:40+00:00</date>
528 <msg xml:space="preserve">second</msg>
528 <msg xml:space="preserve">second</msg>
529 <paths>
529 <paths>
530 <path action="A">second</path>
530 <path action="A">second</path>
531 </paths>
531 </paths>
532 <extra key="branch">default</extra>
532 <extra key="branch">default</extra>
533 </logentry>
533 </logentry>
534 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
534 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
535 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
535 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
536 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
536 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
537 <author email="person">person</author>
537 <author email="person">person</author>
538 <date>1970-01-18T08:40:01+00:00</date>
538 <date>1970-01-18T08:40:01+00:00</date>
539 <msg xml:space="preserve">merge</msg>
539 <msg xml:space="preserve">merge</msg>
540 <paths>
540 <paths>
541 </paths>
541 </paths>
542 <extra key="branch">default</extra>
542 <extra key="branch">default</extra>
543 </logentry>
543 </logentry>
544 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
544 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
545 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
545 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
546 <parent revision="-1" node="0000000000000000000000000000000000000000" />
546 <parent revision="-1" node="0000000000000000000000000000000000000000" />
547 <author email="person">person</author>
547 <author email="person">person</author>
548 <date>1970-01-18T08:40:00+00:00</date>
548 <date>1970-01-18T08:40:00+00:00</date>
549 <msg xml:space="preserve">new head</msg>
549 <msg xml:space="preserve">new head</msg>
550 <paths>
550 <paths>
551 <path action="A">d</path>
551 <path action="A">d</path>
552 </paths>
552 </paths>
553 <extra key="branch">default</extra>
553 <extra key="branch">default</extra>
554 </logentry>
554 </logentry>
555 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
555 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
556 <branch>foo</branch>
556 <branch>foo</branch>
557 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
557 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
558 <parent revision="-1" node="0000000000000000000000000000000000000000" />
558 <parent revision="-1" node="0000000000000000000000000000000000000000" />
559 <author email="person">person</author>
559 <author email="person">person</author>
560 <date>1970-01-17T04:53:20+00:00</date>
560 <date>1970-01-17T04:53:20+00:00</date>
561 <msg xml:space="preserve">new branch</msg>
561 <msg xml:space="preserve">new branch</msg>
562 <paths>
562 <paths>
563 </paths>
563 </paths>
564 <extra key="branch">foo</extra>
564 <extra key="branch">foo</extra>
565 </logentry>
565 </logentry>
566 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
566 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
567 <parent revision="2" node="97054abb4ab824450e9164180baf491ae0078465" />
567 <parent revision="2" node="97054abb4ab824450e9164180baf491ae0078465" />
568 <parent revision="-1" node="0000000000000000000000000000000000000000" />
568 <parent revision="-1" node="0000000000000000000000000000000000000000" />
569 <author email="person">person</author>
569 <author email="person">person</author>
570 <date>1970-01-16T01:06:40+00:00</date>
570 <date>1970-01-16T01:06:40+00:00</date>
571 <msg xml:space="preserve">no user, no domain</msg>
571 <msg xml:space="preserve">no user, no domain</msg>
572 <paths>
572 <paths>
573 <path action="M">c</path>
573 <path action="M">c</path>
574 </paths>
574 </paths>
575 <extra key="branch">default</extra>
575 <extra key="branch">default</extra>
576 </logentry>
576 </logentry>
577 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
577 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
578 <parent revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965" />
578 <parent revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965" />
579 <parent revision="-1" node="0000000000000000000000000000000000000000" />
579 <parent revision="-1" node="0000000000000000000000000000000000000000" />
580 <author email="other@place">other</author>
580 <author email="other@place">other</author>
581 <date>1970-01-14T21:20:00+00:00</date>
581 <date>1970-01-14T21:20:00+00:00</date>
582 <msg xml:space="preserve">no person</msg>
582 <msg xml:space="preserve">no person</msg>
583 <paths>
583 <paths>
584 <path action="A">c</path>
584 <path action="A">c</path>
585 </paths>
585 </paths>
586 <extra key="branch">default</extra>
586 <extra key="branch">default</extra>
587 </logentry>
587 </logentry>
588 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
588 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
589 <parent revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f" />
589 <parent revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f" />
590 <parent revision="-1" node="0000000000000000000000000000000000000000" />
590 <parent revision="-1" node="0000000000000000000000000000000000000000" />
591 <author email="other@place">A. N. Other</author>
591 <author email="other@place">A. N. Other</author>
592 <date>1970-01-13T17:33:20+00:00</date>
592 <date>1970-01-13T17:33:20+00:00</date>
593 <msg xml:space="preserve">other 1
593 <msg xml:space="preserve">other 1
594 other 2
594 other 2
595
595
596 other 3</msg>
596 other 3</msg>
597 <paths>
597 <paths>
598 <path action="A">b</path>
598 <path action="A">b</path>
599 </paths>
599 </paths>
600 <extra key="branch">default</extra>
600 <extra key="branch">default</extra>
601 </logentry>
601 </logentry>
602 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
602 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
603 <parent revision="-1" node="0000000000000000000000000000000000000000" />
603 <parent revision="-1" node="0000000000000000000000000000000000000000" />
604 <parent revision="-1" node="0000000000000000000000000000000000000000" />
604 <parent revision="-1" node="0000000000000000000000000000000000000000" />
605 <author email="user@hostname">User Name</author>
605 <author email="user@hostname">User Name</author>
606 <date>1970-01-12T13:46:40+00:00</date>
606 <date>1970-01-12T13:46:40+00:00</date>
607 <msg xml:space="preserve">line 1
607 <msg xml:space="preserve">line 1
608 line 2</msg>
608 line 2</msg>
609 <paths>
609 <paths>
610 <path action="A">a</path>
610 <path action="A">a</path>
611 </paths>
611 </paths>
612 <extra key="branch">default</extra>
612 <extra key="branch">default</extra>
613 </logentry>
613 </logentry>
614 </log>
614 </log>
615
615
616
616
617 Test JSON style:
617 Test JSON style:
618
618
619 $ hg log -k nosuch -Tjson
619 $ hg log -k nosuch -Tjson
620 []
620 []
621
621
622 $ hg log -qr . -Tjson
622 $ hg log -qr . -Tjson
623 [
623 [
624 {
624 {
625 "rev": 8,
625 "rev": 8,
626 "node": "95c24699272ef57d062b8bccc32c878bf841784a"
626 "node": "95c24699272ef57d062b8bccc32c878bf841784a"
627 }
627 }
628 ]
628 ]
629
629
630 $ hg log -vpr . -Tjson --stat
630 $ hg log -vpr . -Tjson --stat
631 [
631 [
632 {
632 {
633 "rev": 8,
633 "rev": 8,
634 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
634 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
635 "branch": "default",
635 "branch": "default",
636 "phase": "draft",
636 "phase": "draft",
637 "user": "test",
637 "user": "test",
638 "date": [1577872860, 0],
638 "date": [1577872860, 0],
639 "desc": "third",
639 "desc": "third",
640 "bookmarks": [],
640 "bookmarks": [],
641 "tags": ["tip"],
641 "tags": ["tip"],
642 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
642 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
643 "files": ["fourth", "second", "third"],
643 "files": ["fourth", "second", "third"],
644 "diffstat": " fourth | 1 +\n second | 1 -\n third | 1 +\n 3 files changed, 2 insertions(+), 1 deletions(-)\n",
644 "diffstat": " fourth | 1 +\n second | 1 -\n third | 1 +\n 3 files changed, 2 insertions(+), 1 deletions(-)\n",
645 "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"
645 "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"
646 }
646 }
647 ]
647 ]
648
648
649 honor --git but not format-breaking diffopts
649 honor --git but not format-breaking diffopts
650 $ hg --config diff.noprefix=True log --git -vpr . -Tjson
650 $ hg --config diff.noprefix=True log --git -vpr . -Tjson
651 [
651 [
652 {
652 {
653 "rev": 8,
653 "rev": 8,
654 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
654 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
655 "branch": "default",
655 "branch": "default",
656 "phase": "draft",
656 "phase": "draft",
657 "user": "test",
657 "user": "test",
658 "date": [1577872860, 0],
658 "date": [1577872860, 0],
659 "desc": "third",
659 "desc": "third",
660 "bookmarks": [],
660 "bookmarks": [],
661 "tags": ["tip"],
661 "tags": ["tip"],
662 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
662 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
663 "files": ["fourth", "second", "third"],
663 "files": ["fourth", "second", "third"],
664 "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"
664 "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"
665 }
665 }
666 ]
666 ]
667
667
668 $ hg log -T json
668 $ hg log -T json
669 [
669 [
670 {
670 {
671 "rev": 8,
671 "rev": 8,
672 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
672 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
673 "branch": "default",
673 "branch": "default",
674 "phase": "draft",
674 "phase": "draft",
675 "user": "test",
675 "user": "test",
676 "date": [1577872860, 0],
676 "date": [1577872860, 0],
677 "desc": "third",
677 "desc": "third",
678 "bookmarks": [],
678 "bookmarks": [],
679 "tags": ["tip"],
679 "tags": ["tip"],
680 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"]
680 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"]
681 },
681 },
682 {
682 {
683 "rev": 7,
683 "rev": 7,
684 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
684 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
685 "branch": "default",
685 "branch": "default",
686 "phase": "draft",
686 "phase": "draft",
687 "user": "User Name <user@hostname>",
687 "user": "User Name <user@hostname>",
688 "date": [1000000, 0],
688 "date": [1000000, 0],
689 "desc": "second",
689 "desc": "second",
690 "bookmarks": [],
690 "bookmarks": [],
691 "tags": [],
691 "tags": [],
692 "parents": ["0000000000000000000000000000000000000000"]
692 "parents": ["0000000000000000000000000000000000000000"]
693 },
693 },
694 {
694 {
695 "rev": 6,
695 "rev": 6,
696 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
696 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
697 "branch": "default",
697 "branch": "default",
698 "phase": "draft",
698 "phase": "draft",
699 "user": "person",
699 "user": "person",
700 "date": [1500001, 0],
700 "date": [1500001, 0],
701 "desc": "merge",
701 "desc": "merge",
702 "bookmarks": [],
702 "bookmarks": [],
703 "tags": [],
703 "tags": [],
704 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"]
704 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"]
705 },
705 },
706 {
706 {
707 "rev": 5,
707 "rev": 5,
708 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
708 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
709 "branch": "default",
709 "branch": "default",
710 "phase": "draft",
710 "phase": "draft",
711 "user": "person",
711 "user": "person",
712 "date": [1500000, 0],
712 "date": [1500000, 0],
713 "desc": "new head",
713 "desc": "new head",
714 "bookmarks": [],
714 "bookmarks": [],
715 "tags": [],
715 "tags": [],
716 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"]
716 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"]
717 },
717 },
718 {
718 {
719 "rev": 4,
719 "rev": 4,
720 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
720 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
721 "branch": "foo",
721 "branch": "foo",
722 "phase": "draft",
722 "phase": "draft",
723 "user": "person",
723 "user": "person",
724 "date": [1400000, 0],
724 "date": [1400000, 0],
725 "desc": "new branch",
725 "desc": "new branch",
726 "bookmarks": [],
726 "bookmarks": [],
727 "tags": [],
727 "tags": [],
728 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"]
728 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"]
729 },
729 },
730 {
730 {
731 "rev": 3,
731 "rev": 3,
732 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
732 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
733 "branch": "default",
733 "branch": "default",
734 "phase": "draft",
734 "phase": "draft",
735 "user": "person",
735 "user": "person",
736 "date": [1300000, 0],
736 "date": [1300000, 0],
737 "desc": "no user, no domain",
737 "desc": "no user, no domain",
738 "bookmarks": [],
738 "bookmarks": [],
739 "tags": [],
739 "tags": [],
740 "parents": ["97054abb4ab824450e9164180baf491ae0078465"]
740 "parents": ["97054abb4ab824450e9164180baf491ae0078465"]
741 },
741 },
742 {
742 {
743 "rev": 2,
743 "rev": 2,
744 "node": "97054abb4ab824450e9164180baf491ae0078465",
744 "node": "97054abb4ab824450e9164180baf491ae0078465",
745 "branch": "default",
745 "branch": "default",
746 "phase": "draft",
746 "phase": "draft",
747 "user": "other@place",
747 "user": "other@place",
748 "date": [1200000, 0],
748 "date": [1200000, 0],
749 "desc": "no person",
749 "desc": "no person",
750 "bookmarks": [],
750 "bookmarks": [],
751 "tags": [],
751 "tags": [],
752 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"]
752 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"]
753 },
753 },
754 {
754 {
755 "rev": 1,
755 "rev": 1,
756 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
756 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
757 "branch": "default",
757 "branch": "default",
758 "phase": "draft",
758 "phase": "draft",
759 "user": "A. N. Other <other@place>",
759 "user": "A. N. Other <other@place>",
760 "date": [1100000, 0],
760 "date": [1100000, 0],
761 "desc": "other 1\nother 2\n\nother 3",
761 "desc": "other 1\nother 2\n\nother 3",
762 "bookmarks": [],
762 "bookmarks": [],
763 "tags": [],
763 "tags": [],
764 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"]
764 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"]
765 },
765 },
766 {
766 {
767 "rev": 0,
767 "rev": 0,
768 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
768 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
769 "branch": "default",
769 "branch": "default",
770 "phase": "draft",
770 "phase": "draft",
771 "user": "User Name <user@hostname>",
771 "user": "User Name <user@hostname>",
772 "date": [1000000, 0],
772 "date": [1000000, 0],
773 "desc": "line 1\nline 2",
773 "desc": "line 1\nline 2",
774 "bookmarks": [],
774 "bookmarks": [],
775 "tags": [],
775 "tags": [],
776 "parents": ["0000000000000000000000000000000000000000"]
776 "parents": ["0000000000000000000000000000000000000000"]
777 }
777 }
778 ]
778 ]
779
779
780 $ hg heads -v -Tjson
780 $ hg heads -v -Tjson
781 [
781 [
782 {
782 {
783 "rev": 8,
783 "rev": 8,
784 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
784 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
785 "branch": "default",
785 "branch": "default",
786 "phase": "draft",
786 "phase": "draft",
787 "user": "test",
787 "user": "test",
788 "date": [1577872860, 0],
788 "date": [1577872860, 0],
789 "desc": "third",
789 "desc": "third",
790 "bookmarks": [],
790 "bookmarks": [],
791 "tags": ["tip"],
791 "tags": ["tip"],
792 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
792 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
793 "files": ["fourth", "second", "third"]
793 "files": ["fourth", "second", "third"]
794 },
794 },
795 {
795 {
796 "rev": 6,
796 "rev": 6,
797 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
797 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
798 "branch": "default",
798 "branch": "default",
799 "phase": "draft",
799 "phase": "draft",
800 "user": "person",
800 "user": "person",
801 "date": [1500001, 0],
801 "date": [1500001, 0],
802 "desc": "merge",
802 "desc": "merge",
803 "bookmarks": [],
803 "bookmarks": [],
804 "tags": [],
804 "tags": [],
805 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
805 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
806 "files": []
806 "files": []
807 },
807 },
808 {
808 {
809 "rev": 4,
809 "rev": 4,
810 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
810 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
811 "branch": "foo",
811 "branch": "foo",
812 "phase": "draft",
812 "phase": "draft",
813 "user": "person",
813 "user": "person",
814 "date": [1400000, 0],
814 "date": [1400000, 0],
815 "desc": "new branch",
815 "desc": "new branch",
816 "bookmarks": [],
816 "bookmarks": [],
817 "tags": [],
817 "tags": [],
818 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
818 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
819 "files": []
819 "files": []
820 }
820 }
821 ]
821 ]
822
822
823 $ hg log --debug -Tjson
823 $ hg log --debug -Tjson
824 [
824 [
825 {
825 {
826 "rev": 8,
826 "rev": 8,
827 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
827 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
828 "branch": "default",
828 "branch": "default",
829 "phase": "draft",
829 "phase": "draft",
830 "user": "test",
830 "user": "test",
831 "date": [1577872860, 0],
831 "date": [1577872860, 0],
832 "desc": "third",
832 "desc": "third",
833 "bookmarks": [],
833 "bookmarks": [],
834 "tags": ["tip"],
834 "tags": ["tip"],
835 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
835 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
836 "manifest": "94961b75a2da554b4df6fb599e5bfc7d48de0c64",
836 "manifest": "94961b75a2da554b4df6fb599e5bfc7d48de0c64",
837 "extra": {"branch": "default"},
837 "extra": {"branch": "default"},
838 "modified": [],
838 "modified": [],
839 "added": ["fourth", "third"],
839 "added": ["fourth", "third"],
840 "removed": ["second"]
840 "removed": ["second"]
841 },
841 },
842 {
842 {
843 "rev": 7,
843 "rev": 7,
844 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
844 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
845 "branch": "default",
845 "branch": "default",
846 "phase": "draft",
846 "phase": "draft",
847 "user": "User Name <user@hostname>",
847 "user": "User Name <user@hostname>",
848 "date": [1000000, 0],
848 "date": [1000000, 0],
849 "desc": "second",
849 "desc": "second",
850 "bookmarks": [],
850 "bookmarks": [],
851 "tags": [],
851 "tags": [],
852 "parents": ["0000000000000000000000000000000000000000"],
852 "parents": ["0000000000000000000000000000000000000000"],
853 "manifest": "f2dbc354b94e5ec0b4f10680ee0cee816101d0bf",
853 "manifest": "f2dbc354b94e5ec0b4f10680ee0cee816101d0bf",
854 "extra": {"branch": "default"},
854 "extra": {"branch": "default"},
855 "modified": [],
855 "modified": [],
856 "added": ["second"],
856 "added": ["second"],
857 "removed": []
857 "removed": []
858 },
858 },
859 {
859 {
860 "rev": 6,
860 "rev": 6,
861 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
861 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
862 "branch": "default",
862 "branch": "default",
863 "phase": "draft",
863 "phase": "draft",
864 "user": "person",
864 "user": "person",
865 "date": [1500001, 0],
865 "date": [1500001, 0],
866 "desc": "merge",
866 "desc": "merge",
867 "bookmarks": [],
867 "bookmarks": [],
868 "tags": [],
868 "tags": [],
869 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
869 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
870 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
870 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
871 "extra": {"branch": "default"},
871 "extra": {"branch": "default"},
872 "modified": [],
872 "modified": [],
873 "added": [],
873 "added": [],
874 "removed": []
874 "removed": []
875 },
875 },
876 {
876 {
877 "rev": 5,
877 "rev": 5,
878 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
878 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
879 "branch": "default",
879 "branch": "default",
880 "phase": "draft",
880 "phase": "draft",
881 "user": "person",
881 "user": "person",
882 "date": [1500000, 0],
882 "date": [1500000, 0],
883 "desc": "new head",
883 "desc": "new head",
884 "bookmarks": [],
884 "bookmarks": [],
885 "tags": [],
885 "tags": [],
886 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
886 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
887 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
887 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
888 "extra": {"branch": "default"},
888 "extra": {"branch": "default"},
889 "modified": [],
889 "modified": [],
890 "added": ["d"],
890 "added": ["d"],
891 "removed": []
891 "removed": []
892 },
892 },
893 {
893 {
894 "rev": 4,
894 "rev": 4,
895 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
895 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
896 "branch": "foo",
896 "branch": "foo",
897 "phase": "draft",
897 "phase": "draft",
898 "user": "person",
898 "user": "person",
899 "date": [1400000, 0],
899 "date": [1400000, 0],
900 "desc": "new branch",
900 "desc": "new branch",
901 "bookmarks": [],
901 "bookmarks": [],
902 "tags": [],
902 "tags": [],
903 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
903 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
904 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
904 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
905 "extra": {"branch": "foo"},
905 "extra": {"branch": "foo"},
906 "modified": [],
906 "modified": [],
907 "added": [],
907 "added": [],
908 "removed": []
908 "removed": []
909 },
909 },
910 {
910 {
911 "rev": 3,
911 "rev": 3,
912 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
912 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
913 "branch": "default",
913 "branch": "default",
914 "phase": "draft",
914 "phase": "draft",
915 "user": "person",
915 "user": "person",
916 "date": [1300000, 0],
916 "date": [1300000, 0],
917 "desc": "no user, no domain",
917 "desc": "no user, no domain",
918 "bookmarks": [],
918 "bookmarks": [],
919 "tags": [],
919 "tags": [],
920 "parents": ["97054abb4ab824450e9164180baf491ae0078465"],
920 "parents": ["97054abb4ab824450e9164180baf491ae0078465"],
921 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
921 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
922 "extra": {"branch": "default"},
922 "extra": {"branch": "default"},
923 "modified": ["c"],
923 "modified": ["c"],
924 "added": [],
924 "added": [],
925 "removed": []
925 "removed": []
926 },
926 },
927 {
927 {
928 "rev": 2,
928 "rev": 2,
929 "node": "97054abb4ab824450e9164180baf491ae0078465",
929 "node": "97054abb4ab824450e9164180baf491ae0078465",
930 "branch": "default",
930 "branch": "default",
931 "phase": "draft",
931 "phase": "draft",
932 "user": "other@place",
932 "user": "other@place",
933 "date": [1200000, 0],
933 "date": [1200000, 0],
934 "desc": "no person",
934 "desc": "no person",
935 "bookmarks": [],
935 "bookmarks": [],
936 "tags": [],
936 "tags": [],
937 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"],
937 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"],
938 "manifest": "6e0e82995c35d0d57a52aca8da4e56139e06b4b1",
938 "manifest": "6e0e82995c35d0d57a52aca8da4e56139e06b4b1",
939 "extra": {"branch": "default"},
939 "extra": {"branch": "default"},
940 "modified": [],
940 "modified": [],
941 "added": ["c"],
941 "added": ["c"],
942 "removed": []
942 "removed": []
943 },
943 },
944 {
944 {
945 "rev": 1,
945 "rev": 1,
946 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
946 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
947 "branch": "default",
947 "branch": "default",
948 "phase": "draft",
948 "phase": "draft",
949 "user": "A. N. Other <other@place>",
949 "user": "A. N. Other <other@place>",
950 "date": [1100000, 0],
950 "date": [1100000, 0],
951 "desc": "other 1\nother 2\n\nother 3",
951 "desc": "other 1\nother 2\n\nother 3",
952 "bookmarks": [],
952 "bookmarks": [],
953 "tags": [],
953 "tags": [],
954 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"],
954 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"],
955 "manifest": "4e8d705b1e53e3f9375e0e60dc7b525d8211fe55",
955 "manifest": "4e8d705b1e53e3f9375e0e60dc7b525d8211fe55",
956 "extra": {"branch": "default"},
956 "extra": {"branch": "default"},
957 "modified": [],
957 "modified": [],
958 "added": ["b"],
958 "added": ["b"],
959 "removed": []
959 "removed": []
960 },
960 },
961 {
961 {
962 "rev": 0,
962 "rev": 0,
963 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
963 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
964 "branch": "default",
964 "branch": "default",
965 "phase": "draft",
965 "phase": "draft",
966 "user": "User Name <user@hostname>",
966 "user": "User Name <user@hostname>",
967 "date": [1000000, 0],
967 "date": [1000000, 0],
968 "desc": "line 1\nline 2",
968 "desc": "line 1\nline 2",
969 "bookmarks": [],
969 "bookmarks": [],
970 "tags": [],
970 "tags": [],
971 "parents": ["0000000000000000000000000000000000000000"],
971 "parents": ["0000000000000000000000000000000000000000"],
972 "manifest": "a0c8bcbbb45c63b90b70ad007bf38961f64f2af0",
972 "manifest": "a0c8bcbbb45c63b90b70ad007bf38961f64f2af0",
973 "extra": {"branch": "default"},
973 "extra": {"branch": "default"},
974 "modified": [],
974 "modified": [],
975 "added": ["a"],
975 "added": ["a"],
976 "removed": []
976 "removed": []
977 }
977 }
978 ]
978 ]
979
979
980 Error if style not readable:
980 Error if style not readable:
981
981
982 #if unix-permissions no-root
982 #if unix-permissions no-root
983 $ touch q
983 $ touch q
984 $ chmod 0 q
984 $ chmod 0 q
985 $ hg log --style ./q
985 $ hg log --style ./q
986 abort: Permission denied: ./q
986 abort: Permission denied: ./q
987 [255]
987 [255]
988 #endif
988 #endif
989
989
990 Error if no style:
990 Error if no style:
991
991
992 $ hg log --style notexist
992 $ hg log --style notexist
993 abort: style 'notexist' not found
993 abort: style 'notexist' not found
994 (available styles: bisect, changelog, compact, default, phases, status, xml)
994 (available styles: bisect, changelog, compact, default, phases, status, xml)
995 [255]
995 [255]
996
996
997 $ hg log -T list
997 $ hg log -T list
998 available styles: bisect, changelog, compact, default, phases, status, xml
998 available styles: bisect, changelog, compact, default, phases, status, xml
999 abort: specify a template
999 abort: specify a template
1000 [255]
1000 [255]
1001
1001
1002 Error if style missing key:
1002 Error if style missing key:
1003
1003
1004 $ echo 'q = q' > t
1004 $ echo 'q = q' > t
1005 $ hg log --style ./t
1005 $ hg log --style ./t
1006 abort: "changeset" not in template map
1006 abort: "changeset" not in template map
1007 [255]
1007 [255]
1008
1008
1009 Error if style missing value:
1009 Error if style missing value:
1010
1010
1011 $ echo 'changeset =' > t
1011 $ echo 'changeset =' > t
1012 $ hg log --style t
1012 $ hg log --style t
1013 hg: parse error at t:1: missing value
1013 hg: parse error at t:1: missing value
1014 [255]
1014 [255]
1015
1015
1016 Error if include fails:
1016 Error if include fails:
1017
1017
1018 $ echo 'changeset = q' >> t
1018 $ echo 'changeset = q' >> t
1019 #if unix-permissions no-root
1019 #if unix-permissions no-root
1020 $ hg log --style ./t
1020 $ hg log --style ./t
1021 abort: template file ./q: Permission denied
1021 abort: template file ./q: Permission denied
1022 [255]
1022 [255]
1023 $ rm -f q
1023 $ rm -f q
1024 #endif
1024 #endif
1025
1025
1026 Include works:
1026 Include works:
1027
1027
1028 $ echo '{rev}' > q
1028 $ echo '{rev}' > q
1029 $ hg log --style ./t
1029 $ hg log --style ./t
1030 8
1030 8
1031 7
1031 7
1032 6
1032 6
1033 5
1033 5
1034 4
1034 4
1035 3
1035 3
1036 2
1036 2
1037 1
1037 1
1038 0
1038 0
1039
1039
1040 Check that recursive reference does not fall into RuntimeError (issue4758):
1040 Check that recursive reference does not fall into RuntimeError (issue4758):
1041
1041
1042 common mistake:
1042 common mistake:
1043
1043
1044 $ hg log -T '{changeset}\n'
1044 $ hg log -T '{changeset}\n'
1045 abort: recursive reference 'changeset' in template
1045 abort: recursive reference 'changeset' in template
1046 [255]
1046 [255]
1047
1047
1048 circular reference:
1048 circular reference:
1049
1049
1050 $ cat << EOF > issue4758
1050 $ cat << EOF > issue4758
1051 > changeset = '{foo}'
1051 > changeset = '{foo}'
1052 > foo = '{changeset}'
1052 > foo = '{changeset}'
1053 > EOF
1053 > EOF
1054 $ hg log --style ./issue4758
1054 $ hg log --style ./issue4758
1055 abort: recursive reference 'foo' in template
1055 abort: recursive reference 'foo' in template
1056 [255]
1056 [255]
1057
1057
1058 buildmap() -> gettemplate(), where no thunk was made:
1058 buildmap() -> gettemplate(), where no thunk was made:
1059
1059
1060 $ hg log -T '{files % changeset}\n'
1060 $ hg log -T '{files % changeset}\n'
1061 abort: recursive reference 'changeset' in template
1061 abort: recursive reference 'changeset' in template
1062 [255]
1062 [255]
1063
1063
1064 not a recursion if a keyword of the same name exists:
1064 not a recursion if a keyword of the same name exists:
1065
1065
1066 $ cat << EOF > issue4758
1066 $ cat << EOF > issue4758
1067 > changeset = '{tags % rev}'
1067 > changeset = '{tags % rev}'
1068 > rev = '{rev} {tag}\n'
1068 > rev = '{rev} {tag}\n'
1069 > EOF
1069 > EOF
1070 $ hg log --style ./issue4758 -r tip
1070 $ hg log --style ./issue4758 -r tip
1071 8 tip
1071 8 tip
1072
1072
1073 Check that {phase} works correctly on parents:
1073 Check that {phase} works correctly on parents:
1074
1074
1075 $ cat << EOF > parentphase
1075 $ cat << EOF > parentphase
1076 > changeset_debug = '{rev} ({phase}):{parents}\n'
1076 > changeset_debug = '{rev} ({phase}):{parents}\n'
1077 > parent = ' {rev} ({phase})'
1077 > parent = ' {rev} ({phase})'
1078 > EOF
1078 > EOF
1079 $ hg phase -r 5 --public
1079 $ hg phase -r 5 --public
1080 $ hg phase -r 7 --secret --force
1080 $ hg phase -r 7 --secret --force
1081 $ hg log --debug -G --style ./parentphase
1081 $ hg log --debug -G --style ./parentphase
1082 @ 8 (secret): 7 (secret) -1 (public)
1082 @ 8 (secret): 7 (secret) -1 (public)
1083 |
1083 |
1084 o 7 (secret): -1 (public) -1 (public)
1084 o 7 (secret): -1 (public) -1 (public)
1085
1085
1086 o 6 (draft): 5 (public) 4 (draft)
1086 o 6 (draft): 5 (public) 4 (draft)
1087 |\
1087 |\
1088 | o 5 (public): 3 (public) -1 (public)
1088 | o 5 (public): 3 (public) -1 (public)
1089 | |
1089 | |
1090 o | 4 (draft): 3 (public) -1 (public)
1090 o | 4 (draft): 3 (public) -1 (public)
1091 |/
1091 |/
1092 o 3 (public): 2 (public) -1 (public)
1092 o 3 (public): 2 (public) -1 (public)
1093 |
1093 |
1094 o 2 (public): 1 (public) -1 (public)
1094 o 2 (public): 1 (public) -1 (public)
1095 |
1095 |
1096 o 1 (public): 0 (public) -1 (public)
1096 o 1 (public): 0 (public) -1 (public)
1097 |
1097 |
1098 o 0 (public): -1 (public) -1 (public)
1098 o 0 (public): -1 (public) -1 (public)
1099
1099
1100
1100
1101 Missing non-standard names give no error (backward compatibility):
1101 Missing non-standard names give no error (backward compatibility):
1102
1102
1103 $ echo "changeset = '{c}'" > t
1103 $ echo "changeset = '{c}'" > t
1104 $ hg log --style ./t
1104 $ hg log --style ./t
1105
1105
1106 Defining non-standard name works:
1106 Defining non-standard name works:
1107
1107
1108 $ cat <<EOF > t
1108 $ cat <<EOF > t
1109 > changeset = '{c}'
1109 > changeset = '{c}'
1110 > c = q
1110 > c = q
1111 > EOF
1111 > EOF
1112 $ hg log --style ./t
1112 $ hg log --style ./t
1113 8
1113 8
1114 7
1114 7
1115 6
1115 6
1116 5
1116 5
1117 4
1117 4
1118 3
1118 3
1119 2
1119 2
1120 1
1120 1
1121 0
1121 0
1122
1122
1123 ui.style works:
1123 ui.style works:
1124
1124
1125 $ echo '[ui]' > .hg/hgrc
1125 $ echo '[ui]' > .hg/hgrc
1126 $ echo 'style = t' >> .hg/hgrc
1126 $ echo 'style = t' >> .hg/hgrc
1127 $ hg log
1127 $ hg log
1128 8
1128 8
1129 7
1129 7
1130 6
1130 6
1131 5
1131 5
1132 4
1132 4
1133 3
1133 3
1134 2
1134 2
1135 1
1135 1
1136 0
1136 0
1137
1137
1138
1138
1139 Issue338:
1139 Issue338:
1140
1140
1141 $ hg log --style=changelog > changelog
1141 $ hg log --style=changelog > changelog
1142
1142
1143 $ cat changelog
1143 $ cat changelog
1144 2020-01-01 test <test>
1144 2020-01-01 test <test>
1145
1145
1146 * fourth, second, third:
1146 * fourth, second, third:
1147 third
1147 third
1148 [95c24699272e] [tip]
1148 [95c24699272e] [tip]
1149
1149
1150 1970-01-12 User Name <user@hostname>
1150 1970-01-12 User Name <user@hostname>
1151
1151
1152 * second:
1152 * second:
1153 second
1153 second
1154 [29114dbae42b]
1154 [29114dbae42b]
1155
1155
1156 1970-01-18 person <person>
1156 1970-01-18 person <person>
1157
1157
1158 * merge
1158 * merge
1159 [d41e714fe50d]
1159 [d41e714fe50d]
1160
1160
1161 * d:
1161 * d:
1162 new head
1162 new head
1163 [13207e5a10d9]
1163 [13207e5a10d9]
1164
1164
1165 1970-01-17 person <person>
1165 1970-01-17 person <person>
1166
1166
1167 * new branch
1167 * new branch
1168 [bbe44766e73d] <foo>
1168 [bbe44766e73d] <foo>
1169
1169
1170 1970-01-16 person <person>
1170 1970-01-16 person <person>
1171
1171
1172 * c:
1172 * c:
1173 no user, no domain
1173 no user, no domain
1174 [10e46f2dcbf4]
1174 [10e46f2dcbf4]
1175
1175
1176 1970-01-14 other <other@place>
1176 1970-01-14 other <other@place>
1177
1177
1178 * c:
1178 * c:
1179 no person
1179 no person
1180 [97054abb4ab8]
1180 [97054abb4ab8]
1181
1181
1182 1970-01-13 A. N. Other <other@place>
1182 1970-01-13 A. N. Other <other@place>
1183
1183
1184 * b:
1184 * b:
1185 other 1 other 2
1185 other 1 other 2
1186
1186
1187 other 3
1187 other 3
1188 [b608e9d1a3f0]
1188 [b608e9d1a3f0]
1189
1189
1190 1970-01-12 User Name <user@hostname>
1190 1970-01-12 User Name <user@hostname>
1191
1191
1192 * a:
1192 * a:
1193 line 1 line 2
1193 line 1 line 2
1194 [1e4e1b8f71e0]
1194 [1e4e1b8f71e0]
1195
1195
1196
1196
1197 Issue2130: xml output for 'hg heads' is malformed
1197 Issue2130: xml output for 'hg heads' is malformed
1198
1198
1199 $ hg heads --style changelog
1199 $ hg heads --style changelog
1200 2020-01-01 test <test>
1200 2020-01-01 test <test>
1201
1201
1202 * fourth, second, third:
1202 * fourth, second, third:
1203 third
1203 third
1204 [95c24699272e] [tip]
1204 [95c24699272e] [tip]
1205
1205
1206 1970-01-18 person <person>
1206 1970-01-18 person <person>
1207
1207
1208 * merge
1208 * merge
1209 [d41e714fe50d]
1209 [d41e714fe50d]
1210
1210
1211 1970-01-17 person <person>
1211 1970-01-17 person <person>
1212
1212
1213 * new branch
1213 * new branch
1214 [bbe44766e73d] <foo>
1214 [bbe44766e73d] <foo>
1215
1215
1216
1216
1217 Keys work:
1217 Keys work:
1218
1218
1219 $ for key in author branch branches date desc file_adds file_dels file_mods \
1219 $ for key in author branch branches date desc file_adds file_dels file_mods \
1220 > file_copies file_copies_switch files \
1220 > file_copies file_copies_switch files \
1221 > manifest node parents rev tags diffstat extras \
1221 > manifest node parents rev tags diffstat extras \
1222 > p1rev p2rev p1node p2node; do
1222 > p1rev p2rev p1node p2node; do
1223 > for mode in '' --verbose --debug; do
1223 > for mode in '' --verbose --debug; do
1224 > hg log $mode --template "$key$mode: {$key}\n"
1224 > hg log $mode --template "$key$mode: {$key}\n"
1225 > done
1225 > done
1226 > done
1226 > done
1227 author: test
1227 author: test
1228 author: User Name <user@hostname>
1228 author: User Name <user@hostname>
1229 author: person
1229 author: person
1230 author: person
1230 author: person
1231 author: person
1231 author: person
1232 author: person
1232 author: person
1233 author: other@place
1233 author: other@place
1234 author: A. N. Other <other@place>
1234 author: A. N. Other <other@place>
1235 author: User Name <user@hostname>
1235 author: User Name <user@hostname>
1236 author--verbose: test
1236 author--verbose: test
1237 author--verbose: User Name <user@hostname>
1237 author--verbose: User Name <user@hostname>
1238 author--verbose: person
1238 author--verbose: person
1239 author--verbose: person
1239 author--verbose: person
1240 author--verbose: person
1240 author--verbose: person
1241 author--verbose: person
1241 author--verbose: person
1242 author--verbose: other@place
1242 author--verbose: other@place
1243 author--verbose: A. N. Other <other@place>
1243 author--verbose: A. N. Other <other@place>
1244 author--verbose: User Name <user@hostname>
1244 author--verbose: User Name <user@hostname>
1245 author--debug: test
1245 author--debug: test
1246 author--debug: User Name <user@hostname>
1246 author--debug: User Name <user@hostname>
1247 author--debug: person
1247 author--debug: person
1248 author--debug: person
1248 author--debug: person
1249 author--debug: person
1249 author--debug: person
1250 author--debug: person
1250 author--debug: person
1251 author--debug: other@place
1251 author--debug: other@place
1252 author--debug: A. N. Other <other@place>
1252 author--debug: A. N. Other <other@place>
1253 author--debug: User Name <user@hostname>
1253 author--debug: User Name <user@hostname>
1254 branch: default
1254 branch: default
1255 branch: default
1255 branch: default
1256 branch: default
1256 branch: default
1257 branch: default
1257 branch: default
1258 branch: foo
1258 branch: foo
1259 branch: default
1259 branch: default
1260 branch: default
1260 branch: default
1261 branch: default
1261 branch: default
1262 branch: default
1262 branch: default
1263 branch--verbose: default
1263 branch--verbose: default
1264 branch--verbose: default
1264 branch--verbose: default
1265 branch--verbose: default
1265 branch--verbose: default
1266 branch--verbose: default
1266 branch--verbose: default
1267 branch--verbose: foo
1267 branch--verbose: foo
1268 branch--verbose: default
1268 branch--verbose: default
1269 branch--verbose: default
1269 branch--verbose: default
1270 branch--verbose: default
1270 branch--verbose: default
1271 branch--verbose: default
1271 branch--verbose: default
1272 branch--debug: default
1272 branch--debug: default
1273 branch--debug: default
1273 branch--debug: default
1274 branch--debug: default
1274 branch--debug: default
1275 branch--debug: default
1275 branch--debug: default
1276 branch--debug: foo
1276 branch--debug: foo
1277 branch--debug: default
1277 branch--debug: default
1278 branch--debug: default
1278 branch--debug: default
1279 branch--debug: default
1279 branch--debug: default
1280 branch--debug: default
1280 branch--debug: default
1281 branches:
1281 branches:
1282 branches:
1282 branches:
1283 branches:
1283 branches:
1284 branches:
1284 branches:
1285 branches: foo
1285 branches: foo
1286 branches:
1286 branches:
1287 branches:
1287 branches:
1288 branches:
1288 branches:
1289 branches:
1289 branches:
1290 branches--verbose:
1290 branches--verbose:
1291 branches--verbose:
1291 branches--verbose:
1292 branches--verbose:
1292 branches--verbose:
1293 branches--verbose:
1293 branches--verbose:
1294 branches--verbose: foo
1294 branches--verbose: foo
1295 branches--verbose:
1295 branches--verbose:
1296 branches--verbose:
1296 branches--verbose:
1297 branches--verbose:
1297 branches--verbose:
1298 branches--verbose:
1298 branches--verbose:
1299 branches--debug:
1299 branches--debug:
1300 branches--debug:
1300 branches--debug:
1301 branches--debug:
1301 branches--debug:
1302 branches--debug:
1302 branches--debug:
1303 branches--debug: foo
1303 branches--debug: foo
1304 branches--debug:
1304 branches--debug:
1305 branches--debug:
1305 branches--debug:
1306 branches--debug:
1306 branches--debug:
1307 branches--debug:
1307 branches--debug:
1308 date: 1577872860.00
1308 date: 1577872860.00
1309 date: 1000000.00
1309 date: 1000000.00
1310 date: 1500001.00
1310 date: 1500001.00
1311 date: 1500000.00
1311 date: 1500000.00
1312 date: 1400000.00
1312 date: 1400000.00
1313 date: 1300000.00
1313 date: 1300000.00
1314 date: 1200000.00
1314 date: 1200000.00
1315 date: 1100000.00
1315 date: 1100000.00
1316 date: 1000000.00
1316 date: 1000000.00
1317 date--verbose: 1577872860.00
1317 date--verbose: 1577872860.00
1318 date--verbose: 1000000.00
1318 date--verbose: 1000000.00
1319 date--verbose: 1500001.00
1319 date--verbose: 1500001.00
1320 date--verbose: 1500000.00
1320 date--verbose: 1500000.00
1321 date--verbose: 1400000.00
1321 date--verbose: 1400000.00
1322 date--verbose: 1300000.00
1322 date--verbose: 1300000.00
1323 date--verbose: 1200000.00
1323 date--verbose: 1200000.00
1324 date--verbose: 1100000.00
1324 date--verbose: 1100000.00
1325 date--verbose: 1000000.00
1325 date--verbose: 1000000.00
1326 date--debug: 1577872860.00
1326 date--debug: 1577872860.00
1327 date--debug: 1000000.00
1327 date--debug: 1000000.00
1328 date--debug: 1500001.00
1328 date--debug: 1500001.00
1329 date--debug: 1500000.00
1329 date--debug: 1500000.00
1330 date--debug: 1400000.00
1330 date--debug: 1400000.00
1331 date--debug: 1300000.00
1331 date--debug: 1300000.00
1332 date--debug: 1200000.00
1332 date--debug: 1200000.00
1333 date--debug: 1100000.00
1333 date--debug: 1100000.00
1334 date--debug: 1000000.00
1334 date--debug: 1000000.00
1335 desc: third
1335 desc: third
1336 desc: second
1336 desc: second
1337 desc: merge
1337 desc: merge
1338 desc: new head
1338 desc: new head
1339 desc: new branch
1339 desc: new branch
1340 desc: no user, no domain
1340 desc: no user, no domain
1341 desc: no person
1341 desc: no person
1342 desc: other 1
1342 desc: other 1
1343 other 2
1343 other 2
1344
1344
1345 other 3
1345 other 3
1346 desc: line 1
1346 desc: line 1
1347 line 2
1347 line 2
1348 desc--verbose: third
1348 desc--verbose: third
1349 desc--verbose: second
1349 desc--verbose: second
1350 desc--verbose: merge
1350 desc--verbose: merge
1351 desc--verbose: new head
1351 desc--verbose: new head
1352 desc--verbose: new branch
1352 desc--verbose: new branch
1353 desc--verbose: no user, no domain
1353 desc--verbose: no user, no domain
1354 desc--verbose: no person
1354 desc--verbose: no person
1355 desc--verbose: other 1
1355 desc--verbose: other 1
1356 other 2
1356 other 2
1357
1357
1358 other 3
1358 other 3
1359 desc--verbose: line 1
1359 desc--verbose: line 1
1360 line 2
1360 line 2
1361 desc--debug: third
1361 desc--debug: third
1362 desc--debug: second
1362 desc--debug: second
1363 desc--debug: merge
1363 desc--debug: merge
1364 desc--debug: new head
1364 desc--debug: new head
1365 desc--debug: new branch
1365 desc--debug: new branch
1366 desc--debug: no user, no domain
1366 desc--debug: no user, no domain
1367 desc--debug: no person
1367 desc--debug: no person
1368 desc--debug: other 1
1368 desc--debug: other 1
1369 other 2
1369 other 2
1370
1370
1371 other 3
1371 other 3
1372 desc--debug: line 1
1372 desc--debug: line 1
1373 line 2
1373 line 2
1374 file_adds: fourth third
1374 file_adds: fourth third
1375 file_adds: second
1375 file_adds: second
1376 file_adds:
1376 file_adds:
1377 file_adds: d
1377 file_adds: d
1378 file_adds:
1378 file_adds:
1379 file_adds:
1379 file_adds:
1380 file_adds: c
1380 file_adds: c
1381 file_adds: b
1381 file_adds: b
1382 file_adds: a
1382 file_adds: a
1383 file_adds--verbose: fourth third
1383 file_adds--verbose: fourth third
1384 file_adds--verbose: second
1384 file_adds--verbose: second
1385 file_adds--verbose:
1385 file_adds--verbose:
1386 file_adds--verbose: d
1386 file_adds--verbose: d
1387 file_adds--verbose:
1387 file_adds--verbose:
1388 file_adds--verbose:
1388 file_adds--verbose:
1389 file_adds--verbose: c
1389 file_adds--verbose: c
1390 file_adds--verbose: b
1390 file_adds--verbose: b
1391 file_adds--verbose: a
1391 file_adds--verbose: a
1392 file_adds--debug: fourth third
1392 file_adds--debug: fourth third
1393 file_adds--debug: second
1393 file_adds--debug: second
1394 file_adds--debug:
1394 file_adds--debug:
1395 file_adds--debug: d
1395 file_adds--debug: d
1396 file_adds--debug:
1396 file_adds--debug:
1397 file_adds--debug:
1397 file_adds--debug:
1398 file_adds--debug: c
1398 file_adds--debug: c
1399 file_adds--debug: b
1399 file_adds--debug: b
1400 file_adds--debug: a
1400 file_adds--debug: a
1401 file_dels: second
1401 file_dels: second
1402 file_dels:
1402 file_dels:
1403 file_dels:
1403 file_dels:
1404 file_dels:
1404 file_dels:
1405 file_dels:
1405 file_dels:
1406 file_dels:
1406 file_dels:
1407 file_dels:
1407 file_dels:
1408 file_dels:
1408 file_dels:
1409 file_dels:
1409 file_dels:
1410 file_dels--verbose: second
1410 file_dels--verbose: second
1411 file_dels--verbose:
1411 file_dels--verbose:
1412 file_dels--verbose:
1412 file_dels--verbose:
1413 file_dels--verbose:
1413 file_dels--verbose:
1414 file_dels--verbose:
1414 file_dels--verbose:
1415 file_dels--verbose:
1415 file_dels--verbose:
1416 file_dels--verbose:
1416 file_dels--verbose:
1417 file_dels--verbose:
1417 file_dels--verbose:
1418 file_dels--verbose:
1418 file_dels--verbose:
1419 file_dels--debug: second
1419 file_dels--debug: second
1420 file_dels--debug:
1420 file_dels--debug:
1421 file_dels--debug:
1421 file_dels--debug:
1422 file_dels--debug:
1422 file_dels--debug:
1423 file_dels--debug:
1423 file_dels--debug:
1424 file_dels--debug:
1424 file_dels--debug:
1425 file_dels--debug:
1425 file_dels--debug:
1426 file_dels--debug:
1426 file_dels--debug:
1427 file_dels--debug:
1427 file_dels--debug:
1428 file_mods:
1428 file_mods:
1429 file_mods:
1429 file_mods:
1430 file_mods:
1430 file_mods:
1431 file_mods:
1431 file_mods:
1432 file_mods:
1432 file_mods:
1433 file_mods: c
1433 file_mods: c
1434 file_mods:
1434 file_mods:
1435 file_mods:
1435 file_mods:
1436 file_mods:
1436 file_mods:
1437 file_mods--verbose:
1437 file_mods--verbose:
1438 file_mods--verbose:
1438 file_mods--verbose:
1439 file_mods--verbose:
1439 file_mods--verbose:
1440 file_mods--verbose:
1440 file_mods--verbose:
1441 file_mods--verbose:
1441 file_mods--verbose:
1442 file_mods--verbose: c
1442 file_mods--verbose: c
1443 file_mods--verbose:
1443 file_mods--verbose:
1444 file_mods--verbose:
1444 file_mods--verbose:
1445 file_mods--verbose:
1445 file_mods--verbose:
1446 file_mods--debug:
1446 file_mods--debug:
1447 file_mods--debug:
1447 file_mods--debug:
1448 file_mods--debug:
1448 file_mods--debug:
1449 file_mods--debug:
1449 file_mods--debug:
1450 file_mods--debug:
1450 file_mods--debug:
1451 file_mods--debug: c
1451 file_mods--debug: c
1452 file_mods--debug:
1452 file_mods--debug:
1453 file_mods--debug:
1453 file_mods--debug:
1454 file_mods--debug:
1454 file_mods--debug:
1455 file_copies: fourth (second)
1455 file_copies: fourth (second)
1456 file_copies:
1456 file_copies:
1457 file_copies:
1457 file_copies:
1458 file_copies:
1458 file_copies:
1459 file_copies:
1459 file_copies:
1460 file_copies:
1460 file_copies:
1461 file_copies:
1461 file_copies:
1462 file_copies:
1462 file_copies:
1463 file_copies:
1463 file_copies:
1464 file_copies--verbose: fourth (second)
1464 file_copies--verbose: fourth (second)
1465 file_copies--verbose:
1465 file_copies--verbose:
1466 file_copies--verbose:
1466 file_copies--verbose:
1467 file_copies--verbose:
1467 file_copies--verbose:
1468 file_copies--verbose:
1468 file_copies--verbose:
1469 file_copies--verbose:
1469 file_copies--verbose:
1470 file_copies--verbose:
1470 file_copies--verbose:
1471 file_copies--verbose:
1471 file_copies--verbose:
1472 file_copies--verbose:
1472 file_copies--verbose:
1473 file_copies--debug: fourth (second)
1473 file_copies--debug: fourth (second)
1474 file_copies--debug:
1474 file_copies--debug:
1475 file_copies--debug:
1475 file_copies--debug:
1476 file_copies--debug:
1476 file_copies--debug:
1477 file_copies--debug:
1477 file_copies--debug:
1478 file_copies--debug:
1478 file_copies--debug:
1479 file_copies--debug:
1479 file_copies--debug:
1480 file_copies--debug:
1480 file_copies--debug:
1481 file_copies--debug:
1481 file_copies--debug:
1482 file_copies_switch:
1482 file_copies_switch:
1483 file_copies_switch:
1483 file_copies_switch:
1484 file_copies_switch:
1484 file_copies_switch:
1485 file_copies_switch:
1485 file_copies_switch:
1486 file_copies_switch:
1486 file_copies_switch:
1487 file_copies_switch:
1487 file_copies_switch:
1488 file_copies_switch:
1488 file_copies_switch:
1489 file_copies_switch:
1489 file_copies_switch:
1490 file_copies_switch:
1490 file_copies_switch:
1491 file_copies_switch--verbose:
1491 file_copies_switch--verbose:
1492 file_copies_switch--verbose:
1492 file_copies_switch--verbose:
1493 file_copies_switch--verbose:
1493 file_copies_switch--verbose:
1494 file_copies_switch--verbose:
1494 file_copies_switch--verbose:
1495 file_copies_switch--verbose:
1495 file_copies_switch--verbose:
1496 file_copies_switch--verbose:
1496 file_copies_switch--verbose:
1497 file_copies_switch--verbose:
1497 file_copies_switch--verbose:
1498 file_copies_switch--verbose:
1498 file_copies_switch--verbose:
1499 file_copies_switch--verbose:
1499 file_copies_switch--verbose:
1500 file_copies_switch--debug:
1500 file_copies_switch--debug:
1501 file_copies_switch--debug:
1501 file_copies_switch--debug:
1502 file_copies_switch--debug:
1502 file_copies_switch--debug:
1503 file_copies_switch--debug:
1503 file_copies_switch--debug:
1504 file_copies_switch--debug:
1504 file_copies_switch--debug:
1505 file_copies_switch--debug:
1505 file_copies_switch--debug:
1506 file_copies_switch--debug:
1506 file_copies_switch--debug:
1507 file_copies_switch--debug:
1507 file_copies_switch--debug:
1508 file_copies_switch--debug:
1508 file_copies_switch--debug:
1509 files: fourth second third
1509 files: fourth second third
1510 files: second
1510 files: second
1511 files:
1511 files:
1512 files: d
1512 files: d
1513 files:
1513 files:
1514 files: c
1514 files: c
1515 files: c
1515 files: c
1516 files: b
1516 files: b
1517 files: a
1517 files: a
1518 files--verbose: fourth second third
1518 files--verbose: fourth second third
1519 files--verbose: second
1519 files--verbose: second
1520 files--verbose:
1520 files--verbose:
1521 files--verbose: d
1521 files--verbose: d
1522 files--verbose:
1522 files--verbose:
1523 files--verbose: c
1523 files--verbose: c
1524 files--verbose: c
1524 files--verbose: c
1525 files--verbose: b
1525 files--verbose: b
1526 files--verbose: a
1526 files--verbose: a
1527 files--debug: fourth second third
1527 files--debug: fourth second third
1528 files--debug: second
1528 files--debug: second
1529 files--debug:
1529 files--debug:
1530 files--debug: d
1530 files--debug: d
1531 files--debug:
1531 files--debug:
1532 files--debug: c
1532 files--debug: c
1533 files--debug: c
1533 files--debug: c
1534 files--debug: b
1534 files--debug: b
1535 files--debug: a
1535 files--debug: a
1536 manifest: 6:94961b75a2da
1536 manifest: 6:94961b75a2da
1537 manifest: 5:f2dbc354b94e
1537 manifest: 5:f2dbc354b94e
1538 manifest: 4:4dc3def4f9b4
1538 manifest: 4:4dc3def4f9b4
1539 manifest: 4:4dc3def4f9b4
1539 manifest: 4:4dc3def4f9b4
1540 manifest: 3:cb5a1327723b
1540 manifest: 3:cb5a1327723b
1541 manifest: 3:cb5a1327723b
1541 manifest: 3:cb5a1327723b
1542 manifest: 2:6e0e82995c35
1542 manifest: 2:6e0e82995c35
1543 manifest: 1:4e8d705b1e53
1543 manifest: 1:4e8d705b1e53
1544 manifest: 0:a0c8bcbbb45c
1544 manifest: 0:a0c8bcbbb45c
1545 manifest--verbose: 6:94961b75a2da
1545 manifest--verbose: 6:94961b75a2da
1546 manifest--verbose: 5:f2dbc354b94e
1546 manifest--verbose: 5:f2dbc354b94e
1547 manifest--verbose: 4:4dc3def4f9b4
1547 manifest--verbose: 4:4dc3def4f9b4
1548 manifest--verbose: 4:4dc3def4f9b4
1548 manifest--verbose: 4:4dc3def4f9b4
1549 manifest--verbose: 3:cb5a1327723b
1549 manifest--verbose: 3:cb5a1327723b
1550 manifest--verbose: 3:cb5a1327723b
1550 manifest--verbose: 3:cb5a1327723b
1551 manifest--verbose: 2:6e0e82995c35
1551 manifest--verbose: 2:6e0e82995c35
1552 manifest--verbose: 1:4e8d705b1e53
1552 manifest--verbose: 1:4e8d705b1e53
1553 manifest--verbose: 0:a0c8bcbbb45c
1553 manifest--verbose: 0:a0c8bcbbb45c
1554 manifest--debug: 6:94961b75a2da554b4df6fb599e5bfc7d48de0c64
1554 manifest--debug: 6:94961b75a2da554b4df6fb599e5bfc7d48de0c64
1555 manifest--debug: 5:f2dbc354b94e5ec0b4f10680ee0cee816101d0bf
1555 manifest--debug: 5:f2dbc354b94e5ec0b4f10680ee0cee816101d0bf
1556 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
1556 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
1557 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
1557 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
1558 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
1558 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
1559 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
1559 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
1560 manifest--debug: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
1560 manifest--debug: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
1561 manifest--debug: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
1561 manifest--debug: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
1562 manifest--debug: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
1562 manifest--debug: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
1563 node: 95c24699272ef57d062b8bccc32c878bf841784a
1563 node: 95c24699272ef57d062b8bccc32c878bf841784a
1564 node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1564 node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1565 node: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1565 node: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1566 node: 13207e5a10d9fd28ec424934298e176197f2c67f
1566 node: 13207e5a10d9fd28ec424934298e176197f2c67f
1567 node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1567 node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1568 node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1568 node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1569 node: 97054abb4ab824450e9164180baf491ae0078465
1569 node: 97054abb4ab824450e9164180baf491ae0078465
1570 node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1570 node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1571 node: 1e4e1b8f71e05681d422154f5421e385fec3454f
1571 node: 1e4e1b8f71e05681d422154f5421e385fec3454f
1572 node--verbose: 95c24699272ef57d062b8bccc32c878bf841784a
1572 node--verbose: 95c24699272ef57d062b8bccc32c878bf841784a
1573 node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1573 node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1574 node--verbose: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1574 node--verbose: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1575 node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
1575 node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
1576 node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1576 node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1577 node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1577 node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1578 node--verbose: 97054abb4ab824450e9164180baf491ae0078465
1578 node--verbose: 97054abb4ab824450e9164180baf491ae0078465
1579 node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1579 node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1580 node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
1580 node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
1581 node--debug: 95c24699272ef57d062b8bccc32c878bf841784a
1581 node--debug: 95c24699272ef57d062b8bccc32c878bf841784a
1582 node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1582 node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1583 node--debug: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1583 node--debug: d41e714fe50d9e4a5f11b4d595d543481b5f980b
1584 node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
1584 node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
1585 node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1585 node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1586 node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1586 node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1587 node--debug: 97054abb4ab824450e9164180baf491ae0078465
1587 node--debug: 97054abb4ab824450e9164180baf491ae0078465
1588 node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1588 node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1589 node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
1589 node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
1590 parents:
1590 parents:
1591 parents: -1:000000000000
1591 parents: -1:000000000000
1592 parents: 5:13207e5a10d9 4:bbe44766e73d
1592 parents: 5:13207e5a10d9 4:bbe44766e73d
1593 parents: 3:10e46f2dcbf4
1593 parents: 3:10e46f2dcbf4
1594 parents:
1594 parents:
1595 parents:
1595 parents:
1596 parents:
1596 parents:
1597 parents:
1597 parents:
1598 parents:
1598 parents:
1599 parents--verbose:
1599 parents--verbose:
1600 parents--verbose: -1:000000000000
1600 parents--verbose: -1:000000000000
1601 parents--verbose: 5:13207e5a10d9 4:bbe44766e73d
1601 parents--verbose: 5:13207e5a10d9 4:bbe44766e73d
1602 parents--verbose: 3:10e46f2dcbf4
1602 parents--verbose: 3:10e46f2dcbf4
1603 parents--verbose:
1603 parents--verbose:
1604 parents--verbose:
1604 parents--verbose:
1605 parents--verbose:
1605 parents--verbose:
1606 parents--verbose:
1606 parents--verbose:
1607 parents--verbose:
1607 parents--verbose:
1608 parents--debug: 7:29114dbae42b9f078cf2714dbe3a86bba8ec7453 -1:0000000000000000000000000000000000000000
1608 parents--debug: 7:29114dbae42b9f078cf2714dbe3a86bba8ec7453 -1:0000000000000000000000000000000000000000
1609 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
1609 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
1610 parents--debug: 5:13207e5a10d9fd28ec424934298e176197f2c67f 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
1610 parents--debug: 5:13207e5a10d9fd28ec424934298e176197f2c67f 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
1611 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
1611 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
1612 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
1612 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
1613 parents--debug: 2:97054abb4ab824450e9164180baf491ae0078465 -1:0000000000000000000000000000000000000000
1613 parents--debug: 2:97054abb4ab824450e9164180baf491ae0078465 -1:0000000000000000000000000000000000000000
1614 parents--debug: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965 -1:0000000000000000000000000000000000000000
1614 parents--debug: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965 -1:0000000000000000000000000000000000000000
1615 parents--debug: 0:1e4e1b8f71e05681d422154f5421e385fec3454f -1:0000000000000000000000000000000000000000
1615 parents--debug: 0:1e4e1b8f71e05681d422154f5421e385fec3454f -1:0000000000000000000000000000000000000000
1616 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
1616 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
1617 rev: 8
1617 rev: 8
1618 rev: 7
1618 rev: 7
1619 rev: 6
1619 rev: 6
1620 rev: 5
1620 rev: 5
1621 rev: 4
1621 rev: 4
1622 rev: 3
1622 rev: 3
1623 rev: 2
1623 rev: 2
1624 rev: 1
1624 rev: 1
1625 rev: 0
1625 rev: 0
1626 rev--verbose: 8
1626 rev--verbose: 8
1627 rev--verbose: 7
1627 rev--verbose: 7
1628 rev--verbose: 6
1628 rev--verbose: 6
1629 rev--verbose: 5
1629 rev--verbose: 5
1630 rev--verbose: 4
1630 rev--verbose: 4
1631 rev--verbose: 3
1631 rev--verbose: 3
1632 rev--verbose: 2
1632 rev--verbose: 2
1633 rev--verbose: 1
1633 rev--verbose: 1
1634 rev--verbose: 0
1634 rev--verbose: 0
1635 rev--debug: 8
1635 rev--debug: 8
1636 rev--debug: 7
1636 rev--debug: 7
1637 rev--debug: 6
1637 rev--debug: 6
1638 rev--debug: 5
1638 rev--debug: 5
1639 rev--debug: 4
1639 rev--debug: 4
1640 rev--debug: 3
1640 rev--debug: 3
1641 rev--debug: 2
1641 rev--debug: 2
1642 rev--debug: 1
1642 rev--debug: 1
1643 rev--debug: 0
1643 rev--debug: 0
1644 tags: tip
1644 tags: tip
1645 tags:
1645 tags:
1646 tags:
1646 tags:
1647 tags:
1647 tags:
1648 tags:
1648 tags:
1649 tags:
1649 tags:
1650 tags:
1650 tags:
1651 tags:
1651 tags:
1652 tags:
1652 tags:
1653 tags--verbose: tip
1653 tags--verbose: tip
1654 tags--verbose:
1654 tags--verbose:
1655 tags--verbose:
1655 tags--verbose:
1656 tags--verbose:
1656 tags--verbose:
1657 tags--verbose:
1657 tags--verbose:
1658 tags--verbose:
1658 tags--verbose:
1659 tags--verbose:
1659 tags--verbose:
1660 tags--verbose:
1660 tags--verbose:
1661 tags--verbose:
1661 tags--verbose:
1662 tags--debug: tip
1662 tags--debug: tip
1663 tags--debug:
1663 tags--debug:
1664 tags--debug:
1664 tags--debug:
1665 tags--debug:
1665 tags--debug:
1666 tags--debug:
1666 tags--debug:
1667 tags--debug:
1667 tags--debug:
1668 tags--debug:
1668 tags--debug:
1669 tags--debug:
1669 tags--debug:
1670 tags--debug:
1670 tags--debug:
1671 diffstat: 3: +2/-1
1671 diffstat: 3: +2/-1
1672 diffstat: 1: +1/-0
1672 diffstat: 1: +1/-0
1673 diffstat: 0: +0/-0
1673 diffstat: 0: +0/-0
1674 diffstat: 1: +1/-0
1674 diffstat: 1: +1/-0
1675 diffstat: 0: +0/-0
1675 diffstat: 0: +0/-0
1676 diffstat: 1: +1/-0
1676 diffstat: 1: +1/-0
1677 diffstat: 1: +4/-0
1677 diffstat: 1: +4/-0
1678 diffstat: 1: +2/-0
1678 diffstat: 1: +2/-0
1679 diffstat: 1: +1/-0
1679 diffstat: 1: +1/-0
1680 diffstat--verbose: 3: +2/-1
1680 diffstat--verbose: 3: +2/-1
1681 diffstat--verbose: 1: +1/-0
1681 diffstat--verbose: 1: +1/-0
1682 diffstat--verbose: 0: +0/-0
1682 diffstat--verbose: 0: +0/-0
1683 diffstat--verbose: 1: +1/-0
1683 diffstat--verbose: 1: +1/-0
1684 diffstat--verbose: 0: +0/-0
1684 diffstat--verbose: 0: +0/-0
1685 diffstat--verbose: 1: +1/-0
1685 diffstat--verbose: 1: +1/-0
1686 diffstat--verbose: 1: +4/-0
1686 diffstat--verbose: 1: +4/-0
1687 diffstat--verbose: 1: +2/-0
1687 diffstat--verbose: 1: +2/-0
1688 diffstat--verbose: 1: +1/-0
1688 diffstat--verbose: 1: +1/-0
1689 diffstat--debug: 3: +2/-1
1689 diffstat--debug: 3: +2/-1
1690 diffstat--debug: 1: +1/-0
1690 diffstat--debug: 1: +1/-0
1691 diffstat--debug: 0: +0/-0
1691 diffstat--debug: 0: +0/-0
1692 diffstat--debug: 1: +1/-0
1692 diffstat--debug: 1: +1/-0
1693 diffstat--debug: 0: +0/-0
1693 diffstat--debug: 0: +0/-0
1694 diffstat--debug: 1: +1/-0
1694 diffstat--debug: 1: +1/-0
1695 diffstat--debug: 1: +4/-0
1695 diffstat--debug: 1: +4/-0
1696 diffstat--debug: 1: +2/-0
1696 diffstat--debug: 1: +2/-0
1697 diffstat--debug: 1: +1/-0
1697 diffstat--debug: 1: +1/-0
1698 extras: branch=default
1698 extras: branch=default
1699 extras: branch=default
1699 extras: branch=default
1700 extras: branch=default
1700 extras: branch=default
1701 extras: branch=default
1701 extras: branch=default
1702 extras: branch=foo
1702 extras: branch=foo
1703 extras: branch=default
1703 extras: branch=default
1704 extras: branch=default
1704 extras: branch=default
1705 extras: branch=default
1705 extras: branch=default
1706 extras: branch=default
1706 extras: branch=default
1707 extras--verbose: branch=default
1707 extras--verbose: branch=default
1708 extras--verbose: branch=default
1708 extras--verbose: branch=default
1709 extras--verbose: branch=default
1709 extras--verbose: branch=default
1710 extras--verbose: branch=default
1710 extras--verbose: branch=default
1711 extras--verbose: branch=foo
1711 extras--verbose: branch=foo
1712 extras--verbose: branch=default
1712 extras--verbose: branch=default
1713 extras--verbose: branch=default
1713 extras--verbose: branch=default
1714 extras--verbose: branch=default
1714 extras--verbose: branch=default
1715 extras--verbose: branch=default
1715 extras--verbose: branch=default
1716 extras--debug: branch=default
1716 extras--debug: branch=default
1717 extras--debug: branch=default
1717 extras--debug: branch=default
1718 extras--debug: branch=default
1718 extras--debug: branch=default
1719 extras--debug: branch=default
1719 extras--debug: branch=default
1720 extras--debug: branch=foo
1720 extras--debug: branch=foo
1721 extras--debug: branch=default
1721 extras--debug: branch=default
1722 extras--debug: branch=default
1722 extras--debug: branch=default
1723 extras--debug: branch=default
1723 extras--debug: branch=default
1724 extras--debug: branch=default
1724 extras--debug: branch=default
1725 p1rev: 7
1725 p1rev: 7
1726 p1rev: -1
1726 p1rev: -1
1727 p1rev: 5
1727 p1rev: 5
1728 p1rev: 3
1728 p1rev: 3
1729 p1rev: 3
1729 p1rev: 3
1730 p1rev: 2
1730 p1rev: 2
1731 p1rev: 1
1731 p1rev: 1
1732 p1rev: 0
1732 p1rev: 0
1733 p1rev: -1
1733 p1rev: -1
1734 p1rev--verbose: 7
1734 p1rev--verbose: 7
1735 p1rev--verbose: -1
1735 p1rev--verbose: -1
1736 p1rev--verbose: 5
1736 p1rev--verbose: 5
1737 p1rev--verbose: 3
1737 p1rev--verbose: 3
1738 p1rev--verbose: 3
1738 p1rev--verbose: 3
1739 p1rev--verbose: 2
1739 p1rev--verbose: 2
1740 p1rev--verbose: 1
1740 p1rev--verbose: 1
1741 p1rev--verbose: 0
1741 p1rev--verbose: 0
1742 p1rev--verbose: -1
1742 p1rev--verbose: -1
1743 p1rev--debug: 7
1743 p1rev--debug: 7
1744 p1rev--debug: -1
1744 p1rev--debug: -1
1745 p1rev--debug: 5
1745 p1rev--debug: 5
1746 p1rev--debug: 3
1746 p1rev--debug: 3
1747 p1rev--debug: 3
1747 p1rev--debug: 3
1748 p1rev--debug: 2
1748 p1rev--debug: 2
1749 p1rev--debug: 1
1749 p1rev--debug: 1
1750 p1rev--debug: 0
1750 p1rev--debug: 0
1751 p1rev--debug: -1
1751 p1rev--debug: -1
1752 p2rev: -1
1752 p2rev: -1
1753 p2rev: -1
1753 p2rev: -1
1754 p2rev: 4
1754 p2rev: 4
1755 p2rev: -1
1755 p2rev: -1
1756 p2rev: -1
1756 p2rev: -1
1757 p2rev: -1
1757 p2rev: -1
1758 p2rev: -1
1758 p2rev: -1
1759 p2rev: -1
1759 p2rev: -1
1760 p2rev: -1
1760 p2rev: -1
1761 p2rev--verbose: -1
1761 p2rev--verbose: -1
1762 p2rev--verbose: -1
1762 p2rev--verbose: -1
1763 p2rev--verbose: 4
1763 p2rev--verbose: 4
1764 p2rev--verbose: -1
1764 p2rev--verbose: -1
1765 p2rev--verbose: -1
1765 p2rev--verbose: -1
1766 p2rev--verbose: -1
1766 p2rev--verbose: -1
1767 p2rev--verbose: -1
1767 p2rev--verbose: -1
1768 p2rev--verbose: -1
1768 p2rev--verbose: -1
1769 p2rev--verbose: -1
1769 p2rev--verbose: -1
1770 p2rev--debug: -1
1770 p2rev--debug: -1
1771 p2rev--debug: -1
1771 p2rev--debug: -1
1772 p2rev--debug: 4
1772 p2rev--debug: 4
1773 p2rev--debug: -1
1773 p2rev--debug: -1
1774 p2rev--debug: -1
1774 p2rev--debug: -1
1775 p2rev--debug: -1
1775 p2rev--debug: -1
1776 p2rev--debug: -1
1776 p2rev--debug: -1
1777 p2rev--debug: -1
1777 p2rev--debug: -1
1778 p2rev--debug: -1
1778 p2rev--debug: -1
1779 p1node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1779 p1node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1780 p1node: 0000000000000000000000000000000000000000
1780 p1node: 0000000000000000000000000000000000000000
1781 p1node: 13207e5a10d9fd28ec424934298e176197f2c67f
1781 p1node: 13207e5a10d9fd28ec424934298e176197f2c67f
1782 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1782 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1783 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1783 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1784 p1node: 97054abb4ab824450e9164180baf491ae0078465
1784 p1node: 97054abb4ab824450e9164180baf491ae0078465
1785 p1node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1785 p1node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1786 p1node: 1e4e1b8f71e05681d422154f5421e385fec3454f
1786 p1node: 1e4e1b8f71e05681d422154f5421e385fec3454f
1787 p1node: 0000000000000000000000000000000000000000
1787 p1node: 0000000000000000000000000000000000000000
1788 p1node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1788 p1node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1789 p1node--verbose: 0000000000000000000000000000000000000000
1789 p1node--verbose: 0000000000000000000000000000000000000000
1790 p1node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
1790 p1node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
1791 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1791 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1792 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1792 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1793 p1node--verbose: 97054abb4ab824450e9164180baf491ae0078465
1793 p1node--verbose: 97054abb4ab824450e9164180baf491ae0078465
1794 p1node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1794 p1node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1795 p1node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
1795 p1node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
1796 p1node--verbose: 0000000000000000000000000000000000000000
1796 p1node--verbose: 0000000000000000000000000000000000000000
1797 p1node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1797 p1node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1798 p1node--debug: 0000000000000000000000000000000000000000
1798 p1node--debug: 0000000000000000000000000000000000000000
1799 p1node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
1799 p1node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
1800 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1800 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1801 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1801 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1802 p1node--debug: 97054abb4ab824450e9164180baf491ae0078465
1802 p1node--debug: 97054abb4ab824450e9164180baf491ae0078465
1803 p1node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1803 p1node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1804 p1node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
1804 p1node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
1805 p1node--debug: 0000000000000000000000000000000000000000
1805 p1node--debug: 0000000000000000000000000000000000000000
1806 p2node: 0000000000000000000000000000000000000000
1806 p2node: 0000000000000000000000000000000000000000
1807 p2node: 0000000000000000000000000000000000000000
1807 p2node: 0000000000000000000000000000000000000000
1808 p2node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1808 p2node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1809 p2node: 0000000000000000000000000000000000000000
1809 p2node: 0000000000000000000000000000000000000000
1810 p2node: 0000000000000000000000000000000000000000
1810 p2node: 0000000000000000000000000000000000000000
1811 p2node: 0000000000000000000000000000000000000000
1811 p2node: 0000000000000000000000000000000000000000
1812 p2node: 0000000000000000000000000000000000000000
1812 p2node: 0000000000000000000000000000000000000000
1813 p2node: 0000000000000000000000000000000000000000
1813 p2node: 0000000000000000000000000000000000000000
1814 p2node: 0000000000000000000000000000000000000000
1814 p2node: 0000000000000000000000000000000000000000
1815 p2node--verbose: 0000000000000000000000000000000000000000
1815 p2node--verbose: 0000000000000000000000000000000000000000
1816 p2node--verbose: 0000000000000000000000000000000000000000
1816 p2node--verbose: 0000000000000000000000000000000000000000
1817 p2node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1817 p2node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1818 p2node--verbose: 0000000000000000000000000000000000000000
1818 p2node--verbose: 0000000000000000000000000000000000000000
1819 p2node--verbose: 0000000000000000000000000000000000000000
1819 p2node--verbose: 0000000000000000000000000000000000000000
1820 p2node--verbose: 0000000000000000000000000000000000000000
1820 p2node--verbose: 0000000000000000000000000000000000000000
1821 p2node--verbose: 0000000000000000000000000000000000000000
1821 p2node--verbose: 0000000000000000000000000000000000000000
1822 p2node--verbose: 0000000000000000000000000000000000000000
1822 p2node--verbose: 0000000000000000000000000000000000000000
1823 p2node--verbose: 0000000000000000000000000000000000000000
1823 p2node--verbose: 0000000000000000000000000000000000000000
1824 p2node--debug: 0000000000000000000000000000000000000000
1824 p2node--debug: 0000000000000000000000000000000000000000
1825 p2node--debug: 0000000000000000000000000000000000000000
1825 p2node--debug: 0000000000000000000000000000000000000000
1826 p2node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1826 p2node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1827 p2node--debug: 0000000000000000000000000000000000000000
1827 p2node--debug: 0000000000000000000000000000000000000000
1828 p2node--debug: 0000000000000000000000000000000000000000
1828 p2node--debug: 0000000000000000000000000000000000000000
1829 p2node--debug: 0000000000000000000000000000000000000000
1829 p2node--debug: 0000000000000000000000000000000000000000
1830 p2node--debug: 0000000000000000000000000000000000000000
1830 p2node--debug: 0000000000000000000000000000000000000000
1831 p2node--debug: 0000000000000000000000000000000000000000
1831 p2node--debug: 0000000000000000000000000000000000000000
1832 p2node--debug: 0000000000000000000000000000000000000000
1832 p2node--debug: 0000000000000000000000000000000000000000
1833
1833
1834 Filters work:
1834 Filters work:
1835
1835
1836 $ hg log --template '{author|domain}\n'
1836 $ hg log --template '{author|domain}\n'
1837
1837
1838 hostname
1838 hostname
1839
1839
1840
1840
1841
1841
1842
1842
1843 place
1843 place
1844 place
1844 place
1845 hostname
1845 hostname
1846
1846
1847 $ hg log --template '{author|person}\n'
1847 $ hg log --template '{author|person}\n'
1848 test
1848 test
1849 User Name
1849 User Name
1850 person
1850 person
1851 person
1851 person
1852 person
1852 person
1853 person
1853 person
1854 other
1854 other
1855 A. N. Other
1855 A. N. Other
1856 User Name
1856 User Name
1857
1857
1858 $ hg log --template '{author|user}\n'
1858 $ hg log --template '{author|user}\n'
1859 test
1859 test
1860 user
1860 user
1861 person
1861 person
1862 person
1862 person
1863 person
1863 person
1864 person
1864 person
1865 other
1865 other
1866 other
1866 other
1867 user
1867 user
1868
1868
1869 $ hg log --template '{date|date}\n'
1869 $ hg log --template '{date|date}\n'
1870 Wed Jan 01 10:01:00 2020 +0000
1870 Wed Jan 01 10:01:00 2020 +0000
1871 Mon Jan 12 13:46:40 1970 +0000
1871 Mon Jan 12 13:46:40 1970 +0000
1872 Sun Jan 18 08:40:01 1970 +0000
1872 Sun Jan 18 08:40:01 1970 +0000
1873 Sun Jan 18 08:40:00 1970 +0000
1873 Sun Jan 18 08:40:00 1970 +0000
1874 Sat Jan 17 04:53:20 1970 +0000
1874 Sat Jan 17 04:53:20 1970 +0000
1875 Fri Jan 16 01:06:40 1970 +0000
1875 Fri Jan 16 01:06:40 1970 +0000
1876 Wed Jan 14 21:20:00 1970 +0000
1876 Wed Jan 14 21:20:00 1970 +0000
1877 Tue Jan 13 17:33:20 1970 +0000
1877 Tue Jan 13 17:33:20 1970 +0000
1878 Mon Jan 12 13:46:40 1970 +0000
1878 Mon Jan 12 13:46:40 1970 +0000
1879
1879
1880 $ hg log --template '{date|isodate}\n'
1880 $ hg log --template '{date|isodate}\n'
1881 2020-01-01 10:01 +0000
1881 2020-01-01 10:01 +0000
1882 1970-01-12 13:46 +0000
1882 1970-01-12 13:46 +0000
1883 1970-01-18 08:40 +0000
1883 1970-01-18 08:40 +0000
1884 1970-01-18 08:40 +0000
1884 1970-01-18 08:40 +0000
1885 1970-01-17 04:53 +0000
1885 1970-01-17 04:53 +0000
1886 1970-01-16 01:06 +0000
1886 1970-01-16 01:06 +0000
1887 1970-01-14 21:20 +0000
1887 1970-01-14 21:20 +0000
1888 1970-01-13 17:33 +0000
1888 1970-01-13 17:33 +0000
1889 1970-01-12 13:46 +0000
1889 1970-01-12 13:46 +0000
1890
1890
1891 $ hg log --template '{date|isodatesec}\n'
1891 $ hg log --template '{date|isodatesec}\n'
1892 2020-01-01 10:01:00 +0000
1892 2020-01-01 10:01:00 +0000
1893 1970-01-12 13:46:40 +0000
1893 1970-01-12 13:46:40 +0000
1894 1970-01-18 08:40:01 +0000
1894 1970-01-18 08:40:01 +0000
1895 1970-01-18 08:40:00 +0000
1895 1970-01-18 08:40:00 +0000
1896 1970-01-17 04:53:20 +0000
1896 1970-01-17 04:53:20 +0000
1897 1970-01-16 01:06:40 +0000
1897 1970-01-16 01:06:40 +0000
1898 1970-01-14 21:20:00 +0000
1898 1970-01-14 21:20:00 +0000
1899 1970-01-13 17:33:20 +0000
1899 1970-01-13 17:33:20 +0000
1900 1970-01-12 13:46:40 +0000
1900 1970-01-12 13:46:40 +0000
1901
1901
1902 $ hg log --template '{date|rfc822date}\n'
1902 $ hg log --template '{date|rfc822date}\n'
1903 Wed, 01 Jan 2020 10:01:00 +0000
1903 Wed, 01 Jan 2020 10:01:00 +0000
1904 Mon, 12 Jan 1970 13:46:40 +0000
1904 Mon, 12 Jan 1970 13:46:40 +0000
1905 Sun, 18 Jan 1970 08:40:01 +0000
1905 Sun, 18 Jan 1970 08:40:01 +0000
1906 Sun, 18 Jan 1970 08:40:00 +0000
1906 Sun, 18 Jan 1970 08:40:00 +0000
1907 Sat, 17 Jan 1970 04:53:20 +0000
1907 Sat, 17 Jan 1970 04:53:20 +0000
1908 Fri, 16 Jan 1970 01:06:40 +0000
1908 Fri, 16 Jan 1970 01:06:40 +0000
1909 Wed, 14 Jan 1970 21:20:00 +0000
1909 Wed, 14 Jan 1970 21:20:00 +0000
1910 Tue, 13 Jan 1970 17:33:20 +0000
1910 Tue, 13 Jan 1970 17:33:20 +0000
1911 Mon, 12 Jan 1970 13:46:40 +0000
1911 Mon, 12 Jan 1970 13:46:40 +0000
1912
1912
1913 $ hg log --template '{desc|firstline}\n'
1913 $ hg log --template '{desc|firstline}\n'
1914 third
1914 third
1915 second
1915 second
1916 merge
1916 merge
1917 new head
1917 new head
1918 new branch
1918 new branch
1919 no user, no domain
1919 no user, no domain
1920 no person
1920 no person
1921 other 1
1921 other 1
1922 line 1
1922 line 1
1923
1923
1924 $ hg log --template '{node|short}\n'
1924 $ hg log --template '{node|short}\n'
1925 95c24699272e
1925 95c24699272e
1926 29114dbae42b
1926 29114dbae42b
1927 d41e714fe50d
1927 d41e714fe50d
1928 13207e5a10d9
1928 13207e5a10d9
1929 bbe44766e73d
1929 bbe44766e73d
1930 10e46f2dcbf4
1930 10e46f2dcbf4
1931 97054abb4ab8
1931 97054abb4ab8
1932 b608e9d1a3f0
1932 b608e9d1a3f0
1933 1e4e1b8f71e0
1933 1e4e1b8f71e0
1934
1934
1935 $ hg log --template '<changeset author="{author|xmlescape}"/>\n'
1935 $ hg log --template '<changeset author="{author|xmlescape}"/>\n'
1936 <changeset author="test"/>
1936 <changeset author="test"/>
1937 <changeset author="User Name &lt;user@hostname&gt;"/>
1937 <changeset author="User Name &lt;user@hostname&gt;"/>
1938 <changeset author="person"/>
1938 <changeset author="person"/>
1939 <changeset author="person"/>
1939 <changeset author="person"/>
1940 <changeset author="person"/>
1940 <changeset author="person"/>
1941 <changeset author="person"/>
1941 <changeset author="person"/>
1942 <changeset author="other@place"/>
1942 <changeset author="other@place"/>
1943 <changeset author="A. N. Other &lt;other@place&gt;"/>
1943 <changeset author="A. N. Other &lt;other@place&gt;"/>
1944 <changeset author="User Name &lt;user@hostname&gt;"/>
1944 <changeset author="User Name &lt;user@hostname&gt;"/>
1945
1945
1946 $ hg log --template '{rev}: {children}\n'
1946 $ hg log --template '{rev}: {children}\n'
1947 8:
1947 8:
1948 7: 8:95c24699272e
1948 7: 8:95c24699272e
1949 6:
1949 6:
1950 5: 6:d41e714fe50d
1950 5: 6:d41e714fe50d
1951 4: 6:d41e714fe50d
1951 4: 6:d41e714fe50d
1952 3: 4:bbe44766e73d 5:13207e5a10d9
1952 3: 4:bbe44766e73d 5:13207e5a10d9
1953 2: 3:10e46f2dcbf4
1953 2: 3:10e46f2dcbf4
1954 1: 2:97054abb4ab8
1954 1: 2:97054abb4ab8
1955 0: 1:b608e9d1a3f0
1955 0: 1:b608e9d1a3f0
1956
1956
1957 Formatnode filter works:
1957 Formatnode filter works:
1958
1958
1959 $ hg -q log -r 0 --template '{node|formatnode}\n'
1959 $ hg -q log -r 0 --template '{node|formatnode}\n'
1960 1e4e1b8f71e0
1960 1e4e1b8f71e0
1961
1961
1962 $ hg log -r 0 --template '{node|formatnode}\n'
1962 $ hg log -r 0 --template '{node|formatnode}\n'
1963 1e4e1b8f71e0
1963 1e4e1b8f71e0
1964
1964
1965 $ hg -v log -r 0 --template '{node|formatnode}\n'
1965 $ hg -v log -r 0 --template '{node|formatnode}\n'
1966 1e4e1b8f71e0
1966 1e4e1b8f71e0
1967
1967
1968 $ hg --debug log -r 0 --template '{node|formatnode}\n'
1968 $ hg --debug log -r 0 --template '{node|formatnode}\n'
1969 1e4e1b8f71e05681d422154f5421e385fec3454f
1969 1e4e1b8f71e05681d422154f5421e385fec3454f
1970
1970
1971 Age filter:
1971 Age filter:
1972
1972
1973 $ hg init unstable-hash
1973 $ hg init unstable-hash
1974 $ cd unstable-hash
1974 $ cd unstable-hash
1975 $ hg log --template '{date|age}\n' > /dev/null || exit 1
1975 $ hg log --template '{date|age}\n' > /dev/null || exit 1
1976
1976
1977 >>> from datetime import datetime, timedelta
1977 >>> from datetime import datetime, timedelta
1978 >>> fp = open('a', 'w')
1978 >>> fp = open('a', 'w')
1979 >>> n = datetime.now() + timedelta(366 * 7)
1979 >>> n = datetime.now() + timedelta(366 * 7)
1980 >>> fp.write('%d-%d-%d 00:00' % (n.year, n.month, n.day))
1980 >>> fp.write('%d-%d-%d 00:00' % (n.year, n.month, n.day))
1981 >>> fp.close()
1981 >>> fp.close()
1982 $ hg add a
1982 $ hg add a
1983 $ hg commit -m future -d "`cat a`"
1983 $ hg commit -m future -d "`cat a`"
1984
1984
1985 $ hg log -l1 --template '{date|age}\n'
1985 $ hg log -l1 --template '{date|age}\n'
1986 7 years from now
1986 7 years from now
1987
1987
1988 $ cd ..
1988 $ cd ..
1989 $ rm -rf unstable-hash
1989 $ rm -rf unstable-hash
1990
1990
1991 Add a dummy commit to make up for the instability of the above:
1991 Add a dummy commit to make up for the instability of the above:
1992
1992
1993 $ echo a > a
1993 $ echo a > a
1994 $ hg add a
1994 $ hg add a
1995 $ hg ci -m future
1995 $ hg ci -m future
1996
1996
1997 Count filter:
1997 Count filter:
1998
1998
1999 $ hg log -l1 --template '{node|count} {node|short|count}\n'
1999 $ hg log -l1 --template '{node|count} {node|short|count}\n'
2000 40 12
2000 40 12
2001
2001
2002 $ hg log -l1 --template '{revset("null^")|count} {revset(".")|count} {revset("0::3")|count}\n'
2002 $ hg log -l1 --template '{revset("null^")|count} {revset(".")|count} {revset("0::3")|count}\n'
2003 0 1 4
2003 0 1 4
2004
2004
2005 $ hg log -G --template '{rev}: children: {children|count}, \
2005 $ hg log -G --template '{rev}: children: {children|count}, \
2006 > tags: {tags|count}, file_adds: {file_adds|count}, \
2006 > tags: {tags|count}, file_adds: {file_adds|count}, \
2007 > ancestors: {revset("ancestors(%s)", rev)|count}'
2007 > ancestors: {revset("ancestors(%s)", rev)|count}'
2008 @ 9: children: 0, tags: 1, file_adds: 1, ancestors: 3
2008 @ 9: children: 0, tags: 1, file_adds: 1, ancestors: 3
2009 |
2009 |
2010 o 8: children: 1, tags: 0, file_adds: 2, ancestors: 2
2010 o 8: children: 1, tags: 0, file_adds: 2, ancestors: 2
2011 |
2011 |
2012 o 7: children: 1, tags: 0, file_adds: 1, ancestors: 1
2012 o 7: children: 1, tags: 0, file_adds: 1, ancestors: 1
2013
2013
2014 o 6: children: 0, tags: 0, file_adds: 0, ancestors: 7
2014 o 6: children: 0, tags: 0, file_adds: 0, ancestors: 7
2015 |\
2015 |\
2016 | o 5: children: 1, tags: 0, file_adds: 1, ancestors: 5
2016 | o 5: children: 1, tags: 0, file_adds: 1, ancestors: 5
2017 | |
2017 | |
2018 o | 4: children: 1, tags: 0, file_adds: 0, ancestors: 5
2018 o | 4: children: 1, tags: 0, file_adds: 0, ancestors: 5
2019 |/
2019 |/
2020 o 3: children: 2, tags: 0, file_adds: 0, ancestors: 4
2020 o 3: children: 2, tags: 0, file_adds: 0, ancestors: 4
2021 |
2021 |
2022 o 2: children: 1, tags: 0, file_adds: 1, ancestors: 3
2022 o 2: children: 1, tags: 0, file_adds: 1, ancestors: 3
2023 |
2023 |
2024 o 1: children: 1, tags: 0, file_adds: 1, ancestors: 2
2024 o 1: children: 1, tags: 0, file_adds: 1, ancestors: 2
2025 |
2025 |
2026 o 0: children: 1, tags: 0, file_adds: 1, ancestors: 1
2026 o 0: children: 1, tags: 0, file_adds: 1, ancestors: 1
2027
2027
2028
2028
2029 Upper/lower filters:
2029 Upper/lower filters:
2030
2030
2031 $ hg log -r0 --template '{branch|upper}\n'
2031 $ hg log -r0 --template '{branch|upper}\n'
2032 DEFAULT
2032 DEFAULT
2033 $ hg log -r0 --template '{author|lower}\n'
2033 $ hg log -r0 --template '{author|lower}\n'
2034 user name <user@hostname>
2034 user name <user@hostname>
2035 $ hg log -r0 --template '{date|upper}\n'
2035 $ hg log -r0 --template '{date|upper}\n'
2036 abort: template filter 'upper' is not compatible with keyword 'date'
2036 abort: template filter 'upper' is not compatible with keyword 'date'
2037 [255]
2037 [255]
2038
2038
2039 Add a commit that does all possible modifications at once
2039 Add a commit that does all possible modifications at once
2040
2040
2041 $ echo modify >> third
2041 $ echo modify >> third
2042 $ touch b
2042 $ touch b
2043 $ hg add b
2043 $ hg add b
2044 $ hg mv fourth fifth
2044 $ hg mv fourth fifth
2045 $ hg rm a
2045 $ hg rm a
2046 $ hg ci -m "Modify, add, remove, rename"
2046 $ hg ci -m "Modify, add, remove, rename"
2047
2047
2048 Check the status template
2048 Check the status template
2049
2049
2050 $ cat <<EOF >> $HGRCPATH
2050 $ cat <<EOF >> $HGRCPATH
2051 > [extensions]
2051 > [extensions]
2052 > color=
2052 > color=
2053 > EOF
2053 > EOF
2054
2054
2055 $ hg log -T status -r 10
2055 $ hg log -T status -r 10
2056 changeset: 10:0f9759ec227a
2056 changeset: 10:0f9759ec227a
2057 tag: tip
2057 tag: tip
2058 user: test
2058 user: test
2059 date: Thu Jan 01 00:00:00 1970 +0000
2059 date: Thu Jan 01 00:00:00 1970 +0000
2060 summary: Modify, add, remove, rename
2060 summary: Modify, add, remove, rename
2061 files:
2061 files:
2062 M third
2062 M third
2063 A b
2063 A b
2064 A fifth
2064 A fifth
2065 R a
2065 R a
2066 R fourth
2066 R fourth
2067
2067
2068 $ hg log -T status -C -r 10
2068 $ hg log -T status -C -r 10
2069 changeset: 10:0f9759ec227a
2069 changeset: 10:0f9759ec227a
2070 tag: tip
2070 tag: tip
2071 user: test
2071 user: test
2072 date: Thu Jan 01 00:00:00 1970 +0000
2072 date: Thu Jan 01 00:00:00 1970 +0000
2073 summary: Modify, add, remove, rename
2073 summary: Modify, add, remove, rename
2074 files:
2074 files:
2075 M third
2075 M third
2076 A b
2076 A b
2077 A fifth
2077 A fifth
2078 fourth
2078 fourth
2079 R a
2079 R a
2080 R fourth
2080 R fourth
2081
2081
2082 $ hg log -T status -C -r 10 -v
2082 $ hg log -T status -C -r 10 -v
2083 changeset: 10:0f9759ec227a
2083 changeset: 10:0f9759ec227a
2084 tag: tip
2084 tag: tip
2085 user: test
2085 user: test
2086 date: Thu Jan 01 00:00:00 1970 +0000
2086 date: Thu Jan 01 00:00:00 1970 +0000
2087 description:
2087 description:
2088 Modify, add, remove, rename
2088 Modify, add, remove, rename
2089
2089
2090 files:
2090 files:
2091 M third
2091 M third
2092 A b
2092 A b
2093 A fifth
2093 A fifth
2094 fourth
2094 fourth
2095 R a
2095 R a
2096 R fourth
2096 R fourth
2097
2097
2098 $ hg log -T status -C -r 10 --debug
2098 $ hg log -T status -C -r 10 --debug
2099 changeset: 10:0f9759ec227a4859c2014a345cd8a859022b7c6c
2099 changeset: 10:0f9759ec227a4859c2014a345cd8a859022b7c6c
2100 tag: tip
2100 tag: tip
2101 phase: secret
2101 phase: secret
2102 parent: 9:bf9dfba36635106d6a73ccc01e28b762da60e066
2102 parent: 9:bf9dfba36635106d6a73ccc01e28b762da60e066
2103 parent: -1:0000000000000000000000000000000000000000
2103 parent: -1:0000000000000000000000000000000000000000
2104 manifest: 8:89dd546f2de0a9d6d664f58d86097eb97baba567
2104 manifest: 8:89dd546f2de0a9d6d664f58d86097eb97baba567
2105 user: test
2105 user: test
2106 date: Thu Jan 01 00:00:00 1970 +0000
2106 date: Thu Jan 01 00:00:00 1970 +0000
2107 extra: branch=default
2107 extra: branch=default
2108 description:
2108 description:
2109 Modify, add, remove, rename
2109 Modify, add, remove, rename
2110
2110
2111 files:
2111 files:
2112 M third
2112 M third
2113 A b
2113 A b
2114 A fifth
2114 A fifth
2115 fourth
2115 fourth
2116 R a
2116 R a
2117 R fourth
2117 R fourth
2118
2118
2119 $ hg log -T status -C -r 10 --quiet
2119 $ hg log -T status -C -r 10 --quiet
2120 10:0f9759ec227a
2120 10:0f9759ec227a
2121 $ hg --color=debug log -T status -r 10
2121 $ hg --color=debug log -T status -r 10
2122 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2122 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2123 [log.tag|tag: tip]
2123 [log.tag|tag: tip]
2124 [log.user|user: test]
2124 [log.user|user: test]
2125 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2125 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2126 [log.summary|summary: Modify, add, remove, rename]
2126 [log.summary|summary: Modify, add, remove, rename]
2127 [ui.note log.files|files:]
2127 [ui.note log.files|files:]
2128 [status.modified|M third]
2128 [status.modified|M third]
2129 [status.added|A b]
2129 [status.added|A b]
2130 [status.added|A fifth]
2130 [status.added|A fifth]
2131 [status.removed|R a]
2131 [status.removed|R a]
2132 [status.removed|R fourth]
2132 [status.removed|R fourth]
2133
2133
2134 $ hg --color=debug log -T status -C -r 10
2134 $ hg --color=debug log -T status -C -r 10
2135 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2135 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2136 [log.tag|tag: tip]
2136 [log.tag|tag: tip]
2137 [log.user|user: test]
2137 [log.user|user: test]
2138 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2138 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2139 [log.summary|summary: Modify, add, remove, rename]
2139 [log.summary|summary: Modify, add, remove, rename]
2140 [ui.note log.files|files:]
2140 [ui.note log.files|files:]
2141 [status.modified|M third]
2141 [status.modified|M third]
2142 [status.added|A b]
2142 [status.added|A b]
2143 [status.added|A fifth]
2143 [status.added|A fifth]
2144 [status.copied| fourth]
2144 [status.copied| fourth]
2145 [status.removed|R a]
2145 [status.removed|R a]
2146 [status.removed|R fourth]
2146 [status.removed|R fourth]
2147
2147
2148 $ hg --color=debug log -T status -C -r 10 -v
2148 $ hg --color=debug log -T status -C -r 10 -v
2149 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2149 [log.changeset changeset.secret|changeset: 10:0f9759ec227a]
2150 [log.tag|tag: tip]
2150 [log.tag|tag: tip]
2151 [log.user|user: test]
2151 [log.user|user: test]
2152 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2152 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2153 [ui.note log.description|description:]
2153 [ui.note log.description|description:]
2154 [ui.note log.description|Modify, add, remove, rename]
2154 [ui.note log.description|Modify, add, remove, rename]
2155
2155
2156 [ui.note log.files|files:]
2156 [ui.note log.files|files:]
2157 [status.modified|M third]
2157 [status.modified|M third]
2158 [status.added|A b]
2158 [status.added|A b]
2159 [status.added|A fifth]
2159 [status.added|A fifth]
2160 [status.copied| fourth]
2160 [status.copied| fourth]
2161 [status.removed|R a]
2161 [status.removed|R a]
2162 [status.removed|R fourth]
2162 [status.removed|R fourth]
2163
2163
2164 $ hg --color=debug log -T status -C -r 10 --debug
2164 $ hg --color=debug log -T status -C -r 10 --debug
2165 [log.changeset changeset.secret|changeset: 10:0f9759ec227a4859c2014a345cd8a859022b7c6c]
2165 [log.changeset changeset.secret|changeset: 10:0f9759ec227a4859c2014a345cd8a859022b7c6c]
2166 [log.tag|tag: tip]
2166 [log.tag|tag: tip]
2167 [log.phase|phase: secret]
2167 [log.phase|phase: secret]
2168 [log.parent changeset.secret|parent: 9:bf9dfba36635106d6a73ccc01e28b762da60e066]
2168 [log.parent changeset.secret|parent: 9:bf9dfba36635106d6a73ccc01e28b762da60e066]
2169 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2169 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2170 [ui.debug log.manifest|manifest: 8:89dd546f2de0a9d6d664f58d86097eb97baba567]
2170 [ui.debug log.manifest|manifest: 8:89dd546f2de0a9d6d664f58d86097eb97baba567]
2171 [log.user|user: test]
2171 [log.user|user: test]
2172 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2172 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
2173 [ui.debug log.extra|extra: branch=default]
2173 [ui.debug log.extra|extra: branch=default]
2174 [ui.note log.description|description:]
2174 [ui.note log.description|description:]
2175 [ui.note log.description|Modify, add, remove, rename]
2175 [ui.note log.description|Modify, add, remove, rename]
2176
2176
2177 [ui.note log.files|files:]
2177 [ui.note log.files|files:]
2178 [status.modified|M third]
2178 [status.modified|M third]
2179 [status.added|A b]
2179 [status.added|A b]
2180 [status.added|A fifth]
2180 [status.added|A fifth]
2181 [status.copied| fourth]
2181 [status.copied| fourth]
2182 [status.removed|R a]
2182 [status.removed|R a]
2183 [status.removed|R fourth]
2183 [status.removed|R fourth]
2184
2184
2185 $ hg --color=debug log -T status -C -r 10 --quiet
2185 $ hg --color=debug log -T status -C -r 10 --quiet
2186 [log.node|10:0f9759ec227a]
2186 [log.node|10:0f9759ec227a]
2187
2187
2188 Check the bisect template
2188 Check the bisect template
2189
2189
2190 $ hg bisect -g 1
2190 $ hg bisect -g 1
2191 $ hg bisect -b 3 --noupdate
2191 $ hg bisect -b 3 --noupdate
2192 Testing changeset 2:97054abb4ab8 (2 changesets remaining, ~1 tests)
2192 Testing changeset 2:97054abb4ab8 (2 changesets remaining, ~1 tests)
2193 $ hg log -T bisect -r 0:4
2193 $ hg log -T bisect -r 0:4
2194 changeset: 0:1e4e1b8f71e0
2194 changeset: 0:1e4e1b8f71e0
2195 bisect: good (implicit)
2195 bisect: good (implicit)
2196 user: User Name <user@hostname>
2196 user: User Name <user@hostname>
2197 date: Mon Jan 12 13:46:40 1970 +0000
2197 date: Mon Jan 12 13:46:40 1970 +0000
2198 summary: line 1
2198 summary: line 1
2199
2199
2200 changeset: 1:b608e9d1a3f0
2200 changeset: 1:b608e9d1a3f0
2201 bisect: good
2201 bisect: good
2202 user: A. N. Other <other@place>
2202 user: A. N. Other <other@place>
2203 date: Tue Jan 13 17:33:20 1970 +0000
2203 date: Tue Jan 13 17:33:20 1970 +0000
2204 summary: other 1
2204 summary: other 1
2205
2205
2206 changeset: 2:97054abb4ab8
2206 changeset: 2:97054abb4ab8
2207 bisect: untested
2207 bisect: untested
2208 user: other@place
2208 user: other@place
2209 date: Wed Jan 14 21:20:00 1970 +0000
2209 date: Wed Jan 14 21:20:00 1970 +0000
2210 summary: no person
2210 summary: no person
2211
2211
2212 changeset: 3:10e46f2dcbf4
2212 changeset: 3:10e46f2dcbf4
2213 bisect: bad
2213 bisect: bad
2214 user: person
2214 user: person
2215 date: Fri Jan 16 01:06:40 1970 +0000
2215 date: Fri Jan 16 01:06:40 1970 +0000
2216 summary: no user, no domain
2216 summary: no user, no domain
2217
2217
2218 changeset: 4:bbe44766e73d
2218 changeset: 4:bbe44766e73d
2219 bisect: bad (implicit)
2219 bisect: bad (implicit)
2220 branch: foo
2220 branch: foo
2221 user: person
2221 user: person
2222 date: Sat Jan 17 04:53:20 1970 +0000
2222 date: Sat Jan 17 04:53:20 1970 +0000
2223 summary: new branch
2223 summary: new branch
2224
2224
2225 $ hg log --debug -T bisect -r 0:4
2225 $ hg log --debug -T bisect -r 0:4
2226 changeset: 0:1e4e1b8f71e05681d422154f5421e385fec3454f
2226 changeset: 0:1e4e1b8f71e05681d422154f5421e385fec3454f
2227 bisect: good (implicit)
2227 bisect: good (implicit)
2228 phase: public
2228 phase: public
2229 parent: -1:0000000000000000000000000000000000000000
2229 parent: -1:0000000000000000000000000000000000000000
2230 parent: -1:0000000000000000000000000000000000000000
2230 parent: -1:0000000000000000000000000000000000000000
2231 manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
2231 manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
2232 user: User Name <user@hostname>
2232 user: User Name <user@hostname>
2233 date: Mon Jan 12 13:46:40 1970 +0000
2233 date: Mon Jan 12 13:46:40 1970 +0000
2234 files+: a
2234 files+: a
2235 extra: branch=default
2235 extra: branch=default
2236 description:
2236 description:
2237 line 1
2237 line 1
2238 line 2
2238 line 2
2239
2239
2240
2240
2241 changeset: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2241 changeset: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2242 bisect: good
2242 bisect: good
2243 phase: public
2243 phase: public
2244 parent: 0:1e4e1b8f71e05681d422154f5421e385fec3454f
2244 parent: 0:1e4e1b8f71e05681d422154f5421e385fec3454f
2245 parent: -1:0000000000000000000000000000000000000000
2245 parent: -1:0000000000000000000000000000000000000000
2246 manifest: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
2246 manifest: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
2247 user: A. N. Other <other@place>
2247 user: A. N. Other <other@place>
2248 date: Tue Jan 13 17:33:20 1970 +0000
2248 date: Tue Jan 13 17:33:20 1970 +0000
2249 files+: b
2249 files+: b
2250 extra: branch=default
2250 extra: branch=default
2251 description:
2251 description:
2252 other 1
2252 other 1
2253 other 2
2253 other 2
2254
2254
2255 other 3
2255 other 3
2256
2256
2257
2257
2258 changeset: 2:97054abb4ab824450e9164180baf491ae0078465
2258 changeset: 2:97054abb4ab824450e9164180baf491ae0078465
2259 bisect: untested
2259 bisect: untested
2260 phase: public
2260 phase: public
2261 parent: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2261 parent: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965
2262 parent: -1:0000000000000000000000000000000000000000
2262 parent: -1:0000000000000000000000000000000000000000
2263 manifest: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
2263 manifest: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
2264 user: other@place
2264 user: other@place
2265 date: Wed Jan 14 21:20:00 1970 +0000
2265 date: Wed Jan 14 21:20:00 1970 +0000
2266 files+: c
2266 files+: c
2267 extra: branch=default
2267 extra: branch=default
2268 description:
2268 description:
2269 no person
2269 no person
2270
2270
2271
2271
2272 changeset: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47
2272 changeset: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47
2273 bisect: bad
2273 bisect: bad
2274 phase: public
2274 phase: public
2275 parent: 2:97054abb4ab824450e9164180baf491ae0078465
2275 parent: 2:97054abb4ab824450e9164180baf491ae0078465
2276 parent: -1:0000000000000000000000000000000000000000
2276 parent: -1:0000000000000000000000000000000000000000
2277 manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
2277 manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
2278 user: person
2278 user: person
2279 date: Fri Jan 16 01:06:40 1970 +0000
2279 date: Fri Jan 16 01:06:40 1970 +0000
2280 files: c
2280 files: c
2281 extra: branch=default
2281 extra: branch=default
2282 description:
2282 description:
2283 no user, no domain
2283 no user, no domain
2284
2284
2285
2285
2286 changeset: 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
2286 changeset: 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
2287 bisect: bad (implicit)
2287 bisect: bad (implicit)
2288 branch: foo
2288 branch: foo
2289 phase: draft
2289 phase: draft
2290 parent: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47
2290 parent: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47
2291 parent: -1:0000000000000000000000000000000000000000
2291 parent: -1:0000000000000000000000000000000000000000
2292 manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
2292 manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
2293 user: person
2293 user: person
2294 date: Sat Jan 17 04:53:20 1970 +0000
2294 date: Sat Jan 17 04:53:20 1970 +0000
2295 extra: branch=foo
2295 extra: branch=foo
2296 description:
2296 description:
2297 new branch
2297 new branch
2298
2298
2299
2299
2300 $ hg log -v -T bisect -r 0:4
2300 $ hg log -v -T bisect -r 0:4
2301 changeset: 0:1e4e1b8f71e0
2301 changeset: 0:1e4e1b8f71e0
2302 bisect: good (implicit)
2302 bisect: good (implicit)
2303 user: User Name <user@hostname>
2303 user: User Name <user@hostname>
2304 date: Mon Jan 12 13:46:40 1970 +0000
2304 date: Mon Jan 12 13:46:40 1970 +0000
2305 files: a
2305 files: a
2306 description:
2306 description:
2307 line 1
2307 line 1
2308 line 2
2308 line 2
2309
2309
2310
2310
2311 changeset: 1:b608e9d1a3f0
2311 changeset: 1:b608e9d1a3f0
2312 bisect: good
2312 bisect: good
2313 user: A. N. Other <other@place>
2313 user: A. N. Other <other@place>
2314 date: Tue Jan 13 17:33:20 1970 +0000
2314 date: Tue Jan 13 17:33:20 1970 +0000
2315 files: b
2315 files: b
2316 description:
2316 description:
2317 other 1
2317 other 1
2318 other 2
2318 other 2
2319
2319
2320 other 3
2320 other 3
2321
2321
2322
2322
2323 changeset: 2:97054abb4ab8
2323 changeset: 2:97054abb4ab8
2324 bisect: untested
2324 bisect: untested
2325 user: other@place
2325 user: other@place
2326 date: Wed Jan 14 21:20:00 1970 +0000
2326 date: Wed Jan 14 21:20:00 1970 +0000
2327 files: c
2327 files: c
2328 description:
2328 description:
2329 no person
2329 no person
2330
2330
2331
2331
2332 changeset: 3:10e46f2dcbf4
2332 changeset: 3:10e46f2dcbf4
2333 bisect: bad
2333 bisect: bad
2334 user: person
2334 user: person
2335 date: Fri Jan 16 01:06:40 1970 +0000
2335 date: Fri Jan 16 01:06:40 1970 +0000
2336 files: c
2336 files: c
2337 description:
2337 description:
2338 no user, no domain
2338 no user, no domain
2339
2339
2340
2340
2341 changeset: 4:bbe44766e73d
2341 changeset: 4:bbe44766e73d
2342 bisect: bad (implicit)
2342 bisect: bad (implicit)
2343 branch: foo
2343 branch: foo
2344 user: person
2344 user: person
2345 date: Sat Jan 17 04:53:20 1970 +0000
2345 date: Sat Jan 17 04:53:20 1970 +0000
2346 description:
2346 description:
2347 new branch
2347 new branch
2348
2348
2349
2349
2350 $ hg --color=debug log -T bisect -r 0:4
2350 $ hg --color=debug log -T bisect -r 0:4
2351 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e0]
2351 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e0]
2352 [log.bisect bisect.good|bisect: good (implicit)]
2352 [log.bisect bisect.good|bisect: good (implicit)]
2353 [log.user|user: User Name <user@hostname>]
2353 [log.user|user: User Name <user@hostname>]
2354 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2354 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2355 [log.summary|summary: line 1]
2355 [log.summary|summary: line 1]
2356
2356
2357 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0]
2357 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0]
2358 [log.bisect bisect.good|bisect: good]
2358 [log.bisect bisect.good|bisect: good]
2359 [log.user|user: A. N. Other <other@place>]
2359 [log.user|user: A. N. Other <other@place>]
2360 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2360 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2361 [log.summary|summary: other 1]
2361 [log.summary|summary: other 1]
2362
2362
2363 [log.changeset changeset.public|changeset: 2:97054abb4ab8]
2363 [log.changeset changeset.public|changeset: 2:97054abb4ab8]
2364 [log.bisect bisect.untested|bisect: untested]
2364 [log.bisect bisect.untested|bisect: untested]
2365 [log.user|user: other@place]
2365 [log.user|user: other@place]
2366 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2366 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2367 [log.summary|summary: no person]
2367 [log.summary|summary: no person]
2368
2368
2369 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4]
2369 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4]
2370 [log.bisect bisect.bad|bisect: bad]
2370 [log.bisect bisect.bad|bisect: bad]
2371 [log.user|user: person]
2371 [log.user|user: person]
2372 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2372 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2373 [log.summary|summary: no user, no domain]
2373 [log.summary|summary: no user, no domain]
2374
2374
2375 [log.changeset changeset.draft|changeset: 4:bbe44766e73d]
2375 [log.changeset changeset.draft|changeset: 4:bbe44766e73d]
2376 [log.bisect bisect.bad|bisect: bad (implicit)]
2376 [log.bisect bisect.bad|bisect: bad (implicit)]
2377 [log.branch|branch: foo]
2377 [log.branch|branch: foo]
2378 [log.user|user: person]
2378 [log.user|user: person]
2379 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2379 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2380 [log.summary|summary: new branch]
2380 [log.summary|summary: new branch]
2381
2381
2382 $ hg --color=debug log --debug -T bisect -r 0:4
2382 $ hg --color=debug log --debug -T bisect -r 0:4
2383 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e05681d422154f5421e385fec3454f]
2383 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e05681d422154f5421e385fec3454f]
2384 [log.bisect bisect.good|bisect: good (implicit)]
2384 [log.bisect bisect.good|bisect: good (implicit)]
2385 [log.phase|phase: public]
2385 [log.phase|phase: public]
2386 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2386 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2387 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2387 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2388 [ui.debug log.manifest|manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0]
2388 [ui.debug log.manifest|manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0]
2389 [log.user|user: User Name <user@hostname>]
2389 [log.user|user: User Name <user@hostname>]
2390 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2390 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2391 [ui.debug log.files|files+: a]
2391 [ui.debug log.files|files+: a]
2392 [ui.debug log.extra|extra: branch=default]
2392 [ui.debug log.extra|extra: branch=default]
2393 [ui.note log.description|description:]
2393 [ui.note log.description|description:]
2394 [ui.note log.description|line 1
2394 [ui.note log.description|line 1
2395 line 2]
2395 line 2]
2396
2396
2397
2397
2398 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965]
2398 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965]
2399 [log.bisect bisect.good|bisect: good]
2399 [log.bisect bisect.good|bisect: good]
2400 [log.phase|phase: public]
2400 [log.phase|phase: public]
2401 [log.parent changeset.public|parent: 0:1e4e1b8f71e05681d422154f5421e385fec3454f]
2401 [log.parent changeset.public|parent: 0:1e4e1b8f71e05681d422154f5421e385fec3454f]
2402 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2402 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2403 [ui.debug log.manifest|manifest: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55]
2403 [ui.debug log.manifest|manifest: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55]
2404 [log.user|user: A. N. Other <other@place>]
2404 [log.user|user: A. N. Other <other@place>]
2405 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2405 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2406 [ui.debug log.files|files+: b]
2406 [ui.debug log.files|files+: b]
2407 [ui.debug log.extra|extra: branch=default]
2407 [ui.debug log.extra|extra: branch=default]
2408 [ui.note log.description|description:]
2408 [ui.note log.description|description:]
2409 [ui.note log.description|other 1
2409 [ui.note log.description|other 1
2410 other 2
2410 other 2
2411
2411
2412 other 3]
2412 other 3]
2413
2413
2414
2414
2415 [log.changeset changeset.public|changeset: 2:97054abb4ab824450e9164180baf491ae0078465]
2415 [log.changeset changeset.public|changeset: 2:97054abb4ab824450e9164180baf491ae0078465]
2416 [log.bisect bisect.untested|bisect: untested]
2416 [log.bisect bisect.untested|bisect: untested]
2417 [log.phase|phase: public]
2417 [log.phase|phase: public]
2418 [log.parent changeset.public|parent: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965]
2418 [log.parent changeset.public|parent: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965]
2419 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2419 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2420 [ui.debug log.manifest|manifest: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1]
2420 [ui.debug log.manifest|manifest: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1]
2421 [log.user|user: other@place]
2421 [log.user|user: other@place]
2422 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2422 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2423 [ui.debug log.files|files+: c]
2423 [ui.debug log.files|files+: c]
2424 [ui.debug log.extra|extra: branch=default]
2424 [ui.debug log.extra|extra: branch=default]
2425 [ui.note log.description|description:]
2425 [ui.note log.description|description:]
2426 [ui.note log.description|no person]
2426 [ui.note log.description|no person]
2427
2427
2428
2428
2429 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47]
2429 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47]
2430 [log.bisect bisect.bad|bisect: bad]
2430 [log.bisect bisect.bad|bisect: bad]
2431 [log.phase|phase: public]
2431 [log.phase|phase: public]
2432 [log.parent changeset.public|parent: 2:97054abb4ab824450e9164180baf491ae0078465]
2432 [log.parent changeset.public|parent: 2:97054abb4ab824450e9164180baf491ae0078465]
2433 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2433 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2434 [ui.debug log.manifest|manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc]
2434 [ui.debug log.manifest|manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc]
2435 [log.user|user: person]
2435 [log.user|user: person]
2436 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2436 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2437 [ui.debug log.files|files: c]
2437 [ui.debug log.files|files: c]
2438 [ui.debug log.extra|extra: branch=default]
2438 [ui.debug log.extra|extra: branch=default]
2439 [ui.note log.description|description:]
2439 [ui.note log.description|description:]
2440 [ui.note log.description|no user, no domain]
2440 [ui.note log.description|no user, no domain]
2441
2441
2442
2442
2443 [log.changeset changeset.draft|changeset: 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74]
2443 [log.changeset changeset.draft|changeset: 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74]
2444 [log.bisect bisect.bad|bisect: bad (implicit)]
2444 [log.bisect bisect.bad|bisect: bad (implicit)]
2445 [log.branch|branch: foo]
2445 [log.branch|branch: foo]
2446 [log.phase|phase: draft]
2446 [log.phase|phase: draft]
2447 [log.parent changeset.public|parent: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47]
2447 [log.parent changeset.public|parent: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47]
2448 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2448 [log.parent changeset.public|parent: -1:0000000000000000000000000000000000000000]
2449 [ui.debug log.manifest|manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc]
2449 [ui.debug log.manifest|manifest: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc]
2450 [log.user|user: person]
2450 [log.user|user: person]
2451 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2451 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2452 [ui.debug log.extra|extra: branch=foo]
2452 [ui.debug log.extra|extra: branch=foo]
2453 [ui.note log.description|description:]
2453 [ui.note log.description|description:]
2454 [ui.note log.description|new branch]
2454 [ui.note log.description|new branch]
2455
2455
2456
2456
2457 $ hg --color=debug log -v -T bisect -r 0:4
2457 $ hg --color=debug log -v -T bisect -r 0:4
2458 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e0]
2458 [log.changeset changeset.public|changeset: 0:1e4e1b8f71e0]
2459 [log.bisect bisect.good|bisect: good (implicit)]
2459 [log.bisect bisect.good|bisect: good (implicit)]
2460 [log.user|user: User Name <user@hostname>]
2460 [log.user|user: User Name <user@hostname>]
2461 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2461 [log.date|date: Mon Jan 12 13:46:40 1970 +0000]
2462 [ui.note log.files|files: a]
2462 [ui.note log.files|files: a]
2463 [ui.note log.description|description:]
2463 [ui.note log.description|description:]
2464 [ui.note log.description|line 1
2464 [ui.note log.description|line 1
2465 line 2]
2465 line 2]
2466
2466
2467
2467
2468 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0]
2468 [log.changeset changeset.public|changeset: 1:b608e9d1a3f0]
2469 [log.bisect bisect.good|bisect: good]
2469 [log.bisect bisect.good|bisect: good]
2470 [log.user|user: A. N. Other <other@place>]
2470 [log.user|user: A. N. Other <other@place>]
2471 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2471 [log.date|date: Tue Jan 13 17:33:20 1970 +0000]
2472 [ui.note log.files|files: b]
2472 [ui.note log.files|files: b]
2473 [ui.note log.description|description:]
2473 [ui.note log.description|description:]
2474 [ui.note log.description|other 1
2474 [ui.note log.description|other 1
2475 other 2
2475 other 2
2476
2476
2477 other 3]
2477 other 3]
2478
2478
2479
2479
2480 [log.changeset changeset.public|changeset: 2:97054abb4ab8]
2480 [log.changeset changeset.public|changeset: 2:97054abb4ab8]
2481 [log.bisect bisect.untested|bisect: untested]
2481 [log.bisect bisect.untested|bisect: untested]
2482 [log.user|user: other@place]
2482 [log.user|user: other@place]
2483 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2483 [log.date|date: Wed Jan 14 21:20:00 1970 +0000]
2484 [ui.note log.files|files: c]
2484 [ui.note log.files|files: c]
2485 [ui.note log.description|description:]
2485 [ui.note log.description|description:]
2486 [ui.note log.description|no person]
2486 [ui.note log.description|no person]
2487
2487
2488
2488
2489 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4]
2489 [log.changeset changeset.public|changeset: 3:10e46f2dcbf4]
2490 [log.bisect bisect.bad|bisect: bad]
2490 [log.bisect bisect.bad|bisect: bad]
2491 [log.user|user: person]
2491 [log.user|user: person]
2492 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2492 [log.date|date: Fri Jan 16 01:06:40 1970 +0000]
2493 [ui.note log.files|files: c]
2493 [ui.note log.files|files: c]
2494 [ui.note log.description|description:]
2494 [ui.note log.description|description:]
2495 [ui.note log.description|no user, no domain]
2495 [ui.note log.description|no user, no domain]
2496
2496
2497
2497
2498 [log.changeset changeset.draft|changeset: 4:bbe44766e73d]
2498 [log.changeset changeset.draft|changeset: 4:bbe44766e73d]
2499 [log.bisect bisect.bad|bisect: bad (implicit)]
2499 [log.bisect bisect.bad|bisect: bad (implicit)]
2500 [log.branch|branch: foo]
2500 [log.branch|branch: foo]
2501 [log.user|user: person]
2501 [log.user|user: person]
2502 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2502 [log.date|date: Sat Jan 17 04:53:20 1970 +0000]
2503 [ui.note log.description|description:]
2503 [ui.note log.description|description:]
2504 [ui.note log.description|new branch]
2504 [ui.note log.description|new branch]
2505
2505
2506
2506
2507 $ hg bisect --reset
2507 $ hg bisect --reset
2508
2508
2509 Error on syntax:
2509 Error on syntax:
2510
2510
2511 $ echo 'x = "f' >> t
2511 $ echo 'x = "f' >> t
2512 $ hg log
2512 $ hg log
2513 hg: parse error at t:3: unmatched quotes
2513 hg: parse error at t:3: unmatched quotes
2514 [255]
2514 [255]
2515
2515
2516 $ hg log -T '{date'
2516 $ hg log -T '{date'
2517 hg: parse error at 1: unterminated template expansion
2517 hg: parse error at 1: unterminated template expansion
2518 [255]
2518 [255]
2519
2519
2520 Behind the scenes, this will throw TypeError
2520 Behind the scenes, this will throw TypeError
2521
2521
2522 $ hg log -l 3 --template '{date|obfuscate}\n'
2522 $ hg log -l 3 --template '{date|obfuscate}\n'
2523 abort: template filter 'obfuscate' is not compatible with keyword 'date'
2523 abort: template filter 'obfuscate' is not compatible with keyword 'date'
2524 [255]
2524 [255]
2525
2525
2526 Behind the scenes, this will throw a ValueError
2526 Behind the scenes, this will throw a ValueError
2527
2527
2528 $ hg log -l 3 --template 'line: {desc|shortdate}\n'
2528 $ hg log -l 3 --template 'line: {desc|shortdate}\n'
2529 abort: template filter 'shortdate' is not compatible with keyword 'desc'
2529 abort: template filter 'shortdate' is not compatible with keyword 'desc'
2530 [255]
2530 [255]
2531
2531
2532 Behind the scenes, this will throw AttributeError
2532 Behind the scenes, this will throw AttributeError
2533
2533
2534 $ hg log -l 3 --template 'line: {date|escape}\n'
2534 $ hg log -l 3 --template 'line: {date|escape}\n'
2535 abort: template filter 'escape' is not compatible with keyword 'date'
2535 abort: template filter 'escape' is not compatible with keyword 'date'
2536 [255]
2536 [255]
2537
2537
2538 $ hg log -l 3 --template 'line: {extras|localdate}\n'
2538 $ hg log -l 3 --template 'line: {extras|localdate}\n'
2539 hg: parse error: localdate expects a date information
2539 hg: parse error: localdate expects a date information
2540 [255]
2540 [255]
2541
2541
2542 Behind the scenes, this will throw ValueError
2542 Behind the scenes, this will throw ValueError
2543
2543
2544 $ hg tip --template '{author|email|date}\n'
2544 $ hg tip --template '{author|email|date}\n'
2545 hg: parse error: date expects a date information
2545 hg: parse error: date expects a date information
2546 [255]
2546 [255]
2547
2547
2548 Error in nested template:
2548 Error in nested template:
2549
2549
2550 $ hg log -T '{"date'
2550 $ hg log -T '{"date'
2551 hg: parse error at 2: unterminated string
2551 hg: parse error at 2: unterminated string
2552 [255]
2552 [255]
2553
2553
2554 $ hg log -T '{"foo{date|=}"}'
2554 $ hg log -T '{"foo{date|=}"}'
2555 hg: parse error at 11: syntax error
2555 hg: parse error at 11: syntax error
2556 [255]
2556 [255]
2557
2557
2558 Thrown an error if a template function doesn't exist
2558 Thrown an error if a template function doesn't exist
2559
2559
2560 $ hg tip --template '{foo()}\n'
2560 $ hg tip --template '{foo()}\n'
2561 hg: parse error: unknown function 'foo'
2561 hg: parse error: unknown function 'foo'
2562 [255]
2562 [255]
2563
2563
2564 Pass generator object created by template function to filter
2564 Pass generator object created by template function to filter
2565
2565
2566 $ hg log -l 1 --template '{if(author, author)|user}\n'
2566 $ hg log -l 1 --template '{if(author, author)|user}\n'
2567 test
2567 test
2568
2568
2569 Test diff function:
2569 Test diff function:
2570
2570
2571 $ hg diff -c 8
2571 $ hg diff -c 8
2572 diff -r 29114dbae42b -r 95c24699272e fourth
2572 diff -r 29114dbae42b -r 95c24699272e fourth
2573 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2573 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2574 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2574 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2575 @@ -0,0 +1,1 @@
2575 @@ -0,0 +1,1 @@
2576 +second
2576 +second
2577 diff -r 29114dbae42b -r 95c24699272e second
2577 diff -r 29114dbae42b -r 95c24699272e second
2578 --- a/second Mon Jan 12 13:46:40 1970 +0000
2578 --- a/second Mon Jan 12 13:46:40 1970 +0000
2579 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2579 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2580 @@ -1,1 +0,0 @@
2580 @@ -1,1 +0,0 @@
2581 -second
2581 -second
2582 diff -r 29114dbae42b -r 95c24699272e third
2582 diff -r 29114dbae42b -r 95c24699272e third
2583 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2583 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2584 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2584 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2585 @@ -0,0 +1,1 @@
2585 @@ -0,0 +1,1 @@
2586 +third
2586 +third
2587
2587
2588 $ hg log -r 8 -T "{diff()}"
2588 $ hg log -r 8 -T "{diff()}"
2589 diff -r 29114dbae42b -r 95c24699272e fourth
2589 diff -r 29114dbae42b -r 95c24699272e fourth
2590 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2590 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2591 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2591 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2592 @@ -0,0 +1,1 @@
2592 @@ -0,0 +1,1 @@
2593 +second
2593 +second
2594 diff -r 29114dbae42b -r 95c24699272e second
2594 diff -r 29114dbae42b -r 95c24699272e second
2595 --- a/second Mon Jan 12 13:46:40 1970 +0000
2595 --- a/second Mon Jan 12 13:46:40 1970 +0000
2596 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2596 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2597 @@ -1,1 +0,0 @@
2597 @@ -1,1 +0,0 @@
2598 -second
2598 -second
2599 diff -r 29114dbae42b -r 95c24699272e third
2599 diff -r 29114dbae42b -r 95c24699272e third
2600 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2600 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2601 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2601 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2602 @@ -0,0 +1,1 @@
2602 @@ -0,0 +1,1 @@
2603 +third
2603 +third
2604
2604
2605 $ hg log -r 8 -T "{diff('glob:f*')}"
2605 $ hg log -r 8 -T "{diff('glob:f*')}"
2606 diff -r 29114dbae42b -r 95c24699272e fourth
2606 diff -r 29114dbae42b -r 95c24699272e fourth
2607 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2607 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2608 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2608 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2609 @@ -0,0 +1,1 @@
2609 @@ -0,0 +1,1 @@
2610 +second
2610 +second
2611
2611
2612 $ hg log -r 8 -T "{diff('', 'glob:f*')}"
2612 $ hg log -r 8 -T "{diff('', 'glob:f*')}"
2613 diff -r 29114dbae42b -r 95c24699272e second
2613 diff -r 29114dbae42b -r 95c24699272e second
2614 --- a/second Mon Jan 12 13:46:40 1970 +0000
2614 --- a/second Mon Jan 12 13:46:40 1970 +0000
2615 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2615 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2616 @@ -1,1 +0,0 @@
2616 @@ -1,1 +0,0 @@
2617 -second
2617 -second
2618 diff -r 29114dbae42b -r 95c24699272e third
2618 diff -r 29114dbae42b -r 95c24699272e third
2619 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2619 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2620 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2620 +++ b/third Wed Jan 01 10:01:00 2020 +0000
2621 @@ -0,0 +1,1 @@
2621 @@ -0,0 +1,1 @@
2622 +third
2622 +third
2623
2623
2624 $ hg log -r 8 -T "{diff('FOURTH'|lower)}"
2624 $ hg log -r 8 -T "{diff('FOURTH'|lower)}"
2625 diff -r 29114dbae42b -r 95c24699272e fourth
2625 diff -r 29114dbae42b -r 95c24699272e fourth
2626 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2626 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2627 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2627 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
2628 @@ -0,0 +1,1 @@
2628 @@ -0,0 +1,1 @@
2629 +second
2629 +second
2630
2630
2631 $ cd ..
2631 $ cd ..
2632
2632
2633
2633
2634 latesttag:
2634 latesttag:
2635
2635
2636 $ hg init latesttag
2636 $ hg init latesttag
2637 $ cd latesttag
2637 $ cd latesttag
2638
2638
2639 $ echo a > file
2639 $ echo a > file
2640 $ hg ci -Am a -d '0 0'
2640 $ hg ci -Am a -d '0 0'
2641 adding file
2641 adding file
2642
2642
2643 $ echo b >> file
2643 $ echo b >> file
2644 $ hg ci -m b -d '1 0'
2644 $ hg ci -m b -d '1 0'
2645
2645
2646 $ echo c >> head1
2646 $ echo c >> head1
2647 $ hg ci -Am h1c -d '2 0'
2647 $ hg ci -Am h1c -d '2 0'
2648 adding head1
2648 adding head1
2649
2649
2650 $ hg update -q 1
2650 $ hg update -q 1
2651 $ echo d >> head2
2651 $ echo d >> head2
2652 $ hg ci -Am h2d -d '3 0'
2652 $ hg ci -Am h2d -d '3 0'
2653 adding head2
2653 adding head2
2654 created new head
2654 created new head
2655
2655
2656 $ echo e >> head2
2656 $ echo e >> head2
2657 $ hg ci -m h2e -d '4 0'
2657 $ hg ci -m h2e -d '4 0'
2658
2658
2659 $ hg merge -q
2659 $ hg merge -q
2660 $ hg ci -m merge -d '5 -3600'
2660 $ hg ci -m merge -d '5 -3600'
2661
2661
2662 No tag set:
2662 No tag set:
2663
2663
2664 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2664 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2665 5: null+5
2665 5: null+5
2666 4: null+4
2666 4: null+4
2667 3: null+3
2667 3: null+3
2668 2: null+3
2668 2: null+3
2669 1: null+2
2669 1: null+2
2670 0: null+1
2670 0: null+1
2671
2671
2672 One common tag: longest path wins:
2672 One common tag: longest path wins:
2673
2673
2674 $ hg tag -r 1 -m t1 -d '6 0' t1
2674 $ hg tag -r 1 -m t1 -d '6 0' t1
2675 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2675 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2676 6: t1+4
2676 6: t1+4
2677 5: t1+3
2677 5: t1+3
2678 4: t1+2
2678 4: t1+2
2679 3: t1+1
2679 3: t1+1
2680 2: t1+1
2680 2: t1+1
2681 1: t1+0
2681 1: t1+0
2682 0: null+1
2682 0: null+1
2683
2683
2684 One ancestor tag: more recent wins:
2684 One ancestor tag: more recent wins:
2685
2685
2686 $ hg tag -r 2 -m t2 -d '7 0' t2
2686 $ hg tag -r 2 -m t2 -d '7 0' t2
2687 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2687 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2688 7: t2+3
2688 7: t2+3
2689 6: t2+2
2689 6: t2+2
2690 5: t2+1
2690 5: t2+1
2691 4: t1+2
2691 4: t1+2
2692 3: t1+1
2692 3: t1+1
2693 2: t2+0
2693 2: t2+0
2694 1: t1+0
2694 1: t1+0
2695 0: null+1
2695 0: null+1
2696
2696
2697 Two branch tags: more recent wins:
2697 Two branch tags: more recent wins:
2698
2698
2699 $ hg tag -r 3 -m t3 -d '8 0' t3
2699 $ hg tag -r 3 -m t3 -d '8 0' t3
2700 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2700 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2701 8: t3+5
2701 8: t3+5
2702 7: t3+4
2702 7: t3+4
2703 6: t3+3
2703 6: t3+3
2704 5: t3+2
2704 5: t3+2
2705 4: t3+1
2705 4: t3+1
2706 3: t3+0
2706 3: t3+0
2707 2: t2+0
2707 2: t2+0
2708 1: t1+0
2708 1: t1+0
2709 0: null+1
2709 0: null+1
2710
2710
2711 Merged tag overrides:
2711 Merged tag overrides:
2712
2712
2713 $ hg tag -r 5 -m t5 -d '9 0' t5
2713 $ hg tag -r 5 -m t5 -d '9 0' t5
2714 $ hg tag -r 3 -m at3 -d '10 0' at3
2714 $ hg tag -r 3 -m at3 -d '10 0' at3
2715 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2715 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
2716 10: t5+5
2716 10: t5+5
2717 9: t5+4
2717 9: t5+4
2718 8: t5+3
2718 8: t5+3
2719 7: t5+2
2719 7: t5+2
2720 6: t5+1
2720 6: t5+1
2721 5: t5+0
2721 5: t5+0
2722 4: at3:t3+1
2722 4: at3:t3+1
2723 3: at3:t3+0
2723 3: at3:t3+0
2724 2: t2+0
2724 2: t2+0
2725 1: t1+0
2725 1: t1+0
2726 0: null+1
2726 0: null+1
2727
2727
2728 $ hg log --template "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
2728 $ hg log --template "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
2729 10: t5+5,5
2729 10: t5+5,5
2730 9: t5+4,4
2730 9: t5+4,4
2731 8: t5+3,3
2731 8: t5+3,3
2732 7: t5+2,2
2732 7: t5+2,2
2733 6: t5+1,1
2733 6: t5+1,1
2734 5: t5+0,0
2734 5: t5+0,0
2735 4: at3+1,1 t3+1,1
2735 4: at3+1,1 t3+1,1
2736 3: at3+0,0 t3+0,0
2736 3: at3+0,0 t3+0,0
2737 2: t2+0,0
2737 2: t2+0,0
2738 1: t1+0,0
2738 1: t1+0,0
2739 0: null+1,1
2739 0: null+1,1
2740
2740
2741 $ hg log --template "{rev}: {latesttag('re:^t[13]$') % '{tag}, C: {changes}, D: {distance}'}\n"
2741 $ hg log --template "{rev}: {latesttag('re:^t[13]$') % '{tag}, C: {changes}, D: {distance}'}\n"
2742 10: t3, C: 8, D: 7
2742 10: t3, C: 8, D: 7
2743 9: t3, C: 7, D: 6
2743 9: t3, C: 7, D: 6
2744 8: t3, C: 6, D: 5
2744 8: t3, C: 6, D: 5
2745 7: t3, C: 5, D: 4
2745 7: t3, C: 5, D: 4
2746 6: t3, C: 4, D: 3
2746 6: t3, C: 4, D: 3
2747 5: t3, C: 3, D: 2
2747 5: t3, C: 3, D: 2
2748 4: t3, C: 1, D: 1
2748 4: t3, C: 1, D: 1
2749 3: t3, C: 0, D: 0
2749 3: t3, C: 0, D: 0
2750 2: t1, C: 1, D: 1
2750 2: t1, C: 1, D: 1
2751 1: t1, C: 0, D: 0
2751 1: t1, C: 0, D: 0
2752 0: null, C: 1, D: 1
2752 0: null, C: 1, D: 1
2753
2753
2754 $ cd ..
2754 $ cd ..
2755
2755
2756
2756
2757 Style path expansion: issue1948 - ui.style option doesn't work on OSX
2757 Style path expansion: issue1948 - ui.style option doesn't work on OSX
2758 if it is a relative path
2758 if it is a relative path
2759
2759
2760 $ mkdir -p home/styles
2760 $ mkdir -p home/styles
2761
2761
2762 $ cat > home/styles/teststyle <<EOF
2762 $ cat > home/styles/teststyle <<EOF
2763 > changeset = 'test {rev}:{node|short}\n'
2763 > changeset = 'test {rev}:{node|short}\n'
2764 > EOF
2764 > EOF
2765
2765
2766 $ HOME=`pwd`/home; export HOME
2766 $ HOME=`pwd`/home; export HOME
2767
2767
2768 $ cat > latesttag/.hg/hgrc <<EOF
2768 $ cat > latesttag/.hg/hgrc <<EOF
2769 > [ui]
2769 > [ui]
2770 > style = ~/styles/teststyle
2770 > style = ~/styles/teststyle
2771 > EOF
2771 > EOF
2772
2772
2773 $ hg -R latesttag tip
2773 $ hg -R latesttag tip
2774 test 10:9b4a630e5f5f
2774 test 10:9b4a630e5f5f
2775
2775
2776 Test recursive showlist template (issue1989):
2776 Test recursive showlist template (issue1989):
2777
2777
2778 $ cat > style1989 <<EOF
2778 $ cat > style1989 <<EOF
2779 > changeset = '{file_mods}{manifest}{extras}'
2779 > changeset = '{file_mods}{manifest}{extras}'
2780 > file_mod = 'M|{author|person}\n'
2780 > file_mod = 'M|{author|person}\n'
2781 > manifest = '{rev},{author}\n'
2781 > manifest = '{rev},{author}\n'
2782 > extra = '{key}: {author}\n'
2782 > extra = '{key}: {author}\n'
2783 > EOF
2783 > EOF
2784
2784
2785 $ hg -R latesttag log -r tip --style=style1989
2785 $ hg -R latesttag log -r tip --style=style1989
2786 M|test
2786 M|test
2787 10,test
2787 10,test
2788 branch: test
2788 branch: test
2789
2789
2790 Test new-style inline templating:
2790 Test new-style inline templating:
2791
2791
2792 $ hg log -R latesttag -r tip --template 'modified files: {file_mods % " {file}\n"}\n'
2792 $ hg log -R latesttag -r tip --template 'modified files: {file_mods % " {file}\n"}\n'
2793 modified files: .hgtags
2793 modified files: .hgtags
2794
2794
2795
2795
2796 $ hg log -R latesttag -r tip -T '{rev % "a"}\n'
2796 $ hg log -R latesttag -r tip -T '{rev % "a"}\n'
2797 hg: parse error: keyword 'rev' is not iterable
2797 hg: parse error: keyword 'rev' is not iterable
2798 [255]
2798 [255]
2799 $ hg log -R latesttag -r tip -T '{get(extras, "unknown") % "a"}\n'
2799 $ hg log -R latesttag -r tip -T '{get(extras, "unknown") % "a"}\n'
2800 hg: parse error: None is not iterable
2800 hg: parse error: None is not iterable
2801 [255]
2801 [255]
2802
2802
2803 Test the sub function of templating for expansion:
2803 Test the sub function of templating for expansion:
2804
2804
2805 $ hg log -R latesttag -r 10 --template '{sub("[0-9]", "x", "{rev}")}\n'
2805 $ hg log -R latesttag -r 10 --template '{sub("[0-9]", "x", "{rev}")}\n'
2806 xx
2806 xx
2807
2807
2808 $ hg log -R latesttag -r 10 -T '{sub("[", "x", rev)}\n'
2808 $ hg log -R latesttag -r 10 -T '{sub("[", "x", rev)}\n'
2809 hg: parse error: sub got an invalid pattern: [
2809 hg: parse error: sub got an invalid pattern: [
2810 [255]
2810 [255]
2811 $ hg log -R latesttag -r 10 -T '{sub("[0-9]", r"\1", rev)}\n'
2811 $ hg log -R latesttag -r 10 -T '{sub("[0-9]", r"\1", rev)}\n'
2812 hg: parse error: sub got an invalid replacement: \1
2812 hg: parse error: sub got an invalid replacement: \1
2813 [255]
2813 [255]
2814
2814
2815 Test the strip function with chars specified:
2815 Test the strip function with chars specified:
2816
2816
2817 $ hg log -R latesttag --template '{desc}\n'
2817 $ hg log -R latesttag --template '{desc}\n'
2818 at3
2818 at3
2819 t5
2819 t5
2820 t3
2820 t3
2821 t2
2821 t2
2822 t1
2822 t1
2823 merge
2823 merge
2824 h2e
2824 h2e
2825 h2d
2825 h2d
2826 h1c
2826 h1c
2827 b
2827 b
2828 a
2828 a
2829
2829
2830 $ hg log -R latesttag --template '{strip(desc, "te")}\n'
2830 $ hg log -R latesttag --template '{strip(desc, "te")}\n'
2831 at3
2831 at3
2832 5
2832 5
2833 3
2833 3
2834 2
2834 2
2835 1
2835 1
2836 merg
2836 merg
2837 h2
2837 h2
2838 h2d
2838 h2d
2839 h1c
2839 h1c
2840 b
2840 b
2841 a
2841 a
2842
2842
2843 Test date format:
2843 Test date format:
2844
2844
2845 $ hg log -R latesttag --template 'date: {date(date, "%y %m %d %S %z")}\n'
2845 $ hg log -R latesttag --template 'date: {date(date, "%y %m %d %S %z")}\n'
2846 date: 70 01 01 10 +0000
2846 date: 70 01 01 10 +0000
2847 date: 70 01 01 09 +0000
2847 date: 70 01 01 09 +0000
2848 date: 70 01 01 08 +0000
2848 date: 70 01 01 08 +0000
2849 date: 70 01 01 07 +0000
2849 date: 70 01 01 07 +0000
2850 date: 70 01 01 06 +0000
2850 date: 70 01 01 06 +0000
2851 date: 70 01 01 05 +0100
2851 date: 70 01 01 05 +0100
2852 date: 70 01 01 04 +0000
2852 date: 70 01 01 04 +0000
2853 date: 70 01 01 03 +0000
2853 date: 70 01 01 03 +0000
2854 date: 70 01 01 02 +0000
2854 date: 70 01 01 02 +0000
2855 date: 70 01 01 01 +0000
2855 date: 70 01 01 01 +0000
2856 date: 70 01 01 00 +0000
2856 date: 70 01 01 00 +0000
2857
2857
2858 Test invalid date:
2858 Test invalid date:
2859
2859
2860 $ hg log -R latesttag -T '{date(rev)}\n'
2860 $ hg log -R latesttag -T '{date(rev)}\n'
2861 hg: parse error: date expects a date information
2861 hg: parse error: date expects a date information
2862 [255]
2862 [255]
2863
2863
2864 Test integer literal:
2864 Test integer literal:
2865
2865
2866 $ hg debugtemplate -v '{(0)}\n'
2866 $ hg debugtemplate -v '{(0)}\n'
2867 (template
2867 (template
2868 (group
2868 (group
2869 ('integer', '0'))
2869 ('integer', '0'))
2870 ('string', '\n'))
2870 ('string', '\n'))
2871 0
2871 0
2872 $ hg debugtemplate -v '{(123)}\n'
2872 $ hg debugtemplate -v '{(123)}\n'
2873 (template
2873 (template
2874 (group
2874 (group
2875 ('integer', '123'))
2875 ('integer', '123'))
2876 ('string', '\n'))
2876 ('string', '\n'))
2877 123
2877 123
2878 $ hg debugtemplate -v '{(-4)}\n'
2878 $ hg debugtemplate -v '{(-4)}\n'
2879 (template
2879 (template
2880 (group
2880 (group
2881 ('integer', '-4'))
2881 ('integer', '-4'))
2882 ('string', '\n'))
2882 ('string', '\n'))
2883 -4
2883 -4
2884 $ hg debugtemplate '{(-)}\n'
2884 $ hg debugtemplate '{(-)}\n'
2885 hg: parse error at 2: integer literal without digits
2885 hg: parse error at 2: integer literal without digits
2886 [255]
2886 [255]
2887 $ hg debugtemplate '{(-a)}\n'
2887 $ hg debugtemplate '{(-a)}\n'
2888 hg: parse error at 2: integer literal without digits
2888 hg: parse error at 2: integer literal without digits
2889 [255]
2889 [255]
2890
2890
2891 top-level integer literal is interpreted as symbol (i.e. variable name):
2891 top-level integer literal is interpreted as symbol (i.e. variable name):
2892
2892
2893 $ hg debugtemplate -D 1=one -v '{1}\n'
2893 $ hg debugtemplate -D 1=one -v '{1}\n'
2894 (template
2894 (template
2895 ('integer', '1')
2895 ('integer', '1')
2896 ('string', '\n'))
2896 ('string', '\n'))
2897 one
2897 one
2898 $ hg debugtemplate -D 1=one -v '{if("t", "{1}")}\n'
2898 $ hg debugtemplate -D 1=one -v '{if("t", "{1}")}\n'
2899 (template
2899 (template
2900 (func
2900 (func
2901 ('symbol', 'if')
2901 ('symbol', 'if')
2902 (list
2902 (list
2903 ('string', 't')
2903 ('string', 't')
2904 (template
2904 (template
2905 ('integer', '1'))))
2905 ('integer', '1'))))
2906 ('string', '\n'))
2906 ('string', '\n'))
2907 one
2907 one
2908 $ hg debugtemplate -D 1=one -v '{1|stringify}\n'
2908 $ hg debugtemplate -D 1=one -v '{1|stringify}\n'
2909 (template
2909 (template
2910 (|
2910 (|
2911 ('integer', '1')
2911 ('integer', '1')
2912 ('symbol', 'stringify'))
2912 ('symbol', 'stringify'))
2913 ('string', '\n'))
2913 ('string', '\n'))
2914 one
2914 one
2915
2915
2916 unless explicit symbol is expected:
2916 unless explicit symbol is expected:
2917
2917
2918 $ hg log -Ra -r0 -T '{desc|1}\n'
2918 $ hg log -Ra -r0 -T '{desc|1}\n'
2919 hg: parse error: expected a symbol, got 'integer'
2919 hg: parse error: expected a symbol, got 'integer'
2920 [255]
2920 [255]
2921 $ hg log -Ra -r0 -T '{1()}\n'
2921 $ hg log -Ra -r0 -T '{1()}\n'
2922 hg: parse error: expected a symbol, got 'integer'
2922 hg: parse error: expected a symbol, got 'integer'
2923 [255]
2923 [255]
2924
2924
2925 Test string literal:
2925 Test string literal:
2926
2926
2927 $ hg debugtemplate -Ra -r0 -v '{"string with no template fragment"}\n'
2927 $ hg debugtemplate -Ra -r0 -v '{"string with no template fragment"}\n'
2928 (template
2928 (template
2929 ('string', 'string with no template fragment')
2929 ('string', 'string with no template fragment')
2930 ('string', '\n'))
2930 ('string', '\n'))
2931 string with no template fragment
2931 string with no template fragment
2932 $ hg debugtemplate -Ra -r0 -v '{"template: {rev}"}\n'
2932 $ hg debugtemplate -Ra -r0 -v '{"template: {rev}"}\n'
2933 (template
2933 (template
2934 (template
2934 (template
2935 ('string', 'template: ')
2935 ('string', 'template: ')
2936 ('symbol', 'rev'))
2936 ('symbol', 'rev'))
2937 ('string', '\n'))
2937 ('string', '\n'))
2938 template: 0
2938 template: 0
2939 $ hg debugtemplate -Ra -r0 -v '{r"rawstring: {rev}"}\n'
2939 $ hg debugtemplate -Ra -r0 -v '{r"rawstring: {rev}"}\n'
2940 (template
2940 (template
2941 ('string', 'rawstring: {rev}')
2941 ('string', 'rawstring: {rev}')
2942 ('string', '\n'))
2942 ('string', '\n'))
2943 rawstring: {rev}
2943 rawstring: {rev}
2944 $ hg debugtemplate -Ra -r0 -v '{files % r"rawstring: {file}"}\n'
2944 $ hg debugtemplate -Ra -r0 -v '{files % r"rawstring: {file}"}\n'
2945 (template
2945 (template
2946 (%
2946 (%
2947 ('symbol', 'files')
2947 ('symbol', 'files')
2948 ('string', 'rawstring: {file}'))
2948 ('string', 'rawstring: {file}'))
2949 ('string', '\n'))
2949 ('string', '\n'))
2950 rawstring: {file}
2950 rawstring: {file}
2951
2951
2952 Test string escaping:
2952 Test string escaping:
2953
2953
2954 $ hg log -R latesttag -r 0 --template '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2954 $ hg log -R latesttag -r 0 --template '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2955 >
2955 >
2956 <>\n<[>
2956 <>\n<[>
2957 <>\n<]>
2957 <>\n<]>
2958 <>\n<
2958 <>\n<
2959
2959
2960 $ hg log -R latesttag -r 0 \
2960 $ hg log -R latesttag -r 0 \
2961 > --config ui.logtemplate='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2961 > --config ui.logtemplate='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2962 >
2962 >
2963 <>\n<[>
2963 <>\n<[>
2964 <>\n<]>
2964 <>\n<]>
2965 <>\n<
2965 <>\n<
2966
2966
2967 $ hg log -R latesttag -r 0 -T esc \
2967 $ hg log -R latesttag -r 0 -T esc \
2968 > --config templates.esc='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2968 > --config templates.esc='>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2969 >
2969 >
2970 <>\n<[>
2970 <>\n<[>
2971 <>\n<]>
2971 <>\n<]>
2972 <>\n<
2972 <>\n<
2973
2973
2974 $ cat <<'EOF' > esctmpl
2974 $ cat <<'EOF' > esctmpl
2975 > changeset = '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2975 > changeset = '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
2976 > EOF
2976 > EOF
2977 $ hg log -R latesttag -r 0 --style ./esctmpl
2977 $ hg log -R latesttag -r 0 --style ./esctmpl
2978 >
2978 >
2979 <>\n<[>
2979 <>\n<[>
2980 <>\n<]>
2980 <>\n<]>
2981 <>\n<
2981 <>\n<
2982
2982
2983 Test string escaping of quotes:
2983 Test string escaping of quotes:
2984
2984
2985 $ hg log -Ra -r0 -T '{"\""}\n'
2985 $ hg log -Ra -r0 -T '{"\""}\n'
2986 "
2986 "
2987 $ hg log -Ra -r0 -T '{"\\\""}\n'
2987 $ hg log -Ra -r0 -T '{"\\\""}\n'
2988 \"
2988 \"
2989 $ hg log -Ra -r0 -T '{r"\""}\n'
2989 $ hg log -Ra -r0 -T '{r"\""}\n'
2990 \"
2990 \"
2991 $ hg log -Ra -r0 -T '{r"\\\""}\n'
2991 $ hg log -Ra -r0 -T '{r"\\\""}\n'
2992 \\\"
2992 \\\"
2993
2993
2994
2994
2995 $ hg log -Ra -r0 -T '{"\""}\n'
2995 $ hg log -Ra -r0 -T '{"\""}\n'
2996 "
2996 "
2997 $ hg log -Ra -r0 -T '{"\\\""}\n'
2997 $ hg log -Ra -r0 -T '{"\\\""}\n'
2998 \"
2998 \"
2999 $ hg log -Ra -r0 -T '{r"\""}\n'
2999 $ hg log -Ra -r0 -T '{r"\""}\n'
3000 \"
3000 \"
3001 $ hg log -Ra -r0 -T '{r"\\\""}\n'
3001 $ hg log -Ra -r0 -T '{r"\\\""}\n'
3002 \\\"
3002 \\\"
3003
3003
3004 Test exception in quoted template. single backslash before quotation mark is
3004 Test exception in quoted template. single backslash before quotation mark is
3005 stripped before parsing:
3005 stripped before parsing:
3006
3006
3007 $ cat <<'EOF' > escquotetmpl
3007 $ cat <<'EOF' > escquotetmpl
3008 > changeset = "\" \\" \\\" \\\\" {files % \"{file}\"}\n"
3008 > changeset = "\" \\" \\\" \\\\" {files % \"{file}\"}\n"
3009 > EOF
3009 > EOF
3010 $ cd latesttag
3010 $ cd latesttag
3011 $ hg log -r 2 --style ../escquotetmpl
3011 $ hg log -r 2 --style ../escquotetmpl
3012 " \" \" \\" head1
3012 " \" \" \\" head1
3013
3013
3014 $ hg log -r 2 -T esc --config templates.esc='"{\"valid\"}\n"'
3014 $ hg log -r 2 -T esc --config templates.esc='"{\"valid\"}\n"'
3015 valid
3015 valid
3016 $ hg log -r 2 -T esc --config templates.esc="'"'{\'"'"'valid\'"'"'}\n'"'"
3016 $ hg log -r 2 -T esc --config templates.esc="'"'{\'"'"'valid\'"'"'}\n'"'"
3017 valid
3017 valid
3018
3018
3019 Test compatibility with 2.9.2-3.4 of escaped quoted strings in nested
3019 Test compatibility with 2.9.2-3.4 of escaped quoted strings in nested
3020 _evalifliteral() templates (issue4733):
3020 _evalifliteral() templates (issue4733):
3021
3021
3022 $ hg log -r 2 -T '{if(rev, "\"{rev}")}\n'
3022 $ hg log -r 2 -T '{if(rev, "\"{rev}")}\n'
3023 "2
3023 "2
3024 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\"{rev}\")}")}\n'
3024 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\"{rev}\")}")}\n'
3025 "2
3025 "2
3026 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\"{rev}\\\")}\")}")}\n'
3026 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\"{rev}\\\")}\")}")}\n'
3027 "2
3027 "2
3028
3028
3029 $ hg log -r 2 -T '{if(rev, "\\\"")}\n'
3029 $ hg log -r 2 -T '{if(rev, "\\\"")}\n'
3030 \"
3030 \"
3031 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\\\\\"\")}")}\n'
3031 $ hg log -r 2 -T '{if(rev, "{if(rev, \"\\\\\\\"\")}")}\n'
3032 \"
3032 \"
3033 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
3033 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, \\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
3034 \"
3034 \"
3035
3035
3036 $ hg log -r 2 -T '{if(rev, r"\\\"")}\n'
3036 $ hg log -r 2 -T '{if(rev, r"\\\"")}\n'
3037 \\\"
3037 \\\"
3038 $ hg log -r 2 -T '{if(rev, "{if(rev, r\"\\\\\\\"\")}")}\n'
3038 $ hg log -r 2 -T '{if(rev, "{if(rev, r\"\\\\\\\"\")}")}\n'
3039 \\\"
3039 \\\"
3040 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, r\\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
3040 $ hg log -r 2 -T '{if(rev, "{if(rev, \"{if(rev, r\\\"\\\\\\\\\\\\\\\"\\\")}\")}")}\n'
3041 \\\"
3041 \\\"
3042
3042
3043 escaped single quotes and errors:
3043 escaped single quotes and errors:
3044
3044
3045 $ hg log -r 2 -T "{if(rev, '{if(rev, \'foo\')}')}"'\n'
3045 $ hg log -r 2 -T "{if(rev, '{if(rev, \'foo\')}')}"'\n'
3046 foo
3046 foo
3047 $ hg log -r 2 -T "{if(rev, '{if(rev, r\'foo\')}')}"'\n'
3047 $ hg log -r 2 -T "{if(rev, '{if(rev, r\'foo\')}')}"'\n'
3048 foo
3048 foo
3049 $ hg log -r 2 -T '{if(rev, "{if(rev, \")}")}\n'
3049 $ hg log -r 2 -T '{if(rev, "{if(rev, \")}")}\n'
3050 hg: parse error at 21: unterminated string
3050 hg: parse error at 21: unterminated string
3051 [255]
3051 [255]
3052 $ hg log -r 2 -T '{if(rev, \"\\"")}\n'
3052 $ hg log -r 2 -T '{if(rev, \"\\"")}\n'
3053 hg: parse error: trailing \ in string
3053 hg: parse error: trailing \ in string
3054 [255]
3054 [255]
3055 $ hg log -r 2 -T '{if(rev, r\"\\"")}\n'
3055 $ hg log -r 2 -T '{if(rev, r\"\\"")}\n'
3056 hg: parse error: trailing \ in string
3056 hg: parse error: trailing \ in string
3057 [255]
3057 [255]
3058
3058
3059 $ cd ..
3059 $ cd ..
3060
3060
3061 Test leading backslashes:
3061 Test leading backslashes:
3062
3062
3063 $ cd latesttag
3063 $ cd latesttag
3064 $ hg log -r 2 -T '\{rev} {files % "\{file}"}\n'
3064 $ hg log -r 2 -T '\{rev} {files % "\{file}"}\n'
3065 {rev} {file}
3065 {rev} {file}
3066 $ hg log -r 2 -T '\\{rev} {files % "\\{file}"}\n'
3066 $ hg log -r 2 -T '\\{rev} {files % "\\{file}"}\n'
3067 \2 \head1
3067 \2 \head1
3068 $ hg log -r 2 -T '\\\{rev} {files % "\\\{file}"}\n'
3068 $ hg log -r 2 -T '\\\{rev} {files % "\\\{file}"}\n'
3069 \{rev} \{file}
3069 \{rev} \{file}
3070 $ cd ..
3070 $ cd ..
3071
3071
3072 Test leading backslashes in "if" expression (issue4714):
3072 Test leading backslashes in "if" expression (issue4714):
3073
3073
3074 $ cd latesttag
3074 $ cd latesttag
3075 $ hg log -r 2 -T '{if("1", "\{rev}")} {if("1", r"\{rev}")}\n'
3075 $ hg log -r 2 -T '{if("1", "\{rev}")} {if("1", r"\{rev}")}\n'
3076 {rev} \{rev}
3076 {rev} \{rev}
3077 $ hg log -r 2 -T '{if("1", "\\{rev}")} {if("1", r"\\{rev}")}\n'
3077 $ hg log -r 2 -T '{if("1", "\\{rev}")} {if("1", r"\\{rev}")}\n'
3078 \2 \\{rev}
3078 \2 \\{rev}
3079 $ hg log -r 2 -T '{if("1", "\\\{rev}")} {if("1", r"\\\{rev}")}\n'
3079 $ hg log -r 2 -T '{if("1", "\\\{rev}")} {if("1", r"\\\{rev}")}\n'
3080 \{rev} \\\{rev}
3080 \{rev} \\\{rev}
3081 $ cd ..
3081 $ cd ..
3082
3082
3083 "string-escape"-ed "\x5c\x786e" becomes r"\x6e" (once) or r"n" (twice)
3083 "string-escape"-ed "\x5c\x786e" becomes r"\x6e" (once) or r"n" (twice)
3084
3084
3085 $ hg log -R a -r 0 --template '{if("1", "\x5c\x786e", "NG")}\n'
3085 $ hg log -R a -r 0 --template '{if("1", "\x5c\x786e", "NG")}\n'
3086 \x6e
3086 \x6e
3087 $ hg log -R a -r 0 --template '{if("1", r"\x5c\x786e", "NG")}\n'
3087 $ hg log -R a -r 0 --template '{if("1", r"\x5c\x786e", "NG")}\n'
3088 \x5c\x786e
3088 \x5c\x786e
3089 $ hg log -R a -r 0 --template '{if("", "NG", "\x5c\x786e")}\n'
3089 $ hg log -R a -r 0 --template '{if("", "NG", "\x5c\x786e")}\n'
3090 \x6e
3090 \x6e
3091 $ hg log -R a -r 0 --template '{if("", "NG", r"\x5c\x786e")}\n'
3091 $ hg log -R a -r 0 --template '{if("", "NG", r"\x5c\x786e")}\n'
3092 \x5c\x786e
3092 \x5c\x786e
3093
3093
3094 $ hg log -R a -r 2 --template '{ifeq("no perso\x6e", desc, "\x5c\x786e", "NG")}\n'
3094 $ hg log -R a -r 2 --template '{ifeq("no perso\x6e", desc, "\x5c\x786e", "NG")}\n'
3095 \x6e
3095 \x6e
3096 $ hg log -R a -r 2 --template '{ifeq(r"no perso\x6e", desc, "NG", r"\x5c\x786e")}\n'
3096 $ hg log -R a -r 2 --template '{ifeq(r"no perso\x6e", desc, "NG", r"\x5c\x786e")}\n'
3097 \x5c\x786e
3097 \x5c\x786e
3098 $ hg log -R a -r 2 --template '{ifeq(desc, "no perso\x6e", "\x5c\x786e", "NG")}\n'
3098 $ hg log -R a -r 2 --template '{ifeq(desc, "no perso\x6e", "\x5c\x786e", "NG")}\n'
3099 \x6e
3099 \x6e
3100 $ hg log -R a -r 2 --template '{ifeq(desc, r"no perso\x6e", "NG", r"\x5c\x786e")}\n'
3100 $ hg log -R a -r 2 --template '{ifeq(desc, r"no perso\x6e", "NG", r"\x5c\x786e")}\n'
3101 \x5c\x786e
3101 \x5c\x786e
3102
3102
3103 $ hg log -R a -r 8 --template '{join(files, "\n")}\n'
3103 $ hg log -R a -r 8 --template '{join(files, "\n")}\n'
3104 fourth
3104 fourth
3105 second
3105 second
3106 third
3106 third
3107 $ hg log -R a -r 8 --template '{join(files, r"\n")}\n'
3107 $ hg log -R a -r 8 --template '{join(files, r"\n")}\n'
3108 fourth\nsecond\nthird
3108 fourth\nsecond\nthird
3109
3109
3110 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", "htm\x6c")}'
3110 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", "htm\x6c")}'
3111 <p>
3111 <p>
3112 1st
3112 1st
3113 </p>
3113 </p>
3114 <p>
3114 <p>
3115 2nd
3115 2nd
3116 </p>
3116 </p>
3117 $ hg log -R a -r 2 --template '{rstdoc(r"1st\n\n2nd", "html")}'
3117 $ hg log -R a -r 2 --template '{rstdoc(r"1st\n\n2nd", "html")}'
3118 <p>
3118 <p>
3119 1st\n\n2nd
3119 1st\n\n2nd
3120 </p>
3120 </p>
3121 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", r"htm\x6c")}'
3121 $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", r"htm\x6c")}'
3122 1st
3122 1st
3123
3123
3124 2nd
3124 2nd
3125
3125
3126 $ hg log -R a -r 2 --template '{strip(desc, "\x6e")}\n'
3126 $ hg log -R a -r 2 --template '{strip(desc, "\x6e")}\n'
3127 o perso
3127 o perso
3128 $ hg log -R a -r 2 --template '{strip(desc, r"\x6e")}\n'
3128 $ hg log -R a -r 2 --template '{strip(desc, r"\x6e")}\n'
3129 no person
3129 no person
3130 $ hg log -R a -r 2 --template '{strip("no perso\x6e", "\x6e")}\n'
3130 $ hg log -R a -r 2 --template '{strip("no perso\x6e", "\x6e")}\n'
3131 o perso
3131 o perso
3132 $ hg log -R a -r 2 --template '{strip(r"no perso\x6e", r"\x6e")}\n'
3132 $ hg log -R a -r 2 --template '{strip(r"no perso\x6e", r"\x6e")}\n'
3133 no perso
3133 no perso
3134
3134
3135 $ hg log -R a -r 2 --template '{sub("\\x6e", "\x2d", desc)}\n'
3135 $ hg log -R a -r 2 --template '{sub("\\x6e", "\x2d", desc)}\n'
3136 -o perso-
3136 -o perso-
3137 $ hg log -R a -r 2 --template '{sub(r"\\x6e", "-", desc)}\n'
3137 $ hg log -R a -r 2 --template '{sub(r"\\x6e", "-", desc)}\n'
3138 no person
3138 no person
3139 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", desc)}\n'
3139 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", desc)}\n'
3140 \x2do perso\x2d
3140 \x2do perso\x2d
3141 $ hg log -R a -r 2 --template '{sub("n", "\x2d", "no perso\x6e")}\n'
3141 $ hg log -R a -r 2 --template '{sub("n", "\x2d", "no perso\x6e")}\n'
3142 -o perso-
3142 -o perso-
3143 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", r"no perso\x6e")}\n'
3143 $ hg log -R a -r 2 --template '{sub("n", r"\x2d", r"no perso\x6e")}\n'
3144 \x2do perso\x6e
3144 \x2do perso\x6e
3145
3145
3146 $ hg log -R a -r 8 --template '{files % "{file}\n"}'
3146 $ hg log -R a -r 8 --template '{files % "{file}\n"}'
3147 fourth
3147 fourth
3148 second
3148 second
3149 third
3149 third
3150
3150
3151 Test string escaping in nested expression:
3151 Test string escaping in nested expression:
3152
3152
3153 $ hg log -R a -r 8 --template '{ifeq(r"\x6e", if("1", "\x5c\x786e"), join(files, "\x5c\x786e"))}\n'
3153 $ hg log -R a -r 8 --template '{ifeq(r"\x6e", if("1", "\x5c\x786e"), join(files, "\x5c\x786e"))}\n'
3154 fourth\x6esecond\x6ethird
3154 fourth\x6esecond\x6ethird
3155 $ hg log -R a -r 8 --template '{ifeq(if("1", r"\x6e"), "\x5c\x786e", join(files, "\x5c\x786e"))}\n'
3155 $ hg log -R a -r 8 --template '{ifeq(if("1", r"\x6e"), "\x5c\x786e", join(files, "\x5c\x786e"))}\n'
3156 fourth\x6esecond\x6ethird
3156 fourth\x6esecond\x6ethird
3157
3157
3158 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", "\x5c\x786e"))}\n'
3158 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", "\x5c\x786e"))}\n'
3159 fourth\x6esecond\x6ethird
3159 fourth\x6esecond\x6ethird
3160 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", r"\x5c\x786e"))}\n'
3160 $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", r"\x5c\x786e"))}\n'
3161 fourth\x5c\x786esecond\x5c\x786ethird
3161 fourth\x5c\x786esecond\x5c\x786ethird
3162
3162
3163 $ hg log -R a -r 3:4 --template '{rev}:{sub(if("1", "\x6e"), ifeq(branch, "foo", r"\x5c\x786e", "\x5c\x786e"), desc)}\n'
3163 $ hg log -R a -r 3:4 --template '{rev}:{sub(if("1", "\x6e"), ifeq(branch, "foo", r"\x5c\x786e", "\x5c\x786e"), desc)}\n'
3164 3:\x6eo user, \x6eo domai\x6e
3164 3:\x6eo user, \x6eo domai\x6e
3165 4:\x5c\x786eew bra\x5c\x786ech
3165 4:\x5c\x786eew bra\x5c\x786ech
3166
3166
3167 Test quotes in nested expression are evaluated just like a $(command)
3167 Test quotes in nested expression are evaluated just like a $(command)
3168 substitution in POSIX shells:
3168 substitution in POSIX shells:
3169
3169
3170 $ hg log -R a -r 8 -T '{"{"{rev}:{node|short}"}"}\n'
3170 $ hg log -R a -r 8 -T '{"{"{rev}:{node|short}"}"}\n'
3171 8:95c24699272e
3171 8:95c24699272e
3172 $ hg log -R a -r 8 -T '{"{"\{{rev}} \"{node|short}\""}"}\n'
3172 $ hg log -R a -r 8 -T '{"{"\{{rev}} \"{node|short}\""}"}\n'
3173 {8} "95c24699272e"
3173 {8} "95c24699272e"
3174
3174
3175 Test recursive evaluation:
3175 Test recursive evaluation:
3176
3176
3177 $ hg init r
3177 $ hg init r
3178 $ cd r
3178 $ cd r
3179 $ echo a > a
3179 $ echo a > a
3180 $ hg ci -Am '{rev}'
3180 $ hg ci -Am '{rev}'
3181 adding a
3181 adding a
3182 $ hg log -r 0 --template '{if(rev, desc)}\n'
3182 $ hg log -r 0 --template '{if(rev, desc)}\n'
3183 {rev}
3183 {rev}
3184 $ hg log -r 0 --template '{if(rev, "{author} {rev}")}\n'
3184 $ hg log -r 0 --template '{if(rev, "{author} {rev}")}\n'
3185 test 0
3185 test 0
3186
3186
3187 $ hg branch -q 'text.{rev}'
3187 $ hg branch -q 'text.{rev}'
3188 $ echo aa >> aa
3188 $ echo aa >> aa
3189 $ hg ci -u '{node|short}' -m 'desc to be wrapped desc to be wrapped'
3189 $ hg ci -u '{node|short}' -m 'desc to be wrapped desc to be wrapped'
3190
3190
3191 $ hg log -l1 --template '{fill(desc, "20", author, branch)}'
3191 $ hg log -l1 --template '{fill(desc, "20", author, branch)}'
3192 {node|short}desc to
3192 {node|short}desc to
3193 text.{rev}be wrapped
3193 text.{rev}be wrapped
3194 text.{rev}desc to be
3194 text.{rev}desc to be
3195 text.{rev}wrapped (no-eol)
3195 text.{rev}wrapped (no-eol)
3196 $ hg log -l1 --template '{fill(desc, "20", "{node|short}:", "text.{rev}:")}'
3196 $ hg log -l1 --template '{fill(desc, "20", "{node|short}:", "text.{rev}:")}'
3197 bcc7ff960b8e:desc to
3197 bcc7ff960b8e:desc to
3198 text.1:be wrapped
3198 text.1:be wrapped
3199 text.1:desc to be
3199 text.1:desc to be
3200 text.1:wrapped (no-eol)
3200 text.1:wrapped (no-eol)
3201 $ hg log -l1 -T '{fill(desc, date, "", "")}\n'
3201 $ hg log -l1 -T '{fill(desc, date, "", "")}\n'
3202 hg: parse error: fill expects an integer width
3202 hg: parse error: fill expects an integer width
3203 [255]
3203 [255]
3204
3204
3205 $ hg log -l 1 --template '{sub(r"[0-9]", "-", author)}'
3205 $ hg log -l 1 --template '{sub(r"[0-9]", "-", author)}'
3206 {node|short} (no-eol)
3206 {node|short} (no-eol)
3207 $ hg log -l 1 --template '{sub(r"[0-9]", "-", "{node|short}")}'
3207 $ hg log -l 1 --template '{sub(r"[0-9]", "-", "{node|short}")}'
3208 bcc-ff---b-e (no-eol)
3208 bcc-ff---b-e (no-eol)
3209
3209
3210 $ cat >> .hg/hgrc <<EOF
3210 $ cat >> .hg/hgrc <<EOF
3211 > [extensions]
3211 > [extensions]
3212 > color=
3212 > color=
3213 > [color]
3213 > [color]
3214 > mode=ansi
3214 > mode=ansi
3215 > text.{rev} = red
3215 > text.{rev} = red
3216 > text.1 = green
3216 > text.1 = green
3217 > EOF
3217 > EOF
3218 $ hg log --color=always -l 1 --template '{label(branch, "text\n")}'
3218 $ hg log --color=always -l 1 --template '{label(branch, "text\n")}'
3219 \x1b[0;31mtext\x1b[0m (esc)
3219 \x1b[0;31mtext\x1b[0m (esc)
3220 $ hg log --color=always -l 1 --template '{label("text.{rev}", "text\n")}'
3220 $ hg log --color=always -l 1 --template '{label("text.{rev}", "text\n")}'
3221 \x1b[0;32mtext\x1b[0m (esc)
3221 \x1b[0;32mtext\x1b[0m (esc)
3222
3222
3223 color effect can be specified without quoting:
3223 color effect can be specified without quoting:
3224
3224
3225 $ hg log --color=always -l 1 --template '{label(red, "text\n")}'
3225 $ hg log --color=always -l 1 --template '{label(red, "text\n")}'
3226 \x1b[0;31mtext\x1b[0m (esc)
3226 \x1b[0;31mtext\x1b[0m (esc)
3227
3227
3228 label should be no-op if color is disabled:
3228 label should be no-op if color is disabled:
3229
3229
3230 $ hg log --color=never -l 1 --template '{label(red, "text\n")}'
3230 $ hg log --color=never -l 1 --template '{label(red, "text\n")}'
3231 text
3231 text
3232 $ hg log --config extensions.color=! -l 1 --template '{label(red, "text\n")}'
3232 $ hg log --config extensions.color=! -l 1 --template '{label(red, "text\n")}'
3233 text
3233 text
3234
3234
3235 Test branches inside if statement:
3235 Test branches inside if statement:
3236
3236
3237 $ hg log -r 0 --template '{if(branches, "yes", "no")}\n'
3237 $ hg log -r 0 --template '{if(branches, "yes", "no")}\n'
3238 no
3238 no
3239
3239
3240 Test get function:
3240 Test get function:
3241
3241
3242 $ hg log -r 0 --template '{get(extras, "branch")}\n'
3242 $ hg log -r 0 --template '{get(extras, "branch")}\n'
3243 default
3243 default
3244 $ hg log -r 0 --template '{get(extras, "br{"anch"}")}\n'
3244 $ hg log -r 0 --template '{get(extras, "br{"anch"}")}\n'
3245 default
3245 default
3246 $ hg log -r 0 --template '{get(files, "should_fail")}\n'
3246 $ hg log -r 0 --template '{get(files, "should_fail")}\n'
3247 hg: parse error: get() expects a dict as first argument
3247 hg: parse error: get() expects a dict as first argument
3248 [255]
3248 [255]
3249
3249
3250 Test localdate(date, tz) function:
3250 Test localdate(date, tz) function:
3251
3251
3252 $ TZ=JST-09 hg log -r0 -T '{date|localdate|isodate}\n'
3252 $ TZ=JST-09 hg log -r0 -T '{date|localdate|isodate}\n'
3253 1970-01-01 09:00 +0900
3253 1970-01-01 09:00 +0900
3254 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "UTC")|isodate}\n'
3254 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "UTC")|isodate}\n'
3255 1970-01-01 00:00 +0000
3255 1970-01-01 00:00 +0000
3256 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "+0200")|isodate}\n'
3256 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "+0200")|isodate}\n'
3257 1970-01-01 02:00 +0200
3257 1970-01-01 02:00 +0200
3258 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "0")|isodate}\n'
3258 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "0")|isodate}\n'
3259 1970-01-01 00:00 +0000
3259 1970-01-01 00:00 +0000
3260 $ TZ=JST-09 hg log -r0 -T '{localdate(date, 0)|isodate}\n'
3260 $ TZ=JST-09 hg log -r0 -T '{localdate(date, 0)|isodate}\n'
3261 1970-01-01 00:00 +0000
3261 1970-01-01 00:00 +0000
3262 $ hg log -r0 -T '{localdate(date, "invalid")|isodate}\n'
3262 $ hg log -r0 -T '{localdate(date, "invalid")|isodate}\n'
3263 hg: parse error: localdate expects a timezone
3263 hg: parse error: localdate expects a timezone
3264 [255]
3264 [255]
3265 $ hg log -r0 -T '{localdate(date, date)|isodate}\n'
3265 $ hg log -r0 -T '{localdate(date, date)|isodate}\n'
3266 hg: parse error: localdate expects a timezone
3266 hg: parse error: localdate expects a timezone
3267 [255]
3267 [255]
3268
3268
3269 Test shortest(node) function:
3269 Test shortest(node) function:
3270
3270
3271 $ echo b > b
3271 $ echo b > b
3272 $ hg ci -qAm b
3272 $ hg ci -qAm b
3273 $ hg log --template '{shortest(node)}\n'
3273 $ hg log --template '{shortest(node)}\n'
3274 e777
3274 e777
3275 bcc7
3275 bcc7
3276 f776
3276 f776
3277 $ hg log --template '{shortest(node, 10)}\n'
3277 $ hg log --template '{shortest(node, 10)}\n'
3278 e777603221
3278 e777603221
3279 bcc7ff960b
3279 bcc7ff960b
3280 f7769ec2ab
3280 f7769ec2ab
3281 $ hg log --template '{node|shortest}\n' -l1
3281 $ hg log --template '{node|shortest}\n' -l1
3282 e777
3282 e777
3283
3283
3284 $ hg log -r 0 -T '{shortest(node, "1{"0"}")}\n'
3284 $ hg log -r 0 -T '{shortest(node, "1{"0"}")}\n'
3285 f7769ec2ab
3285 f7769ec2ab
3286 $ hg log -r 0 -T '{shortest(node, "not an int")}\n'
3286 $ hg log -r 0 -T '{shortest(node, "not an int")}\n'
3287 hg: parse error: shortest() expects an integer minlength
3287 hg: parse error: shortest() expects an integer minlength
3288 [255]
3288 [255]
3289
3289
3290 Test pad function
3290 Test pad function
3291
3291
3292 $ hg log --template '{pad(rev, 20)} {author|user}\n'
3292 $ hg log --template '{pad(rev, 20)} {author|user}\n'
3293 2 test
3293 2 test
3294 1 {node|short}
3294 1 {node|short}
3295 0 test
3295 0 test
3296
3296
3297 $ hg log --template '{pad(rev, 20, " ", True)} {author|user}\n'
3297 $ hg log --template '{pad(rev, 20, " ", True)} {author|user}\n'
3298 2 test
3298 2 test
3299 1 {node|short}
3299 1 {node|short}
3300 0 test
3300 0 test
3301
3301
3302 $ hg log --template '{pad(rev, 20, "-", False)} {author|user}\n'
3302 $ hg log --template '{pad(rev, 20, "-", False)} {author|user}\n'
3303 2------------------- test
3303 2------------------- test
3304 1------------------- {node|short}
3304 1------------------- {node|short}
3305 0------------------- test
3305 0------------------- test
3306
3306
3307 Test template string in pad function
3307 Test template string in pad function
3308
3308
3309 $ hg log -r 0 -T '{pad("\{{rev}}", 10)} {author|user}\n'
3309 $ hg log -r 0 -T '{pad("\{{rev}}", 10)} {author|user}\n'
3310 {0} test
3310 {0} test
3311
3311
3312 $ hg log -r 0 -T '{pad(r"\{rev}", 10)} {author|user}\n'
3312 $ hg log -r 0 -T '{pad(r"\{rev}", 10)} {author|user}\n'
3313 \{rev} test
3313 \{rev} test
3314
3314
3315 Test width argument passed to pad function
3315 Test width argument passed to pad function
3316
3316
3317 $ hg log -r 0 -T '{pad(rev, "1{"0"}")} {author|user}\n'
3317 $ hg log -r 0 -T '{pad(rev, "1{"0"}")} {author|user}\n'
3318 0 test
3318 0 test
3319 $ hg log -r 0 -T '{pad(rev, "not an int")}\n'
3319 $ hg log -r 0 -T '{pad(rev, "not an int")}\n'
3320 hg: parse error: pad() expects an integer width
3320 hg: parse error: pad() expects an integer width
3321 [255]
3321 [255]
3322
3322
3323 Test ifcontains function
3323 Test ifcontains function
3324
3324
3325 $ hg log --template '{rev} {ifcontains(rev, "2 two 0", "is in the string", "is not")}\n'
3325 $ hg log --template '{rev} {ifcontains(rev, "2 two 0", "is in the string", "is not")}\n'
3326 2 is in the string
3326 2 is in the string
3327 1 is not
3327 1 is not
3328 0 is in the string
3328 0 is in the string
3329
3329
3330 $ hg log -T '{rev} {ifcontains(rev, "2 two{" 0"}", "is in the string", "is not")}\n'
3330 $ hg log -T '{rev} {ifcontains(rev, "2 two{" 0"}", "is in the string", "is not")}\n'
3331 2 is in the string
3331 2 is in the string
3332 1 is not
3332 1 is not
3333 0 is in the string
3333 0 is in the string
3334
3334
3335 $ hg log --template '{rev} {ifcontains("a", file_adds, "added a", "did not add a")}\n'
3335 $ hg log --template '{rev} {ifcontains("a", file_adds, "added a", "did not add a")}\n'
3336 2 did not add a
3336 2 did not add a
3337 1 did not add a
3337 1 did not add a
3338 0 added a
3338 0 added a
3339
3339
3340 $ hg log --debug -T '{rev}{ifcontains(1, parents, " is parent of 1")}\n'
3340 $ hg log --debug -T '{rev}{ifcontains(1, parents, " is parent of 1")}\n'
3341 2 is parent of 1
3341 2 is parent of 1
3342 1
3342 1
3343 0
3343 0
3344
3344
3345 Test revset function
3345 Test revset function
3346
3346
3347 $ hg log --template '{rev} {ifcontains(rev, revset("."), "current rev", "not current rev")}\n'
3347 $ hg log --template '{rev} {ifcontains(rev, revset("."), "current rev", "not current rev")}\n'
3348 2 current rev
3348 2 current rev
3349 1 not current rev
3349 1 not current rev
3350 0 not current rev
3350 0 not current rev
3351
3351
3352 $ hg log --template '{rev} {ifcontains(rev, revset(". + .^"), "match rev", "not match rev")}\n'
3352 $ hg log --template '{rev} {ifcontains(rev, revset(". + .^"), "match rev", "not match rev")}\n'
3353 2 match rev
3353 2 match rev
3354 1 match rev
3354 1 match rev
3355 0 not match rev
3355 0 not match rev
3356
3356
3357 $ hg log --template '{rev} Parents: {revset("parents(%s)", rev)}\n'
3357 $ hg log --template '{rev} Parents: {revset("parents(%s)", rev)}\n'
3358 2 Parents: 1
3358 2 Parents: 1
3359 1 Parents: 0
3359 1 Parents: 0
3360 0 Parents:
3360 0 Parents:
3361
3361
3362 $ cat >> .hg/hgrc <<EOF
3362 $ cat >> .hg/hgrc <<EOF
3363 > [revsetalias]
3363 > [revsetalias]
3364 > myparents(\$1) = parents(\$1)
3364 > myparents(\$1) = parents(\$1)
3365 > EOF
3365 > EOF
3366 $ hg log --template '{rev} Parents: {revset("myparents(%s)", rev)}\n'
3366 $ hg log --template '{rev} Parents: {revset("myparents(%s)", rev)}\n'
3367 2 Parents: 1
3367 2 Parents: 1
3368 1 Parents: 0
3368 1 Parents: 0
3369 0 Parents:
3369 0 Parents:
3370
3370
3371 $ hg log --template 'Rev: {rev}\n{revset("::%s", rev) % "Ancestor: {revision}\n"}\n'
3371 $ hg log --template 'Rev: {rev}\n{revset("::%s", rev) % "Ancestor: {revision}\n"}\n'
3372 Rev: 2
3372 Rev: 2
3373 Ancestor: 0
3373 Ancestor: 0
3374 Ancestor: 1
3374 Ancestor: 1
3375 Ancestor: 2
3375 Ancestor: 2
3376
3376
3377 Rev: 1
3377 Rev: 1
3378 Ancestor: 0
3378 Ancestor: 0
3379 Ancestor: 1
3379 Ancestor: 1
3380
3380
3381 Rev: 0
3381 Rev: 0
3382 Ancestor: 0
3382 Ancestor: 0
3383
3383
3384 $ hg log --template '{revset("TIP"|lower)}\n' -l1
3384 $ hg log --template '{revset("TIP"|lower)}\n' -l1
3385 2
3385 2
3386
3386
3387 $ hg log -T '{revset("%s", "t{"ip"}")}\n' -l1
3387 $ hg log -T '{revset("%s", "t{"ip"}")}\n' -l1
3388 2
3388 2
3389
3389
3390 a list template is evaluated for each item of revset/parents
3390 a list template is evaluated for each item of revset/parents
3391
3391
3392 $ hg log -T '{rev} p: {revset("p1(%s)", rev) % "{rev}:{node|short}"}\n'
3392 $ hg log -T '{rev} p: {revset("p1(%s)", rev) % "{rev}:{node|short}"}\n'
3393 2 p: 1:bcc7ff960b8e
3393 2 p: 1:bcc7ff960b8e
3394 1 p: 0:f7769ec2ab97
3394 1 p: 0:f7769ec2ab97
3395 0 p:
3395 0 p:
3396
3396
3397 $ hg log --debug -T '{rev} p:{parents % " {rev}:{node|short}"}\n'
3397 $ hg log --debug -T '{rev} p:{parents % " {rev}:{node|short}"}\n'
3398 2 p: 1:bcc7ff960b8e -1:000000000000
3398 2 p: 1:bcc7ff960b8e -1:000000000000
3399 1 p: 0:f7769ec2ab97 -1:000000000000
3399 1 p: 0:f7769ec2ab97 -1:000000000000
3400 0 p: -1:000000000000 -1:000000000000
3400 0 p: -1:000000000000 -1:000000000000
3401
3401
3402 therefore, 'revcache' should be recreated for each rev
3402 therefore, 'revcache' should be recreated for each rev
3403
3403
3404 $ hg log -T '{rev} {file_adds}\np {revset("p1(%s)", rev) % "{file_adds}"}\n'
3404 $ hg log -T '{rev} {file_adds}\np {revset("p1(%s)", rev) % "{file_adds}"}\n'
3405 2 aa b
3405 2 aa b
3406 p
3406 p
3407 1
3407 1
3408 p a
3408 p a
3409 0 a
3409 0 a
3410 p
3410 p
3411
3411
3412 $ hg log --debug -T '{rev} {file_adds}\np {parents % "{file_adds}"}\n'
3412 $ hg log --debug -T '{rev} {file_adds}\np {parents % "{file_adds}"}\n'
3413 2 aa b
3413 2 aa b
3414 p
3414 p
3415 1
3415 1
3416 p a
3416 p a
3417 0 a
3417 0 a
3418 p
3418 p
3419
3419
3420 a revset item must be evaluated as an integer revision, not an offset from tip
3420 a revset item must be evaluated as an integer revision, not an offset from tip
3421
3421
3422 $ hg log -l 1 -T '{revset("null") % "{rev}:{node|short}"}\n'
3422 $ hg log -l 1 -T '{revset("null") % "{rev}:{node|short}"}\n'
3423 -1:000000000000
3423 -1:000000000000
3424 $ hg log -l 1 -T '{revset("%s", "null") % "{rev}:{node|short}"}\n'
3424 $ hg log -l 1 -T '{revset("%s", "null") % "{rev}:{node|short}"}\n'
3425 -1:000000000000
3425 -1:000000000000
3426
3426
3427 Test active bookmark templating
3427 Test active bookmark templating
3428
3428
3429 $ hg book foo
3429 $ hg book foo
3430 $ hg book bar
3430 $ hg book bar
3431 $ hg log --template "{rev} {bookmarks % '{bookmark}{ifeq(bookmark, active, \"*\")} '}\n"
3431 $ hg log --template "{rev} {bookmarks % '{bookmark}{ifeq(bookmark, active, \"*\")} '}\n"
3432 2 bar* foo
3432 2 bar* foo
3433 1
3433 1
3434 0
3434 0
3435 $ hg log --template "{rev} {activebookmark}\n"
3435 $ hg log --template "{rev} {activebookmark}\n"
3436 2 bar
3436 2 bar
3437 1
3437 1
3438 0
3438 0
3439 $ hg bookmarks --inactive bar
3439 $ hg bookmarks --inactive bar
3440 $ hg log --template "{rev} {activebookmark}\n"
3440 $ hg log --template "{rev} {activebookmark}\n"
3441 2
3441 2
3442 1
3442 1
3443 0
3443 0
3444 $ hg book -r1 baz
3444 $ hg book -r1 baz
3445 $ hg log --template "{rev} {join(bookmarks, ' ')}\n"
3445 $ hg log --template "{rev} {join(bookmarks, ' ')}\n"
3446 2 bar foo
3446 2 bar foo
3447 1 baz
3447 1 baz
3448 0
3448 0
3449 $ hg log --template "{rev} {ifcontains('foo', bookmarks, 't', 'f')}\n"
3449 $ hg log --template "{rev} {ifcontains('foo', bookmarks, 't', 'f')}\n"
3450 2 t
3450 2 t
3451 1 f
3451 1 f
3452 0 f
3452 0 f
3453
3453
3454 Test namespaces dict
3454 Test namespaces dict
3455
3455
3456 $ hg log -T '{rev}{namespaces % " {namespace}={join(names, ",")}"}\n'
3456 $ hg log -T '{rev}{namespaces % " {namespace}={join(names, ",")}"}\n'
3457 2 bookmarks=bar,foo tags=tip branches=text.{rev}
3457 2 bookmarks=bar,foo tags=tip branches=text.{rev}
3458 1 bookmarks=baz tags= branches=text.{rev}
3458 1 bookmarks=baz tags= branches=text.{rev}
3459 0 bookmarks= tags= branches=default
3459 0 bookmarks= tags= branches=default
3460 $ hg log -r2 -T '{namespaces % "{namespace}: {names}\n"}'
3460 $ hg log -r2 -T '{namespaces % "{namespace}: {names}\n"}'
3461 bookmarks: bar foo
3461 bookmarks: bar foo
3462 tags: tip
3462 tags: tip
3463 branches: text.{rev}
3463 branches: text.{rev}
3464 $ hg log -r2 -T '{namespaces % "{namespace}:\n{names % " {name}\n"}"}'
3464 $ hg log -r2 -T '{namespaces % "{namespace}:\n{names % " {name}\n"}"}'
3465 bookmarks:
3465 bookmarks:
3466 bar
3466 bar
3467 foo
3467 foo
3468 tags:
3468 tags:
3469 tip
3469 tip
3470 branches:
3470 branches:
3471 text.{rev}
3471 text.{rev}
3472 $ hg log -r2 -T '{get(namespaces, "bookmarks") % "{name}\n"}'
3472 $ hg log -r2 -T '{get(namespaces, "bookmarks") % "{name}\n"}'
3473 bar
3473 bar
3474 foo
3474 foo
3475
3475
3476 Test stringify on sub expressions
3476 Test stringify on sub expressions
3477
3477
3478 $ cd ..
3478 $ cd ..
3479 $ hg log -R a -r 8 --template '{join(files, if("1", if("1", ", ")))}\n'
3479 $ hg log -R a -r 8 --template '{join(files, if("1", if("1", ", ")))}\n'
3480 fourth, second, third
3480 fourth, second, third
3481 $ hg log -R a -r 8 --template '{strip(if("1", if("1", "-abc-")), if("1", if("1", "-")))}\n'
3481 $ hg log -R a -r 8 --template '{strip(if("1", if("1", "-abc-")), if("1", if("1", "-")))}\n'
3482 abc
3482 abc
3483
3483
3484 Test splitlines
3484 Test splitlines
3485
3485
3486 $ hg log -Gv -R a --template "{splitlines(desc) % 'foo {line}\n'}"
3486 $ hg log -Gv -R a --template "{splitlines(desc) % 'foo {line}\n'}"
3487 @ foo Modify, add, remove, rename
3487 @ foo Modify, add, remove, rename
3488 |
3488 |
3489 o foo future
3489 o foo future
3490 |
3490 |
3491 o foo third
3491 o foo third
3492 |
3492 |
3493 o foo second
3493 o foo second
3494
3494
3495 o foo merge
3495 o foo merge
3496 |\
3496 |\
3497 | o foo new head
3497 | o foo new head
3498 | |
3498 | |
3499 o | foo new branch
3499 o | foo new branch
3500 |/
3500 |/
3501 o foo no user, no domain
3501 o foo no user, no domain
3502 |
3502 |
3503 o foo no person
3503 o foo no person
3504 |
3504 |
3505 o foo other 1
3505 o foo other 1
3506 | foo other 2
3506 | foo other 2
3507 | foo
3507 | foo
3508 | foo other 3
3508 | foo other 3
3509 o foo line 1
3509 o foo line 1
3510 foo line 2
3510 foo line 2
3511
3511
3512 Test startswith
3512 Test startswith
3513 $ hg log -Gv -R a --template "{startswith(desc)}"
3513 $ hg log -Gv -R a --template "{startswith(desc)}"
3514 hg: parse error: startswith expects two arguments
3514 hg: parse error: startswith expects two arguments
3515 [255]
3515 [255]
3516
3516
3517 $ hg log -Gv -R a --template "{startswith('line', desc)}"
3517 $ hg log -Gv -R a --template "{startswith('line', desc)}"
3518 @
3518 @
3519 |
3519 |
3520 o
3520 o
3521 |
3521 |
3522 o
3522 o
3523 |
3523 |
3524 o
3524 o
3525
3525
3526 o
3526 o
3527 |\
3527 |\
3528 | o
3528 | o
3529 | |
3529 | |
3530 o |
3530 o |
3531 |/
3531 |/
3532 o
3532 o
3533 |
3533 |
3534 o
3534 o
3535 |
3535 |
3536 o
3536 o
3537 |
3537 |
3538 o line 1
3538 o line 1
3539 line 2
3539 line 2
3540
3540
3541 Test bad template with better error message
3541 Test bad template with better error message
3542
3542
3543 $ hg log -Gv -R a --template '{desc|user()}'
3543 $ hg log -Gv -R a --template '{desc|user()}'
3544 hg: parse error: expected a symbol, got 'func'
3544 hg: parse error: expected a symbol, got 'func'
3545 [255]
3545 [255]
3546
3546
3547 Test word function (including index out of bounds graceful failure)
3547 Test word function (including index out of bounds graceful failure)
3548
3548
3549 $ hg log -Gv -R a --template "{word('1', desc)}"
3549 $ hg log -Gv -R a --template "{word('1', desc)}"
3550 @ add,
3550 @ add,
3551 |
3551 |
3552 o
3552 o
3553 |
3553 |
3554 o
3554 o
3555 |
3555 |
3556 o
3556 o
3557
3557
3558 o
3558 o
3559 |\
3559 |\
3560 | o head
3560 | o head
3561 | |
3561 | |
3562 o | branch
3562 o | branch
3563 |/
3563 |/
3564 o user,
3564 o user,
3565 |
3565 |
3566 o person
3566 o person
3567 |
3567 |
3568 o 1
3568 o 1
3569 |
3569 |
3570 o 1
3570 o 1
3571
3571
3572
3572
3573 Test word third parameter used as splitter
3573 Test word third parameter used as splitter
3574
3574
3575 $ hg log -Gv -R a --template "{word('0', desc, 'o')}"
3575 $ hg log -Gv -R a --template "{word('0', desc, 'o')}"
3576 @ M
3576 @ M
3577 |
3577 |
3578 o future
3578 o future
3579 |
3579 |
3580 o third
3580 o third
3581 |
3581 |
3582 o sec
3582 o sec
3583
3583
3584 o merge
3584 o merge
3585 |\
3585 |\
3586 | o new head
3586 | o new head
3587 | |
3587 | |
3588 o | new branch
3588 o | new branch
3589 |/
3589 |/
3590 o n
3590 o n
3591 |
3591 |
3592 o n
3592 o n
3593 |
3593 |
3594 o
3594 o
3595 |
3595 |
3596 o line 1
3596 o line 1
3597 line 2
3597 line 2
3598
3598
3599 Test word error messages for not enough and too many arguments
3599 Test word error messages for not enough and too many arguments
3600
3600
3601 $ hg log -Gv -R a --template "{word('0')}"
3601 $ hg log -Gv -R a --template "{word('0')}"
3602 hg: parse error: word expects two or three arguments, got 1
3602 hg: parse error: word expects two or three arguments, got 1
3603 [255]
3603 [255]
3604
3604
3605 $ hg log -Gv -R a --template "{word('0', desc, 'o', 'h', 'b', 'o', 'y')}"
3605 $ hg log -Gv -R a --template "{word('0', desc, 'o', 'h', 'b', 'o', 'y')}"
3606 hg: parse error: word expects two or three arguments, got 7
3606 hg: parse error: word expects two or three arguments, got 7
3607 [255]
3607 [255]
3608
3608
3609 Test word for integer literal
3609 Test word for integer literal
3610
3610
3611 $ hg log -R a --template "{word(2, desc)}\n" -r0
3611 $ hg log -R a --template "{word(2, desc)}\n" -r0
3612 line
3612 line
3613
3613
3614 Test word for invalid numbers
3614 Test word for invalid numbers
3615
3615
3616 $ hg log -Gv -R a --template "{word('a', desc)}"
3616 $ hg log -Gv -R a --template "{word('a', desc)}"
3617 hg: parse error: word expects an integer index
3617 hg: parse error: word expects an integer index
3618 [255]
3618 [255]
3619
3619
3620 Test word for out of range
3620 Test word for out of range
3621
3621
3622 $ hg log -R a --template "{word(10000, desc)}"
3622 $ hg log -R a --template "{word(10000, desc)}"
3623 $ hg log -R a --template "{word(-10000, desc)}"
3623 $ hg log -R a --template "{word(-10000, desc)}"
3624
3624
3625 Test indent and not adding to empty lines
3625 Test indent and not adding to empty lines
3626
3626
3627 $ hg log -T "-----\n{indent(desc, '>> ', ' > ')}\n" -r 0:1 -R a
3627 $ hg log -T "-----\n{indent(desc, '>> ', ' > ')}\n" -r 0:1 -R a
3628 -----
3628 -----
3629 > line 1
3629 > line 1
3630 >> line 2
3630 >> line 2
3631 -----
3631 -----
3632 > other 1
3632 > other 1
3633 >> other 2
3633 >> other 2
3634
3634
3635 >> other 3
3635 >> other 3
3636
3636
3637 Test with non-strings like dates
3637 Test with non-strings like dates
3638
3638
3639 $ hg log -T "{indent(date, ' ')}\n" -r 2:3 -R a
3639 $ hg log -T "{indent(date, ' ')}\n" -r 2:3 -R a
3640 1200000.00
3640 1200000.00
3641 1300000.00
3641 1300000.00
3642
3642
3643 Test broken string escapes:
3643 Test broken string escapes:
3644
3644
3645 $ hg log -T "bogus\\" -R a
3645 $ hg log -T "bogus\\" -R a
3646 hg: parse error: trailing \ in string
3646 hg: parse error: trailing \ in string
3647 [255]
3647 [255]
3648 $ hg log -T "\\xy" -R a
3648 $ hg log -T "\\xy" -R a
3649 hg: parse error: invalid \x escape
3649 hg: parse error: invalid \x escape
3650 [255]
3650 [255]
3651
3651
3652 json filter should escape HTML tags so that the output can be embedded in hgweb:
3652 json filter should escape HTML tags so that the output can be embedded in hgweb:
3653
3653
3654 $ hg log -T "{'<foo@example.org>'|json}\n" -R a -l1
3654 $ hg log -T "{'<foo@example.org>'|json}\n" -R a -l1
3655 "\u003cfoo@example.org\u003e"
3655 "\u003cfoo@example.org\u003e"
3656
3656
3657 Templater supports aliases of symbol and func() styles:
3657 Templater supports aliases of symbol and func() styles:
3658
3658
3659 $ hg clone -q a aliases
3659 $ hg clone -q a aliases
3660 $ cd aliases
3660 $ cd aliases
3661 $ cat <<EOF >> .hg/hgrc
3661 $ cat <<EOF >> .hg/hgrc
3662 > [templatealias]
3662 > [templatealias]
3663 > r = rev
3663 > r = rev
3664 > rn = "{r}:{node|short}"
3664 > rn = "{r}:{node|short}"
3665 > status(c, files) = files % "{c} {file}\n"
3665 > status(c, files) = files % "{c} {file}\n"
3666 > utcdate(d) = localdate(d, "UTC")
3666 > utcdate(d) = localdate(d, "UTC")
3667 > EOF
3667 > EOF
3668
3668
3669 $ hg debugtemplate -vr0 '{rn} {utcdate(date)|isodate}\n'
3669 $ hg debugtemplate -vr0 '{rn} {utcdate(date)|isodate}\n'
3670 (template
3670 (template
3671 ('symbol', 'rn')
3671 ('symbol', 'rn')
3672 ('string', ' ')
3672 ('string', ' ')
3673 (|
3673 (|
3674 (func
3674 (func
3675 ('symbol', 'utcdate')
3675 ('symbol', 'utcdate')
3676 ('symbol', 'date'))
3676 ('symbol', 'date'))
3677 ('symbol', 'isodate'))
3677 ('symbol', 'isodate'))
3678 ('string', '\n'))
3678 ('string', '\n'))
3679 * expanded:
3679 * expanded:
3680 (template
3680 (template
3681 (template
3681 (template
3682 ('symbol', 'rev')
3682 ('symbol', 'rev')
3683 ('string', ':')
3683 ('string', ':')
3684 (|
3684 (|
3685 ('symbol', 'node')
3685 ('symbol', 'node')
3686 ('symbol', 'short')))
3686 ('symbol', 'short')))
3687 ('string', ' ')
3687 ('string', ' ')
3688 (|
3688 (|
3689 (func
3689 (func
3690 ('symbol', 'localdate')
3690 ('symbol', 'localdate')
3691 (list
3691 (list
3692 ('symbol', 'date')
3692 ('symbol', 'date')
3693 ('string', 'UTC')))
3693 ('string', 'UTC')))
3694 ('symbol', 'isodate'))
3694 ('symbol', 'isodate'))
3695 ('string', '\n'))
3695 ('string', '\n'))
3696 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
3696 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
3697
3697
3698 $ hg debugtemplate -vr0 '{status("A", file_adds)}'
3698 $ hg debugtemplate -vr0 '{status("A", file_adds)}'
3699 (template
3699 (template
3700 (func
3700 (func
3701 ('symbol', 'status')
3701 ('symbol', 'status')
3702 (list
3702 (list
3703 ('string', 'A')
3703 ('string', 'A')
3704 ('symbol', 'file_adds'))))
3704 ('symbol', 'file_adds'))))
3705 * expanded:
3705 * expanded:
3706 (template
3706 (template
3707 (%
3707 (%
3708 ('symbol', 'file_adds')
3708 ('symbol', 'file_adds')
3709 (template
3709 (template
3710 ('string', 'A')
3710 ('string', 'A')
3711 ('string', ' ')
3711 ('string', ' ')
3712 ('symbol', 'file')
3712 ('symbol', 'file')
3713 ('string', '\n'))))
3713 ('string', '\n'))))
3714 A a
3714 A a
3715
3715
3716 A unary function alias can be called as a filter:
3716 A unary function alias can be called as a filter:
3717
3717
3718 $ hg debugtemplate -vr0 '{date|utcdate|isodate}\n'
3718 $ hg debugtemplate -vr0 '{date|utcdate|isodate}\n'
3719 (template
3719 (template
3720 (|
3720 (|
3721 (|
3721 (|
3722 ('symbol', 'date')
3722 ('symbol', 'date')
3723 ('symbol', 'utcdate'))
3723 ('symbol', 'utcdate'))
3724 ('symbol', 'isodate'))
3724 ('symbol', 'isodate'))
3725 ('string', '\n'))
3725 ('string', '\n'))
3726 * expanded:
3726 * expanded:
3727 (template
3727 (template
3728 (|
3728 (|
3729 (func
3729 (func
3730 ('symbol', 'localdate')
3730 ('symbol', 'localdate')
3731 (list
3731 (list
3732 ('symbol', 'date')
3732 ('symbol', 'date')
3733 ('string', 'UTC')))
3733 ('string', 'UTC')))
3734 ('symbol', 'isodate'))
3734 ('symbol', 'isodate'))
3735 ('string', '\n'))
3735 ('string', '\n'))
3736 1970-01-12 13:46 +0000
3736 1970-01-12 13:46 +0000
3737
3737
3738 Aliases should be applied only to command arguments and templates in hgrc.
3738 Aliases should be applied only to command arguments and templates in hgrc.
3739 Otherwise, our stock styles and web templates could be corrupted:
3739 Otherwise, our stock styles and web templates could be corrupted:
3740
3740
3741 $ hg log -r0 -T '{rn} {utcdate(date)|isodate}\n'
3741 $ hg log -r0 -T '{rn} {utcdate(date)|isodate}\n'
3742 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
3742 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
3743
3743
3744 $ hg log -r0 --config ui.logtemplate='"{rn} {utcdate(date)|isodate}\n"'
3744 $ hg log -r0 --config ui.logtemplate='"{rn} {utcdate(date)|isodate}\n"'
3745 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
3745 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
3746
3746
3747 $ cat <<EOF > tmpl
3747 $ cat <<EOF > tmpl
3748 > changeset = 'nothing expanded:{rn}\n'
3748 > changeset = 'nothing expanded:{rn}\n'
3749 > EOF
3749 > EOF
3750 $ hg log -r0 --style ./tmpl
3750 $ hg log -r0 --style ./tmpl
3751 nothing expanded:
3751 nothing expanded:
3752
3752
3753 Aliases in formatter:
3753 Aliases in formatter:
3754
3754
3755 $ hg branches -T '{pad(branch, 7)} {rn}\n'
3755 $ hg branches -T '{pad(branch, 7)} {rn}\n'
3756 default 6:d41e714fe50d
3756 default 6:d41e714fe50d
3757 foo 4:bbe44766e73d
3757 foo 4:bbe44766e73d
3758
3758
3759 Aliases should honor HGPLAIN:
3760
3761 $ HGPLAIN= hg log -r0 -T 'nothing expanded:{rn}\n'
3762 nothing expanded:
3763 $ HGPLAINEXCEPT=templatealias hg log -r0 -T '{rn}\n'
3764 0:1e4e1b8f71e0
3765
3759 Unparsable alias:
3766 Unparsable alias:
3760
3767
3761 $ hg debugtemplate --config templatealias.bad='x(' -v '{bad}'
3768 $ hg debugtemplate --config templatealias.bad='x(' -v '{bad}'
3762 (template
3769 (template
3763 ('symbol', 'bad'))
3770 ('symbol', 'bad'))
3764 abort: failed to parse the definition of template alias "bad": at 2: not a prefix: end
3771 abort: failed to parse the definition of template alias "bad": at 2: not a prefix: end
3765 [255]
3772 [255]
3766 $ hg log --config templatealias.bad='x(' -T '{bad}'
3773 $ hg log --config templatealias.bad='x(' -T '{bad}'
3767 abort: failed to parse the definition of template alias "bad": at 2: not a prefix: end
3774 abort: failed to parse the definition of template alias "bad": at 2: not a prefix: end
3768 [255]
3775 [255]
3769
3776
3770 $ cd ..
3777 $ cd ..
3771
3778
3772 Set up repository for non-ascii encoding tests:
3779 Set up repository for non-ascii encoding tests:
3773
3780
3774 $ hg init nonascii
3781 $ hg init nonascii
3775 $ cd nonascii
3782 $ cd nonascii
3776 $ python <<EOF
3783 $ python <<EOF
3777 > open('latin1', 'w').write('\xe9')
3784 > open('latin1', 'w').write('\xe9')
3778 > open('utf-8', 'w').write('\xc3\xa9')
3785 > open('utf-8', 'w').write('\xc3\xa9')
3779 > EOF
3786 > EOF
3780 $ HGENCODING=utf-8 hg branch -q `cat utf-8`
3787 $ HGENCODING=utf-8 hg branch -q `cat utf-8`
3781 $ HGENCODING=utf-8 hg ci -qAm "non-ascii branch: `cat utf-8`" utf-8
3788 $ HGENCODING=utf-8 hg ci -qAm "non-ascii branch: `cat utf-8`" utf-8
3782
3789
3783 json filter should try round-trip conversion to utf-8:
3790 json filter should try round-trip conversion to utf-8:
3784
3791
3785 $ HGENCODING=ascii hg log -T "{branch|json}\n" -r0
3792 $ HGENCODING=ascii hg log -T "{branch|json}\n" -r0
3786 "\u00e9"
3793 "\u00e9"
3787 $ HGENCODING=ascii hg log -T "{desc|json}\n" -r0
3794 $ HGENCODING=ascii hg log -T "{desc|json}\n" -r0
3788 "non-ascii branch: \u00e9"
3795 "non-ascii branch: \u00e9"
3789
3796
3790 json filter takes input as utf-8b:
3797 json filter takes input as utf-8b:
3791
3798
3792 $ HGENCODING=ascii hg log -T "{'`cat utf-8`'|json}\n" -l1
3799 $ HGENCODING=ascii hg log -T "{'`cat utf-8`'|json}\n" -l1
3793 "\u00e9"
3800 "\u00e9"
3794 $ HGENCODING=ascii hg log -T "{'`cat latin1`'|json}\n" -l1
3801 $ HGENCODING=ascii hg log -T "{'`cat latin1`'|json}\n" -l1
3795 "\udce9"
3802 "\udce9"
3796
3803
3797 utf8 filter:
3804 utf8 filter:
3798
3805
3799 $ HGENCODING=ascii hg log -T "round-trip: {branch|utf8|hex}\n" -r0
3806 $ HGENCODING=ascii hg log -T "round-trip: {branch|utf8|hex}\n" -r0
3800 round-trip: c3a9
3807 round-trip: c3a9
3801 $ HGENCODING=latin1 hg log -T "decoded: {'`cat latin1`'|utf8|hex}\n" -l1
3808 $ HGENCODING=latin1 hg log -T "decoded: {'`cat latin1`'|utf8|hex}\n" -l1
3802 decoded: c3a9
3809 decoded: c3a9
3803 $ HGENCODING=ascii hg log -T "replaced: {'`cat latin1`'|utf8|hex}\n" -l1
3810 $ HGENCODING=ascii hg log -T "replaced: {'`cat latin1`'|utf8|hex}\n" -l1
3804 abort: decoding near * (glob)
3811 abort: decoding near * (glob)
3805 [255]
3812 [255]
3806 $ hg log -T "invalid type: {rev|utf8}\n" -r0
3813 $ hg log -T "invalid type: {rev|utf8}\n" -r0
3807 abort: template filter 'utf8' is not compatible with keyword 'rev'
3814 abort: template filter 'utf8' is not compatible with keyword 'rev'
3808 [255]
3815 [255]
3809
3816
3810 $ cd ..
3817 $ cd ..
3811
3818
3812 Test that template function in extension is registered as expected
3819 Test that template function in extension is registered as expected
3813
3820
3814 $ cd a
3821 $ cd a
3815
3822
3816 $ cat <<EOF > $TESTTMP/customfunc.py
3823 $ cat <<EOF > $TESTTMP/customfunc.py
3817 > from mercurial import registrar
3824 > from mercurial import registrar
3818 >
3825 >
3819 > templatefunc = registrar.templatefunc()
3826 > templatefunc = registrar.templatefunc()
3820 >
3827 >
3821 > @templatefunc('custom()')
3828 > @templatefunc('custom()')
3822 > def custom(context, mapping, args):
3829 > def custom(context, mapping, args):
3823 > return 'custom'
3830 > return 'custom'
3824 > EOF
3831 > EOF
3825 $ cat <<EOF > .hg/hgrc
3832 $ cat <<EOF > .hg/hgrc
3826 > [extensions]
3833 > [extensions]
3827 > customfunc = $TESTTMP/customfunc.py
3834 > customfunc = $TESTTMP/customfunc.py
3828 > EOF
3835 > EOF
3829
3836
3830 $ hg log -r . -T "{custom()}\n" --config customfunc.enabled=true
3837 $ hg log -r . -T "{custom()}\n" --config customfunc.enabled=true
3831 custom
3838 custom
3832
3839
3833 $ cd ..
3840 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now