mercurial/commands.py
changeset 596 9a8daeff0ffa
parent 593 ca3c499e94c6
child 603 bc5d058e65e9
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)