12 demandload(globals(), "errno socket version struct atexit") |
12 demandload(globals(), "errno socket version struct atexit") |
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 |
|
20 def filterfiles(filters, files): |
17 def filterfiles(filters, files): |
21 l = [x for x in files if x in filters] |
18 l = [x for x in files if x in filters] |
22 |
19 |
23 for t in filters: |
20 for t in filters: |
24 if t and t[-1] != "/": |
21 if t and t[-1] != "/": |
33 return files |
30 return files |
34 |
31 |
35 def relpath(repo, args): |
32 def relpath(repo, args): |
36 cwd = repo.getcwd() |
33 cwd = repo.getcwd() |
37 if cwd: |
34 if cwd: |
38 return [util.pconvert(os.path.normpath(os.path.join(cwd, x))) |
35 return [util.normpath(os.path.join(cwd, x)) for x in args] |
39 for x in args] |
|
40 return args |
36 return args |
41 |
37 |
42 def matchpats(cwd, pats = [], opts = {}, head = ''): |
38 def matchpats(repo, cwd, pats = [], opts = {}, head = ''): |
43 return util.matcher(cwd, pats or ['.'], opts.get('include'), |
39 return util.matcher(repo, cwd, pats or ['.'], opts.get('include'), |
44 opts.get('exclude'), head) |
40 opts.get('exclude'), head) |
45 |
|
46 def pathto(n1, n2): |
|
47 '''return the relative path from one place to another''' |
|
48 if not n1: return n2 |
|
49 a, b = n1.split(os.sep), n2.split(os.sep) |
|
50 a.reverse(), b.reverse() |
|
51 while a and b and a[-1] == b[-1]: |
|
52 a.pop(), b.pop() |
|
53 b.reverse() |
|
54 return os.sep.join((['..'] * len(a)) + b) |
|
55 |
41 |
56 def makewalk(repo, pats, opts, head = ''): |
42 def makewalk(repo, pats, opts, head = ''): |
57 cwd = repo.getcwd() |
43 cwd = repo.getcwd() |
58 files, matchfn = matchpats(cwd, pats, opts, head) |
44 files, matchfn = matchpats(repo, cwd, pats, opts, head) |
59 def walk(): |
45 def walk(): |
60 for src, fn in repo.walk(files = files, match = matchfn): |
46 for src, fn in repo.walk(files = files, match = matchfn): |
61 yield src, fn, pathto(cwd, fn) |
47 yield src, fn, util.pathto(cwd, fn) |
62 return files, matchfn, walk() |
48 return files, matchfn, walk() |
63 |
49 |
64 def walk(repo, pats, opts, head = ''): |
50 def walk(repo, pats, opts, head = ''): |
65 files, matchfn, results = makewalk(repo, pats, opts, head) |
51 files, matchfn, results = makewalk(repo, pats, opts, head) |
66 for r in results: yield r |
52 for r in results: yield r |
87 num = repo.changelog.rev(repo.lookup(val)) |
73 num = repo.changelog.rev(repo.lookup(val)) |
88 except KeyError: |
74 except KeyError: |
89 try: |
75 try: |
90 num = revlog.rev(revlog.lookup(val)) |
76 num = revlog.rev(revlog.lookup(val)) |
91 except KeyError: |
77 except KeyError: |
92 raise Abort('invalid revision identifier %s', val) |
78 raise util.Abort('invalid revision identifier %s', val) |
93 return num |
79 return num |
94 for spec in revs: |
80 for spec in revs: |
95 if spec.find(revrangesep) >= 0: |
81 if spec.find(revrangesep) >= 0: |
96 start, end = spec.split(revrangesep, 1) |
82 start, end = spec.split(revrangesep, 1) |
97 start = fix(start, 0) |
83 start = fix(start, 0) |
142 c = expander[c]() |
128 c = expander[c]() |
143 newname.append(c) |
129 newname.append(c) |
144 i += 1 |
130 i += 1 |
145 return ''.join(newname) |
131 return ''.join(newname) |
146 except KeyError, inst: |
132 except KeyError, inst: |
147 raise Abort("invalid format spec '%%%s' in output file name", |
133 raise util.Abort("invalid format spec '%%%s' in output file name", |
148 inst.args[0]) |
134 inst.args[0]) |
149 |
135 |
150 def make_file(repo, r, pat, node=None, |
136 def make_file(repo, r, pat, node=None, |
151 total=None, seqno=None, revwidth=None, mode='wb'): |
137 total=None, seqno=None, revwidth=None, mode='wb'): |
152 if not pat or pat == '-': |
138 if not pat or pat == '-': |
394 def addremove(ui, repo, *pats, **opts): |
380 def addremove(ui, repo, *pats, **opts): |
395 """add all new files, delete all missing files""" |
381 """add all new files, delete all missing files""" |
396 q = dict(zip(pats, pats)) |
382 q = dict(zip(pats, pats)) |
397 add, remove = [], [] |
383 add, remove = [], [] |
398 for src, abs, rel in walk(repo, pats, opts): |
384 for src, abs, rel in walk(repo, pats, opts): |
399 if src == 'f': |
385 if src == 'f' and repo.dirstate.state(abs) == '?': |
400 if repo.dirstate.state(abs) == '?': |
386 add.append(abs) |
401 add.append(abs) |
387 if rel not in q: ui.status('adding ', rel, '\n') |
402 if rel not in q: ui.status('adding ', rel, '\n') |
388 if repo.dirstate.state(abs) != 'r' and not os.path.exists(rel): |
403 elif repo.dirstate.state(abs) != 'r' and not os.path.exists(rel): |
|
404 remove.append(abs) |
389 remove.append(abs) |
405 if rel not in q: ui.status('removing ', rel, '\n') |
390 if rel not in q: ui.status('removing ', rel, '\n') |
406 repo.add(add) |
391 repo.add(add) |
407 repo.remove(remove) |
392 repo.remove(remove) |
408 |
393 |
539 addremove(ui, repo, *pats, **opts) |
526 addremove(ui, repo, *pats, **opts) |
540 cwd = repo.getcwd() |
527 cwd = repo.getcwd() |
541 if not pats and cwd: |
528 if not pats and cwd: |
542 opts['include'] = [os.path.join(cwd, i) for i in opts['include']] |
529 opts['include'] = [os.path.join(cwd, i) for i in opts['include']] |
543 opts['exclude'] = [os.path.join(cwd, x) for x in opts['exclude']] |
530 opts['exclude'] = [os.path.join(cwd, x) for x in opts['exclude']] |
544 fns, match = matchpats((pats and repo.getcwd()) or '', pats, opts) |
531 fns, match = matchpats(repo, (pats and repo.getcwd()) or '', pats, opts) |
545 if pats: |
532 if pats: |
546 c, a, d, u = repo.changes(files = fns, match = match) |
533 c, a, d, u = repo.changes(files = fns, match = match) |
547 files = c + a + [fn for fn in d if repo.dirstate.state(fn) == 'r'] |
534 files = c + a + [fn for fn in d if repo.dirstate.state(fn) == 'r'] |
548 else: |
535 else: |
549 files = [] |
536 files = [] |
581 state = repo.dirstate.state(f) |
568 state = repo.dirstate.state(f) |
582 if state not in "nrm": |
569 if state not in "nrm": |
583 ui.warn("%s in manifest1, but listed as state %s" % (f, state)) |
570 ui.warn("%s in manifest1, but listed as state %s" % (f, state)) |
584 errors += 1 |
571 errors += 1 |
585 if errors: |
572 if errors: |
586 raise Abort(".hg/dirstate inconsistent with current parent's manifest") |
573 raise util.Abort(".hg/dirstate inconsistent with current parent's manifest") |
587 |
574 |
588 def debugstate(ui, repo): |
575 def debugstate(ui, repo): |
589 """show the contents of the current dirstate""" |
576 """show the contents of the current dirstate""" |
590 repo.dirstate.read() |
577 repo.dirstate.read() |
591 dc = repo.dirstate.map |
578 dc = repo.dirstate.map |
619 ui.write("\t%d -> %d\n" % (r.rev(e[5]), i)) |
606 ui.write("\t%d -> %d\n" % (r.rev(e[5]), i)) |
620 ui.write("}\n") |
607 ui.write("}\n") |
621 |
608 |
622 def debugwalk(ui, repo, *pats, **opts): |
609 def debugwalk(ui, repo, *pats, **opts): |
623 items = list(walk(repo, pats, opts)) |
610 items = list(walk(repo, pats, opts)) |
|
611 if not items: return |
624 fmt = '%%s %%-%ds %%s' % max([len(abs) for (src, abs, rel) in items]) |
612 fmt = '%%s %%-%ds %%s' % max([len(abs) for (src, abs, rel) in items]) |
625 for i in items: print fmt % i |
613 for i in items: print fmt % i |
626 |
614 |
627 def diff(ui, repo, *pats, **opts): |
615 def diff(ui, repo, *pats, **opts): |
628 """diff working directory (or selected files)""" |
616 """diff working directory (or selected files)""" |
629 revs = [] |
617 revs = [] |
630 if opts['rev']: |
618 if opts['rev']: |
631 revs = map(lambda x: repo.lookup(x), opts['rev']) |
619 revs = map(lambda x: repo.lookup(x), opts['rev']) |
632 |
620 |
633 if len(revs) > 2: |
621 if len(revs) > 2: |
634 raise Abort("too many revisions to diff") |
622 raise util.Abort("too many revisions to diff") |
635 |
623 |
636 files = [] |
624 files = [] |
637 roots, match, results = makewalk(repo, pats, opts) |
625 match = util.always |
638 for src, abs, rel in results: |
626 if pats: |
639 files.append(abs) |
627 roots, match, results = makewalk(repo, pats, opts) |
|
628 for src, abs, rel in results: |
|
629 files.append(abs) |
640 dodiff(sys.stdout, ui, repo, files, *revs, **{'match': match}) |
630 dodiff(sys.stdout, ui, repo, files, *revs, **{'match': match}) |
641 |
631 |
642 def doexport(ui, repo, changeset, seqno, total, revwidth, opts): |
632 def doexport(ui, repo, changeset, seqno, total, revwidth, opts): |
643 node = repo.lookup(changeset) |
633 node = repo.lookup(changeset) |
644 prev, other = repo.changelog.parents(node) |
634 prev, other = repo.changelog.parents(node) |
663 if fp != sys.stdout: fp.close() |
653 if fp != sys.stdout: fp.close() |
664 |
654 |
665 def export(ui, repo, *changesets, **opts): |
655 def export(ui, repo, *changesets, **opts): |
666 """dump the header and diffs for one or more changesets""" |
656 """dump the header and diffs for one or more changesets""" |
667 if not changesets: |
657 if not changesets: |
668 raise Abort("export requires at least one changeset") |
658 raise util.Abort("export requires at least one changeset") |
669 seqno = 0 |
659 seqno = 0 |
670 revs = list(revrange(ui, repo, changesets)) |
660 revs = list(revrange(ui, repo, changesets)) |
671 total = len(revs) |
661 total = len(revs) |
672 revwidth = max(len(revs[0]), len(revs[-1])) |
662 revwidth = max(len(revs[0]), len(revs[-1])) |
673 ui.note(len(revs) > 1 and "Exporting patches:\n" or "Exporting patch:\n") |
663 ui.note(len(revs) > 1 and "Exporting patches:\n" or "Exporting patch:\n") |
760 pf = l[14:] |
750 pf = l[14:] |
761 if pf not in files: |
751 if pf not in files: |
762 files.append(pf) |
752 files.append(pf) |
763 patcherr = f.close() |
753 patcherr = f.close() |
764 if patcherr: |
754 if patcherr: |
765 raise Abort("patch failed") |
755 raise util.Abort("patch failed") |
766 |
756 |
767 if len(files) > 0: |
757 if len(files) > 0: |
768 addremove(ui, repo, *files) |
758 addremove(ui, repo, *files) |
769 repo.commit(files, message, user) |
759 repo.commit(files, message, user) |
770 |
760 |
771 def init(ui, source=None): |
761 def init(ui, source=None): |
772 """create a new repository in the current directory""" |
762 """create a new repository in the current directory""" |
773 |
763 |
774 if source: |
764 if source: |
775 raise Abort("no longer supported: use \"hg clone\" instead") |
765 raise util.Abort("no longer supported: use \"hg clone\" instead") |
776 hg.repository(ui, ".", create=1) |
766 hg.repository(ui, ".", create=1) |
777 |
767 |
778 def locate(ui, repo, *pats, **opts): |
768 def locate(ui, repo, *pats, **opts): |
779 """locate files matching specific patterns""" |
769 """locate files matching specific patterns""" |
780 end = '\n' |
770 end = '\n' |
1076 R = removed |
1066 R = removed |
1077 ? = not tracked |
1067 ? = not tracked |
1078 ''' |
1068 ''' |
1079 |
1069 |
1080 cwd = repo.getcwd() |
1070 cwd = repo.getcwd() |
1081 files, matchfn = matchpats(cwd, pats, opts) |
1071 files, matchfn = matchpats(repo, cwd, pats, opts) |
1082 (c, a, d, u) = [[pathto(cwd, x) for x in n] |
1072 (c, a, d, u) = [[util.pathto(cwd, x) for x in n] |
1083 for n in repo.changes(files=files, match=matchfn)] |
1073 for n in repo.changes(files=files, match=matchfn)] |
1084 |
1074 |
1085 changetypes = [('modified', 'M', c), |
1075 changetypes = [('modified', 'M', c), |
1086 ('added', 'A', a), |
1076 ('added', 'A', a), |
1087 ('removed', 'R', d), |
1077 ('removed', 'R', d), |
1469 return d() |
1459 return d() |
1470 except: |
1460 except: |
1471 if options['traceback']: |
1461 if options['traceback']: |
1472 traceback.print_exc() |
1462 traceback.print_exc() |
1473 raise |
1463 raise |
1474 except util.CommandError, inst: |
|
1475 u.warn("abort: %s\n" % inst.args) |
|
1476 except hg.RepoError, inst: |
1464 except hg.RepoError, inst: |
1477 u.warn("abort: ", inst, "!\n") |
1465 u.warn("abort: ", inst, "!\n") |
1478 except SignalInterrupt: |
1466 except SignalInterrupt: |
1479 u.warn("killed!\n") |
1467 u.warn("killed!\n") |
1480 except KeyboardInterrupt: |
1468 except KeyboardInterrupt: |
1498 except OSError, inst: |
1486 except OSError, inst: |
1499 if hasattr(inst, "filename"): |
1487 if hasattr(inst, "filename"): |
1500 u.warn("abort: %s: %s\n" % (inst.strerror, inst.filename)) |
1488 u.warn("abort: %s: %s\n" % (inst.strerror, inst.filename)) |
1501 else: |
1489 else: |
1502 u.warn("abort: %s\n" % inst.strerror) |
1490 u.warn("abort: %s\n" % inst.strerror) |
1503 except Abort, inst: |
1491 except util.Abort, inst: |
1504 u.warn('abort: ', inst.args[0] % inst.args[1:], '\n') |
1492 u.warn('abort: ', inst.args[0] % inst.args[1:], '\n') |
1505 sys.exit(1) |
1493 sys.exit(1) |
1506 except TypeError, inst: |
1494 except TypeError, inst: |
1507 # was this an argument error? |
1495 # was this an argument error? |
1508 tb = traceback.extract_tb(sys.exc_info()[2]) |
1496 tb = traceback.extract_tb(sys.exc_info()[2]) |