mercurial/commands.py
changeset 870 a82eae840447
parent 868 6a8a50bcc143
child 871 c2e77581bc84
equal deleted inserted replaced
869:1e3a23719662 870:a82eae840447
    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] != "/":
    37     if cwd:
    34     if cwd:
    38         return [util.pconvert(os.path.normpath(os.path.join(cwd, x)))
    35         return [util.pconvert(os.path.normpath(os.path.join(cwd, x)))
    39                 for x in args]
    36                 for x in args]
    40     return args
    37     return args
    41 
    38 
    42 def matchpats(cwd, pats = [], opts = {}, head = ''):
    39 def matchpats(repo, cwd, pats = [], opts = {}, head = ''):
    43     return util.matcher(cwd, pats or ['.'], opts.get('include'),
    40     return util.matcher(repo, cwd, pats or ['.'], opts.get('include'),
    44                         opts.get('exclude'), head)
    41                         opts.get('exclude'), head)
    45 
    42 
    46 def pathto(n1, n2):
    43 def pathto(n1, n2):
    47     '''return the relative path from one place to another'''
    44     '''return the relative path from one place to another'''
    48     if not n1: return n2
    45     if not n1: return n2
    53     b.reverse()
    50     b.reverse()
    54     return os.sep.join((['..'] * len(a)) + b)
    51     return os.sep.join((['..'] * len(a)) + b)
    55 
    52 
    56 def makewalk(repo, pats, opts, head = ''):
    53 def makewalk(repo, pats, opts, head = ''):
    57     cwd = repo.getcwd()
    54     cwd = repo.getcwd()
    58     files, matchfn = matchpats(cwd, pats, opts, head)
    55     files, matchfn = matchpats(repo, cwd, pats, opts, head)
    59     def walk():
    56     def walk():
    60         for src, fn in repo.walk(files = files, match = matchfn):
    57         for src, fn in repo.walk(files = files, match = matchfn):
    61             yield src, fn, pathto(cwd, fn)
    58             yield src, fn, pathto(cwd, fn)
    62     return files, matchfn, walk()
    59     return files, matchfn, walk()
    63 
    60 
    87                 num = repo.changelog.rev(repo.lookup(val))
    84                 num = repo.changelog.rev(repo.lookup(val))
    88             except KeyError:
    85             except KeyError:
    89                 try:
    86                 try:
    90                     num = revlog.rev(revlog.lookup(val))
    87                     num = revlog.rev(revlog.lookup(val))
    91                 except KeyError:
    88                 except KeyError:
    92                     raise Abort('invalid revision identifier %s', val)
    89                     raise util.Abort('invalid revision identifier %s', val)
    93         return num
    90         return num
    94     for spec in revs:
    91     for spec in revs:
    95         if spec.find(revrangesep) >= 0:
    92         if spec.find(revrangesep) >= 0:
    96             start, end = spec.split(revrangesep, 1)
    93             start, end = spec.split(revrangesep, 1)
    97             start = fix(start, 0)
    94             start = fix(start, 0)
   142                 c = expander[c]()
   139                 c = expander[c]()
   143             newname.append(c)
   140             newname.append(c)
   144             i += 1
   141             i += 1
   145         return ''.join(newname)
   142         return ''.join(newname)
   146     except KeyError, inst:
   143     except KeyError, inst:
   147         raise Abort("invalid format spec '%%%s' in output file name",
   144         raise util.Abort("invalid format spec '%%%s' in output file name",
   148                     inst.args[0])
   145                     inst.args[0])
   149 
   146 
   150 def make_file(repo, r, pat, node=None,
   147 def make_file(repo, r, pat, node=None,
   151               total=None, seqno=None, revwidth=None, mode='wb'):
   148               total=None, seqno=None, revwidth=None, mode='wb'):
   152     if not pat or pat == '-':
   149     if not pat or pat == '-':
   385                 name = name[f+1:]
   382                 name = name[f+1:]
   386             bcache[rev] = name
   383             bcache[rev] = name
   387             return name
   384             return name
   388 
   385 
   389     if not pats:
   386     if not pats:
   390         raise Abort('at least one file name or pattern required')
   387         raise util.Abort('at least one file name or pattern required')
   391 
   388 
   392     bcache = {}
   389     bcache = {}
   393     opmap = [['user', getname], ['number', str], ['changeset', getnode]]
   390     opmap = [['user', getname], ['number', str], ['changeset', getnode]]
   394     if not opts['user'] and not opts['changeset']:
   391     if not opts['user'] and not opts['changeset']:
   395         opts['number'] = 1
   392         opts['number'] = 1
   499         addremove(ui, repo, *pats, **opts)
   496         addremove(ui, repo, *pats, **opts)
   500     cwd = repo.getcwd()
   497     cwd = repo.getcwd()
   501     if not pats and cwd:
   498     if not pats and cwd:
   502         opts['include'] = [os.path.join(cwd, i) for i in opts['include']]
   499         opts['include'] = [os.path.join(cwd, i) for i in opts['include']]
   503         opts['exclude'] = [os.path.join(cwd, x) for x in opts['exclude']]
   500         opts['exclude'] = [os.path.join(cwd, x) for x in opts['exclude']]
   504     fns, match = matchpats((pats and repo.getcwd()) or '', pats, opts)
   501     fns, match = matchpats(repo, (pats and repo.getcwd()) or '', pats, opts)
   505     if pats:
   502     if pats:
   506         c, a, d, u = repo.changes(files = fns, match = match)
   503         c, a, d, u = repo.changes(files = fns, match = match)
   507         files = c + a + [fn for fn in d if repo.dirstate.state(fn) == 'r']
   504         files = c + a + [fn for fn in d if repo.dirstate.state(fn) == 'r']
   508     else:
   505     else:
   509         files = []
   506         files = []
   541         state = repo.dirstate.state(f)
   538         state = repo.dirstate.state(f)
   542         if state not in "nrm":
   539         if state not in "nrm":
   543             ui.warn("%s in manifest1, but listed as state %s" % (f, state))
   540             ui.warn("%s in manifest1, but listed as state %s" % (f, state))
   544             errors += 1
   541             errors += 1
   545     if errors:
   542     if errors:
   546         raise Abort(".hg/dirstate inconsistent with current parent's manifest")
   543         raise util.Abort(".hg/dirstate inconsistent with current parent's manifest")
   547 
   544 
   548 def debugstate(ui, repo):
   545 def debugstate(ui, repo):
   549     """show the contents of the current dirstate"""
   546     """show the contents of the current dirstate"""
   550     repo.dirstate.read()
   547     repo.dirstate.read()
   551     dc = repo.dirstate.map
   548     dc = repo.dirstate.map
   590     revs = []
   587     revs = []
   591     if opts['rev']:
   588     if opts['rev']:
   592         revs = map(lambda x: repo.lookup(x), opts['rev'])
   589         revs = map(lambda x: repo.lookup(x), opts['rev'])
   593 
   590 
   594     if len(revs) > 2:
   591     if len(revs) > 2:
   595         raise Abort("too many revisions to diff")
   592         raise util.Abort("too many revisions to diff")
   596 
   593 
   597     files = []
   594     files = []
   598     roots, match, results = makewalk(repo, pats, opts)
   595     roots, match, results = makewalk(repo, pats, opts)
   599     for src, abs, rel in results:
   596     for src, abs, rel in results:
   600         files.append(abs)
   597         files.append(abs)
   624     if fp != sys.stdout: fp.close()
   621     if fp != sys.stdout: fp.close()
   625 
   622 
   626 def export(ui, repo, *changesets, **opts):
   623 def export(ui, repo, *changesets, **opts):
   627     """dump the header and diffs for one or more changesets"""
   624     """dump the header and diffs for one or more changesets"""
   628     if not changesets:
   625     if not changesets:
   629         raise Abort("export requires at least one changeset")
   626         raise util.Abort("export requires at least one changeset")
   630     seqno = 0
   627     seqno = 0
   631     revs = list(revrange(ui, repo, changesets))
   628     revs = list(revrange(ui, repo, changesets))
   632     total = len(revs)
   629     total = len(revs)
   633     revwidth = max(len(revs[0]), len(revs[-1]))
   630     revwidth = max(len(revs[0]), len(revs[-1]))
   634     ui.note(len(revs) > 1 and "Exporting patches:\n" or "Exporting patch:\n")
   631     ui.note(len(revs) > 1 and "Exporting patches:\n" or "Exporting patch:\n")
   720                 pf = l[14:]
   717                 pf = l[14:]
   721                 if pf not in files:
   718                 if pf not in files:
   722                     files.append(pf)
   719                     files.append(pf)
   723         patcherr = f.close()
   720         patcherr = f.close()
   724         if patcherr:
   721         if patcherr:
   725             raise Abort("patch failed")
   722             raise util.Abort("patch failed")
   726 
   723 
   727         if len(files) > 0:
   724         if len(files) > 0:
   728             addremove(ui, repo, *files)
   725             addremove(ui, repo, *files)
   729         repo.commit(files, message, user)
   726         repo.commit(files, message, user)
   730 
   727 
   731 def init(ui, source=None):
   728 def init(ui, source=None):
   732     """create a new repository in the current directory"""
   729     """create a new repository in the current directory"""
   733 
   730 
   734     if source:
   731     if source:
   735         raise Abort("no longer supported: use \"hg clone\" instead")
   732         raise util.Abort("no longer supported: use \"hg clone\" instead")
   736     hg.repository(ui, ".", create=1)
   733     hg.repository(ui, ".", create=1)
   737 
   734 
   738 def locate(ui, repo, *pats, **opts):
   735 def locate(ui, repo, *pats, **opts):
   739     """locate files matching specific patterns"""
   736     """locate files matching specific patterns"""
   740     end = '\n'
   737     end = '\n'
  1035     A = added
  1032     A = added
  1036     R = removed
  1033     R = removed
  1037     ? = not tracked'''
  1034     ? = not tracked'''
  1038 
  1035 
  1039     cwd = repo.getcwd()
  1036     cwd = repo.getcwd()
  1040     files, matchfn = matchpats(cwd, pats, opts)
  1037     files, matchfn = matchpats(repo, cwd, pats, opts)
  1041     (c, a, d, u) = [[pathto(cwd, x) for x in n]
  1038     (c, a, d, u) = [[pathto(cwd, x) for x in n]
  1042                     for n in repo.changes(files=files, match=matchfn)]
  1039                     for n in repo.changes(files=files, match=matchfn)]
  1043 
  1040 
  1044     for f in c:
  1041     for f in c:
  1045         ui.write("M ", f, "\n")
  1042         ui.write("M ", f, "\n")
  1418                 return d()
  1415                 return d()
  1419         except:
  1416         except:
  1420             if options['traceback']:
  1417             if options['traceback']:
  1421                 traceback.print_exc()
  1418                 traceback.print_exc()
  1422             raise
  1419             raise
  1423     except util.CommandError, inst:
       
  1424         u.warn("abort: %s\n" % inst.args)
       
  1425     except hg.RepoError, inst:
  1420     except hg.RepoError, inst:
  1426         u.warn("abort: ", inst, "!\n")
  1421         u.warn("abort: ", inst, "!\n")
  1427     except SignalInterrupt:
  1422     except SignalInterrupt:
  1428         u.warn("killed!\n")
  1423         u.warn("killed!\n")
  1429     except KeyboardInterrupt:
  1424     except KeyboardInterrupt:
  1447     except OSError, inst:
  1442     except OSError, inst:
  1448         if hasattr(inst, "filename"):
  1443         if hasattr(inst, "filename"):
  1449             u.warn("abort: %s: %s\n" % (inst.strerror, inst.filename))
  1444             u.warn("abort: %s: %s\n" % (inst.strerror, inst.filename))
  1450         else:
  1445         else:
  1451             u.warn("abort: %s\n" % inst.strerror)
  1446             u.warn("abort: %s\n" % inst.strerror)
  1452     except Abort, inst:
  1447     except util.Abort, inst:
  1453         u.warn('abort: ', inst.args[0] % inst.args[1:], '\n')
  1448         u.warn('abort: ', inst.args[0] % inst.args[1:], '\n')
  1454         sys.exit(1)
  1449         sys.exit(1)
  1455     except TypeError, inst:
  1450     except TypeError, inst:
  1456         # was this an argument error?
  1451         # was this an argument error?
  1457         tb = traceback.extract_tb(sys.exc_info()[2])
  1452         tb = traceback.extract_tb(sys.exc_info()[2])