##// END OF EJS Templates
errors: raise InputError on bad repo arguments...
Martin von Zweigbergk -
r46523:89390625 default
parent child Browse files
Show More
@@ -1,1324 +1,1324 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 __future__ import absolute_import, print_function
8 from __future__ import absolute_import, print_function
9
9
10 import errno
10 import errno
11 import getopt
11 import getopt
12 import io
12 import io
13 import os
13 import os
14 import pdb
14 import pdb
15 import re
15 import re
16 import signal
16 import signal
17 import sys
17 import sys
18 import traceback
18 import traceback
19
19
20
20
21 from .i18n import _
21 from .i18n import _
22 from .pycompat import getattr
22 from .pycompat import getattr
23
23
24 from hgdemandimport import tracing
24 from hgdemandimport import tracing
25
25
26 from . import (
26 from . import (
27 cmdutil,
27 cmdutil,
28 color,
28 color,
29 commands,
29 commands,
30 demandimport,
30 demandimport,
31 encoding,
31 encoding,
32 error,
32 error,
33 extensions,
33 extensions,
34 fancyopts,
34 fancyopts,
35 help,
35 help,
36 hg,
36 hg,
37 hook,
37 hook,
38 localrepo,
38 localrepo,
39 profiling,
39 profiling,
40 pycompat,
40 pycompat,
41 rcutil,
41 rcutil,
42 registrar,
42 registrar,
43 requirements as requirementsmod,
43 requirements as requirementsmod,
44 scmutil,
44 scmutil,
45 ui as uimod,
45 ui as uimod,
46 util,
46 util,
47 vfs,
47 vfs,
48 )
48 )
49
49
50 from .utils import (
50 from .utils import (
51 procutil,
51 procutil,
52 stringutil,
52 stringutil,
53 )
53 )
54
54
55
55
56 class request(object):
56 class request(object):
57 def __init__(
57 def __init__(
58 self,
58 self,
59 args,
59 args,
60 ui=None,
60 ui=None,
61 repo=None,
61 repo=None,
62 fin=None,
62 fin=None,
63 fout=None,
63 fout=None,
64 ferr=None,
64 ferr=None,
65 fmsg=None,
65 fmsg=None,
66 prereposetups=None,
66 prereposetups=None,
67 ):
67 ):
68 self.args = args
68 self.args = args
69 self.ui = ui
69 self.ui = ui
70 self.repo = repo
70 self.repo = repo
71
71
72 # input/output/error streams
72 # input/output/error streams
73 self.fin = fin
73 self.fin = fin
74 self.fout = fout
74 self.fout = fout
75 self.ferr = ferr
75 self.ferr = ferr
76 # separate stream for status/error messages
76 # separate stream for status/error messages
77 self.fmsg = fmsg
77 self.fmsg = fmsg
78
78
79 # remember options pre-parsed by _earlyparseopts()
79 # remember options pre-parsed by _earlyparseopts()
80 self.earlyoptions = {}
80 self.earlyoptions = {}
81
81
82 # reposetups which run before extensions, useful for chg to pre-fill
82 # reposetups which run before extensions, useful for chg to pre-fill
83 # low-level repo state (for example, changelog) before extensions.
83 # low-level repo state (for example, changelog) before extensions.
84 self.prereposetups = prereposetups or []
84 self.prereposetups = prereposetups or []
85
85
86 # store the parsed and canonical command
86 # store the parsed and canonical command
87 self.canonical_command = None
87 self.canonical_command = None
88
88
89 def _runexithandlers(self):
89 def _runexithandlers(self):
90 exc = None
90 exc = None
91 handlers = self.ui._exithandlers
91 handlers = self.ui._exithandlers
92 try:
92 try:
93 while handlers:
93 while handlers:
94 func, args, kwargs = handlers.pop()
94 func, args, kwargs = handlers.pop()
95 try:
95 try:
96 func(*args, **kwargs)
96 func(*args, **kwargs)
97 except: # re-raises below
97 except: # re-raises below
98 if exc is None:
98 if exc is None:
99 exc = sys.exc_info()[1]
99 exc = sys.exc_info()[1]
100 self.ui.warnnoi18n(b'error in exit handlers:\n')
100 self.ui.warnnoi18n(b'error in exit handlers:\n')
101 self.ui.traceback(force=True)
101 self.ui.traceback(force=True)
102 finally:
102 finally:
103 if exc is not None:
103 if exc is not None:
104 raise exc
104 raise exc
105
105
106
106
107 def run():
107 def run():
108 """run the command in sys.argv"""
108 """run the command in sys.argv"""
109 try:
109 try:
110 initstdio()
110 initstdio()
111 with tracing.log('parse args into request'):
111 with tracing.log('parse args into request'):
112 req = request(pycompat.sysargv[1:])
112 req = request(pycompat.sysargv[1:])
113 err = None
113 err = None
114 try:
114 try:
115 status = dispatch(req)
115 status = dispatch(req)
116 except error.StdioError as e:
116 except error.StdioError as e:
117 err = e
117 err = e
118 status = -1
118 status = -1
119
119
120 # In all cases we try to flush stdio streams.
120 # In all cases we try to flush stdio streams.
121 if util.safehasattr(req.ui, b'fout'):
121 if util.safehasattr(req.ui, b'fout'):
122 assert req.ui is not None # help pytype
122 assert req.ui is not None # help pytype
123 assert req.ui.fout is not None # help pytype
123 assert req.ui.fout is not None # help pytype
124 try:
124 try:
125 req.ui.fout.flush()
125 req.ui.fout.flush()
126 except IOError as e:
126 except IOError as e:
127 err = e
127 err = e
128 status = -1
128 status = -1
129
129
130 if util.safehasattr(req.ui, b'ferr'):
130 if util.safehasattr(req.ui, b'ferr'):
131 assert req.ui is not None # help pytype
131 assert req.ui is not None # help pytype
132 assert req.ui.ferr is not None # help pytype
132 assert req.ui.ferr is not None # help pytype
133 try:
133 try:
134 if err is not None and err.errno != errno.EPIPE:
134 if err is not None and err.errno != errno.EPIPE:
135 req.ui.ferr.write(
135 req.ui.ferr.write(
136 b'abort: %s\n' % encoding.strtolocal(err.strerror)
136 b'abort: %s\n' % encoding.strtolocal(err.strerror)
137 )
137 )
138 req.ui.ferr.flush()
138 req.ui.ferr.flush()
139 # There's not much we can do about an I/O error here. So (possibly)
139 # There's not much we can do about an I/O error here. So (possibly)
140 # change the status code and move on.
140 # change the status code and move on.
141 except IOError:
141 except IOError:
142 status = -1
142 status = -1
143
143
144 _silencestdio()
144 _silencestdio()
145 except KeyboardInterrupt:
145 except KeyboardInterrupt:
146 # Catch early/late KeyboardInterrupt as last ditch. Here nothing will
146 # Catch early/late KeyboardInterrupt as last ditch. Here nothing will
147 # be printed to console to avoid another IOError/KeyboardInterrupt.
147 # be printed to console to avoid another IOError/KeyboardInterrupt.
148 status = -1
148 status = -1
149 sys.exit(status & 255)
149 sys.exit(status & 255)
150
150
151
151
152 if pycompat.ispy3:
152 if pycompat.ispy3:
153
153
154 def initstdio():
154 def initstdio():
155 # stdio streams on Python 3 are io.TextIOWrapper instances proxying another
155 # stdio streams on Python 3 are io.TextIOWrapper instances proxying another
156 # buffer. These streams will normalize \n to \r\n by default. Mercurial's
156 # buffer. These streams will normalize \n to \r\n by default. Mercurial's
157 # preferred mechanism for writing output (ui.write()) uses io.BufferedWriter
157 # preferred mechanism for writing output (ui.write()) uses io.BufferedWriter
158 # instances, which write to the underlying stdio file descriptor in binary
158 # instances, which write to the underlying stdio file descriptor in binary
159 # mode. ui.write() uses \n for line endings and no line ending normalization
159 # mode. ui.write() uses \n for line endings and no line ending normalization
160 # is attempted through this interface. This "just works," even if the system
160 # is attempted through this interface. This "just works," even if the system
161 # preferred line ending is not \n.
161 # preferred line ending is not \n.
162 #
162 #
163 # But some parts of Mercurial (e.g. hooks) can still send data to sys.stdout
163 # But some parts of Mercurial (e.g. hooks) can still send data to sys.stdout
164 # and sys.stderr. They will inherit the line ending normalization settings,
164 # and sys.stderr. They will inherit the line ending normalization settings,
165 # potentially causing e.g. \r\n to be emitted. Since emitting \n should
165 # potentially causing e.g. \r\n to be emitted. Since emitting \n should
166 # "just work," here we change the sys.* streams to disable line ending
166 # "just work," here we change the sys.* streams to disable line ending
167 # normalization, ensuring compatibility with our ui type.
167 # normalization, ensuring compatibility with our ui type.
168
168
169 # write_through is new in Python 3.7.
169 # write_through is new in Python 3.7.
170 kwargs = {
170 kwargs = {
171 "newline": "\n",
171 "newline": "\n",
172 "line_buffering": sys.stdout.line_buffering,
172 "line_buffering": sys.stdout.line_buffering,
173 }
173 }
174 if util.safehasattr(sys.stdout, "write_through"):
174 if util.safehasattr(sys.stdout, "write_through"):
175 kwargs["write_through"] = sys.stdout.write_through
175 kwargs["write_through"] = sys.stdout.write_through
176 sys.stdout = io.TextIOWrapper(
176 sys.stdout = io.TextIOWrapper(
177 sys.stdout.buffer, sys.stdout.encoding, sys.stdout.errors, **kwargs
177 sys.stdout.buffer, sys.stdout.encoding, sys.stdout.errors, **kwargs
178 )
178 )
179
179
180 kwargs = {
180 kwargs = {
181 "newline": "\n",
181 "newline": "\n",
182 "line_buffering": sys.stderr.line_buffering,
182 "line_buffering": sys.stderr.line_buffering,
183 }
183 }
184 if util.safehasattr(sys.stderr, "write_through"):
184 if util.safehasattr(sys.stderr, "write_through"):
185 kwargs["write_through"] = sys.stderr.write_through
185 kwargs["write_through"] = sys.stderr.write_through
186 sys.stderr = io.TextIOWrapper(
186 sys.stderr = io.TextIOWrapper(
187 sys.stderr.buffer, sys.stderr.encoding, sys.stderr.errors, **kwargs
187 sys.stderr.buffer, sys.stderr.encoding, sys.stderr.errors, **kwargs
188 )
188 )
189
189
190 # No write_through on read-only stream.
190 # No write_through on read-only stream.
191 sys.stdin = io.TextIOWrapper(
191 sys.stdin = io.TextIOWrapper(
192 sys.stdin.buffer,
192 sys.stdin.buffer,
193 sys.stdin.encoding,
193 sys.stdin.encoding,
194 sys.stdin.errors,
194 sys.stdin.errors,
195 # None is universal newlines mode.
195 # None is universal newlines mode.
196 newline=None,
196 newline=None,
197 line_buffering=sys.stdin.line_buffering,
197 line_buffering=sys.stdin.line_buffering,
198 )
198 )
199
199
200 def _silencestdio():
200 def _silencestdio():
201 for fp in (sys.stdout, sys.stderr):
201 for fp in (sys.stdout, sys.stderr):
202 # Check if the file is okay
202 # Check if the file is okay
203 try:
203 try:
204 fp.flush()
204 fp.flush()
205 continue
205 continue
206 except IOError:
206 except IOError:
207 pass
207 pass
208 # Otherwise mark it as closed to silence "Exception ignored in"
208 # Otherwise mark it as closed to silence "Exception ignored in"
209 # message emitted by the interpreter finalizer. Be careful to
209 # message emitted by the interpreter finalizer. Be careful to
210 # not close procutil.stdout, which may be a fdopen-ed file object
210 # not close procutil.stdout, which may be a fdopen-ed file object
211 # and its close() actually closes the underlying file descriptor.
211 # and its close() actually closes the underlying file descriptor.
212 try:
212 try:
213 fp.close()
213 fp.close()
214 except IOError:
214 except IOError:
215 pass
215 pass
216
216
217
217
218 else:
218 else:
219
219
220 def initstdio():
220 def initstdio():
221 for fp in (sys.stdin, sys.stdout, sys.stderr):
221 for fp in (sys.stdin, sys.stdout, sys.stderr):
222 procutil.setbinary(fp)
222 procutil.setbinary(fp)
223
223
224 def _silencestdio():
224 def _silencestdio():
225 pass
225 pass
226
226
227
227
228 def _formatargs(args):
228 def _formatargs(args):
229 return b' '.join(procutil.shellquote(a) for a in args)
229 return b' '.join(procutil.shellquote(a) for a in args)
230
230
231
231
232 def dispatch(req):
232 def dispatch(req):
233 """run the command specified in req.args; returns an integer status code"""
233 """run the command specified in req.args; returns an integer status code"""
234 with tracing.log('dispatch.dispatch'):
234 with tracing.log('dispatch.dispatch'):
235 if req.ferr:
235 if req.ferr:
236 ferr = req.ferr
236 ferr = req.ferr
237 elif req.ui:
237 elif req.ui:
238 ferr = req.ui.ferr
238 ferr = req.ui.ferr
239 else:
239 else:
240 ferr = procutil.stderr
240 ferr = procutil.stderr
241
241
242 try:
242 try:
243 if not req.ui:
243 if not req.ui:
244 req.ui = uimod.ui.load()
244 req.ui = uimod.ui.load()
245 req.earlyoptions.update(_earlyparseopts(req.ui, req.args))
245 req.earlyoptions.update(_earlyparseopts(req.ui, req.args))
246 if req.earlyoptions[b'traceback']:
246 if req.earlyoptions[b'traceback']:
247 req.ui.setconfig(b'ui', b'traceback', b'on', b'--traceback')
247 req.ui.setconfig(b'ui', b'traceback', b'on', b'--traceback')
248
248
249 # set ui streams from the request
249 # set ui streams from the request
250 if req.fin:
250 if req.fin:
251 req.ui.fin = req.fin
251 req.ui.fin = req.fin
252 if req.fout:
252 if req.fout:
253 req.ui.fout = req.fout
253 req.ui.fout = req.fout
254 if req.ferr:
254 if req.ferr:
255 req.ui.ferr = req.ferr
255 req.ui.ferr = req.ferr
256 if req.fmsg:
256 if req.fmsg:
257 req.ui.fmsg = req.fmsg
257 req.ui.fmsg = req.fmsg
258 except error.Abort as inst:
258 except error.Abort as inst:
259 ferr.write(inst.format())
259 ferr.write(inst.format())
260 return -1
260 return -1
261
261
262 msg = _formatargs(req.args)
262 msg = _formatargs(req.args)
263 starttime = util.timer()
263 starttime = util.timer()
264 ret = 1 # default of Python exit code on unhandled exception
264 ret = 1 # default of Python exit code on unhandled exception
265 try:
265 try:
266 ret = _runcatch(req) or 0
266 ret = _runcatch(req) or 0
267 except error.ProgrammingError as inst:
267 except error.ProgrammingError as inst:
268 req.ui.error(_(b'** ProgrammingError: %s\n') % inst)
268 req.ui.error(_(b'** ProgrammingError: %s\n') % inst)
269 if inst.hint:
269 if inst.hint:
270 req.ui.error(_(b'** (%s)\n') % inst.hint)
270 req.ui.error(_(b'** (%s)\n') % inst.hint)
271 raise
271 raise
272 except KeyboardInterrupt as inst:
272 except KeyboardInterrupt as inst:
273 try:
273 try:
274 if isinstance(inst, error.SignalInterrupt):
274 if isinstance(inst, error.SignalInterrupt):
275 msg = _(b"killed!\n")
275 msg = _(b"killed!\n")
276 else:
276 else:
277 msg = _(b"interrupted!\n")
277 msg = _(b"interrupted!\n")
278 req.ui.error(msg)
278 req.ui.error(msg)
279 except error.SignalInterrupt:
279 except error.SignalInterrupt:
280 # maybe pager would quit without consuming all the output, and
280 # maybe pager would quit without consuming all the output, and
281 # SIGPIPE was raised. we cannot print anything in this case.
281 # SIGPIPE was raised. we cannot print anything in this case.
282 pass
282 pass
283 except IOError as inst:
283 except IOError as inst:
284 if inst.errno != errno.EPIPE:
284 if inst.errno != errno.EPIPE:
285 raise
285 raise
286 ret = -1
286 ret = -1
287 finally:
287 finally:
288 duration = util.timer() - starttime
288 duration = util.timer() - starttime
289 req.ui.flush() # record blocked times
289 req.ui.flush() # record blocked times
290 if req.ui.logblockedtimes:
290 if req.ui.logblockedtimes:
291 req.ui._blockedtimes[b'command_duration'] = duration * 1000
291 req.ui._blockedtimes[b'command_duration'] = duration * 1000
292 req.ui.log(
292 req.ui.log(
293 b'uiblocked',
293 b'uiblocked',
294 b'ui blocked ms\n',
294 b'ui blocked ms\n',
295 **pycompat.strkwargs(req.ui._blockedtimes)
295 **pycompat.strkwargs(req.ui._blockedtimes)
296 )
296 )
297 return_code = ret & 255
297 return_code = ret & 255
298 req.ui.log(
298 req.ui.log(
299 b"commandfinish",
299 b"commandfinish",
300 b"%s exited %d after %0.2f seconds\n",
300 b"%s exited %d after %0.2f seconds\n",
301 msg,
301 msg,
302 return_code,
302 return_code,
303 duration,
303 duration,
304 return_code=return_code,
304 return_code=return_code,
305 duration=duration,
305 duration=duration,
306 canonical_command=req.canonical_command,
306 canonical_command=req.canonical_command,
307 )
307 )
308 try:
308 try:
309 req._runexithandlers()
309 req._runexithandlers()
310 except: # exiting, so no re-raises
310 except: # exiting, so no re-raises
311 ret = ret or -1
311 ret = ret or -1
312 # do flush again since ui.log() and exit handlers may write to ui
312 # do flush again since ui.log() and exit handlers may write to ui
313 req.ui.flush()
313 req.ui.flush()
314 return ret
314 return ret
315
315
316
316
317 def _runcatch(req):
317 def _runcatch(req):
318 with tracing.log('dispatch._runcatch'):
318 with tracing.log('dispatch._runcatch'):
319
319
320 def catchterm(*args):
320 def catchterm(*args):
321 raise error.SignalInterrupt
321 raise error.SignalInterrupt
322
322
323 ui = req.ui
323 ui = req.ui
324 try:
324 try:
325 for name in b'SIGBREAK', b'SIGHUP', b'SIGTERM':
325 for name in b'SIGBREAK', b'SIGHUP', b'SIGTERM':
326 num = getattr(signal, name, None)
326 num = getattr(signal, name, None)
327 if num:
327 if num:
328 signal.signal(num, catchterm)
328 signal.signal(num, catchterm)
329 except ValueError:
329 except ValueError:
330 pass # happens if called in a thread
330 pass # happens if called in a thread
331
331
332 def _runcatchfunc():
332 def _runcatchfunc():
333 realcmd = None
333 realcmd = None
334 try:
334 try:
335 cmdargs = fancyopts.fancyopts(
335 cmdargs = fancyopts.fancyopts(
336 req.args[:], commands.globalopts, {}
336 req.args[:], commands.globalopts, {}
337 )
337 )
338 cmd = cmdargs[0]
338 cmd = cmdargs[0]
339 aliases, entry = cmdutil.findcmd(cmd, commands.table, False)
339 aliases, entry = cmdutil.findcmd(cmd, commands.table, False)
340 realcmd = aliases[0]
340 realcmd = aliases[0]
341 except (
341 except (
342 error.UnknownCommand,
342 error.UnknownCommand,
343 error.AmbiguousCommand,
343 error.AmbiguousCommand,
344 IndexError,
344 IndexError,
345 getopt.GetoptError,
345 getopt.GetoptError,
346 ):
346 ):
347 # Don't handle this here. We know the command is
347 # Don't handle this here. We know the command is
348 # invalid, but all we're worried about for now is that
348 # invalid, but all we're worried about for now is that
349 # it's not a command that server operators expect to
349 # it's not a command that server operators expect to
350 # be safe to offer to users in a sandbox.
350 # be safe to offer to users in a sandbox.
351 pass
351 pass
352 if realcmd == b'serve' and b'--stdio' in cmdargs:
352 if realcmd == b'serve' and b'--stdio' in cmdargs:
353 # We want to constrain 'hg serve --stdio' instances pretty
353 # We want to constrain 'hg serve --stdio' instances pretty
354 # closely, as many shared-ssh access tools want to grant
354 # closely, as many shared-ssh access tools want to grant
355 # access to run *only* 'hg -R $repo serve --stdio'. We
355 # access to run *only* 'hg -R $repo serve --stdio'. We
356 # restrict to exactly that set of arguments, and prohibit
356 # restrict to exactly that set of arguments, and prohibit
357 # any repo name that starts with '--' to prevent
357 # any repo name that starts with '--' to prevent
358 # shenanigans wherein a user does something like pass
358 # shenanigans wherein a user does something like pass
359 # --debugger or --config=ui.debugger=1 as a repo
359 # --debugger or --config=ui.debugger=1 as a repo
360 # name. This used to actually run the debugger.
360 # name. This used to actually run the debugger.
361 if (
361 if (
362 len(req.args) != 4
362 len(req.args) != 4
363 or req.args[0] != b'-R'
363 or req.args[0] != b'-R'
364 or req.args[1].startswith(b'--')
364 or req.args[1].startswith(b'--')
365 or req.args[2] != b'serve'
365 or req.args[2] != b'serve'
366 or req.args[3] != b'--stdio'
366 or req.args[3] != b'--stdio'
367 ):
367 ):
368 raise error.Abort(
368 raise error.Abort(
369 _(b'potentially unsafe serve --stdio invocation: %s')
369 _(b'potentially unsafe serve --stdio invocation: %s')
370 % (stringutil.pprint(req.args),)
370 % (stringutil.pprint(req.args),)
371 )
371 )
372
372
373 try:
373 try:
374 debugger = b'pdb'
374 debugger = b'pdb'
375 debugtrace = {b'pdb': pdb.set_trace}
375 debugtrace = {b'pdb': pdb.set_trace}
376 debugmortem = {b'pdb': pdb.post_mortem}
376 debugmortem = {b'pdb': pdb.post_mortem}
377
377
378 # read --config before doing anything else
378 # read --config before doing anything else
379 # (e.g. to change trust settings for reading .hg/hgrc)
379 # (e.g. to change trust settings for reading .hg/hgrc)
380 cfgs = _parseconfig(req.ui, req.earlyoptions[b'config'])
380 cfgs = _parseconfig(req.ui, req.earlyoptions[b'config'])
381
381
382 if req.repo:
382 if req.repo:
383 # copy configs that were passed on the cmdline (--config) to
383 # copy configs that were passed on the cmdline (--config) to
384 # the repo ui
384 # the repo ui
385 for sec, name, val in cfgs:
385 for sec, name, val in cfgs:
386 req.repo.ui.setconfig(
386 req.repo.ui.setconfig(
387 sec, name, val, source=b'--config'
387 sec, name, val, source=b'--config'
388 )
388 )
389
389
390 # developer config: ui.debugger
390 # developer config: ui.debugger
391 debugger = ui.config(b"ui", b"debugger")
391 debugger = ui.config(b"ui", b"debugger")
392 debugmod = pdb
392 debugmod = pdb
393 if not debugger or ui.plain():
393 if not debugger or ui.plain():
394 # if we are in HGPLAIN mode, then disable custom debugging
394 # if we are in HGPLAIN mode, then disable custom debugging
395 debugger = b'pdb'
395 debugger = b'pdb'
396 elif req.earlyoptions[b'debugger']:
396 elif req.earlyoptions[b'debugger']:
397 # This import can be slow for fancy debuggers, so only
397 # This import can be slow for fancy debuggers, so only
398 # do it when absolutely necessary, i.e. when actual
398 # do it when absolutely necessary, i.e. when actual
399 # debugging has been requested
399 # debugging has been requested
400 with demandimport.deactivated():
400 with demandimport.deactivated():
401 try:
401 try:
402 debugmod = __import__(debugger)
402 debugmod = __import__(debugger)
403 except ImportError:
403 except ImportError:
404 pass # Leave debugmod = pdb
404 pass # Leave debugmod = pdb
405
405
406 debugtrace[debugger] = debugmod.set_trace
406 debugtrace[debugger] = debugmod.set_trace
407 debugmortem[debugger] = debugmod.post_mortem
407 debugmortem[debugger] = debugmod.post_mortem
408
408
409 # enter the debugger before command execution
409 # enter the debugger before command execution
410 if req.earlyoptions[b'debugger']:
410 if req.earlyoptions[b'debugger']:
411 ui.warn(
411 ui.warn(
412 _(
412 _(
413 b"entering debugger - "
413 b"entering debugger - "
414 b"type c to continue starting hg or h for help\n"
414 b"type c to continue starting hg or h for help\n"
415 )
415 )
416 )
416 )
417
417
418 if (
418 if (
419 debugger != b'pdb'
419 debugger != b'pdb'
420 and debugtrace[debugger] == debugtrace[b'pdb']
420 and debugtrace[debugger] == debugtrace[b'pdb']
421 ):
421 ):
422 ui.warn(
422 ui.warn(
423 _(
423 _(
424 b"%s debugger specified "
424 b"%s debugger specified "
425 b"but its module was not found\n"
425 b"but its module was not found\n"
426 )
426 )
427 % debugger
427 % debugger
428 )
428 )
429 with demandimport.deactivated():
429 with demandimport.deactivated():
430 debugtrace[debugger]()
430 debugtrace[debugger]()
431 try:
431 try:
432 return _dispatch(req)
432 return _dispatch(req)
433 finally:
433 finally:
434 ui.flush()
434 ui.flush()
435 except: # re-raises
435 except: # re-raises
436 # enter the debugger when we hit an exception
436 # enter the debugger when we hit an exception
437 if req.earlyoptions[b'debugger']:
437 if req.earlyoptions[b'debugger']:
438 traceback.print_exc()
438 traceback.print_exc()
439 debugmortem[debugger](sys.exc_info()[2])
439 debugmortem[debugger](sys.exc_info()[2])
440 raise
440 raise
441
441
442 return _callcatch(ui, _runcatchfunc)
442 return _callcatch(ui, _runcatchfunc)
443
443
444
444
445 def _callcatch(ui, func):
445 def _callcatch(ui, func):
446 """like scmutil.callcatch but handles more high-level exceptions about
446 """like scmutil.callcatch but handles more high-level exceptions about
447 config parsing and commands. besides, use handlecommandexception to handle
447 config parsing and commands. besides, use handlecommandexception to handle
448 uncaught exceptions.
448 uncaught exceptions.
449 """
449 """
450 try:
450 try:
451 return scmutil.callcatch(ui, func)
451 return scmutil.callcatch(ui, func)
452 except error.AmbiguousCommand as inst:
452 except error.AmbiguousCommand as inst:
453 ui.warn(
453 ui.warn(
454 _(b"hg: command '%s' is ambiguous:\n %s\n")
454 _(b"hg: command '%s' is ambiguous:\n %s\n")
455 % (inst.prefix, b" ".join(inst.matches))
455 % (inst.prefix, b" ".join(inst.matches))
456 )
456 )
457 except error.CommandError as inst:
457 except error.CommandError as inst:
458 if inst.command:
458 if inst.command:
459 ui.pager(b'help')
459 ui.pager(b'help')
460 msgbytes = pycompat.bytestr(inst.message)
460 msgbytes = pycompat.bytestr(inst.message)
461 ui.warn(_(b"hg %s: %s\n") % (inst.command, msgbytes))
461 ui.warn(_(b"hg %s: %s\n") % (inst.command, msgbytes))
462 commands.help_(ui, inst.command, full=False, command=True)
462 commands.help_(ui, inst.command, full=False, command=True)
463 else:
463 else:
464 ui.warn(_(b"hg: %s\n") % inst.message)
464 ui.warn(_(b"hg: %s\n") % inst.message)
465 ui.warn(_(b"(use 'hg help -v' for a list of global options)\n"))
465 ui.warn(_(b"(use 'hg help -v' for a list of global options)\n"))
466 except error.UnknownCommand as inst:
466 except error.UnknownCommand as inst:
467 nocmdmsg = _(b"hg: unknown command '%s'\n") % inst.command
467 nocmdmsg = _(b"hg: unknown command '%s'\n") % inst.command
468 try:
468 try:
469 # check if the command is in a disabled extension
469 # check if the command is in a disabled extension
470 # (but don't check for extensions themselves)
470 # (but don't check for extensions themselves)
471 formatted = help.formattedhelp(
471 formatted = help.formattedhelp(
472 ui, commands, inst.command, unknowncmd=True
472 ui, commands, inst.command, unknowncmd=True
473 )
473 )
474 ui.warn(nocmdmsg)
474 ui.warn(nocmdmsg)
475 ui.write(formatted)
475 ui.write(formatted)
476 except (error.UnknownCommand, error.Abort):
476 except (error.UnknownCommand, error.Abort):
477 suggested = False
477 suggested = False
478 if inst.all_commands:
478 if inst.all_commands:
479 sim = error.getsimilar(inst.all_commands, inst.command)
479 sim = error.getsimilar(inst.all_commands, inst.command)
480 if sim:
480 if sim:
481 ui.warn(nocmdmsg)
481 ui.warn(nocmdmsg)
482 ui.warn(b"(%s)\n" % error.similarity_hint(sim))
482 ui.warn(b"(%s)\n" % error.similarity_hint(sim))
483 suggested = True
483 suggested = True
484 if not suggested:
484 if not suggested:
485 ui.warn(nocmdmsg)
485 ui.warn(nocmdmsg)
486 ui.warn(_(b"(use 'hg help' for a list of commands)\n"))
486 ui.warn(_(b"(use 'hg help' for a list of commands)\n"))
487 except IOError:
487 except IOError:
488 raise
488 raise
489 except KeyboardInterrupt:
489 except KeyboardInterrupt:
490 raise
490 raise
491 except: # probably re-raises
491 except: # probably re-raises
492 if not handlecommandexception(ui):
492 if not handlecommandexception(ui):
493 raise
493 raise
494
494
495 return -1
495 return -1
496
496
497
497
498 def aliasargs(fn, givenargs):
498 def aliasargs(fn, givenargs):
499 args = []
499 args = []
500 # only care about alias 'args', ignore 'args' set by extensions.wrapfunction
500 # only care about alias 'args', ignore 'args' set by extensions.wrapfunction
501 if not util.safehasattr(fn, b'_origfunc'):
501 if not util.safehasattr(fn, b'_origfunc'):
502 args = getattr(fn, 'args', args)
502 args = getattr(fn, 'args', args)
503 if args:
503 if args:
504 cmd = b' '.join(map(procutil.shellquote, args))
504 cmd = b' '.join(map(procutil.shellquote, args))
505
505
506 nums = []
506 nums = []
507
507
508 def replacer(m):
508 def replacer(m):
509 num = int(m.group(1)) - 1
509 num = int(m.group(1)) - 1
510 nums.append(num)
510 nums.append(num)
511 if num < len(givenargs):
511 if num < len(givenargs):
512 return givenargs[num]
512 return givenargs[num]
513 raise error.Abort(_(b'too few arguments for command alias'))
513 raise error.Abort(_(b'too few arguments for command alias'))
514
514
515 cmd = re.sub(br'\$(\d+|\$)', replacer, cmd)
515 cmd = re.sub(br'\$(\d+|\$)', replacer, cmd)
516 givenargs = [x for i, x in enumerate(givenargs) if i not in nums]
516 givenargs = [x for i, x in enumerate(givenargs) if i not in nums]
517 args = pycompat.shlexsplit(cmd)
517 args = pycompat.shlexsplit(cmd)
518 return args + givenargs
518 return args + givenargs
519
519
520
520
521 def aliasinterpolate(name, args, cmd):
521 def aliasinterpolate(name, args, cmd):
522 '''interpolate args into cmd for shell aliases
522 '''interpolate args into cmd for shell aliases
523
523
524 This also handles $0, $@ and "$@".
524 This also handles $0, $@ and "$@".
525 '''
525 '''
526 # util.interpolate can't deal with "$@" (with quotes) because it's only
526 # util.interpolate can't deal with "$@" (with quotes) because it's only
527 # built to match prefix + patterns.
527 # built to match prefix + patterns.
528 replacemap = {b'$%d' % (i + 1): arg for i, arg in enumerate(args)}
528 replacemap = {b'$%d' % (i + 1): arg for i, arg in enumerate(args)}
529 replacemap[b'$0'] = name
529 replacemap[b'$0'] = name
530 replacemap[b'$$'] = b'$'
530 replacemap[b'$$'] = b'$'
531 replacemap[b'$@'] = b' '.join(args)
531 replacemap[b'$@'] = b' '.join(args)
532 # Typical Unix shells interpolate "$@" (with quotes) as all the positional
532 # Typical Unix shells interpolate "$@" (with quotes) as all the positional
533 # parameters, separated out into words. Emulate the same behavior here by
533 # parameters, separated out into words. Emulate the same behavior here by
534 # quoting the arguments individually. POSIX shells will then typically
534 # quoting the arguments individually. POSIX shells will then typically
535 # tokenize each argument into exactly one word.
535 # tokenize each argument into exactly one word.
536 replacemap[b'"$@"'] = b' '.join(procutil.shellquote(arg) for arg in args)
536 replacemap[b'"$@"'] = b' '.join(procutil.shellquote(arg) for arg in args)
537 # escape '\$' for regex
537 # escape '\$' for regex
538 regex = b'|'.join(replacemap.keys()).replace(b'$', br'\$')
538 regex = b'|'.join(replacemap.keys()).replace(b'$', br'\$')
539 r = re.compile(regex)
539 r = re.compile(regex)
540 return r.sub(lambda x: replacemap[x.group()], cmd)
540 return r.sub(lambda x: replacemap[x.group()], cmd)
541
541
542
542
543 class cmdalias(object):
543 class cmdalias(object):
544 def __init__(self, ui, name, definition, cmdtable, source):
544 def __init__(self, ui, name, definition, cmdtable, source):
545 self.name = self.cmd = name
545 self.name = self.cmd = name
546 self.cmdname = b''
546 self.cmdname = b''
547 self.definition = definition
547 self.definition = definition
548 self.fn = None
548 self.fn = None
549 self.givenargs = []
549 self.givenargs = []
550 self.opts = []
550 self.opts = []
551 self.help = b''
551 self.help = b''
552 self.badalias = None
552 self.badalias = None
553 self.unknowncmd = False
553 self.unknowncmd = False
554 self.source = source
554 self.source = source
555
555
556 try:
556 try:
557 aliases, entry = cmdutil.findcmd(self.name, cmdtable)
557 aliases, entry = cmdutil.findcmd(self.name, cmdtable)
558 for alias, e in pycompat.iteritems(cmdtable):
558 for alias, e in pycompat.iteritems(cmdtable):
559 if e is entry:
559 if e is entry:
560 self.cmd = alias
560 self.cmd = alias
561 break
561 break
562 self.shadows = True
562 self.shadows = True
563 except error.UnknownCommand:
563 except error.UnknownCommand:
564 self.shadows = False
564 self.shadows = False
565
565
566 if not self.definition:
566 if not self.definition:
567 self.badalias = _(b"no definition for alias '%s'") % self.name
567 self.badalias = _(b"no definition for alias '%s'") % self.name
568 return
568 return
569
569
570 if self.definition.startswith(b'!'):
570 if self.definition.startswith(b'!'):
571 shdef = self.definition[1:]
571 shdef = self.definition[1:]
572 self.shell = True
572 self.shell = True
573
573
574 def fn(ui, *args):
574 def fn(ui, *args):
575 env = {b'HG_ARGS': b' '.join((self.name,) + args)}
575 env = {b'HG_ARGS': b' '.join((self.name,) + args)}
576
576
577 def _checkvar(m):
577 def _checkvar(m):
578 if m.groups()[0] == b'$':
578 if m.groups()[0] == b'$':
579 return m.group()
579 return m.group()
580 elif int(m.groups()[0]) <= len(args):
580 elif int(m.groups()[0]) <= len(args):
581 return m.group()
581 return m.group()
582 else:
582 else:
583 ui.debug(
583 ui.debug(
584 b"No argument found for substitution "
584 b"No argument found for substitution "
585 b"of %i variable in alias '%s' definition.\n"
585 b"of %i variable in alias '%s' definition.\n"
586 % (int(m.groups()[0]), self.name)
586 % (int(m.groups()[0]), self.name)
587 )
587 )
588 return b''
588 return b''
589
589
590 cmd = re.sub(br'\$(\d+|\$)', _checkvar, shdef)
590 cmd = re.sub(br'\$(\d+|\$)', _checkvar, shdef)
591 cmd = aliasinterpolate(self.name, args, cmd)
591 cmd = aliasinterpolate(self.name, args, cmd)
592 return ui.system(
592 return ui.system(
593 cmd, environ=env, blockedtag=b'alias_%s' % self.name
593 cmd, environ=env, blockedtag=b'alias_%s' % self.name
594 )
594 )
595
595
596 self.fn = fn
596 self.fn = fn
597 self.alias = True
597 self.alias = True
598 self._populatehelp(ui, name, shdef, self.fn)
598 self._populatehelp(ui, name, shdef, self.fn)
599 return
599 return
600
600
601 try:
601 try:
602 args = pycompat.shlexsplit(self.definition)
602 args = pycompat.shlexsplit(self.definition)
603 except ValueError as inst:
603 except ValueError as inst:
604 self.badalias = _(b"error in definition for alias '%s': %s") % (
604 self.badalias = _(b"error in definition for alias '%s': %s") % (
605 self.name,
605 self.name,
606 stringutil.forcebytestr(inst),
606 stringutil.forcebytestr(inst),
607 )
607 )
608 return
608 return
609 earlyopts, args = _earlysplitopts(args)
609 earlyopts, args = _earlysplitopts(args)
610 if earlyopts:
610 if earlyopts:
611 self.badalias = _(
611 self.badalias = _(
612 b"error in definition for alias '%s': %s may "
612 b"error in definition for alias '%s': %s may "
613 b"only be given on the command line"
613 b"only be given on the command line"
614 ) % (self.name, b'/'.join(pycompat.ziplist(*earlyopts)[0]))
614 ) % (self.name, b'/'.join(pycompat.ziplist(*earlyopts)[0]))
615 return
615 return
616 self.cmdname = cmd = args.pop(0)
616 self.cmdname = cmd = args.pop(0)
617 self.givenargs = args
617 self.givenargs = args
618
618
619 try:
619 try:
620 tableentry = cmdutil.findcmd(cmd, cmdtable, False)[1]
620 tableentry = cmdutil.findcmd(cmd, cmdtable, False)[1]
621 if len(tableentry) > 2:
621 if len(tableentry) > 2:
622 self.fn, self.opts, cmdhelp = tableentry
622 self.fn, self.opts, cmdhelp = tableentry
623 else:
623 else:
624 self.fn, self.opts = tableentry
624 self.fn, self.opts = tableentry
625 cmdhelp = None
625 cmdhelp = None
626
626
627 self.alias = True
627 self.alias = True
628 self._populatehelp(ui, name, cmd, self.fn, cmdhelp)
628 self._populatehelp(ui, name, cmd, self.fn, cmdhelp)
629
629
630 except error.UnknownCommand:
630 except error.UnknownCommand:
631 self.badalias = _(
631 self.badalias = _(
632 b"alias '%s' resolves to unknown command '%s'"
632 b"alias '%s' resolves to unknown command '%s'"
633 ) % (self.name, cmd,)
633 ) % (self.name, cmd,)
634 self.unknowncmd = True
634 self.unknowncmd = True
635 except error.AmbiguousCommand:
635 except error.AmbiguousCommand:
636 self.badalias = _(
636 self.badalias = _(
637 b"alias '%s' resolves to ambiguous command '%s'"
637 b"alias '%s' resolves to ambiguous command '%s'"
638 ) % (self.name, cmd,)
638 ) % (self.name, cmd,)
639
639
640 def _populatehelp(self, ui, name, cmd, fn, defaulthelp=None):
640 def _populatehelp(self, ui, name, cmd, fn, defaulthelp=None):
641 # confine strings to be passed to i18n.gettext()
641 # confine strings to be passed to i18n.gettext()
642 cfg = {}
642 cfg = {}
643 for k in (b'doc', b'help', b'category'):
643 for k in (b'doc', b'help', b'category'):
644 v = ui.config(b'alias', b'%s:%s' % (name, k), None)
644 v = ui.config(b'alias', b'%s:%s' % (name, k), None)
645 if v is None:
645 if v is None:
646 continue
646 continue
647 if not encoding.isasciistr(v):
647 if not encoding.isasciistr(v):
648 self.badalias = _(
648 self.badalias = _(
649 b"non-ASCII character in alias definition '%s:%s'"
649 b"non-ASCII character in alias definition '%s:%s'"
650 ) % (name, k)
650 ) % (name, k)
651 return
651 return
652 cfg[k] = v
652 cfg[k] = v
653
653
654 self.help = cfg.get(b'help', defaulthelp or b'')
654 self.help = cfg.get(b'help', defaulthelp or b'')
655 if self.help and self.help.startswith(b"hg " + cmd):
655 if self.help and self.help.startswith(b"hg " + cmd):
656 # drop prefix in old-style help lines so hg shows the alias
656 # drop prefix in old-style help lines so hg shows the alias
657 self.help = self.help[4 + len(cmd) :]
657 self.help = self.help[4 + len(cmd) :]
658
658
659 self.owndoc = b'doc' in cfg
659 self.owndoc = b'doc' in cfg
660 doc = cfg.get(b'doc', pycompat.getdoc(fn))
660 doc = cfg.get(b'doc', pycompat.getdoc(fn))
661 if doc is not None:
661 if doc is not None:
662 doc = pycompat.sysstr(doc)
662 doc = pycompat.sysstr(doc)
663 self.__doc__ = doc
663 self.__doc__ = doc
664
664
665 self.helpcategory = cfg.get(
665 self.helpcategory = cfg.get(
666 b'category', registrar.command.CATEGORY_NONE
666 b'category', registrar.command.CATEGORY_NONE
667 )
667 )
668
668
669 @property
669 @property
670 def args(self):
670 def args(self):
671 args = pycompat.maplist(util.expandpath, self.givenargs)
671 args = pycompat.maplist(util.expandpath, self.givenargs)
672 return aliasargs(self.fn, args)
672 return aliasargs(self.fn, args)
673
673
674 def __getattr__(self, name):
674 def __getattr__(self, name):
675 adefaults = {
675 adefaults = {
676 'norepo': True,
676 'norepo': True,
677 'intents': set(),
677 'intents': set(),
678 'optionalrepo': False,
678 'optionalrepo': False,
679 'inferrepo': False,
679 'inferrepo': False,
680 }
680 }
681 if name not in adefaults:
681 if name not in adefaults:
682 raise AttributeError(name)
682 raise AttributeError(name)
683 if self.badalias or util.safehasattr(self, b'shell'):
683 if self.badalias or util.safehasattr(self, b'shell'):
684 return adefaults[name]
684 return adefaults[name]
685 return getattr(self.fn, name)
685 return getattr(self.fn, name)
686
686
687 def __call__(self, ui, *args, **opts):
687 def __call__(self, ui, *args, **opts):
688 if self.badalias:
688 if self.badalias:
689 hint = None
689 hint = None
690 if self.unknowncmd:
690 if self.unknowncmd:
691 try:
691 try:
692 # check if the command is in a disabled extension
692 # check if the command is in a disabled extension
693 cmd, ext = extensions.disabledcmd(ui, self.cmdname)[:2]
693 cmd, ext = extensions.disabledcmd(ui, self.cmdname)[:2]
694 hint = _(b"'%s' is provided by '%s' extension") % (cmd, ext)
694 hint = _(b"'%s' is provided by '%s' extension") % (cmd, ext)
695 except error.UnknownCommand:
695 except error.UnknownCommand:
696 pass
696 pass
697 raise error.Abort(self.badalias, hint=hint)
697 raise error.Abort(self.badalias, hint=hint)
698 if self.shadows:
698 if self.shadows:
699 ui.debug(
699 ui.debug(
700 b"alias '%s' shadows command '%s'\n" % (self.name, self.cmdname)
700 b"alias '%s' shadows command '%s'\n" % (self.name, self.cmdname)
701 )
701 )
702
702
703 ui.log(
703 ui.log(
704 b'commandalias',
704 b'commandalias',
705 b"alias '%s' expands to '%s'\n",
705 b"alias '%s' expands to '%s'\n",
706 self.name,
706 self.name,
707 self.definition,
707 self.definition,
708 )
708 )
709 if util.safehasattr(self, b'shell'):
709 if util.safehasattr(self, b'shell'):
710 return self.fn(ui, *args, **opts)
710 return self.fn(ui, *args, **opts)
711 else:
711 else:
712 try:
712 try:
713 return util.checksignature(self.fn)(ui, *args, **opts)
713 return util.checksignature(self.fn)(ui, *args, **opts)
714 except error.SignatureError:
714 except error.SignatureError:
715 args = b' '.join([self.cmdname] + self.args)
715 args = b' '.join([self.cmdname] + self.args)
716 ui.debug(b"alias '%s' expands to '%s'\n" % (self.name, args))
716 ui.debug(b"alias '%s' expands to '%s'\n" % (self.name, args))
717 raise
717 raise
718
718
719
719
720 class lazyaliasentry(object):
720 class lazyaliasentry(object):
721 """like a typical command entry (func, opts, help), but is lazy"""
721 """like a typical command entry (func, opts, help), but is lazy"""
722
722
723 def __init__(self, ui, name, definition, cmdtable, source):
723 def __init__(self, ui, name, definition, cmdtable, source):
724 self.ui = ui
724 self.ui = ui
725 self.name = name
725 self.name = name
726 self.definition = definition
726 self.definition = definition
727 self.cmdtable = cmdtable.copy()
727 self.cmdtable = cmdtable.copy()
728 self.source = source
728 self.source = source
729 self.alias = True
729 self.alias = True
730
730
731 @util.propertycache
731 @util.propertycache
732 def _aliasdef(self):
732 def _aliasdef(self):
733 return cmdalias(
733 return cmdalias(
734 self.ui, self.name, self.definition, self.cmdtable, self.source
734 self.ui, self.name, self.definition, self.cmdtable, self.source
735 )
735 )
736
736
737 def __getitem__(self, n):
737 def __getitem__(self, n):
738 aliasdef = self._aliasdef
738 aliasdef = self._aliasdef
739 if n == 0:
739 if n == 0:
740 return aliasdef
740 return aliasdef
741 elif n == 1:
741 elif n == 1:
742 return aliasdef.opts
742 return aliasdef.opts
743 elif n == 2:
743 elif n == 2:
744 return aliasdef.help
744 return aliasdef.help
745 else:
745 else:
746 raise IndexError
746 raise IndexError
747
747
748 def __iter__(self):
748 def __iter__(self):
749 for i in range(3):
749 for i in range(3):
750 yield self[i]
750 yield self[i]
751
751
752 def __len__(self):
752 def __len__(self):
753 return 3
753 return 3
754
754
755
755
756 def addaliases(ui, cmdtable):
756 def addaliases(ui, cmdtable):
757 # aliases are processed after extensions have been loaded, so they
757 # aliases are processed after extensions have been loaded, so they
758 # may use extension commands. Aliases can also use other alias definitions,
758 # may use extension commands. Aliases can also use other alias definitions,
759 # but only if they have been defined prior to the current definition.
759 # but only if they have been defined prior to the current definition.
760 for alias, definition in ui.configitems(b'alias', ignoresub=True):
760 for alias, definition in ui.configitems(b'alias', ignoresub=True):
761 try:
761 try:
762 if cmdtable[alias].definition == definition:
762 if cmdtable[alias].definition == definition:
763 continue
763 continue
764 except (KeyError, AttributeError):
764 except (KeyError, AttributeError):
765 # definition might not exist or it might not be a cmdalias
765 # definition might not exist or it might not be a cmdalias
766 pass
766 pass
767
767
768 source = ui.configsource(b'alias', alias)
768 source = ui.configsource(b'alias', alias)
769 entry = lazyaliasentry(ui, alias, definition, cmdtable, source)
769 entry = lazyaliasentry(ui, alias, definition, cmdtable, source)
770 cmdtable[alias] = entry
770 cmdtable[alias] = entry
771
771
772
772
773 def _parse(ui, args):
773 def _parse(ui, args):
774 options = {}
774 options = {}
775 cmdoptions = {}
775 cmdoptions = {}
776
776
777 try:
777 try:
778 args = fancyopts.fancyopts(args, commands.globalopts, options)
778 args = fancyopts.fancyopts(args, commands.globalopts, options)
779 except getopt.GetoptError as inst:
779 except getopt.GetoptError as inst:
780 raise error.CommandError(None, stringutil.forcebytestr(inst))
780 raise error.CommandError(None, stringutil.forcebytestr(inst))
781
781
782 if args:
782 if args:
783 cmd, args = args[0], args[1:]
783 cmd, args = args[0], args[1:]
784 aliases, entry = cmdutil.findcmd(
784 aliases, entry = cmdutil.findcmd(
785 cmd, commands.table, ui.configbool(b"ui", b"strict")
785 cmd, commands.table, ui.configbool(b"ui", b"strict")
786 )
786 )
787 cmd = aliases[0]
787 cmd = aliases[0]
788 args = aliasargs(entry[0], args)
788 args = aliasargs(entry[0], args)
789 defaults = ui.config(b"defaults", cmd)
789 defaults = ui.config(b"defaults", cmd)
790 if defaults:
790 if defaults:
791 args = (
791 args = (
792 pycompat.maplist(util.expandpath, pycompat.shlexsplit(defaults))
792 pycompat.maplist(util.expandpath, pycompat.shlexsplit(defaults))
793 + args
793 + args
794 )
794 )
795 c = list(entry[1])
795 c = list(entry[1])
796 else:
796 else:
797 cmd = None
797 cmd = None
798 c = []
798 c = []
799
799
800 # combine global options into local
800 # combine global options into local
801 for o in commands.globalopts:
801 for o in commands.globalopts:
802 c.append((o[0], o[1], options[o[1]], o[3]))
802 c.append((o[0], o[1], options[o[1]], o[3]))
803
803
804 try:
804 try:
805 args = fancyopts.fancyopts(args, c, cmdoptions, gnu=True)
805 args = fancyopts.fancyopts(args, c, cmdoptions, gnu=True)
806 except getopt.GetoptError as inst:
806 except getopt.GetoptError as inst:
807 raise error.CommandError(cmd, stringutil.forcebytestr(inst))
807 raise error.CommandError(cmd, stringutil.forcebytestr(inst))
808
808
809 # separate global options back out
809 # separate global options back out
810 for o in commands.globalopts:
810 for o in commands.globalopts:
811 n = o[1]
811 n = o[1]
812 options[n] = cmdoptions[n]
812 options[n] = cmdoptions[n]
813 del cmdoptions[n]
813 del cmdoptions[n]
814
814
815 return (cmd, cmd and entry[0] or None, args, options, cmdoptions)
815 return (cmd, cmd and entry[0] or None, args, options, cmdoptions)
816
816
817
817
818 def _parseconfig(ui, config):
818 def _parseconfig(ui, config):
819 """parse the --config options from the command line"""
819 """parse the --config options from the command line"""
820 configs = []
820 configs = []
821
821
822 for cfg in config:
822 for cfg in config:
823 try:
823 try:
824 name, value = [cfgelem.strip() for cfgelem in cfg.split(b'=', 1)]
824 name, value = [cfgelem.strip() for cfgelem in cfg.split(b'=', 1)]
825 section, name = name.split(b'.', 1)
825 section, name = name.split(b'.', 1)
826 if not section or not name:
826 if not section or not name:
827 raise IndexError
827 raise IndexError
828 ui.setconfig(section, name, value, b'--config')
828 ui.setconfig(section, name, value, b'--config')
829 configs.append((section, name, value))
829 configs.append((section, name, value))
830 except (IndexError, ValueError):
830 except (IndexError, ValueError):
831 raise error.Abort(
831 raise error.Abort(
832 _(
832 _(
833 b'malformed --config option: %r '
833 b'malformed --config option: %r '
834 b'(use --config section.name=value)'
834 b'(use --config section.name=value)'
835 )
835 )
836 % pycompat.bytestr(cfg)
836 % pycompat.bytestr(cfg)
837 )
837 )
838
838
839 return configs
839 return configs
840
840
841
841
842 def _earlyparseopts(ui, args):
842 def _earlyparseopts(ui, args):
843 options = {}
843 options = {}
844 fancyopts.fancyopts(
844 fancyopts.fancyopts(
845 args,
845 args,
846 commands.globalopts,
846 commands.globalopts,
847 options,
847 options,
848 gnu=not ui.plain(b'strictflags'),
848 gnu=not ui.plain(b'strictflags'),
849 early=True,
849 early=True,
850 optaliases={b'repository': [b'repo']},
850 optaliases={b'repository': [b'repo']},
851 )
851 )
852 return options
852 return options
853
853
854
854
855 def _earlysplitopts(args):
855 def _earlysplitopts(args):
856 """Split args into a list of possible early options and remainder args"""
856 """Split args into a list of possible early options and remainder args"""
857 shortoptions = b'R:'
857 shortoptions = b'R:'
858 # TODO: perhaps 'debugger' should be included
858 # TODO: perhaps 'debugger' should be included
859 longoptions = [b'cwd=', b'repository=', b'repo=', b'config=']
859 longoptions = [b'cwd=', b'repository=', b'repo=', b'config=']
860 return fancyopts.earlygetopt(
860 return fancyopts.earlygetopt(
861 args, shortoptions, longoptions, gnu=True, keepsep=True
861 args, shortoptions, longoptions, gnu=True, keepsep=True
862 )
862 )
863
863
864
864
865 def runcommand(lui, repo, cmd, fullargs, ui, options, d, cmdpats, cmdoptions):
865 def runcommand(lui, repo, cmd, fullargs, ui, options, d, cmdpats, cmdoptions):
866 # run pre-hook, and abort if it fails
866 # run pre-hook, and abort if it fails
867 hook.hook(
867 hook.hook(
868 lui,
868 lui,
869 repo,
869 repo,
870 b"pre-%s" % cmd,
870 b"pre-%s" % cmd,
871 True,
871 True,
872 args=b" ".join(fullargs),
872 args=b" ".join(fullargs),
873 pats=cmdpats,
873 pats=cmdpats,
874 opts=cmdoptions,
874 opts=cmdoptions,
875 )
875 )
876 try:
876 try:
877 ret = _runcommand(ui, options, cmd, d)
877 ret = _runcommand(ui, options, cmd, d)
878 # run post-hook, passing command result
878 # run post-hook, passing command result
879 hook.hook(
879 hook.hook(
880 lui,
880 lui,
881 repo,
881 repo,
882 b"post-%s" % cmd,
882 b"post-%s" % cmd,
883 False,
883 False,
884 args=b" ".join(fullargs),
884 args=b" ".join(fullargs),
885 result=ret,
885 result=ret,
886 pats=cmdpats,
886 pats=cmdpats,
887 opts=cmdoptions,
887 opts=cmdoptions,
888 )
888 )
889 except Exception:
889 except Exception:
890 # run failure hook and re-raise
890 # run failure hook and re-raise
891 hook.hook(
891 hook.hook(
892 lui,
892 lui,
893 repo,
893 repo,
894 b"fail-%s" % cmd,
894 b"fail-%s" % cmd,
895 False,
895 False,
896 args=b" ".join(fullargs),
896 args=b" ".join(fullargs),
897 pats=cmdpats,
897 pats=cmdpats,
898 opts=cmdoptions,
898 opts=cmdoptions,
899 )
899 )
900 raise
900 raise
901 return ret
901 return ret
902
902
903
903
904 def _readsharedsourceconfig(ui, path):
904 def _readsharedsourceconfig(ui, path):
905 """if the current repository is shared one, this tries to read
905 """if the current repository is shared one, this tries to read
906 .hg/hgrc of shared source if we are in share-safe mode
906 .hg/hgrc of shared source if we are in share-safe mode
907
907
908 Config read is loaded into the ui object passed
908 Config read is loaded into the ui object passed
909
909
910 This should be called before reading .hg/hgrc or the main repo
910 This should be called before reading .hg/hgrc or the main repo
911 as that overrides config set in shared source"""
911 as that overrides config set in shared source"""
912 try:
912 try:
913 with open(os.path.join(path, b".hg", b"requires"), "rb") as fp:
913 with open(os.path.join(path, b".hg", b"requires"), "rb") as fp:
914 requirements = set(fp.read().splitlines())
914 requirements = set(fp.read().splitlines())
915 if not (
915 if not (
916 requirementsmod.SHARESAFE_REQUIREMENT in requirements
916 requirementsmod.SHARESAFE_REQUIREMENT in requirements
917 and requirementsmod.SHARED_REQUIREMENT in requirements
917 and requirementsmod.SHARED_REQUIREMENT in requirements
918 ):
918 ):
919 return
919 return
920 hgvfs = vfs.vfs(os.path.join(path, b".hg"))
920 hgvfs = vfs.vfs(os.path.join(path, b".hg"))
921 sharedvfs = localrepo._getsharedvfs(hgvfs, requirements)
921 sharedvfs = localrepo._getsharedvfs(hgvfs, requirements)
922 ui.readconfig(sharedvfs.join(b"hgrc"), path)
922 ui.readconfig(sharedvfs.join(b"hgrc"), path)
923 except IOError:
923 except IOError:
924 pass
924 pass
925
925
926
926
927 def _getlocal(ui, rpath, wd=None):
927 def _getlocal(ui, rpath, wd=None):
928 """Return (path, local ui object) for the given target path.
928 """Return (path, local ui object) for the given target path.
929
929
930 Takes paths in [cwd]/.hg/hgrc into account."
930 Takes paths in [cwd]/.hg/hgrc into account."
931 """
931 """
932 if wd is None:
932 if wd is None:
933 try:
933 try:
934 wd = encoding.getcwd()
934 wd = encoding.getcwd()
935 except OSError as e:
935 except OSError as e:
936 raise error.Abort(
936 raise error.Abort(
937 _(b"error getting current working directory: %s")
937 _(b"error getting current working directory: %s")
938 % encoding.strtolocal(e.strerror)
938 % encoding.strtolocal(e.strerror)
939 )
939 )
940
940
941 path = cmdutil.findrepo(wd) or b""
941 path = cmdutil.findrepo(wd) or b""
942 if not path:
942 if not path:
943 lui = ui
943 lui = ui
944 else:
944 else:
945 lui = ui.copy()
945 lui = ui.copy()
946 if rcutil.use_repo_hgrc():
946 if rcutil.use_repo_hgrc():
947 _readsharedsourceconfig(lui, path)
947 _readsharedsourceconfig(lui, path)
948 lui.readconfig(os.path.join(path, b".hg", b"hgrc"), path)
948 lui.readconfig(os.path.join(path, b".hg", b"hgrc"), path)
949 lui.readconfig(os.path.join(path, b".hg", b"hgrc-not-shared"), path)
949 lui.readconfig(os.path.join(path, b".hg", b"hgrc-not-shared"), path)
950
950
951 if rpath:
951 if rpath:
952 path = lui.expandpath(rpath)
952 path = lui.expandpath(rpath)
953 lui = ui.copy()
953 lui = ui.copy()
954 if rcutil.use_repo_hgrc():
954 if rcutil.use_repo_hgrc():
955 _readsharedsourceconfig(lui, path)
955 _readsharedsourceconfig(lui, path)
956 lui.readconfig(os.path.join(path, b".hg", b"hgrc"), path)
956 lui.readconfig(os.path.join(path, b".hg", b"hgrc"), path)
957 lui.readconfig(os.path.join(path, b".hg", b"hgrc-not-shared"), path)
957 lui.readconfig(os.path.join(path, b".hg", b"hgrc-not-shared"), path)
958
958
959 return path, lui
959 return path, lui
960
960
961
961
962 def _checkshellalias(lui, ui, args):
962 def _checkshellalias(lui, ui, args):
963 """Return the function to run the shell alias, if it is required"""
963 """Return the function to run the shell alias, if it is required"""
964 options = {}
964 options = {}
965
965
966 try:
966 try:
967 args = fancyopts.fancyopts(args, commands.globalopts, options)
967 args = fancyopts.fancyopts(args, commands.globalopts, options)
968 except getopt.GetoptError:
968 except getopt.GetoptError:
969 return
969 return
970
970
971 if not args:
971 if not args:
972 return
972 return
973
973
974 cmdtable = commands.table
974 cmdtable = commands.table
975
975
976 cmd = args[0]
976 cmd = args[0]
977 try:
977 try:
978 strict = ui.configbool(b"ui", b"strict")
978 strict = ui.configbool(b"ui", b"strict")
979 aliases, entry = cmdutil.findcmd(cmd, cmdtable, strict)
979 aliases, entry = cmdutil.findcmd(cmd, cmdtable, strict)
980 except (error.AmbiguousCommand, error.UnknownCommand):
980 except (error.AmbiguousCommand, error.UnknownCommand):
981 return
981 return
982
982
983 cmd = aliases[0]
983 cmd = aliases[0]
984 fn = entry[0]
984 fn = entry[0]
985
985
986 if cmd and util.safehasattr(fn, b'shell'):
986 if cmd and util.safehasattr(fn, b'shell'):
987 # shell alias shouldn't receive early options which are consumed by hg
987 # shell alias shouldn't receive early options which are consumed by hg
988 _earlyopts, args = _earlysplitopts(args)
988 _earlyopts, args = _earlysplitopts(args)
989 d = lambda: fn(ui, *args[1:])
989 d = lambda: fn(ui, *args[1:])
990 return lambda: runcommand(
990 return lambda: runcommand(
991 lui, None, cmd, args[:1], ui, options, d, [], {}
991 lui, None, cmd, args[:1], ui, options, d, [], {}
992 )
992 )
993
993
994
994
995 def _dispatch(req):
995 def _dispatch(req):
996 args = req.args
996 args = req.args
997 ui = req.ui
997 ui = req.ui
998
998
999 # check for cwd
999 # check for cwd
1000 cwd = req.earlyoptions[b'cwd']
1000 cwd = req.earlyoptions[b'cwd']
1001 if cwd:
1001 if cwd:
1002 os.chdir(cwd)
1002 os.chdir(cwd)
1003
1003
1004 rpath = req.earlyoptions[b'repository']
1004 rpath = req.earlyoptions[b'repository']
1005 path, lui = _getlocal(ui, rpath)
1005 path, lui = _getlocal(ui, rpath)
1006
1006
1007 uis = {ui, lui}
1007 uis = {ui, lui}
1008
1008
1009 if req.repo:
1009 if req.repo:
1010 uis.add(req.repo.ui)
1010 uis.add(req.repo.ui)
1011
1011
1012 if (
1012 if (
1013 req.earlyoptions[b'verbose']
1013 req.earlyoptions[b'verbose']
1014 or req.earlyoptions[b'debug']
1014 or req.earlyoptions[b'debug']
1015 or req.earlyoptions[b'quiet']
1015 or req.earlyoptions[b'quiet']
1016 ):
1016 ):
1017 for opt in (b'verbose', b'debug', b'quiet'):
1017 for opt in (b'verbose', b'debug', b'quiet'):
1018 val = pycompat.bytestr(bool(req.earlyoptions[opt]))
1018 val = pycompat.bytestr(bool(req.earlyoptions[opt]))
1019 for ui_ in uis:
1019 for ui_ in uis:
1020 ui_.setconfig(b'ui', opt, val, b'--' + opt)
1020 ui_.setconfig(b'ui', opt, val, b'--' + opt)
1021
1021
1022 if req.earlyoptions[b'profile']:
1022 if req.earlyoptions[b'profile']:
1023 for ui_ in uis:
1023 for ui_ in uis:
1024 ui_.setconfig(b'profiling', b'enabled', b'true', b'--profile')
1024 ui_.setconfig(b'profiling', b'enabled', b'true', b'--profile')
1025
1025
1026 profile = lui.configbool(b'profiling', b'enabled')
1026 profile = lui.configbool(b'profiling', b'enabled')
1027 with profiling.profile(lui, enabled=profile) as profiler:
1027 with profiling.profile(lui, enabled=profile) as profiler:
1028 # Configure extensions in phases: uisetup, extsetup, cmdtable, and
1028 # Configure extensions in phases: uisetup, extsetup, cmdtable, and
1029 # reposetup
1029 # reposetup
1030 extensions.loadall(lui)
1030 extensions.loadall(lui)
1031 # Propagate any changes to lui.__class__ by extensions
1031 # Propagate any changes to lui.__class__ by extensions
1032 ui.__class__ = lui.__class__
1032 ui.__class__ = lui.__class__
1033
1033
1034 # (uisetup and extsetup are handled in extensions.loadall)
1034 # (uisetup and extsetup are handled in extensions.loadall)
1035
1035
1036 # (reposetup is handled in hg.repository)
1036 # (reposetup is handled in hg.repository)
1037
1037
1038 addaliases(lui, commands.table)
1038 addaliases(lui, commands.table)
1039
1039
1040 # All aliases and commands are completely defined, now.
1040 # All aliases and commands are completely defined, now.
1041 # Check abbreviation/ambiguity of shell alias.
1041 # Check abbreviation/ambiguity of shell alias.
1042 shellaliasfn = _checkshellalias(lui, ui, args)
1042 shellaliasfn = _checkshellalias(lui, ui, args)
1043 if shellaliasfn:
1043 if shellaliasfn:
1044 # no additional configs will be set, set up the ui instances
1044 # no additional configs will be set, set up the ui instances
1045 for ui_ in uis:
1045 for ui_ in uis:
1046 extensions.populateui(ui_)
1046 extensions.populateui(ui_)
1047 return shellaliasfn()
1047 return shellaliasfn()
1048
1048
1049 # check for fallback encoding
1049 # check for fallback encoding
1050 fallback = lui.config(b'ui', b'fallbackencoding')
1050 fallback = lui.config(b'ui', b'fallbackencoding')
1051 if fallback:
1051 if fallback:
1052 encoding.fallbackencoding = fallback
1052 encoding.fallbackencoding = fallback
1053
1053
1054 fullargs = args
1054 fullargs = args
1055 cmd, func, args, options, cmdoptions = _parse(lui, args)
1055 cmd, func, args, options, cmdoptions = _parse(lui, args)
1056
1056
1057 # store the canonical command name in request object for later access
1057 # store the canonical command name in request object for later access
1058 req.canonical_command = cmd
1058 req.canonical_command = cmd
1059
1059
1060 if options[b"config"] != req.earlyoptions[b"config"]:
1060 if options[b"config"] != req.earlyoptions[b"config"]:
1061 raise error.Abort(_(b"option --config may not be abbreviated"))
1061 raise error.Abort(_(b"option --config may not be abbreviated"))
1062 if options[b"cwd"] != req.earlyoptions[b"cwd"]:
1062 if options[b"cwd"] != req.earlyoptions[b"cwd"]:
1063 raise error.Abort(_(b"option --cwd may not be abbreviated"))
1063 raise error.Abort(_(b"option --cwd may not be abbreviated"))
1064 if options[b"repository"] != req.earlyoptions[b"repository"]:
1064 if options[b"repository"] != req.earlyoptions[b"repository"]:
1065 raise error.Abort(
1065 raise error.Abort(
1066 _(
1066 _(
1067 b"option -R has to be separated from other options (e.g. not "
1067 b"option -R has to be separated from other options (e.g. not "
1068 b"-qR) and --repository may only be abbreviated as --repo"
1068 b"-qR) and --repository may only be abbreviated as --repo"
1069 )
1069 )
1070 )
1070 )
1071 if options[b"debugger"] != req.earlyoptions[b"debugger"]:
1071 if options[b"debugger"] != req.earlyoptions[b"debugger"]:
1072 raise error.Abort(_(b"option --debugger may not be abbreviated"))
1072 raise error.Abort(_(b"option --debugger may not be abbreviated"))
1073 # don't validate --profile/--traceback, which can be enabled from now
1073 # don't validate --profile/--traceback, which can be enabled from now
1074
1074
1075 if options[b"encoding"]:
1075 if options[b"encoding"]:
1076 encoding.encoding = options[b"encoding"]
1076 encoding.encoding = options[b"encoding"]
1077 if options[b"encodingmode"]:
1077 if options[b"encodingmode"]:
1078 encoding.encodingmode = options[b"encodingmode"]
1078 encoding.encodingmode = options[b"encodingmode"]
1079 if options[b"time"]:
1079 if options[b"time"]:
1080
1080
1081 def get_times():
1081 def get_times():
1082 t = os.times()
1082 t = os.times()
1083 if t[4] == 0.0:
1083 if t[4] == 0.0:
1084 # Windows leaves this as zero, so use time.perf_counter()
1084 # Windows leaves this as zero, so use time.perf_counter()
1085 t = (t[0], t[1], t[2], t[3], util.timer())
1085 t = (t[0], t[1], t[2], t[3], util.timer())
1086 return t
1086 return t
1087
1087
1088 s = get_times()
1088 s = get_times()
1089
1089
1090 def print_time():
1090 def print_time():
1091 t = get_times()
1091 t = get_times()
1092 ui.warn(
1092 ui.warn(
1093 _(b"time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n")
1093 _(b"time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n")
1094 % (
1094 % (
1095 t[4] - s[4],
1095 t[4] - s[4],
1096 t[0] - s[0],
1096 t[0] - s[0],
1097 t[2] - s[2],
1097 t[2] - s[2],
1098 t[1] - s[1],
1098 t[1] - s[1],
1099 t[3] - s[3],
1099 t[3] - s[3],
1100 )
1100 )
1101 )
1101 )
1102
1102
1103 ui.atexit(print_time)
1103 ui.atexit(print_time)
1104 if options[b"profile"]:
1104 if options[b"profile"]:
1105 profiler.start()
1105 profiler.start()
1106
1106
1107 # if abbreviated version of this were used, take them in account, now
1107 # if abbreviated version of this were used, take them in account, now
1108 if options[b'verbose'] or options[b'debug'] or options[b'quiet']:
1108 if options[b'verbose'] or options[b'debug'] or options[b'quiet']:
1109 for opt in (b'verbose', b'debug', b'quiet'):
1109 for opt in (b'verbose', b'debug', b'quiet'):
1110 if options[opt] == req.earlyoptions[opt]:
1110 if options[opt] == req.earlyoptions[opt]:
1111 continue
1111 continue
1112 val = pycompat.bytestr(bool(options[opt]))
1112 val = pycompat.bytestr(bool(options[opt]))
1113 for ui_ in uis:
1113 for ui_ in uis:
1114 ui_.setconfig(b'ui', opt, val, b'--' + opt)
1114 ui_.setconfig(b'ui', opt, val, b'--' + opt)
1115
1115
1116 if options[b'traceback']:
1116 if options[b'traceback']:
1117 for ui_ in uis:
1117 for ui_ in uis:
1118 ui_.setconfig(b'ui', b'traceback', b'on', b'--traceback')
1118 ui_.setconfig(b'ui', b'traceback', b'on', b'--traceback')
1119
1119
1120 if options[b'noninteractive']:
1120 if options[b'noninteractive']:
1121 for ui_ in uis:
1121 for ui_ in uis:
1122 ui_.setconfig(b'ui', b'interactive', b'off', b'-y')
1122 ui_.setconfig(b'ui', b'interactive', b'off', b'-y')
1123
1123
1124 if cmdoptions.get(b'insecure', False):
1124 if cmdoptions.get(b'insecure', False):
1125 for ui_ in uis:
1125 for ui_ in uis:
1126 ui_.insecureconnections = True
1126 ui_.insecureconnections = True
1127
1127
1128 # setup color handling before pager, because setting up pager
1128 # setup color handling before pager, because setting up pager
1129 # might cause incorrect console information
1129 # might cause incorrect console information
1130 coloropt = options[b'color']
1130 coloropt = options[b'color']
1131 for ui_ in uis:
1131 for ui_ in uis:
1132 if coloropt:
1132 if coloropt:
1133 ui_.setconfig(b'ui', b'color', coloropt, b'--color')
1133 ui_.setconfig(b'ui', b'color', coloropt, b'--color')
1134 color.setup(ui_)
1134 color.setup(ui_)
1135
1135
1136 if stringutil.parsebool(options[b'pager']):
1136 if stringutil.parsebool(options[b'pager']):
1137 # ui.pager() expects 'internal-always-' prefix in this case
1137 # ui.pager() expects 'internal-always-' prefix in this case
1138 ui.pager(b'internal-always-' + cmd)
1138 ui.pager(b'internal-always-' + cmd)
1139 elif options[b'pager'] != b'auto':
1139 elif options[b'pager'] != b'auto':
1140 for ui_ in uis:
1140 for ui_ in uis:
1141 ui_.disablepager()
1141 ui_.disablepager()
1142
1142
1143 # configs are fully loaded, set up the ui instances
1143 # configs are fully loaded, set up the ui instances
1144 for ui_ in uis:
1144 for ui_ in uis:
1145 extensions.populateui(ui_)
1145 extensions.populateui(ui_)
1146
1146
1147 if options[b'version']:
1147 if options[b'version']:
1148 return commands.version_(ui)
1148 return commands.version_(ui)
1149 if options[b'help']:
1149 if options[b'help']:
1150 return commands.help_(ui, cmd, command=cmd is not None)
1150 return commands.help_(ui, cmd, command=cmd is not None)
1151 elif not cmd:
1151 elif not cmd:
1152 return commands.help_(ui, b'shortlist')
1152 return commands.help_(ui, b'shortlist')
1153
1153
1154 repo = None
1154 repo = None
1155 cmdpats = args[:]
1155 cmdpats = args[:]
1156 assert func is not None # help out pytype
1156 assert func is not None # help out pytype
1157 if not func.norepo:
1157 if not func.norepo:
1158 # use the repo from the request only if we don't have -R
1158 # use the repo from the request only if we don't have -R
1159 if not rpath and not cwd:
1159 if not rpath and not cwd:
1160 repo = req.repo
1160 repo = req.repo
1161
1161
1162 if repo:
1162 if repo:
1163 # set the descriptors of the repo ui to those of ui
1163 # set the descriptors of the repo ui to those of ui
1164 repo.ui.fin = ui.fin
1164 repo.ui.fin = ui.fin
1165 repo.ui.fout = ui.fout
1165 repo.ui.fout = ui.fout
1166 repo.ui.ferr = ui.ferr
1166 repo.ui.ferr = ui.ferr
1167 repo.ui.fmsg = ui.fmsg
1167 repo.ui.fmsg = ui.fmsg
1168 else:
1168 else:
1169 try:
1169 try:
1170 repo = hg.repository(
1170 repo = hg.repository(
1171 ui,
1171 ui,
1172 path=path,
1172 path=path,
1173 presetupfuncs=req.prereposetups,
1173 presetupfuncs=req.prereposetups,
1174 intents=func.intents,
1174 intents=func.intents,
1175 )
1175 )
1176 if not repo.local():
1176 if not repo.local():
1177 raise error.Abort(
1177 raise error.InputError(
1178 _(b"repository '%s' is not local") % path
1178 _(b"repository '%s' is not local") % path
1179 )
1179 )
1180 repo.ui.setconfig(
1180 repo.ui.setconfig(
1181 b"bundle", b"mainreporoot", repo.root, b'repo'
1181 b"bundle", b"mainreporoot", repo.root, b'repo'
1182 )
1182 )
1183 except error.RequirementError:
1183 except error.RequirementError:
1184 raise
1184 raise
1185 except error.RepoError:
1185 except error.RepoError:
1186 if rpath: # invalid -R path
1186 if rpath: # invalid -R path
1187 raise
1187 raise
1188 if not func.optionalrepo:
1188 if not func.optionalrepo:
1189 if func.inferrepo and args and not path:
1189 if func.inferrepo and args and not path:
1190 # try to infer -R from command args
1190 # try to infer -R from command args
1191 repos = pycompat.maplist(cmdutil.findrepo, args)
1191 repos = pycompat.maplist(cmdutil.findrepo, args)
1192 guess = repos[0]
1192 guess = repos[0]
1193 if guess and repos.count(guess) == len(repos):
1193 if guess and repos.count(guess) == len(repos):
1194 req.args = [b'--repository', guess] + fullargs
1194 req.args = [b'--repository', guess] + fullargs
1195 req.earlyoptions[b'repository'] = guess
1195 req.earlyoptions[b'repository'] = guess
1196 return _dispatch(req)
1196 return _dispatch(req)
1197 if not path:
1197 if not path:
1198 raise error.RepoError(
1198 raise error.InputError(
1199 _(
1199 _(
1200 b"no repository found in"
1200 b"no repository found in"
1201 b" '%s' (.hg not found)"
1201 b" '%s' (.hg not found)"
1202 )
1202 )
1203 % encoding.getcwd()
1203 % encoding.getcwd()
1204 )
1204 )
1205 raise
1205 raise
1206 if repo:
1206 if repo:
1207 ui = repo.ui
1207 ui = repo.ui
1208 if options[b'hidden']:
1208 if options[b'hidden']:
1209 repo = repo.unfiltered()
1209 repo = repo.unfiltered()
1210 args.insert(0, repo)
1210 args.insert(0, repo)
1211 elif rpath:
1211 elif rpath:
1212 ui.warn(_(b"warning: --repository ignored\n"))
1212 ui.warn(_(b"warning: --repository ignored\n"))
1213
1213
1214 msg = _formatargs(fullargs)
1214 msg = _formatargs(fullargs)
1215 ui.log(b"command", b'%s\n', msg)
1215 ui.log(b"command", b'%s\n', msg)
1216 strcmdopt = pycompat.strkwargs(cmdoptions)
1216 strcmdopt = pycompat.strkwargs(cmdoptions)
1217 d = lambda: util.checksignature(func)(ui, *args, **strcmdopt)
1217 d = lambda: util.checksignature(func)(ui, *args, **strcmdopt)
1218 try:
1218 try:
1219 return runcommand(
1219 return runcommand(
1220 lui, repo, cmd, fullargs, ui, options, d, cmdpats, cmdoptions
1220 lui, repo, cmd, fullargs, ui, options, d, cmdpats, cmdoptions
1221 )
1221 )
1222 finally:
1222 finally:
1223 if repo and repo != req.repo:
1223 if repo and repo != req.repo:
1224 repo.close()
1224 repo.close()
1225
1225
1226
1226
1227 def _runcommand(ui, options, cmd, cmdfunc):
1227 def _runcommand(ui, options, cmd, cmdfunc):
1228 """Run a command function, possibly with profiling enabled."""
1228 """Run a command function, possibly with profiling enabled."""
1229 try:
1229 try:
1230 with tracing.log("Running %s command" % cmd):
1230 with tracing.log("Running %s command" % cmd):
1231 return cmdfunc()
1231 return cmdfunc()
1232 except error.SignatureError:
1232 except error.SignatureError:
1233 raise error.CommandError(cmd, _(b'invalid arguments'))
1233 raise error.CommandError(cmd, _(b'invalid arguments'))
1234
1234
1235
1235
1236 def _exceptionwarning(ui):
1236 def _exceptionwarning(ui):
1237 """Produce a warning message for the current active exception"""
1237 """Produce a warning message for the current active exception"""
1238
1238
1239 # For compatibility checking, we discard the portion of the hg
1239 # For compatibility checking, we discard the portion of the hg
1240 # version after the + on the assumption that if a "normal
1240 # version after the + on the assumption that if a "normal
1241 # user" is running a build with a + in it the packager
1241 # user" is running a build with a + in it the packager
1242 # probably built from fairly close to a tag and anyone with a
1242 # probably built from fairly close to a tag and anyone with a
1243 # 'make local' copy of hg (where the version number can be out
1243 # 'make local' copy of hg (where the version number can be out
1244 # of date) will be clueful enough to notice the implausible
1244 # of date) will be clueful enough to notice the implausible
1245 # version number and try updating.
1245 # version number and try updating.
1246 ct = util.versiontuple(n=2)
1246 ct = util.versiontuple(n=2)
1247 worst = None, ct, b''
1247 worst = None, ct, b''
1248 if ui.config(b'ui', b'supportcontact') is None:
1248 if ui.config(b'ui', b'supportcontact') is None:
1249 for name, mod in extensions.extensions():
1249 for name, mod in extensions.extensions():
1250 # 'testedwith' should be bytes, but not all extensions are ported
1250 # 'testedwith' should be bytes, but not all extensions are ported
1251 # to py3 and we don't want UnicodeException because of that.
1251 # to py3 and we don't want UnicodeException because of that.
1252 testedwith = stringutil.forcebytestr(
1252 testedwith = stringutil.forcebytestr(
1253 getattr(mod, 'testedwith', b'')
1253 getattr(mod, 'testedwith', b'')
1254 )
1254 )
1255 report = getattr(mod, 'buglink', _(b'the extension author.'))
1255 report = getattr(mod, 'buglink', _(b'the extension author.'))
1256 if not testedwith.strip():
1256 if not testedwith.strip():
1257 # We found an untested extension. It's likely the culprit.
1257 # We found an untested extension. It's likely the culprit.
1258 worst = name, b'unknown', report
1258 worst = name, b'unknown', report
1259 break
1259 break
1260
1260
1261 # Never blame on extensions bundled with Mercurial.
1261 # Never blame on extensions bundled with Mercurial.
1262 if extensions.ismoduleinternal(mod):
1262 if extensions.ismoduleinternal(mod):
1263 continue
1263 continue
1264
1264
1265 tested = [util.versiontuple(t, 2) for t in testedwith.split()]
1265 tested = [util.versiontuple(t, 2) for t in testedwith.split()]
1266 if ct in tested:
1266 if ct in tested:
1267 continue
1267 continue
1268
1268
1269 lower = [t for t in tested if t < ct]
1269 lower = [t for t in tested if t < ct]
1270 nearest = max(lower or tested)
1270 nearest = max(lower or tested)
1271 if worst[0] is None or nearest < worst[1]:
1271 if worst[0] is None or nearest < worst[1]:
1272 worst = name, nearest, report
1272 worst = name, nearest, report
1273 if worst[0] is not None:
1273 if worst[0] is not None:
1274 name, testedwith, report = worst
1274 name, testedwith, report = worst
1275 if not isinstance(testedwith, (bytes, str)):
1275 if not isinstance(testedwith, (bytes, str)):
1276 testedwith = b'.'.join(
1276 testedwith = b'.'.join(
1277 [stringutil.forcebytestr(c) for c in testedwith]
1277 [stringutil.forcebytestr(c) for c in testedwith]
1278 )
1278 )
1279 warning = _(
1279 warning = _(
1280 b'** Unknown exception encountered with '
1280 b'** Unknown exception encountered with '
1281 b'possibly-broken third-party extension %s\n'
1281 b'possibly-broken third-party extension %s\n'
1282 b'** which supports versions %s of Mercurial.\n'
1282 b'** which supports versions %s of Mercurial.\n'
1283 b'** Please disable %s and try your action again.\n'
1283 b'** Please disable %s and try your action again.\n'
1284 b'** If that fixes the bug please report it to %s\n'
1284 b'** If that fixes the bug please report it to %s\n'
1285 ) % (name, testedwith, name, stringutil.forcebytestr(report))
1285 ) % (name, testedwith, name, stringutil.forcebytestr(report))
1286 else:
1286 else:
1287 bugtracker = ui.config(b'ui', b'supportcontact')
1287 bugtracker = ui.config(b'ui', b'supportcontact')
1288 if bugtracker is None:
1288 if bugtracker is None:
1289 bugtracker = _(b"https://mercurial-scm.org/wiki/BugTracker")
1289 bugtracker = _(b"https://mercurial-scm.org/wiki/BugTracker")
1290 warning = (
1290 warning = (
1291 _(
1291 _(
1292 b"** unknown exception encountered, "
1292 b"** unknown exception encountered, "
1293 b"please report by visiting\n** "
1293 b"please report by visiting\n** "
1294 )
1294 )
1295 + bugtracker
1295 + bugtracker
1296 + b'\n'
1296 + b'\n'
1297 )
1297 )
1298 sysversion = pycompat.sysbytes(sys.version).replace(b'\n', b'')
1298 sysversion = pycompat.sysbytes(sys.version).replace(b'\n', b'')
1299 warning += (
1299 warning += (
1300 (_(b"** Python %s\n") % sysversion)
1300 (_(b"** Python %s\n") % sysversion)
1301 + (_(b"** Mercurial Distributed SCM (version %s)\n") % util.version())
1301 + (_(b"** Mercurial Distributed SCM (version %s)\n") % util.version())
1302 + (
1302 + (
1303 _(b"** Extensions loaded: %s\n")
1303 _(b"** Extensions loaded: %s\n")
1304 % b", ".join([x[0] for x in extensions.extensions()])
1304 % b", ".join([x[0] for x in extensions.extensions()])
1305 )
1305 )
1306 )
1306 )
1307 return warning
1307 return warning
1308
1308
1309
1309
1310 def handlecommandexception(ui):
1310 def handlecommandexception(ui):
1311 """Produce a warning message for broken commands
1311 """Produce a warning message for broken commands
1312
1312
1313 Called when handling an exception; the exception is reraised if
1313 Called when handling an exception; the exception is reraised if
1314 this function returns False, ignored otherwise.
1314 this function returns False, ignored otherwise.
1315 """
1315 """
1316 warning = _exceptionwarning(ui)
1316 warning = _exceptionwarning(ui)
1317 ui.log(
1317 ui.log(
1318 b"commandexception",
1318 b"commandexception",
1319 b"%s\n%s\n",
1319 b"%s\n%s\n",
1320 warning,
1320 warning,
1321 pycompat.sysbytes(traceback.format_exc()),
1321 pycompat.sysbytes(traceback.format_exc()),
1322 )
1322 )
1323 ui.warn(warning)
1323 ui.warn(warning)
1324 return False # re-raise the exception
1324 return False # re-raise the exception
@@ -1,722 +1,722 b''
1 $ HGFOO=BAR; export HGFOO
1 $ HGFOO=BAR; export HGFOO
2 $ cat >> $HGRCPATH <<EOF
2 $ cat >> $HGRCPATH <<EOF
3 > [alias]
3 > [alias]
4 > # should clobber ci but not commit (issue2993)
4 > # should clobber ci but not commit (issue2993)
5 > ci = version
5 > ci = version
6 > myinit = init
6 > myinit = init
7 > myinit:doc = This is my documented alias for init.
7 > myinit:doc = This is my documented alias for init.
8 > myinit:help = [OPTIONS] [BLA] [BLE]
8 > myinit:help = [OPTIONS] [BLA] [BLE]
9 > mycommit = commit
9 > mycommit = commit
10 > mycommit:doc = This is my alias with only doc.
10 > mycommit:doc = This is my alias with only doc.
11 > optionalrepo = showconfig alias.myinit
11 > optionalrepo = showconfig alias.myinit
12 > cleanstatus = status -c
12 > cleanstatus = status -c
13 > cleanstatus:help = [ONLYHELPHERE]
13 > cleanstatus:help = [ONLYHELPHERE]
14 > unknown = bargle
14 > unknown = bargle
15 > ambiguous = s
15 > ambiguous = s
16 > recursive = recursive
16 > recursive = recursive
17 > disabled = email
17 > disabled = email
18 > nodefinition =
18 > nodefinition =
19 > noclosingquotation = '
19 > noclosingquotation = '
20 > no--cwd = status --cwd elsewhere
20 > no--cwd = status --cwd elsewhere
21 > no-R = status -R elsewhere
21 > no-R = status -R elsewhere
22 > no--repo = status --repo elsewhere
22 > no--repo = status --repo elsewhere
23 > no--repository = status --repository elsewhere
23 > no--repository = status --repository elsewhere
24 > no--config = status --config a.config=1
24 > no--config = status --config a.config=1
25 > mylog = log
25 > mylog = log
26 > lognull = log -r null
26 > lognull = log -r null
27 > lognull:doc = Logs the null rev
27 > lognull:doc = Logs the null rev
28 > lognull:help = foo bar baz
28 > lognull:help = foo bar baz
29 > shortlog = log --template '{rev} {node|short} | {date|isodate}\n'
29 > shortlog = log --template '{rev} {node|short} | {date|isodate}\n'
30 > positional = log --template '{\$2} {\$1} | {date|isodate}\n'
30 > positional = log --template '{\$2} {\$1} | {date|isodate}\n'
31 > dln = lognull --debug
31 > dln = lognull --debug
32 > recursivedoc = dln
32 > recursivedoc = dln
33 > recursivedoc:doc = Logs the null rev in debug mode
33 > recursivedoc:doc = Logs the null rev in debug mode
34 > nousage = rollback
34 > nousage = rollback
35 > put = export -r 0 -o "\$FOO/%R.diff"
35 > put = export -r 0 -o "\$FOO/%R.diff"
36 > blank = !printf '\n'
36 > blank = !printf '\n'
37 > self = !printf '\$0\n'
37 > self = !printf '\$0\n'
38 > echoall = !printf '\$@\n'
38 > echoall = !printf '\$@\n'
39 > echo1 = !printf '\$1\n'
39 > echo1 = !printf '\$1\n'
40 > echo2 = !printf '\$2\n'
40 > echo2 = !printf '\$2\n'
41 > echo13 = !printf '\$1 \$3\n'
41 > echo13 = !printf '\$1 \$3\n'
42 > echotokens = !printf "%s\n" "\$@"
42 > echotokens = !printf "%s\n" "\$@"
43 > count = !hg log -r "\$@" --template=. | wc -c | sed -e 's/ //g'
43 > count = !hg log -r "\$@" --template=. | wc -c | sed -e 's/ //g'
44 > mcount = !hg log \$@ --template=. | wc -c | sed -e 's/ //g'
44 > mcount = !hg log \$@ --template=. | wc -c | sed -e 's/ //g'
45 > rt = root
45 > rt = root
46 > tglog = log -G --template "{rev}:{node|short}: '{desc}' {branches}\n"
46 > tglog = log -G --template "{rev}:{node|short}: '{desc}' {branches}\n"
47 > idalias = id
47 > idalias = id
48 > idaliaslong = id
48 > idaliaslong = id
49 > idaliasshell = !echo test
49 > idaliasshell = !echo test
50 > parentsshell1 = !echo one
50 > parentsshell1 = !echo one
51 > parentsshell2 = !echo two
51 > parentsshell2 = !echo two
52 > escaped1 = !printf 'test\$\$test\n'
52 > escaped1 = !printf 'test\$\$test\n'
53 > escaped2 = !sh -c 'echo "HGFOO is \$\$HGFOO"'
53 > escaped2 = !sh -c 'echo "HGFOO is \$\$HGFOO"'
54 > escaped3 = !sh -c 'echo "\$1 is \$\$\$1"'
54 > escaped3 = !sh -c 'echo "\$1 is \$\$\$1"'
55 > escaped4 = !printf '\$\$0 \$\$@\n'
55 > escaped4 = !printf '\$\$0 \$\$@\n'
56 > exit1 = !sh -c 'exit 1'
56 > exit1 = !sh -c 'exit 1'
57 >
57 >
58 > [defaults]
58 > [defaults]
59 > mylog = -q
59 > mylog = -q
60 > lognull = -q
60 > lognull = -q
61 > log = -v
61 > log = -v
62 > EOF
62 > EOF
63
63
64 basic
64 basic
65
65
66 $ hg myinit alias
66 $ hg myinit alias
67
67
68 help
68 help
69
69
70 $ hg help -c | grep myinit
70 $ hg help -c | grep myinit
71 myinit This is my documented alias for init.
71 myinit This is my documented alias for init.
72 $ hg help -c | grep mycommit
72 $ hg help -c | grep mycommit
73 mycommit This is my alias with only doc.
73 mycommit This is my alias with only doc.
74 $ hg help -c | grep cleanstatus
74 $ hg help -c | grep cleanstatus
75 [1]
75 [1]
76 $ hg help -c | grep lognull
76 $ hg help -c | grep lognull
77 lognull Logs the null rev
77 lognull Logs the null rev
78 $ hg help -c | grep dln
78 $ hg help -c | grep dln
79 [1]
79 [1]
80 $ hg help -c | grep recursivedoc
80 $ hg help -c | grep recursivedoc
81 recursivedoc Logs the null rev in debug mode
81 recursivedoc Logs the null rev in debug mode
82 $ hg help myinit
82 $ hg help myinit
83 hg myinit [OPTIONS] [BLA] [BLE]
83 hg myinit [OPTIONS] [BLA] [BLE]
84
84
85 alias for: hg init
85 alias for: hg init
86
86
87 This is my documented alias for init.
87 This is my documented alias for init.
88
88
89 defined by: * (glob)
89 defined by: * (glob)
90 */* (glob) (?)
90 */* (glob) (?)
91 */* (glob) (?)
91 */* (glob) (?)
92 */* (glob) (?)
92 */* (glob) (?)
93
93
94 options:
94 options:
95
95
96 -e --ssh CMD specify ssh command to use
96 -e --ssh CMD specify ssh command to use
97 --remotecmd CMD specify hg command to run on the remote side
97 --remotecmd CMD specify hg command to run on the remote side
98 --insecure do not verify server certificate (ignoring web.cacerts
98 --insecure do not verify server certificate (ignoring web.cacerts
99 config)
99 config)
100
100
101 (some details hidden, use --verbose to show complete help)
101 (some details hidden, use --verbose to show complete help)
102
102
103 $ hg help mycommit
103 $ hg help mycommit
104 hg mycommit [OPTION]... [FILE]...
104 hg mycommit [OPTION]... [FILE]...
105
105
106 alias for: hg commit
106 alias for: hg commit
107
107
108 This is my alias with only doc.
108 This is my alias with only doc.
109
109
110 defined by: * (glob)
110 defined by: * (glob)
111 */* (glob) (?)
111 */* (glob) (?)
112 */* (glob) (?)
112 */* (glob) (?)
113 */* (glob) (?)
113 */* (glob) (?)
114
114
115 options ([+] can be repeated):
115 options ([+] can be repeated):
116
116
117 -A --addremove mark new/missing files as added/removed before
117 -A --addremove mark new/missing files as added/removed before
118 committing
118 committing
119 --close-branch mark a branch head as closed
119 --close-branch mark a branch head as closed
120 --amend amend the parent of the working directory
120 --amend amend the parent of the working directory
121 -s --secret use the secret phase for committing
121 -s --secret use the secret phase for committing
122 -e --edit invoke editor on commit messages
122 -e --edit invoke editor on commit messages
123 -i --interactive use interactive mode
123 -i --interactive use interactive mode
124 -I --include PATTERN [+] include names matching the given patterns
124 -I --include PATTERN [+] include names matching the given patterns
125 -X --exclude PATTERN [+] exclude names matching the given patterns
125 -X --exclude PATTERN [+] exclude names matching the given patterns
126 -m --message TEXT use text as commit message
126 -m --message TEXT use text as commit message
127 -l --logfile FILE read commit message from file
127 -l --logfile FILE read commit message from file
128 -d --date DATE record the specified date as commit date
128 -d --date DATE record the specified date as commit date
129 -u --user USER record the specified user as committer
129 -u --user USER record the specified user as committer
130 -S --subrepos recurse into subrepositories
130 -S --subrepos recurse into subrepositories
131
131
132 (some details hidden, use --verbose to show complete help)
132 (some details hidden, use --verbose to show complete help)
133
133
134 $ hg help cleanstatus
134 $ hg help cleanstatus
135 hg cleanstatus [ONLYHELPHERE]
135 hg cleanstatus [ONLYHELPHERE]
136
136
137 alias for: hg status -c
137 alias for: hg status -c
138
138
139 show changed files in the working directory
139 show changed files in the working directory
140
140
141 Show status of files in the repository. If names are given, only files
141 Show status of files in the repository. If names are given, only files
142 that match are shown. Files that are clean or ignored or the source of a
142 that match are shown. Files that are clean or ignored or the source of a
143 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
143 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
144 -C/--copies or -A/--all are given. Unless options described with "show
144 -C/--copies or -A/--all are given. Unless options described with "show
145 only ..." are given, the options -mardu are used.
145 only ..." are given, the options -mardu are used.
146
146
147 Option -q/--quiet hides untracked (unknown and ignored) files unless
147 Option -q/--quiet hides untracked (unknown and ignored) files unless
148 explicitly requested with -u/--unknown or -i/--ignored.
148 explicitly requested with -u/--unknown or -i/--ignored.
149
149
150 Note:
150 Note:
151 'hg status' may appear to disagree with diff if permissions have
151 'hg status' may appear to disagree with diff if permissions have
152 changed or a merge has occurred. The standard diff format does not
152 changed or a merge has occurred. The standard diff format does not
153 report permission changes and diff only reports changes relative to one
153 report permission changes and diff only reports changes relative to one
154 merge parent.
154 merge parent.
155
155
156 If one revision is given, it is used as the base revision. If two
156 If one revision is given, it is used as the base revision. If two
157 revisions are given, the differences between them are shown. The --change
157 revisions are given, the differences between them are shown. The --change
158 option can also be used as a shortcut to list the changed files of a
158 option can also be used as a shortcut to list the changed files of a
159 revision from its first parent.
159 revision from its first parent.
160
160
161 The codes used to show the status of files are:
161 The codes used to show the status of files are:
162
162
163 M = modified
163 M = modified
164 A = added
164 A = added
165 R = removed
165 R = removed
166 C = clean
166 C = clean
167 ! = missing (deleted by non-hg command, but still tracked)
167 ! = missing (deleted by non-hg command, but still tracked)
168 ? = not tracked
168 ? = not tracked
169 I = ignored
169 I = ignored
170 = origin of the previous file (with --copies)
170 = origin of the previous file (with --copies)
171
171
172 Returns 0 on success.
172 Returns 0 on success.
173
173
174 defined by: * (glob)
174 defined by: * (glob)
175 */* (glob) (?)
175 */* (glob) (?)
176 */* (glob) (?)
176 */* (glob) (?)
177 */* (glob) (?)
177 */* (glob) (?)
178
178
179 options ([+] can be repeated):
179 options ([+] can be repeated):
180
180
181 -A --all show status of all files
181 -A --all show status of all files
182 -m --modified show only modified files
182 -m --modified show only modified files
183 -a --added show only added files
183 -a --added show only added files
184 -r --removed show only removed files
184 -r --removed show only removed files
185 -d --deleted show only missing files
185 -d --deleted show only missing files
186 -c --clean show only files without changes
186 -c --clean show only files without changes
187 -u --unknown show only unknown (not tracked) files
187 -u --unknown show only unknown (not tracked) files
188 -i --ignored show only ignored files
188 -i --ignored show only ignored files
189 -n --no-status hide status prefix
189 -n --no-status hide status prefix
190 -C --copies show source of copied files
190 -C --copies show source of copied files
191 -0 --print0 end filenames with NUL, for use with xargs
191 -0 --print0 end filenames with NUL, for use with xargs
192 --rev REV [+] show difference from revision
192 --rev REV [+] show difference from revision
193 --change REV list the changed files of a revision
193 --change REV list the changed files of a revision
194 -I --include PATTERN [+] include names matching the given patterns
194 -I --include PATTERN [+] include names matching the given patterns
195 -X --exclude PATTERN [+] exclude names matching the given patterns
195 -X --exclude PATTERN [+] exclude names matching the given patterns
196 -S --subrepos recurse into subrepositories
196 -S --subrepos recurse into subrepositories
197 -T --template TEMPLATE display with template
197 -T --template TEMPLATE display with template
198
198
199 (some details hidden, use --verbose to show complete help)
199 (some details hidden, use --verbose to show complete help)
200
200
201 $ hg help recursivedoc | head -n 5
201 $ hg help recursivedoc | head -n 5
202 hg recursivedoc foo bar baz
202 hg recursivedoc foo bar baz
203
203
204 alias for: hg dln
204 alias for: hg dln
205
205
206 Logs the null rev in debug mode
206 Logs the null rev in debug mode
207
207
208 unknown
208 unknown
209
209
210 $ hg unknown
210 $ hg unknown
211 abort: alias 'unknown' resolves to unknown command 'bargle'
211 abort: alias 'unknown' resolves to unknown command 'bargle'
212 [255]
212 [255]
213 $ hg help unknown
213 $ hg help unknown
214 alias 'unknown' resolves to unknown command 'bargle'
214 alias 'unknown' resolves to unknown command 'bargle'
215
215
216
216
217 ambiguous
217 ambiguous
218
218
219 $ hg ambiguous
219 $ hg ambiguous
220 abort: alias 'ambiguous' resolves to ambiguous command 's'
220 abort: alias 'ambiguous' resolves to ambiguous command 's'
221 [255]
221 [255]
222 $ hg help ambiguous
222 $ hg help ambiguous
223 alias 'ambiguous' resolves to ambiguous command 's'
223 alias 'ambiguous' resolves to ambiguous command 's'
224
224
225
225
226 recursive
226 recursive
227
227
228 $ hg recursive
228 $ hg recursive
229 abort: alias 'recursive' resolves to unknown command 'recursive'
229 abort: alias 'recursive' resolves to unknown command 'recursive'
230 [255]
230 [255]
231 $ hg help recursive
231 $ hg help recursive
232 alias 'recursive' resolves to unknown command 'recursive'
232 alias 'recursive' resolves to unknown command 'recursive'
233
233
234
234
235 disabled
235 disabled
236
236
237 $ hg disabled
237 $ hg disabled
238 abort: alias 'disabled' resolves to unknown command 'email'
238 abort: alias 'disabled' resolves to unknown command 'email'
239 ('email' is provided by 'patchbomb' extension)
239 ('email' is provided by 'patchbomb' extension)
240 [255]
240 [255]
241 $ hg help disabled
241 $ hg help disabled
242 alias 'disabled' resolves to unknown command 'email'
242 alias 'disabled' resolves to unknown command 'email'
243
243
244 'email' is provided by the following extension:
244 'email' is provided by the following extension:
245
245
246 patchbomb command to send changesets as (a series of) patch emails
246 patchbomb command to send changesets as (a series of) patch emails
247
247
248 (use 'hg help extensions' for information on enabling extensions)
248 (use 'hg help extensions' for information on enabling extensions)
249
249
250
250
251 no definition
251 no definition
252
252
253 $ hg nodef
253 $ hg nodef
254 abort: no definition for alias 'nodefinition'
254 abort: no definition for alias 'nodefinition'
255 [255]
255 [255]
256 $ hg help nodef
256 $ hg help nodef
257 no definition for alias 'nodefinition'
257 no definition for alias 'nodefinition'
258
258
259
259
260 no closing quotation
260 no closing quotation
261
261
262 $ hg noclosing
262 $ hg noclosing
263 abort: error in definition for alias 'noclosingquotation': No closing quotation
263 abort: error in definition for alias 'noclosingquotation': No closing quotation
264 [255]
264 [255]
265 $ hg help noclosing
265 $ hg help noclosing
266 error in definition for alias 'noclosingquotation': No closing quotation
266 error in definition for alias 'noclosingquotation': No closing quotation
267
267
268 "--" in alias definition should be preserved
268 "--" in alias definition should be preserved
269
269
270 $ hg --config alias.dash='cat --' -R alias dash -r0
270 $ hg --config alias.dash='cat --' -R alias dash -r0
271 abort: -r0 not under root '$TESTTMP/alias'
271 abort: -r0 not under root '$TESTTMP/alias'
272 (consider using '--cwd alias')
272 (consider using '--cwd alias')
273 [255]
273 [255]
274
274
275 invalid options
275 invalid options
276
276
277 $ hg no--cwd
277 $ hg no--cwd
278 abort: error in definition for alias 'no--cwd': --cwd may only be given on the command line
278 abort: error in definition for alias 'no--cwd': --cwd may only be given on the command line
279 [255]
279 [255]
280 $ hg help no--cwd
280 $ hg help no--cwd
281 error in definition for alias 'no--cwd': --cwd may only be given on the
281 error in definition for alias 'no--cwd': --cwd may only be given on the
282 command line
282 command line
283 $ hg no-R
283 $ hg no-R
284 abort: error in definition for alias 'no-R': -R may only be given on the command line
284 abort: error in definition for alias 'no-R': -R may only be given on the command line
285 [255]
285 [255]
286 $ hg help no-R
286 $ hg help no-R
287 error in definition for alias 'no-R': -R may only be given on the command line
287 error in definition for alias 'no-R': -R may only be given on the command line
288 $ hg no--repo
288 $ hg no--repo
289 abort: error in definition for alias 'no--repo': --repo may only be given on the command line
289 abort: error in definition for alias 'no--repo': --repo may only be given on the command line
290 [255]
290 [255]
291 $ hg help no--repo
291 $ hg help no--repo
292 error in definition for alias 'no--repo': --repo may only be given on the
292 error in definition for alias 'no--repo': --repo may only be given on the
293 command line
293 command line
294 $ hg no--repository
294 $ hg no--repository
295 abort: error in definition for alias 'no--repository': --repository may only be given on the command line
295 abort: error in definition for alias 'no--repository': --repository may only be given on the command line
296 [255]
296 [255]
297 $ hg help no--repository
297 $ hg help no--repository
298 error in definition for alias 'no--repository': --repository may only be given
298 error in definition for alias 'no--repository': --repository may only be given
299 on the command line
299 on the command line
300 $ hg no--config
300 $ hg no--config
301 abort: error in definition for alias 'no--config': --config may only be given on the command line
301 abort: error in definition for alias 'no--config': --config may only be given on the command line
302 [255]
302 [255]
303 $ hg no --config alias.no='--repo elsewhere --cwd elsewhere status'
303 $ hg no --config alias.no='--repo elsewhere --cwd elsewhere status'
304 abort: error in definition for alias 'no': --repo/--cwd may only be given on the command line
304 abort: error in definition for alias 'no': --repo/--cwd may only be given on the command line
305 [255]
305 [255]
306 $ hg no --config alias.no='--repo elsewhere'
306 $ hg no --config alias.no='--repo elsewhere'
307 abort: error in definition for alias 'no': --repo may only be given on the command line
307 abort: error in definition for alias 'no': --repo may only be given on the command line
308 [255]
308 [255]
309
309
310 optional repository
310 optional repository
311
311
312 #if no-outer-repo
312 #if no-outer-repo
313 $ hg optionalrepo
313 $ hg optionalrepo
314 init
314 init
315 #endif
315 #endif
316 $ cd alias
316 $ cd alias
317 $ cat > .hg/hgrc <<EOF
317 $ cat > .hg/hgrc <<EOF
318 > [alias]
318 > [alias]
319 > myinit = init -q
319 > myinit = init -q
320 > EOF
320 > EOF
321 $ hg optionalrepo
321 $ hg optionalrepo
322 init -q
322 init -q
323
323
324 no usage
324 no usage
325
325
326 $ hg nousage
326 $ hg nousage
327 no rollback information available
327 no rollback information available
328 [1]
328 [1]
329
329
330 $ echo foo > foo
330 $ echo foo > foo
331 $ hg commit -Amfoo
331 $ hg commit -Amfoo
332 adding foo
332 adding foo
333
333
334 infer repository
334 infer repository
335
335
336 $ cd ..
336 $ cd ..
337
337
338 #if no-outer-repo
338 #if no-outer-repo
339 $ hg shortlog alias/foo
339 $ hg shortlog alias/foo
340 0 e63c23eaa88a | 1970-01-01 00:00 +0000
340 0 e63c23eaa88a | 1970-01-01 00:00 +0000
341 #endif
341 #endif
342
342
343 $ cd alias
343 $ cd alias
344
344
345 with opts
345 with opts
346
346
347 $ hg cleanst
347 $ hg cleanst
348 C foo
348 C foo
349
349
350
350
351 with opts and whitespace
351 with opts and whitespace
352
352
353 $ hg shortlog
353 $ hg shortlog
354 0 e63c23eaa88a | 1970-01-01 00:00 +0000
354 0 e63c23eaa88a | 1970-01-01 00:00 +0000
355
355
356 positional arguments
356 positional arguments
357
357
358 $ hg positional
358 $ hg positional
359 abort: too few arguments for command alias
359 abort: too few arguments for command alias
360 [255]
360 [255]
361 $ hg positional a
361 $ hg positional a
362 abort: too few arguments for command alias
362 abort: too few arguments for command alias
363 [255]
363 [255]
364 $ hg positional 'node|short' rev
364 $ hg positional 'node|short' rev
365 0 e63c23eaa88a | 1970-01-01 00:00 +0000
365 0 e63c23eaa88a | 1970-01-01 00:00 +0000
366
366
367 interaction with defaults
367 interaction with defaults
368
368
369 $ hg mylog
369 $ hg mylog
370 0:e63c23eaa88a
370 0:e63c23eaa88a
371 $ hg lognull
371 $ hg lognull
372 -1:000000000000
372 -1:000000000000
373
373
374
374
375 properly recursive
375 properly recursive
376
376
377 $ hg dln
377 $ hg dln
378 changeset: -1:0000000000000000000000000000000000000000
378 changeset: -1:0000000000000000000000000000000000000000
379 phase: public
379 phase: public
380 parent: -1:0000000000000000000000000000000000000000
380 parent: -1:0000000000000000000000000000000000000000
381 parent: -1:0000000000000000000000000000000000000000
381 parent: -1:0000000000000000000000000000000000000000
382 manifest: -1:0000000000000000000000000000000000000000
382 manifest: -1:0000000000000000000000000000000000000000
383 user:
383 user:
384 date: Thu Jan 01 00:00:00 1970 +0000
384 date: Thu Jan 01 00:00:00 1970 +0000
385 extra: branch=default
385 extra: branch=default
386
386
387
387
388
388
389 path expanding
389 path expanding
390
390
391 $ FOO=`pwd` hg put
391 $ FOO=`pwd` hg put
392 $ cat 0.diff
392 $ cat 0.diff
393 # HG changeset patch
393 # HG changeset patch
394 # User test
394 # User test
395 # Date 0 0
395 # Date 0 0
396 # Thu Jan 01 00:00:00 1970 +0000
396 # Thu Jan 01 00:00:00 1970 +0000
397 # Node ID e63c23eaa88ae77967edcf4ea194d31167c478b0
397 # Node ID e63c23eaa88ae77967edcf4ea194d31167c478b0
398 # Parent 0000000000000000000000000000000000000000
398 # Parent 0000000000000000000000000000000000000000
399 foo
399 foo
400
400
401 diff -r 000000000000 -r e63c23eaa88a foo
401 diff -r 000000000000 -r e63c23eaa88a foo
402 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
402 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
403 +++ b/foo Thu Jan 01 00:00:00 1970 +0000
403 +++ b/foo Thu Jan 01 00:00:00 1970 +0000
404 @@ -0,0 +1,1 @@
404 @@ -0,0 +1,1 @@
405 +foo
405 +foo
406
406
407
407
408 simple shell aliases
408 simple shell aliases
409
409
410 $ hg blank
410 $ hg blank
411
411
412 $ hg blank foo
412 $ hg blank foo
413
413
414 $ hg self
414 $ hg self
415 self
415 self
416 $ hg echoall
416 $ hg echoall
417
417
418 $ hg echoall foo
418 $ hg echoall foo
419 foo
419 foo
420 $ hg echoall 'test $2' foo
420 $ hg echoall 'test $2' foo
421 test $2 foo
421 test $2 foo
422 $ hg echoall 'test $@' foo '$@'
422 $ hg echoall 'test $@' foo '$@'
423 test $@ foo $@
423 test $@ foo $@
424 $ hg echoall 'test "$@"' foo '"$@"'
424 $ hg echoall 'test "$@"' foo '"$@"'
425 test "$@" foo "$@"
425 test "$@" foo "$@"
426 $ hg echo1 foo bar baz
426 $ hg echo1 foo bar baz
427 foo
427 foo
428 $ hg echo2 foo bar baz
428 $ hg echo2 foo bar baz
429 bar
429 bar
430 $ hg echo13 foo bar baz test
430 $ hg echo13 foo bar baz test
431 foo baz
431 foo baz
432 $ hg echo2 foo
432 $ hg echo2 foo
433
433
434 $ hg echotokens
434 $ hg echotokens
435
435
436 $ hg echotokens foo 'bar $1 baz'
436 $ hg echotokens foo 'bar $1 baz'
437 foo
437 foo
438 bar $1 baz
438 bar $1 baz
439 $ hg echotokens 'test $2' foo
439 $ hg echotokens 'test $2' foo
440 test $2
440 test $2
441 foo
441 foo
442 $ hg echotokens 'test $@' foo '$@'
442 $ hg echotokens 'test $@' foo '$@'
443 test $@
443 test $@
444 foo
444 foo
445 $@
445 $@
446 $ hg echotokens 'test "$@"' foo '"$@"'
446 $ hg echotokens 'test "$@"' foo '"$@"'
447 test "$@"
447 test "$@"
448 foo
448 foo
449 "$@"
449 "$@"
450 $ echo bar > bar
450 $ echo bar > bar
451 $ hg commit -qA -m bar
451 $ hg commit -qA -m bar
452 $ hg count .
452 $ hg count .
453 1
453 1
454 $ hg count 'branch(default)'
454 $ hg count 'branch(default)'
455 2
455 2
456 $ hg mcount -r '"branch(default)"'
456 $ hg mcount -r '"branch(default)"'
457 2
457 2
458
458
459 $ hg tglog
459 $ hg tglog
460 @ 1:042423737847: 'bar'
460 @ 1:042423737847: 'bar'
461 |
461 |
462 o 0:e63c23eaa88a: 'foo'
462 o 0:e63c23eaa88a: 'foo'
463
463
464
464
465
465
466 shadowing
466 shadowing
467
467
468 $ hg i
468 $ hg i
469 hg: command 'i' is ambiguous:
469 hg: command 'i' is ambiguous:
470 idalias idaliaslong idaliasshell identify import incoming init
470 idalias idaliaslong idaliasshell identify import incoming init
471 [255]
471 [255]
472 $ hg id
472 $ hg id
473 042423737847 tip
473 042423737847 tip
474 $ hg ida
474 $ hg ida
475 hg: command 'ida' is ambiguous:
475 hg: command 'ida' is ambiguous:
476 idalias idaliaslong idaliasshell
476 idalias idaliaslong idaliasshell
477 [255]
477 [255]
478 $ hg idalias
478 $ hg idalias
479 042423737847 tip
479 042423737847 tip
480 $ hg idaliasl
480 $ hg idaliasl
481 042423737847 tip
481 042423737847 tip
482 $ hg idaliass
482 $ hg idaliass
483 test
483 test
484 $ hg parentsshell
484 $ hg parentsshell
485 hg: command 'parentsshell' is ambiguous:
485 hg: command 'parentsshell' is ambiguous:
486 parentsshell1 parentsshell2
486 parentsshell1 parentsshell2
487 [255]
487 [255]
488 $ hg parentsshell1
488 $ hg parentsshell1
489 one
489 one
490 $ hg parentsshell2
490 $ hg parentsshell2
491 two
491 two
492
492
493
493
494 shell aliases with global options
494 shell aliases with global options
495
495
496 $ hg init sub
496 $ hg init sub
497 $ cd sub
497 $ cd sub
498 $ hg count 'branch(default)'
498 $ hg count 'branch(default)'
499 abort: unknown revision 'default'
499 abort: unknown revision 'default'
500 0
500 0
501 $ hg -v count 'branch(default)'
501 $ hg -v count 'branch(default)'
502 abort: unknown revision 'default'
502 abort: unknown revision 'default'
503 0
503 0
504 $ hg -R .. count 'branch(default)'
504 $ hg -R .. count 'branch(default)'
505 abort: unknown revision 'default'
505 abort: unknown revision 'default'
506 0
506 0
507 $ hg --cwd .. count 'branch(default)'
507 $ hg --cwd .. count 'branch(default)'
508 2
508 2
509 $ hg echoall --cwd ..
509 $ hg echoall --cwd ..
510
510
511
511
512 "--" passed to shell alias should be preserved
512 "--" passed to shell alias should be preserved
513
513
514 $ hg --config alias.printf='!printf "$@"' printf '%s %s %s\n' -- --cwd ..
514 $ hg --config alias.printf='!printf "$@"' printf '%s %s %s\n' -- --cwd ..
515 -- --cwd ..
515 -- --cwd ..
516
516
517 repo specific shell aliases
517 repo specific shell aliases
518
518
519 $ cat >> .hg/hgrc <<EOF
519 $ cat >> .hg/hgrc <<EOF
520 > [alias]
520 > [alias]
521 > subalias = !echo sub
521 > subalias = !echo sub
522 > EOF
522 > EOF
523 $ cat >> ../.hg/hgrc <<EOF
523 $ cat >> ../.hg/hgrc <<EOF
524 > [alias]
524 > [alias]
525 > mainalias = !echo main
525 > mainalias = !echo main
526 > EOF
526 > EOF
527
527
528
528
529 shell alias defined in current repo
529 shell alias defined in current repo
530
530
531 $ hg subalias
531 $ hg subalias
532 sub
532 sub
533 $ hg --cwd .. subalias > /dev/null
533 $ hg --cwd .. subalias > /dev/null
534 hg: unknown command 'subalias'
534 hg: unknown command 'subalias'
535 (did you mean idalias?)
535 (did you mean idalias?)
536 [255]
536 [255]
537 $ hg -R .. subalias > /dev/null
537 $ hg -R .. subalias > /dev/null
538 hg: unknown command 'subalias'
538 hg: unknown command 'subalias'
539 (did you mean idalias?)
539 (did you mean idalias?)
540 [255]
540 [255]
541
541
542
542
543 shell alias defined in other repo
543 shell alias defined in other repo
544
544
545 $ hg mainalias > /dev/null
545 $ hg mainalias > /dev/null
546 hg: unknown command 'mainalias'
546 hg: unknown command 'mainalias'
547 (did you mean idalias?)
547 (did you mean idalias?)
548 [255]
548 [255]
549 $ hg -R .. mainalias
549 $ hg -R .. mainalias
550 main
550 main
551 $ hg --cwd .. mainalias
551 $ hg --cwd .. mainalias
552 main
552 main
553
553
554 typos get useful suggestions
554 typos get useful suggestions
555 $ hg --cwd .. manalias
555 $ hg --cwd .. manalias
556 hg: unknown command 'manalias'
556 hg: unknown command 'manalias'
557 (did you mean one of idalias, mainalias, manifest?)
557 (did you mean one of idalias, mainalias, manifest?)
558 [255]
558 [255]
559
559
560 shell aliases with escaped $ chars
560 shell aliases with escaped $ chars
561
561
562 $ hg escaped1
562 $ hg escaped1
563 test$test
563 test$test
564 $ hg escaped2
564 $ hg escaped2
565 HGFOO is BAR
565 HGFOO is BAR
566 $ hg escaped3 HGFOO
566 $ hg escaped3 HGFOO
567 HGFOO is BAR
567 HGFOO is BAR
568 $ hg escaped4 test
568 $ hg escaped4 test
569 $0 $@
569 $0 $@
570
570
571 abbreviated name, which matches against both shell alias and the
571 abbreviated name, which matches against both shell alias and the
572 command provided extension, should be aborted.
572 command provided extension, should be aborted.
573
573
574 $ cat >> .hg/hgrc <<EOF
574 $ cat >> .hg/hgrc <<EOF
575 > [extensions]
575 > [extensions]
576 > hgext.rebase =
576 > hgext.rebase =
577 > EOF
577 > EOF
578 #if windows
578 #if windows
579 $ cat >> .hg/hgrc <<EOF
579 $ cat >> .hg/hgrc <<EOF
580 > [alias]
580 > [alias]
581 > rebate = !echo this is %HG_ARGS%
581 > rebate = !echo this is %HG_ARGS%
582 > EOF
582 > EOF
583 #else
583 #else
584 $ cat >> .hg/hgrc <<EOF
584 $ cat >> .hg/hgrc <<EOF
585 > [alias]
585 > [alias]
586 > rebate = !echo this is \$HG_ARGS
586 > rebate = !echo this is \$HG_ARGS
587 > EOF
587 > EOF
588 #endif
588 #endif
589 $ cat >> .hg/hgrc <<EOF
589 $ cat >> .hg/hgrc <<EOF
590 > rebate:doc = This is my alias which just prints something.
590 > rebate:doc = This is my alias which just prints something.
591 > rebate:help = [MYARGS]
591 > rebate:help = [MYARGS]
592 > EOF
592 > EOF
593 $ hg reba
593 $ hg reba
594 hg: command 'reba' is ambiguous:
594 hg: command 'reba' is ambiguous:
595 rebase rebate
595 rebase rebate
596 [255]
596 [255]
597 $ hg rebat
597 $ hg rebat
598 this is rebate
598 this is rebate
599 $ hg rebat --foo-bar
599 $ hg rebat --foo-bar
600 this is rebate --foo-bar
600 this is rebate --foo-bar
601
601
602 help for a shell alias
602 help for a shell alias
603
603
604 $ hg help -c | grep rebate
604 $ hg help -c | grep rebate
605 rebate This is my alias which just prints something.
605 rebate This is my alias which just prints something.
606 $ hg help rebate
606 $ hg help rebate
607 hg rebate [MYARGS]
607 hg rebate [MYARGS]
608
608
609 shell alias for: echo this is %HG_ARGS% (windows !)
609 shell alias for: echo this is %HG_ARGS% (windows !)
610 shell alias for: echo this is $HG_ARGS (no-windows !)
610 shell alias for: echo this is $HG_ARGS (no-windows !)
611
611
612 This is my alias which just prints something.
612 This is my alias which just prints something.
613
613
614 defined by:* (glob)
614 defined by:* (glob)
615 */* (glob) (?)
615 */* (glob) (?)
616 */* (glob) (?)
616 */* (glob) (?)
617 */* (glob) (?)
617 */* (glob) (?)
618
618
619 (some details hidden, use --verbose to show complete help)
619 (some details hidden, use --verbose to show complete help)
620
620
621 invalid character in user-specified help
621 invalid character in user-specified help
622
622
623 >>> with open('.hg/hgrc', 'ab') as f:
623 >>> with open('.hg/hgrc', 'ab') as f:
624 ... f.write(b'[alias]\n'
624 ... f.write(b'[alias]\n'
625 ... b'invaliddoc = log\n'
625 ... b'invaliddoc = log\n'
626 ... b'invaliddoc:doc = \xc3\xa9\n'
626 ... b'invaliddoc:doc = \xc3\xa9\n'
627 ... b'invalidhelp = log\n'
627 ... b'invalidhelp = log\n'
628 ... b'invalidhelp:help = \xc3\xa9\n') and None
628 ... b'invalidhelp:help = \xc3\xa9\n') and None
629 $ hg help invaliddoc
629 $ hg help invaliddoc
630 non-ASCII character in alias definition 'invaliddoc:doc'
630 non-ASCII character in alias definition 'invaliddoc:doc'
631 $ hg help invalidhelp
631 $ hg help invalidhelp
632 non-ASCII character in alias definition 'invalidhelp:help'
632 non-ASCII character in alias definition 'invalidhelp:help'
633 $ hg invaliddoc
633 $ hg invaliddoc
634 abort: non-ASCII character in alias definition 'invaliddoc:doc'
634 abort: non-ASCII character in alias definition 'invaliddoc:doc'
635 [255]
635 [255]
636 $ hg invalidhelp
636 $ hg invalidhelp
637 abort: non-ASCII character in alias definition 'invalidhelp:help'
637 abort: non-ASCII character in alias definition 'invalidhelp:help'
638 [255]
638 [255]
639
639
640 invalid arguments
640 invalid arguments
641
641
642 $ hg rt foo
642 $ hg rt foo
643 hg rt: invalid arguments
643 hg rt: invalid arguments
644 hg rt
644 hg rt
645
645
646 alias for: hg root
646 alias for: hg root
647
647
648 options:
648 options:
649
649
650 -T --template TEMPLATE display with template
650 -T --template TEMPLATE display with template
651
651
652 (use 'hg rt -h' to show more help)
652 (use 'hg rt -h' to show more help)
653 [255]
653 [255]
654
654
655 invalid global arguments for normal commands, aliases, and shell aliases
655 invalid global arguments for normal commands, aliases, and shell aliases
656
656
657 $ hg --invalid root
657 $ hg --invalid root
658 hg: option --invalid not recognized
658 hg: option --invalid not recognized
659 (use 'hg help -v' for a list of global options)
659 (use 'hg help -v' for a list of global options)
660 [255]
660 [255]
661 $ hg --invalid mylog
661 $ hg --invalid mylog
662 hg: option --invalid not recognized
662 hg: option --invalid not recognized
663 (use 'hg help -v' for a list of global options)
663 (use 'hg help -v' for a list of global options)
664 [255]
664 [255]
665 $ hg --invalid blank
665 $ hg --invalid blank
666 hg: option --invalid not recognized
666 hg: option --invalid not recognized
667 (use 'hg help -v' for a list of global options)
667 (use 'hg help -v' for a list of global options)
668 [255]
668 [255]
669
669
670 environment variable changes in alias commands
670 environment variable changes in alias commands
671
671
672 $ cat > $TESTTMP/expandalias.py <<EOF
672 $ cat > $TESTTMP/expandalias.py <<EOF
673 > import os
673 > import os
674 > from mercurial import cmdutil, commands, registrar
674 > from mercurial import cmdutil, commands, registrar
675 > cmdtable = {}
675 > cmdtable = {}
676 > command = registrar.command(cmdtable)
676 > command = registrar.command(cmdtable)
677 > @command(b'expandalias')
677 > @command(b'expandalias')
678 > def expandalias(ui, repo, name):
678 > def expandalias(ui, repo, name):
679 > alias = cmdutil.findcmd(name, commands.table)[1][0]
679 > alias = cmdutil.findcmd(name, commands.table)[1][0]
680 > ui.write(b'%s args: %s\n' % (name, b' '.join(alias.args)))
680 > ui.write(b'%s args: %s\n' % (name, b' '.join(alias.args)))
681 > os.environ['COUNT'] = '2'
681 > os.environ['COUNT'] = '2'
682 > ui.write(b'%s args: %s (with COUNT=2)\n' % (name, b' '.join(alias.args)))
682 > ui.write(b'%s args: %s (with COUNT=2)\n' % (name, b' '.join(alias.args)))
683 > EOF
683 > EOF
684
684
685 $ cat >> $HGRCPATH <<'EOF'
685 $ cat >> $HGRCPATH <<'EOF'
686 > [extensions]
686 > [extensions]
687 > expandalias = $TESTTMP/expandalias.py
687 > expandalias = $TESTTMP/expandalias.py
688 > [alias]
688 > [alias]
689 > showcount = log -T "$COUNT" -r .
689 > showcount = log -T "$COUNT" -r .
690 > EOF
690 > EOF
691
691
692 $ COUNT=1 hg expandalias showcount
692 $ COUNT=1 hg expandalias showcount
693 showcount args: -T 1 -r .
693 showcount args: -T 1 -r .
694 showcount args: -T 2 -r . (with COUNT=2)
694 showcount args: -T 2 -r . (with COUNT=2)
695
695
696 This should show id:
696 This should show id:
697
697
698 $ hg --config alias.log='id' log
698 $ hg --config alias.log='id' log
699 000000000000 tip
699 000000000000 tip
700
700
701 This shouldn't:
701 This shouldn't:
702
702
703 $ hg --config alias.log='id' history
703 $ hg --config alias.log='id' history
704
704
705 $ cd ../..
705 $ cd ../..
706
706
707 return code of command and shell aliases:
707 return code of command and shell aliases:
708
708
709 $ hg mycommit -R alias
709 $ hg mycommit -R alias
710 nothing changed
710 nothing changed
711 [1]
711 [1]
712 $ hg exit1
712 $ hg exit1
713 [1]
713 [1]
714
714
715 #if no-outer-repo
715 #if no-outer-repo
716 $ hg root
716 $ hg root
717 abort: no repository found in '$TESTTMP' (.hg not found)
717 abort: no repository found in '$TESTTMP' (.hg not found)
718 [255]
718 [10]
719 $ hg --config alias.hgroot='!hg root' hgroot
719 $ hg --config alias.hgroot='!hg root' hgroot
720 abort: no repository found in '$TESTTMP' (.hg not found)
720 abort: no repository found in '$TESTTMP' (.hg not found)
721 [255]
721 [10]
722 #endif
722 #endif
@@ -1,221 +1,221 b''
1 test command parsing and dispatch
1 test command parsing and dispatch
2
2
3 $ hg init a
3 $ hg init a
4 $ cd a
4 $ cd a
5
5
6 Redundant options used to crash (issue436):
6 Redundant options used to crash (issue436):
7 $ hg -v log -v
7 $ hg -v log -v
8 $ hg -v log -v x
8 $ hg -v log -v x
9
9
10 $ echo a > a
10 $ echo a > a
11 $ hg ci -Ama
11 $ hg ci -Ama
12 adding a
12 adding a
13
13
14 Missing arg:
14 Missing arg:
15
15
16 $ hg cat
16 $ hg cat
17 hg cat: invalid arguments
17 hg cat: invalid arguments
18 hg cat [OPTION]... FILE...
18 hg cat [OPTION]... FILE...
19
19
20 output the current or given revision of files
20 output the current or given revision of files
21
21
22 options ([+] can be repeated):
22 options ([+] can be repeated):
23
23
24 -o --output FORMAT print output to file with formatted name
24 -o --output FORMAT print output to file with formatted name
25 -r --rev REV print the given revision
25 -r --rev REV print the given revision
26 --decode apply any matching decode filter
26 --decode apply any matching decode filter
27 -I --include PATTERN [+] include names matching the given patterns
27 -I --include PATTERN [+] include names matching the given patterns
28 -X --exclude PATTERN [+] exclude names matching the given patterns
28 -X --exclude PATTERN [+] exclude names matching the given patterns
29 -T --template TEMPLATE display with template
29 -T --template TEMPLATE display with template
30
30
31 (use 'hg cat -h' to show more help)
31 (use 'hg cat -h' to show more help)
32 [255]
32 [255]
33
33
34 Missing parameter for early option:
34 Missing parameter for early option:
35
35
36 $ hg log -R 2>&1 | grep 'hg log'
36 $ hg log -R 2>&1 | grep 'hg log'
37 hg log: option -R requires argument
37 hg log: option -R requires argument
38 hg log [OPTION]... [FILE]
38 hg log [OPTION]... [FILE]
39 (use 'hg log -h' to show more help)
39 (use 'hg log -h' to show more help)
40
40
41 "--" may be an option value:
41 "--" may be an option value:
42
42
43 $ hg -R -- log
43 $ hg -R -- log
44 abort: repository -- not found
44 abort: repository -- not found
45 [255]
45 [255]
46 $ hg log -R --
46 $ hg log -R --
47 abort: repository -- not found
47 abort: repository -- not found
48 [255]
48 [255]
49 $ hg log -T --
49 $ hg log -T --
50 -- (no-eol)
50 -- (no-eol)
51 $ hg log -T -- -k nomatch
51 $ hg log -T -- -k nomatch
52
52
53 Parsing of early options should stop at "--":
53 Parsing of early options should stop at "--":
54
54
55 $ hg cat -- --config=hooks.pre-cat=false
55 $ hg cat -- --config=hooks.pre-cat=false
56 --config=hooks.pre-cat=false: no such file in rev cb9a9f314b8b
56 --config=hooks.pre-cat=false: no such file in rev cb9a9f314b8b
57 [1]
57 [1]
58 $ hg cat -- --debugger
58 $ hg cat -- --debugger
59 --debugger: no such file in rev cb9a9f314b8b
59 --debugger: no such file in rev cb9a9f314b8b
60 [1]
60 [1]
61
61
62 Unparsable form of early options:
62 Unparsable form of early options:
63
63
64 $ hg cat --debugg
64 $ hg cat --debugg
65 abort: option --debugger may not be abbreviated
65 abort: option --debugger may not be abbreviated
66 [255]
66 [255]
67
67
68 Parsing failure of early options should be detected before executing the
68 Parsing failure of early options should be detected before executing the
69 command:
69 command:
70
70
71 $ hg log -b '--config=hooks.pre-log=false' default
71 $ hg log -b '--config=hooks.pre-log=false' default
72 abort: option --config may not be abbreviated
72 abort: option --config may not be abbreviated
73 [255]
73 [255]
74 $ hg log -b -R. default
74 $ hg log -b -R. default
75 abort: option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo
75 abort: option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo
76 [255]
76 [255]
77 $ hg log --cwd .. -b --cwd=. default
77 $ hg log --cwd .. -b --cwd=. default
78 abort: option --cwd may not be abbreviated
78 abort: option --cwd may not be abbreviated
79 [255]
79 [255]
80
80
81 However, we can't prevent it from loading extensions and configs:
81 However, we can't prevent it from loading extensions and configs:
82
82
83 $ cat <<EOF > bad.py
83 $ cat <<EOF > bad.py
84 > raise Exception('bad')
84 > raise Exception('bad')
85 > EOF
85 > EOF
86 $ hg log -b '--config=extensions.bad=bad.py' default
86 $ hg log -b '--config=extensions.bad=bad.py' default
87 *** failed to import extension bad from bad.py: bad
87 *** failed to import extension bad from bad.py: bad
88 abort: option --config may not be abbreviated
88 abort: option --config may not be abbreviated
89 [255]
89 [255]
90
90
91 $ mkdir -p badrepo/.hg
91 $ mkdir -p badrepo/.hg
92 $ echo 'invalid-syntax' > badrepo/.hg/hgrc
92 $ echo 'invalid-syntax' > badrepo/.hg/hgrc
93 $ hg log -b -Rbadrepo default
93 $ hg log -b -Rbadrepo default
94 config error at badrepo/.hg/hgrc:1: invalid-syntax
94 config error at badrepo/.hg/hgrc:1: invalid-syntax
95 [30]
95 [30]
96
96
97 $ hg log -b --cwd=inexistent default
97 $ hg log -b --cwd=inexistent default
98 abort: $ENOENT$: 'inexistent'
98 abort: $ENOENT$: 'inexistent'
99 [255]
99 [255]
100
100
101 $ hg log -b '--config=ui.traceback=yes' 2>&1 | grep '^Traceback'
101 $ hg log -b '--config=ui.traceback=yes' 2>&1 | grep '^Traceback'
102 Traceback (most recent call last):
102 Traceback (most recent call last):
103 $ hg log -b '--config=profiling.enabled=yes' 2>&1 | grep -i sample
103 $ hg log -b '--config=profiling.enabled=yes' 2>&1 | grep -i sample
104 Sample count: .*|No samples recorded\. (re)
104 Sample count: .*|No samples recorded\. (re)
105
105
106 Early options can't be specified in [aliases] and [defaults] because they are
106 Early options can't be specified in [aliases] and [defaults] because they are
107 applied before the command name is resolved:
107 applied before the command name is resolved:
108
108
109 $ hg log -b '--config=alias.log=log --config=hooks.pre-log=false'
109 $ hg log -b '--config=alias.log=log --config=hooks.pre-log=false'
110 hg log: option -b not recognized
110 hg log: option -b not recognized
111 error in definition for alias 'log': --config may only be given on the command
111 error in definition for alias 'log': --config may only be given on the command
112 line
112 line
113 [255]
113 [255]
114
114
115 $ hg log -b '--config=defaults.log=--config=hooks.pre-log=false'
115 $ hg log -b '--config=defaults.log=--config=hooks.pre-log=false'
116 abort: option --config may not be abbreviated
116 abort: option --config may not be abbreviated
117 [255]
117 [255]
118
118
119 Shell aliases bypass any command parsing rules but for the early one:
119 Shell aliases bypass any command parsing rules but for the early one:
120
120
121 $ hg log -b '--config=alias.log=!echo howdy'
121 $ hg log -b '--config=alias.log=!echo howdy'
122 howdy
122 howdy
123
123
124 Early options must come first if HGPLAIN=+strictflags is specified:
124 Early options must come first if HGPLAIN=+strictflags is specified:
125 (BUG: chg cherry-picks early options to pass them as a server command)
125 (BUG: chg cherry-picks early options to pass them as a server command)
126
126
127 #if no-chg
127 #if no-chg
128 $ HGPLAIN=+strictflags hg log -b --config='hooks.pre-log=false' default
128 $ HGPLAIN=+strictflags hg log -b --config='hooks.pre-log=false' default
129 abort: unknown revision '--config=hooks.pre-log=false'
129 abort: unknown revision '--config=hooks.pre-log=false'
130 [255]
130 [255]
131 $ HGPLAIN=+strictflags hg log -b -R. default
131 $ HGPLAIN=+strictflags hg log -b -R. default
132 abort: unknown revision '-R.'
132 abort: unknown revision '-R.'
133 [255]
133 [255]
134 $ HGPLAIN=+strictflags hg log -b --cwd=. default
134 $ HGPLAIN=+strictflags hg log -b --cwd=. default
135 abort: unknown revision '--cwd=.'
135 abort: unknown revision '--cwd=.'
136 [255]
136 [255]
137 #endif
137 #endif
138 $ HGPLAIN=+strictflags hg log -b --debugger default
138 $ HGPLAIN=+strictflags hg log -b --debugger default
139 abort: unknown revision '--debugger'
139 abort: unknown revision '--debugger'
140 [255]
140 [255]
141 $ HGPLAIN=+strictflags hg log -b --config='alias.log=!echo pwned' default
141 $ HGPLAIN=+strictflags hg log -b --config='alias.log=!echo pwned' default
142 abort: unknown revision '--config=alias.log=!echo pwned'
142 abort: unknown revision '--config=alias.log=!echo pwned'
143 [255]
143 [255]
144
144
145 $ HGPLAIN=+strictflags hg log --config='hooks.pre-log=false' -b default
145 $ HGPLAIN=+strictflags hg log --config='hooks.pre-log=false' -b default
146 abort: option --config may not be abbreviated
146 abort: option --config may not be abbreviated
147 [255]
147 [255]
148 $ HGPLAIN=+strictflags hg log -q --cwd=.. -b default
148 $ HGPLAIN=+strictflags hg log -q --cwd=.. -b default
149 abort: option --cwd may not be abbreviated
149 abort: option --cwd may not be abbreviated
150 [255]
150 [255]
151 $ HGPLAIN=+strictflags hg log -q -R . -b default
151 $ HGPLAIN=+strictflags hg log -q -R . -b default
152 abort: option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo
152 abort: option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo
153 [255]
153 [255]
154
154
155 $ HGPLAIN=+strictflags hg --config='hooks.pre-log=false' log -b default
155 $ HGPLAIN=+strictflags hg --config='hooks.pre-log=false' log -b default
156 abort: pre-log hook exited with status 1
156 abort: pre-log hook exited with status 1
157 [255]
157 [255]
158 $ HGPLAIN=+strictflags hg --cwd .. -q -Ra log -b default
158 $ HGPLAIN=+strictflags hg --cwd .. -q -Ra log -b default
159 0:cb9a9f314b8b
159 0:cb9a9f314b8b
160 $ HGPLAIN=+strictflags hg --cwd .. -q --repository a log -b default
160 $ HGPLAIN=+strictflags hg --cwd .. -q --repository a log -b default
161 0:cb9a9f314b8b
161 0:cb9a9f314b8b
162 $ HGPLAIN=+strictflags hg --cwd .. -q --repo a log -b default
162 $ HGPLAIN=+strictflags hg --cwd .. -q --repo a log -b default
163 0:cb9a9f314b8b
163 0:cb9a9f314b8b
164
164
165 For compatibility reasons, HGPLAIN=+strictflags is not enabled by plain HGPLAIN:
165 For compatibility reasons, HGPLAIN=+strictflags is not enabled by plain HGPLAIN:
166
166
167 $ HGPLAIN= hg log --config='hooks.pre-log=false' -b default
167 $ HGPLAIN= hg log --config='hooks.pre-log=false' -b default
168 abort: pre-log hook exited with status 1
168 abort: pre-log hook exited with status 1
169 [255]
169 [255]
170 $ HGPLAINEXCEPT= hg log --cwd .. -q -Ra -b default
170 $ HGPLAINEXCEPT= hg log --cwd .. -q -Ra -b default
171 0:cb9a9f314b8b
171 0:cb9a9f314b8b
172
172
173 [defaults]
173 [defaults]
174
174
175 $ hg cat a
175 $ hg cat a
176 a
176 a
177 $ cat >> $HGRCPATH <<EOF
177 $ cat >> $HGRCPATH <<EOF
178 > [defaults]
178 > [defaults]
179 > cat = -r null
179 > cat = -r null
180 > EOF
180 > EOF
181 $ hg cat a
181 $ hg cat a
182 a: no such file in rev 000000000000
182 a: no such file in rev 000000000000
183 [1]
183 [1]
184
184
185 $ cd "$TESTTMP"
185 $ cd "$TESTTMP"
186
186
187 OSError "No such file or directory" / "The system cannot find the path
187 OSError "No such file or directory" / "The system cannot find the path
188 specified" should include filename even when it is empty
188 specified" should include filename even when it is empty
189
189
190 $ hg -R a archive ''
190 $ hg -R a archive ''
191 abort: $ENOENT$: '' (no-windows !)
191 abort: $ENOENT$: '' (no-windows !)
192 abort: $ENOTDIR$: '' (windows !)
192 abort: $ENOTDIR$: '' (windows !)
193 [255]
193 [255]
194
194
195 #if no-outer-repo
195 #if no-outer-repo
196
196
197 No repo:
197 No repo:
198
198
199 $ hg cat
199 $ hg cat
200 abort: no repository found in '$TESTTMP' (.hg not found)
200 abort: no repository found in '$TESTTMP' (.hg not found)
201 [255]
201 [10]
202
202
203 #endif
203 #endif
204
204
205 #if rmcwd
205 #if rmcwd
206
206
207 Current directory removed:
207 Current directory removed:
208
208
209 $ mkdir $TESTTMP/repo1
209 $ mkdir $TESTTMP/repo1
210 $ cd $TESTTMP/repo1
210 $ cd $TESTTMP/repo1
211 $ rm -rf $TESTTMP/repo1
211 $ rm -rf $TESTTMP/repo1
212
212
213 The output could be one of the following and something else:
213 The output could be one of the following and something else:
214 chg: abort: failed to getcwd (errno = *) (glob)
214 chg: abort: failed to getcwd (errno = *) (glob)
215 abort: error getting current working directory: * (glob)
215 abort: error getting current working directory: * (glob)
216 sh: 0: getcwd() failed: $ENOENT$
216 sh: 0: getcwd() failed: $ENOENT$
217 Since the exact behavior depends on the shell, only check it returns non-zero.
217 Since the exact behavior depends on the shell, only check it returns non-zero.
218 $ HGDEMANDIMPORT=disable hg version -q 2>/dev/null || false
218 $ HGDEMANDIMPORT=disable hg version -q 2>/dev/null || false
219 [1]
219 [1]
220
220
221 #endif
221 #endif
@@ -1,562 +1,562 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 ci -A -d'1 0' -m a
4 $ hg ci -A -d'1 0' -m a
5 adding a
5 adding a
6
6
7 $ cd ..
7 $ cd ..
8
8
9 $ hg init b
9 $ hg init b
10 $ cd b
10 $ cd b
11 $ echo b > b
11 $ echo b > b
12 $ hg ci -A -d'1 0' -m b
12 $ hg ci -A -d'1 0' -m b
13 adding b
13 adding b
14
14
15 $ cd ..
15 $ cd ..
16
16
17 $ hg clone a c
17 $ hg clone a c
18 updating to branch default
18 updating to branch default
19 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
19 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
20 $ cd c
20 $ cd c
21 $ cat >> .hg/hgrc <<EOF
21 $ cat >> .hg/hgrc <<EOF
22 > [paths]
22 > [paths]
23 > relative = ../a
23 > relative = ../a
24 > EOF
24 > EOF
25 $ hg pull -f ../b
25 $ hg pull -f ../b
26 pulling from ../b
26 pulling from ../b
27 searching for changes
27 searching for changes
28 warning: repository is unrelated
28 warning: repository is unrelated
29 requesting all changes
29 requesting all changes
30 adding changesets
30 adding changesets
31 adding manifests
31 adding manifests
32 adding file changes
32 adding file changes
33 added 1 changesets with 1 changes to 1 files (+1 heads)
33 added 1 changesets with 1 changes to 1 files (+1 heads)
34 new changesets b6c483daf290
34 new changesets b6c483daf290
35 (run 'hg heads' to see heads, 'hg merge' to merge)
35 (run 'hg heads' to see heads, 'hg merge' to merge)
36 $ hg merge
36 $ hg merge
37 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
37 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
38 (branch merge, don't forget to commit)
38 (branch merge, don't forget to commit)
39
39
40 $ cd ..
40 $ cd ..
41
41
42 Testing -R/--repository:
42 Testing -R/--repository:
43
43
44 $ hg -R a tip
44 $ hg -R a tip
45 changeset: 0:8580ff50825a
45 changeset: 0:8580ff50825a
46 tag: tip
46 tag: tip
47 user: test
47 user: test
48 date: Thu Jan 01 00:00:01 1970 +0000
48 date: Thu Jan 01 00:00:01 1970 +0000
49 summary: a
49 summary: a
50
50
51 $ hg --repository b tip
51 $ hg --repository b tip
52 changeset: 0:b6c483daf290
52 changeset: 0:b6c483daf290
53 tag: tip
53 tag: tip
54 user: test
54 user: test
55 date: Thu Jan 01 00:00:01 1970 +0000
55 date: Thu Jan 01 00:00:01 1970 +0000
56 summary: b
56 summary: b
57
57
58
58
59 -R with a URL:
59 -R with a URL:
60
60
61 $ hg -R file:a identify
61 $ hg -R file:a identify
62 8580ff50825a tip
62 8580ff50825a tip
63 $ hg -R file://localhost/`pwd`/a/ identify
63 $ hg -R file://localhost/`pwd`/a/ identify
64 8580ff50825a tip
64 8580ff50825a tip
65
65
66 -R with path aliases:
66 -R with path aliases:
67
67
68 $ cd c
68 $ cd c
69 $ hg -R default identify
69 $ hg -R default identify
70 8580ff50825a tip
70 8580ff50825a tip
71 $ hg -R relative identify
71 $ hg -R relative identify
72 8580ff50825a tip
72 8580ff50825a tip
73 $ echo '[paths]' >> $HGRCPATH
73 $ echo '[paths]' >> $HGRCPATH
74 $ echo 'relativetohome = a' >> $HGRCPATH
74 $ echo 'relativetohome = a' >> $HGRCPATH
75 $ HOME=`pwd`/../ hg -R relativetohome identify
75 $ HOME=`pwd`/../ hg -R relativetohome identify
76 8580ff50825a tip
76 8580ff50825a tip
77 $ cd ..
77 $ cd ..
78
78
79 #if no-outer-repo
79 #if no-outer-repo
80
80
81 Implicit -R:
81 Implicit -R:
82
82
83 $ hg ann a/a
83 $ hg ann a/a
84 0: a
84 0: a
85 $ hg ann a/a a/a
85 $ hg ann a/a a/a
86 0: a
86 0: a
87 $ hg ann a/a b/b
87 $ hg ann a/a b/b
88 abort: no repository found in '$TESTTMP' (.hg not found)
88 abort: no repository found in '$TESTTMP' (.hg not found)
89 [255]
89 [10]
90 $ hg -R b ann a/a
90 $ hg -R b ann a/a
91 abort: a/a not under root '$TESTTMP/b'
91 abort: a/a not under root '$TESTTMP/b'
92 (consider using '--cwd b')
92 (consider using '--cwd b')
93 [255]
93 [255]
94 $ hg log
94 $ hg log
95 abort: no repository found in '$TESTTMP' (.hg not found)
95 abort: no repository found in '$TESTTMP' (.hg not found)
96 [255]
96 [10]
97
97
98 #endif
98 #endif
99
99
100 Abbreviation of long option:
100 Abbreviation of long option:
101
101
102 $ hg --repo c tip
102 $ hg --repo c tip
103 changeset: 1:b6c483daf290
103 changeset: 1:b6c483daf290
104 tag: tip
104 tag: tip
105 parent: -1:000000000000
105 parent: -1:000000000000
106 user: test
106 user: test
107 date: Thu Jan 01 00:00:01 1970 +0000
107 date: Thu Jan 01 00:00:01 1970 +0000
108 summary: b
108 summary: b
109
109
110
110
111 earlygetopt with duplicate options (36d23de02da1):
111 earlygetopt with duplicate options (36d23de02da1):
112
112
113 $ hg --cwd a --cwd b --cwd c tip
113 $ hg --cwd a --cwd b --cwd c tip
114 changeset: 1:b6c483daf290
114 changeset: 1:b6c483daf290
115 tag: tip
115 tag: tip
116 parent: -1:000000000000
116 parent: -1:000000000000
117 user: test
117 user: test
118 date: Thu Jan 01 00:00:01 1970 +0000
118 date: Thu Jan 01 00:00:01 1970 +0000
119 summary: b
119 summary: b
120
120
121 $ hg --repo c --repository b -R a tip
121 $ hg --repo c --repository b -R a tip
122 changeset: 0:8580ff50825a
122 changeset: 0:8580ff50825a
123 tag: tip
123 tag: tip
124 user: test
124 user: test
125 date: Thu Jan 01 00:00:01 1970 +0000
125 date: Thu Jan 01 00:00:01 1970 +0000
126 summary: a
126 summary: a
127
127
128
128
129 earlygetopt short option without following space:
129 earlygetopt short option without following space:
130
130
131 $ hg -q -Rb tip
131 $ hg -q -Rb tip
132 0:b6c483daf290
132 0:b6c483daf290
133
133
134 earlygetopt with illegal abbreviations:
134 earlygetopt with illegal abbreviations:
135
135
136 $ hg --confi "foo.bar=baz"
136 $ hg --confi "foo.bar=baz"
137 abort: option --config may not be abbreviated
137 abort: option --config may not be abbreviated
138 [255]
138 [255]
139 $ hg --cw a tip
139 $ hg --cw a tip
140 abort: option --cwd may not be abbreviated
140 abort: option --cwd may not be abbreviated
141 [255]
141 [255]
142 $ hg --rep a tip
142 $ hg --rep a tip
143 abort: option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo
143 abort: option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo
144 [255]
144 [255]
145 $ hg --repositor a tip
145 $ hg --repositor a tip
146 abort: option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo
146 abort: option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo
147 [255]
147 [255]
148 $ hg -qR a tip
148 $ hg -qR a tip
149 abort: option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo
149 abort: option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo
150 [255]
150 [255]
151 $ hg -qRa tip
151 $ hg -qRa tip
152 abort: option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo
152 abort: option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo
153 [255]
153 [255]
154
154
155 Testing --cwd:
155 Testing --cwd:
156
156
157 $ hg --cwd a parents
157 $ hg --cwd a parents
158 changeset: 0:8580ff50825a
158 changeset: 0:8580ff50825a
159 tag: tip
159 tag: tip
160 user: test
160 user: test
161 date: Thu Jan 01 00:00:01 1970 +0000
161 date: Thu Jan 01 00:00:01 1970 +0000
162 summary: a
162 summary: a
163
163
164
164
165 Testing -y/--noninteractive - just be sure it is parsed:
165 Testing -y/--noninteractive - just be sure it is parsed:
166
166
167 $ hg --cwd a tip -q --noninteractive
167 $ hg --cwd a tip -q --noninteractive
168 0:8580ff50825a
168 0:8580ff50825a
169 $ hg --cwd a tip -q -y
169 $ hg --cwd a tip -q -y
170 0:8580ff50825a
170 0:8580ff50825a
171
171
172 Testing -q/--quiet:
172 Testing -q/--quiet:
173
173
174 $ hg -R a -q tip
174 $ hg -R a -q tip
175 0:8580ff50825a
175 0:8580ff50825a
176 $ hg -R b -q tip
176 $ hg -R b -q tip
177 0:b6c483daf290
177 0:b6c483daf290
178 $ hg -R c --quiet parents
178 $ hg -R c --quiet parents
179 0:8580ff50825a
179 0:8580ff50825a
180 1:b6c483daf290
180 1:b6c483daf290
181
181
182 Testing -v/--verbose:
182 Testing -v/--verbose:
183
183
184 $ hg --cwd c head -v
184 $ hg --cwd c head -v
185 changeset: 1:b6c483daf290
185 changeset: 1:b6c483daf290
186 tag: tip
186 tag: tip
187 parent: -1:000000000000
187 parent: -1:000000000000
188 user: test
188 user: test
189 date: Thu Jan 01 00:00:01 1970 +0000
189 date: Thu Jan 01 00:00:01 1970 +0000
190 files: b
190 files: b
191 description:
191 description:
192 b
192 b
193
193
194
194
195 changeset: 0:8580ff50825a
195 changeset: 0:8580ff50825a
196 user: test
196 user: test
197 date: Thu Jan 01 00:00:01 1970 +0000
197 date: Thu Jan 01 00:00:01 1970 +0000
198 files: a
198 files: a
199 description:
199 description:
200 a
200 a
201
201
202
202
203 $ hg --cwd b tip --verbose
203 $ hg --cwd b tip --verbose
204 changeset: 0:b6c483daf290
204 changeset: 0:b6c483daf290
205 tag: tip
205 tag: tip
206 user: test
206 user: test
207 date: Thu Jan 01 00:00:01 1970 +0000
207 date: Thu Jan 01 00:00:01 1970 +0000
208 files: b
208 files: b
209 description:
209 description:
210 b
210 b
211
211
212
212
213
213
214 Testing --config:
214 Testing --config:
215
215
216 $ hg --cwd c --config paths.quuxfoo=bar paths | grep quuxfoo > /dev/null && echo quuxfoo
216 $ hg --cwd c --config paths.quuxfoo=bar paths | grep quuxfoo > /dev/null && echo quuxfoo
217 quuxfoo
217 quuxfoo
218 $ hg --cwd c --config '' tip -q
218 $ hg --cwd c --config '' tip -q
219 abort: malformed --config option: '' (use --config section.name=value)
219 abort: malformed --config option: '' (use --config section.name=value)
220 [255]
220 [255]
221 $ hg --cwd c --config a.b tip -q
221 $ hg --cwd c --config a.b tip -q
222 abort: malformed --config option: 'a.b' (use --config section.name=value)
222 abort: malformed --config option: 'a.b' (use --config section.name=value)
223 [255]
223 [255]
224 $ hg --cwd c --config a tip -q
224 $ hg --cwd c --config a tip -q
225 abort: malformed --config option: 'a' (use --config section.name=value)
225 abort: malformed --config option: 'a' (use --config section.name=value)
226 [255]
226 [255]
227 $ hg --cwd c --config a.= tip -q
227 $ hg --cwd c --config a.= tip -q
228 abort: malformed --config option: 'a.=' (use --config section.name=value)
228 abort: malformed --config option: 'a.=' (use --config section.name=value)
229 [255]
229 [255]
230 $ hg --cwd c --config .b= tip -q
230 $ hg --cwd c --config .b= tip -q
231 abort: malformed --config option: '.b=' (use --config section.name=value)
231 abort: malformed --config option: '.b=' (use --config section.name=value)
232 [255]
232 [255]
233
233
234 Testing --debug:
234 Testing --debug:
235
235
236 $ hg --cwd c log --debug
236 $ hg --cwd c log --debug
237 changeset: 1:b6c483daf2907ce5825c0bb50f5716226281cc1a
237 changeset: 1:b6c483daf2907ce5825c0bb50f5716226281cc1a
238 tag: tip
238 tag: tip
239 phase: public
239 phase: public
240 parent: -1:0000000000000000000000000000000000000000
240 parent: -1:0000000000000000000000000000000000000000
241 parent: -1:0000000000000000000000000000000000000000
241 parent: -1:0000000000000000000000000000000000000000
242 manifest: 1:23226e7a252cacdc2d99e4fbdc3653441056de49
242 manifest: 1:23226e7a252cacdc2d99e4fbdc3653441056de49
243 user: test
243 user: test
244 date: Thu Jan 01 00:00:01 1970 +0000
244 date: Thu Jan 01 00:00:01 1970 +0000
245 files+: b
245 files+: b
246 extra: branch=default
246 extra: branch=default
247 description:
247 description:
248 b
248 b
249
249
250
250
251 changeset: 0:8580ff50825a50c8f716709acdf8de0deddcd6ab
251 changeset: 0:8580ff50825a50c8f716709acdf8de0deddcd6ab
252 phase: public
252 phase: public
253 parent: -1:0000000000000000000000000000000000000000
253 parent: -1:0000000000000000000000000000000000000000
254 parent: -1:0000000000000000000000000000000000000000
254 parent: -1:0000000000000000000000000000000000000000
255 manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
255 manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
256 user: test
256 user: test
257 date: Thu Jan 01 00:00:01 1970 +0000
257 date: Thu Jan 01 00:00:01 1970 +0000
258 files+: a
258 files+: a
259 extra: branch=default
259 extra: branch=default
260 description:
260 description:
261 a
261 a
262
262
263
263
264
264
265 Testing --traceback:
265 Testing --traceback:
266
266
267 #if no-chg
267 #if no-chg
268 $ hg --cwd c --config x --traceback id 2>&1 | grep -i 'traceback'
268 $ hg --cwd c --config x --traceback id 2>&1 | grep -i 'traceback'
269 Traceback (most recent call last):
269 Traceback (most recent call last):
270 Traceback (most recent call last): (py3 !)
270 Traceback (most recent call last): (py3 !)
271 #else
271 #else
272 Traceback for '--config' errors not supported with chg.
272 Traceback for '--config' errors not supported with chg.
273 $ hg --cwd c --config x --traceback id 2>&1 | grep -i 'traceback'
273 $ hg --cwd c --config x --traceback id 2>&1 | grep -i 'traceback'
274 [1]
274 [1]
275 #endif
275 #endif
276
276
277 Testing --time:
277 Testing --time:
278
278
279 $ hg --cwd a --time id
279 $ hg --cwd a --time id
280 8580ff50825a tip
280 8580ff50825a tip
281 time: real * (glob)
281 time: real * (glob)
282
282
283 Testing --version:
283 Testing --version:
284
284
285 $ hg --version -q
285 $ hg --version -q
286 Mercurial Distributed SCM * (glob)
286 Mercurial Distributed SCM * (glob)
287
287
288 hide outer repo
288 hide outer repo
289 $ hg init
289 $ hg init
290
290
291 Testing -h/--help:
291 Testing -h/--help:
292
292
293 #if no-extraextensions
293 #if no-extraextensions
294
294
295 $ hg -h
295 $ hg -h
296 Mercurial Distributed SCM
296 Mercurial Distributed SCM
297
297
298 list of commands:
298 list of commands:
299
299
300 Repository creation:
300 Repository creation:
301
301
302 clone make a copy of an existing repository
302 clone make a copy of an existing repository
303 init create a new repository in the given directory
303 init create a new repository in the given directory
304
304
305 Remote repository management:
305 Remote repository management:
306
306
307 incoming show new changesets found in source
307 incoming show new changesets found in source
308 outgoing show changesets not found in the destination
308 outgoing show changesets not found in the destination
309 paths show aliases for remote repositories
309 paths show aliases for remote repositories
310 pull pull changes from the specified source
310 pull pull changes from the specified source
311 push push changes to the specified destination
311 push push changes to the specified destination
312 serve start stand-alone webserver
312 serve start stand-alone webserver
313
313
314 Change creation:
314 Change creation:
315
315
316 commit commit the specified files or all outstanding changes
316 commit commit the specified files or all outstanding changes
317
317
318 Change manipulation:
318 Change manipulation:
319
319
320 backout reverse effect of earlier changeset
320 backout reverse effect of earlier changeset
321 graft copy changes from other branches onto the current branch
321 graft copy changes from other branches onto the current branch
322 merge merge another revision into working directory
322 merge merge another revision into working directory
323
323
324 Change organization:
324 Change organization:
325
325
326 bookmarks create a new bookmark or list existing bookmarks
326 bookmarks create a new bookmark or list existing bookmarks
327 branch set or show the current branch name
327 branch set or show the current branch name
328 branches list repository named branches
328 branches list repository named branches
329 phase set or show the current phase name
329 phase set or show the current phase name
330 tag add one or more tags for the current or given revision
330 tag add one or more tags for the current or given revision
331 tags list repository tags
331 tags list repository tags
332
332
333 File content management:
333 File content management:
334
334
335 annotate show changeset information by line for each file
335 annotate show changeset information by line for each file
336 cat output the current or given revision of files
336 cat output the current or given revision of files
337 copy mark files as copied for the next commit
337 copy mark files as copied for the next commit
338 diff diff repository (or selected files)
338 diff diff repository (or selected files)
339 grep search for a pattern in specified files
339 grep search for a pattern in specified files
340
340
341 Change navigation:
341 Change navigation:
342
342
343 bisect subdivision search of changesets
343 bisect subdivision search of changesets
344 heads show branch heads
344 heads show branch heads
345 identify identify the working directory or specified revision
345 identify identify the working directory or specified revision
346 log show revision history of entire repository or files
346 log show revision history of entire repository or files
347
347
348 Working directory management:
348 Working directory management:
349
349
350 add add the specified files on the next commit
350 add add the specified files on the next commit
351 addremove add all new files, delete all missing files
351 addremove add all new files, delete all missing files
352 files list tracked files
352 files list tracked files
353 forget forget the specified files on the next commit
353 forget forget the specified files on the next commit
354 remove remove the specified files on the next commit
354 remove remove the specified files on the next commit
355 rename rename files; equivalent of copy + remove
355 rename rename files; equivalent of copy + remove
356 resolve redo merges or set/view the merge status of files
356 resolve redo merges or set/view the merge status of files
357 revert restore files to their checkout state
357 revert restore files to their checkout state
358 root print the root (top) of the current working directory
358 root print the root (top) of the current working directory
359 shelve save and set aside changes from the working directory
359 shelve save and set aside changes from the working directory
360 status show changed files in the working directory
360 status show changed files in the working directory
361 summary summarize working directory state
361 summary summarize working directory state
362 unshelve restore a shelved change to the working directory
362 unshelve restore a shelved change to the working directory
363 update update working directory (or switch revisions)
363 update update working directory (or switch revisions)
364
364
365 Change import/export:
365 Change import/export:
366
366
367 archive create an unversioned archive of a repository revision
367 archive create an unversioned archive of a repository revision
368 bundle create a bundle file
368 bundle create a bundle file
369 export dump the header and diffs for one or more changesets
369 export dump the header and diffs for one or more changesets
370 import import an ordered set of patches
370 import import an ordered set of patches
371 unbundle apply one or more bundle files
371 unbundle apply one or more bundle files
372
372
373 Repository maintenance:
373 Repository maintenance:
374
374
375 manifest output the current or given revision of the project manifest
375 manifest output the current or given revision of the project manifest
376 recover roll back an interrupted transaction
376 recover roll back an interrupted transaction
377 verify verify the integrity of the repository
377 verify verify the integrity of the repository
378
378
379 Help:
379 Help:
380
380
381 config show combined config settings from all hgrc files
381 config show combined config settings from all hgrc files
382 help show help for a given topic or a help overview
382 help show help for a given topic or a help overview
383 version output version and copyright information
383 version output version and copyright information
384
384
385 additional help topics:
385 additional help topics:
386
386
387 Mercurial identifiers:
387 Mercurial identifiers:
388
388
389 filesets Specifying File Sets
389 filesets Specifying File Sets
390 hgignore Syntax for Mercurial Ignore Files
390 hgignore Syntax for Mercurial Ignore Files
391 patterns File Name Patterns
391 patterns File Name Patterns
392 revisions Specifying Revisions
392 revisions Specifying Revisions
393 urls URL Paths
393 urls URL Paths
394
394
395 Mercurial output:
395 Mercurial output:
396
396
397 color Colorizing Outputs
397 color Colorizing Outputs
398 dates Date Formats
398 dates Date Formats
399 diffs Diff Formats
399 diffs Diff Formats
400 templating Template Usage
400 templating Template Usage
401
401
402 Mercurial configuration:
402 Mercurial configuration:
403
403
404 config Configuration Files
404 config Configuration Files
405 environment Environment Variables
405 environment Environment Variables
406 extensions Using Additional Features
406 extensions Using Additional Features
407 flags Command-line flags
407 flags Command-line flags
408 hgweb Configuring hgweb
408 hgweb Configuring hgweb
409 merge-tools Merge Tools
409 merge-tools Merge Tools
410 pager Pager Support
410 pager Pager Support
411
411
412 Concepts:
412 Concepts:
413
413
414 bundlespec Bundle File Formats
414 bundlespec Bundle File Formats
415 glossary Glossary
415 glossary Glossary
416 phases Working with Phases
416 phases Working with Phases
417 subrepos Subrepositories
417 subrepos Subrepositories
418
418
419 Miscellaneous:
419 Miscellaneous:
420
420
421 deprecated Deprecated Features
421 deprecated Deprecated Features
422 internals Technical implementation topics
422 internals Technical implementation topics
423 scripting Using Mercurial from scripts and automation
423 scripting Using Mercurial from scripts and automation
424
424
425 (use 'hg help -v' to show built-in aliases and global options)
425 (use 'hg help -v' to show built-in aliases and global options)
426
426
427 $ hg --help
427 $ hg --help
428 Mercurial Distributed SCM
428 Mercurial Distributed SCM
429
429
430 list of commands:
430 list of commands:
431
431
432 Repository creation:
432 Repository creation:
433
433
434 clone make a copy of an existing repository
434 clone make a copy of an existing repository
435 init create a new repository in the given directory
435 init create a new repository in the given directory
436
436
437 Remote repository management:
437 Remote repository management:
438
438
439 incoming show new changesets found in source
439 incoming show new changesets found in source
440 outgoing show changesets not found in the destination
440 outgoing show changesets not found in the destination
441 paths show aliases for remote repositories
441 paths show aliases for remote repositories
442 pull pull changes from the specified source
442 pull pull changes from the specified source
443 push push changes to the specified destination
443 push push changes to the specified destination
444 serve start stand-alone webserver
444 serve start stand-alone webserver
445
445
446 Change creation:
446 Change creation:
447
447
448 commit commit the specified files or all outstanding changes
448 commit commit the specified files or all outstanding changes
449
449
450 Change manipulation:
450 Change manipulation:
451
451
452 backout reverse effect of earlier changeset
452 backout reverse effect of earlier changeset
453 graft copy changes from other branches onto the current branch
453 graft copy changes from other branches onto the current branch
454 merge merge another revision into working directory
454 merge merge another revision into working directory
455
455
456 Change organization:
456 Change organization:
457
457
458 bookmarks create a new bookmark or list existing bookmarks
458 bookmarks create a new bookmark or list existing bookmarks
459 branch set or show the current branch name
459 branch set or show the current branch name
460 branches list repository named branches
460 branches list repository named branches
461 phase set or show the current phase name
461 phase set or show the current phase name
462 tag add one or more tags for the current or given revision
462 tag add one or more tags for the current or given revision
463 tags list repository tags
463 tags list repository tags
464
464
465 File content management:
465 File content management:
466
466
467 annotate show changeset information by line for each file
467 annotate show changeset information by line for each file
468 cat output the current or given revision of files
468 cat output the current or given revision of files
469 copy mark files as copied for the next commit
469 copy mark files as copied for the next commit
470 diff diff repository (or selected files)
470 diff diff repository (or selected files)
471 grep search for a pattern in specified files
471 grep search for a pattern in specified files
472
472
473 Change navigation:
473 Change navigation:
474
474
475 bisect subdivision search of changesets
475 bisect subdivision search of changesets
476 heads show branch heads
476 heads show branch heads
477 identify identify the working directory or specified revision
477 identify identify the working directory or specified revision
478 log show revision history of entire repository or files
478 log show revision history of entire repository or files
479
479
480 Working directory management:
480 Working directory management:
481
481
482 add add the specified files on the next commit
482 add add the specified files on the next commit
483 addremove add all new files, delete all missing files
483 addremove add all new files, delete all missing files
484 files list tracked files
484 files list tracked files
485 forget forget the specified files on the next commit
485 forget forget the specified files on the next commit
486 remove remove the specified files on the next commit
486 remove remove the specified files on the next commit
487 rename rename files; equivalent of copy + remove
487 rename rename files; equivalent of copy + remove
488 resolve redo merges or set/view the merge status of files
488 resolve redo merges or set/view the merge status of files
489 revert restore files to their checkout state
489 revert restore files to their checkout state
490 root print the root (top) of the current working directory
490 root print the root (top) of the current working directory
491 shelve save and set aside changes from the working directory
491 shelve save and set aside changes from the working directory
492 status show changed files in the working directory
492 status show changed files in the working directory
493 summary summarize working directory state
493 summary summarize working directory state
494 unshelve restore a shelved change to the working directory
494 unshelve restore a shelved change to the working directory
495 update update working directory (or switch revisions)
495 update update working directory (or switch revisions)
496
496
497 Change import/export:
497 Change import/export:
498
498
499 archive create an unversioned archive of a repository revision
499 archive create an unversioned archive of a repository revision
500 bundle create a bundle file
500 bundle create a bundle file
501 export dump the header and diffs for one or more changesets
501 export dump the header and diffs for one or more changesets
502 import import an ordered set of patches
502 import import an ordered set of patches
503 unbundle apply one or more bundle files
503 unbundle apply one or more bundle files
504
504
505 Repository maintenance:
505 Repository maintenance:
506
506
507 manifest output the current or given revision of the project manifest
507 manifest output the current or given revision of the project manifest
508 recover roll back an interrupted transaction
508 recover roll back an interrupted transaction
509 verify verify the integrity of the repository
509 verify verify the integrity of the repository
510
510
511 Help:
511 Help:
512
512
513 config show combined config settings from all hgrc files
513 config show combined config settings from all hgrc files
514 help show help for a given topic or a help overview
514 help show help for a given topic or a help overview
515 version output version and copyright information
515 version output version and copyright information
516
516
517 additional help topics:
517 additional help topics:
518
518
519 Mercurial identifiers:
519 Mercurial identifiers:
520
520
521 filesets Specifying File Sets
521 filesets Specifying File Sets
522 hgignore Syntax for Mercurial Ignore Files
522 hgignore Syntax for Mercurial Ignore Files
523 patterns File Name Patterns
523 patterns File Name Patterns
524 revisions Specifying Revisions
524 revisions Specifying Revisions
525 urls URL Paths
525 urls URL Paths
526
526
527 Mercurial output:
527 Mercurial output:
528
528
529 color Colorizing Outputs
529 color Colorizing Outputs
530 dates Date Formats
530 dates Date Formats
531 diffs Diff Formats
531 diffs Diff Formats
532 templating Template Usage
532 templating Template Usage
533
533
534 Mercurial configuration:
534 Mercurial configuration:
535
535
536 config Configuration Files
536 config Configuration Files
537 environment Environment Variables
537 environment Environment Variables
538 extensions Using Additional Features
538 extensions Using Additional Features
539 flags Command-line flags
539 flags Command-line flags
540 hgweb Configuring hgweb
540 hgweb Configuring hgweb
541 merge-tools Merge Tools
541 merge-tools Merge Tools
542 pager Pager Support
542 pager Pager Support
543
543
544 Concepts:
544 Concepts:
545
545
546 bundlespec Bundle File Formats
546 bundlespec Bundle File Formats
547 glossary Glossary
547 glossary Glossary
548 phases Working with Phases
548 phases Working with Phases
549 subrepos Subrepositories
549 subrepos Subrepositories
550
550
551 Miscellaneous:
551 Miscellaneous:
552
552
553 deprecated Deprecated Features
553 deprecated Deprecated Features
554 internals Technical implementation topics
554 internals Technical implementation topics
555 scripting Using Mercurial from scripts and automation
555 scripting Using Mercurial from scripts and automation
556
556
557 (use 'hg help -v' to show built-in aliases and global options)
557 (use 'hg help -v' to show built-in aliases and global options)
558
558
559 #endif
559 #endif
560
560
561 Not tested: --debugger
561 Not tested: --debugger
562
562
@@ -1,74 +1,74 b''
1 (Translations are optional)
1 (Translations are optional)
2
2
3 #if gettext no-outer-repo
3 #if gettext no-outer-repo
4
4
5 Test that translations are compiled and installed correctly.
5 Test that translations are compiled and installed correctly.
6
6
7 Default encoding in tests is "ascii" and the translation is encoded
7 Default encoding in tests is "ascii" and the translation is encoded
8 using the "replace" error handler:
8 using the "replace" error handler:
9
9
10 $ LANGUAGE=pt_BR hg tip
10 $ LANGUAGE=pt_BR hg tip
11 abortado: n?o foi encontrado um reposit?rio em '$TESTTMP' (.hg n?o encontrado)
11 abortado: n?o foi encontrado um reposit?rio em '$TESTTMP' (.hg n?o encontrado)
12 [255]
12 [10]
13
13
14 Using a more accommodating encoding:
14 Using a more accommodating encoding:
15
15
16 $ HGENCODING=UTF-8 LANGUAGE=pt_BR hg tip
16 $ HGENCODING=UTF-8 LANGUAGE=pt_BR hg tip
17 abortado: n\xc3\xa3o foi encontrado um reposit\xc3\xb3rio em '$TESTTMP' (.hg n\xc3\xa3o encontrado) (esc)
17 abortado: n\xc3\xa3o foi encontrado um reposit\xc3\xb3rio em '$TESTTMP' (.hg n\xc3\xa3o encontrado) (esc)
18 [255]
18 [10]
19
19
20 Different encoding:
20 Different encoding:
21
21
22 $ HGENCODING=Latin-1 LANGUAGE=pt_BR hg tip
22 $ HGENCODING=Latin-1 LANGUAGE=pt_BR hg tip
23 abortado: n\xe3o foi encontrado um reposit\xf3rio em '$TESTTMP' (.hg n\xe3o encontrado) (esc)
23 abortado: n\xe3o foi encontrado um reposit\xf3rio em '$TESTTMP' (.hg n\xe3o encontrado) (esc)
24 [255]
24 [10]
25
25
26 #endif
26 #endif
27
27
28 #if gettext
28 #if gettext
29
29
30 Test keyword search in translated help text:
30 Test keyword search in translated help text:
31
31
32 $ HGENCODING=UTF-8 LANGUAGE=de hg help -k Aktualisiert
32 $ HGENCODING=UTF-8 LANGUAGE=de hg help -k Aktualisiert
33 Themen:
33 Themen:
34
34
35 subrepos Unterarchive
35 subrepos Unterarchive
36
36
37 Befehle:
37 Befehle:
38
38
39 pull Ruft \xc3\x84nderungen von der angegebenen Quelle ab (esc)
39 pull Ruft \xc3\x84nderungen von der angegebenen Quelle ab (esc)
40 update Aktualisiert das Arbeitsverzeichnis (oder wechselt die Version)
40 update Aktualisiert das Arbeitsverzeichnis (oder wechselt die Version)
41
41
42 #endif
42 #endif
43
43
44 Check Mercurial specific translation problems in each *.po files, and
44 Check Mercurial specific translation problems in each *.po files, and
45 tool itself by doctest
45 tool itself by doctest
46
46
47 $ cd "$TESTDIR"/../i18n
47 $ cd "$TESTDIR"/../i18n
48 $ "$PYTHON" check-translation.py *.po
48 $ "$PYTHON" check-translation.py *.po
49 $ "$PYTHON" check-translation.py --doctest
49 $ "$PYTHON" check-translation.py --doctest
50 $ cd $TESTTMP
50 $ cd $TESTTMP
51
51
52 #if gettext
52 #if gettext
53
53
54 Check i18n cache isn't reused after encoding change:
54 Check i18n cache isn't reused after encoding change:
55
55
56 $ cat > $TESTTMP/encodingchange.py << EOF
56 $ cat > $TESTTMP/encodingchange.py << EOF
57 > from mercurial.i18n import _
57 > from mercurial.i18n import _
58 > from mercurial import encoding, registrar
58 > from mercurial import encoding, registrar
59 > cmdtable = {}
59 > cmdtable = {}
60 > command = registrar.command(cmdtable)
60 > command = registrar.command(cmdtable)
61 > @command(b'encodingchange', norepo=True)
61 > @command(b'encodingchange', norepo=True)
62 > def encodingchange(ui):
62 > def encodingchange(ui):
63 > for encode in (b'ascii', b'UTF-8', b'ascii', b'UTF-8'):
63 > for encode in (b'ascii', b'UTF-8', b'ascii', b'UTF-8'):
64 > encoding.encoding = encode
64 > encoding.encoding = encode
65 > ui.write(b'%s\n' % _(b'(EXPERIMENTAL)'))
65 > ui.write(b'%s\n' % _(b'(EXPERIMENTAL)'))
66 > EOF
66 > EOF
67
67
68 $ LANGUAGE=ja hg --config extensions.encodingchange=$TESTTMP/encodingchange.py encodingchange
68 $ LANGUAGE=ja hg --config extensions.encodingchange=$TESTTMP/encodingchange.py encodingchange
69 (?????)
69 (?????)
70 (\xe5\xae\x9f\xe9\xa8\x93\xe7\x9a\x84\xe5\xae\x9f\xe8\xa3\x85) (esc)
70 (\xe5\xae\x9f\xe9\xa8\x93\xe7\x9a\x84\xe5\xae\x9f\xe8\xa3\x85) (esc)
71 (?????)
71 (?????)
72 (\xe5\xae\x9f\xe9\xa8\x93\xe7\x9a\x84\xe5\xae\x9f\xe8\xa3\x85) (esc)
72 (\xe5\xae\x9f\xe9\xa8\x93\xe7\x9a\x84\xe5\xae\x9f\xe8\xa3\x85) (esc)
73
73
74 #endif
74 #endif
@@ -1,706 +1,706 b''
1 $ cat >> $HGRCPATH <<EOF
1 $ cat >> $HGRCPATH <<EOF
2 > [commands]
2 > [commands]
3 > status.verbose=1
3 > status.verbose=1
4 > EOF
4 > EOF
5
5
6 # Construct the following history tree:
6 # Construct the following history tree:
7 #
7 #
8 # @ 5:e1bb631146ca b1
8 # @ 5:e1bb631146ca b1
9 # |
9 # |
10 # o 4:a4fdb3b883c4 0:b608b9236435 b1
10 # o 4:a4fdb3b883c4 0:b608b9236435 b1
11 # |
11 # |
12 # | o 3:4b57d2520816 1:44592833ba9f
12 # | o 3:4b57d2520816 1:44592833ba9f
13 # | |
13 # | |
14 # | | o 2:063f31070f65
14 # | | o 2:063f31070f65
15 # | |/
15 # | |/
16 # | o 1:44592833ba9f
16 # | o 1:44592833ba9f
17 # |/
17 # |/
18 # o 0:b608b9236435
18 # o 0:b608b9236435
19
19
20 $ mkdir b1
20 $ mkdir b1
21 $ cd b1
21 $ cd b1
22 $ hg init
22 $ hg init
23 $ echo foo > foo
23 $ echo foo > foo
24 $ echo zero > a
24 $ echo zero > a
25 $ hg init sub
25 $ hg init sub
26 $ echo suba > sub/suba
26 $ echo suba > sub/suba
27 $ hg --cwd sub ci -Am addsuba
27 $ hg --cwd sub ci -Am addsuba
28 adding suba
28 adding suba
29 $ echo 'sub = sub' > .hgsub
29 $ echo 'sub = sub' > .hgsub
30 $ hg ci -qAm0
30 $ hg ci -qAm0
31 $ echo one > a ; hg ci -m1
31 $ echo one > a ; hg ci -m1
32 $ echo two > a ; hg ci -m2
32 $ echo two > a ; hg ci -m2
33 $ hg up -q 1
33 $ hg up -q 1
34 $ echo three > a ; hg ci -qm3
34 $ echo three > a ; hg ci -qm3
35 $ hg up -q 0
35 $ hg up -q 0
36 $ hg branch -q b1
36 $ hg branch -q b1
37 $ echo four > a ; hg ci -qm4
37 $ echo four > a ; hg ci -qm4
38 $ echo five > a ; hg ci -qm5
38 $ echo five > a ; hg ci -qm5
39
39
40 Initial repo state:
40 Initial repo state:
41
41
42 $ hg log -G --template '{rev}:{node|short} {parents} {branches}\n'
42 $ hg log -G --template '{rev}:{node|short} {parents} {branches}\n'
43 @ 5:ff252e8273df b1
43 @ 5:ff252e8273df b1
44 |
44 |
45 o 4:d047485b3896 0:60829823a42a b1
45 o 4:d047485b3896 0:60829823a42a b1
46 |
46 |
47 | o 3:6efa171f091b 1:0786582aa4b1
47 | o 3:6efa171f091b 1:0786582aa4b1
48 | |
48 | |
49 | | o 2:bd10386d478c
49 | | o 2:bd10386d478c
50 | |/
50 | |/
51 | o 1:0786582aa4b1
51 | o 1:0786582aa4b1
52 |/
52 |/
53 o 0:60829823a42a
53 o 0:60829823a42a
54
54
55
55
56 Make sure update doesn't assume b1 is a repository if invoked from outside:
56 Make sure update doesn't assume b1 is a repository if invoked from outside:
57
57
58 $ cd ..
58 $ cd ..
59 $ hg update b1
59 $ hg update b1
60 abort: no repository found in '$TESTTMP' (.hg not found)
60 abort: no repository found in '$TESTTMP' (.hg not found)
61 [255]
61 [10]
62 $ cd b1
62 $ cd b1
63
63
64 Test helper functions:
64 Test helper functions:
65
65
66 $ revtest () {
66 $ revtest () {
67 > msg=$1
67 > msg=$1
68 > dirtyflag=$2 # 'clean', 'dirty' or 'dirtysub'
68 > dirtyflag=$2 # 'clean', 'dirty' or 'dirtysub'
69 > startrev=$3
69 > startrev=$3
70 > targetrev=$4
70 > targetrev=$4
71 > opt=$5
71 > opt=$5
72 > hg up -qC $startrev
72 > hg up -qC $startrev
73 > test $dirtyflag = dirty && echo dirty > foo
73 > test $dirtyflag = dirty && echo dirty > foo
74 > test $dirtyflag = dirtysub && echo dirty > sub/suba
74 > test $dirtyflag = dirtysub && echo dirty > sub/suba
75 > hg up $opt $targetrev
75 > hg up $opt $targetrev
76 > hg parent --template 'parent={rev}\n'
76 > hg parent --template 'parent={rev}\n'
77 > hg stat -S
77 > hg stat -S
78 > }
78 > }
79
79
80 $ norevtest () {
80 $ norevtest () {
81 > msg=$1
81 > msg=$1
82 > dirtyflag=$2 # 'clean', 'dirty' or 'dirtysub'
82 > dirtyflag=$2 # 'clean', 'dirty' or 'dirtysub'
83 > startrev=$3
83 > startrev=$3
84 > opt=$4
84 > opt=$4
85 > hg up -qC $startrev
85 > hg up -qC $startrev
86 > test $dirtyflag = dirty && echo dirty > foo
86 > test $dirtyflag = dirty && echo dirty > foo
87 > test $dirtyflag = dirtysub && echo dirty > sub/suba
87 > test $dirtyflag = dirtysub && echo dirty > sub/suba
88 > hg up $opt
88 > hg up $opt
89 > hg parent --template 'parent={rev}\n'
89 > hg parent --template 'parent={rev}\n'
90 > hg stat -S
90 > hg stat -S
91 > }
91 > }
92
92
93 Test cases are documented in a table in the update function of merge.py.
93 Test cases are documented in a table in the update function of merge.py.
94 Cases are run as shown in that table, row by row.
94 Cases are run as shown in that table, row by row.
95
95
96 $ norevtest 'none clean linear' clean 4
96 $ norevtest 'none clean linear' clean 4
97 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
97 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
98 parent=5
98 parent=5
99
99
100 $ norevtest 'none clean same' clean 2
100 $ norevtest 'none clean same' clean 2
101 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
101 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
102 updated to "bd10386d478c: 2"
102 updated to "bd10386d478c: 2"
103 1 other heads for branch "default"
103 1 other heads for branch "default"
104 parent=2
104 parent=2
105
105
106
106
107 $ revtest 'none clean linear' clean 1 2
107 $ revtest 'none clean linear' clean 1 2
108 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
108 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
109 parent=2
109 parent=2
110
110
111 $ revtest 'none clean same' clean 2 3
111 $ revtest 'none clean same' clean 2 3
112 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
112 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
113 parent=3
113 parent=3
114
114
115 $ revtest 'none clean cross' clean 3 4
115 $ revtest 'none clean cross' clean 3 4
116 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
116 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
117 parent=4
117 parent=4
118
118
119
119
120 $ revtest 'none dirty linear' dirty 1 2
120 $ revtest 'none dirty linear' dirty 1 2
121 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
121 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
122 parent=2
122 parent=2
123 M foo
123 M foo
124
124
125 $ revtest 'none dirtysub linear' dirtysub 1 2
125 $ revtest 'none dirtysub linear' dirtysub 1 2
126 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
126 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
127 parent=2
127 parent=2
128 M sub/suba
128 M sub/suba
129
129
130 $ revtest 'none dirty same' dirty 2 3
130 $ revtest 'none dirty same' dirty 2 3
131 abort: uncommitted changes
131 abort: uncommitted changes
132 (commit or update --clean to discard changes)
132 (commit or update --clean to discard changes)
133 parent=2
133 parent=2
134 M foo
134 M foo
135
135
136 $ revtest 'none dirtysub same' dirtysub 2 3
136 $ revtest 'none dirtysub same' dirtysub 2 3
137 abort: uncommitted changes
137 abort: uncommitted changes
138 (commit or update --clean to discard changes)
138 (commit or update --clean to discard changes)
139 parent=2
139 parent=2
140 M sub/suba
140 M sub/suba
141
141
142 $ revtest 'none dirty cross' dirty 3 4
142 $ revtest 'none dirty cross' dirty 3 4
143 abort: uncommitted changes
143 abort: uncommitted changes
144 (commit or update --clean to discard changes)
144 (commit or update --clean to discard changes)
145 parent=3
145 parent=3
146 M foo
146 M foo
147
147
148 $ norevtest 'none dirty cross' dirty 2
148 $ norevtest 'none dirty cross' dirty 2
149 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
149 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
150 updated to "bd10386d478c: 2"
150 updated to "bd10386d478c: 2"
151 1 other heads for branch "default"
151 1 other heads for branch "default"
152 parent=2
152 parent=2
153 M foo
153 M foo
154
154
155 $ revtest 'none dirtysub cross' dirtysub 3 4
155 $ revtest 'none dirtysub cross' dirtysub 3 4
156 abort: uncommitted changes
156 abort: uncommitted changes
157 (commit or update --clean to discard changes)
157 (commit or update --clean to discard changes)
158 parent=3
158 parent=3
159 M sub/suba
159 M sub/suba
160
160
161 $ revtest '-C dirty linear' dirty 1 2 -C
161 $ revtest '-C dirty linear' dirty 1 2 -C
162 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
162 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
163 parent=2
163 parent=2
164
164
165 $ revtest '-c dirty linear' dirty 1 2 -c
165 $ revtest '-c dirty linear' dirty 1 2 -c
166 abort: uncommitted changes
166 abort: uncommitted changes
167 parent=1
167 parent=1
168 M foo
168 M foo
169
169
170 $ revtest '-m dirty linear' dirty 1 2 -m
170 $ revtest '-m dirty linear' dirty 1 2 -m
171 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
171 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
172 parent=2
172 parent=2
173 M foo
173 M foo
174
174
175 $ revtest '-m dirty cross' dirty 3 4 -m
175 $ revtest '-m dirty cross' dirty 3 4 -m
176 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
176 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
177 parent=4
177 parent=4
178 M foo
178 M foo
179
179
180 $ revtest '-c dirtysub linear' dirtysub 1 2 -c
180 $ revtest '-c dirtysub linear' dirtysub 1 2 -c
181 abort: uncommitted changes in subrepository "sub"
181 abort: uncommitted changes in subrepository "sub"
182 parent=1
182 parent=1
183 M sub/suba
183 M sub/suba
184
184
185 $ norevtest '-c clean same' clean 2 -c
185 $ norevtest '-c clean same' clean 2 -c
186 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
186 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
187 updated to "bd10386d478c: 2"
187 updated to "bd10386d478c: 2"
188 1 other heads for branch "default"
188 1 other heads for branch "default"
189 parent=2
189 parent=2
190
190
191 $ revtest '-cC dirty linear' dirty 1 2 -cC
191 $ revtest '-cC dirty linear' dirty 1 2 -cC
192 abort: cannot specify both --clean and --check
192 abort: cannot specify both --clean and --check
193 parent=1
193 parent=1
194 M foo
194 M foo
195
195
196 $ revtest '-mc dirty linear' dirty 1 2 -mc
196 $ revtest '-mc dirty linear' dirty 1 2 -mc
197 abort: cannot specify both --check and --merge
197 abort: cannot specify both --check and --merge
198 parent=1
198 parent=1
199 M foo
199 M foo
200
200
201 $ revtest '-mC dirty linear' dirty 1 2 -mC
201 $ revtest '-mC dirty linear' dirty 1 2 -mC
202 abort: cannot specify both --clean and --merge
202 abort: cannot specify both --clean and --merge
203 parent=1
203 parent=1
204 M foo
204 M foo
205
205
206 $ echo '[commands]' >> .hg/hgrc
206 $ echo '[commands]' >> .hg/hgrc
207 $ echo 'update.check = abort' >> .hg/hgrc
207 $ echo 'update.check = abort' >> .hg/hgrc
208
208
209 $ revtest 'none dirty linear' dirty 1 2
209 $ revtest 'none dirty linear' dirty 1 2
210 abort: uncommitted changes
210 abort: uncommitted changes
211 parent=1
211 parent=1
212 M foo
212 M foo
213
213
214 $ revtest 'none dirty linear' dirty 1 2 -c
214 $ revtest 'none dirty linear' dirty 1 2 -c
215 abort: uncommitted changes
215 abort: uncommitted changes
216 parent=1
216 parent=1
217 M foo
217 M foo
218
218
219 $ revtest 'none dirty linear' dirty 1 2 -C
219 $ revtest 'none dirty linear' dirty 1 2 -C
220 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
220 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
221 parent=2
221 parent=2
222
222
223 $ echo 'update.check = none' >> .hg/hgrc
223 $ echo 'update.check = none' >> .hg/hgrc
224
224
225 $ revtest 'none dirty cross' dirty 3 4
225 $ revtest 'none dirty cross' dirty 3 4
226 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
226 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
227 parent=4
227 parent=4
228 M foo
228 M foo
229
229
230 $ revtest 'none dirty linear' dirty 1 2
230 $ revtest 'none dirty linear' dirty 1 2
231 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
231 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
232 parent=2
232 parent=2
233 M foo
233 M foo
234
234
235 $ revtest 'none dirty linear' dirty 1 2 -c
235 $ revtest 'none dirty linear' dirty 1 2 -c
236 abort: uncommitted changes
236 abort: uncommitted changes
237 parent=1
237 parent=1
238 M foo
238 M foo
239
239
240 $ revtest 'none dirty linear' dirty 1 2 -C
240 $ revtest 'none dirty linear' dirty 1 2 -C
241 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
241 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
242 parent=2
242 parent=2
243
243
244 $ hg co -qC 3
244 $ hg co -qC 3
245 $ echo dirty >> a
245 $ echo dirty >> a
246 $ hg co --tool :merge3 4
246 $ hg co --tool :merge3 4
247 merging a
247 merging a
248 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
248 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
249 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
249 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
250 use 'hg resolve' to retry unresolved file merges
250 use 'hg resolve' to retry unresolved file merges
251 [1]
251 [1]
252 $ hg log -G --template '{rev}:{node|short} {parents} {branches}\n'
252 $ hg log -G --template '{rev}:{node|short} {parents} {branches}\n'
253 o 5:ff252e8273df b1
253 o 5:ff252e8273df b1
254 |
254 |
255 @ 4:d047485b3896 0:60829823a42a b1
255 @ 4:d047485b3896 0:60829823a42a b1
256 |
256 |
257 | % 3:6efa171f091b 1:0786582aa4b1
257 | % 3:6efa171f091b 1:0786582aa4b1
258 | |
258 | |
259 | | o 2:bd10386d478c
259 | | o 2:bd10386d478c
260 | |/
260 | |/
261 | o 1:0786582aa4b1
261 | o 1:0786582aa4b1
262 |/
262 |/
263 o 0:60829823a42a
263 o 0:60829823a42a
264
264
265 $ hg st
265 $ hg st
266 M a
266 M a
267 ? a.orig
267 ? a.orig
268 # Unresolved merge conflicts:
268 # Unresolved merge conflicts:
269 #
269 #
270 # a
270 # a
271 #
271 #
272 # To mark files as resolved: hg resolve --mark FILE
272 # To mark files as resolved: hg resolve --mark FILE
273
273
274 $ cat a
274 $ cat a
275 <<<<<<< working copy: 6efa171f091b - test: 3
275 <<<<<<< working copy: 6efa171f091b - test: 3
276 three
276 three
277 dirty
277 dirty
278 ||||||| base
278 ||||||| base
279 three
279 three
280 =======
280 =======
281 four
281 four
282 >>>>>>> destination: d047485b3896 b1 - test: 4
282 >>>>>>> destination: d047485b3896 b1 - test: 4
283 $ rm a.orig
283 $ rm a.orig
284
284
285 $ echo 'update.check = noconflict' >> .hg/hgrc
285 $ echo 'update.check = noconflict' >> .hg/hgrc
286
286
287 $ revtest 'none dirty cross' dirty 3 4
287 $ revtest 'none dirty cross' dirty 3 4
288 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
288 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
289 parent=4
289 parent=4
290 M foo
290 M foo
291
291
292 $ revtest 'none dirty linear' dirty 1 2
292 $ revtest 'none dirty linear' dirty 1 2
293 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
293 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
294 parent=2
294 parent=2
295 M foo
295 M foo
296
296
297 $ revtest 'none dirty linear' dirty 1 2 -c
297 $ revtest 'none dirty linear' dirty 1 2 -c
298 abort: uncommitted changes
298 abort: uncommitted changes
299 parent=1
299 parent=1
300 M foo
300 M foo
301
301
302 $ revtest 'none dirty linear' dirty 1 2 -C
302 $ revtest 'none dirty linear' dirty 1 2 -C
303 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
303 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
304 parent=2
304 parent=2
305
305
306 Locally added file is allowed
306 Locally added file is allowed
307 $ hg up -qC 3
307 $ hg up -qC 3
308 $ echo a > bar
308 $ echo a > bar
309 $ hg add bar
309 $ hg add bar
310 $ hg up -q 4
310 $ hg up -q 4
311 $ hg st
311 $ hg st
312 A bar
312 A bar
313 $ hg forget bar
313 $ hg forget bar
314 $ rm bar
314 $ rm bar
315
315
316 Locally removed file is allowed
316 Locally removed file is allowed
317 $ hg up -qC 3
317 $ hg up -qC 3
318 $ hg rm foo
318 $ hg rm foo
319 $ hg up -q 4
319 $ hg up -q 4
320
320
321 File conflict is not allowed
321 File conflict is not allowed
322 $ hg up -qC 3
322 $ hg up -qC 3
323 $ echo dirty >> a
323 $ echo dirty >> a
324 $ hg up -q 4
324 $ hg up -q 4
325 abort: conflicting changes
325 abort: conflicting changes
326 (commit or update --clean to discard changes)
326 (commit or update --clean to discard changes)
327 [255]
327 [255]
328 $ hg up -m 4
328 $ hg up -m 4
329 merging a
329 merging a
330 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
330 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
331 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
331 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
332 use 'hg resolve' to retry unresolved file merges
332 use 'hg resolve' to retry unresolved file merges
333 [1]
333 [1]
334 $ rm a.orig
334 $ rm a.orig
335 $ hg status
335 $ hg status
336 M a
336 M a
337 # Unresolved merge conflicts:
337 # Unresolved merge conflicts:
338 #
338 #
339 # a
339 # a
340 #
340 #
341 # To mark files as resolved: hg resolve --mark FILE
341 # To mark files as resolved: hg resolve --mark FILE
342
342
343 $ hg resolve -l
343 $ hg resolve -l
344 U a
344 U a
345
345
346 Try to make empty commit while there are conflicts
346 Try to make empty commit while there are conflicts
347 $ hg revert -r . a
347 $ hg revert -r . a
348 $ rm a.orig
348 $ rm a.orig
349 $ hg ci -m empty
349 $ hg ci -m empty
350 abort: unresolved merge conflicts (see 'hg help resolve')
350 abort: unresolved merge conflicts (see 'hg help resolve')
351 [255]
351 [255]
352 $ hg resolve -m a
352 $ hg resolve -m a
353 (no more unresolved files)
353 (no more unresolved files)
354 $ hg resolve -l
354 $ hg resolve -l
355 R a
355 R a
356 $ hg ci -m empty
356 $ hg ci -m empty
357 nothing changed
357 nothing changed
358 [1]
358 [1]
359 $ hg resolve -l
359 $ hg resolve -l
360
360
361 Change/delete conflict is not allowed
361 Change/delete conflict is not allowed
362 $ hg up -qC 3
362 $ hg up -qC 3
363 $ hg rm foo
363 $ hg rm foo
364 $ hg up -q 4
364 $ hg up -q 4
365
365
366 Uses default value of "linear" when value is misspelled
366 Uses default value of "linear" when value is misspelled
367 $ echo 'update.check = linyar' >> .hg/hgrc
367 $ echo 'update.check = linyar' >> .hg/hgrc
368
368
369 $ revtest 'dirty cross' dirty 3 4
369 $ revtest 'dirty cross' dirty 3 4
370 abort: uncommitted changes
370 abort: uncommitted changes
371 (commit or update --clean to discard changes)
371 (commit or update --clean to discard changes)
372 parent=3
372 parent=3
373 M foo
373 M foo
374
374
375 Setup for later tests
375 Setup for later tests
376 $ revtest 'none dirty linear' dirty 1 2 -c
376 $ revtest 'none dirty linear' dirty 1 2 -c
377 abort: uncommitted changes
377 abort: uncommitted changes
378 parent=1
378 parent=1
379 M foo
379 M foo
380
380
381 $ cd ..
381 $ cd ..
382
382
383 Test updating to null revision
383 Test updating to null revision
384
384
385 $ hg init null-repo
385 $ hg init null-repo
386 $ cd null-repo
386 $ cd null-repo
387 $ echo a > a
387 $ echo a > a
388 $ hg add a
388 $ hg add a
389 $ hg ci -m a
389 $ hg ci -m a
390 $ hg up -qC 0
390 $ hg up -qC 0
391 $ echo b > b
391 $ echo b > b
392 $ hg add b
392 $ hg add b
393 $ hg up null
393 $ hg up null
394 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
394 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
395 $ hg st
395 $ hg st
396 A b
396 A b
397 $ hg up -q 0
397 $ hg up -q 0
398 $ hg st
398 $ hg st
399 A b
399 A b
400 $ hg up -qC null
400 $ hg up -qC null
401 $ hg st
401 $ hg st
402 ? b
402 ? b
403 $ cd ..
403 $ cd ..
404
404
405 Test updating with closed head
405 Test updating with closed head
406 ---------------------------------------------------------------------
406 ---------------------------------------------------------------------
407
407
408 $ hg clone -U -q b1 closed-heads
408 $ hg clone -U -q b1 closed-heads
409 $ cd closed-heads
409 $ cd closed-heads
410
410
411 Test updating if at least one non-closed branch head exists
411 Test updating if at least one non-closed branch head exists
412
412
413 if on the closed branch head:
413 if on the closed branch head:
414 - update to "."
414 - update to "."
415 - "updated to a closed branch head ...." message is displayed
415 - "updated to a closed branch head ...." message is displayed
416 - "N other heads for ...." message is displayed
416 - "N other heads for ...." message is displayed
417
417
418 $ hg update -q -C 3
418 $ hg update -q -C 3
419 $ hg commit --close-branch -m 6
419 $ hg commit --close-branch -m 6
420 $ norevtest "on closed branch head" clean 6
420 $ norevtest "on closed branch head" clean 6
421 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
421 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
422 no open descendant heads on branch "default", updating to a closed head
422 no open descendant heads on branch "default", updating to a closed head
423 (committing will reopen the head, use 'hg heads .' to see 1 other heads)
423 (committing will reopen the head, use 'hg heads .' to see 1 other heads)
424 parent=6
424 parent=6
425
425
426 if descendant non-closed branch head exists, and it is only one branch head:
426 if descendant non-closed branch head exists, and it is only one branch head:
427 - update to it, even if its revision is less than closed one
427 - update to it, even if its revision is less than closed one
428 - "N other heads for ...." message isn't displayed
428 - "N other heads for ...." message isn't displayed
429
429
430 $ norevtest "non-closed 2 should be chosen" clean 1
430 $ norevtest "non-closed 2 should be chosen" clean 1
431 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
431 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
432 parent=2
432 parent=2
433
433
434 if all descendant branch heads are closed, but there is another branch head:
434 if all descendant branch heads are closed, but there is another branch head:
435 - update to the tipmost descendant head
435 - update to the tipmost descendant head
436 - "updated to a closed branch head ...." message is displayed
436 - "updated to a closed branch head ...." message is displayed
437 - "N other heads for ...." message is displayed
437 - "N other heads for ...." message is displayed
438
438
439 $ norevtest "all descendant branch heads are closed" clean 3
439 $ norevtest "all descendant branch heads are closed" clean 3
440 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
440 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
441 no open descendant heads on branch "default", updating to a closed head
441 no open descendant heads on branch "default", updating to a closed head
442 (committing will reopen the head, use 'hg heads .' to see 1 other heads)
442 (committing will reopen the head, use 'hg heads .' to see 1 other heads)
443 parent=6
443 parent=6
444
444
445 Test updating if all branch heads are closed
445 Test updating if all branch heads are closed
446
446
447 if on the closed branch head:
447 if on the closed branch head:
448 - update to "."
448 - update to "."
449 - "updated to a closed branch head ...." message is displayed
449 - "updated to a closed branch head ...." message is displayed
450 - "all heads of branch ...." message is displayed
450 - "all heads of branch ...." message is displayed
451
451
452 $ hg update -q -C 2
452 $ hg update -q -C 2
453 $ hg commit --close-branch -m 7
453 $ hg commit --close-branch -m 7
454 $ norevtest "all heads of branch default are closed" clean 6
454 $ norevtest "all heads of branch default are closed" clean 6
455 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
455 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
456 no open descendant heads on branch "default", updating to a closed head
456 no open descendant heads on branch "default", updating to a closed head
457 (committing will reopen branch "default")
457 (committing will reopen branch "default")
458 parent=6
458 parent=6
459
459
460 if not on the closed branch head:
460 if not on the closed branch head:
461 - update to the tipmost descendant (closed) head
461 - update to the tipmost descendant (closed) head
462 - "updated to a closed branch head ...." message is displayed
462 - "updated to a closed branch head ...." message is displayed
463 - "all heads of branch ...." message is displayed
463 - "all heads of branch ...." message is displayed
464
464
465 $ norevtest "all heads of branch default are closed" clean 1
465 $ norevtest "all heads of branch default are closed" clean 1
466 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
466 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
467 no open descendant heads on branch "default", updating to a closed head
467 no open descendant heads on branch "default", updating to a closed head
468 (committing will reopen branch "default")
468 (committing will reopen branch "default")
469 parent=7
469 parent=7
470
470
471 $ cd ..
471 $ cd ..
472
472
473 Test updating if "default" branch doesn't exist and no revision is
473 Test updating if "default" branch doesn't exist and no revision is
474 checked out (= "default" is used as current branch)
474 checked out (= "default" is used as current branch)
475
475
476 $ hg init no-default-branch
476 $ hg init no-default-branch
477 $ cd no-default-branch
477 $ cd no-default-branch
478
478
479 $ hg branch foobar
479 $ hg branch foobar
480 marked working directory as branch foobar
480 marked working directory as branch foobar
481 (branches are permanent and global, did you want a bookmark?)
481 (branches are permanent and global, did you want a bookmark?)
482 $ echo a > a
482 $ echo a > a
483 $ hg commit -m "#0" -A
483 $ hg commit -m "#0" -A
484 adding a
484 adding a
485 $ echo 1 >> a
485 $ echo 1 >> a
486 $ hg commit -m "#1"
486 $ hg commit -m "#1"
487 $ hg update -q 0
487 $ hg update -q 0
488 $ echo 3 >> a
488 $ echo 3 >> a
489 $ hg commit -m "#2"
489 $ hg commit -m "#2"
490 created new head
490 created new head
491 $ hg commit --close-branch -m "#3"
491 $ hg commit --close-branch -m "#3"
492
492
493 if there is at least one non-closed branch head:
493 if there is at least one non-closed branch head:
494 - update to the tipmost branch head
494 - update to the tipmost branch head
495
495
496 $ norevtest "non-closed 1 should be chosen" clean null
496 $ norevtest "non-closed 1 should be chosen" clean null
497 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
497 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
498 parent=1
498 parent=1
499
499
500 if all branch heads are closed
500 if all branch heads are closed
501 - update to "tip"
501 - update to "tip"
502 - "updated to a closed branch head ...." message is displayed
502 - "updated to a closed branch head ...." message is displayed
503 - "all heads for branch "XXXX" are closed" message is displayed
503 - "all heads for branch "XXXX" are closed" message is displayed
504
504
505 $ hg update -q -C 1
505 $ hg update -q -C 1
506 $ hg commit --close-branch -m "#4"
506 $ hg commit --close-branch -m "#4"
507
507
508 $ norevtest "all branches are closed" clean null
508 $ norevtest "all branches are closed" clean null
509 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
509 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
510 no open descendant heads on branch "foobar", updating to a closed head
510 no open descendant heads on branch "foobar", updating to a closed head
511 (committing will reopen branch "foobar")
511 (committing will reopen branch "foobar")
512 parent=4
512 parent=4
513
513
514 $ cd ../b1
514 $ cd ../b1
515
515
516 Test obsolescence behavior
516 Test obsolescence behavior
517 ---------------------------------------------------------------------
517 ---------------------------------------------------------------------
518
518
519 successors should be taken in account when checking head destination
519 successors should be taken in account when checking head destination
520
520
521 $ cat << EOF >> $HGRCPATH
521 $ cat << EOF >> $HGRCPATH
522 > [ui]
522 > [ui]
523 > logtemplate={rev}:{node|short} {desc|firstline}
523 > logtemplate={rev}:{node|short} {desc|firstline}
524 > [experimental]
524 > [experimental]
525 > evolution.createmarkers=True
525 > evolution.createmarkers=True
526 > EOF
526 > EOF
527
527
528 Test no-argument update to a successor of an obsoleted changeset
528 Test no-argument update to a successor of an obsoleted changeset
529
529
530 $ hg log -G
530 $ hg log -G
531 o 5:ff252e8273df 5
531 o 5:ff252e8273df 5
532 |
532 |
533 o 4:d047485b3896 4
533 o 4:d047485b3896 4
534 |
534 |
535 | o 3:6efa171f091b 3
535 | o 3:6efa171f091b 3
536 | |
536 | |
537 | | o 2:bd10386d478c 2
537 | | o 2:bd10386d478c 2
538 | |/
538 | |/
539 | @ 1:0786582aa4b1 1
539 | @ 1:0786582aa4b1 1
540 |/
540 |/
541 o 0:60829823a42a 0
541 o 0:60829823a42a 0
542
542
543 $ hg book bm -r 3
543 $ hg book bm -r 3
544 $ hg status
544 $ hg status
545 M foo
545 M foo
546
546
547 We add simple obsolescence marker between 3 and 4 (indirect successors)
547 We add simple obsolescence marker between 3 and 4 (indirect successors)
548
548
549 $ hg id --debug -i -r 3
549 $ hg id --debug -i -r 3
550 6efa171f091b00a3c35edc15d48c52a498929953
550 6efa171f091b00a3c35edc15d48c52a498929953
551 $ hg id --debug -i -r 4
551 $ hg id --debug -i -r 4
552 d047485b3896813b2a624e86201983520f003206
552 d047485b3896813b2a624e86201983520f003206
553 $ hg debugobsolete 6efa171f091b00a3c35edc15d48c52a498929953 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
553 $ hg debugobsolete 6efa171f091b00a3c35edc15d48c52a498929953 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
554 1 new obsolescence markers
554 1 new obsolescence markers
555 obsoleted 1 changesets
555 obsoleted 1 changesets
556 $ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa d047485b3896813b2a624e86201983520f003206
556 $ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa d047485b3896813b2a624e86201983520f003206
557 1 new obsolescence markers
557 1 new obsolescence markers
558
558
559 Test that 5 is detected as a valid destination from 3 and also accepts moving
559 Test that 5 is detected as a valid destination from 3 and also accepts moving
560 the bookmark (issue4015)
560 the bookmark (issue4015)
561
561
562 $ hg up --quiet --hidden 3
562 $ hg up --quiet --hidden 3
563 $ hg up 5
563 $ hg up 5
564 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
564 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
565 $ hg book bm
565 $ hg book bm
566 moving bookmark 'bm' forward from 6efa171f091b
566 moving bookmark 'bm' forward from 6efa171f091b
567 $ hg bookmarks
567 $ hg bookmarks
568 * bm 5:ff252e8273df
568 * bm 5:ff252e8273df
569
569
570 Test that we abort before we warn about the hidden commit if the working
570 Test that we abort before we warn about the hidden commit if the working
571 directory is dirty
571 directory is dirty
572 $ echo conflict > a
572 $ echo conflict > a
573 $ hg up --hidden 3
573 $ hg up --hidden 3
574 abort: uncommitted changes
574 abort: uncommitted changes
575 (commit or update --clean to discard changes)
575 (commit or update --clean to discard changes)
576 [255]
576 [255]
577
577
578 Test that we still warn also when there are conflicts
578 Test that we still warn also when there are conflicts
579 $ hg up -m --hidden 3
579 $ hg up -m --hidden 3
580 merging a
580 merging a
581 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
581 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
582 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
582 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
583 use 'hg resolve' to retry unresolved file merges
583 use 'hg resolve' to retry unresolved file merges
584 (leaving bookmark bm)
584 (leaving bookmark bm)
585 updated to hidden changeset 6efa171f091b
585 updated to hidden changeset 6efa171f091b
586 (hidden revision '6efa171f091b' was rewritten as: d047485b3896)
586 (hidden revision '6efa171f091b' was rewritten as: d047485b3896)
587 [1]
587 [1]
588
588
589 Test that statuses are reported properly before and after merge resolution.
589 Test that statuses are reported properly before and after merge resolution.
590 $ rm a.orig
590 $ rm a.orig
591 $ hg resolve -l
591 $ hg resolve -l
592 U a
592 U a
593 $ hg status
593 $ hg status
594 M a
594 M a
595 M foo
595 M foo
596 # Unresolved merge conflicts:
596 # Unresolved merge conflicts:
597 #
597 #
598 # a
598 # a
599 #
599 #
600 # To mark files as resolved: hg resolve --mark FILE
600 # To mark files as resolved: hg resolve --mark FILE
601
601
602
602
603 $ hg revert -r . a
603 $ hg revert -r . a
604
604
605 $ rm a.orig
605 $ rm a.orig
606 $ hg resolve -l
606 $ hg resolve -l
607 U a
607 U a
608 $ hg status
608 $ hg status
609 M foo
609 M foo
610 # Unresolved merge conflicts:
610 # Unresolved merge conflicts:
611 #
611 #
612 # a
612 # a
613 #
613 #
614 # To mark files as resolved: hg resolve --mark FILE
614 # To mark files as resolved: hg resolve --mark FILE
615
615
616 $ hg status -Tjson
616 $ hg status -Tjson
617 [
617 [
618 {
618 {
619 "itemtype": "file",
619 "itemtype": "file",
620 "path": "foo",
620 "path": "foo",
621 "status": "M"
621 "status": "M"
622 },
622 },
623 {
623 {
624 "itemtype": "file",
624 "itemtype": "file",
625 "path": "a",
625 "path": "a",
626 "unresolved": true
626 "unresolved": true
627 }
627 }
628 ]
628 ]
629
629
630 $ hg resolve -m
630 $ hg resolve -m
631 (no more unresolved files)
631 (no more unresolved files)
632
632
633 $ hg resolve -l
633 $ hg resolve -l
634 R a
634 R a
635 $ hg status
635 $ hg status
636 M foo
636 M foo
637 # No unresolved merge conflicts.
637 # No unresolved merge conflicts.
638
638
639 $ hg status -Tjson
639 $ hg status -Tjson
640 [
640 [
641 {
641 {
642 "itemtype": "file",
642 "itemtype": "file",
643 "path": "foo",
643 "path": "foo",
644 "status": "M"
644 "status": "M"
645 }
645 }
646 ]
646 ]
647
647
648 Test that 4 is detected as the no-argument destination from 3 and also moves
648 Test that 4 is detected as the no-argument destination from 3 and also moves
649 the bookmark with it
649 the bookmark with it
650 $ hg up --quiet 0 # we should be able to update to 3 directly
650 $ hg up --quiet 0 # we should be able to update to 3 directly
651 $ hg status
651 $ hg status
652 M foo
652 M foo
653 $ hg up --quiet --hidden 3 # but not implemented yet.
653 $ hg up --quiet --hidden 3 # but not implemented yet.
654 updated to hidden changeset 6efa171f091b
654 updated to hidden changeset 6efa171f091b
655 (hidden revision '6efa171f091b' was rewritten as: d047485b3896)
655 (hidden revision '6efa171f091b' was rewritten as: d047485b3896)
656 $ hg book -f bm
656 $ hg book -f bm
657 $ hg up
657 $ hg up
658 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
658 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
659 updating bookmark bm
659 updating bookmark bm
660 $ hg book
660 $ hg book
661 * bm 4:d047485b3896
661 * bm 4:d047485b3896
662
662
663 Test that 5 is detected as a valid destination from 1
663 Test that 5 is detected as a valid destination from 1
664 $ hg up --quiet 0 # we should be able to update to 3 directly
664 $ hg up --quiet 0 # we should be able to update to 3 directly
665 $ hg up --quiet --hidden 3 # but not implemented yet.
665 $ hg up --quiet --hidden 3 # but not implemented yet.
666 updated to hidden changeset 6efa171f091b
666 updated to hidden changeset 6efa171f091b
667 (hidden revision '6efa171f091b' was rewritten as: d047485b3896)
667 (hidden revision '6efa171f091b' was rewritten as: d047485b3896)
668 $ hg up 5
668 $ hg up 5
669 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
669 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
670
670
671 Test that 5 is not detected as a valid destination from 2
671 Test that 5 is not detected as a valid destination from 2
672 $ hg up --quiet 0
672 $ hg up --quiet 0
673 $ hg up --quiet 2
673 $ hg up --quiet 2
674 $ hg up 5
674 $ hg up 5
675 abort: uncommitted changes
675 abort: uncommitted changes
676 (commit or update --clean to discard changes)
676 (commit or update --clean to discard changes)
677 [255]
677 [255]
678
678
679 Test that we don't crash when updating from a pruned changeset (i.e. has no
679 Test that we don't crash when updating from a pruned changeset (i.e. has no
680 successors). Behavior should probably be that we update to the first
680 successors). Behavior should probably be that we update to the first
681 non-obsolete parent but that will be decided later.
681 non-obsolete parent but that will be decided later.
682 $ hg id --debug -r 2
682 $ hg id --debug -r 2
683 bd10386d478cd5a9faf2e604114c8e6da62d3889
683 bd10386d478cd5a9faf2e604114c8e6da62d3889
684 $ hg up --quiet 0
684 $ hg up --quiet 0
685 $ hg up --quiet 2
685 $ hg up --quiet 2
686 $ hg debugobsolete bd10386d478cd5a9faf2e604114c8e6da62d3889
686 $ hg debugobsolete bd10386d478cd5a9faf2e604114c8e6da62d3889
687 1 new obsolescence markers
687 1 new obsolescence markers
688 obsoleted 1 changesets
688 obsoleted 1 changesets
689 $ hg up
689 $ hg up
690 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
690 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
691
691
692 Test experimental revset support
692 Test experimental revset support
693
693
694 $ hg log -r '_destupdate()'
694 $ hg log -r '_destupdate()'
695 2:bd10386d478c 2 (no-eol)
695 2:bd10386d478c 2 (no-eol)
696
696
697 Test that boolean flags allow --no-flag specification to override [defaults]
697 Test that boolean flags allow --no-flag specification to override [defaults]
698 $ cat >> $HGRCPATH <<EOF
698 $ cat >> $HGRCPATH <<EOF
699 > [defaults]
699 > [defaults]
700 > update = --check
700 > update = --check
701 > EOF
701 > EOF
702 $ hg co 2
702 $ hg co 2
703 abort: uncommitted changes
703 abort: uncommitted changes
704 [20]
704 [20]
705 $ hg co --no-check 2
705 $ hg co --no-check 2
706 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
706 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
General Comments 0
You need to be logged in to leave comments. Login now