comparison mercurial/commands.py @ 740:d2422f10c136

Merge from BOS manifest hash: 2276dbd96bb4221e579c871a1de2403c92c85659
author mpm@selenic.com
date Wed, 20 Jul 2005 20:00:29 -0500
parents 938dd667ca21 36edb39e8e8c
children 092937de2ad7
comparison
equal deleted inserted replaced
722:e5b39ce2c3c9 740:d2422f10c136
12 demandload(globals(), "errno socket version struct") 12 demandload(globals(), "errno socket version struct")
13 13
14 class UnknownCommand(Exception): 14 class UnknownCommand(Exception):
15 """Exception raised if command is not in the command table.""" 15 """Exception raised if command is not in the command table."""
16 16
17 class Abort(Exception):
18 """Raised if a command needs to print an error and exit."""
19
17 def filterfiles(filters, files): 20 def filterfiles(filters, files):
18 l = [x for x in files if x in filters] 21 l = [x for x in files if x in filters]
19 22
20 for t in filters: 23 for t in filters:
21 if t and t[-1] != "/": 24 if t and t[-1] != "/":
33 cwd = repo.getcwd() 36 cwd = repo.getcwd()
34 if cwd: 37 if cwd:
35 return [util.pconvert(os.path.normpath(os.path.join(cwd, x))) 38 return [util.pconvert(os.path.normpath(os.path.join(cwd, x)))
36 for x in args] 39 for x in args]
37 return args 40 return args
41
42 def matchpats(ui, cwd, pats = [], opts = {}, emptyok = True):
43 if not pats and not emptyok:
44 raise Abort('at least one file name or pattern required')
45 head = ''
46 if opts.get('rootless'): head = '(?:.*/|)'
47 def reify(name, tail):
48 if name.startswith('re:'):
49 return name[3:]
50 elif name.startswith('glob:'):
51 return head + util.globre(name[5:], '', tail)
52 elif name.startswith('path:'):
53 return '^' + re.escape(name[5:]) + '$'
54 return head + util.globre(name, '', tail)
55 cwdsep = cwd + os.sep
56 def under(fn):
57 if not cwd or fn.startswith(cwdsep): return True
58 def matchfn(pats, tail, ifempty = util.always):
59 if not pats: return ifempty
60 pat = '(?:%s)' % '|'.join([reify(p, tail) for p in pats])
61 if cwd: pat = re.escape(cwd + os.sep) + pat
62 ui.debug('regexp: %s\n' % pat)
63 return re.compile(pat).match
64 patmatch = matchfn(pats, '$')
65 incmatch = matchfn(opts.get('include'), '(?:/|$)', under)
66 excmatch = matchfn(opts.get('exclude'), '(?:/|$)', util.never)
67 return lambda fn: (incmatch(fn) and not excmatch(fn) and
68 (fn.endswith('/') or patmatch(fn)))
69
70 def walk(repo, pats, opts, emptyok = True):
71 cwd = repo.getcwd()
72 if cwd: c = len(cwd) + 1
73 for src, fn in repo.walk(match = matchpats(repo.ui, cwd, pats, opts, emptyok)):
74 if cwd: yield src, fn, fn[c:]
75 else: yield src, fn, fn
38 76
39 revrangesep = ':' 77 revrangesep = ':'
40 78
41 def revrange(ui, repo, revs, revlog=None): 79 def revrange(ui, repo, revs, revlog=None):
42 if revlog is None: 80 if revlog is None:
58 num = repo.changelog.rev(repo.lookup(val)) 96 num = repo.changelog.rev(repo.lookup(val))
59 except KeyError: 97 except KeyError:
60 try: 98 try:
61 num = revlog.rev(revlog.lookup(val)) 99 num = revlog.rev(revlog.lookup(val))
62 except KeyError: 100 except KeyError:
63 ui.warn('abort: invalid revision identifier %s\n' % val) 101 raise Abort('invalid revision identifier %s', val)
64 sys.exit(1)
65 return num 102 return num
66 for spec in revs: 103 for spec in revs:
67 if spec.find(revrangesep) >= 0: 104 if spec.find(revrangesep) >= 0:
68 start, end = spec.split(revrangesep, 1) 105 start, end = spec.split(revrangesep, 1)
69 start = fix(start, 0) 106 start = fix(start, 0)
89 expander = { 126 expander = {
90 '%': lambda: '%', 127 '%': lambda: '%',
91 'b': lambda: os.path.basename(repo.root), 128 'b': lambda: os.path.basename(repo.root),
92 } 129 }
93 130
94 if node: 131 try:
95 expander.update(node_expander) 132 if node:
96 if node and revwidth is not None: 133 expander.update(node_expander)
97 expander['r'] = lambda: str(r.rev(node)).zfill(revwidth) 134 if node and revwidth is not None:
98 if total is not None: 135 expander['r'] = lambda: str(r.rev(node)).zfill(revwidth)
99 expander['N'] = lambda: str(total) 136 if total is not None:
100 if seqno is not None: 137 expander['N'] = lambda: str(total)
101 expander['n'] = lambda: str(seqno) 138 if seqno is not None:
102 if total is not None and seqno is not None: 139 expander['n'] = lambda: str(seqno)
103 expander['n'] = lambda:str(seqno).zfill(len(str(total))) 140 if total is not None and seqno is not None:
104 141 expander['n'] = lambda:str(seqno).zfill(len(str(total)))
105 newname = [] 142
106 patlen = len(pat) 143 newname = []
107 i = 0 144 patlen = len(pat)
108 while i < patlen: 145 i = 0
109 c = pat[i] 146 while i < patlen:
110 if c == '%': 147 c = pat[i]
148 if c == '%':
149 i += 1
150 c = pat[i]
151 c = expander[c]()
152 newname.append(c)
111 i += 1 153 i += 1
112 c = pat[i] 154 return ''.join(newname)
113 c = expander[c]() 155 except KeyError, inst:
114 newname.append(c) 156 raise Abort("invalid format spec '%%%s' in output file name",
115 i += 1 157 inst.args[0])
116 return ''.join(newname) 158
159 def make_file(repo, r, pat, node=None,
160 total=None, seqno=None, revwidth=None, mode='wb'):
161 if not pat or pat == '-':
162 if 'w' in mode: return sys.stdout
163 else: return sys.stdin
164 if hasattr(pat, 'write') and 'w' in mode:
165 return pat
166 if hasattr(pat, 'read') and 'r' in mode:
167 return pat
168 return open(make_filename(repo, r, pat, node, total, seqno, revwidth),
169 mode)
117 170
118 def dodiff(fp, ui, repo, files=None, node1=None, node2=None): 171 def dodiff(fp, ui, repo, files=None, node1=None, node2=None):
119 def date(c): 172 def date(c):
120 return time.asctime(time.gmtime(float(c[2].split(' ')[0]))) 173 return time.asctime(time.gmtime(float(c[2].split(' ')[0])))
121 174
286 for f in fns: 339 for f in fns:
287 ui.write(' %-*s %s\n' % (m, f, h[f])) 340 ui.write(' %-*s %s\n' % (m, f, h[f]))
288 341
289 # Commands start here, listed alphabetically 342 # Commands start here, listed alphabetically
290 343
291 def add(ui, repo, file1, *files): 344 def add(ui, repo, *pats, **opts):
292 '''add the specified files on the next commit''' 345 '''add the specified files on the next commit'''
293 repo.add(relpath(repo, (file1,) + files)) 346 names = []
347 q = dict(zip(pats, pats))
348 for src, abs, rel in walk(repo, pats, opts):
349 if rel in q or abs in q:
350 names.append(abs)
351 elif repo.dirstate.state(abs) == '?':
352 ui.status('adding %s\n' % rel)
353 names.append(abs)
354 repo.add(names)
294 355
295 def addremove(ui, repo, *files): 356 def addremove(ui, repo, *files):
296 """add all new files, delete all missing files""" 357 """add all new files, delete all missing files"""
297 if files: 358 if files:
298 files = relpath(repo, files) 359 files = relpath(repo, files)
305 if s != 'r' and not isfile: 366 if s != 'r' and not isfile:
306 d.append(f) 367 d.append(f)
307 elif s not in 'nmai' and isfile: 368 elif s not in 'nmai' and isfile:
308 u.append(f) 369 u.append(f)
309 else: 370 else:
310 (c, a, d, u) = repo.changes(None, None) 371 (c, a, d, u) = repo.changes()
311 repo.add(u) 372 repo.add(u)
312 repo.remove(d) 373 repo.remove(d)
313 374
314 def annotate(ui, repo, file1, *files, **opts): 375 def annotate(ui, repo, *pats, **opts):
315 """show changeset information per file line""" 376 """show changeset information per file line"""
316 def getnode(rev): 377 def getnode(rev):
317 return hg.short(repo.changelog.node(rev)) 378 return hg.short(repo.changelog.node(rev))
318 379
319 def getname(rev): 380 def getname(rev):
340 node = repo.changelog.lookup(opts['rev']) 401 node = repo.changelog.lookup(opts['rev'])
341 else: 402 else:
342 node = repo.dirstate.parents()[0] 403 node = repo.dirstate.parents()[0]
343 change = repo.changelog.read(node) 404 change = repo.changelog.read(node)
344 mmap = repo.manifest.read(change[0]) 405 mmap = repo.manifest.read(change[0])
345 for f in relpath(repo, (file1,) + files): 406 for src, abs, rel in walk(repo, pats, opts, emptyok = False):
346 lines = repo.file(f).annotate(mmap[f]) 407 lines = repo.file(abs).annotate(mmap[abs])
347 pieces = [] 408 pieces = []
348 409
349 for o, f in opmap: 410 for o, f in opmap:
350 if opts[o]: 411 if opts[o]:
351 l = [f(n) for n, dummy in lines] 412 l = [f(n) for n, dummy in lines]
360 r = repo.file(relpath(repo, [file1])[0]) 421 r = repo.file(relpath(repo, [file1])[0])
361 if rev: 422 if rev:
362 n = r.lookup(rev) 423 n = r.lookup(rev)
363 else: 424 else:
364 n = r.tip() 425 n = r.tip()
365 if opts['output'] and opts['output'] != '-': 426 fp = make_file(repo, r, opts['output'], node=n)
366 try:
367 outname = make_filename(repo, r, opts['output'], node=n)
368 fp = open(outname, 'wb')
369 except KeyError, inst:
370 ui.warn("error: invlaid format spec '%%%s' in output file name\n" %
371 inst.args[0])
372 sys.exit(1);
373 else:
374 fp = sys.stdout
375 fp.write(r.read(n)) 427 fp.write(r.read(n))
376 428
377 def clone(ui, source, dest=None, **opts): 429 def clone(ui, source, dest=None, **opts):
378 """make a copy of an existing repository""" 430 """make a copy of an existing repository"""
379 if dest is None: 431 if dest is None:
473 state = repo.dirstate.state(f) 525 state = repo.dirstate.state(f)
474 if state not in "nrm": 526 if state not in "nrm":
475 ui.warn("%s in manifest1, but listed as state %s" % (f, state)) 527 ui.warn("%s in manifest1, but listed as state %s" % (f, state))
476 errors += 1 528 errors += 1
477 if errors: 529 if errors:
478 ui.warn(".hg/dirstate inconsistent with current parent's manifest\n") 530 raise Abort(".hg/dirstate inconsistent with current parent's manifest")
479 sys.exit(1)
480 531
481 def debugstate(ui, repo): 532 def debugstate(ui, repo):
482 """show the contents of the current dirstate""" 533 """show the contents of the current dirstate"""
483 repo.dirstate.read() 534 repo.dirstate.read()
484 dc = repo.dirstate.map 535 dc = repo.dirstate.map
507 ui.write("\t%d -> %d\n" % (r.rev(e[4]), i)) 558 ui.write("\t%d -> %d\n" % (r.rev(e[4]), i))
508 if e[5] != hg.nullid: 559 if e[5] != hg.nullid:
509 ui.write("\t%d -> %d\n" % (r.rev(e[5]), i)) 560 ui.write("\t%d -> %d\n" % (r.rev(e[5]), i))
510 ui.write("}\n") 561 ui.write("}\n")
511 562
512 def diff(ui, repo, *files, **opts): 563 def diff(ui, repo, *pats, **opts):
513 """diff working directory (or selected files)""" 564 """diff working directory (or selected files)"""
514 revs = [] 565 revs = []
515 if opts['rev']: 566 if opts['rev']:
516 revs = map(lambda x: repo.lookup(x), opts['rev']) 567 revs = map(lambda x: repo.lookup(x), opts['rev'])
517 568
518 if len(revs) > 2: 569 if len(revs) > 2:
519 ui.warn("too many revisions to diff\n") 570 raise Abort("too many revisions to diff")
520 sys.exit(1) 571
521 572 files = []
522 if files: 573 for src, abs, rel in walk(repo, pats, opts):
523 files = relpath(repo, files) 574 files.append(abs)
524 else:
525 files = relpath(repo, [""])
526
527 dodiff(sys.stdout, ui, repo, files, *revs) 575 dodiff(sys.stdout, ui, repo, files, *revs)
528 576
529 def doexport(ui, repo, changeset, seqno, total, revwidth, opts): 577 def doexport(ui, repo, changeset, seqno, total, revwidth, opts):
530 node = repo.lookup(changeset) 578 node = repo.lookup(changeset)
531 prev, other = repo.changelog.parents(node) 579 prev, other = repo.changelog.parents(node)
532 change = repo.changelog.read(node) 580 change = repo.changelog.read(node)
533 581
534 if opts['output'] and opts['output'] != '-': 582 fp = make_file(repo, repo.changelog, opts['output'],
535 try: 583 node=node, total=total, seqno=seqno,
536 outname = make_filename(repo, repo.changelog, opts['output'], 584 revwidth=revwidth)
537 node=node, total=total, seqno=seqno, 585 if fp != sys.stdout:
538 revwidth=revwidth) 586 ui.note("Exporting patch to '%s'.\n" % fp.name)
539 ui.note("Exporting patch to '%s'.\n" % outname)
540 fp = open(outname, 'wb')
541 except KeyError, inst:
542 ui.warn("error: invalid format spec '%%%s' in output file name\n" %
543 inst.args[0])
544 sys.exit(1)
545 else:
546 fp = sys.stdout
547 587
548 fp.write("# HG changeset patch\n") 588 fp.write("# HG changeset patch\n")
549 fp.write("# User %s\n" % change[1]) 589 fp.write("# User %s\n" % change[1])
550 fp.write("# Node ID %s\n" % hg.hex(node)) 590 fp.write("# Node ID %s\n" % hg.hex(node))
551 fp.write("# Parent %s\n" % hg.hex(prev)) 591 fp.write("# Parent %s\n" % hg.hex(prev))
553 fp.write("# Parent %s\n" % hg.hex(other)) 593 fp.write("# Parent %s\n" % hg.hex(other))
554 fp.write(change[4].rstrip()) 594 fp.write(change[4].rstrip())
555 fp.write("\n\n") 595 fp.write("\n\n")
556 596
557 dodiff(fp, ui, repo, None, prev, node) 597 dodiff(fp, ui, repo, None, prev, node)
598 if fp != sys.stdout: fp.close()
558 599
559 def export(ui, repo, *changesets, **opts): 600 def export(ui, repo, *changesets, **opts):
560 """dump the header and diffs for one or more changesets""" 601 """dump the header and diffs for one or more changesets"""
561 if not changesets: 602 if not changesets:
562 ui.warn("error: export requires at least one changeset\n") 603 raise Abort("export requires at least one changeset")
563 sys.exit(1)
564 seqno = 0 604 seqno = 0
565 revs = list(revrange(ui, repo, changesets)) 605 revs = list(revrange(ui, repo, changesets))
566 total = len(revs) 606 total = len(revs)
567 revwidth = max(len(revs[0]), len(revs[-1])) 607 revwidth = max(len(revs[0]), len(revs[-1]))
568 for cset in revs: 608 for cset in revs:
584 if not parents: 624 if not parents:
585 ui.write("unknown\n") 625 ui.write("unknown\n")
586 return 626 return
587 627
588 hexfunc = ui.verbose and hg.hex or hg.short 628 hexfunc = ui.verbose and hg.hex or hg.short
589 (c, a, d, u) = repo.changes(None, None) 629 (c, a, d, u) = repo.changes()
590 output = ["%s%s" % ('+'.join([hexfunc(parent) for parent in parents]), 630 output = ["%s%s" % ('+'.join([hexfunc(parent) for parent in parents]),
591 (c or a or d) and "+" or "")] 631 (c or a or d) and "+" or "")]
592 632
593 if not ui.quiet: 633 if not ui.quiet:
594 # multiple tags for a single parent separated by '/' 634 # multiple tags for a single parent separated by '/'
652 pf = l[14:] 692 pf = l[14:]
653 if pf not in files: 693 if pf not in files:
654 files.append(pf) 694 files.append(pf)
655 patcherr = f.close() 695 patcherr = f.close()
656 if patcherr: 696 if patcherr:
657 sys.stderr.write("patch failed") 697 raise Abort("patch failed")
658 sys.exit(1)
659 698
660 if len(files) > 0: 699 if len(files) > 0:
661 addremove(ui, repo, *files) 700 addremove(ui, repo, *files)
662 repo.commit(files, text, user) 701 repo.commit(files, text, user)
663 702
664 def init(ui, source=None): 703 def init(ui, source=None):
665 """create a new repository in the current directory""" 704 """create a new repository in the current directory"""
666 705
667 if source: 706 if source:
668 ui.warn("no longer supported: use \"hg clone\" instead\n") 707 raise Abort("no longer supported: use \"hg clone\" instead")
669 sys.exit(1)
670 hg.repository(ui, ".", create=1) 708 hg.repository(ui, ".", create=1)
671 709
672 def locate(ui, repo, *pats, **opts): 710 def locate(ui, repo, *pats, **opts):
673 """locate files matching specific patterns""" 711 """locate files matching specific patterns"""
674 if [p for p in pats if os.sep in p]: 712 if opts['print0']: end = '\0'
675 ui.warn("error: patterns may not contain '%s'\n" % os.sep) 713 else: end = '\n'
676 ui.warn("use '-i <dir>' instead\n") 714 opts['rootless'] = True
677 sys.exit(1) 715 for src, abs, rel in walk(repo, pats, opts):
678 def compile(pats, head='^', tail=os.sep, on_empty=True): 716 if repo.dirstate.state(abs) == '?': continue
679 if not pats:
680 class c:
681 def match(self, x):
682 return on_empty
683 return c()
684 fnpats = [fnmatch.translate(os.path.normpath(os.path.normcase(p)))[:-1]
685 for p in pats]
686 regexp = r'%s(?:%s)%s' % (head, '|'.join(fnpats), tail)
687 return re.compile(regexp)
688 exclude = compile(opts['exclude'], on_empty=False)
689 include = compile(opts['include'])
690 pat = compile(pats, head='', tail='$')
691 end = opts['print0'] and '\0' or '\n'
692 if opts['rev']:
693 node = repo.manifest.lookup(opts['rev'])
694 else:
695 node = repo.manifest.tip()
696 manifest = repo.manifest.read(node)
697 cwd = repo.getcwd()
698 cwd_plus = cwd and (cwd + os.sep)
699 found = []
700 for f in manifest:
701 f = os.path.normcase(f)
702 if exclude.match(f) or not(include.match(f) and
703 f.startswith(cwd_plus) and
704 pat.match(os.path.basename(f))):
705 continue
706 if opts['fullpath']: 717 if opts['fullpath']:
707 f = os.path.join(repo.root, f) 718 ui.write(os.path.join(repo.root, abs), end)
708 elif cwd: 719 else:
709 f = f[len(cwd_plus):] 720 ui.write(rel, end)
710 found.append(f)
711 found.sort()
712 for f in found:
713 ui.write(f, end)
714 721
715 def log(ui, repo, f=None, **opts): 722 def log(ui, repo, f=None, **opts):
716 """show the revision history of the repository or a single file""" 723 """show the revision history of the repository or a single file"""
717 if f: 724 if f:
718 files = relpath(repo, [f]) 725 files = relpath(repo, [f])
743 i = filelog.linkrev(filenode) 750 i = filelog.linkrev(filenode)
744 changenode = repo.changelog.node(i) 751 changenode = repo.changelog.node(i)
745 prev, other = repo.changelog.parents(changenode) 752 prev, other = repo.changelog.parents(changenode)
746 dodiff(sys.stdout, ui, repo, files, prev, changenode) 753 dodiff(sys.stdout, ui, repo, files, prev, changenode)
747 ui.write("\n\n") 754 ui.write("\n\n")
755
756 def ls(ui, repo, *pats, **opts):
757 """list files"""
758 for src, abs, rel in walk(repo, pats, opts):
759 ui.write(rel, '\n')
748 760
749 def manifest(ui, repo, rev=None): 761 def manifest(ui, repo, rev=None):
750 """output the latest or given revision of the project manifest""" 762 """output the latest or given revision of the project manifest"""
751 if rev: 763 if rev:
752 try: 764 try:
976 ui.status('listening at http://%s:%d/\n' % (addr, port)) 988 ui.status('listening at http://%s:%d/\n' % (addr, port))
977 else: 989 else:
978 ui.status('listening at http://%s/\n' % addr) 990 ui.status('listening at http://%s/\n' % addr)
979 httpd.serve_forever() 991 httpd.serve_forever()
980 992
981 def status(ui, repo): 993 def status(ui, repo, *pats, **opts):
982 '''show changed files in the working directory 994 '''show changed files in the working directory
983 995
984 C = changed 996 C = changed
985 A = added 997 A = added
986 R = removed 998 R = removed
987 ? = not tracked''' 999 ? = not tracked'''
988 1000
989 (c, a, d, u) = repo.changes(None, None) 1001 (c, a, d, u) = repo.changes(match = matchpats(ui, repo.getcwd(),
1002 pats, opts))
990 (c, a, d, u) = map(lambda x: relfilter(repo, x), (c, a, d, u)) 1003 (c, a, d, u) = map(lambda x: relfilter(repo, x), (c, a, d, u))
991 1004
992 for f in c: 1005 for f in c:
993 ui.write("C ", f, "\n") 1006 ui.write("C ", f, "\n")
994 for f in a: 1007 for f in a:
1015 1028
1016 if opts['local']: 1029 if opts['local']:
1017 repo.opener("localtags", "a").write("%s %s\n" % (r, name)) 1030 repo.opener("localtags", "a").write("%s %s\n" % (r, name))
1018 return 1031 return
1019 1032
1020 (c, a, d, u) = repo.changes(None, None) 1033 (c, a, d, u) = repo.changes()
1021 for x in (c, a, d, u): 1034 for x in (c, a, d, u):
1022 if ".hgtags" in x: 1035 if ".hgtags" in x:
1023 ui.warn("abort: working copy of .hgtags is changed!\n") 1036 ui.warn("abort: working copy of .hgtags is changed!\n")
1024 ui.status("(please commit .hgtags manually)\n") 1037 ui.status("(please commit .hgtags manually)\n")
1025 return -1 1038 return -1
1086 return repo.verify() 1099 return repo.verify()
1087 1100
1088 # Command options and aliases are listed here, alphabetically 1101 # Command options and aliases are listed here, alphabetically
1089 1102
1090 table = { 1103 table = {
1091 "^add": (add, [], "hg add FILE..."), 1104 "^add": (add,
1092 "addremove": (addremove, [], "hg addremove [FILE]..."), 1105 [('I', 'include', [], 'include path in search'),
1106 ('X', 'exclude', [], 'exclude path from search')],
1107 "hg add [OPTIONS] [FILES]"),
1108 "addremove": (addremove, [], "hg addremove [FILES]"),
1093 "^annotate": 1109 "^annotate":
1094 (annotate, 1110 (annotate,
1095 [('r', 'rev', '', 'revision'), 1111 [('I', 'include', [], 'include path in search'),
1112 ('X', 'exclude', [], 'exclude path from search'),
1113 ('r', 'rev', '', 'revision'),
1096 ('u', 'user', None, 'show user'), 1114 ('u', 'user', None, 'show user'),
1097 ('n', 'number', None, 'show revision number'), 1115 ('n', 'number', None, 'show revision number'),
1098 ('c', 'changeset', None, 'show changeset')], 1116 ('c', 'changeset', None, 'show changeset')],
1099 'hg annotate [-r REV] [-u] [-n] [-c] FILE...'), 1117 'hg annotate [-r REV] [-u] [-n] [-c] FILE...'),
1100 "cat": 1118 "cat":
1118 "debugstate": (debugstate, [], 'debugstate'), 1136 "debugstate": (debugstate, [], 'debugstate'),
1119 "debugindex": (debugindex, [], 'debugindex FILE'), 1137 "debugindex": (debugindex, [], 'debugindex FILE'),
1120 "debugindexdot": (debugindexdot, [], 'debugindexdot FILE'), 1138 "debugindexdot": (debugindexdot, [], 'debugindexdot FILE'),
1121 "^diff": 1139 "^diff":
1122 (diff, 1140 (diff,
1123 [('r', 'rev', [], 'revision')], 1141 [('I', 'include', [], 'include path in search'),
1142 ('X', 'exclude', [], 'exclude path from search'),
1143 ('r', 'rev', [], 'revision')],
1124 'hg diff [-r REV1 [-r REV2]] [FILE]...'), 1144 'hg diff [-r REV1 [-r REV2]] [FILE]...'),
1125 "^export": 1145 "^export":
1126 (export, 1146 (export,
1127 [('o', 'output', "", 'output to file')], 1147 [('o', 'output', "", 'output to file')],
1128 "hg export [-o OUTFILE] REV..."), 1148 "hg export [-o OUTFILE] REV..."),
1138 "^init": (init, [], 'hg init'), 1158 "^init": (init, [], 'hg init'),
1139 "locate": 1159 "locate":
1140 (locate, 1160 (locate,
1141 [('0', 'print0', None, 'end records with NUL'), 1161 [('0', 'print0', None, 'end records with NUL'),
1142 ('f', 'fullpath', None, 'print complete paths'), 1162 ('f', 'fullpath', None, 'print complete paths'),
1143 ('i', 'include', [], 'include path in search'), 1163 ('I', 'include', [], 'include path in search'),
1144 ('r', 'rev', '', 'revision'), 1164 ('r', 'rev', '', 'revision'),
1145 ('x', 'exclude', [], 'exclude path from search')], 1165 ('X', 'exclude', [], 'exclude path from search')],
1146 'hg locate [OPTION]... [PATTERN]...'), 1166 'hg locate [OPTION]... [PATTERN]...'),
1147 "^log|history": 1167 "^log|history":
1148 (log, 1168 (log,
1149 [('r', 'rev', [], 'revision'), 1169 [('r', 'rev', [], 'revision'),
1150 ('p', 'patch', None, 'show patch')], 1170 ('p', 'patch', None, 'show patch')],
1151 'hg log [-r REV1 [-r REV2]] [-p] [FILE]'), 1171 'hg log [-r REV1 [-r REV2]] [-p] [FILE]'),
1172 "list|ls": (ls,
1173 [('I', 'include', [], 'include path in search'),
1174 ('X', 'exclude', [], 'exclude path from search')],
1175 "hg ls [OPTION]... [PATTERN]...."),
1152 "manifest": (manifest, [], 'hg manifest [REV]'), 1176 "manifest": (manifest, [], 'hg manifest [REV]'),
1153 "parents": (parents, [], 'hg parents [REV]'), 1177 "parents": (parents, [], 'hg parents [REV]'),
1154 "^pull": 1178 "^pull":
1155 (pull, 1179 (pull,
1156 [('u', 'update', None, 'update working directory')], 1180 [('u', 'update', None, 'update working directory')],
1181 ('a', 'address', '', 'interface address'), 1205 ('a', 'address', '', 'interface address'),
1182 ('n', 'name', os.getcwd(), 'repository name'), 1206 ('n', 'name', os.getcwd(), 'repository name'),
1183 ('', 'stdio', None, 'for remote clients'), 1207 ('', 'stdio', None, 'for remote clients'),
1184 ('t', 'templates', "", 'template map')], 1208 ('t', 'templates', "", 'template map')],
1185 "hg serve [OPTION]..."), 1209 "hg serve [OPTION]..."),
1186 "^status": (status, [], 'hg status'), 1210 "^status": (status,
1211 [('I', 'include', [], 'include path in search'),
1212 ('X', 'exclude', [], 'exclude path from search')],
1213 'hg status [OPTION]... [FILE]...'),
1187 "tag": 1214 "tag":
1188 (tag, 1215 (tag,
1189 [('l', 'local', None, 'make the tag local'), 1216 [('l', 'local', None, 'make the tag local'),
1190 ('t', 'text', "", 'commit text'), 1217 ('t', 'text', "", 'commit text'),
1191 ('d', 'date', "", 'date code'), 1218 ('d', 'date', "", 'date code'),
1342 except OSError, inst: 1369 except OSError, inst:
1343 if hasattr(inst, "filename"): 1370 if hasattr(inst, "filename"):
1344 u.warn("abort: %s: %s\n" % (inst.strerror, inst.filename)) 1371 u.warn("abort: %s: %s\n" % (inst.strerror, inst.filename))
1345 else: 1372 else:
1346 u.warn("abort: %s\n" % inst.strerror) 1373 u.warn("abort: %s\n" % inst.strerror)
1374 except Abort, inst:
1375 u.warn('abort: ', inst.args[0] % inst.args[1:], '\n')
1376 sys.exit(1)
1347 except TypeError, inst: 1377 except TypeError, inst:
1348 # was this an argument error? 1378 # was this an argument error?
1349 tb = traceback.extract_tb(sys.exc_info()[2]) 1379 tb = traceback.extract_tb(sys.exc_info()[2])
1350 if len(tb) > 2: # no 1380 if len(tb) > 2: # no
1351 raise 1381 raise