##// END OF EJS Templates
merge with crew-stable
Kevin Bullock -
r18225:6a082e72 merge default
parent child Browse files
Show More
@@ -1,831 +1,831 b''
1 # dispatch.py - command dispatching for mercurial
1 # dispatch.py - command dispatching 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 i18n import _
8 from i18n import _
9 import os, sys, atexit, signal, pdb, socket, errno, shlex, time, traceback, re
9 import os, sys, atexit, signal, pdb, socket, errno, shlex, time, traceback, re
10 import util, commands, hg, fancyopts, extensions, hook, error
10 import util, commands, hg, fancyopts, extensions, hook, error
11 import cmdutil, encoding
11 import cmdutil, encoding
12 import ui as uimod
12 import ui as uimod
13
13
14 class request(object):
14 class request(object):
15 def __init__(self, args, ui=None, repo=None, fin=None, fout=None,
15 def __init__(self, args, ui=None, repo=None, fin=None, fout=None,
16 ferr=None):
16 ferr=None):
17 self.args = args
17 self.args = args
18 self.ui = ui
18 self.ui = ui
19 self.repo = repo
19 self.repo = repo
20
20
21 # input/output/error streams
21 # input/output/error streams
22 self.fin = fin
22 self.fin = fin
23 self.fout = fout
23 self.fout = fout
24 self.ferr = ferr
24 self.ferr = ferr
25
25
26 def run():
26 def run():
27 "run the command in sys.argv"
27 "run the command in sys.argv"
28 sys.exit((dispatch(request(sys.argv[1:])) or 0) & 255)
28 sys.exit((dispatch(request(sys.argv[1:])) or 0) & 255)
29
29
30 def dispatch(req):
30 def dispatch(req):
31 "run the command specified in req.args"
31 "run the command specified in req.args"
32 if req.ferr:
32 if req.ferr:
33 ferr = req.ferr
33 ferr = req.ferr
34 elif req.ui:
34 elif req.ui:
35 ferr = req.ui.ferr
35 ferr = req.ui.ferr
36 else:
36 else:
37 ferr = sys.stderr
37 ferr = sys.stderr
38
38
39 try:
39 try:
40 if not req.ui:
40 if not req.ui:
41 req.ui = uimod.ui()
41 req.ui = uimod.ui()
42 if '--traceback' in req.args:
42 if '--traceback' in req.args:
43 req.ui.setconfig('ui', 'traceback', 'on')
43 req.ui.setconfig('ui', 'traceback', 'on')
44
44
45 # set ui streams from the request
45 # set ui streams from the request
46 if req.fin:
46 if req.fin:
47 req.ui.fin = req.fin
47 req.ui.fin = req.fin
48 if req.fout:
48 if req.fout:
49 req.ui.fout = req.fout
49 req.ui.fout = req.fout
50 if req.ferr:
50 if req.ferr:
51 req.ui.ferr = req.ferr
51 req.ui.ferr = req.ferr
52 except util.Abort, inst:
52 except util.Abort, inst:
53 ferr.write(_("abort: %s\n") % inst)
53 ferr.write(_("abort: %s\n") % inst)
54 if inst.hint:
54 if inst.hint:
55 ferr.write(_("(%s)\n") % inst.hint)
55 ferr.write(_("(%s)\n") % inst.hint)
56 return -1
56 return -1
57 except error.ParseError, inst:
57 except error.ParseError, inst:
58 if len(inst.args) > 1:
58 if len(inst.args) > 1:
59 ferr.write(_("hg: parse error at %s: %s\n") %
59 ferr.write(_("hg: parse error at %s: %s\n") %
60 (inst.args[1], inst.args[0]))
60 (inst.args[1], inst.args[0]))
61 else:
61 else:
62 ferr.write(_("hg: parse error: %s\n") % inst.args[0])
62 ferr.write(_("hg: parse error: %s\n") % inst.args[0])
63 return -1
63 return -1
64
64
65 return _runcatch(req)
65 return _runcatch(req)
66
66
67 def _runcatch(req):
67 def _runcatch(req):
68 def catchterm(*args):
68 def catchterm(*args):
69 raise error.SignalInterrupt
69 raise error.SignalInterrupt
70
70
71 ui = req.ui
71 ui = req.ui
72 try:
72 try:
73 for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
73 for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
74 num = getattr(signal, name, None)
74 num = getattr(signal, name, None)
75 if num:
75 if num:
76 signal.signal(num, catchterm)
76 signal.signal(num, catchterm)
77 except ValueError:
77 except ValueError:
78 pass # happens if called in a thread
78 pass # happens if called in a thread
79
79
80 try:
80 try:
81 try:
81 try:
82 # enter the debugger before command execution
82 # enter the debugger before command execution
83 if '--debugger' in req.args:
83 if '--debugger' in req.args:
84 ui.warn(_("entering debugger - "
84 ui.warn(_("entering debugger - "
85 "type c to continue starting hg or h for help\n"))
85 "type c to continue starting hg or h for help\n"))
86 pdb.set_trace()
86 pdb.set_trace()
87 try:
87 try:
88 return _dispatch(req)
88 return _dispatch(req)
89 finally:
89 finally:
90 ui.flush()
90 ui.flush()
91 except: # re-raises
91 except: # re-raises
92 # enter the debugger when we hit an exception
92 # enter the debugger when we hit an exception
93 if '--debugger' in req.args:
93 if '--debugger' in req.args:
94 traceback.print_exc()
94 traceback.print_exc()
95 pdb.post_mortem(sys.exc_info()[2])
95 pdb.post_mortem(sys.exc_info()[2])
96 ui.traceback()
96 ui.traceback()
97 raise
97 raise
98
98
99 # Global exception handling, alphabetically
99 # Global exception handling, alphabetically
100 # Mercurial-specific first, followed by built-in and library exceptions
100 # Mercurial-specific first, followed by built-in and library exceptions
101 except error.AmbiguousCommand, inst:
101 except error.AmbiguousCommand, inst:
102 ui.warn(_("hg: command '%s' is ambiguous:\n %s\n") %
102 ui.warn(_("hg: command '%s' is ambiguous:\n %s\n") %
103 (inst.args[0], " ".join(inst.args[1])))
103 (inst.args[0], " ".join(inst.args[1])))
104 except error.ParseError, inst:
104 except error.ParseError, inst:
105 if len(inst.args) > 1:
105 if len(inst.args) > 1:
106 ui.warn(_("hg: parse error at %s: %s\n") %
106 ui.warn(_("hg: parse error at %s: %s\n") %
107 (inst.args[1], inst.args[0]))
107 (inst.args[1], inst.args[0]))
108 else:
108 else:
109 ui.warn(_("hg: parse error: %s\n") % inst.args[0])
109 ui.warn(_("hg: parse error: %s\n") % inst.args[0])
110 return -1
110 return -1
111 except error.LockHeld, inst:
111 except error.LockHeld, inst:
112 if inst.errno == errno.ETIMEDOUT:
112 if inst.errno == errno.ETIMEDOUT:
113 reason = _('timed out waiting for lock held by %s') % inst.locker
113 reason = _('timed out waiting for lock held by %s') % inst.locker
114 else:
114 else:
115 reason = _('lock held by %s') % inst.locker
115 reason = _('lock held by %s') % inst.locker
116 ui.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason))
116 ui.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason))
117 except error.LockUnavailable, inst:
117 except error.LockUnavailable, inst:
118 ui.warn(_("abort: could not lock %s: %s\n") %
118 ui.warn(_("abort: could not lock %s: %s\n") %
119 (inst.desc or inst.filename, inst.strerror))
119 (inst.desc or inst.filename, inst.strerror))
120 except error.CommandError, inst:
120 except error.CommandError, inst:
121 if inst.args[0]:
121 if inst.args[0]:
122 ui.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
122 ui.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
123 commands.help_(ui, inst.args[0], full=False, command=True)
123 commands.help_(ui, inst.args[0], full=False, command=True)
124 else:
124 else:
125 ui.warn(_("hg: %s\n") % inst.args[1])
125 ui.warn(_("hg: %s\n") % inst.args[1])
126 commands.help_(ui, 'shortlist')
126 commands.help_(ui, 'shortlist')
127 except error.OutOfBandError, inst:
127 except error.OutOfBandError, inst:
128 ui.warn(_("abort: remote error:\n"))
128 ui.warn(_("abort: remote error:\n"))
129 ui.warn(''.join(inst.args))
129 ui.warn(''.join(inst.args))
130 except error.RepoError, inst:
130 except error.RepoError, inst:
131 ui.warn(_("abort: %s!\n") % inst)
131 ui.warn(_("abort: %s!\n") % inst)
132 if inst.hint:
132 if inst.hint:
133 ui.warn(_("(%s)\n") % inst.hint)
133 ui.warn(_("(%s)\n") % inst.hint)
134 except error.ResponseError, inst:
134 except error.ResponseError, inst:
135 ui.warn(_("abort: %s") % inst.args[0])
135 ui.warn(_("abort: %s") % inst.args[0])
136 if not isinstance(inst.args[1], basestring):
136 if not isinstance(inst.args[1], basestring):
137 ui.warn(" %r\n" % (inst.args[1],))
137 ui.warn(" %r\n" % (inst.args[1],))
138 elif not inst.args[1]:
138 elif not inst.args[1]:
139 ui.warn(_(" empty string\n"))
139 ui.warn(_(" empty string\n"))
140 else:
140 else:
141 ui.warn("\n%r\n" % util.ellipsis(inst.args[1]))
141 ui.warn("\n%r\n" % util.ellipsis(inst.args[1]))
142 except error.RevlogError, inst:
142 except error.RevlogError, inst:
143 ui.warn(_("abort: %s!\n") % inst)
143 ui.warn(_("abort: %s!\n") % inst)
144 except error.SignalInterrupt:
144 except error.SignalInterrupt:
145 ui.warn(_("killed!\n"))
145 ui.warn(_("killed!\n"))
146 except error.UnknownCommand, inst:
146 except error.UnknownCommand, inst:
147 ui.warn(_("hg: unknown command '%s'\n") % inst.args[0])
147 ui.warn(_("hg: unknown command '%s'\n") % inst.args[0])
148 try:
148 try:
149 # check if the command is in a disabled extension
149 # check if the command is in a disabled extension
150 # (but don't check for extensions themselves)
150 # (but don't check for extensions themselves)
151 commands.help_(ui, inst.args[0], unknowncmd=True)
151 commands.help_(ui, inst.args[0], unknowncmd=True)
152 except error.UnknownCommand:
152 except error.UnknownCommand:
153 commands.help_(ui, 'shortlist')
153 commands.help_(ui, 'shortlist')
154 except util.Abort, inst:
154 except util.Abort, inst:
155 ui.warn(_("abort: %s\n") % inst)
155 ui.warn(_("abort: %s\n") % inst)
156 if inst.hint:
156 if inst.hint:
157 ui.warn(_("(%s)\n") % inst.hint)
157 ui.warn(_("(%s)\n") % inst.hint)
158 except ImportError, inst:
158 except ImportError, inst:
159 ui.warn(_("abort: %s!\n") % inst)
159 ui.warn(_("abort: %s!\n") % inst)
160 m = str(inst).split()[-1]
160 m = str(inst).split()[-1]
161 if m in "mpatch bdiff".split():
161 if m in "mpatch bdiff".split():
162 ui.warn(_("(did you forget to compile extensions?)\n"))
162 ui.warn(_("(did you forget to compile extensions?)\n"))
163 elif m in "zlib".split():
163 elif m in "zlib".split():
164 ui.warn(_("(is your Python install correct?)\n"))
164 ui.warn(_("(is your Python install correct?)\n"))
165 except IOError, inst:
165 except IOError, inst:
166 if util.safehasattr(inst, "code"):
166 if util.safehasattr(inst, "code"):
167 ui.warn(_("abort: %s\n") % inst)
167 ui.warn(_("abort: %s\n") % inst)
168 elif util.safehasattr(inst, "reason"):
168 elif util.safehasattr(inst, "reason"):
169 try: # usually it is in the form (errno, strerror)
169 try: # usually it is in the form (errno, strerror)
170 reason = inst.reason.args[1]
170 reason = inst.reason.args[1]
171 except (AttributeError, IndexError):
171 except (AttributeError, IndexError):
172 # it might be anything, for example a string
172 # it might be anything, for example a string
173 reason = inst.reason
173 reason = inst.reason
174 ui.warn(_("abort: error: %s\n") % reason)
174 ui.warn(_("abort: error: %s\n") % reason)
175 elif util.safehasattr(inst, "args") and inst.args[0] == errno.EPIPE:
175 elif util.safehasattr(inst, "args") and inst.args[0] == errno.EPIPE:
176 if ui.debugflag:
176 if ui.debugflag:
177 ui.warn(_("broken pipe\n"))
177 ui.warn(_("broken pipe\n"))
178 elif getattr(inst, "strerror", None):
178 elif getattr(inst, "strerror", None):
179 if getattr(inst, "filename", None):
179 if getattr(inst, "filename", None):
180 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
180 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
181 else:
181 else:
182 ui.warn(_("abort: %s\n") % inst.strerror)
182 ui.warn(_("abort: %s\n") % inst.strerror)
183 else:
183 else:
184 raise
184 raise
185 except OSError, inst:
185 except OSError, inst:
186 if getattr(inst, "filename", None):
186 if getattr(inst, "filename", None):
187 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
187 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
188 else:
188 else:
189 ui.warn(_("abort: %s\n") % inst.strerror)
189 ui.warn(_("abort: %s\n") % inst.strerror)
190 except KeyboardInterrupt:
190 except KeyboardInterrupt:
191 try:
191 try:
192 ui.warn(_("interrupted!\n"))
192 ui.warn(_("interrupted!\n"))
193 except IOError, inst:
193 except IOError, inst:
194 if inst.errno == errno.EPIPE:
194 if inst.errno == errno.EPIPE:
195 if ui.debugflag:
195 if ui.debugflag:
196 ui.warn(_("\nbroken pipe\n"))
196 ui.warn(_("\nbroken pipe\n"))
197 else:
197 else:
198 raise
198 raise
199 except MemoryError:
199 except MemoryError:
200 ui.warn(_("abort: out of memory\n"))
200 ui.warn(_("abort: out of memory\n"))
201 except SystemExit, inst:
201 except SystemExit, inst:
202 # Commands shouldn't sys.exit directly, but give a return code.
202 # Commands shouldn't sys.exit directly, but give a return code.
203 # Just in case catch this and and pass exit code to caller.
203 # Just in case catch this and and pass exit code to caller.
204 return inst.code
204 return inst.code
205 except socket.error, inst:
205 except socket.error, inst:
206 ui.warn(_("abort: %s\n") % inst.args[-1])
206 ui.warn(_("abort: %s\n") % inst.args[-1])
207 except: # re-raises
207 except: # re-raises
208 myver = util.version()
208 myver = util.version()
209 # For compatibility checking, we discard the portion of the hg
209 # For compatibility checking, we discard the portion of the hg
210 # version after the + on the assumption that if a "normal
210 # version after the + on the assumption that if a "normal
211 # user" is running a build with a + in it the packager
211 # user" is running a build with a + in it the packager
212 # probably built from fairly close to a tag and anyone with a
212 # probably built from fairly close to a tag and anyone with a
213 # 'make local' copy of hg (where the version number can be out
213 # 'make local' copy of hg (where the version number can be out
214 # of date) will be clueful enough to notice the implausible
214 # of date) will be clueful enough to notice the implausible
215 # version number and try updating.
215 # version number and try updating.
216 compare = myver.split('+')[0]
216 compare = myver.split('+')[0]
217 ct = tuplever(compare)
217 ct = tuplever(compare)
218 worst = None, ct, ''
218 worst = None, ct, ''
219 for name, mod in extensions.extensions():
219 for name, mod in extensions.extensions():
220 testedwith = getattr(mod, 'testedwith', 'unknown')
220 testedwith = getattr(mod, 'testedwith', '')
221 report = getattr(mod, 'buglink', _('the extension author.'))
221 report = getattr(mod, 'buglink', _('the extension author.'))
222 if testedwith == 'unknown':
222 if not testedwith.strip():
223 # We found an untested extension. It's likely the culprit.
223 # We found an untested extension. It's likely the culprit.
224 worst = name, testedwith, report
224 worst = name, 'unknown', report
225 break
225 break
226 if compare not in testedwith.split() and testedwith != 'internal':
226 if compare not in testedwith.split() and testedwith != 'internal':
227 tested = [tuplever(v) for v in testedwith.split()]
227 tested = [tuplever(v) for v in testedwith.split()]
228 lower = [t for t in tested if t < ct]
228 lower = [t for t in tested if t < ct]
229 nearest = max(lower or tested)
229 nearest = max(lower or tested)
230 if worst[0] is None or nearest < worst[1]:
230 if worst[0] is None or nearest < worst[1]:
231 worst = name, nearest, report
231 worst = name, nearest, report
232 if worst[0] is not None:
232 if worst[0] is not None:
233 name, testedwith, report = worst
233 name, testedwith, report = worst
234 if not isinstance(testedwith, str):
234 if not isinstance(testedwith, str):
235 testedwith = '.'.join([str(c) for c in testedwith])
235 testedwith = '.'.join([str(c) for c in testedwith])
236 warning = (_('** Unknown exception encountered with '
236 warning = (_('** Unknown exception encountered with '
237 'possibly-broken third-party extension %s\n'
237 'possibly-broken third-party extension %s\n'
238 '** which supports versions %s of Mercurial.\n'
238 '** which supports versions %s of Mercurial.\n'
239 '** Please disable %s and try your action again.\n'
239 '** Please disable %s and try your action again.\n'
240 '** If that fixes the bug please report it to %s\n')
240 '** If that fixes the bug please report it to %s\n')
241 % (name, testedwith, name, report))
241 % (name, testedwith, name, report))
242 else:
242 else:
243 warning = (_("** unknown exception encountered, "
243 warning = (_("** unknown exception encountered, "
244 "please report by visiting\n") +
244 "please report by visiting\n") +
245 _("** http://mercurial.selenic.com/wiki/BugTracker\n"))
245 _("** http://mercurial.selenic.com/wiki/BugTracker\n"))
246 warning += ((_("** Python %s\n") % sys.version.replace('\n', '')) +
246 warning += ((_("** Python %s\n") % sys.version.replace('\n', '')) +
247 (_("** Mercurial Distributed SCM (version %s)\n") % myver) +
247 (_("** Mercurial Distributed SCM (version %s)\n") % myver) +
248 (_("** Extensions loaded: %s\n") %
248 (_("** Extensions loaded: %s\n") %
249 ", ".join([x[0] for x in extensions.extensions()])))
249 ", ".join([x[0] for x in extensions.extensions()])))
250 ui.warn(warning)
250 ui.warn(warning)
251 raise
251 raise
252
252
253 return -1
253 return -1
254
254
255 def tuplever(v):
255 def tuplever(v):
256 try:
256 try:
257 return tuple([int(i) for i in v.split('.')])
257 return tuple([int(i) for i in v.split('.')])
258 except ValueError:
258 except ValueError:
259 return tuple()
259 return tuple()
260
260
261 def aliasargs(fn, givenargs):
261 def aliasargs(fn, givenargs):
262 args = getattr(fn, 'args', [])
262 args = getattr(fn, 'args', [])
263 if args:
263 if args:
264 cmd = ' '.join(map(util.shellquote, args))
264 cmd = ' '.join(map(util.shellquote, args))
265
265
266 nums = []
266 nums = []
267 def replacer(m):
267 def replacer(m):
268 num = int(m.group(1)) - 1
268 num = int(m.group(1)) - 1
269 nums.append(num)
269 nums.append(num)
270 if num < len(givenargs):
270 if num < len(givenargs):
271 return givenargs[num]
271 return givenargs[num]
272 raise util.Abort(_('too few arguments for command alias'))
272 raise util.Abort(_('too few arguments for command alias'))
273 cmd = re.sub(r'\$(\d+|\$)', replacer, cmd)
273 cmd = re.sub(r'\$(\d+|\$)', replacer, cmd)
274 givenargs = [x for i, x in enumerate(givenargs)
274 givenargs = [x for i, x in enumerate(givenargs)
275 if i not in nums]
275 if i not in nums]
276 args = shlex.split(cmd)
276 args = shlex.split(cmd)
277 return args + givenargs
277 return args + givenargs
278
278
279 class cmdalias(object):
279 class cmdalias(object):
280 def __init__(self, name, definition, cmdtable):
280 def __init__(self, name, definition, cmdtable):
281 self.name = self.cmd = name
281 self.name = self.cmd = name
282 self.cmdname = ''
282 self.cmdname = ''
283 self.definition = definition
283 self.definition = definition
284 self.args = []
284 self.args = []
285 self.opts = []
285 self.opts = []
286 self.help = ''
286 self.help = ''
287 self.norepo = True
287 self.norepo = True
288 self.optionalrepo = False
288 self.optionalrepo = False
289 self.badalias = False
289 self.badalias = False
290
290
291 try:
291 try:
292 aliases, entry = cmdutil.findcmd(self.name, cmdtable)
292 aliases, entry = cmdutil.findcmd(self.name, cmdtable)
293 for alias, e in cmdtable.iteritems():
293 for alias, e in cmdtable.iteritems():
294 if e is entry:
294 if e is entry:
295 self.cmd = alias
295 self.cmd = alias
296 break
296 break
297 self.shadows = True
297 self.shadows = True
298 except error.UnknownCommand:
298 except error.UnknownCommand:
299 self.shadows = False
299 self.shadows = False
300
300
301 if not self.definition:
301 if not self.definition:
302 def fn(ui, *args):
302 def fn(ui, *args):
303 ui.warn(_("no definition for alias '%s'\n") % self.name)
303 ui.warn(_("no definition for alias '%s'\n") % self.name)
304 return 1
304 return 1
305 self.fn = fn
305 self.fn = fn
306 self.badalias = True
306 self.badalias = True
307 return
307 return
308
308
309 if self.definition.startswith('!'):
309 if self.definition.startswith('!'):
310 self.shell = True
310 self.shell = True
311 def fn(ui, *args):
311 def fn(ui, *args):
312 env = {'HG_ARGS': ' '.join((self.name,) + args)}
312 env = {'HG_ARGS': ' '.join((self.name,) + args)}
313 def _checkvar(m):
313 def _checkvar(m):
314 if m.groups()[0] == '$':
314 if m.groups()[0] == '$':
315 return m.group()
315 return m.group()
316 elif int(m.groups()[0]) <= len(args):
316 elif int(m.groups()[0]) <= len(args):
317 return m.group()
317 return m.group()
318 else:
318 else:
319 ui.debug("No argument found for substitution "
319 ui.debug("No argument found for substitution "
320 "of %i variable in alias '%s' definition."
320 "of %i variable in alias '%s' definition."
321 % (int(m.groups()[0]), self.name))
321 % (int(m.groups()[0]), self.name))
322 return ''
322 return ''
323 cmd = re.sub(r'\$(\d+|\$)', _checkvar, self.definition[1:])
323 cmd = re.sub(r'\$(\d+|\$)', _checkvar, self.definition[1:])
324 replace = dict((str(i + 1), arg) for i, arg in enumerate(args))
324 replace = dict((str(i + 1), arg) for i, arg in enumerate(args))
325 replace['0'] = self.name
325 replace['0'] = self.name
326 replace['@'] = ' '.join(args)
326 replace['@'] = ' '.join(args)
327 cmd = util.interpolate(r'\$', replace, cmd, escape_prefix=True)
327 cmd = util.interpolate(r'\$', replace, cmd, escape_prefix=True)
328 return util.system(cmd, environ=env, out=ui.fout)
328 return util.system(cmd, environ=env, out=ui.fout)
329 self.fn = fn
329 self.fn = fn
330 return
330 return
331
331
332 args = shlex.split(self.definition)
332 args = shlex.split(self.definition)
333 self.cmdname = cmd = args.pop(0)
333 self.cmdname = cmd = args.pop(0)
334 args = map(util.expandpath, args)
334 args = map(util.expandpath, args)
335
335
336 for invalidarg in ("--cwd", "-R", "--repository", "--repo"):
336 for invalidarg in ("--cwd", "-R", "--repository", "--repo"):
337 if _earlygetopt([invalidarg], args):
337 if _earlygetopt([invalidarg], args):
338 def fn(ui, *args):
338 def fn(ui, *args):
339 ui.warn(_("error in definition for alias '%s': %s may only "
339 ui.warn(_("error in definition for alias '%s': %s may only "
340 "be given on the command line\n")
340 "be given on the command line\n")
341 % (self.name, invalidarg))
341 % (self.name, invalidarg))
342 return 1
342 return 1
343
343
344 self.fn = fn
344 self.fn = fn
345 self.badalias = True
345 self.badalias = True
346 return
346 return
347
347
348 try:
348 try:
349 tableentry = cmdutil.findcmd(cmd, cmdtable, False)[1]
349 tableentry = cmdutil.findcmd(cmd, cmdtable, False)[1]
350 if len(tableentry) > 2:
350 if len(tableentry) > 2:
351 self.fn, self.opts, self.help = tableentry
351 self.fn, self.opts, self.help = tableentry
352 else:
352 else:
353 self.fn, self.opts = tableentry
353 self.fn, self.opts = tableentry
354
354
355 self.args = aliasargs(self.fn, args)
355 self.args = aliasargs(self.fn, args)
356 if cmd not in commands.norepo.split(' '):
356 if cmd not in commands.norepo.split(' '):
357 self.norepo = False
357 self.norepo = False
358 if cmd in commands.optionalrepo.split(' '):
358 if cmd in commands.optionalrepo.split(' '):
359 self.optionalrepo = True
359 self.optionalrepo = True
360 if self.help.startswith("hg " + cmd):
360 if self.help.startswith("hg " + cmd):
361 # drop prefix in old-style help lines so hg shows the alias
361 # drop prefix in old-style help lines so hg shows the alias
362 self.help = self.help[4 + len(cmd):]
362 self.help = self.help[4 + len(cmd):]
363 self.__doc__ = self.fn.__doc__
363 self.__doc__ = self.fn.__doc__
364
364
365 except error.UnknownCommand:
365 except error.UnknownCommand:
366 def fn(ui, *args):
366 def fn(ui, *args):
367 ui.warn(_("alias '%s' resolves to unknown command '%s'\n") \
367 ui.warn(_("alias '%s' resolves to unknown command '%s'\n") \
368 % (self.name, cmd))
368 % (self.name, cmd))
369 try:
369 try:
370 # check if the command is in a disabled extension
370 # check if the command is in a disabled extension
371 commands.help_(ui, cmd, unknowncmd=True)
371 commands.help_(ui, cmd, unknowncmd=True)
372 except error.UnknownCommand:
372 except error.UnknownCommand:
373 pass
373 pass
374 return 1
374 return 1
375 self.fn = fn
375 self.fn = fn
376 self.badalias = True
376 self.badalias = True
377 except error.AmbiguousCommand:
377 except error.AmbiguousCommand:
378 def fn(ui, *args):
378 def fn(ui, *args):
379 ui.warn(_("alias '%s' resolves to ambiguous command '%s'\n") \
379 ui.warn(_("alias '%s' resolves to ambiguous command '%s'\n") \
380 % (self.name, cmd))
380 % (self.name, cmd))
381 return 1
381 return 1
382 self.fn = fn
382 self.fn = fn
383 self.badalias = True
383 self.badalias = True
384
384
385 def __call__(self, ui, *args, **opts):
385 def __call__(self, ui, *args, **opts):
386 if self.shadows:
386 if self.shadows:
387 ui.debug("alias '%s' shadows command '%s'\n" %
387 ui.debug("alias '%s' shadows command '%s'\n" %
388 (self.name, self.cmdname))
388 (self.name, self.cmdname))
389
389
390 if util.safehasattr(self, 'shell'):
390 if util.safehasattr(self, 'shell'):
391 return self.fn(ui, *args, **opts)
391 return self.fn(ui, *args, **opts)
392 else:
392 else:
393 try:
393 try:
394 util.checksignature(self.fn)(ui, *args, **opts)
394 util.checksignature(self.fn)(ui, *args, **opts)
395 except error.SignatureError:
395 except error.SignatureError:
396 args = ' '.join([self.cmdname] + self.args)
396 args = ' '.join([self.cmdname] + self.args)
397 ui.debug("alias '%s' expands to '%s'\n" % (self.name, args))
397 ui.debug("alias '%s' expands to '%s'\n" % (self.name, args))
398 raise
398 raise
399
399
400 def addaliases(ui, cmdtable):
400 def addaliases(ui, cmdtable):
401 # aliases are processed after extensions have been loaded, so they
401 # aliases are processed after extensions have been loaded, so they
402 # may use extension commands. Aliases can also use other alias definitions,
402 # may use extension commands. Aliases can also use other alias definitions,
403 # but only if they have been defined prior to the current definition.
403 # but only if they have been defined prior to the current definition.
404 for alias, definition in ui.configitems('alias'):
404 for alias, definition in ui.configitems('alias'):
405 aliasdef = cmdalias(alias, definition, cmdtable)
405 aliasdef = cmdalias(alias, definition, cmdtable)
406
406
407 try:
407 try:
408 olddef = cmdtable[aliasdef.cmd][0]
408 olddef = cmdtable[aliasdef.cmd][0]
409 if olddef.definition == aliasdef.definition:
409 if olddef.definition == aliasdef.definition:
410 continue
410 continue
411 except (KeyError, AttributeError):
411 except (KeyError, AttributeError):
412 # definition might not exist or it might not be a cmdalias
412 # definition might not exist or it might not be a cmdalias
413 pass
413 pass
414
414
415 cmdtable[aliasdef.name] = (aliasdef, aliasdef.opts, aliasdef.help)
415 cmdtable[aliasdef.name] = (aliasdef, aliasdef.opts, aliasdef.help)
416 if aliasdef.norepo:
416 if aliasdef.norepo:
417 commands.norepo += ' %s' % alias
417 commands.norepo += ' %s' % alias
418 if aliasdef.optionalrepo:
418 if aliasdef.optionalrepo:
419 commands.optionalrepo += ' %s' % alias
419 commands.optionalrepo += ' %s' % alias
420
420
421 def _parse(ui, args):
421 def _parse(ui, args):
422 options = {}
422 options = {}
423 cmdoptions = {}
423 cmdoptions = {}
424
424
425 try:
425 try:
426 args = fancyopts.fancyopts(args, commands.globalopts, options)
426 args = fancyopts.fancyopts(args, commands.globalopts, options)
427 except fancyopts.getopt.GetoptError, inst:
427 except fancyopts.getopt.GetoptError, inst:
428 raise error.CommandError(None, inst)
428 raise error.CommandError(None, inst)
429
429
430 if args:
430 if args:
431 cmd, args = args[0], args[1:]
431 cmd, args = args[0], args[1:]
432 aliases, entry = cmdutil.findcmd(cmd, commands.table,
432 aliases, entry = cmdutil.findcmd(cmd, commands.table,
433 ui.configbool("ui", "strict"))
433 ui.configbool("ui", "strict"))
434 cmd = aliases[0]
434 cmd = aliases[0]
435 args = aliasargs(entry[0], args)
435 args = aliasargs(entry[0], args)
436 defaults = ui.config("defaults", cmd)
436 defaults = ui.config("defaults", cmd)
437 if defaults:
437 if defaults:
438 args = map(util.expandpath, shlex.split(defaults)) + args
438 args = map(util.expandpath, shlex.split(defaults)) + args
439 c = list(entry[1])
439 c = list(entry[1])
440 else:
440 else:
441 cmd = None
441 cmd = None
442 c = []
442 c = []
443
443
444 # combine global options into local
444 # combine global options into local
445 for o in commands.globalopts:
445 for o in commands.globalopts:
446 c.append((o[0], o[1], options[o[1]], o[3]))
446 c.append((o[0], o[1], options[o[1]], o[3]))
447
447
448 try:
448 try:
449 args = fancyopts.fancyopts(args, c, cmdoptions, True)
449 args = fancyopts.fancyopts(args, c, cmdoptions, True)
450 except fancyopts.getopt.GetoptError, inst:
450 except fancyopts.getopt.GetoptError, inst:
451 raise error.CommandError(cmd, inst)
451 raise error.CommandError(cmd, inst)
452
452
453 # separate global options back out
453 # separate global options back out
454 for o in commands.globalopts:
454 for o in commands.globalopts:
455 n = o[1]
455 n = o[1]
456 options[n] = cmdoptions[n]
456 options[n] = cmdoptions[n]
457 del cmdoptions[n]
457 del cmdoptions[n]
458
458
459 return (cmd, cmd and entry[0] or None, args, options, cmdoptions)
459 return (cmd, cmd and entry[0] or None, args, options, cmdoptions)
460
460
461 def _parseconfig(ui, config):
461 def _parseconfig(ui, config):
462 """parse the --config options from the command line"""
462 """parse the --config options from the command line"""
463 configs = []
463 configs = []
464
464
465 for cfg in config:
465 for cfg in config:
466 try:
466 try:
467 name, value = cfg.split('=', 1)
467 name, value = cfg.split('=', 1)
468 section, name = name.split('.', 1)
468 section, name = name.split('.', 1)
469 if not section or not name:
469 if not section or not name:
470 raise IndexError
470 raise IndexError
471 ui.setconfig(section, name, value)
471 ui.setconfig(section, name, value)
472 configs.append((section, name, value))
472 configs.append((section, name, value))
473 except (IndexError, ValueError):
473 except (IndexError, ValueError):
474 raise util.Abort(_('malformed --config option: %r '
474 raise util.Abort(_('malformed --config option: %r '
475 '(use --config section.name=value)') % cfg)
475 '(use --config section.name=value)') % cfg)
476
476
477 return configs
477 return configs
478
478
479 def _earlygetopt(aliases, args):
479 def _earlygetopt(aliases, args):
480 """Return list of values for an option (or aliases).
480 """Return list of values for an option (or aliases).
481
481
482 The values are listed in the order they appear in args.
482 The values are listed in the order they appear in args.
483 The options and values are removed from args.
483 The options and values are removed from args.
484 """
484 """
485 try:
485 try:
486 argcount = args.index("--")
486 argcount = args.index("--")
487 except ValueError:
487 except ValueError:
488 argcount = len(args)
488 argcount = len(args)
489 shortopts = [opt for opt in aliases if len(opt) == 2]
489 shortopts = [opt for opt in aliases if len(opt) == 2]
490 values = []
490 values = []
491 pos = 0
491 pos = 0
492 while pos < argcount:
492 while pos < argcount:
493 if args[pos] in aliases:
493 if args[pos] in aliases:
494 if pos + 1 >= argcount:
494 if pos + 1 >= argcount:
495 # ignore and let getopt report an error if there is no value
495 # ignore and let getopt report an error if there is no value
496 break
496 break
497 del args[pos]
497 del args[pos]
498 values.append(args.pop(pos))
498 values.append(args.pop(pos))
499 argcount -= 2
499 argcount -= 2
500 elif args[pos][:2] in shortopts:
500 elif args[pos][:2] in shortopts:
501 # short option can have no following space, e.g. hg log -Rfoo
501 # short option can have no following space, e.g. hg log -Rfoo
502 values.append(args.pop(pos)[2:])
502 values.append(args.pop(pos)[2:])
503 argcount -= 1
503 argcount -= 1
504 else:
504 else:
505 pos += 1
505 pos += 1
506 return values
506 return values
507
507
508 def runcommand(lui, repo, cmd, fullargs, ui, options, d, cmdpats, cmdoptions):
508 def runcommand(lui, repo, cmd, fullargs, ui, options, d, cmdpats, cmdoptions):
509 # run pre-hook, and abort if it fails
509 # run pre-hook, and abort if it fails
510 ret = hook.hook(lui, repo, "pre-%s" % cmd, False, args=" ".join(fullargs),
510 ret = hook.hook(lui, repo, "pre-%s" % cmd, False, args=" ".join(fullargs),
511 pats=cmdpats, opts=cmdoptions)
511 pats=cmdpats, opts=cmdoptions)
512 if ret:
512 if ret:
513 return ret
513 return ret
514 ret = _runcommand(ui, options, cmd, d)
514 ret = _runcommand(ui, options, cmd, d)
515 # run post-hook, passing command result
515 # run post-hook, passing command result
516 hook.hook(lui, repo, "post-%s" % cmd, False, args=" ".join(fullargs),
516 hook.hook(lui, repo, "post-%s" % cmd, False, args=" ".join(fullargs),
517 result=ret, pats=cmdpats, opts=cmdoptions)
517 result=ret, pats=cmdpats, opts=cmdoptions)
518 return ret
518 return ret
519
519
520 def _getlocal(ui, rpath):
520 def _getlocal(ui, rpath):
521 """Return (path, local ui object) for the given target path.
521 """Return (path, local ui object) for the given target path.
522
522
523 Takes paths in [cwd]/.hg/hgrc into account."
523 Takes paths in [cwd]/.hg/hgrc into account."
524 """
524 """
525 try:
525 try:
526 wd = os.getcwd()
526 wd = os.getcwd()
527 except OSError, e:
527 except OSError, e:
528 raise util.Abort(_("error getting current working directory: %s") %
528 raise util.Abort(_("error getting current working directory: %s") %
529 e.strerror)
529 e.strerror)
530 path = cmdutil.findrepo(wd) or ""
530 path = cmdutil.findrepo(wd) or ""
531 if not path:
531 if not path:
532 lui = ui
532 lui = ui
533 else:
533 else:
534 lui = ui.copy()
534 lui = ui.copy()
535 lui.readconfig(os.path.join(path, ".hg", "hgrc"), path)
535 lui.readconfig(os.path.join(path, ".hg", "hgrc"), path)
536
536
537 if rpath and rpath[-1]:
537 if rpath and rpath[-1]:
538 path = lui.expandpath(rpath[-1])
538 path = lui.expandpath(rpath[-1])
539 lui = ui.copy()
539 lui = ui.copy()
540 lui.readconfig(os.path.join(path, ".hg", "hgrc"), path)
540 lui.readconfig(os.path.join(path, ".hg", "hgrc"), path)
541
541
542 return path, lui
542 return path, lui
543
543
544 def _checkshellalias(lui, ui, args):
544 def _checkshellalias(lui, ui, args):
545 options = {}
545 options = {}
546
546
547 try:
547 try:
548 args = fancyopts.fancyopts(args, commands.globalopts, options)
548 args = fancyopts.fancyopts(args, commands.globalopts, options)
549 except fancyopts.getopt.GetoptError:
549 except fancyopts.getopt.GetoptError:
550 return
550 return
551
551
552 if not args:
552 if not args:
553 return
553 return
554
554
555 norepo = commands.norepo
555 norepo = commands.norepo
556 optionalrepo = commands.optionalrepo
556 optionalrepo = commands.optionalrepo
557 def restorecommands():
557 def restorecommands():
558 commands.norepo = norepo
558 commands.norepo = norepo
559 commands.optionalrepo = optionalrepo
559 commands.optionalrepo = optionalrepo
560
560
561 cmdtable = commands.table.copy()
561 cmdtable = commands.table.copy()
562 addaliases(lui, cmdtable)
562 addaliases(lui, cmdtable)
563
563
564 cmd = args[0]
564 cmd = args[0]
565 try:
565 try:
566 aliases, entry = cmdutil.findcmd(cmd, cmdtable,
566 aliases, entry = cmdutil.findcmd(cmd, cmdtable,
567 lui.configbool("ui", "strict"))
567 lui.configbool("ui", "strict"))
568 except (error.AmbiguousCommand, error.UnknownCommand):
568 except (error.AmbiguousCommand, error.UnknownCommand):
569 restorecommands()
569 restorecommands()
570 return
570 return
571
571
572 cmd = aliases[0]
572 cmd = aliases[0]
573 fn = entry[0]
573 fn = entry[0]
574
574
575 if cmd and util.safehasattr(fn, 'shell'):
575 if cmd and util.safehasattr(fn, 'shell'):
576 d = lambda: fn(ui, *args[1:])
576 d = lambda: fn(ui, *args[1:])
577 return lambda: runcommand(lui, None, cmd, args[:1], ui, options, d,
577 return lambda: runcommand(lui, None, cmd, args[:1], ui, options, d,
578 [], {})
578 [], {})
579
579
580 restorecommands()
580 restorecommands()
581
581
582 _loaded = set()
582 _loaded = set()
583 def _dispatch(req):
583 def _dispatch(req):
584 args = req.args
584 args = req.args
585 ui = req.ui
585 ui = req.ui
586
586
587 # read --config before doing anything else
587 # read --config before doing anything else
588 # (e.g. to change trust settings for reading .hg/hgrc)
588 # (e.g. to change trust settings for reading .hg/hgrc)
589 cfgs = _parseconfig(ui, _earlygetopt(['--config'], args))
589 cfgs = _parseconfig(ui, _earlygetopt(['--config'], args))
590
590
591 # check for cwd
591 # check for cwd
592 cwd = _earlygetopt(['--cwd'], args)
592 cwd = _earlygetopt(['--cwd'], args)
593 if cwd:
593 if cwd:
594 os.chdir(cwd[-1])
594 os.chdir(cwd[-1])
595
595
596 rpath = _earlygetopt(["-R", "--repository", "--repo"], args)
596 rpath = _earlygetopt(["-R", "--repository", "--repo"], args)
597 path, lui = _getlocal(ui, rpath)
597 path, lui = _getlocal(ui, rpath)
598
598
599 # Now that we're operating in the right directory/repository with
599 # Now that we're operating in the right directory/repository with
600 # the right config settings, check for shell aliases
600 # the right config settings, check for shell aliases
601 shellaliasfn = _checkshellalias(lui, ui, args)
601 shellaliasfn = _checkshellalias(lui, ui, args)
602 if shellaliasfn:
602 if shellaliasfn:
603 return shellaliasfn()
603 return shellaliasfn()
604
604
605 # Configure extensions in phases: uisetup, extsetup, cmdtable, and
605 # Configure extensions in phases: uisetup, extsetup, cmdtable, and
606 # reposetup. Programs like TortoiseHg will call _dispatch several
606 # reposetup. Programs like TortoiseHg will call _dispatch several
607 # times so we keep track of configured extensions in _loaded.
607 # times so we keep track of configured extensions in _loaded.
608 extensions.loadall(lui)
608 extensions.loadall(lui)
609 exts = [ext for ext in extensions.extensions() if ext[0] not in _loaded]
609 exts = [ext for ext in extensions.extensions() if ext[0] not in _loaded]
610 # Propagate any changes to lui.__class__ by extensions
610 # Propagate any changes to lui.__class__ by extensions
611 ui.__class__ = lui.__class__
611 ui.__class__ = lui.__class__
612
612
613 # (uisetup and extsetup are handled in extensions.loadall)
613 # (uisetup and extsetup are handled in extensions.loadall)
614
614
615 for name, module in exts:
615 for name, module in exts:
616 cmdtable = getattr(module, 'cmdtable', {})
616 cmdtable = getattr(module, 'cmdtable', {})
617 overrides = [cmd for cmd in cmdtable if cmd in commands.table]
617 overrides = [cmd for cmd in cmdtable if cmd in commands.table]
618 if overrides:
618 if overrides:
619 ui.warn(_("extension '%s' overrides commands: %s\n")
619 ui.warn(_("extension '%s' overrides commands: %s\n")
620 % (name, " ".join(overrides)))
620 % (name, " ".join(overrides)))
621 commands.table.update(cmdtable)
621 commands.table.update(cmdtable)
622 _loaded.add(name)
622 _loaded.add(name)
623
623
624 # (reposetup is handled in hg.repository)
624 # (reposetup is handled in hg.repository)
625
625
626 addaliases(lui, commands.table)
626 addaliases(lui, commands.table)
627
627
628 # check for fallback encoding
628 # check for fallback encoding
629 fallback = lui.config('ui', 'fallbackencoding')
629 fallback = lui.config('ui', 'fallbackencoding')
630 if fallback:
630 if fallback:
631 encoding.fallbackencoding = fallback
631 encoding.fallbackencoding = fallback
632
632
633 fullargs = args
633 fullargs = args
634 cmd, func, args, options, cmdoptions = _parse(lui, args)
634 cmd, func, args, options, cmdoptions = _parse(lui, args)
635
635
636 if options["config"]:
636 if options["config"]:
637 raise util.Abort(_("option --config may not be abbreviated!"))
637 raise util.Abort(_("option --config may not be abbreviated!"))
638 if options["cwd"]:
638 if options["cwd"]:
639 raise util.Abort(_("option --cwd may not be abbreviated!"))
639 raise util.Abort(_("option --cwd may not be abbreviated!"))
640 if options["repository"]:
640 if options["repository"]:
641 raise util.Abort(_(
641 raise util.Abort(_(
642 "option -R has to be separated from other options (e.g. not -qR) "
642 "option -R has to be separated from other options (e.g. not -qR) "
643 "and --repository may only be abbreviated as --repo!"))
643 "and --repository may only be abbreviated as --repo!"))
644
644
645 if options["encoding"]:
645 if options["encoding"]:
646 encoding.encoding = options["encoding"]
646 encoding.encoding = options["encoding"]
647 if options["encodingmode"]:
647 if options["encodingmode"]:
648 encoding.encodingmode = options["encodingmode"]
648 encoding.encodingmode = options["encodingmode"]
649 if options["time"]:
649 if options["time"]:
650 def get_times():
650 def get_times():
651 t = os.times()
651 t = os.times()
652 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
652 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
653 t = (t[0], t[1], t[2], t[3], time.clock())
653 t = (t[0], t[1], t[2], t[3], time.clock())
654 return t
654 return t
655 s = get_times()
655 s = get_times()
656 def print_time():
656 def print_time():
657 t = get_times()
657 t = get_times()
658 ui.warn(_("time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
658 ui.warn(_("time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
659 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
659 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
660 atexit.register(print_time)
660 atexit.register(print_time)
661
661
662 uis = set([ui, lui])
662 uis = set([ui, lui])
663
663
664 if req.repo:
664 if req.repo:
665 uis.add(req.repo.ui)
665 uis.add(req.repo.ui)
666
666
667 # copy configs that were passed on the cmdline (--config) to the repo ui
667 # copy configs that were passed on the cmdline (--config) to the repo ui
668 for cfg in cfgs:
668 for cfg in cfgs:
669 req.repo.ui.setconfig(*cfg)
669 req.repo.ui.setconfig(*cfg)
670
670
671 if options['verbose'] or options['debug'] or options['quiet']:
671 if options['verbose'] or options['debug'] or options['quiet']:
672 for opt in ('verbose', 'debug', 'quiet'):
672 for opt in ('verbose', 'debug', 'quiet'):
673 val = str(bool(options[opt]))
673 val = str(bool(options[opt]))
674 for ui_ in uis:
674 for ui_ in uis:
675 ui_.setconfig('ui', opt, val)
675 ui_.setconfig('ui', opt, val)
676
676
677 if options['traceback']:
677 if options['traceback']:
678 for ui_ in uis:
678 for ui_ in uis:
679 ui_.setconfig('ui', 'traceback', 'on')
679 ui_.setconfig('ui', 'traceback', 'on')
680
680
681 if options['noninteractive']:
681 if options['noninteractive']:
682 for ui_ in uis:
682 for ui_ in uis:
683 ui_.setconfig('ui', 'interactive', 'off')
683 ui_.setconfig('ui', 'interactive', 'off')
684
684
685 if cmdoptions.get('insecure', False):
685 if cmdoptions.get('insecure', False):
686 for ui_ in uis:
686 for ui_ in uis:
687 ui_.setconfig('web', 'cacerts', '')
687 ui_.setconfig('web', 'cacerts', '')
688
688
689 if options['version']:
689 if options['version']:
690 return commands.version_(ui)
690 return commands.version_(ui)
691 if options['help']:
691 if options['help']:
692 return commands.help_(ui, cmd)
692 return commands.help_(ui, cmd)
693 elif not cmd:
693 elif not cmd:
694 return commands.help_(ui, 'shortlist')
694 return commands.help_(ui, 'shortlist')
695
695
696 repo = None
696 repo = None
697 cmdpats = args[:]
697 cmdpats = args[:]
698 if cmd not in commands.norepo.split():
698 if cmd not in commands.norepo.split():
699 # use the repo from the request only if we don't have -R
699 # use the repo from the request only if we don't have -R
700 if not rpath and not cwd:
700 if not rpath and not cwd:
701 repo = req.repo
701 repo = req.repo
702
702
703 if repo:
703 if repo:
704 # set the descriptors of the repo ui to those of ui
704 # set the descriptors of the repo ui to those of ui
705 repo.ui.fin = ui.fin
705 repo.ui.fin = ui.fin
706 repo.ui.fout = ui.fout
706 repo.ui.fout = ui.fout
707 repo.ui.ferr = ui.ferr
707 repo.ui.ferr = ui.ferr
708 else:
708 else:
709 try:
709 try:
710 repo = hg.repository(ui, path=path)
710 repo = hg.repository(ui, path=path)
711 if not repo.local():
711 if not repo.local():
712 raise util.Abort(_("repository '%s' is not local") % path)
712 raise util.Abort(_("repository '%s' is not local") % path)
713 repo.ui.setconfig("bundle", "mainreporoot", repo.root)
713 repo.ui.setconfig("bundle", "mainreporoot", repo.root)
714 except error.RequirementError:
714 except error.RequirementError:
715 raise
715 raise
716 except error.RepoError:
716 except error.RepoError:
717 if cmd not in commands.optionalrepo.split():
717 if cmd not in commands.optionalrepo.split():
718 if (cmd in commands.inferrepo.split() and
718 if (cmd in commands.inferrepo.split() and
719 args and not path): # try to infer -R from command args
719 args and not path): # try to infer -R from command args
720 repos = map(cmdutil.findrepo, args)
720 repos = map(cmdutil.findrepo, args)
721 guess = repos[0]
721 guess = repos[0]
722 if guess and repos.count(guess) == len(repos):
722 if guess and repos.count(guess) == len(repos):
723 req.args = ['--repository', guess] + fullargs
723 req.args = ['--repository', guess] + fullargs
724 return _dispatch(req)
724 return _dispatch(req)
725 if not path:
725 if not path:
726 raise error.RepoError(_("no repository found in '%s'"
726 raise error.RepoError(_("no repository found in '%s'"
727 " (.hg not found)")
727 " (.hg not found)")
728 % os.getcwd())
728 % os.getcwd())
729 raise
729 raise
730 if repo:
730 if repo:
731 ui = repo.ui
731 ui = repo.ui
732 args.insert(0, repo)
732 args.insert(0, repo)
733 elif rpath:
733 elif rpath:
734 ui.warn(_("warning: --repository ignored\n"))
734 ui.warn(_("warning: --repository ignored\n"))
735
735
736 msg = ' '.join(' ' in a and repr(a) or a for a in fullargs)
736 msg = ' '.join(' ' in a and repr(a) or a for a in fullargs)
737 ui.log("command", msg + "\n")
737 ui.log("command", msg + "\n")
738 d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
738 d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
739 try:
739 try:
740 return runcommand(lui, repo, cmd, fullargs, ui, options, d,
740 return runcommand(lui, repo, cmd, fullargs, ui, options, d,
741 cmdpats, cmdoptions)
741 cmdpats, cmdoptions)
742 finally:
742 finally:
743 if repo and repo != req.repo:
743 if repo and repo != req.repo:
744 repo.close()
744 repo.close()
745
745
746 def lsprofile(ui, func, fp):
746 def lsprofile(ui, func, fp):
747 format = ui.config('profiling', 'format', default='text')
747 format = ui.config('profiling', 'format', default='text')
748 field = ui.config('profiling', 'sort', default='inlinetime')
748 field = ui.config('profiling', 'sort', default='inlinetime')
749 climit = ui.configint('profiling', 'nested', default=5)
749 climit = ui.configint('profiling', 'nested', default=5)
750
750
751 if format not in ['text', 'kcachegrind']:
751 if format not in ['text', 'kcachegrind']:
752 ui.warn(_("unrecognized profiling format '%s'"
752 ui.warn(_("unrecognized profiling format '%s'"
753 " - Ignored\n") % format)
753 " - Ignored\n") % format)
754 format = 'text'
754 format = 'text'
755
755
756 try:
756 try:
757 from mercurial import lsprof
757 from mercurial import lsprof
758 except ImportError:
758 except ImportError:
759 raise util.Abort(_(
759 raise util.Abort(_(
760 'lsprof not available - install from '
760 'lsprof not available - install from '
761 'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'))
761 'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'))
762 p = lsprof.Profiler()
762 p = lsprof.Profiler()
763 p.enable(subcalls=True)
763 p.enable(subcalls=True)
764 try:
764 try:
765 return func()
765 return func()
766 finally:
766 finally:
767 p.disable()
767 p.disable()
768
768
769 if format == 'kcachegrind':
769 if format == 'kcachegrind':
770 import lsprofcalltree
770 import lsprofcalltree
771 calltree = lsprofcalltree.KCacheGrind(p)
771 calltree = lsprofcalltree.KCacheGrind(p)
772 calltree.output(fp)
772 calltree.output(fp)
773 else:
773 else:
774 # format == 'text'
774 # format == 'text'
775 stats = lsprof.Stats(p.getstats())
775 stats = lsprof.Stats(p.getstats())
776 stats.sort(field)
776 stats.sort(field)
777 stats.pprint(limit=30, file=fp, climit=climit)
777 stats.pprint(limit=30, file=fp, climit=climit)
778
778
779 def statprofile(ui, func, fp):
779 def statprofile(ui, func, fp):
780 try:
780 try:
781 import statprof
781 import statprof
782 except ImportError:
782 except ImportError:
783 raise util.Abort(_(
783 raise util.Abort(_(
784 'statprof not available - install using "easy_install statprof"'))
784 'statprof not available - install using "easy_install statprof"'))
785
785
786 freq = ui.configint('profiling', 'freq', default=1000)
786 freq = ui.configint('profiling', 'freq', default=1000)
787 if freq > 0:
787 if freq > 0:
788 statprof.reset(freq)
788 statprof.reset(freq)
789 else:
789 else:
790 ui.warn(_("invalid sampling frequency '%s' - ignoring\n") % freq)
790 ui.warn(_("invalid sampling frequency '%s' - ignoring\n") % freq)
791
791
792 statprof.start()
792 statprof.start()
793 try:
793 try:
794 return func()
794 return func()
795 finally:
795 finally:
796 statprof.stop()
796 statprof.stop()
797 statprof.display(fp)
797 statprof.display(fp)
798
798
799 def _runcommand(ui, options, cmd, cmdfunc):
799 def _runcommand(ui, options, cmd, cmdfunc):
800 def checkargs():
800 def checkargs():
801 try:
801 try:
802 return cmdfunc()
802 return cmdfunc()
803 except error.SignatureError:
803 except error.SignatureError:
804 raise error.CommandError(cmd, _("invalid arguments"))
804 raise error.CommandError(cmd, _("invalid arguments"))
805
805
806 if options['profile']:
806 if options['profile']:
807 profiler = os.getenv('HGPROF')
807 profiler = os.getenv('HGPROF')
808 if profiler is None:
808 if profiler is None:
809 profiler = ui.config('profiling', 'type', default='ls')
809 profiler = ui.config('profiling', 'type', default='ls')
810 if profiler not in ('ls', 'stat'):
810 if profiler not in ('ls', 'stat'):
811 ui.warn(_("unrecognized profiler '%s' - ignored\n") % profiler)
811 ui.warn(_("unrecognized profiler '%s' - ignored\n") % profiler)
812 profiler = 'ls'
812 profiler = 'ls'
813
813
814 output = ui.config('profiling', 'output')
814 output = ui.config('profiling', 'output')
815
815
816 if output:
816 if output:
817 path = ui.expandpath(output)
817 path = ui.expandpath(output)
818 fp = open(path, 'wb')
818 fp = open(path, 'wb')
819 else:
819 else:
820 fp = sys.stderr
820 fp = sys.stderr
821
821
822 try:
822 try:
823 if profiler == 'ls':
823 if profiler == 'ls':
824 return lsprofile(ui, checkargs, fp)
824 return lsprofile(ui, checkargs, fp)
825 else:
825 else:
826 return statprofile(ui, checkargs, fp)
826 return statprofile(ui, checkargs, fp)
827 finally:
827 finally:
828 if output:
828 if output:
829 fp.close()
829 fp.close()
830 else:
830 else:
831 return checkargs()
831 return checkargs()
@@ -1,1528 +1,1528 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 Quoting for ui.logtemplate
46 Quoting for ui.logtemplate
47
47
48 $ hg tip --config "ui.logtemplate={rev}\n"
48 $ hg tip --config "ui.logtemplate={rev}\n"
49 8
49 8
50 $ hg tip --config "ui.logtemplate='{rev}\n'"
50 $ hg tip --config "ui.logtemplate='{rev}\n'"
51 8
51 8
52 $ hg tip --config 'ui.logtemplate="{rev}\n"'
52 $ hg tip --config 'ui.logtemplate="{rev}\n"'
53 8
53 8
54
54
55 Make sure user/global hgrc does not affect tests
55 Make sure user/global hgrc does not affect tests
56
56
57 $ echo '[ui]' > .hg/hgrc
57 $ echo '[ui]' > .hg/hgrc
58 $ echo 'logtemplate =' >> .hg/hgrc
58 $ echo 'logtemplate =' >> .hg/hgrc
59 $ echo 'style =' >> .hg/hgrc
59 $ echo 'style =' >> .hg/hgrc
60
60
61 Default style is like normal output:
61 Default style is like normal output:
62
62
63 $ hg log > log.out
63 $ hg log > log.out
64 $ hg log --style default > style.out
64 $ hg log --style default > style.out
65 $ cmp log.out style.out || diff -u log.out style.out
65 $ cmp log.out style.out || diff -u log.out style.out
66
66
67 $ hg log -v > log.out
67 $ hg log -v > log.out
68 $ hg log -v --style default > style.out
68 $ hg log -v --style default > style.out
69 $ cmp log.out style.out || diff -u log.out style.out
69 $ cmp log.out style.out || diff -u log.out style.out
70
70
71 $ hg log --debug > log.out
71 $ hg log --debug > log.out
72 $ hg log --debug --style default > style.out
72 $ hg log --debug --style default > style.out
73 $ cmp log.out style.out || diff -u log.out style.out
73 $ cmp log.out style.out || diff -u log.out style.out
74
74
75 Revision with no copies (used to print a traceback):
75 Revision with no copies (used to print a traceback):
76
76
77 $ hg tip -v --template '\n'
77 $ hg tip -v --template '\n'
78
78
79
79
80 Compact style works:
80 Compact style works:
81
81
82 $ hg log --style compact
82 $ hg log --style compact
83 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
83 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
84 third
84 third
85
85
86 7:-1 29114dbae42b 1970-01-12 13:46 +0000 user
86 7:-1 29114dbae42b 1970-01-12 13:46 +0000 user
87 second
87 second
88
88
89 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
89 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
90 merge
90 merge
91
91
92 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
92 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
93 new head
93 new head
94
94
95 4 bbe44766e73d 1970-01-17 04:53 +0000 person
95 4 bbe44766e73d 1970-01-17 04:53 +0000 person
96 new branch
96 new branch
97
97
98 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
98 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
99 no user, no domain
99 no user, no domain
100
100
101 2 97054abb4ab8 1970-01-14 21:20 +0000 other
101 2 97054abb4ab8 1970-01-14 21:20 +0000 other
102 no person
102 no person
103
103
104 1 b608e9d1a3f0 1970-01-13 17:33 +0000 other
104 1 b608e9d1a3f0 1970-01-13 17:33 +0000 other
105 other 1
105 other 1
106
106
107 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 user
107 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 user
108 line 1
108 line 1
109
109
110
110
111 $ hg log -v --style compact
111 $ hg log -v --style compact
112 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
112 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
113 third
113 third
114
114
115 7:-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
115 7:-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
116 second
116 second
117
117
118 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
118 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
119 merge
119 merge
120
120
121 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
121 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
122 new head
122 new head
123
123
124 4 bbe44766e73d 1970-01-17 04:53 +0000 person
124 4 bbe44766e73d 1970-01-17 04:53 +0000 person
125 new branch
125 new branch
126
126
127 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
127 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
128 no user, no domain
128 no user, no domain
129
129
130 2 97054abb4ab8 1970-01-14 21:20 +0000 other@place
130 2 97054abb4ab8 1970-01-14 21:20 +0000 other@place
131 no person
131 no person
132
132
133 1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
133 1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
134 other 1
134 other 1
135 other 2
135 other 2
136
136
137 other 3
137 other 3
138
138
139 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
139 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
140 line 1
140 line 1
141 line 2
141 line 2
142
142
143
143
144 $ hg log --debug --style compact
144 $ hg log --debug --style compact
145 8[tip]:7,-1 95c24699272e 2020-01-01 10:01 +0000 test
145 8[tip]:7,-1 95c24699272e 2020-01-01 10:01 +0000 test
146 third
146 third
147
147
148 7:-1,-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
148 7:-1,-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
149 second
149 second
150
150
151 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
151 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
152 merge
152 merge
153
153
154 5:3,-1 13207e5a10d9 1970-01-18 08:40 +0000 person
154 5:3,-1 13207e5a10d9 1970-01-18 08:40 +0000 person
155 new head
155 new head
156
156
157 4:3,-1 bbe44766e73d 1970-01-17 04:53 +0000 person
157 4:3,-1 bbe44766e73d 1970-01-17 04:53 +0000 person
158 new branch
158 new branch
159
159
160 3:2,-1 10e46f2dcbf4 1970-01-16 01:06 +0000 person
160 3:2,-1 10e46f2dcbf4 1970-01-16 01:06 +0000 person
161 no user, no domain
161 no user, no domain
162
162
163 2:1,-1 97054abb4ab8 1970-01-14 21:20 +0000 other@place
163 2:1,-1 97054abb4ab8 1970-01-14 21:20 +0000 other@place
164 no person
164 no person
165
165
166 1:0,-1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
166 1:0,-1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
167 other 1
167 other 1
168 other 2
168 other 2
169
169
170 other 3
170 other 3
171
171
172 0:-1,-1 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
172 0:-1,-1 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
173 line 1
173 line 1
174 line 2
174 line 2
175
175
176
176
177 Test xml styles:
177 Test xml styles:
178
178
179 $ hg log --style xml
179 $ hg log --style xml
180 <?xml version="1.0"?>
180 <?xml version="1.0"?>
181 <log>
181 <log>
182 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
182 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
183 <tag>tip</tag>
183 <tag>tip</tag>
184 <author email="test">test</author>
184 <author email="test">test</author>
185 <date>2020-01-01T10:01:00+00:00</date>
185 <date>2020-01-01T10:01:00+00:00</date>
186 <msg xml:space="preserve">third</msg>
186 <msg xml:space="preserve">third</msg>
187 </logentry>
187 </logentry>
188 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
188 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
189 <parent revision="-1" node="0000000000000000000000000000000000000000" />
189 <parent revision="-1" node="0000000000000000000000000000000000000000" />
190 <author email="user@hostname">User Name</author>
190 <author email="user@hostname">User Name</author>
191 <date>1970-01-12T13:46:40+00:00</date>
191 <date>1970-01-12T13:46:40+00:00</date>
192 <msg xml:space="preserve">second</msg>
192 <msg xml:space="preserve">second</msg>
193 </logentry>
193 </logentry>
194 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
194 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
195 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
195 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
196 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
196 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
197 <author email="person">person</author>
197 <author email="person">person</author>
198 <date>1970-01-18T08:40:01+00:00</date>
198 <date>1970-01-18T08:40:01+00:00</date>
199 <msg xml:space="preserve">merge</msg>
199 <msg xml:space="preserve">merge</msg>
200 </logentry>
200 </logentry>
201 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
201 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
202 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
202 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
203 <author email="person">person</author>
203 <author email="person">person</author>
204 <date>1970-01-18T08:40:00+00:00</date>
204 <date>1970-01-18T08:40:00+00:00</date>
205 <msg xml:space="preserve">new head</msg>
205 <msg xml:space="preserve">new head</msg>
206 </logentry>
206 </logentry>
207 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
207 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
208 <branch>foo</branch>
208 <branch>foo</branch>
209 <author email="person">person</author>
209 <author email="person">person</author>
210 <date>1970-01-17T04:53:20+00:00</date>
210 <date>1970-01-17T04:53:20+00:00</date>
211 <msg xml:space="preserve">new branch</msg>
211 <msg xml:space="preserve">new branch</msg>
212 </logentry>
212 </logentry>
213 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
213 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
214 <author email="person">person</author>
214 <author email="person">person</author>
215 <date>1970-01-16T01:06:40+00:00</date>
215 <date>1970-01-16T01:06:40+00:00</date>
216 <msg xml:space="preserve">no user, no domain</msg>
216 <msg xml:space="preserve">no user, no domain</msg>
217 </logentry>
217 </logentry>
218 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
218 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
219 <author email="other@place">other</author>
219 <author email="other@place">other</author>
220 <date>1970-01-14T21:20:00+00:00</date>
220 <date>1970-01-14T21:20:00+00:00</date>
221 <msg xml:space="preserve">no person</msg>
221 <msg xml:space="preserve">no person</msg>
222 </logentry>
222 </logentry>
223 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
223 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
224 <author email="other@place">A. N. Other</author>
224 <author email="other@place">A. N. Other</author>
225 <date>1970-01-13T17:33:20+00:00</date>
225 <date>1970-01-13T17:33:20+00:00</date>
226 <msg xml:space="preserve">other 1
226 <msg xml:space="preserve">other 1
227 other 2
227 other 2
228
228
229 other 3</msg>
229 other 3</msg>
230 </logentry>
230 </logentry>
231 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
231 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
232 <author email="user@hostname">User Name</author>
232 <author email="user@hostname">User Name</author>
233 <date>1970-01-12T13:46:40+00:00</date>
233 <date>1970-01-12T13:46:40+00:00</date>
234 <msg xml:space="preserve">line 1
234 <msg xml:space="preserve">line 1
235 line 2</msg>
235 line 2</msg>
236 </logentry>
236 </logentry>
237 </log>
237 </log>
238
238
239 $ hg log -v --style xml
239 $ hg log -v --style xml
240 <?xml version="1.0"?>
240 <?xml version="1.0"?>
241 <log>
241 <log>
242 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
242 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
243 <tag>tip</tag>
243 <tag>tip</tag>
244 <author email="test">test</author>
244 <author email="test">test</author>
245 <date>2020-01-01T10:01:00+00:00</date>
245 <date>2020-01-01T10:01:00+00:00</date>
246 <msg xml:space="preserve">third</msg>
246 <msg xml:space="preserve">third</msg>
247 <paths>
247 <paths>
248 <path action="A">fourth</path>
248 <path action="A">fourth</path>
249 <path action="A">third</path>
249 <path action="A">third</path>
250 <path action="R">second</path>
250 <path action="R">second</path>
251 </paths>
251 </paths>
252 <copies>
252 <copies>
253 <copy source="second">fourth</copy>
253 <copy source="second">fourth</copy>
254 </copies>
254 </copies>
255 </logentry>
255 </logentry>
256 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
256 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
257 <parent revision="-1" node="0000000000000000000000000000000000000000" />
257 <parent revision="-1" node="0000000000000000000000000000000000000000" />
258 <author email="user@hostname">User Name</author>
258 <author email="user@hostname">User Name</author>
259 <date>1970-01-12T13:46:40+00:00</date>
259 <date>1970-01-12T13:46:40+00:00</date>
260 <msg xml:space="preserve">second</msg>
260 <msg xml:space="preserve">second</msg>
261 <paths>
261 <paths>
262 <path action="A">second</path>
262 <path action="A">second</path>
263 </paths>
263 </paths>
264 </logentry>
264 </logentry>
265 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
265 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
266 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
266 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
267 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
267 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
268 <author email="person">person</author>
268 <author email="person">person</author>
269 <date>1970-01-18T08:40:01+00:00</date>
269 <date>1970-01-18T08:40:01+00:00</date>
270 <msg xml:space="preserve">merge</msg>
270 <msg xml:space="preserve">merge</msg>
271 <paths>
271 <paths>
272 </paths>
272 </paths>
273 </logentry>
273 </logentry>
274 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
274 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
275 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
275 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
276 <author email="person">person</author>
276 <author email="person">person</author>
277 <date>1970-01-18T08:40:00+00:00</date>
277 <date>1970-01-18T08:40:00+00:00</date>
278 <msg xml:space="preserve">new head</msg>
278 <msg xml:space="preserve">new head</msg>
279 <paths>
279 <paths>
280 <path action="A">d</path>
280 <path action="A">d</path>
281 </paths>
281 </paths>
282 </logentry>
282 </logentry>
283 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
283 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
284 <branch>foo</branch>
284 <branch>foo</branch>
285 <author email="person">person</author>
285 <author email="person">person</author>
286 <date>1970-01-17T04:53:20+00:00</date>
286 <date>1970-01-17T04:53:20+00:00</date>
287 <msg xml:space="preserve">new branch</msg>
287 <msg xml:space="preserve">new branch</msg>
288 <paths>
288 <paths>
289 </paths>
289 </paths>
290 </logentry>
290 </logentry>
291 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
291 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
292 <author email="person">person</author>
292 <author email="person">person</author>
293 <date>1970-01-16T01:06:40+00:00</date>
293 <date>1970-01-16T01:06:40+00:00</date>
294 <msg xml:space="preserve">no user, no domain</msg>
294 <msg xml:space="preserve">no user, no domain</msg>
295 <paths>
295 <paths>
296 <path action="M">c</path>
296 <path action="M">c</path>
297 </paths>
297 </paths>
298 </logentry>
298 </logentry>
299 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
299 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
300 <author email="other@place">other</author>
300 <author email="other@place">other</author>
301 <date>1970-01-14T21:20:00+00:00</date>
301 <date>1970-01-14T21:20:00+00:00</date>
302 <msg xml:space="preserve">no person</msg>
302 <msg xml:space="preserve">no person</msg>
303 <paths>
303 <paths>
304 <path action="A">c</path>
304 <path action="A">c</path>
305 </paths>
305 </paths>
306 </logentry>
306 </logentry>
307 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
307 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
308 <author email="other@place">A. N. Other</author>
308 <author email="other@place">A. N. Other</author>
309 <date>1970-01-13T17:33:20+00:00</date>
309 <date>1970-01-13T17:33:20+00:00</date>
310 <msg xml:space="preserve">other 1
310 <msg xml:space="preserve">other 1
311 other 2
311 other 2
312
312
313 other 3</msg>
313 other 3</msg>
314 <paths>
314 <paths>
315 <path action="A">b</path>
315 <path action="A">b</path>
316 </paths>
316 </paths>
317 </logentry>
317 </logentry>
318 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
318 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
319 <author email="user@hostname">User Name</author>
319 <author email="user@hostname">User Name</author>
320 <date>1970-01-12T13:46:40+00:00</date>
320 <date>1970-01-12T13:46:40+00:00</date>
321 <msg xml:space="preserve">line 1
321 <msg xml:space="preserve">line 1
322 line 2</msg>
322 line 2</msg>
323 <paths>
323 <paths>
324 <path action="A">a</path>
324 <path action="A">a</path>
325 </paths>
325 </paths>
326 </logentry>
326 </logentry>
327 </log>
327 </log>
328
328
329 $ hg log --debug --style xml
329 $ hg log --debug --style xml
330 <?xml version="1.0"?>
330 <?xml version="1.0"?>
331 <log>
331 <log>
332 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
332 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
333 <tag>tip</tag>
333 <tag>tip</tag>
334 <parent revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453" />
334 <parent revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453" />
335 <parent revision="-1" node="0000000000000000000000000000000000000000" />
335 <parent revision="-1" node="0000000000000000000000000000000000000000" />
336 <author email="test">test</author>
336 <author email="test">test</author>
337 <date>2020-01-01T10:01:00+00:00</date>
337 <date>2020-01-01T10:01:00+00:00</date>
338 <msg xml:space="preserve">third</msg>
338 <msg xml:space="preserve">third</msg>
339 <paths>
339 <paths>
340 <path action="A">fourth</path>
340 <path action="A">fourth</path>
341 <path action="A">third</path>
341 <path action="A">third</path>
342 <path action="R">second</path>
342 <path action="R">second</path>
343 </paths>
343 </paths>
344 <copies>
344 <copies>
345 <copy source="second">fourth</copy>
345 <copy source="second">fourth</copy>
346 </copies>
346 </copies>
347 <extra key="branch">default</extra>
347 <extra key="branch">default</extra>
348 </logentry>
348 </logentry>
349 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
349 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
350 <parent revision="-1" node="0000000000000000000000000000000000000000" />
350 <parent revision="-1" node="0000000000000000000000000000000000000000" />
351 <parent revision="-1" node="0000000000000000000000000000000000000000" />
351 <parent revision="-1" node="0000000000000000000000000000000000000000" />
352 <author email="user@hostname">User Name</author>
352 <author email="user@hostname">User Name</author>
353 <date>1970-01-12T13:46:40+00:00</date>
353 <date>1970-01-12T13:46:40+00:00</date>
354 <msg xml:space="preserve">second</msg>
354 <msg xml:space="preserve">second</msg>
355 <paths>
355 <paths>
356 <path action="A">second</path>
356 <path action="A">second</path>
357 </paths>
357 </paths>
358 <extra key="branch">default</extra>
358 <extra key="branch">default</extra>
359 </logentry>
359 </logentry>
360 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
360 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
361 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
361 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
362 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
362 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
363 <author email="person">person</author>
363 <author email="person">person</author>
364 <date>1970-01-18T08:40:01+00:00</date>
364 <date>1970-01-18T08:40:01+00:00</date>
365 <msg xml:space="preserve">merge</msg>
365 <msg xml:space="preserve">merge</msg>
366 <paths>
366 <paths>
367 </paths>
367 </paths>
368 <extra key="branch">default</extra>
368 <extra key="branch">default</extra>
369 </logentry>
369 </logentry>
370 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
370 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
371 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
371 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
372 <parent revision="-1" node="0000000000000000000000000000000000000000" />
372 <parent revision="-1" node="0000000000000000000000000000000000000000" />
373 <author email="person">person</author>
373 <author email="person">person</author>
374 <date>1970-01-18T08:40:00+00:00</date>
374 <date>1970-01-18T08:40:00+00:00</date>
375 <msg xml:space="preserve">new head</msg>
375 <msg xml:space="preserve">new head</msg>
376 <paths>
376 <paths>
377 <path action="A">d</path>
377 <path action="A">d</path>
378 </paths>
378 </paths>
379 <extra key="branch">default</extra>
379 <extra key="branch">default</extra>
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 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
383 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
384 <parent revision="-1" node="0000000000000000000000000000000000000000" />
384 <parent revision="-1" node="0000000000000000000000000000000000000000" />
385 <author email="person">person</author>
385 <author email="person">person</author>
386 <date>1970-01-17T04:53:20+00:00</date>
386 <date>1970-01-17T04:53:20+00:00</date>
387 <msg xml:space="preserve">new branch</msg>
387 <msg xml:space="preserve">new branch</msg>
388 <paths>
388 <paths>
389 </paths>
389 </paths>
390 <extra key="branch">foo</extra>
390 <extra key="branch">foo</extra>
391 </logentry>
391 </logentry>
392 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
392 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
393 <parent revision="2" node="97054abb4ab824450e9164180baf491ae0078465" />
393 <parent revision="2" node="97054abb4ab824450e9164180baf491ae0078465" />
394 <parent revision="-1" node="0000000000000000000000000000000000000000" />
394 <parent revision="-1" node="0000000000000000000000000000000000000000" />
395 <author email="person">person</author>
395 <author email="person">person</author>
396 <date>1970-01-16T01:06:40+00:00</date>
396 <date>1970-01-16T01:06:40+00:00</date>
397 <msg xml:space="preserve">no user, no domain</msg>
397 <msg xml:space="preserve">no user, no domain</msg>
398 <paths>
398 <paths>
399 <path action="M">c</path>
399 <path action="M">c</path>
400 </paths>
400 </paths>
401 <extra key="branch">default</extra>
401 <extra key="branch">default</extra>
402 </logentry>
402 </logentry>
403 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
403 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
404 <parent revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965" />
404 <parent revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965" />
405 <parent revision="-1" node="0000000000000000000000000000000000000000" />
405 <parent revision="-1" node="0000000000000000000000000000000000000000" />
406 <author email="other@place">other</author>
406 <author email="other@place">other</author>
407 <date>1970-01-14T21:20:00+00:00</date>
407 <date>1970-01-14T21:20:00+00:00</date>
408 <msg xml:space="preserve">no person</msg>
408 <msg xml:space="preserve">no person</msg>
409 <paths>
409 <paths>
410 <path action="A">c</path>
410 <path action="A">c</path>
411 </paths>
411 </paths>
412 <extra key="branch">default</extra>
412 <extra key="branch">default</extra>
413 </logentry>
413 </logentry>
414 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
414 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
415 <parent revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f" />
415 <parent revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f" />
416 <parent revision="-1" node="0000000000000000000000000000000000000000" />
416 <parent revision="-1" node="0000000000000000000000000000000000000000" />
417 <author email="other@place">A. N. Other</author>
417 <author email="other@place">A. N. Other</author>
418 <date>1970-01-13T17:33:20+00:00</date>
418 <date>1970-01-13T17:33:20+00:00</date>
419 <msg xml:space="preserve">other 1
419 <msg xml:space="preserve">other 1
420 other 2
420 other 2
421
421
422 other 3</msg>
422 other 3</msg>
423 <paths>
423 <paths>
424 <path action="A">b</path>
424 <path action="A">b</path>
425 </paths>
425 </paths>
426 <extra key="branch">default</extra>
426 <extra key="branch">default</extra>
427 </logentry>
427 </logentry>
428 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
428 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
429 <parent revision="-1" node="0000000000000000000000000000000000000000" />
429 <parent revision="-1" node="0000000000000000000000000000000000000000" />
430 <parent revision="-1" node="0000000000000000000000000000000000000000" />
430 <parent revision="-1" node="0000000000000000000000000000000000000000" />
431 <author email="user@hostname">User Name</author>
431 <author email="user@hostname">User Name</author>
432 <date>1970-01-12T13:46:40+00:00</date>
432 <date>1970-01-12T13:46:40+00:00</date>
433 <msg xml:space="preserve">line 1
433 <msg xml:space="preserve">line 1
434 line 2</msg>
434 line 2</msg>
435 <paths>
435 <paths>
436 <path action="A">a</path>
436 <path action="A">a</path>
437 </paths>
437 </paths>
438 <extra key="branch">default</extra>
438 <extra key="branch">default</extra>
439 </logentry>
439 </logentry>
440 </log>
440 </log>
441
441
442
442
443 Error if style not readable:
443 Error if style not readable:
444
444
445 #if unix-permissions
445 #if unix-permissions
446 $ touch q
446 $ touch q
447 $ chmod 0 q
447 $ chmod 0 q
448 $ hg log --style ./q
448 $ hg log --style ./q
449 abort: Permission denied: ./q
449 abort: Permission denied: ./q
450 [255]
450 [255]
451 #endif
451 #endif
452
452
453 Error if no style:
453 Error if no style:
454
454
455 $ hg log --style notexist
455 $ hg log --style notexist
456 abort: style not found: notexist
456 abort: style not found: notexist
457 [255]
457 [255]
458
458
459 Error if style missing key:
459 Error if style missing key:
460
460
461 $ echo 'q = q' > t
461 $ echo 'q = q' > t
462 $ hg log --style ./t
462 $ hg log --style ./t
463 abort: "changeset" not in template map
463 abort: "changeset" not in template map
464 [255]
464 [255]
465
465
466 Error if style missing value:
466 Error if style missing value:
467
467
468 $ echo 'changeset =' > t
468 $ echo 'changeset =' > t
469 $ hg log --style t
469 $ hg log --style t
470 abort: t:1: missing value
470 abort: t:1: missing value
471 [255]
471 [255]
472
472
473 Error if include fails:
473 Error if include fails:
474
474
475 $ echo 'changeset = q' >> t
475 $ echo 'changeset = q' >> t
476 #if unix-permissions
476 #if unix-permissions
477 $ hg log --style ./t
477 $ hg log --style ./t
478 abort: template file ./q: Permission denied
478 abort: template file ./q: Permission denied
479 [255]
479 [255]
480 $ rm q
480 $ rm q
481 #endif
481 #endif
482
482
483 Include works:
483 Include works:
484
484
485 $ echo '{rev}' > q
485 $ echo '{rev}' > q
486 $ hg log --style ./t
486 $ hg log --style ./t
487 8
487 8
488 7
488 7
489 6
489 6
490 5
490 5
491 4
491 4
492 3
492 3
493 2
493 2
494 1
494 1
495 0
495 0
496
496
497 ui.style works:
497 ui.style works:
498
498
499 $ echo '[ui]' > .hg/hgrc
499 $ echo '[ui]' > .hg/hgrc
500 $ echo 'style = t' >> .hg/hgrc
500 $ echo 'style = t' >> .hg/hgrc
501 $ hg log
501 $ hg log
502 8
502 8
503 7
503 7
504 6
504 6
505 5
505 5
506 4
506 4
507 3
507 3
508 2
508 2
509 1
509 1
510 0
510 0
511
511
512
512
513 Issue338:
513 Issue338:
514
514
515 $ hg log --style=changelog > changelog
515 $ hg log --style=changelog > changelog
516
516
517 $ cat changelog
517 $ cat changelog
518 2020-01-01 test <test>
518 2020-01-01 test <test>
519
519
520 * fourth, second, third:
520 * fourth, second, third:
521 third
521 third
522 [95c24699272e] [tip]
522 [95c24699272e] [tip]
523
523
524 1970-01-12 User Name <user@hostname>
524 1970-01-12 User Name <user@hostname>
525
525
526 * second:
526 * second:
527 second
527 second
528 [29114dbae42b]
528 [29114dbae42b]
529
529
530 1970-01-18 person <person>
530 1970-01-18 person <person>
531
531
532 * merge
532 * merge
533 [d41e714fe50d]
533 [d41e714fe50d]
534
534
535 * d:
535 * d:
536 new head
536 new head
537 [13207e5a10d9]
537 [13207e5a10d9]
538
538
539 1970-01-17 person <person>
539 1970-01-17 person <person>
540
540
541 * new branch
541 * new branch
542 [bbe44766e73d] <foo>
542 [bbe44766e73d] <foo>
543
543
544 1970-01-16 person <person>
544 1970-01-16 person <person>
545
545
546 * c:
546 * c:
547 no user, no domain
547 no user, no domain
548 [10e46f2dcbf4]
548 [10e46f2dcbf4]
549
549
550 1970-01-14 other <other@place>
550 1970-01-14 other <other@place>
551
551
552 * c:
552 * c:
553 no person
553 no person
554 [97054abb4ab8]
554 [97054abb4ab8]
555
555
556 1970-01-13 A. N. Other <other@place>
556 1970-01-13 A. N. Other <other@place>
557
557
558 * b:
558 * b:
559 other 1 other 2
559 other 1 other 2
560
560
561 other 3
561 other 3
562 [b608e9d1a3f0]
562 [b608e9d1a3f0]
563
563
564 1970-01-12 User Name <user@hostname>
564 1970-01-12 User Name <user@hostname>
565
565
566 * a:
566 * a:
567 line 1 line 2
567 line 1 line 2
568 [1e4e1b8f71e0]
568 [1e4e1b8f71e0]
569
569
570
570
571 Issue2130: xml output for 'hg heads' is malformed
571 Issue2130: xml output for 'hg heads' is malformed
572
572
573 $ hg heads --style changelog
573 $ hg heads --style changelog
574 2020-01-01 test <test>
574 2020-01-01 test <test>
575
575
576 * fourth, second, third:
576 * fourth, second, third:
577 third
577 third
578 [95c24699272e] [tip]
578 [95c24699272e] [tip]
579
579
580 1970-01-18 person <person>
580 1970-01-18 person <person>
581
581
582 * merge
582 * merge
583 [d41e714fe50d]
583 [d41e714fe50d]
584
584
585 1970-01-17 person <person>
585 1970-01-17 person <person>
586
586
587 * new branch
587 * new branch
588 [bbe44766e73d] <foo>
588 [bbe44766e73d] <foo>
589
589
590
590
591 Keys work:
591 Keys work:
592
592
593 $ for key in author branch branches date desc file_adds file_dels file_mods \
593 $ for key in author branch branches date desc file_adds file_dels file_mods \
594 > file_copies file_copies_switch files \
594 > file_copies file_copies_switch files \
595 > manifest node parents rev tags diffstat extras \
595 > manifest node parents rev tags diffstat extras \
596 > p1rev p2rev p1node p2node; do
596 > p1rev p2rev p1node p2node; do
597 > for mode in '' --verbose --debug; do
597 > for mode in '' --verbose --debug; do
598 > hg log $mode --template "$key$mode: {$key}\n"
598 > hg log $mode --template "$key$mode: {$key}\n"
599 > done
599 > done
600 > done
600 > done
601 author: test
601 author: test
602 author: User Name <user@hostname>
602 author: User Name <user@hostname>
603 author: person
603 author: person
604 author: person
604 author: person
605 author: person
605 author: person
606 author: person
606 author: person
607 author: other@place
607 author: other@place
608 author: A. N. Other <other@place>
608 author: A. N. Other <other@place>
609 author: User Name <user@hostname>
609 author: User Name <user@hostname>
610 author--verbose: test
610 author--verbose: test
611 author--verbose: User Name <user@hostname>
611 author--verbose: User Name <user@hostname>
612 author--verbose: person
612 author--verbose: person
613 author--verbose: person
613 author--verbose: person
614 author--verbose: person
614 author--verbose: person
615 author--verbose: person
615 author--verbose: person
616 author--verbose: other@place
616 author--verbose: other@place
617 author--verbose: A. N. Other <other@place>
617 author--verbose: A. N. Other <other@place>
618 author--verbose: User Name <user@hostname>
618 author--verbose: User Name <user@hostname>
619 author--debug: test
619 author--debug: test
620 author--debug: User Name <user@hostname>
620 author--debug: User Name <user@hostname>
621 author--debug: person
621 author--debug: person
622 author--debug: person
622 author--debug: person
623 author--debug: person
623 author--debug: person
624 author--debug: person
624 author--debug: person
625 author--debug: other@place
625 author--debug: other@place
626 author--debug: A. N. Other <other@place>
626 author--debug: A. N. Other <other@place>
627 author--debug: User Name <user@hostname>
627 author--debug: User Name <user@hostname>
628 branch: default
628 branch: default
629 branch: default
629 branch: default
630 branch: default
630 branch: default
631 branch: default
631 branch: default
632 branch: foo
632 branch: foo
633 branch: default
633 branch: default
634 branch: default
634 branch: default
635 branch: default
635 branch: default
636 branch: default
636 branch: default
637 branch--verbose: default
637 branch--verbose: default
638 branch--verbose: default
638 branch--verbose: default
639 branch--verbose: default
639 branch--verbose: default
640 branch--verbose: default
640 branch--verbose: default
641 branch--verbose: foo
641 branch--verbose: foo
642 branch--verbose: default
642 branch--verbose: default
643 branch--verbose: default
643 branch--verbose: default
644 branch--verbose: default
644 branch--verbose: default
645 branch--verbose: default
645 branch--verbose: default
646 branch--debug: default
646 branch--debug: default
647 branch--debug: default
647 branch--debug: default
648 branch--debug: default
648 branch--debug: default
649 branch--debug: default
649 branch--debug: default
650 branch--debug: foo
650 branch--debug: foo
651 branch--debug: default
651 branch--debug: default
652 branch--debug: default
652 branch--debug: default
653 branch--debug: default
653 branch--debug: default
654 branch--debug: default
654 branch--debug: default
655 branches:
655 branches:
656 branches:
656 branches:
657 branches:
657 branches:
658 branches:
658 branches:
659 branches: foo
659 branches: foo
660 branches:
660 branches:
661 branches:
661 branches:
662 branches:
662 branches:
663 branches:
663 branches:
664 branches--verbose:
664 branches--verbose:
665 branches--verbose:
665 branches--verbose:
666 branches--verbose:
666 branches--verbose:
667 branches--verbose:
667 branches--verbose:
668 branches--verbose: foo
668 branches--verbose: foo
669 branches--verbose:
669 branches--verbose:
670 branches--verbose:
670 branches--verbose:
671 branches--verbose:
671 branches--verbose:
672 branches--verbose:
672 branches--verbose:
673 branches--debug:
673 branches--debug:
674 branches--debug:
674 branches--debug:
675 branches--debug:
675 branches--debug:
676 branches--debug:
676 branches--debug:
677 branches--debug: foo
677 branches--debug: foo
678 branches--debug:
678 branches--debug:
679 branches--debug:
679 branches--debug:
680 branches--debug:
680 branches--debug:
681 branches--debug:
681 branches--debug:
682 date: 1577872860.00
682 date: 1577872860.00
683 date: 1000000.00
683 date: 1000000.00
684 date: 1500001.00
684 date: 1500001.00
685 date: 1500000.00
685 date: 1500000.00
686 date: 1400000.00
686 date: 1400000.00
687 date: 1300000.00
687 date: 1300000.00
688 date: 1200000.00
688 date: 1200000.00
689 date: 1100000.00
689 date: 1100000.00
690 date: 1000000.00
690 date: 1000000.00
691 date--verbose: 1577872860.00
691 date--verbose: 1577872860.00
692 date--verbose: 1000000.00
692 date--verbose: 1000000.00
693 date--verbose: 1500001.00
693 date--verbose: 1500001.00
694 date--verbose: 1500000.00
694 date--verbose: 1500000.00
695 date--verbose: 1400000.00
695 date--verbose: 1400000.00
696 date--verbose: 1300000.00
696 date--verbose: 1300000.00
697 date--verbose: 1200000.00
697 date--verbose: 1200000.00
698 date--verbose: 1100000.00
698 date--verbose: 1100000.00
699 date--verbose: 1000000.00
699 date--verbose: 1000000.00
700 date--debug: 1577872860.00
700 date--debug: 1577872860.00
701 date--debug: 1000000.00
701 date--debug: 1000000.00
702 date--debug: 1500001.00
702 date--debug: 1500001.00
703 date--debug: 1500000.00
703 date--debug: 1500000.00
704 date--debug: 1400000.00
704 date--debug: 1400000.00
705 date--debug: 1300000.00
705 date--debug: 1300000.00
706 date--debug: 1200000.00
706 date--debug: 1200000.00
707 date--debug: 1100000.00
707 date--debug: 1100000.00
708 date--debug: 1000000.00
708 date--debug: 1000000.00
709 desc: third
709 desc: third
710 desc: second
710 desc: second
711 desc: merge
711 desc: merge
712 desc: new head
712 desc: new head
713 desc: new branch
713 desc: new branch
714 desc: no user, no domain
714 desc: no user, no domain
715 desc: no person
715 desc: no person
716 desc: other 1
716 desc: other 1
717 other 2
717 other 2
718
718
719 other 3
719 other 3
720 desc: line 1
720 desc: line 1
721 line 2
721 line 2
722 desc--verbose: third
722 desc--verbose: third
723 desc--verbose: second
723 desc--verbose: second
724 desc--verbose: merge
724 desc--verbose: merge
725 desc--verbose: new head
725 desc--verbose: new head
726 desc--verbose: new branch
726 desc--verbose: new branch
727 desc--verbose: no user, no domain
727 desc--verbose: no user, no domain
728 desc--verbose: no person
728 desc--verbose: no person
729 desc--verbose: other 1
729 desc--verbose: other 1
730 other 2
730 other 2
731
731
732 other 3
732 other 3
733 desc--verbose: line 1
733 desc--verbose: line 1
734 line 2
734 line 2
735 desc--debug: third
735 desc--debug: third
736 desc--debug: second
736 desc--debug: second
737 desc--debug: merge
737 desc--debug: merge
738 desc--debug: new head
738 desc--debug: new head
739 desc--debug: new branch
739 desc--debug: new branch
740 desc--debug: no user, no domain
740 desc--debug: no user, no domain
741 desc--debug: no person
741 desc--debug: no person
742 desc--debug: other 1
742 desc--debug: other 1
743 other 2
743 other 2
744
744
745 other 3
745 other 3
746 desc--debug: line 1
746 desc--debug: line 1
747 line 2
747 line 2
748 file_adds: fourth third
748 file_adds: fourth third
749 file_adds: second
749 file_adds: second
750 file_adds:
750 file_adds:
751 file_adds: d
751 file_adds: d
752 file_adds:
752 file_adds:
753 file_adds:
753 file_adds:
754 file_adds: c
754 file_adds: c
755 file_adds: b
755 file_adds: b
756 file_adds: a
756 file_adds: a
757 file_adds--verbose: fourth third
757 file_adds--verbose: fourth third
758 file_adds--verbose: second
758 file_adds--verbose: second
759 file_adds--verbose:
759 file_adds--verbose:
760 file_adds--verbose: d
760 file_adds--verbose: d
761 file_adds--verbose:
761 file_adds--verbose:
762 file_adds--verbose:
762 file_adds--verbose:
763 file_adds--verbose: c
763 file_adds--verbose: c
764 file_adds--verbose: b
764 file_adds--verbose: b
765 file_adds--verbose: a
765 file_adds--verbose: a
766 file_adds--debug: fourth third
766 file_adds--debug: fourth third
767 file_adds--debug: second
767 file_adds--debug: second
768 file_adds--debug:
768 file_adds--debug:
769 file_adds--debug: d
769 file_adds--debug: d
770 file_adds--debug:
770 file_adds--debug:
771 file_adds--debug:
771 file_adds--debug:
772 file_adds--debug: c
772 file_adds--debug: c
773 file_adds--debug: b
773 file_adds--debug: b
774 file_adds--debug: a
774 file_adds--debug: a
775 file_dels: second
775 file_dels: second
776 file_dels:
776 file_dels:
777 file_dels:
777 file_dels:
778 file_dels:
778 file_dels:
779 file_dels:
779 file_dels:
780 file_dels:
780 file_dels:
781 file_dels:
781 file_dels:
782 file_dels:
782 file_dels:
783 file_dels:
783 file_dels:
784 file_dels--verbose: second
784 file_dels--verbose: second
785 file_dels--verbose:
785 file_dels--verbose:
786 file_dels--verbose:
786 file_dels--verbose:
787 file_dels--verbose:
787 file_dels--verbose:
788 file_dels--verbose:
788 file_dels--verbose:
789 file_dels--verbose:
789 file_dels--verbose:
790 file_dels--verbose:
790 file_dels--verbose:
791 file_dels--verbose:
791 file_dels--verbose:
792 file_dels--verbose:
792 file_dels--verbose:
793 file_dels--debug: second
793 file_dels--debug: second
794 file_dels--debug:
794 file_dels--debug:
795 file_dels--debug:
795 file_dels--debug:
796 file_dels--debug:
796 file_dels--debug:
797 file_dels--debug:
797 file_dels--debug:
798 file_dels--debug:
798 file_dels--debug:
799 file_dels--debug:
799 file_dels--debug:
800 file_dels--debug:
800 file_dels--debug:
801 file_dels--debug:
801 file_dels--debug:
802 file_mods:
802 file_mods:
803 file_mods:
803 file_mods:
804 file_mods:
804 file_mods:
805 file_mods:
805 file_mods:
806 file_mods:
806 file_mods:
807 file_mods: c
807 file_mods: c
808 file_mods:
808 file_mods:
809 file_mods:
809 file_mods:
810 file_mods:
810 file_mods:
811 file_mods--verbose:
811 file_mods--verbose:
812 file_mods--verbose:
812 file_mods--verbose:
813 file_mods--verbose:
813 file_mods--verbose:
814 file_mods--verbose:
814 file_mods--verbose:
815 file_mods--verbose:
815 file_mods--verbose:
816 file_mods--verbose: c
816 file_mods--verbose: c
817 file_mods--verbose:
817 file_mods--verbose:
818 file_mods--verbose:
818 file_mods--verbose:
819 file_mods--verbose:
819 file_mods--verbose:
820 file_mods--debug:
820 file_mods--debug:
821 file_mods--debug:
821 file_mods--debug:
822 file_mods--debug:
822 file_mods--debug:
823 file_mods--debug:
823 file_mods--debug:
824 file_mods--debug:
824 file_mods--debug:
825 file_mods--debug: c
825 file_mods--debug: c
826 file_mods--debug:
826 file_mods--debug:
827 file_mods--debug:
827 file_mods--debug:
828 file_mods--debug:
828 file_mods--debug:
829 file_copies: fourth (second)
829 file_copies: fourth (second)
830 file_copies:
830 file_copies:
831 file_copies:
831 file_copies:
832 file_copies:
832 file_copies:
833 file_copies:
833 file_copies:
834 file_copies:
834 file_copies:
835 file_copies:
835 file_copies:
836 file_copies:
836 file_copies:
837 file_copies:
837 file_copies:
838 file_copies--verbose: fourth (second)
838 file_copies--verbose: fourth (second)
839 file_copies--verbose:
839 file_copies--verbose:
840 file_copies--verbose:
840 file_copies--verbose:
841 file_copies--verbose:
841 file_copies--verbose:
842 file_copies--verbose:
842 file_copies--verbose:
843 file_copies--verbose:
843 file_copies--verbose:
844 file_copies--verbose:
844 file_copies--verbose:
845 file_copies--verbose:
845 file_copies--verbose:
846 file_copies--verbose:
846 file_copies--verbose:
847 file_copies--debug: fourth (second)
847 file_copies--debug: fourth (second)
848 file_copies--debug:
848 file_copies--debug:
849 file_copies--debug:
849 file_copies--debug:
850 file_copies--debug:
850 file_copies--debug:
851 file_copies--debug:
851 file_copies--debug:
852 file_copies--debug:
852 file_copies--debug:
853 file_copies--debug:
853 file_copies--debug:
854 file_copies--debug:
854 file_copies--debug:
855 file_copies--debug:
855 file_copies--debug:
856 file_copies_switch:
856 file_copies_switch:
857 file_copies_switch:
857 file_copies_switch:
858 file_copies_switch:
858 file_copies_switch:
859 file_copies_switch:
859 file_copies_switch:
860 file_copies_switch:
860 file_copies_switch:
861 file_copies_switch:
861 file_copies_switch:
862 file_copies_switch:
862 file_copies_switch:
863 file_copies_switch:
863 file_copies_switch:
864 file_copies_switch:
864 file_copies_switch:
865 file_copies_switch--verbose:
865 file_copies_switch--verbose:
866 file_copies_switch--verbose:
866 file_copies_switch--verbose:
867 file_copies_switch--verbose:
867 file_copies_switch--verbose:
868 file_copies_switch--verbose:
868 file_copies_switch--verbose:
869 file_copies_switch--verbose:
869 file_copies_switch--verbose:
870 file_copies_switch--verbose:
870 file_copies_switch--verbose:
871 file_copies_switch--verbose:
871 file_copies_switch--verbose:
872 file_copies_switch--verbose:
872 file_copies_switch--verbose:
873 file_copies_switch--verbose:
873 file_copies_switch--verbose:
874 file_copies_switch--debug:
874 file_copies_switch--debug:
875 file_copies_switch--debug:
875 file_copies_switch--debug:
876 file_copies_switch--debug:
876 file_copies_switch--debug:
877 file_copies_switch--debug:
877 file_copies_switch--debug:
878 file_copies_switch--debug:
878 file_copies_switch--debug:
879 file_copies_switch--debug:
879 file_copies_switch--debug:
880 file_copies_switch--debug:
880 file_copies_switch--debug:
881 file_copies_switch--debug:
881 file_copies_switch--debug:
882 file_copies_switch--debug:
882 file_copies_switch--debug:
883 files: fourth second third
883 files: fourth second third
884 files: second
884 files: second
885 files:
885 files:
886 files: d
886 files: d
887 files:
887 files:
888 files: c
888 files: c
889 files: c
889 files: c
890 files: b
890 files: b
891 files: a
891 files: a
892 files--verbose: fourth second third
892 files--verbose: fourth second third
893 files--verbose: second
893 files--verbose: second
894 files--verbose:
894 files--verbose:
895 files--verbose: d
895 files--verbose: d
896 files--verbose:
896 files--verbose:
897 files--verbose: c
897 files--verbose: c
898 files--verbose: c
898 files--verbose: c
899 files--verbose: b
899 files--verbose: b
900 files--verbose: a
900 files--verbose: a
901 files--debug: fourth second third
901 files--debug: fourth second third
902 files--debug: second
902 files--debug: second
903 files--debug:
903 files--debug:
904 files--debug: d
904 files--debug: d
905 files--debug:
905 files--debug:
906 files--debug: c
906 files--debug: c
907 files--debug: c
907 files--debug: c
908 files--debug: b
908 files--debug: b
909 files--debug: a
909 files--debug: a
910 manifest: 6:94961b75a2da
910 manifest: 6:94961b75a2da
911 manifest: 5:f2dbc354b94e
911 manifest: 5:f2dbc354b94e
912 manifest: 4:4dc3def4f9b4
912 manifest: 4:4dc3def4f9b4
913 manifest: 4:4dc3def4f9b4
913 manifest: 4:4dc3def4f9b4
914 manifest: 3:cb5a1327723b
914 manifest: 3:cb5a1327723b
915 manifest: 3:cb5a1327723b
915 manifest: 3:cb5a1327723b
916 manifest: 2:6e0e82995c35
916 manifest: 2:6e0e82995c35
917 manifest: 1:4e8d705b1e53
917 manifest: 1:4e8d705b1e53
918 manifest: 0:a0c8bcbbb45c
918 manifest: 0:a0c8bcbbb45c
919 manifest--verbose: 6:94961b75a2da
919 manifest--verbose: 6:94961b75a2da
920 manifest--verbose: 5:f2dbc354b94e
920 manifest--verbose: 5:f2dbc354b94e
921 manifest--verbose: 4:4dc3def4f9b4
921 manifest--verbose: 4:4dc3def4f9b4
922 manifest--verbose: 4:4dc3def4f9b4
922 manifest--verbose: 4:4dc3def4f9b4
923 manifest--verbose: 3:cb5a1327723b
923 manifest--verbose: 3:cb5a1327723b
924 manifest--verbose: 3:cb5a1327723b
924 manifest--verbose: 3:cb5a1327723b
925 manifest--verbose: 2:6e0e82995c35
925 manifest--verbose: 2:6e0e82995c35
926 manifest--verbose: 1:4e8d705b1e53
926 manifest--verbose: 1:4e8d705b1e53
927 manifest--verbose: 0:a0c8bcbbb45c
927 manifest--verbose: 0:a0c8bcbbb45c
928 manifest--debug: 6:94961b75a2da554b4df6fb599e5bfc7d48de0c64
928 manifest--debug: 6:94961b75a2da554b4df6fb599e5bfc7d48de0c64
929 manifest--debug: 5:f2dbc354b94e5ec0b4f10680ee0cee816101d0bf
929 manifest--debug: 5:f2dbc354b94e5ec0b4f10680ee0cee816101d0bf
930 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
930 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
931 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
931 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
932 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
932 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
933 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
933 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
934 manifest--debug: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
934 manifest--debug: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
935 manifest--debug: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
935 manifest--debug: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
936 manifest--debug: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
936 manifest--debug: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
937 node: 95c24699272ef57d062b8bccc32c878bf841784a
937 node: 95c24699272ef57d062b8bccc32c878bf841784a
938 node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
938 node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
939 node: d41e714fe50d9e4a5f11b4d595d543481b5f980b
939 node: d41e714fe50d9e4a5f11b4d595d543481b5f980b
940 node: 13207e5a10d9fd28ec424934298e176197f2c67f
940 node: 13207e5a10d9fd28ec424934298e176197f2c67f
941 node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
941 node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
942 node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
942 node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
943 node: 97054abb4ab824450e9164180baf491ae0078465
943 node: 97054abb4ab824450e9164180baf491ae0078465
944 node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
944 node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
945 node: 1e4e1b8f71e05681d422154f5421e385fec3454f
945 node: 1e4e1b8f71e05681d422154f5421e385fec3454f
946 node--verbose: 95c24699272ef57d062b8bccc32c878bf841784a
946 node--verbose: 95c24699272ef57d062b8bccc32c878bf841784a
947 node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
947 node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
948 node--verbose: d41e714fe50d9e4a5f11b4d595d543481b5f980b
948 node--verbose: d41e714fe50d9e4a5f11b4d595d543481b5f980b
949 node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
949 node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
950 node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
950 node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
951 node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
951 node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
952 node--verbose: 97054abb4ab824450e9164180baf491ae0078465
952 node--verbose: 97054abb4ab824450e9164180baf491ae0078465
953 node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
953 node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
954 node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
954 node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
955 node--debug: 95c24699272ef57d062b8bccc32c878bf841784a
955 node--debug: 95c24699272ef57d062b8bccc32c878bf841784a
956 node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
956 node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
957 node--debug: d41e714fe50d9e4a5f11b4d595d543481b5f980b
957 node--debug: d41e714fe50d9e4a5f11b4d595d543481b5f980b
958 node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
958 node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
959 node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
959 node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
960 node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
960 node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
961 node--debug: 97054abb4ab824450e9164180baf491ae0078465
961 node--debug: 97054abb4ab824450e9164180baf491ae0078465
962 node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
962 node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
963 node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
963 node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
964 parents:
964 parents:
965 parents: -1:000000000000
965 parents: -1:000000000000
966 parents: 5:13207e5a10d9 4:bbe44766e73d
966 parents: 5:13207e5a10d9 4:bbe44766e73d
967 parents: 3:10e46f2dcbf4
967 parents: 3:10e46f2dcbf4
968 parents:
968 parents:
969 parents:
969 parents:
970 parents:
970 parents:
971 parents:
971 parents:
972 parents:
972 parents:
973 parents--verbose:
973 parents--verbose:
974 parents--verbose: -1:000000000000
974 parents--verbose: -1:000000000000
975 parents--verbose: 5:13207e5a10d9 4:bbe44766e73d
975 parents--verbose: 5:13207e5a10d9 4:bbe44766e73d
976 parents--verbose: 3:10e46f2dcbf4
976 parents--verbose: 3:10e46f2dcbf4
977 parents--verbose:
977 parents--verbose:
978 parents--verbose:
978 parents--verbose:
979 parents--verbose:
979 parents--verbose:
980 parents--verbose:
980 parents--verbose:
981 parents--verbose:
981 parents--verbose:
982 parents--debug: 7:29114dbae42b9f078cf2714dbe3a86bba8ec7453 -1:0000000000000000000000000000000000000000
982 parents--debug: 7:29114dbae42b9f078cf2714dbe3a86bba8ec7453 -1:0000000000000000000000000000000000000000
983 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
983 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
984 parents--debug: 5:13207e5a10d9fd28ec424934298e176197f2c67f 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
984 parents--debug: 5:13207e5a10d9fd28ec424934298e176197f2c67f 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
985 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
985 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
986 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
986 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
987 parents--debug: 2:97054abb4ab824450e9164180baf491ae0078465 -1:0000000000000000000000000000000000000000
987 parents--debug: 2:97054abb4ab824450e9164180baf491ae0078465 -1:0000000000000000000000000000000000000000
988 parents--debug: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965 -1:0000000000000000000000000000000000000000
988 parents--debug: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965 -1:0000000000000000000000000000000000000000
989 parents--debug: 0:1e4e1b8f71e05681d422154f5421e385fec3454f -1:0000000000000000000000000000000000000000
989 parents--debug: 0:1e4e1b8f71e05681d422154f5421e385fec3454f -1:0000000000000000000000000000000000000000
990 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
990 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
991 rev: 8
991 rev: 8
992 rev: 7
992 rev: 7
993 rev: 6
993 rev: 6
994 rev: 5
994 rev: 5
995 rev: 4
995 rev: 4
996 rev: 3
996 rev: 3
997 rev: 2
997 rev: 2
998 rev: 1
998 rev: 1
999 rev: 0
999 rev: 0
1000 rev--verbose: 8
1000 rev--verbose: 8
1001 rev--verbose: 7
1001 rev--verbose: 7
1002 rev--verbose: 6
1002 rev--verbose: 6
1003 rev--verbose: 5
1003 rev--verbose: 5
1004 rev--verbose: 4
1004 rev--verbose: 4
1005 rev--verbose: 3
1005 rev--verbose: 3
1006 rev--verbose: 2
1006 rev--verbose: 2
1007 rev--verbose: 1
1007 rev--verbose: 1
1008 rev--verbose: 0
1008 rev--verbose: 0
1009 rev--debug: 8
1009 rev--debug: 8
1010 rev--debug: 7
1010 rev--debug: 7
1011 rev--debug: 6
1011 rev--debug: 6
1012 rev--debug: 5
1012 rev--debug: 5
1013 rev--debug: 4
1013 rev--debug: 4
1014 rev--debug: 3
1014 rev--debug: 3
1015 rev--debug: 2
1015 rev--debug: 2
1016 rev--debug: 1
1016 rev--debug: 1
1017 rev--debug: 0
1017 rev--debug: 0
1018 tags: tip
1018 tags: tip
1019 tags:
1019 tags:
1020 tags:
1020 tags:
1021 tags:
1021 tags:
1022 tags:
1022 tags:
1023 tags:
1023 tags:
1024 tags:
1024 tags:
1025 tags:
1025 tags:
1026 tags:
1026 tags:
1027 tags--verbose: tip
1027 tags--verbose: tip
1028 tags--verbose:
1028 tags--verbose:
1029 tags--verbose:
1029 tags--verbose:
1030 tags--verbose:
1030 tags--verbose:
1031 tags--verbose:
1031 tags--verbose:
1032 tags--verbose:
1032 tags--verbose:
1033 tags--verbose:
1033 tags--verbose:
1034 tags--verbose:
1034 tags--verbose:
1035 tags--verbose:
1035 tags--verbose:
1036 tags--debug: tip
1036 tags--debug: tip
1037 tags--debug:
1037 tags--debug:
1038 tags--debug:
1038 tags--debug:
1039 tags--debug:
1039 tags--debug:
1040 tags--debug:
1040 tags--debug:
1041 tags--debug:
1041 tags--debug:
1042 tags--debug:
1042 tags--debug:
1043 tags--debug:
1043 tags--debug:
1044 tags--debug:
1044 tags--debug:
1045 diffstat: 3: +2/-1
1045 diffstat: 3: +2/-1
1046 diffstat: 1: +1/-0
1046 diffstat: 1: +1/-0
1047 diffstat: 0: +0/-0
1047 diffstat: 0: +0/-0
1048 diffstat: 1: +1/-0
1048 diffstat: 1: +1/-0
1049 diffstat: 0: +0/-0
1049 diffstat: 0: +0/-0
1050 diffstat: 1: +1/-0
1050 diffstat: 1: +1/-0
1051 diffstat: 1: +4/-0
1051 diffstat: 1: +4/-0
1052 diffstat: 1: +2/-0
1052 diffstat: 1: +2/-0
1053 diffstat: 1: +1/-0
1053 diffstat: 1: +1/-0
1054 diffstat--verbose: 3: +2/-1
1054 diffstat--verbose: 3: +2/-1
1055 diffstat--verbose: 1: +1/-0
1055 diffstat--verbose: 1: +1/-0
1056 diffstat--verbose: 0: +0/-0
1056 diffstat--verbose: 0: +0/-0
1057 diffstat--verbose: 1: +1/-0
1057 diffstat--verbose: 1: +1/-0
1058 diffstat--verbose: 0: +0/-0
1058 diffstat--verbose: 0: +0/-0
1059 diffstat--verbose: 1: +1/-0
1059 diffstat--verbose: 1: +1/-0
1060 diffstat--verbose: 1: +4/-0
1060 diffstat--verbose: 1: +4/-0
1061 diffstat--verbose: 1: +2/-0
1061 diffstat--verbose: 1: +2/-0
1062 diffstat--verbose: 1: +1/-0
1062 diffstat--verbose: 1: +1/-0
1063 diffstat--debug: 3: +2/-1
1063 diffstat--debug: 3: +2/-1
1064 diffstat--debug: 1: +1/-0
1064 diffstat--debug: 1: +1/-0
1065 diffstat--debug: 0: +0/-0
1065 diffstat--debug: 0: +0/-0
1066 diffstat--debug: 1: +1/-0
1066 diffstat--debug: 1: +1/-0
1067 diffstat--debug: 0: +0/-0
1067 diffstat--debug: 0: +0/-0
1068 diffstat--debug: 1: +1/-0
1068 diffstat--debug: 1: +1/-0
1069 diffstat--debug: 1: +4/-0
1069 diffstat--debug: 1: +4/-0
1070 diffstat--debug: 1: +2/-0
1070 diffstat--debug: 1: +2/-0
1071 diffstat--debug: 1: +1/-0
1071 diffstat--debug: 1: +1/-0
1072 extras: branch=default
1072 extras: branch=default
1073 extras: branch=default
1073 extras: branch=default
1074 extras: branch=default
1074 extras: branch=default
1075 extras: branch=default
1075 extras: branch=default
1076 extras: branch=foo
1076 extras: branch=foo
1077 extras: branch=default
1077 extras: branch=default
1078 extras: branch=default
1078 extras: branch=default
1079 extras: branch=default
1079 extras: branch=default
1080 extras: branch=default
1080 extras: branch=default
1081 extras--verbose: branch=default
1081 extras--verbose: branch=default
1082 extras--verbose: branch=default
1082 extras--verbose: branch=default
1083 extras--verbose: branch=default
1083 extras--verbose: branch=default
1084 extras--verbose: branch=default
1084 extras--verbose: branch=default
1085 extras--verbose: branch=foo
1085 extras--verbose: branch=foo
1086 extras--verbose: branch=default
1086 extras--verbose: branch=default
1087 extras--verbose: branch=default
1087 extras--verbose: branch=default
1088 extras--verbose: branch=default
1088 extras--verbose: branch=default
1089 extras--verbose: branch=default
1089 extras--verbose: branch=default
1090 extras--debug: branch=default
1090 extras--debug: branch=default
1091 extras--debug: branch=default
1091 extras--debug: branch=default
1092 extras--debug: branch=default
1092 extras--debug: branch=default
1093 extras--debug: branch=default
1093 extras--debug: branch=default
1094 extras--debug: branch=foo
1094 extras--debug: branch=foo
1095 extras--debug: branch=default
1095 extras--debug: branch=default
1096 extras--debug: branch=default
1096 extras--debug: branch=default
1097 extras--debug: branch=default
1097 extras--debug: branch=default
1098 extras--debug: branch=default
1098 extras--debug: branch=default
1099 p1rev: 7
1099 p1rev: 7
1100 p1rev: -1
1100 p1rev: -1
1101 p1rev: 5
1101 p1rev: 5
1102 p1rev: 3
1102 p1rev: 3
1103 p1rev: 3
1103 p1rev: 3
1104 p1rev: 2
1104 p1rev: 2
1105 p1rev: 1
1105 p1rev: 1
1106 p1rev: 0
1106 p1rev: 0
1107 p1rev: -1
1107 p1rev: -1
1108 p1rev--verbose: 7
1108 p1rev--verbose: 7
1109 p1rev--verbose: -1
1109 p1rev--verbose: -1
1110 p1rev--verbose: 5
1110 p1rev--verbose: 5
1111 p1rev--verbose: 3
1111 p1rev--verbose: 3
1112 p1rev--verbose: 3
1112 p1rev--verbose: 3
1113 p1rev--verbose: 2
1113 p1rev--verbose: 2
1114 p1rev--verbose: 1
1114 p1rev--verbose: 1
1115 p1rev--verbose: 0
1115 p1rev--verbose: 0
1116 p1rev--verbose: -1
1116 p1rev--verbose: -1
1117 p1rev--debug: 7
1117 p1rev--debug: 7
1118 p1rev--debug: -1
1118 p1rev--debug: -1
1119 p1rev--debug: 5
1119 p1rev--debug: 5
1120 p1rev--debug: 3
1120 p1rev--debug: 3
1121 p1rev--debug: 3
1121 p1rev--debug: 3
1122 p1rev--debug: 2
1122 p1rev--debug: 2
1123 p1rev--debug: 1
1123 p1rev--debug: 1
1124 p1rev--debug: 0
1124 p1rev--debug: 0
1125 p1rev--debug: -1
1125 p1rev--debug: -1
1126 p2rev: -1
1126 p2rev: -1
1127 p2rev: -1
1127 p2rev: -1
1128 p2rev: 4
1128 p2rev: 4
1129 p2rev: -1
1129 p2rev: -1
1130 p2rev: -1
1130 p2rev: -1
1131 p2rev: -1
1131 p2rev: -1
1132 p2rev: -1
1132 p2rev: -1
1133 p2rev: -1
1133 p2rev: -1
1134 p2rev: -1
1134 p2rev: -1
1135 p2rev--verbose: -1
1135 p2rev--verbose: -1
1136 p2rev--verbose: -1
1136 p2rev--verbose: -1
1137 p2rev--verbose: 4
1137 p2rev--verbose: 4
1138 p2rev--verbose: -1
1138 p2rev--verbose: -1
1139 p2rev--verbose: -1
1139 p2rev--verbose: -1
1140 p2rev--verbose: -1
1140 p2rev--verbose: -1
1141 p2rev--verbose: -1
1141 p2rev--verbose: -1
1142 p2rev--verbose: -1
1142 p2rev--verbose: -1
1143 p2rev--verbose: -1
1143 p2rev--verbose: -1
1144 p2rev--debug: -1
1144 p2rev--debug: -1
1145 p2rev--debug: -1
1145 p2rev--debug: -1
1146 p2rev--debug: 4
1146 p2rev--debug: 4
1147 p2rev--debug: -1
1147 p2rev--debug: -1
1148 p2rev--debug: -1
1148 p2rev--debug: -1
1149 p2rev--debug: -1
1149 p2rev--debug: -1
1150 p2rev--debug: -1
1150 p2rev--debug: -1
1151 p2rev--debug: -1
1151 p2rev--debug: -1
1152 p2rev--debug: -1
1152 p2rev--debug: -1
1153 p1node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1153 p1node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1154 p1node: 0000000000000000000000000000000000000000
1154 p1node: 0000000000000000000000000000000000000000
1155 p1node: 13207e5a10d9fd28ec424934298e176197f2c67f
1155 p1node: 13207e5a10d9fd28ec424934298e176197f2c67f
1156 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1156 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1157 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1157 p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1158 p1node: 97054abb4ab824450e9164180baf491ae0078465
1158 p1node: 97054abb4ab824450e9164180baf491ae0078465
1159 p1node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1159 p1node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1160 p1node: 1e4e1b8f71e05681d422154f5421e385fec3454f
1160 p1node: 1e4e1b8f71e05681d422154f5421e385fec3454f
1161 p1node: 0000000000000000000000000000000000000000
1161 p1node: 0000000000000000000000000000000000000000
1162 p1node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1162 p1node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1163 p1node--verbose: 0000000000000000000000000000000000000000
1163 p1node--verbose: 0000000000000000000000000000000000000000
1164 p1node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
1164 p1node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
1165 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1165 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1166 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1166 p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1167 p1node--verbose: 97054abb4ab824450e9164180baf491ae0078465
1167 p1node--verbose: 97054abb4ab824450e9164180baf491ae0078465
1168 p1node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1168 p1node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1169 p1node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
1169 p1node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
1170 p1node--verbose: 0000000000000000000000000000000000000000
1170 p1node--verbose: 0000000000000000000000000000000000000000
1171 p1node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1171 p1node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
1172 p1node--debug: 0000000000000000000000000000000000000000
1172 p1node--debug: 0000000000000000000000000000000000000000
1173 p1node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
1173 p1node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
1174 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1174 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1175 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1175 p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
1176 p1node--debug: 97054abb4ab824450e9164180baf491ae0078465
1176 p1node--debug: 97054abb4ab824450e9164180baf491ae0078465
1177 p1node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1177 p1node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
1178 p1node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
1178 p1node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
1179 p1node--debug: 0000000000000000000000000000000000000000
1179 p1node--debug: 0000000000000000000000000000000000000000
1180 p2node: 0000000000000000000000000000000000000000
1180 p2node: 0000000000000000000000000000000000000000
1181 p2node: 0000000000000000000000000000000000000000
1181 p2node: 0000000000000000000000000000000000000000
1182 p2node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1182 p2node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1183 p2node: 0000000000000000000000000000000000000000
1183 p2node: 0000000000000000000000000000000000000000
1184 p2node: 0000000000000000000000000000000000000000
1184 p2node: 0000000000000000000000000000000000000000
1185 p2node: 0000000000000000000000000000000000000000
1185 p2node: 0000000000000000000000000000000000000000
1186 p2node: 0000000000000000000000000000000000000000
1186 p2node: 0000000000000000000000000000000000000000
1187 p2node: 0000000000000000000000000000000000000000
1187 p2node: 0000000000000000000000000000000000000000
1188 p2node: 0000000000000000000000000000000000000000
1188 p2node: 0000000000000000000000000000000000000000
1189 p2node--verbose: 0000000000000000000000000000000000000000
1189 p2node--verbose: 0000000000000000000000000000000000000000
1190 p2node--verbose: 0000000000000000000000000000000000000000
1190 p2node--verbose: 0000000000000000000000000000000000000000
1191 p2node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1191 p2node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1192 p2node--verbose: 0000000000000000000000000000000000000000
1192 p2node--verbose: 0000000000000000000000000000000000000000
1193 p2node--verbose: 0000000000000000000000000000000000000000
1193 p2node--verbose: 0000000000000000000000000000000000000000
1194 p2node--verbose: 0000000000000000000000000000000000000000
1194 p2node--verbose: 0000000000000000000000000000000000000000
1195 p2node--verbose: 0000000000000000000000000000000000000000
1195 p2node--verbose: 0000000000000000000000000000000000000000
1196 p2node--verbose: 0000000000000000000000000000000000000000
1196 p2node--verbose: 0000000000000000000000000000000000000000
1197 p2node--verbose: 0000000000000000000000000000000000000000
1197 p2node--verbose: 0000000000000000000000000000000000000000
1198 p2node--debug: 0000000000000000000000000000000000000000
1198 p2node--debug: 0000000000000000000000000000000000000000
1199 p2node--debug: 0000000000000000000000000000000000000000
1199 p2node--debug: 0000000000000000000000000000000000000000
1200 p2node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1200 p2node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
1201 p2node--debug: 0000000000000000000000000000000000000000
1201 p2node--debug: 0000000000000000000000000000000000000000
1202 p2node--debug: 0000000000000000000000000000000000000000
1202 p2node--debug: 0000000000000000000000000000000000000000
1203 p2node--debug: 0000000000000000000000000000000000000000
1203 p2node--debug: 0000000000000000000000000000000000000000
1204 p2node--debug: 0000000000000000000000000000000000000000
1204 p2node--debug: 0000000000000000000000000000000000000000
1205 p2node--debug: 0000000000000000000000000000000000000000
1205 p2node--debug: 0000000000000000000000000000000000000000
1206 p2node--debug: 0000000000000000000000000000000000000000
1206 p2node--debug: 0000000000000000000000000000000000000000
1207
1207
1208 Filters work:
1208 Filters work:
1209
1209
1210 $ hg log --template '{author|domain}\n'
1210 $ hg log --template '{author|domain}\n'
1211
1211
1212 hostname
1212 hostname
1213
1213
1214
1214
1215
1215
1216
1216
1217 place
1217 place
1218 place
1218 place
1219 hostname
1219 hostname
1220
1220
1221 $ hg log --template '{author|person}\n'
1221 $ hg log --template '{author|person}\n'
1222 test
1222 test
1223 User Name
1223 User Name
1224 person
1224 person
1225 person
1225 person
1226 person
1226 person
1227 person
1227 person
1228 other
1228 other
1229 A. N. Other
1229 A. N. Other
1230 User Name
1230 User Name
1231
1231
1232 $ hg log --template '{author|user}\n'
1232 $ hg log --template '{author|user}\n'
1233 test
1233 test
1234 user
1234 user
1235 person
1235 person
1236 person
1236 person
1237 person
1237 person
1238 person
1238 person
1239 other
1239 other
1240 other
1240 other
1241 user
1241 user
1242
1242
1243 $ hg log --template '{date|date}\n'
1243 $ hg log --template '{date|date}\n'
1244 Wed Jan 01 10:01:00 2020 +0000
1244 Wed Jan 01 10:01:00 2020 +0000
1245 Mon Jan 12 13:46:40 1970 +0000
1245 Mon Jan 12 13:46:40 1970 +0000
1246 Sun Jan 18 08:40:01 1970 +0000
1246 Sun Jan 18 08:40:01 1970 +0000
1247 Sun Jan 18 08:40:00 1970 +0000
1247 Sun Jan 18 08:40:00 1970 +0000
1248 Sat Jan 17 04:53:20 1970 +0000
1248 Sat Jan 17 04:53:20 1970 +0000
1249 Fri Jan 16 01:06:40 1970 +0000
1249 Fri Jan 16 01:06:40 1970 +0000
1250 Wed Jan 14 21:20:00 1970 +0000
1250 Wed Jan 14 21:20:00 1970 +0000
1251 Tue Jan 13 17:33:20 1970 +0000
1251 Tue Jan 13 17:33:20 1970 +0000
1252 Mon Jan 12 13:46:40 1970 +0000
1252 Mon Jan 12 13:46:40 1970 +0000
1253
1253
1254 $ hg log --template '{date|isodate}\n'
1254 $ hg log --template '{date|isodate}\n'
1255 2020-01-01 10:01 +0000
1255 2020-01-01 10:01 +0000
1256 1970-01-12 13:46 +0000
1256 1970-01-12 13:46 +0000
1257 1970-01-18 08:40 +0000
1257 1970-01-18 08:40 +0000
1258 1970-01-18 08:40 +0000
1258 1970-01-18 08:40 +0000
1259 1970-01-17 04:53 +0000
1259 1970-01-17 04:53 +0000
1260 1970-01-16 01:06 +0000
1260 1970-01-16 01:06 +0000
1261 1970-01-14 21:20 +0000
1261 1970-01-14 21:20 +0000
1262 1970-01-13 17:33 +0000
1262 1970-01-13 17:33 +0000
1263 1970-01-12 13:46 +0000
1263 1970-01-12 13:46 +0000
1264
1264
1265 $ hg log --template '{date|isodatesec}\n'
1265 $ hg log --template '{date|isodatesec}\n'
1266 2020-01-01 10:01:00 +0000
1266 2020-01-01 10:01:00 +0000
1267 1970-01-12 13:46:40 +0000
1267 1970-01-12 13:46:40 +0000
1268 1970-01-18 08:40:01 +0000
1268 1970-01-18 08:40:01 +0000
1269 1970-01-18 08:40:00 +0000
1269 1970-01-18 08:40:00 +0000
1270 1970-01-17 04:53:20 +0000
1270 1970-01-17 04:53:20 +0000
1271 1970-01-16 01:06:40 +0000
1271 1970-01-16 01:06:40 +0000
1272 1970-01-14 21:20:00 +0000
1272 1970-01-14 21:20:00 +0000
1273 1970-01-13 17:33:20 +0000
1273 1970-01-13 17:33:20 +0000
1274 1970-01-12 13:46:40 +0000
1274 1970-01-12 13:46:40 +0000
1275
1275
1276 $ hg log --template '{date|rfc822date}\n'
1276 $ hg log --template '{date|rfc822date}\n'
1277 Wed, 01 Jan 2020 10:01:00 +0000
1277 Wed, 01 Jan 2020 10:01:00 +0000
1278 Mon, 12 Jan 1970 13:46:40 +0000
1278 Mon, 12 Jan 1970 13:46:40 +0000
1279 Sun, 18 Jan 1970 08:40:01 +0000
1279 Sun, 18 Jan 1970 08:40:01 +0000
1280 Sun, 18 Jan 1970 08:40:00 +0000
1280 Sun, 18 Jan 1970 08:40:00 +0000
1281 Sat, 17 Jan 1970 04:53:20 +0000
1281 Sat, 17 Jan 1970 04:53:20 +0000
1282 Fri, 16 Jan 1970 01:06:40 +0000
1282 Fri, 16 Jan 1970 01:06:40 +0000
1283 Wed, 14 Jan 1970 21:20:00 +0000
1283 Wed, 14 Jan 1970 21:20:00 +0000
1284 Tue, 13 Jan 1970 17:33:20 +0000
1284 Tue, 13 Jan 1970 17:33:20 +0000
1285 Mon, 12 Jan 1970 13:46:40 +0000
1285 Mon, 12 Jan 1970 13:46:40 +0000
1286
1286
1287 $ hg log --template '{desc|firstline}\n'
1287 $ hg log --template '{desc|firstline}\n'
1288 third
1288 third
1289 second
1289 second
1290 merge
1290 merge
1291 new head
1291 new head
1292 new branch
1292 new branch
1293 no user, no domain
1293 no user, no domain
1294 no person
1294 no person
1295 other 1
1295 other 1
1296 line 1
1296 line 1
1297
1297
1298 $ hg log --template '{node|short}\n'
1298 $ hg log --template '{node|short}\n'
1299 95c24699272e
1299 95c24699272e
1300 29114dbae42b
1300 29114dbae42b
1301 d41e714fe50d
1301 d41e714fe50d
1302 13207e5a10d9
1302 13207e5a10d9
1303 bbe44766e73d
1303 bbe44766e73d
1304 10e46f2dcbf4
1304 10e46f2dcbf4
1305 97054abb4ab8
1305 97054abb4ab8
1306 b608e9d1a3f0
1306 b608e9d1a3f0
1307 1e4e1b8f71e0
1307 1e4e1b8f71e0
1308
1308
1309 $ hg log --template '<changeset author="{author|xmlescape}"/>\n'
1309 $ hg log --template '<changeset author="{author|xmlescape}"/>\n'
1310 <changeset author="test"/>
1310 <changeset author="test"/>
1311 <changeset author="User Name &lt;user@hostname&gt;"/>
1311 <changeset author="User Name &lt;user@hostname&gt;"/>
1312 <changeset author="person"/>
1312 <changeset author="person"/>
1313 <changeset author="person"/>
1313 <changeset author="person"/>
1314 <changeset author="person"/>
1314 <changeset author="person"/>
1315 <changeset author="person"/>
1315 <changeset author="person"/>
1316 <changeset author="other@place"/>
1316 <changeset author="other@place"/>
1317 <changeset author="A. N. Other &lt;other@place&gt;"/>
1317 <changeset author="A. N. Other &lt;other@place&gt;"/>
1318 <changeset author="User Name &lt;user@hostname&gt;"/>
1318 <changeset author="User Name &lt;user@hostname&gt;"/>
1319
1319
1320 $ hg log --template '{rev}: {children}\n'
1320 $ hg log --template '{rev}: {children}\n'
1321 8:
1321 8:
1322 7: 8:95c24699272e
1322 7: 8:95c24699272e
1323 6:
1323 6:
1324 5: 6:d41e714fe50d
1324 5: 6:d41e714fe50d
1325 4: 6:d41e714fe50d
1325 4: 6:d41e714fe50d
1326 3: 4:bbe44766e73d 5:13207e5a10d9
1326 3: 4:bbe44766e73d 5:13207e5a10d9
1327 2: 3:10e46f2dcbf4
1327 2: 3:10e46f2dcbf4
1328 1: 2:97054abb4ab8
1328 1: 2:97054abb4ab8
1329 0: 1:b608e9d1a3f0
1329 0: 1:b608e9d1a3f0
1330
1330
1331 Formatnode filter works:
1331 Formatnode filter works:
1332
1332
1333 $ hg -q log -r 0 --template '{node|formatnode}\n'
1333 $ hg -q log -r 0 --template '{node|formatnode}\n'
1334 1e4e1b8f71e0
1334 1e4e1b8f71e0
1335
1335
1336 $ hg log -r 0 --template '{node|formatnode}\n'
1336 $ hg log -r 0 --template '{node|formatnode}\n'
1337 1e4e1b8f71e0
1337 1e4e1b8f71e0
1338
1338
1339 $ hg -v log -r 0 --template '{node|formatnode}\n'
1339 $ hg -v log -r 0 --template '{node|formatnode}\n'
1340 1e4e1b8f71e0
1340 1e4e1b8f71e0
1341
1341
1342 $ hg --debug log -r 0 --template '{node|formatnode}\n'
1342 $ hg --debug log -r 0 --template '{node|formatnode}\n'
1343 1e4e1b8f71e05681d422154f5421e385fec3454f
1343 1e4e1b8f71e05681d422154f5421e385fec3454f
1344
1344
1345 Age filter:
1345 Age filter:
1346
1346
1347 $ hg log --template '{date|age}\n' > /dev/null || exit 1
1347 $ hg log --template '{date|age}\n' > /dev/null || exit 1
1348
1348
1349 >>> from datetime import datetime
1349 >>> from datetime import datetime, timedelta
1350 >>> fp = open('a', 'w')
1350 >>> fp = open('a', 'w')
1351 >>> n = datetime.now()
1351 >>> n = datetime.now() + timedelta(366 * 7)
1352 >>> fp.write('%d-%d-%d 00:00' % ((n.year + 7), n.month, n.day))
1352 >>> fp.write('%d-%d-%d 00:00' % (n.year, n.month, n.day))
1353 >>> fp.close()
1353 >>> fp.close()
1354 $ hg add a
1354 $ hg add a
1355 $ hg commit -m future -d "`cat a`"
1355 $ hg commit -m future -d "`cat a`"
1356
1356
1357 $ hg log -l1 --template '{date|age}\n'
1357 $ hg log -l1 --template '{date|age}\n'
1358 7 years from now
1358 7 years from now
1359
1359
1360 Error on syntax:
1360 Error on syntax:
1361
1361
1362 $ echo 'x = "f' >> t
1362 $ echo 'x = "f' >> t
1363 $ hg log
1363 $ hg log
1364 abort: t:3: unmatched quotes
1364 abort: t:3: unmatched quotes
1365 [255]
1365 [255]
1366
1366
1367 Behind the scenes, this will throw TypeError
1367 Behind the scenes, this will throw TypeError
1368
1368
1369 $ hg log -l 3 --template '{date|obfuscate}\n'
1369 $ hg log -l 3 --template '{date|obfuscate}\n'
1370 abort: template filter 'obfuscate' is not compatible with keyword 'date'
1370 abort: template filter 'obfuscate' is not compatible with keyword 'date'
1371 [255]
1371 [255]
1372
1372
1373 Behind the scenes, this will throw a ValueError
1373 Behind the scenes, this will throw a ValueError
1374
1374
1375 $ hg log -l 3 --template 'line: {desc|shortdate}\n'
1375 $ hg log -l 3 --template 'line: {desc|shortdate}\n'
1376 abort: template filter 'shortdate' is not compatible with keyword 'desc'
1376 abort: template filter 'shortdate' is not compatible with keyword 'desc'
1377 [255]
1377 [255]
1378
1378
1379 Behind the scenes, this will throw AttributeError
1379 Behind the scenes, this will throw AttributeError
1380
1380
1381 $ hg log -l 3 --template 'line: {date|escape}\n'
1381 $ hg log -l 3 --template 'line: {date|escape}\n'
1382 abort: template filter 'escape' is not compatible with keyword 'date'
1382 abort: template filter 'escape' is not compatible with keyword 'date'
1383 [255]
1383 [255]
1384
1384
1385 Behind the scenes, this will throw ValueError
1385 Behind the scenes, this will throw ValueError
1386
1386
1387 $ hg tip --template '{author|email|date}\n'
1387 $ hg tip --template '{author|email|date}\n'
1388 abort: template filter 'datefilter' is not compatible with keyword 'author'
1388 abort: template filter 'datefilter' is not compatible with keyword 'author'
1389 [255]
1389 [255]
1390
1390
1391 $ cd ..
1391 $ cd ..
1392
1392
1393
1393
1394 latesttag:
1394 latesttag:
1395
1395
1396 $ hg init latesttag
1396 $ hg init latesttag
1397 $ cd latesttag
1397 $ cd latesttag
1398
1398
1399 $ echo a > file
1399 $ echo a > file
1400 $ hg ci -Am a -d '0 0'
1400 $ hg ci -Am a -d '0 0'
1401 adding file
1401 adding file
1402
1402
1403 $ echo b >> file
1403 $ echo b >> file
1404 $ hg ci -m b -d '1 0'
1404 $ hg ci -m b -d '1 0'
1405
1405
1406 $ echo c >> head1
1406 $ echo c >> head1
1407 $ hg ci -Am h1c -d '2 0'
1407 $ hg ci -Am h1c -d '2 0'
1408 adding head1
1408 adding head1
1409
1409
1410 $ hg update -q 1
1410 $ hg update -q 1
1411 $ echo d >> head2
1411 $ echo d >> head2
1412 $ hg ci -Am h2d -d '3 0'
1412 $ hg ci -Am h2d -d '3 0'
1413 adding head2
1413 adding head2
1414 created new head
1414 created new head
1415
1415
1416 $ echo e >> head2
1416 $ echo e >> head2
1417 $ hg ci -m h2e -d '4 0'
1417 $ hg ci -m h2e -d '4 0'
1418
1418
1419 $ hg merge -q
1419 $ hg merge -q
1420 $ hg ci -m merge -d '5 0'
1420 $ hg ci -m merge -d '5 0'
1421
1421
1422 No tag set:
1422 No tag set:
1423
1423
1424 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1424 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1425 5: null+5
1425 5: null+5
1426 4: null+4
1426 4: null+4
1427 3: null+3
1427 3: null+3
1428 2: null+3
1428 2: null+3
1429 1: null+2
1429 1: null+2
1430 0: null+1
1430 0: null+1
1431
1431
1432 One common tag: longuest path wins:
1432 One common tag: longuest path wins:
1433
1433
1434 $ hg tag -r 1 -m t1 -d '6 0' t1
1434 $ hg tag -r 1 -m t1 -d '6 0' t1
1435 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1435 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1436 6: t1+4
1436 6: t1+4
1437 5: t1+3
1437 5: t1+3
1438 4: t1+2
1438 4: t1+2
1439 3: t1+1
1439 3: t1+1
1440 2: t1+1
1440 2: t1+1
1441 1: t1+0
1441 1: t1+0
1442 0: null+1
1442 0: null+1
1443
1443
1444 One ancestor tag: more recent wins:
1444 One ancestor tag: more recent wins:
1445
1445
1446 $ hg tag -r 2 -m t2 -d '7 0' t2
1446 $ hg tag -r 2 -m t2 -d '7 0' t2
1447 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1447 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1448 7: t2+3
1448 7: t2+3
1449 6: t2+2
1449 6: t2+2
1450 5: t2+1
1450 5: t2+1
1451 4: t1+2
1451 4: t1+2
1452 3: t1+1
1452 3: t1+1
1453 2: t2+0
1453 2: t2+0
1454 1: t1+0
1454 1: t1+0
1455 0: null+1
1455 0: null+1
1456
1456
1457 Two branch tags: more recent wins:
1457 Two branch tags: more recent wins:
1458
1458
1459 $ hg tag -r 3 -m t3 -d '8 0' t3
1459 $ hg tag -r 3 -m t3 -d '8 0' t3
1460 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1460 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1461 8: t3+5
1461 8: t3+5
1462 7: t3+4
1462 7: t3+4
1463 6: t3+3
1463 6: t3+3
1464 5: t3+2
1464 5: t3+2
1465 4: t3+1
1465 4: t3+1
1466 3: t3+0
1466 3: t3+0
1467 2: t2+0
1467 2: t2+0
1468 1: t1+0
1468 1: t1+0
1469 0: null+1
1469 0: null+1
1470
1470
1471 Merged tag overrides:
1471 Merged tag overrides:
1472
1472
1473 $ hg tag -r 5 -m t5 -d '9 0' t5
1473 $ hg tag -r 5 -m t5 -d '9 0' t5
1474 $ hg tag -r 3 -m at3 -d '10 0' at3
1474 $ hg tag -r 3 -m at3 -d '10 0' at3
1475 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1475 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1476 10: t5+5
1476 10: t5+5
1477 9: t5+4
1477 9: t5+4
1478 8: t5+3
1478 8: t5+3
1479 7: t5+2
1479 7: t5+2
1480 6: t5+1
1480 6: t5+1
1481 5: t5+0
1481 5: t5+0
1482 4: at3:t3+1
1482 4: at3:t3+1
1483 3: at3:t3+0
1483 3: at3:t3+0
1484 2: t2+0
1484 2: t2+0
1485 1: t1+0
1485 1: t1+0
1486 0: null+1
1486 0: null+1
1487
1487
1488 $ cd ..
1488 $ cd ..
1489
1489
1490
1490
1491 Style path expansion: issue1948 - ui.style option doesn't work on OSX
1491 Style path expansion: issue1948 - ui.style option doesn't work on OSX
1492 if it is a relative path
1492 if it is a relative path
1493
1493
1494 $ mkdir -p home/styles
1494 $ mkdir -p home/styles
1495
1495
1496 $ cat > home/styles/teststyle <<EOF
1496 $ cat > home/styles/teststyle <<EOF
1497 > changeset = 'test {rev}:{node|short}\n'
1497 > changeset = 'test {rev}:{node|short}\n'
1498 > EOF
1498 > EOF
1499
1499
1500 $ HOME=`pwd`/home; export HOME
1500 $ HOME=`pwd`/home; export HOME
1501
1501
1502 $ cat > latesttag/.hg/hgrc <<EOF
1502 $ cat > latesttag/.hg/hgrc <<EOF
1503 > [ui]
1503 > [ui]
1504 > style = ~/styles/teststyle
1504 > style = ~/styles/teststyle
1505 > EOF
1505 > EOF
1506
1506
1507 $ hg -R latesttag tip
1507 $ hg -R latesttag tip
1508 test 10:dee8f28249af
1508 test 10:dee8f28249af
1509
1509
1510 Test recursive showlist template (issue1989):
1510 Test recursive showlist template (issue1989):
1511
1511
1512 $ cat > style1989 <<EOF
1512 $ cat > style1989 <<EOF
1513 > changeset = '{file_mods}{manifest}{extras}'
1513 > changeset = '{file_mods}{manifest}{extras}'
1514 > file_mod = 'M|{author|person}\n'
1514 > file_mod = 'M|{author|person}\n'
1515 > manifest = '{rev},{author}\n'
1515 > manifest = '{rev},{author}\n'
1516 > extra = '{key}: {author}\n'
1516 > extra = '{key}: {author}\n'
1517 > EOF
1517 > EOF
1518
1518
1519 $ hg -R latesttag log -r tip --style=style1989
1519 $ hg -R latesttag log -r tip --style=style1989
1520 M|test
1520 M|test
1521 10,test
1521 10,test
1522 branch: test
1522 branch: test
1523
1523
1524 Test new-style inline templating:
1524 Test new-style inline templating:
1525
1525
1526 $ hg log -R latesttag -r tip --template 'modified files: {file_mods % " {file}\n"}\n'
1526 $ hg log -R latesttag -r tip --template 'modified files: {file_mods % " {file}\n"}\n'
1527 modified files: .hgtags
1527 modified files: .hgtags
1528
1528
@@ -1,561 +1,571 b''
1 Test basic extension support
1 Test basic extension support
2
2
3 $ cat > foobar.py <<EOF
3 $ cat > foobar.py <<EOF
4 > import os
4 > import os
5 > from mercurial import commands
5 > from mercurial import commands
6 >
6 >
7 > def uisetup(ui):
7 > def uisetup(ui):
8 > ui.write("uisetup called\\n")
8 > ui.write("uisetup called\\n")
9 >
9 >
10 > def reposetup(ui, repo):
10 > def reposetup(ui, repo):
11 > ui.write("reposetup called for %s\\n" % os.path.basename(repo.root))
11 > ui.write("reposetup called for %s\\n" % os.path.basename(repo.root))
12 > ui.write("ui %s= repo.ui\\n" % (ui == repo.ui and "=" or "!"))
12 > ui.write("ui %s= repo.ui\\n" % (ui == repo.ui and "=" or "!"))
13 >
13 >
14 > def foo(ui, *args, **kwargs):
14 > def foo(ui, *args, **kwargs):
15 > ui.write("Foo\\n")
15 > ui.write("Foo\\n")
16 >
16 >
17 > def bar(ui, *args, **kwargs):
17 > def bar(ui, *args, **kwargs):
18 > ui.write("Bar\\n")
18 > ui.write("Bar\\n")
19 >
19 >
20 > cmdtable = {
20 > cmdtable = {
21 > "foo": (foo, [], "hg foo"),
21 > "foo": (foo, [], "hg foo"),
22 > "bar": (bar, [], "hg bar"),
22 > "bar": (bar, [], "hg bar"),
23 > }
23 > }
24 >
24 >
25 > commands.norepo += ' bar'
25 > commands.norepo += ' bar'
26 > EOF
26 > EOF
27 $ abspath=`pwd`/foobar.py
27 $ abspath=`pwd`/foobar.py
28
28
29 $ mkdir barfoo
29 $ mkdir barfoo
30 $ cp foobar.py barfoo/__init__.py
30 $ cp foobar.py barfoo/__init__.py
31 $ barfoopath=`pwd`/barfoo
31 $ barfoopath=`pwd`/barfoo
32
32
33 $ hg init a
33 $ hg init a
34 $ cd a
34 $ cd a
35 $ echo foo > file
35 $ echo foo > file
36 $ hg add file
36 $ hg add file
37 $ hg commit -m 'add file'
37 $ hg commit -m 'add file'
38
38
39 $ echo '[extensions]' >> $HGRCPATH
39 $ echo '[extensions]' >> $HGRCPATH
40 $ echo "foobar = $abspath" >> $HGRCPATH
40 $ echo "foobar = $abspath" >> $HGRCPATH
41 $ hg foo
41 $ hg foo
42 uisetup called
42 uisetup called
43 reposetup called for a
43 reposetup called for a
44 ui == repo.ui
44 ui == repo.ui
45 Foo
45 Foo
46
46
47 $ cd ..
47 $ cd ..
48 $ hg clone a b
48 $ hg clone a b
49 uisetup called
49 uisetup called
50 reposetup called for a
50 reposetup called for a
51 ui == repo.ui
51 ui == repo.ui
52 reposetup called for b
52 reposetup called for b
53 ui == repo.ui
53 ui == repo.ui
54 updating to branch default
54 updating to branch default
55 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
55 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
56
56
57 $ hg bar
57 $ hg bar
58 uisetup called
58 uisetup called
59 Bar
59 Bar
60 $ echo 'foobar = !' >> $HGRCPATH
60 $ echo 'foobar = !' >> $HGRCPATH
61
61
62 module/__init__.py-style
62 module/__init__.py-style
63
63
64 $ echo "barfoo = $barfoopath" >> $HGRCPATH
64 $ echo "barfoo = $barfoopath" >> $HGRCPATH
65 $ cd a
65 $ cd a
66 $ hg foo
66 $ hg foo
67 uisetup called
67 uisetup called
68 reposetup called for a
68 reposetup called for a
69 ui == repo.ui
69 ui == repo.ui
70 Foo
70 Foo
71 $ echo 'barfoo = !' >> $HGRCPATH
71 $ echo 'barfoo = !' >> $HGRCPATH
72
72
73 Check that extensions are loaded in phases:
73 Check that extensions are loaded in phases:
74
74
75 $ cat > foo.py <<EOF
75 $ cat > foo.py <<EOF
76 > import os
76 > import os
77 > name = os.path.basename(__file__).rsplit('.', 1)[0]
77 > name = os.path.basename(__file__).rsplit('.', 1)[0]
78 > print "1) %s imported" % name
78 > print "1) %s imported" % name
79 > def uisetup(ui):
79 > def uisetup(ui):
80 > print "2) %s uisetup" % name
80 > print "2) %s uisetup" % name
81 > def extsetup():
81 > def extsetup():
82 > print "3) %s extsetup" % name
82 > print "3) %s extsetup" % name
83 > def reposetup(ui, repo):
83 > def reposetup(ui, repo):
84 > print "4) %s reposetup" % name
84 > print "4) %s reposetup" % name
85 > EOF
85 > EOF
86
86
87 $ cp foo.py bar.py
87 $ cp foo.py bar.py
88 $ echo 'foo = foo.py' >> $HGRCPATH
88 $ echo 'foo = foo.py' >> $HGRCPATH
89 $ echo 'bar = bar.py' >> $HGRCPATH
89 $ echo 'bar = bar.py' >> $HGRCPATH
90
90
91 Command with no output, we just want to see the extensions loaded:
91 Command with no output, we just want to see the extensions loaded:
92
92
93 $ hg paths
93 $ hg paths
94 1) foo imported
94 1) foo imported
95 1) bar imported
95 1) bar imported
96 2) foo uisetup
96 2) foo uisetup
97 2) bar uisetup
97 2) bar uisetup
98 3) foo extsetup
98 3) foo extsetup
99 3) bar extsetup
99 3) bar extsetup
100 4) foo reposetup
100 4) foo reposetup
101 4) bar reposetup
101 4) bar reposetup
102
102
103 Check hgweb's load order:
103 Check hgweb's load order:
104
104
105 $ cat > hgweb.cgi <<EOF
105 $ cat > hgweb.cgi <<EOF
106 > #!/usr/bin/env python
106 > #!/usr/bin/env python
107 > from mercurial import demandimport; demandimport.enable()
107 > from mercurial import demandimport; demandimport.enable()
108 > from mercurial.hgweb import hgweb
108 > from mercurial.hgweb import hgweb
109 > from mercurial.hgweb import wsgicgi
109 > from mercurial.hgweb import wsgicgi
110 >
110 >
111 > application = hgweb('.', 'test repo')
111 > application = hgweb('.', 'test repo')
112 > wsgicgi.launch(application)
112 > wsgicgi.launch(application)
113 > EOF
113 > EOF
114
114
115 $ SCRIPT_NAME='/' SERVER_PORT='80' SERVER_NAME='localhost' python hgweb.cgi \
115 $ SCRIPT_NAME='/' SERVER_PORT='80' SERVER_NAME='localhost' python hgweb.cgi \
116 > | grep '^[0-9]) ' # ignores HTML output
116 > | grep '^[0-9]) ' # ignores HTML output
117 1) foo imported
117 1) foo imported
118 1) bar imported
118 1) bar imported
119 2) foo uisetup
119 2) foo uisetup
120 2) bar uisetup
120 2) bar uisetup
121 3) foo extsetup
121 3) foo extsetup
122 3) bar extsetup
122 3) bar extsetup
123 4) foo reposetup
123 4) foo reposetup
124 4) bar reposetup
124 4) bar reposetup
125 4) foo reposetup
125 4) foo reposetup
126 4) bar reposetup
126 4) bar reposetup
127
127
128 $ echo 'foo = !' >> $HGRCPATH
128 $ echo 'foo = !' >> $HGRCPATH
129 $ echo 'bar = !' >> $HGRCPATH
129 $ echo 'bar = !' >> $HGRCPATH
130
130
131 $ cd ..
131 $ cd ..
132
132
133 hide outer repo
133 hide outer repo
134 $ hg init
134 $ hg init
135
135
136 $ cat > empty.py <<EOF
136 $ cat > empty.py <<EOF
137 > '''empty cmdtable
137 > '''empty cmdtable
138 > '''
138 > '''
139 > cmdtable = {}
139 > cmdtable = {}
140 > EOF
140 > EOF
141 $ emptypath=`pwd`/empty.py
141 $ emptypath=`pwd`/empty.py
142 $ echo "empty = $emptypath" >> $HGRCPATH
142 $ echo "empty = $emptypath" >> $HGRCPATH
143 $ hg help empty
143 $ hg help empty
144 empty extension - empty cmdtable
144 empty extension - empty cmdtable
145
145
146 no commands defined
146 no commands defined
147
147
148 $ echo 'empty = !' >> $HGRCPATH
148 $ echo 'empty = !' >> $HGRCPATH
149
149
150 $ cat > debugextension.py <<EOF
150 $ cat > debugextension.py <<EOF
151 > '''only debugcommands
151 > '''only debugcommands
152 > '''
152 > '''
153 > def debugfoobar(ui, repo, *args, **opts):
153 > def debugfoobar(ui, repo, *args, **opts):
154 > "yet another debug command"
154 > "yet another debug command"
155 > pass
155 > pass
156 >
156 >
157 > def foo(ui, repo, *args, **opts):
157 > def foo(ui, repo, *args, **opts):
158 > """yet another foo command
158 > """yet another foo command
159 >
159 >
160 > This command has been DEPRECATED since forever.
160 > This command has been DEPRECATED since forever.
161 > """
161 > """
162 > pass
162 > pass
163 >
163 >
164 > cmdtable = {
164 > cmdtable = {
165 > "debugfoobar": (debugfoobar, (), "hg debugfoobar"),
165 > "debugfoobar": (debugfoobar, (), "hg debugfoobar"),
166 > "foo": (foo, (), "hg foo")
166 > "foo": (foo, (), "hg foo")
167 > }
167 > }
168 > EOF
168 > EOF
169 $ debugpath=`pwd`/debugextension.py
169 $ debugpath=`pwd`/debugextension.py
170 $ echo "debugextension = $debugpath" >> $HGRCPATH
170 $ echo "debugextension = $debugpath" >> $HGRCPATH
171
171
172 $ hg help debugextension
172 $ hg help debugextension
173 debugextension extension - only debugcommands
173 debugextension extension - only debugcommands
174
174
175 no commands defined
175 no commands defined
176
176
177 $ hg --verbose help debugextension
177 $ hg --verbose help debugextension
178 debugextension extension - only debugcommands
178 debugextension extension - only debugcommands
179
179
180 list of commands:
180 list of commands:
181
181
182 foo yet another foo command
182 foo yet another foo command
183
183
184 global options:
184 global options:
185
185
186 -R --repository REPO repository root directory or name of overlay bundle
186 -R --repository REPO repository root directory or name of overlay bundle
187 file
187 file
188 --cwd DIR change working directory
188 --cwd DIR change working directory
189 -y --noninteractive do not prompt, automatically pick the first choice for
189 -y --noninteractive do not prompt, automatically pick the first choice for
190 all prompts
190 all prompts
191 -q --quiet suppress output
191 -q --quiet suppress output
192 -v --verbose enable additional output
192 -v --verbose enable additional output
193 --config CONFIG [+] set/override config option (use 'section.name=value')
193 --config CONFIG [+] set/override config option (use 'section.name=value')
194 --debug enable debugging output
194 --debug enable debugging output
195 --debugger start debugger
195 --debugger start debugger
196 --encoding ENCODE set the charset encoding (default: ascii)
196 --encoding ENCODE set the charset encoding (default: ascii)
197 --encodingmode MODE set the charset encoding mode (default: strict)
197 --encodingmode MODE set the charset encoding mode (default: strict)
198 --traceback always print a traceback on exception
198 --traceback always print a traceback on exception
199 --time time how long the command takes
199 --time time how long the command takes
200 --profile print command execution profile
200 --profile print command execution profile
201 --version output version information and exit
201 --version output version information and exit
202 -h --help display help and exit
202 -h --help display help and exit
203
203
204 [+] marked option can be specified multiple times
204 [+] marked option can be specified multiple times
205
205
206 $ hg --debug help debugextension
206 $ hg --debug help debugextension
207 debugextension extension - only debugcommands
207 debugextension extension - only debugcommands
208
208
209 list of commands:
209 list of commands:
210
210
211 debugfoobar yet another debug command
211 debugfoobar yet another debug command
212 foo yet another foo command
212 foo yet another foo command
213
213
214 global options:
214 global options:
215
215
216 -R --repository REPO repository root directory or name of overlay bundle
216 -R --repository REPO repository root directory or name of overlay bundle
217 file
217 file
218 --cwd DIR change working directory
218 --cwd DIR change working directory
219 -y --noninteractive do not prompt, automatically pick the first choice for
219 -y --noninteractive do not prompt, automatically pick the first choice for
220 all prompts
220 all prompts
221 -q --quiet suppress output
221 -q --quiet suppress output
222 -v --verbose enable additional output
222 -v --verbose enable additional output
223 --config CONFIG [+] set/override config option (use 'section.name=value')
223 --config CONFIG [+] set/override config option (use 'section.name=value')
224 --debug enable debugging output
224 --debug enable debugging output
225 --debugger start debugger
225 --debugger start debugger
226 --encoding ENCODE set the charset encoding (default: ascii)
226 --encoding ENCODE set the charset encoding (default: ascii)
227 --encodingmode MODE set the charset encoding mode (default: strict)
227 --encodingmode MODE set the charset encoding mode (default: strict)
228 --traceback always print a traceback on exception
228 --traceback always print a traceback on exception
229 --time time how long the command takes
229 --time time how long the command takes
230 --profile print command execution profile
230 --profile print command execution profile
231 --version output version information and exit
231 --version output version information and exit
232 -h --help display help and exit
232 -h --help display help and exit
233
233
234 [+] marked option can be specified multiple times
234 [+] marked option can be specified multiple times
235 $ echo 'debugextension = !' >> $HGRCPATH
235 $ echo 'debugextension = !' >> $HGRCPATH
236
236
237 Extension module help vs command help:
237 Extension module help vs command help:
238
238
239 $ echo 'extdiff =' >> $HGRCPATH
239 $ echo 'extdiff =' >> $HGRCPATH
240 $ hg help extdiff
240 $ hg help extdiff
241 hg extdiff [OPT]... [FILE]...
241 hg extdiff [OPT]... [FILE]...
242
242
243 use external program to diff repository (or selected files)
243 use external program to diff repository (or selected files)
244
244
245 Show differences between revisions for the specified files, using an
245 Show differences between revisions for the specified files, using an
246 external program. The default program used is diff, with default options
246 external program. The default program used is diff, with default options
247 "-Npru".
247 "-Npru".
248
248
249 To select a different program, use the -p/--program option. The program
249 To select a different program, use the -p/--program option. The program
250 will be passed the names of two directories to compare. To pass additional
250 will be passed the names of two directories to compare. To pass additional
251 options to the program, use -o/--option. These will be passed before the
251 options to the program, use -o/--option. These will be passed before the
252 names of the directories to compare.
252 names of the directories to compare.
253
253
254 When two revision arguments are given, then changes are shown between
254 When two revision arguments are given, then changes are shown between
255 those revisions. If only one revision is specified then that revision is
255 those revisions. If only one revision is specified then that revision is
256 compared to the working directory, and, when no revisions are specified,
256 compared to the working directory, and, when no revisions are specified,
257 the working directory files are compared to its parent.
257 the working directory files are compared to its parent.
258
258
259 use "hg help -e extdiff" to show help for the extdiff extension
259 use "hg help -e extdiff" to show help for the extdiff extension
260
260
261 options:
261 options:
262
262
263 -p --program CMD comparison program to run
263 -p --program CMD comparison program to run
264 -o --option OPT [+] pass option to comparison program
264 -o --option OPT [+] pass option to comparison program
265 -r --rev REV [+] revision
265 -r --rev REV [+] revision
266 -c --change REV change made by revision
266 -c --change REV change made by revision
267 -I --include PATTERN [+] include names matching the given patterns
267 -I --include PATTERN [+] include names matching the given patterns
268 -X --exclude PATTERN [+] exclude names matching the given patterns
268 -X --exclude PATTERN [+] exclude names matching the given patterns
269
269
270 [+] marked option can be specified multiple times
270 [+] marked option can be specified multiple times
271
271
272 use "hg -v help extdiff" to show the global options
272 use "hg -v help extdiff" to show the global options
273
273
274 $ hg help --extension extdiff
274 $ hg help --extension extdiff
275 extdiff extension - command to allow external programs to compare revisions
275 extdiff extension - command to allow external programs to compare revisions
276
276
277 The extdiff Mercurial extension allows you to use external programs to compare
277 The extdiff Mercurial extension allows you to use external programs to compare
278 revisions, or revision with working directory. The external diff programs are
278 revisions, or revision with working directory. The external diff programs are
279 called with a configurable set of options and two non-option arguments: paths
279 called with a configurable set of options and two non-option arguments: paths
280 to directories containing snapshots of files to compare.
280 to directories containing snapshots of files to compare.
281
281
282 The extdiff extension also allows you to configure new diff commands, so you
282 The extdiff extension also allows you to configure new diff commands, so you
283 do not need to type "hg extdiff -p kdiff3" always.
283 do not need to type "hg extdiff -p kdiff3" always.
284
284
285 [extdiff]
285 [extdiff]
286 # add new command that runs GNU diff(1) in 'context diff' mode
286 # add new command that runs GNU diff(1) in 'context diff' mode
287 cdiff = gdiff -Nprc5
287 cdiff = gdiff -Nprc5
288 ## or the old way:
288 ## or the old way:
289 #cmd.cdiff = gdiff
289 #cmd.cdiff = gdiff
290 #opts.cdiff = -Nprc5
290 #opts.cdiff = -Nprc5
291
291
292 # add new command called vdiff, runs kdiff3
292 # add new command called vdiff, runs kdiff3
293 vdiff = kdiff3
293 vdiff = kdiff3
294
294
295 # add new command called meld, runs meld (no need to name twice)
295 # add new command called meld, runs meld (no need to name twice)
296 meld =
296 meld =
297
297
298 # add new command called vimdiff, runs gvimdiff with DirDiff plugin
298 # add new command called vimdiff, runs gvimdiff with DirDiff plugin
299 # (see http://www.vim.org/scripts/script.php?script_id=102) Non
299 # (see http://www.vim.org/scripts/script.php?script_id=102) Non
300 # English user, be sure to put "let g:DirDiffDynamicDiffText = 1" in
300 # English user, be sure to put "let g:DirDiffDynamicDiffText = 1" in
301 # your .vimrc
301 # your .vimrc
302 vimdiff = gvim -f "+next" \
302 vimdiff = gvim -f "+next" \
303 "+execute 'DirDiff' fnameescape(argv(0)) fnameescape(argv(1))"
303 "+execute 'DirDiff' fnameescape(argv(0)) fnameescape(argv(1))"
304
304
305 Tool arguments can include variables that are expanded at runtime:
305 Tool arguments can include variables that are expanded at runtime:
306
306
307 $parent1, $plabel1 - filename, descriptive label of first parent
307 $parent1, $plabel1 - filename, descriptive label of first parent
308 $child, $clabel - filename, descriptive label of child revision
308 $child, $clabel - filename, descriptive label of child revision
309 $parent2, $plabel2 - filename, descriptive label of second parent
309 $parent2, $plabel2 - filename, descriptive label of second parent
310 $root - repository root
310 $root - repository root
311 $parent is an alias for $parent1.
311 $parent is an alias for $parent1.
312
312
313 The extdiff extension will look in your [diff-tools] and [merge-tools]
313 The extdiff extension will look in your [diff-tools] and [merge-tools]
314 sections for diff tool arguments, when none are specified in [extdiff].
314 sections for diff tool arguments, when none are specified in [extdiff].
315
315
316 [extdiff]
316 [extdiff]
317 kdiff3 =
317 kdiff3 =
318
318
319 [diff-tools]
319 [diff-tools]
320 kdiff3.diffargs=--L1 '$plabel1' --L2 '$clabel' $parent $child
320 kdiff3.diffargs=--L1 '$plabel1' --L2 '$clabel' $parent $child
321
321
322 You can use -I/-X and list of file or directory names like normal "hg diff"
322 You can use -I/-X and list of file or directory names like normal "hg diff"
323 command. The extdiff extension makes snapshots of only needed files, so
323 command. The extdiff extension makes snapshots of only needed files, so
324 running the external diff program will actually be pretty fast (at least
324 running the external diff program will actually be pretty fast (at least
325 faster than having to compare the entire tree).
325 faster than having to compare the entire tree).
326
326
327 list of commands:
327 list of commands:
328
328
329 extdiff use external program to diff repository (or selected files)
329 extdiff use external program to diff repository (or selected files)
330
330
331 use "hg -v help extdiff" to show builtin aliases and global options
331 use "hg -v help extdiff" to show builtin aliases and global options
332
332
333 $ echo 'extdiff = !' >> $HGRCPATH
333 $ echo 'extdiff = !' >> $HGRCPATH
334
334
335 Test help topic with same name as extension
335 Test help topic with same name as extension
336
336
337 $ cat > multirevs.py <<EOF
337 $ cat > multirevs.py <<EOF
338 > from mercurial import commands
338 > from mercurial import commands
339 > """multirevs extension
339 > """multirevs extension
340 > Big multi-line module docstring."""
340 > Big multi-line module docstring."""
341 > def multirevs(ui, repo, arg, *args, **opts):
341 > def multirevs(ui, repo, arg, *args, **opts):
342 > """multirevs command"""
342 > """multirevs command"""
343 > pass
343 > pass
344 > cmdtable = {
344 > cmdtable = {
345 > "multirevs": (multirevs, [], 'ARG')
345 > "multirevs": (multirevs, [], 'ARG')
346 > }
346 > }
347 > commands.norepo += ' multirevs'
347 > commands.norepo += ' multirevs'
348 > EOF
348 > EOF
349 $ echo "multirevs = multirevs.py" >> $HGRCPATH
349 $ echo "multirevs = multirevs.py" >> $HGRCPATH
350
350
351 $ hg help multirevs
351 $ hg help multirevs
352 Specifying Multiple Revisions
352 Specifying Multiple Revisions
353
353
354 When Mercurial accepts more than one revision, they may be specified
354 When Mercurial accepts more than one revision, they may be specified
355 individually, or provided as a topologically continuous range, separated
355 individually, or provided as a topologically continuous range, separated
356 by the ":" character.
356 by the ":" character.
357
357
358 The syntax of range notation is [BEGIN]:[END], where BEGIN and END are
358 The syntax of range notation is [BEGIN]:[END], where BEGIN and END are
359 revision identifiers. Both BEGIN and END are optional. If BEGIN is not
359 revision identifiers. Both BEGIN and END are optional. If BEGIN is not
360 specified, it defaults to revision number 0. If END is not specified, it
360 specified, it defaults to revision number 0. If END is not specified, it
361 defaults to the tip. The range ":" thus means "all revisions".
361 defaults to the tip. The range ":" thus means "all revisions".
362
362
363 If BEGIN is greater than END, revisions are treated in reverse order.
363 If BEGIN is greater than END, revisions are treated in reverse order.
364
364
365 A range acts as a closed interval. This means that a range of 3:5 gives 3,
365 A range acts as a closed interval. This means that a range of 3:5 gives 3,
366 4 and 5. Similarly, a range of 9:6 gives 9, 8, 7, and 6.
366 4 and 5. Similarly, a range of 9:6 gives 9, 8, 7, and 6.
367
367
368 use "hg help -c multirevs" to see help for the multirevs command
368 use "hg help -c multirevs" to see help for the multirevs command
369
369
370 $ hg help -c multirevs
370 $ hg help -c multirevs
371 hg multirevs ARG
371 hg multirevs ARG
372
372
373 multirevs command
373 multirevs command
374
374
375 use "hg -v help multirevs" to show the global options
375 use "hg -v help multirevs" to show the global options
376
376
377 $ hg multirevs
377 $ hg multirevs
378 hg multirevs: invalid arguments
378 hg multirevs: invalid arguments
379 hg multirevs ARG
379 hg multirevs ARG
380
380
381 multirevs command
381 multirevs command
382
382
383 use "hg help multirevs" to show the full help text
383 use "hg help multirevs" to show the full help text
384 [255]
384 [255]
385
385
386 $ echo "multirevs = !" >> $HGRCPATH
386 $ echo "multirevs = !" >> $HGRCPATH
387
387
388 Issue811: Problem loading extensions twice (by site and by user)
388 Issue811: Problem loading extensions twice (by site and by user)
389
389
390 $ debugpath=`pwd`/debugissue811.py
390 $ debugpath=`pwd`/debugissue811.py
391 $ cat > debugissue811.py <<EOF
391 $ cat > debugissue811.py <<EOF
392 > '''show all loaded extensions
392 > '''show all loaded extensions
393 > '''
393 > '''
394 > from mercurial import extensions, commands
394 > from mercurial import extensions, commands
395 >
395 >
396 > def debugextensions(ui):
396 > def debugextensions(ui):
397 > "yet another debug command"
397 > "yet another debug command"
398 > ui.write("%s\n" % '\n'.join([x for x, y in extensions.extensions()]))
398 > ui.write("%s\n" % '\n'.join([x for x, y in extensions.extensions()]))
399 >
399 >
400 > cmdtable = {"debugextensions": (debugextensions, (), "hg debugextensions")}
400 > cmdtable = {"debugextensions": (debugextensions, (), "hg debugextensions")}
401 > commands.norepo += " debugextensions"
401 > commands.norepo += " debugextensions"
402 > EOF
402 > EOF
403 $ echo "debugissue811 = $debugpath" >> $HGRCPATH
403 $ echo "debugissue811 = $debugpath" >> $HGRCPATH
404 $ echo "mq=" >> $HGRCPATH
404 $ echo "mq=" >> $HGRCPATH
405 $ echo "hgext.mq=" >> $HGRCPATH
405 $ echo "hgext.mq=" >> $HGRCPATH
406 $ echo "hgext/mq=" >> $HGRCPATH
406 $ echo "hgext/mq=" >> $HGRCPATH
407
407
408 Show extensions:
408 Show extensions:
409
409
410 $ hg debugextensions
410 $ hg debugextensions
411 debugissue811
411 debugissue811
412 mq
412 mq
413
413
414 Disabled extension commands:
414 Disabled extension commands:
415
415
416 $ HGRCPATH=
416 $ HGRCPATH=
417 $ export HGRCPATH
417 $ export HGRCPATH
418 $ hg help email
418 $ hg help email
419 'email' is provided by the following extension:
419 'email' is provided by the following extension:
420
420
421 patchbomb command to send changesets as (a series of) patch emails
421 patchbomb command to send changesets as (a series of) patch emails
422
422
423 use "hg help extensions" for information on enabling extensions
423 use "hg help extensions" for information on enabling extensions
424 $ hg qdel
424 $ hg qdel
425 hg: unknown command 'qdel'
425 hg: unknown command 'qdel'
426 'qdelete' is provided by the following extension:
426 'qdelete' is provided by the following extension:
427
427
428 mq manage a stack of patches
428 mq manage a stack of patches
429
429
430 use "hg help extensions" for information on enabling extensions
430 use "hg help extensions" for information on enabling extensions
431 [255]
431 [255]
432 $ hg churn
432 $ hg churn
433 hg: unknown command 'churn'
433 hg: unknown command 'churn'
434 'churn' is provided by the following extension:
434 'churn' is provided by the following extension:
435
435
436 churn command to display statistics about repository history
436 churn command to display statistics about repository history
437
437
438 use "hg help extensions" for information on enabling extensions
438 use "hg help extensions" for information on enabling extensions
439 [255]
439 [255]
440
440
441 Disabled extensions:
441 Disabled extensions:
442
442
443 $ hg help churn
443 $ hg help churn
444 churn extension - command to display statistics about repository history
444 churn extension - command to display statistics about repository history
445
445
446 use "hg help extensions" for information on enabling extensions
446 use "hg help extensions" for information on enabling extensions
447 $ hg help patchbomb
447 $ hg help patchbomb
448 patchbomb extension - command to send changesets as (a series of) patch emails
448 patchbomb extension - command to send changesets as (a series of) patch emails
449
449
450 use "hg help extensions" for information on enabling extensions
450 use "hg help extensions" for information on enabling extensions
451
451
452 Broken disabled extension and command:
452 Broken disabled extension and command:
453
453
454 $ mkdir hgext
454 $ mkdir hgext
455 $ echo > hgext/__init__.py
455 $ echo > hgext/__init__.py
456 $ cat > hgext/broken.py <<EOF
456 $ cat > hgext/broken.py <<EOF
457 > "broken extension'
457 > "broken extension'
458 > EOF
458 > EOF
459 $ cat > path.py <<EOF
459 $ cat > path.py <<EOF
460 > import os, sys
460 > import os, sys
461 > sys.path.insert(0, os.environ['HGEXTPATH'])
461 > sys.path.insert(0, os.environ['HGEXTPATH'])
462 > EOF
462 > EOF
463 $ HGEXTPATH=`pwd`
463 $ HGEXTPATH=`pwd`
464 $ export HGEXTPATH
464 $ export HGEXTPATH
465
465
466 $ hg --config extensions.path=./path.py help broken
466 $ hg --config extensions.path=./path.py help broken
467 broken extension - (no help text available)
467 broken extension - (no help text available)
468
468
469 use "hg help extensions" for information on enabling extensions
469 use "hg help extensions" for information on enabling extensions
470
470
471 $ cat > hgext/forest.py <<EOF
471 $ cat > hgext/forest.py <<EOF
472 > cmdtable = None
472 > cmdtable = None
473 > EOF
473 > EOF
474 $ hg --config extensions.path=./path.py help foo > /dev/null
474 $ hg --config extensions.path=./path.py help foo > /dev/null
475 warning: error finding commands in $TESTTMP/hgext/forest.py (glob)
475 warning: error finding commands in $TESTTMP/hgext/forest.py (glob)
476 hg: unknown command 'foo'
476 hg: unknown command 'foo'
477 warning: error finding commands in $TESTTMP/hgext/forest.py (glob)
477 warning: error finding commands in $TESTTMP/hgext/forest.py (glob)
478 [255]
478 [255]
479
479
480 $ cat > throw.py <<EOF
480 $ cat > throw.py <<EOF
481 > from mercurial import cmdutil, commands
481 > from mercurial import cmdutil, commands
482 > cmdtable = {}
482 > cmdtable = {}
483 > command = cmdutil.command(cmdtable)
483 > command = cmdutil.command(cmdtable)
484 > class Bogon(Exception): pass
484 > class Bogon(Exception): pass
485 >
485 >
486 > @command('throw', [], 'hg throw')
486 > @command('throw', [], 'hg throw')
487 > def throw(ui, **opts):
487 > def throw(ui, **opts):
488 > """throws an exception"""
488 > """throws an exception"""
489 > raise Bogon()
489 > raise Bogon()
490 > commands.norepo += " throw"
490 > commands.norepo += " throw"
491 > EOF
491 > EOF
492 No declared supported version, extension complains:
492 No declared supported version, extension complains:
493 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
493 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
494 ** Unknown exception encountered with possibly-broken third-party extension throw
494 ** Unknown exception encountered with possibly-broken third-party extension throw
495 ** which supports versions unknown of Mercurial.
495 ** which supports versions unknown of Mercurial.
496 ** Please disable throw and try your action again.
496 ** Please disable throw and try your action again.
497 ** If that fixes the bug please report it to the extension author.
497 ** If that fixes the bug please report it to the extension author.
498 ** Python * (glob)
498 ** Python * (glob)
499 ** Mercurial Distributed SCM * (glob)
499 ** Mercurial Distributed SCM * (glob)
500 ** Extensions loaded: throw
500 ** Extensions loaded: throw
501 empty declaration of supported version, extension complains:
502 $ echo "testedwith = ''" >> throw.py
503 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
504 ** Unknown exception encountered with possibly-broken third-party extension throw
505 ** which supports versions unknown of Mercurial.
506 ** Please disable throw and try your action again.
507 ** If that fixes the bug please report it to the extension author.
508 ** Python * (glob)
509 ** Mercurial Distributed SCM (*) (glob)
510 ** Extensions loaded: throw
501 If the extension specifies a buglink, show that:
511 If the extension specifies a buglink, show that:
502 $ echo 'buglink = "http://example.com/bts"' >> throw.py
512 $ echo 'buglink = "http://example.com/bts"' >> throw.py
503 $ rm -f throw.pyc throw.pyo
513 $ rm -f throw.pyc throw.pyo
504 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
514 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
505 ** Unknown exception encountered with possibly-broken third-party extension throw
515 ** Unknown exception encountered with possibly-broken third-party extension throw
506 ** which supports versions unknown of Mercurial.
516 ** which supports versions unknown of Mercurial.
507 ** Please disable throw and try your action again.
517 ** Please disable throw and try your action again.
508 ** If that fixes the bug please report it to http://example.com/bts
518 ** If that fixes the bug please report it to http://example.com/bts
509 ** Python * (glob)
519 ** Python * (glob)
510 ** Mercurial Distributed SCM (*) (glob)
520 ** Mercurial Distributed SCM (*) (glob)
511 ** Extensions loaded: throw
521 ** Extensions loaded: throw
512 If the extensions declare outdated versions, accuse the older extension first:
522 If the extensions declare outdated versions, accuse the older extension first:
513 $ echo "from mercurial import util" >> older.py
523 $ echo "from mercurial import util" >> older.py
514 $ echo "util.version = lambda:'2.2'" >> older.py
524 $ echo "util.version = lambda:'2.2'" >> older.py
515 $ echo "testedwith = '1.9.3'" >> older.py
525 $ echo "testedwith = '1.9.3'" >> older.py
516 $ echo "testedwith = '2.1.1'" >> throw.py
526 $ echo "testedwith = '2.1.1'" >> throw.py
517 $ rm -f throw.pyc throw.pyo
527 $ rm -f throw.pyc throw.pyo
518 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
528 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
519 > throw 2>&1 | egrep '^\*\*'
529 > throw 2>&1 | egrep '^\*\*'
520 ** Unknown exception encountered with possibly-broken third-party extension older
530 ** Unknown exception encountered with possibly-broken third-party extension older
521 ** which supports versions 1.9.3 of Mercurial.
531 ** which supports versions 1.9.3 of Mercurial.
522 ** Please disable older and try your action again.
532 ** Please disable older and try your action again.
523 ** If that fixes the bug please report it to the extension author.
533 ** If that fixes the bug please report it to the extension author.
524 ** Python * (glob)
534 ** Python * (glob)
525 ** Mercurial Distributed SCM (version 2.2)
535 ** Mercurial Distributed SCM (version 2.2)
526 ** Extensions loaded: throw, older
536 ** Extensions loaded: throw, older
527 One extension only tested with older, one only with newer versions:
537 One extension only tested with older, one only with newer versions:
528 $ echo "util.version = lambda:'2.1.0'" >> older.py
538 $ echo "util.version = lambda:'2.1.0'" >> older.py
529 $ rm -f older.pyc older.pyo
539 $ rm -f older.pyc older.pyo
530 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
540 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
531 > throw 2>&1 | egrep '^\*\*'
541 > throw 2>&1 | egrep '^\*\*'
532 ** Unknown exception encountered with possibly-broken third-party extension older
542 ** Unknown exception encountered with possibly-broken third-party extension older
533 ** which supports versions 1.9.3 of Mercurial.
543 ** which supports versions 1.9.3 of Mercurial.
534 ** Please disable older and try your action again.
544 ** Please disable older and try your action again.
535 ** If that fixes the bug please report it to the extension author.
545 ** If that fixes the bug please report it to the extension author.
536 ** Python * (glob)
546 ** Python * (glob)
537 ** Mercurial Distributed SCM (version 2.1.0)
547 ** Mercurial Distributed SCM (version 2.1.0)
538 ** Extensions loaded: throw, older
548 ** Extensions loaded: throw, older
539 Older extension is tested with current version, the other only with newer:
549 Older extension is tested with current version, the other only with newer:
540 $ echo "util.version = lambda:'1.9.3'" >> older.py
550 $ echo "util.version = lambda:'1.9.3'" >> older.py
541 $ rm -f older.pyc older.pyo
551 $ rm -f older.pyc older.pyo
542 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
552 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
543 > throw 2>&1 | egrep '^\*\*'
553 > throw 2>&1 | egrep '^\*\*'
544 ** Unknown exception encountered with possibly-broken third-party extension throw
554 ** Unknown exception encountered with possibly-broken third-party extension throw
545 ** which supports versions 2.1.1 of Mercurial.
555 ** which supports versions 2.1.1 of Mercurial.
546 ** Please disable throw and try your action again.
556 ** Please disable throw and try your action again.
547 ** If that fixes the bug please report it to http://example.com/bts
557 ** If that fixes the bug please report it to http://example.com/bts
548 ** Python * (glob)
558 ** Python * (glob)
549 ** Mercurial Distributed SCM (version 1.9.3)
559 ** Mercurial Distributed SCM (version 1.9.3)
550 ** Extensions loaded: throw, older
560 ** Extensions loaded: throw, older
551
561
552 Declare the version as supporting this hg version, show regular bts link:
562 Declare the version as supporting this hg version, show regular bts link:
553 $ hgver=`python -c 'from mercurial import util; print util.version().split("+")[0]'`
563 $ hgver=`python -c 'from mercurial import util; print util.version().split("+")[0]'`
554 $ echo 'testedwith = """'"$hgver"'"""' >> throw.py
564 $ echo 'testedwith = """'"$hgver"'"""' >> throw.py
555 $ rm -f throw.pyc throw.pyo
565 $ rm -f throw.pyc throw.pyo
556 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
566 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
557 ** unknown exception encountered, please report by visiting
567 ** unknown exception encountered, please report by visiting
558 ** http://mercurial.selenic.com/wiki/BugTracker
568 ** http://mercurial.selenic.com/wiki/BugTracker
559 ** Python * (glob)
569 ** Python * (glob)
560 ** Mercurial Distributed SCM (*) (glob)
570 ** Mercurial Distributed SCM (*) (glob)
561 ** Extensions loaded: throw
571 ** Extensions loaded: throw
General Comments 0
You need to be logged in to leave comments. Login now