comparison mercurial/commands.py @ 3098:fe9b13e35e46

Merge with crew
author Matt Mackall <mpm@selenic.com>
date Fri, 15 Sep 2006 15:22:45 -0500
parents 25857e00af8e
children 81da3c45aabd
comparison
equal deleted inserted replaced
3097:1b738357bba9 3098:fe9b13e35e46
6 # of the GNU General Public License, incorporated herein by reference. 6 # of the GNU General Public License, incorporated herein by reference.
7 7
8 from demandload import demandload 8 from demandload import demandload
9 from node import * 9 from node import *
10 from i18n import gettext as _ 10 from i18n import gettext as _
11 demandload(globals(), "os re sys signal shutil imp urllib pdb") 11 demandload(globals(), "os re sys signal shutil imp urllib pdb shlex")
12 demandload(globals(), "fancyopts ui hg util lock revlog templater bundlerepo") 12 demandload(globals(), "fancyopts ui hg util lock revlog templater bundlerepo")
13 demandload(globals(), "fnmatch difflib patch random signal tempfile time") 13 demandload(globals(), "fnmatch difflib patch random signal tempfile time")
14 demandload(globals(), "traceback errno socket version struct atexit sets bz2") 14 demandload(globals(), "traceback errno socket version struct atexit sets bz2")
15 demandload(globals(), "archival cStringIO changegroup") 15 demandload(globals(), "archival cStringIO changegroup")
16 demandload(globals(), "cmdutil hgweb.server sshserver") 16 demandload(globals(), "cmdutil hgweb.server sshserver")
48 except IOError, inst: 48 except IOError, inst:
49 raise util.Abort(_("can't read commit message '%s': %s") % 49 raise util.Abort(_("can't read commit message '%s': %s") %
50 (logfile, inst.strerror)) 50 (logfile, inst.strerror))
51 return message 51 return message
52 52
53 def defaultrev(repo, rev=None, default='tip'):
54 """returns rev if it is specified, otherwise the working dir
55 parent if there is only one, or tip if there is no working
56 dir"""
57 if rev:
58 return rev
59
60 p1, p2 = repo.dirstate.parents()
61 if p2 != nullid:
62 raise util.Abort(_('uncommitted merge - please provide a '
63 'specific revision'))
64 if p1 != nullid:
65 return hex(p1)
66 return default
67
53 def walkchangerevs(ui, repo, pats, opts): 68 def walkchangerevs(ui, repo, pats, opts):
54 '''Iterate over files and the revs they changed in. 69 '''Iterate over files and the revs they changed in.
55 70
56 Callers most commonly need to iterate backwards over the history 71 Callers most commonly need to iterate backwards over the history
57 it is interested in. Doing so has awful (quadratic-looking) 72 it is interested in. Doing so has awful (quadratic-looking)
97 112
98 if repo.changelog.count() == 0: 113 if repo.changelog.count() == 0:
99 return [], False, matchfn 114 return [], False, matchfn
100 115
101 if follow: 116 if follow:
102 p = repo.dirstate.parents()[0] 117 defrange = '%s:0' % defaultrev(repo)
103 if p == nullid:
104 ui.warn(_('No working directory revision; defaulting to tip\n'))
105 start = 'tip'
106 else:
107 start = repo.changelog.rev(p)
108 defrange = '%s:0' % start
109 else: 118 else:
110 defrange = 'tip:0' 119 defrange = 'tip:0'
111 revs = map(int, revrange(ui, repo, opts['rev'] or [defrange])) 120 revs = map(int, cmdutil.revrange(ui, repo, opts['rev'] or [defrange]))
112 wanted = {} 121 wanted = {}
113 slowpath = anypats 122 slowpath = anypats
114 fncache = {} 123 fncache = {}
115 124
116 chcache = {} 125 chcache = {}
250 yield 'add', rev, fns 259 yield 'add', rev, fns
251 for rev in nrevs: 260 for rev in nrevs:
252 yield 'iter', rev, None 261 yield 'iter', rev, None
253 return iterate(), getchange, matchfn 262 return iterate(), getchange, matchfn
254 263
255 revrangesep = ':'
256
257 def revfix(repo, val, defval):
258 '''turn user-level id of changeset into rev number.
259 user-level id can be tag, changeset, rev number, or negative rev
260 number relative to number of revs (-1 is tip, etc).'''
261 if not val:
262 return defval
263 try:
264 num = int(val)
265 if str(num) != val:
266 raise ValueError
267 if num < 0:
268 num += repo.changelog.count()
269 if num < 0:
270 num = 0
271 elif num >= repo.changelog.count():
272 raise ValueError
273 except ValueError:
274 try:
275 num = repo.changelog.rev(repo.lookup(val))
276 except KeyError:
277 raise util.Abort(_('invalid revision identifier %s'), val)
278 return num
279
280 def revpair(ui, repo, revs):
281 '''return pair of nodes, given list of revisions. second item can
282 be None, meaning use working dir.'''
283 if not revs:
284 return repo.dirstate.parents()[0], None
285 end = None
286 if len(revs) == 1:
287 start = revs[0]
288 if revrangesep in start:
289 start, end = start.split(revrangesep, 1)
290 start = revfix(repo, start, 0)
291 end = revfix(repo, end, repo.changelog.count() - 1)
292 else:
293 start = revfix(repo, start, None)
294 elif len(revs) == 2:
295 if revrangesep in revs[0] or revrangesep in revs[1]:
296 raise util.Abort(_('too many revisions specified'))
297 start = revfix(repo, revs[0], None)
298 end = revfix(repo, revs[1], None)
299 else:
300 raise util.Abort(_('too many revisions specified'))
301 if end is not None: end = repo.lookup(str(end))
302 return repo.lookup(str(start)), end
303
304 def revrange(ui, repo, revs):
305 """Yield revision as strings from a list of revision specifications."""
306 seen = {}
307 for spec in revs:
308 if revrangesep in spec:
309 start, end = spec.split(revrangesep, 1)
310 start = revfix(repo, start, 0)
311 end = revfix(repo, end, repo.changelog.count() - 1)
312 step = start > end and -1 or 1
313 for rev in xrange(start, end+step, step):
314 if rev in seen:
315 continue
316 seen[rev] = 1
317 yield str(rev)
318 else:
319 rev = revfix(repo, spec, None)
320 if rev in seen:
321 continue
322 seen[rev] = 1
323 yield str(rev)
324
325 def write_bundle(cg, filename=None, compress=True): 264 def write_bundle(cg, filename=None, compress=True):
326 """Write a bundle file and return its filename. 265 """Write a bundle file and return its filename.
327 266
328 Existing files will not be overwritten. 267 Existing files will not be overwritten.
329 If no filename is specified, a temporary file is created. 268 If no filename is specified, a temporary file is created.
339 fh = None 278 fh = None
340 cleanup = None 279 cleanup = None
341 try: 280 try:
342 if filename: 281 if filename:
343 if os.path.exists(filename): 282 if os.path.exists(filename):
344 raise util.Abort(_("file '%s' already exists"), filename) 283 raise util.Abort(_("file '%s' already exists") % filename)
345 fh = open(filename, "wb") 284 fh = open(filename, "wb")
346 else: 285 else:
347 fd, filename = tempfile.mkstemp(prefix="hg-bundle-", suffix=".hg") 286 fd, filename = tempfile.mkstemp(prefix="hg-bundle-", suffix=".hg")
348 fh = os.fdopen(fd, "wb") 287 fh = os.fdopen(fd, "wb")
349 cleanup = filename 288 cleanup = filename
503 442
504 def helpcmd(name): 443 def helpcmd(name):
505 if with_version: 444 if with_version:
506 show_version(ui) 445 show_version(ui)
507 ui.write('\n') 446 ui.write('\n')
508 aliases, i = findcmd(name) 447 aliases, i = findcmd(ui, name)
509 # synopsis 448 # synopsis
510 ui.write("%s\n\n" % i[2]) 449 ui.write("%s\n\n" % i[2])
511 450
512 # description 451 # description
513 doc = i[0].__doc__ 452 doc = i[0].__doc__
705 opmap = [['user', getname], ['number', str], ['changeset', getnode], 644 opmap = [['user', getname], ['number', str], ['changeset', getnode],
706 ['date', getdate]] 645 ['date', getdate]]
707 if not opts['user'] and not opts['changeset'] and not opts['date']: 646 if not opts['user'] and not opts['changeset'] and not opts['date']:
708 opts['number'] = 1 647 opts['number'] = 1
709 648
710 ctx = repo.changectx(opts['rev'] or repo.dirstate.parents()[0]) 649 ctx = repo.changectx(defaultrev(repo, opts['rev']))
711 650
712 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, 651 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
713 node=ctx.node()): 652 node=ctx.node()):
714 fctx = ctx.filectx(abs) 653 fctx = ctx.filectx(abs)
715 if not opts['text'] and util.binary(fctx.data()): 654 if not opts['text'] and util.binary(fctx.data()):
752 Each member added to an archive file has a directory prefix 691 Each member added to an archive file has a directory prefix
753 prepended. Use "-p" to specify a format string for the prefix. 692 prepended. Use "-p" to specify a format string for the prefix.
754 The default is the basename of the archive, with suffixes removed. 693 The default is the basename of the archive, with suffixes removed.
755 ''' 694 '''
756 695
757 if opts['rev']: 696 node = repo.lookup(defaultrev(repo, opts['rev']))
758 node = repo.lookup(opts['rev'])
759 else:
760 node, p2 = repo.dirstate.parents()
761 if p2 != nullid:
762 raise util.Abort(_('uncommitted merge - please provide a '
763 'specific revision'))
764
765 dest = cmdutil.make_filename(repo, dest, node) 697 dest = cmdutil.make_filename(repo, dest, node)
766 if os.path.realpath(dest) == repo.root: 698 if os.path.realpath(dest) == repo.root:
767 raise util.Abort(_('repository root cannot be destination')) 699 raise util.Abort(_('repository root cannot be destination'))
768 dummy, matchfn, dummy = cmdutil.matchpats(repo, [], opts) 700 dummy, matchfn, dummy = cmdutil.matchpats(repo, [], opts)
769 kind = opts.get('type') or 'files' 701 kind = opts.get('type') or 'files'
816 if opts['parent']: 748 if opts['parent']:
817 raise util.Abort(_('cannot use --parent on non-merge changeset')) 749 raise util.Abort(_('cannot use --parent on non-merge changeset'))
818 parent = p1 750 parent = p1
819 hg.clean(repo, node, show_stats=False) 751 hg.clean(repo, node, show_stats=False)
820 revert_opts = opts.copy() 752 revert_opts = opts.copy()
753 revert_opts['all'] = True
821 revert_opts['rev'] = hex(parent) 754 revert_opts['rev'] = hex(parent)
822 revert(ui, repo, **revert_opts) 755 revert(ui, repo, **revert_opts)
823 commit_opts = opts.copy() 756 commit_opts = opts.copy()
824 commit_opts['addremove'] = False 757 commit_opts['addremove'] = False
825 if not commit_opts['message'] and not commit_opts['logfile']: 758 if not commit_opts['message'] and not commit_opts['logfile']:
864 797
865 def cat(ui, repo, file1, *pats, **opts): 798 def cat(ui, repo, file1, *pats, **opts):
866 """output the latest or given revisions of files 799 """output the latest or given revisions of files
867 800
868 Print the specified files as they were at the given revision. 801 Print the specified files as they were at the given revision.
869 If no revision is given then the tip is used. 802 If no revision is given then working dir parent is used, or tip
803 if no revision is checked out.
870 804
871 Output may be to a file, in which case the name of the file is 805 Output may be to a file, in which case the name of the file is
872 given using a format string. The formatting rules are the same as 806 given using a format string. The formatting rules are the same as
873 for the export command, with the following additions: 807 for the export command, with the following additions:
874 808
875 %s basename of file being printed 809 %s basename of file being printed
876 %d dirname of file being printed, or '.' if in repo root 810 %d dirname of file being printed, or '.' if in repo root
877 %p root-relative path name of file being printed 811 %p root-relative path name of file being printed
878 """ 812 """
879 ctx = repo.changectx(opts['rev'] or "-1") 813 ctx = repo.changectx(defaultrev(repo, opts['rev']))
880 for src, abs, rel, exact in cmdutil.walk(repo, (file1,) + pats, opts, 814 for src, abs, rel, exact in cmdutil.walk(repo, (file1,) + pats, opts,
881 ctx.node()): 815 ctx.node()):
882 fp = cmdutil.make_file(repo, opts['output'], ctx.node(), pathname=abs) 816 fp = cmdutil.make_file(repo, opts['output'], ctx.node(), pathname=abs)
883 fp.write(ctx.filectx(abs).data()) 817 fp.write(ctx.filectx(abs).data())
884 818
1149 1083
1150 if opts['options']: 1084 if opts['options']:
1151 options = [] 1085 options = []
1152 otables = [globalopts] 1086 otables = [globalopts]
1153 if cmd: 1087 if cmd:
1154 aliases, entry = findcmd(cmd) 1088 aliases, entry = findcmd(ui, cmd)
1155 otables.append(entry[1]) 1089 otables.append(entry[1])
1156 for t in otables: 1090 for t in otables:
1157 for o in t: 1091 for o in t:
1158 if o[0]: 1092 if o[0]:
1159 options.append('-%s' % o[0]) 1093 options.append('-%s' % o[0])
1160 options.append('--%s' % o[1]) 1094 options.append('--%s' % o[1])
1161 ui.write("%s\n" % "\n".join(options)) 1095 ui.write("%s\n" % "\n".join(options))
1162 return 1096 return
1163 1097
1164 clist = findpossible(cmd).keys() 1098 clist = findpossible(ui, cmd).keys()
1165 clist.sort() 1099 clist.sort()
1166 ui.write("%s\n" % "\n".join(clist)) 1100 ui.write("%s\n" % "\n".join(clist))
1167 1101
1168 def debugrebuildstate(ui, repo, rev=None): 1102 def debugrebuildstate(ui, repo, rev=None):
1169 """rebuild the dirstate as it would look like for the given revision""" 1103 """rebuild the dirstate as it would look like for the given revision"""
1266 r = revlog.revlog(util.opener(os.getcwd(), audit=False), 1200 r = revlog.revlog(util.opener(os.getcwd(), audit=False),
1267 file_[:-2] + ".i", file_, 0) 1201 file_[:-2] + ".i", file_, 0)
1268 try: 1202 try:
1269 ui.write(r.revision(r.lookup(rev))) 1203 ui.write(r.revision(r.lookup(rev)))
1270 except KeyError: 1204 except KeyError:
1271 raise util.Abort(_('invalid revision identifier %s'), rev) 1205 raise util.Abort(_('invalid revision identifier %s') % rev)
1272 1206
1273 def debugindex(ui, file_): 1207 def debugindex(ui, file_):
1274 """dump the contents of an index file""" 1208 """dump the contents of an index file"""
1275 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_, "", 0) 1209 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_, "", 0)
1276 ui.write(" rev offset length base linkrev" + 1210 ui.write(" rev offset length base linkrev" +
1341 1275
1342 Without the -a option, diff will avoid generating diffs of files 1276 Without the -a option, diff will avoid generating diffs of files
1343 it detects as binary. With -a, diff will generate a diff anyway, 1277 it detects as binary. With -a, diff will generate a diff anyway,
1344 probably with undesirable results. 1278 probably with undesirable results.
1345 """ 1279 """
1346 node1, node2 = revpair(ui, repo, opts['rev']) 1280 node1, node2 = cmdutil.revpair(ui, repo, opts['rev'])
1347 1281
1348 fns, matchfn, anypats = cmdutil.matchpats(repo, pats, opts) 1282 fns, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
1349 1283
1350 patch.diff(repo, node1, node2, fns, match=matchfn, 1284 patch.diff(repo, node1, node2, fns, match=matchfn,
1351 opts=patch.diffopts(ui, opts)) 1285 opts=patch.diffopts(ui, opts))
1377 With the --switch-parent option, the diff will be against the second 1311 With the --switch-parent option, the diff will be against the second
1378 parent. It can be useful to review a merge. 1312 parent. It can be useful to review a merge.
1379 """ 1313 """
1380 if not changesets: 1314 if not changesets:
1381 raise util.Abort(_("export requires at least one changeset")) 1315 raise util.Abort(_("export requires at least one changeset"))
1382 revs = list(revrange(ui, repo, changesets)) 1316 revs = list(cmdutil.revrange(ui, repo, changesets))
1383 if len(revs) > 1: 1317 if len(revs) > 1:
1384 ui.note(_('exporting patches:\n')) 1318 ui.note(_('exporting patches:\n'))
1385 else: 1319 else:
1386 ui.note(_('exporting patch:\n')) 1320 ui.note(_('exporting patch:\n'))
1387 patch.export(repo, map(repo.lookup, revs), template=opts['output'], 1321 patch.export(repo, map(repo.lookup, revs), template=opts['output'],
1937 head revision, and the repository contains exactly one other head, 1871 head revision, and the repository contains exactly one other head,
1938 the other head is merged with by default. Otherwise, an explicit 1872 the other head is merged with by default. Otherwise, an explicit
1939 revision to merge with must be provided. 1873 revision to merge with must be provided.
1940 """ 1874 """
1941 1875
1942 if node: 1876 if node or branch:
1943 node = _lookup(repo, node, branch) 1877 node = _lookup(repo, node, branch)
1944 else: 1878 else:
1945 heads = repo.heads() 1879 heads = repo.heads()
1946 if len(heads) > 2: 1880 if len(heads) > 2:
1947 raise util.Abort(_('repo has %d heads - ' 1881 raise util.Abort(_('repo has %d heads - '
2269 explicitly specify the revision to revert to. 2203 explicitly specify the revision to revert to.
2270 2204
2271 Modified files are saved with a .orig suffix before reverting. 2205 Modified files are saved with a .orig suffix before reverting.
2272 To disable these backups, use --no-backup. 2206 To disable these backups, use --no-backup.
2273 2207
2274 Using the -r option, revert the given files or directories to 2208 Using the -r option, revert the given files or directories to their
2275 their contents as of a specific revision. This can be helpful to"roll 2209 contents as of a specific revision. This can be helpful to "roll
2276 back" some or all of a change that should not have been committed. 2210 back" some or all of a change that should not have been committed.
2277 2211
2278 Revert modifies the working directory. It does not commit any 2212 Revert modifies the working directory. It does not commit any
2279 changes, or change the parent of the working directory. If you 2213 changes, or change the parent of the working directory. If you
2280 revert to a revision other than the parent of the working 2214 revert to a revision other than the parent of the working
2284 If a file has been deleted, it is recreated. If the executable 2218 If a file has been deleted, it is recreated. If the executable
2285 mode of a file was changed, it is reset. 2219 mode of a file was changed, it is reset.
2286 2220
2287 If names are given, all files matching the names are reverted. 2221 If names are given, all files matching the names are reverted.
2288 2222
2289 If no arguments are given, all files in the repository are reverted. 2223 If no arguments are given, no files are reverted.
2290 """ 2224 """
2225
2226 if not pats and not opts['all']:
2227 raise util.Abort(_('no files or directories specified; '
2228 'use --all to revert the whole repo'))
2229
2291 parent, p2 = repo.dirstate.parents() 2230 parent, p2 = repo.dirstate.parents()
2292 if opts['rev']: 2231 node = repo.lookup(defaultrev(repo, opts['rev']))
2293 node = repo.lookup(opts['rev'])
2294 elif p2 != nullid:
2295 raise util.Abort(_('working dir has two parents; '
2296 'you must specify the revision to revert to'))
2297 else:
2298 node = parent
2299 mf = repo.manifest.read(repo.changelog.read(node)[0]) 2232 mf = repo.manifest.read(repo.changelog.read(node)[0])
2300 if node == parent: 2233 if node == parent:
2301 pmf = mf 2234 pmf = mf
2302 else: 2235 else:
2303 pmf = None 2236 pmf = None
2450 stderr. Use the "-A" and "-E" options to log to files. 2383 stderr. Use the "-A" and "-E" options to log to files.
2451 """ 2384 """
2452 2385
2453 if opts["stdio"]: 2386 if opts["stdio"]:
2454 if repo is None: 2387 if repo is None:
2455 raise hg.RepoError(_('no repo found')) 2388 raise hg.RepoError(_("There is no Mercurial repository here"
2389 " (.hg not found)"))
2456 s = sshserver.sshserver(ui, repo) 2390 s = sshserver.sshserver(ui, repo)
2457 s.serve_forever() 2391 s.serve_forever()
2458 2392
2459 optlist = ("name templates style address port ipv6" 2393 optlist = ("name templates style address port ipv6"
2460 " accesslog errorlog webdir_conf") 2394 " accesslog errorlog webdir_conf")
2461 for o in optlist.split(): 2395 for o in optlist.split():
2462 if opts[o]: 2396 if opts[o]:
2463 ui.setconfig("web", o, opts[o]) 2397 ui.setconfig("web", o, opts[o])
2464 2398
2465 if repo is None and not ui.config("web", "webdir_conf"): 2399 if repo is None and not ui.config("web", "webdir_conf"):
2466 raise hg.RepoError(_('no repo found')) 2400 raise hg.RepoError(_("There is no Mercurial repository here"
2401 " (.hg not found)"))
2467 2402
2468 if opts['daemon'] and not opts['daemon_pipefds']: 2403 if opts['daemon'] and not opts['daemon_pipefds']:
2469 rfd, wfd = os.pipe() 2404 rfd, wfd = os.pipe()
2470 args = sys.argv[:] 2405 args = sys.argv[:]
2471 args.append('--daemon-pipefds=%d,%d' % (rfd, wfd)) 2406 args.append('--daemon-pipefds=%d,%d' % (rfd, wfd))
2476 os._exit(0) 2411 os._exit(0)
2477 2412
2478 try: 2413 try:
2479 httpd = hgweb.server.create_server(ui, repo) 2414 httpd = hgweb.server.create_server(ui, repo)
2480 except socket.error, inst: 2415 except socket.error, inst:
2481 raise util.Abort(_('cannot start server: ') + inst.args[1]) 2416 raise util.Abort(_('cannot start server: %s') % inst.args[1])
2482 2417
2483 if ui.verbose: 2418 if ui.verbose:
2484 addr, port = httpd.socket.getsockname() 2419 addr, port = httpd.socket.getsockname()
2485 if addr == '0.0.0.0': 2420 if addr == '0.0.0.0':
2486 addr = socket.gethostname() 2421 addr = socket.gethostname()
2591 "please use 'hg tag [-r REV] NAME' instead\n")) 2526 "please use 'hg tag [-r REV] NAME' instead\n"))
2592 if opts['rev']: 2527 if opts['rev']:
2593 raise util.Abort(_("use only one form to specify the revision")) 2528 raise util.Abort(_("use only one form to specify the revision"))
2594 if opts['rev']: 2529 if opts['rev']:
2595 rev_ = opts['rev'] 2530 rev_ = opts['rev']
2596 if rev_: 2531 r = defaultrev(repo, rev_, nullid)
2597 r = repo.lookup(rev_) 2532 if r == nullid:
2598 else: 2533 raise util.Abort(_('no revision to tag'))
2599 p1, p2 = repo.dirstate.parents() 2534 r = repo.lookup(r)
2600 if p1 == nullid:
2601 raise util.Abort(_('no revision to tag'))
2602 if p2 != nullid:
2603 raise util.Abort(_('outstanding uncommitted merges'))
2604 r = p1
2605 2535
2606 message = opts['message'] 2536 message = opts['message']
2607 if not message: 2537 if not message:
2608 message = _('Added tag %s for changeset %s') % (name, short(r)) 2538 message = _('Added tag %s for changeset %s') % (name, short(r))
2609 2539
2726 if len(found) == 1: 2656 if len(found) == 1:
2727 node = found[0] 2657 node = found[0]
2728 repo.ui.warn(_("Using head %s for branch %s\n") 2658 repo.ui.warn(_("Using head %s for branch %s\n")
2729 % (short(node), branch)) 2659 % (short(node), branch))
2730 else: 2660 else:
2731 raise util.Abort(_("branch %s not found\n") % (branch)) 2661 raise util.Abort(_("branch %s not found") % branch)
2732 else: 2662 else:
2733 node = node and repo.lookup(node) or repo.changelog.tip() 2663 node = node and repo.lookup(node) or repo.changelog.tip()
2734 return node 2664 return node
2735 2665
2736 def verify(ui, repo): 2666 def verify(ui, repo):
2879 _('hg diff [-a] [-I] [-X] [-r REV1 [-r REV2]] [FILE]...')), 2809 _('hg diff [-a] [-I] [-X] [-r REV1 [-r REV2]] [FILE]...')),
2880 "^export": 2810 "^export":
2881 (export, 2811 (export,
2882 [('o', 'output', '', _('print output to file with formatted name')), 2812 [('o', 'output', '', _('print output to file with formatted name')),
2883 ('a', 'text', None, _('treat all files as text')), 2813 ('a', 'text', None, _('treat all files as text')),
2814 ('g', 'git', None, _('use git extended diff format')),
2884 ('', 'switch-parent', None, _('diff against the second parent'))], 2815 ('', 'switch-parent', None, _('diff against the second parent'))],
2885 _('hg export [-a] [-o OUTFILESPEC] REV...')), 2816 _('hg export [-a] [-o OUTFILESPEC] REV...')),
2886 "debugforget|forget": 2817 "debugforget|forget":
2887 (forget, 2818 (forget,
2888 [('I', 'include', [], _('include names matching the given patterns')), 2819 [('I', 'include', [], _('include names matching the given patterns')),
3044 ('X', 'exclude', [], _('exclude names matching the given patterns')), 2975 ('X', 'exclude', [], _('exclude names matching the given patterns')),
3045 ('n', 'dry-run', None, _('do not perform actions, just print output'))], 2976 ('n', 'dry-run', None, _('do not perform actions, just print output'))],
3046 _('hg rename [OPTION]... SOURCE... DEST')), 2977 _('hg rename [OPTION]... SOURCE... DEST')),
3047 "^revert": 2978 "^revert":
3048 (revert, 2979 (revert,
3049 [('r', 'rev', '', _('revision to revert to')), 2980 [('a', 'all', None, _('revert all changes when no arguments given')),
2981 ('r', 'rev', '', _('revision to revert to')),
3050 ('', 'no-backup', None, _('do not save backup copies of files')), 2982 ('', 'no-backup', None, _('do not save backup copies of files')),
3051 ('I', 'include', [], _('include names matching given patterns')), 2983 ('I', 'include', [], _('include names matching given patterns')),
3052 ('X', 'exclude', [], _('exclude names matching given patterns')), 2984 ('X', 'exclude', [], _('exclude names matching given patterns')),
3053 ('n', 'dry-run', None, _('do not perform actions, just print output'))], 2985 ('n', 'dry-run', None, _('do not perform actions, just print output'))],
3054 _('hg revert [-r REV] [NAME]...')), 2986 _('hg revert [-r REV] [NAME]...')),
3143 3075
3144 norepo = ("clone init version help debugancestor debugcomplete debugdata" 3076 norepo = ("clone init version help debugancestor debugcomplete debugdata"
3145 " debugindex debugindexdot") 3077 " debugindex debugindexdot")
3146 optionalrepo = ("paths serve debugconfig") 3078 optionalrepo = ("paths serve debugconfig")
3147 3079
3148 def findpossible(cmd): 3080 def findpossible(ui, cmd):
3149 """ 3081 """
3150 Return cmd -> (aliases, command table entry) 3082 Return cmd -> (aliases, command table entry)
3151 for each matching command. 3083 for each matching command.
3152 Return debug commands (or their aliases) only if no normal command matches. 3084 Return debug commands (or their aliases) only if no normal command matches.
3153 """ 3085 """
3156 for e in table.keys(): 3088 for e in table.keys():
3157 aliases = e.lstrip("^").split("|") 3089 aliases = e.lstrip("^").split("|")
3158 found = None 3090 found = None
3159 if cmd in aliases: 3091 if cmd in aliases:
3160 found = cmd 3092 found = cmd
3161 else: 3093 elif not ui.config("ui", "strict"):
3162 for a in aliases: 3094 for a in aliases:
3163 if a.startswith(cmd): 3095 if a.startswith(cmd):
3164 found = a 3096 found = a
3165 break 3097 break
3166 if found is not None: 3098 if found is not None:
3172 if not choice and debugchoice: 3104 if not choice and debugchoice:
3173 choice = debugchoice 3105 choice = debugchoice
3174 3106
3175 return choice 3107 return choice
3176 3108
3177 def findcmd(cmd): 3109 def findcmd(ui, cmd):
3178 """Return (aliases, command table entry) for command string.""" 3110 """Return (aliases, command table entry) for command string."""
3179 choice = findpossible(cmd) 3111 choice = findpossible(ui, cmd)
3180 3112
3181 if choice.has_key(cmd): 3113 if choice.has_key(cmd):
3182 return choice[cmd] 3114 return choice[cmd]
3183 3115
3184 if len(choice) > 1: 3116 if len(choice) > 1:
3209 except fancyopts.getopt.GetoptError, inst: 3141 except fancyopts.getopt.GetoptError, inst:
3210 raise ParseError(None, inst) 3142 raise ParseError(None, inst)
3211 3143
3212 if args: 3144 if args:
3213 cmd, args = args[0], args[1:] 3145 cmd, args = args[0], args[1:]
3214 aliases, i = findcmd(cmd) 3146 aliases, i = findcmd(ui, cmd)
3215 cmd = aliases[0] 3147 cmd = aliases[0]
3216 defaults = ui.config("defaults", cmd) 3148 defaults = ui.config("defaults", cmd)
3217 if defaults: 3149 if defaults:
3218 args = defaults.split() + args 3150 args = shlex.split(defaults) + args
3219 c = list(i[1]) 3151 c = list(i[1])
3220 else: 3152 else:
3221 cmd = None 3153 cmd = None
3222 c = [] 3154 c = []
3223 3155
3297 for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM': 3229 for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
3298 num = getattr(signal, name, None) 3230 num = getattr(signal, name, None)
3299 if num: signal.signal(num, catchterm) 3231 if num: signal.signal(num, catchterm)
3300 3232
3301 try: 3233 try:
3302 u = ui.ui(traceback='--traceback' in sys.argv[1:], 3234 u = ui.ui(traceback='--traceback' in sys.argv[1:])
3303 readhooks=[load_extensions])
3304 except util.Abort, inst: 3235 except util.Abort, inst:
3305 sys.stderr.write(_("abort: %s\n") % inst) 3236 sys.stderr.write(_("abort: %s\n") % inst)
3306 return -1 3237 return -1
3238
3239 load_extensions(u)
3240 u.addreadhook(load_extensions)
3307 3241
3308 try: 3242 try:
3309 cmd, func, args, options, cmdoptions = parse(u, args) 3243 cmd, func, args, options, cmdoptions = parse(u, args)
3310 if options["time"]: 3244 if options["time"]:
3311 def get_times(): 3245 def get_times():
3437 u.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason)) 3371 u.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason))
3438 except lock.LockUnavailable, inst: 3372 except lock.LockUnavailable, inst:
3439 u.warn(_("abort: could not lock %s: %s\n") % 3373 u.warn(_("abort: could not lock %s: %s\n") %
3440 (inst.desc or inst.filename, inst.strerror)) 3374 (inst.desc or inst.filename, inst.strerror))
3441 except revlog.RevlogError, inst: 3375 except revlog.RevlogError, inst:
3442 u.warn(_("abort: "), inst, "!\n") 3376 u.warn(_("abort: %s!\n") % inst)
3443 except util.SignalInterrupt: 3377 except util.SignalInterrupt:
3444 u.warn(_("killed!\n")) 3378 u.warn(_("killed!\n"))
3445 except KeyboardInterrupt: 3379 except KeyboardInterrupt:
3446 try: 3380 try:
3447 u.warn(_("interrupted!\n")) 3381 u.warn(_("interrupted!\n"))
3459 elif hasattr(inst, "args") and inst[0] == errno.EPIPE: 3393 elif hasattr(inst, "args") and inst[0] == errno.EPIPE:
3460 if u.debugflag: 3394 if u.debugflag:
3461 u.warn(_("broken pipe\n")) 3395 u.warn(_("broken pipe\n"))
3462 elif getattr(inst, "strerror", None): 3396 elif getattr(inst, "strerror", None):
3463 if getattr(inst, "filename", None): 3397 if getattr(inst, "filename", None):
3464 u.warn(_("abort: %s - %s\n") % (inst.strerror, inst.filename)) 3398 u.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
3465 else: 3399 else:
3466 u.warn(_("abort: %s\n") % inst.strerror) 3400 u.warn(_("abort: %s\n") % inst.strerror)
3467 else: 3401 else:
3468 raise 3402 raise
3469 except OSError, inst: 3403 except OSError, inst:
3470 if hasattr(inst, "filename"): 3404 if getattr(inst, "filename", None):
3471 u.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename)) 3405 u.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
3472 else: 3406 else:
3473 u.warn(_("abort: %s\n") % inst.strerror) 3407 u.warn(_("abort: %s\n") % inst.strerror)
3474 except util.Abort, inst: 3408 except util.Abort, inst:
3475 u.warn(_('abort: '), inst.args[0] % inst.args[1:], '\n') 3409 u.warn(_("abort: %s\n") % inst)
3476 except TypeError, inst: 3410 except TypeError, inst:
3477 # was this an argument error? 3411 # was this an argument error?
3478 tb = traceback.extract_tb(sys.exc_info()[2]) 3412 tb = traceback.extract_tb(sys.exc_info()[2])
3479 if len(tb) > 2: # no 3413 if len(tb) > 2: # no
3480 raise 3414 raise