11 demandload(globals(), "fnmatch hgweb mdiff random signal time traceback") |
11 demandload(globals(), "fnmatch hgweb mdiff random signal time traceback") |
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 |
|
17 class Abort(Exception): |
|
18 """Raised if a command needs to print an error and exit.""" |
16 |
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: |
91 num = repo.changelog.rev(repo.lookup(val)) |
94 num = repo.changelog.rev(repo.lookup(val)) |
92 except KeyError: |
95 except KeyError: |
93 try: |
96 try: |
94 num = revlog.rev(revlog.lookup(val)) |
97 num = revlog.rev(revlog.lookup(val)) |
95 except KeyError: |
98 except KeyError: |
96 ui.warn('abort: invalid revision identifier %s\n' % val) |
99 raise Abort('invalid revision identifier %s', val) |
97 sys.exit(1) |
|
98 return num |
100 return num |
99 for spec in revs: |
101 for spec in revs: |
100 if spec.find(revrangesep) >= 0: |
102 if spec.find(revrangesep) >= 0: |
101 start, end = spec.split(revrangesep, 1) |
103 start, end = spec.split(revrangesep, 1) |
102 start = fix(start, 0) |
104 start = fix(start, 0) |
122 expander = { |
124 expander = { |
123 '%': lambda: '%', |
125 '%': lambda: '%', |
124 'b': lambda: os.path.basename(repo.root), |
126 'b': lambda: os.path.basename(repo.root), |
125 } |
127 } |
126 |
128 |
127 if node: |
129 try: |
128 expander.update(node_expander) |
130 if node: |
129 if node and revwidth is not None: |
131 expander.update(node_expander) |
130 expander['r'] = lambda: str(r.rev(node)).zfill(revwidth) |
132 if node and revwidth is not None: |
131 if total is not None: |
133 expander['r'] = lambda: str(r.rev(node)).zfill(revwidth) |
132 expander['N'] = lambda: str(total) |
134 if total is not None: |
133 if seqno is not None: |
135 expander['N'] = lambda: str(total) |
134 expander['n'] = lambda: str(seqno) |
136 if seqno is not None: |
135 if total is not None and seqno is not None: |
137 expander['n'] = lambda: str(seqno) |
136 expander['n'] = lambda:str(seqno).zfill(len(str(total))) |
138 if total is not None and seqno is not None: |
137 |
139 expander['n'] = lambda:str(seqno).zfill(len(str(total))) |
138 newname = [] |
140 |
139 patlen = len(pat) |
141 newname = [] |
140 i = 0 |
142 patlen = len(pat) |
141 while i < patlen: |
143 i = 0 |
142 c = pat[i] |
144 while i < patlen: |
143 if c == '%': |
145 c = pat[i] |
|
146 if c == '%': |
|
147 i += 1 |
|
148 c = pat[i] |
|
149 c = expander[c]() |
|
150 newname.append(c) |
144 i += 1 |
151 i += 1 |
145 c = pat[i] |
152 return ''.join(newname) |
146 c = expander[c]() |
153 except KeyError, inst: |
147 newname.append(c) |
154 raise Abort("invalid format spec '%%%s' in output file name", |
148 i += 1 |
155 inst.args[0]) |
149 return ''.join(newname) |
|
150 |
156 |
151 def dodiff(fp, ui, repo, files=None, node1=None, node2=None): |
157 def dodiff(fp, ui, repo, files=None, node1=None, node2=None): |
152 def date(c): |
158 def date(c): |
153 return time.asctime(time.gmtime(float(c[2].split(' ')[0]))) |
159 return time.asctime(time.gmtime(float(c[2].split(' ')[0]))) |
154 |
160 |
402 if rev: |
408 if rev: |
403 n = r.lookup(rev) |
409 n = r.lookup(rev) |
404 else: |
410 else: |
405 n = r.tip() |
411 n = r.tip() |
406 if opts['output'] and opts['output'] != '-': |
412 if opts['output'] and opts['output'] != '-': |
407 try: |
413 fp = open(make_filename(repo, r, opts['output'], node=n), 'wb') |
408 outname = make_filename(repo, r, opts['output'], node=n) |
|
409 fp = open(outname, 'wb') |
|
410 except KeyError, inst: |
|
411 ui.warn("error: invlaid format spec '%%%s' in output file name\n" % |
|
412 inst.args[0]) |
|
413 sys.exit(1); |
|
414 else: |
414 else: |
415 fp = sys.stdout |
415 fp = sys.stdout |
416 fp.write(r.read(n)) |
416 fp.write(r.read(n)) |
417 |
417 |
418 def clone(ui, source, dest=None, **opts): |
418 def clone(ui, source, dest=None, **opts): |
514 state = repo.dirstate.state(f) |
514 state = repo.dirstate.state(f) |
515 if state not in "nrm": |
515 if state not in "nrm": |
516 ui.warn("%s in manifest1, but listed as state %s" % (f, state)) |
516 ui.warn("%s in manifest1, but listed as state %s" % (f, state)) |
517 errors += 1 |
517 errors += 1 |
518 if errors: |
518 if errors: |
519 ui.warn(".hg/dirstate inconsistent with current parent's manifest\n") |
519 raise Abort(".hg/dirstate inconsistent with current parent's manifest") |
520 sys.exit(1) |
|
521 |
520 |
522 def debugstate(ui, repo): |
521 def debugstate(ui, repo): |
523 """show the contents of the current dirstate""" |
522 """show the contents of the current dirstate""" |
524 repo.dirstate.read() |
523 repo.dirstate.read() |
525 dc = repo.dirstate.map |
524 dc = repo.dirstate.map |
555 revs = [] |
554 revs = [] |
556 if opts['rev']: |
555 if opts['rev']: |
557 revs = map(lambda x: repo.lookup(x), opts['rev']) |
556 revs = map(lambda x: repo.lookup(x), opts['rev']) |
558 |
557 |
559 if len(revs) > 2: |
558 if len(revs) > 2: |
560 ui.warn("too many revisions to diff\n") |
559 raise Abort("too many revisions to diff") |
561 sys.exit(1) |
|
562 |
560 |
563 if files: |
561 if files: |
564 files = relpath(repo, files) |
562 files = relpath(repo, files) |
565 else: |
563 else: |
566 files = relpath(repo, [""]) |
564 files = relpath(repo, [""]) |
571 node = repo.lookup(changeset) |
569 node = repo.lookup(changeset) |
572 prev, other = repo.changelog.parents(node) |
570 prev, other = repo.changelog.parents(node) |
573 change = repo.changelog.read(node) |
571 change = repo.changelog.read(node) |
574 |
572 |
575 if opts['output'] and opts['output'] != '-': |
573 if opts['output'] and opts['output'] != '-': |
576 try: |
574 outname = make_filename(repo, repo.changelog, opts['output'], |
577 outname = make_filename(repo, repo.changelog, opts['output'], |
575 node=node, total=total, seqno=seqno, |
578 node=node, total=total, seqno=seqno, |
576 revwidth=revwidth) |
579 revwidth=revwidth) |
577 ui.note("Exporting patch to '%s'.\n" % outname) |
580 ui.note("Exporting patch to '%s'.\n" % outname) |
578 fp = open(outname, 'wb') |
581 fp = open(outname, 'wb') |
|
582 except KeyError, inst: |
|
583 ui.warn("error: invalid format spec '%%%s' in output file name\n" % |
|
584 inst.args[0]) |
|
585 sys.exit(1) |
|
586 else: |
579 else: |
587 fp = sys.stdout |
580 fp = sys.stdout |
588 |
581 |
589 fp.write("# HG changeset patch\n") |
582 fp.write("# HG changeset patch\n") |
590 fp.write("# User %s\n" % change[1]) |
583 fp.write("# User %s\n" % change[1]) |
598 dodiff(fp, ui, repo, None, prev, node) |
591 dodiff(fp, ui, repo, None, prev, node) |
599 |
592 |
600 def export(ui, repo, *changesets, **opts): |
593 def export(ui, repo, *changesets, **opts): |
601 """dump the header and diffs for one or more changesets""" |
594 """dump the header and diffs for one or more changesets""" |
602 if not changesets: |
595 if not changesets: |
603 ui.warn("error: export requires at least one changeset\n") |
596 raise Abort("export requires at least one changeset") |
604 sys.exit(1) |
|
605 seqno = 0 |
597 seqno = 0 |
606 revs = list(revrange(ui, repo, changesets)) |
598 revs = list(revrange(ui, repo, changesets)) |
607 total = len(revs) |
599 total = len(revs) |
608 revwidth = max(len(revs[0]), len(revs[-1])) |
600 revwidth = max(len(revs[0]), len(revs[-1])) |
609 for cset in revs: |
601 for cset in revs: |
693 pf = l[14:] |
685 pf = l[14:] |
694 if pf not in files: |
686 if pf not in files: |
695 files.append(pf) |
687 files.append(pf) |
696 patcherr = f.close() |
688 patcherr = f.close() |
697 if patcherr: |
689 if patcherr: |
698 sys.stderr.write("patch failed") |
690 raise Abort("patch failed") |
699 sys.exit(1) |
|
700 |
691 |
701 if len(files) > 0: |
692 if len(files) > 0: |
702 addremove(ui, repo, *files) |
693 addremove(ui, repo, *files) |
703 repo.commit(files, text, user) |
694 repo.commit(files, text, user) |
704 |
695 |
705 def init(ui, source=None): |
696 def init(ui, source=None): |
706 """create a new repository in the current directory""" |
697 """create a new repository in the current directory""" |
707 |
698 |
708 if source: |
699 if source: |
709 ui.warn("no longer supported: use \"hg clone\" instead\n") |
700 raise Abort("no longer supported: use \"hg clone\" instead") |
710 sys.exit(1) |
|
711 hg.repository(ui, ".", create=1) |
701 hg.repository(ui, ".", create=1) |
712 |
702 |
713 def locate(ui, repo, *pats, **opts): |
703 def locate(ui, repo, *pats, **opts): |
714 """locate files matching specific patterns""" |
704 """locate files matching specific patterns""" |
715 if opts['print0']: end = '\0' |
705 if opts['print0']: end = '\0' |
753 i = filelog.linkrev(filenode) |
743 i = filelog.linkrev(filenode) |
754 changenode = repo.changelog.node(i) |
744 changenode = repo.changelog.node(i) |
755 prev, other = repo.changelog.parents(changenode) |
745 prev, other = repo.changelog.parents(changenode) |
756 dodiff(sys.stdout, ui, repo, files, prev, changenode) |
746 dodiff(sys.stdout, ui, repo, files, prev, changenode) |
757 ui.write("\n\n") |
747 ui.write("\n\n") |
|
748 |
|
749 def ls(ui, repo, *pats, **opts): |
|
750 """list files""" |
|
751 for src, abs, rel in walk(repo, pats, opts): |
|
752 ui.write(rel, '\n') |
758 |
753 |
759 def manifest(ui, repo, rev=None): |
754 def manifest(ui, repo, rev=None): |
760 """output the latest or given revision of the project manifest""" |
755 """output the latest or given revision of the project manifest""" |
761 if rev: |
756 if rev: |
762 try: |
757 try: |
1160 "^log|history": |
1155 "^log|history": |
1161 (log, |
1156 (log, |
1162 [('r', 'rev', [], 'revision'), |
1157 [('r', 'rev', [], 'revision'), |
1163 ('p', 'patch', None, 'show patch')], |
1158 ('p', 'patch', None, 'show patch')], |
1164 'hg log [-r REV1 [-r REV2]] [-p] [FILE]'), |
1159 'hg log [-r REV1 [-r REV2]] [-p] [FILE]'), |
|
1160 "list|ls": (ls, |
|
1161 [('I', 'include', [], 'include path in search'), |
|
1162 ('X', 'exclude', [], 'exclude path from search')], |
|
1163 "hg ls [OPTION]... [PATTERN]...."), |
1165 "manifest": (manifest, [], 'hg manifest [REV]'), |
1164 "manifest": (manifest, [], 'hg manifest [REV]'), |
1166 "parents": (parents, [], 'hg parents [REV]'), |
1165 "parents": (parents, [], 'hg parents [REV]'), |
1167 "^pull": |
1166 "^pull": |
1168 (pull, |
1167 (pull, |
1169 [('u', 'update', None, 'update working directory')], |
1168 [('u', 'update', None, 'update working directory')], |
1355 except OSError, inst: |
1354 except OSError, inst: |
1356 if hasattr(inst, "filename"): |
1355 if hasattr(inst, "filename"): |
1357 u.warn("abort: %s: %s\n" % (inst.strerror, inst.filename)) |
1356 u.warn("abort: %s: %s\n" % (inst.strerror, inst.filename)) |
1358 else: |
1357 else: |
1359 u.warn("abort: %s\n" % inst.strerror) |
1358 u.warn("abort: %s\n" % inst.strerror) |
|
1359 except Abort, inst: |
|
1360 u.warn('abort: ', inst.args[0] % inst.args[1:], '\n') |
|
1361 sys.exit(1) |
1360 except TypeError, inst: |
1362 except TypeError, inst: |
1361 # was this an argument error? |
1363 # was this an argument error? |
1362 tb = traceback.extract_tb(sys.exc_info()[2]) |
1364 tb = traceback.extract_tb(sys.exc_info()[2]) |
1363 if len(tb) > 2: # no |
1365 if len(tb) > 2: # no |
1364 raise |
1366 raise |