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)