Mercurial > public > mercurial-scm > hg
comparison mercurial/commands.py @ 596:9a8daeff0ffa
A bunch of parsing/help updates
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
A bunch of parsing/help updates
more explanation of how to get non-basic commands
shorten names of debug functions and add docstrings
add undo long docstring
promote anotate, export, and revert
make the global opts array global
refactor parsing
kill two unused arguments to fancyopts
update test-help
manifest hash: 459ae2273aaf54f71b4576677a681dc53ab2908c
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (GNU/Linux)
iD8DBQFCyEDhywK+sNU5EO8RAr0DAJ9LTu8Fc2quLRtuwLPTQzWqlOJWKwCbBpZk
pnMkYnshsutVYljcil1P46I=
=Sleg
-----END PGP SIGNATURE-----
author | mpm@selenic.com |
---|---|
date | Sun, 03 Jul 2005 11:47:45 -0800 |
parents | ca3c499e94c6 |
children | bc5d058e65e9 |
comparison
equal
deleted
inserted
replaced
595:c2c2c6d617bd | 596:9a8daeff0ffa |
---|---|
219 show_version(ui) | 219 show_version(ui) |
220 ui.write('\n') | 220 ui.write('\n') |
221 if ui.verbose: | 221 if ui.verbose: |
222 ui.write('hg commands:\n\n') | 222 ui.write('hg commands:\n\n') |
223 else: | 223 else: |
224 ui.write('basic hg commands (use -v for long list):\n\n') | 224 ui.write('basic hg commands (use "hg help -v" for more):\n\n') |
225 | 225 |
226 h = {} | 226 h = {} |
227 for c, e in table.items(): | 227 for c, e in table.items(): |
228 f = c.split("|")[0] | 228 f = c.split("|")[0] |
229 if not ui.verbose and not f.startswith("^"): | 229 if not ui.verbose and not f.startswith("^"): |
390 | 390 |
391 def copy(ui, repo, source, dest): | 391 def copy(ui, repo, source, dest): |
392 """mark a file as copied or renamed for the next commit""" | 392 """mark a file as copied or renamed for the next commit""" |
393 return repo.copy(*relpath(repo, (source, dest))) | 393 return repo.copy(*relpath(repo, (source, dest))) |
394 | 394 |
395 def debugcheckdirstate(ui, repo): | 395 def debugcheckstate(ui, repo): |
396 """validate the correctness of the current dirstate""" | |
396 parent1, parent2 = repo.dirstate.parents() | 397 parent1, parent2 = repo.dirstate.parents() |
397 repo.dirstate.read() | 398 repo.dirstate.read() |
398 dc = repo.dirstate.map | 399 dc = repo.dirstate.map |
399 keys = dc.keys() | 400 keys = dc.keys() |
400 keys.sort() | 401 keys.sort() |
422 errors += 1 | 423 errors += 1 |
423 if errors: | 424 if errors: |
424 ui.warn(".hg/dirstate inconsistent with current parent's manifest\n") | 425 ui.warn(".hg/dirstate inconsistent with current parent's manifest\n") |
425 sys.exit(1) | 426 sys.exit(1) |
426 | 427 |
427 def debugdumpdirstate(ui, repo): | 428 def debugstate(ui, repo): |
429 """show the contents of the current dirstate""" | |
428 repo.dirstate.read() | 430 repo.dirstate.read() |
429 dc = repo.dirstate.map | 431 dc = repo.dirstate.map |
430 keys = dc.keys() | 432 keys = dc.keys() |
431 keys.sort() | 433 keys.sort() |
432 for file in keys: | 434 for file in keys: |
433 ui.write("%c %s\n" % (dc[file][0], file)) | 435 ui.write("%c %s\n" % (dc[file][0], file)) |
434 | 436 |
435 def debugindex(ui, file): | 437 def debugindex(ui, file): |
438 """dump the contents of an index file""" | |
436 r = hg.revlog(hg.opener(""), file, "") | 439 r = hg.revlog(hg.opener(""), file, "") |
437 ui.write(" rev offset length base linkrev" + | 440 ui.write(" rev offset length base linkrev" + |
438 " p1 p2 nodeid\n") | 441 " p1 p2 nodeid\n") |
439 for i in range(r.count()): | 442 for i in range(r.count()): |
440 e = r.index[i] | 443 e = r.index[i] |
441 ui.write("% 6d % 9d % 7d % 6d % 7d %s.. %s.. %s..\n" % ( | 444 ui.write("% 6d % 9d % 7d % 6d % 7d %s.. %s.. %s..\n" % ( |
442 i, e[0], e[1], e[2], e[3], | 445 i, e[0], e[1], e[2], e[3], |
443 hg.hex(e[4][:5]), hg.hex(e[5][:5]), hg.hex(e[6][:5]))) | 446 hg.hex(e[4][:5]), hg.hex(e[5][:5]), hg.hex(e[6][:5]))) |
444 | 447 |
445 def debugindexdot(ui, file): | 448 def debugindexdot(ui, file): |
449 """dump an index DAG as a .dot file""" | |
446 r = hg.revlog(hg.opener(""), file, "") | 450 r = hg.revlog(hg.opener(""), file, "") |
447 ui.write("digraph G {\n") | 451 ui.write("digraph G {\n") |
448 for i in range(r.count()): | 452 for i in range(r.count()): |
449 e = r.index[i] | 453 e = r.index[i] |
450 ui.write("\t%d -> %d\n" % (r.rev(e[4]), i)) | 454 ui.write("\t%d -> %d\n" % (r.rev(e[4]), i)) |
856 """show the tip revision""" | 860 """show the tip revision""" |
857 n = repo.changelog.tip() | 861 n = repo.changelog.tip() |
858 show_changeset(ui, repo, changenode=n) | 862 show_changeset(ui, repo, changenode=n) |
859 | 863 |
860 def undo(ui, repo): | 864 def undo(ui, repo): |
861 """undo the last transaction""" | 865 """undo the last commit or pull |
866 | |
867 Roll back the last pull or commit transaction on the | |
868 repository, restoring the project to its earlier state. | |
869 | |
870 This command should be used with care. There is only one level of | |
871 undo and there is no redo. | |
872 | |
873 This command is not intended for use on public repositories. Once | |
874 a change is visible for pull by other users, undoing it locally is | |
875 ineffective. | |
876 """ | |
862 repo.undo() | 877 repo.undo() |
863 | 878 |
864 def update(ui, repo, node=None, merge=False, clean=False): | 879 def update(ui, repo, node=None, merge=False, clean=False): |
865 '''update or merge working directory | 880 '''update or merge working directory |
866 | 881 |
884 # Command options and aliases are listed here, alphabetically | 899 # Command options and aliases are listed here, alphabetically |
885 | 900 |
886 table = { | 901 table = { |
887 "^add": (add, [], "hg add [files]"), | 902 "^add": (add, [], "hg add [files]"), |
888 "addremove": (addremove, [], "hg addremove [files]"), | 903 "addremove": (addremove, [], "hg addremove [files]"), |
889 "annotate": (annotate, | 904 "^annotate": (annotate, |
890 [('r', 'revision', '', 'revision'), | 905 [('r', 'revision', '', 'revision'), |
891 ('u', 'user', None, 'show user'), | 906 ('u', 'user', None, 'show user'), |
892 ('n', 'number', None, 'show revision number'), | 907 ('n', 'number', None, 'show revision number'), |
893 ('c', 'changeset', None, 'show changeset')], | 908 ('c', 'changeset', None, 'show changeset')], |
894 'hg annotate [-u] [-c] [-n] [-r id] [files]'), | 909 'hg annotate [-u] [-c] [-n] [-r id] [files]'), |
901 ('l', 'logfile', "", 'commit text file'), | 916 ('l', 'logfile', "", 'commit text file'), |
902 ('d', 'date', "", 'date code'), | 917 ('d', 'date', "", 'date code'), |
903 ('u', 'user', "", 'user')], | 918 ('u', 'user', "", 'user')], |
904 'hg commit [files]'), | 919 'hg commit [files]'), |
905 "copy": (copy, [], 'hg copy <source> <dest>'), | 920 "copy": (copy, [], 'hg copy <source> <dest>'), |
906 "debugcheckdirstate": (debugcheckdirstate, [], 'debugcheckdirstate'), | 921 "debugcheckstate": (debugcheckstate, [], 'debugcheckstate'), |
907 "debugdumpdirstate": (debugdumpdirstate, [], 'debugdumpdirstate'), | 922 "debugstate": (debugstate, [], 'debugstate'), |
908 "debugindex": (debugindex, [], 'debugindex <file>'), | 923 "debugindex": (debugindex, [], 'debugindex <file>'), |
909 "debugindexdot": (debugindexdot, [], 'debugindexdot <file>'), | 924 "debugindexdot": (debugindexdot, [], 'debugindexdot <file>'), |
910 "^diff": (diff, [('r', 'rev', [], 'revision')], | 925 "^diff": (diff, [('r', 'rev', [], 'revision')], |
911 'hg diff [-r A] [-r B] [files]'), | 926 'hg diff [-r A] [-r B] [files]'), |
912 "export": (export, [('o', 'output', "", 'output to file')], | 927 "^export": (export, [('o', 'output', "", 'output to file')], |
913 "hg export [-o file] <changeset> ..."), | 928 "hg export [-o file] <changeset> ..."), |
914 "forget": (forget, [], "hg forget [files]"), | 929 "forget": (forget, [], "hg forget [files]"), |
915 "heads": (heads, [], 'hg heads'), | 930 "heads": (heads, [], 'hg heads'), |
916 "help": (help, [], 'hg help [command]'), | 931 "help": (help, [], 'hg help [command]'), |
917 "identify|id": (identify, [], 'hg identify'), | 932 "identify|id": (identify, [], 'hg identify'), |
937 ('t', 'text', "", 'commit text'), | 952 ('t', 'text', "", 'commit text'), |
938 ('l', 'logfile', "", 'commit text file')], | 953 ('l', 'logfile', "", 'commit text file')], |
939 'hg rawcommit [options] [files]'), | 954 'hg rawcommit [options] [files]'), |
940 "recover": (recover, [], "hg recover"), | 955 "recover": (recover, [], "hg recover"), |
941 "^remove|rm": (remove, [], "hg remove [files]"), | 956 "^remove|rm": (remove, [], "hg remove [files]"), |
942 "revert": (revert, | 957 "^revert": (revert, |
943 [("n", "nonrecursive", None, "don't recurse into subdirs"), | 958 [("n", "nonrecursive", None, "don't recurse into subdirs"), |
944 ("r", "rev", "", "revision")], | 959 ("r", "rev", "", "revision")], |
945 "hg revert [files|dirs]"), | 960 "hg revert [files|dirs]"), |
946 "root": (root, [], "hg root"), | 961 "root": (root, [], "hg root"), |
947 "^serve": (serve, [('p', 'port', 8000, 'listen port'), | 962 "^serve": (serve, [('p', 'port', 8000, 'listen port'), |
964 'hg update [options] [node]'), | 979 'hg update [options] [node]'), |
965 "verify": (verify, [], 'hg verify'), | 980 "verify": (verify, [], 'hg verify'), |
966 "version": (show_version, [], 'hg version'), | 981 "version": (show_version, [], 'hg version'), |
967 } | 982 } |
968 | 983 |
984 globalopts = [('v', 'verbose', None, 'verbose'), | |
985 ('', 'debug', None, 'debug'), | |
986 ('q', 'quiet', None, 'quiet'), | |
987 ('', 'profile', None, 'profile'), | |
988 ('R', 'repository', "", 'repository root directory'), | |
989 ('', 'traceback', None, 'print traceback on exception'), | |
990 ('y', 'noninteractive', None, 'run non-interactively'), | |
991 ('', 'version', None, 'output version information and exit'), | |
992 ] | |
993 | |
969 norepo = "clone init version help debugindex debugindexdot" | 994 norepo = "clone init version help debugindex debugindexdot" |
970 | 995 |
971 def find(cmd): | 996 def find(cmd): |
972 for e in table.keys(): | 997 for e in table.keys(): |
973 if re.match("(%s)$" % e, cmd): | 998 if re.match("(%s)$" % e, cmd): |
981 raise SignalInterrupt | 1006 raise SignalInterrupt |
982 | 1007 |
983 def run(): | 1008 def run(): |
984 sys.exit(dispatch(sys.argv[1:])) | 1009 sys.exit(dispatch(sys.argv[1:])) |
985 | 1010 |
986 def dispatch(args): | 1011 class ParseError(Exception): pass |
987 signal.signal(signal.SIGTERM, catchterm) | 1012 |
988 | 1013 def parse(args): |
989 def get_ui(): | |
990 return ui.ui(options["verbose"], options["debug"], options["quiet"], | |
991 not options["noninteractive"]) | |
992 | |
993 options = {} | 1014 options = {} |
994 opts = [('v', 'verbose', None, 'verbose'), | 1015 cmdoptions = {} |
995 ('', 'debug', None, 'debug'), | |
996 ('q', 'quiet', None, 'quiet'), | |
997 ('', 'profile', None, 'profile'), | |
998 ('R', 'repository', "", 'repository root directory'), | |
999 ('', 'traceback', None, 'print traceback on exception'), | |
1000 ('y', 'noninteractive', None, 'run non-interactively'), | |
1001 ('', 'version', None, 'output version information and exit'), | |
1002 ] | |
1003 | 1016 |
1004 try: | 1017 try: |
1005 args = fancyopts.fancyopts(args, opts, options, | 1018 args = fancyopts.fancyopts(args, globalopts, options) |
1006 'hg [options] <command> [options] [files]') | |
1007 except fancyopts.getopt.GetoptError, inst: | 1019 except fancyopts.getopt.GetoptError, inst: |
1008 u = ui.ui() | 1020 raise ParseError(cmd, inst) |
1009 u.warn("hg: %s\n" % (inst)) | 1021 |
1010 sys.exit(-1) | 1022 if options["version"]: |
1011 | 1023 return ("version", show_version, [], options, cmdoptions) |
1012 if not args: | 1024 elif not args: |
1013 cmd = "help" | 1025 return ("help", help, [], options, cmdoptions) |
1014 else: | 1026 else: |
1015 cmd, args = args[0], args[1:] | 1027 cmd, args = args[0], args[1:] |
1016 | 1028 |
1017 if options["version"]: | 1029 i = find(cmd) |
1018 show_version(get_ui()) | |
1019 sys.exit(0) | |
1020 | |
1021 try: | |
1022 i = find(cmd) | |
1023 except UnknownCommand: | |
1024 u = get_ui() | |
1025 u.warn("hg: unknown command '%s'\n" % cmd) | |
1026 help(u) | |
1027 sys.exit(1) | |
1028 | 1030 |
1029 # combine global options into local | 1031 # combine global options into local |
1030 c = list(i[1]) | 1032 c = list(i[1]) |
1031 l = len(c) | 1033 l = len(c) |
1032 for o in opts: | 1034 for o in globalopts: |
1033 c.append((o[0], o[1], options[o[1]], o[3])) | 1035 c.append((o[0], o[1], options[o[1]], o[3])) |
1034 | 1036 |
1035 cmdoptions = {} | |
1036 try: | 1037 try: |
1037 args = fancyopts.fancyopts(args, c, cmdoptions, i[2]) | 1038 args = fancyopts.fancyopts(args, c, cmdoptions) |
1038 except fancyopts.getopt.GetoptError, inst: | 1039 except fancyopts.getopt.GetoptError, inst: |
1039 u = get_ui() | 1040 raise ParseError(cmd, inst) |
1040 u.warn("hg %s: %s\n" % (cmd, inst)) | |
1041 help(u, cmd) | |
1042 sys.exit(-1) | |
1043 | 1041 |
1044 # separate global options back out | 1042 # separate global options back out |
1045 for o in opts: | 1043 for o in globalopts: |
1046 n = o[1] | 1044 n = o[1] |
1047 options[n] = cmdoptions[n] | 1045 options[n] = cmdoptions[n] |
1048 del cmdoptions[n] | 1046 del cmdoptions[n] |
1049 | 1047 |
1050 u = get_ui() | 1048 return (cmd, i[0], args, options, cmdoptions) |
1049 | |
1050 def dispatch(args): | |
1051 signal.signal(signal.SIGTERM, catchterm) | |
1052 | |
1053 try: | |
1054 cmd, func, args, options, cmdoptions = parse(args) | |
1055 except ParseError, inst: | |
1056 u = ui.ui() | |
1057 if inst.args[0]: | |
1058 u.warn("hg %s: %s\n" % (inst.args[0], inst.args[1])) | |
1059 help(u, inst.args[0]) | |
1060 else: | |
1061 u.warn("hg: %s\n" % inst.args[1]) | |
1062 help(u) | |
1063 sys.exit(-1) | |
1064 except UnknownCommand, inst: | |
1065 u = ui.ui() | |
1066 u.warn("hg: unknown command '%s'\n" % inst.args[0]) | |
1067 help(u) | |
1068 sys.exit(1) | |
1069 | |
1070 u = ui.ui(options["verbose"], options["debug"], options["quiet"], | |
1071 not options["noninteractive"]) | |
1051 | 1072 |
1052 try: | 1073 try: |
1053 try: | 1074 try: |
1054 if cmd not in norepo.split(): | 1075 if cmd not in norepo.split(): |
1055 path = options["repository"] or "" | 1076 path = options["repository"] or "" |
1056 repo = hg.repository(ui=u, path=path) | 1077 repo = hg.repository(ui=u, path=path) |
1057 d = lambda: i[0](u, repo, *args, **cmdoptions) | 1078 d = lambda: func(u, repo, *args, **cmdoptions) |
1058 else: | 1079 else: |
1059 d = lambda: i[0](u, *args, **cmdoptions) | 1080 d = lambda: func(u, *args, **cmdoptions) |
1060 | 1081 |
1061 if options['profile']: | 1082 if options['profile']: |
1062 import hotshot, hotshot.stats | 1083 import hotshot, hotshot.stats |
1063 prof = hotshot.Profile("hg.prof") | 1084 prof = hotshot.Profile("hg.prof") |
1064 r = prof.runcall(d) | 1085 r = prof.runcall(d) |
1100 # was this an argument error? | 1121 # was this an argument error? |
1101 tb = traceback.extract_tb(sys.exc_info()[2]) | 1122 tb = traceback.extract_tb(sys.exc_info()[2]) |
1102 if len(tb) > 2: # no | 1123 if len(tb) > 2: # no |
1103 raise | 1124 raise |
1104 u.debug(inst, "\n") | 1125 u.debug(inst, "\n") |
1105 u.warn("%s: invalid arguments\n" % i[0].__name__) | 1126 u.warn("%s: invalid arguments\n" % cmd) |
1106 help(u, cmd) | 1127 help(u, cmd) |
1107 | 1128 |
1108 sys.exit(-1) | 1129 sys.exit(-1) |