mercurial/commands.py
changeset 2881 cf98cd70d2c4
parent 2877 982c3237c63d
child 2882 c2932ad5476a
equal deleted inserted replaced
2880:eab07a7b7491 2881:cf98cd70d2c4
    48         except IOError, inst:
    48         except IOError, inst:
    49             raise util.Abort(_("can't read commit message '%s': %s") %
    49             raise util.Abort(_("can't read commit message '%s': %s") %
    50                              (logfile, inst.strerror))
    50                              (logfile, inst.strerror))
    51     return message
    51     return message
    52 
    52 
    53 def matchpats(repo, pats=[], opts={}, head=''):
       
    54     cwd = repo.getcwd()
       
    55     if not pats and cwd:
       
    56         opts['include'] = [os.path.join(cwd, i) for i in opts['include']]
       
    57         opts['exclude'] = [os.path.join(cwd, x) for x in opts['exclude']]
       
    58         cwd = ''
       
    59     return util.cmdmatcher(repo.root, cwd, pats or ['.'], opts.get('include'),
       
    60                            opts.get('exclude'), head)
       
    61 
       
    62 def makewalk(repo, pats, opts, node=None, head='', badmatch=None):
       
    63     files, matchfn, anypats = matchpats(repo, pats, opts, head)
       
    64     exact = dict(zip(files, files))
       
    65     def walk():
       
    66         for src, fn in repo.walk(node=node, files=files, match=matchfn,
       
    67                                  badmatch=badmatch):
       
    68             yield src, fn, util.pathto(repo.getcwd(), fn), fn in exact
       
    69     return files, matchfn, walk()
       
    70 
       
    71 def walk(repo, pats, opts, node=None, head='', badmatch=None):
       
    72     files, matchfn, results = makewalk(repo, pats, opts, node, head, badmatch)
       
    73     for r in results:
       
    74         yield r
       
    75 
       
    76 def walkchangerevs(ui, repo, pats, opts):
    53 def walkchangerevs(ui, repo, pats, opts):
    77     '''Iterate over files and the revs they changed in.
    54     '''Iterate over files and the revs they changed in.
    78 
    55 
    79     Callers most commonly need to iterate backwards over the history
    56     Callers most commonly need to iterate backwards over the history
    80     it is interested in.  Doing so has awful (quadratic-looking)
    57     it is interested in.  Doing so has awful (quadratic-looking)
   113                 start -= windowsize
    90                 start -= windowsize
   114                 if windowsize < sizelimit:
    91                 if windowsize < sizelimit:
   115                     windowsize *= 2
    92                     windowsize *= 2
   116 
    93 
   117 
    94 
   118     files, matchfn, anypats = matchpats(repo, pats, opts)
    95     files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
   119     follow = opts.get('follow') or opts.get('follow_first')
    96     follow = opts.get('follow') or opts.get('follow_first')
   120 
    97 
   121     if repo.changelog.count() == 0:
    98     if repo.changelog.count() == 0:
   122         return [], False, matchfn
    99         return [], False, matchfn
   123 
   100 
   651 
   628 
   652     If no names are given, add all files in the repository.
   629     If no names are given, add all files in the repository.
   653     """
   630     """
   654 
   631 
   655     names = []
   632     names = []
   656     for src, abs, rel, exact in walk(repo, pats, opts):
   633     for src, abs, rel, exact in cmdutil.walk(repo, pats, opts):
   657         if exact:
   634         if exact:
   658             if ui.verbose:
   635             if ui.verbose:
   659                 ui.status(_('adding %s\n') % rel)
   636                 ui.status(_('adding %s\n') % rel)
   660             names.append(abs)
   637             names.append(abs)
   661         elif repo.dirstate.state(abs) == '?':
   638         elif repo.dirstate.state(abs) == '?':
   680               '--after instead)\n'))
   657               '--after instead)\n'))
   681     return addremove_lock(ui, repo, pats, opts)
   658     return addremove_lock(ui, repo, pats, opts)
   682 
   659 
   683 def addremove_lock(ui, repo, pats, opts, wlock=None):
   660 def addremove_lock(ui, repo, pats, opts, wlock=None):
   684     add, remove = [], []
   661     add, remove = [], []
   685     for src, abs, rel, exact in walk(repo, pats, opts):
   662     for src, abs, rel, exact in cmdutil.walk(repo, pats, opts):
   686         if src == 'f' and repo.dirstate.state(abs) == '?':
   663         if src == 'f' and repo.dirstate.state(abs) == '?':
   687             add.append(abs)
   664             add.append(abs)
   688             if ui.verbose or not exact:
   665             if ui.verbose or not exact:
   689                 ui.status(_('adding %s\n') % ((pats and rel) or abs))
   666                 ui.status(_('adding %s\n') % ((pats and rel) or abs))
   690         if repo.dirstate.state(abs) != 'r' and not os.path.exists(rel):
   667         if repo.dirstate.state(abs) != 'r' and not os.path.exists(rel):
   734     if not opts['user'] and not opts['changeset'] and not opts['date']:
   711     if not opts['user'] and not opts['changeset'] and not opts['date']:
   735         opts['number'] = 1
   712         opts['number'] = 1
   736 
   713 
   737     ctx = repo.changectx(opts['rev'] or repo.dirstate.parents()[0])
   714     ctx = repo.changectx(opts['rev'] or repo.dirstate.parents()[0])
   738 
   715 
   739     for src, abs, rel, exact in walk(repo, pats, opts, node=ctx.node()):
   716     for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
       
   717                                              node=ctx.node()):
   740         fctx = ctx.filectx(abs)
   718         fctx = ctx.filectx(abs)
   741         if not opts['text'] and util.binary(fctx.data()):
   719         if not opts['text'] and util.binary(fctx.data()):
   742             ui.write(_("%s: binary file\n") % ((pats and rel) or abs))
   720             ui.write(_("%s: binary file\n") % ((pats and rel) or abs))
   743             continue
   721             continue
   744 
   722 
   789                                'specific revision'))
   767                                'specific revision'))
   790 
   768 
   791     dest = cmdutil.make_filename(repo, dest, node)
   769     dest = cmdutil.make_filename(repo, dest, node)
   792     if os.path.realpath(dest) == repo.root:
   770     if os.path.realpath(dest) == repo.root:
   793         raise util.Abort(_('repository root cannot be destination'))
   771         raise util.Abort(_('repository root cannot be destination'))
   794     dummy, matchfn, dummy = matchpats(repo, [], opts)
   772     dummy, matchfn, dummy = cmdutil.matchpats(repo, [], opts)
   795     kind = opts.get('type') or 'files'
   773     kind = opts.get('type') or 'files'
   796     prefix = opts['prefix']
   774     prefix = opts['prefix']
   797     if dest == '-':
   775     if dest == '-':
   798         if kind == 'files':
   776         if kind == 'files':
   799             raise util.Abort(_('cannot archive plain files to stdout'))
   777             raise util.Abort(_('cannot archive plain files to stdout'))
   901     %s   basename of file being printed
   879     %s   basename of file being printed
   902     %d   dirname of file being printed, or '.' if in repo root
   880     %d   dirname of file being printed, or '.' if in repo root
   903     %p   root-relative path name of file being printed
   881     %p   root-relative path name of file being printed
   904     """
   882     """
   905     ctx = repo.changectx(opts['rev'] or "-1")
   883     ctx = repo.changectx(opts['rev'] or "-1")
   906     for src, abs, rel, exact in walk(repo, (file1,) + pats, opts, ctx.node()):
   884     for src, abs, rel, exact in cmdutil.walk(repo, (file1,) + pats, opts,
       
   885                                              ctx.node()):
   907         fp = cmdutil.make_file(repo, opts['output'], ctx.node(), pathname=abs)
   886         fp = cmdutil.make_file(repo, opts['output'], ctx.node(), pathname=abs)
   908         fp.write(ctx.filectx(abs).data())
   887         fp.write(ctx.filectx(abs).data())
   909 
   888 
   910 def clone(ui, source, dest=None, **opts):
   889 def clone(ui, source, dest=None, **opts):
   911     """make a copy of an existing repository
   890     """make a copy of an existing repository
   965     """
   944     """
   966     message = logmessage(opts)
   945     message = logmessage(opts)
   967 
   946 
   968     if opts['addremove']:
   947     if opts['addremove']:
   969         addremove_lock(ui, repo, pats, opts)
   948         addremove_lock(ui, repo, pats, opts)
   970     fns, match, anypats = matchpats(repo, pats, opts)
   949     fns, match, anypats = cmdutil.matchpats(repo, pats, opts)
   971     if pats:
   950     if pats:
   972         modified, added, removed = repo.status(files=fns, match=match)[:3]
   951         modified, added, removed = repo.status(files=fns, match=match)[:3]
   973         files = modified + added + removed
   952         files = modified + added + removed
   974     else:
   953     else:
   975         files = []
   954         files = []
  1122     else:
  1101     else:
  1123         tfn = targetpathfn
  1102         tfn = targetpathfn
  1124     copylist = []
  1103     copylist = []
  1125     for pat in pats:
  1104     for pat in pats:
  1126         srcs = []
  1105         srcs = []
  1127         for tag, abssrc, relsrc, exact in walk(repo, [pat], opts):
  1106         for tag, abssrc, relsrc, exact in cmdutil.walk(repo, [pat], opts):
  1128             origsrc = okaytocopy(abssrc, relsrc, exact)
  1107             origsrc = okaytocopy(abssrc, relsrc, exact)
  1129             if origsrc:
  1108             if origsrc:
  1130                 srcs.append((origsrc, abssrc, relsrc, exact))
  1109                 srcs.append((origsrc, abssrc, relsrc, exact))
  1131         if not srcs:
  1110         if not srcs:
  1132             continue
  1111             continue
  1339     else:
  1318     else:
  1340         ui.write(_("not renamed\n"))
  1319         ui.write(_("not renamed\n"))
  1341 
  1320 
  1342 def debugwalk(ui, repo, *pats, **opts):
  1321 def debugwalk(ui, repo, *pats, **opts):
  1343     """show how files match on given patterns"""
  1322     """show how files match on given patterns"""
  1344     items = list(walk(repo, pats, opts))
  1323     items = list(cmdutil.walk(repo, pats, opts))
  1345     if not items:
  1324     if not items:
  1346         return
  1325         return
  1347     fmt = '%%s  %%-%ds  %%-%ds  %%s' % (
  1326     fmt = '%%s  %%-%ds  %%-%ds  %%s' % (
  1348         max([len(abs) for (src, abs, rel, exact) in items]),
  1327         max([len(abs) for (src, abs, rel, exact) in items]),
  1349         max([len(rel) for (src, abs, rel, exact) in items]))
  1328         max([len(rel) for (src, abs, rel, exact) in items]))
  1368     it detects as binary. With -a, diff will generate a diff anyway,
  1347     it detects as binary. With -a, diff will generate a diff anyway,
  1369     probably with undesirable results.
  1348     probably with undesirable results.
  1370     """
  1349     """
  1371     node1, node2 = revpair(ui, repo, opts['rev'])
  1350     node1, node2 = revpair(ui, repo, opts['rev'])
  1372 
  1351 
  1373     fns, matchfn, anypats = matchpats(repo, pats, opts)
  1352     fns, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
  1374 
  1353 
  1375     patch.diff(repo, node1, node2, fns, match=matchfn,
  1354     patch.diff(repo, node1, node2, fns, match=matchfn,
  1376                opts=ui.diffopts(opts))
  1355                opts=ui.diffopts(opts))
  1377 
  1356 
  1378 def export(ui, repo, *changesets, **opts):
  1357 def export(ui, repo, *changesets, **opts):
  1421     This command is now deprecated and will be removed in a future
  1400     This command is now deprecated and will be removed in a future
  1422     release. Please use revert instead.
  1401     release. Please use revert instead.
  1423     """
  1402     """
  1424     ui.warn(_("(the forget command is deprecated; use revert instead)\n"))
  1403     ui.warn(_("(the forget command is deprecated; use revert instead)\n"))
  1425     forget = []
  1404     forget = []
  1426     for src, abs, rel, exact in walk(repo, pats, opts):
  1405     for src, abs, rel, exact in cmdutil.walk(repo, pats, opts):
  1427         if repo.dirstate.state(abs) == 'a':
  1406         if repo.dirstate.state(abs) == 'a':
  1428             forget.append(abs)
  1407             forget.append(abs)
  1429             if ui.verbose or not exact:
  1408             if ui.verbose or not exact:
  1430                 ui.status(_('forgetting %s\n') % ((pats and rel) or abs))
  1409                 ui.status(_('forgetting %s\n') % ((pats and rel) or abs))
  1431     repo.forget(forget)
  1410     repo.forget(forget)
  1845     if rev:
  1824     if rev:
  1846         node = repo.lookup(rev)
  1825         node = repo.lookup(rev)
  1847     else:
  1826     else:
  1848         node = None
  1827         node = None
  1849 
  1828 
  1850     for src, abs, rel, exact in walk(repo, pats, opts, node=node,
  1829     for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, node=node,
  1851                                      head='(?:.*/|)'):
  1830                                              head='(?:.*/|)'):
  1852         if not node and repo.dirstate.state(abs) == '?':
  1831         if not node and repo.dirstate.state(abs) == '?':
  1853             continue
  1832             continue
  1854         if opts['fullpath']:
  1833         if opts['fullpath']:
  1855             ui.write(os.path.join(repo.root, abs), end)
  1834             ui.write(os.path.join(repo.root, abs), end)
  1856         else:
  1835         else:
  2242     remove them, use the -f/--force option.
  2221     remove them, use the -f/--force option.
  2243     """
  2222     """
  2244     names = []
  2223     names = []
  2245     if not opts['after'] and not pats:
  2224     if not opts['after'] and not pats:
  2246         raise util.Abort(_('no files specified'))
  2225         raise util.Abort(_('no files specified'))
  2247     files, matchfn, anypats = matchpats(repo, pats, opts)
  2226     files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
  2248     exact = dict.fromkeys(files)
  2227     exact = dict.fromkeys(files)
  2249     mardu = map(dict.fromkeys, repo.status(files=files, match=matchfn))[:5]
  2228     mardu = map(dict.fromkeys, repo.status(files=files, match=matchfn))[:5]
  2250     modified, added, removed, deleted, unknown = mardu
  2229     modified, added, removed, deleted, unknown = mardu
  2251     remove, forget = [], []
  2230     remove, forget = [], []
  2252     for src, abs, rel, exact in walk(repo, pats, opts):
  2231     for src, abs, rel, exact in cmdutil.walk(repo, pats, opts):
  2253         reason = None
  2232         reason = None
  2254         if abs not in deleted and opts['after']:
  2233         if abs not in deleted and opts['after']:
  2255             reason = _('is still present')
  2234             reason = _('is still present')
  2256         elif abs in modified and not opts['force']:
  2235         elif abs in modified and not opts['force']:
  2257             reason = _('is modified (use -f to force removal)')
  2236             reason = _('is modified (use -f to force removal)')
  2354     names = {}
  2333     names = {}
  2355     target_only = {}
  2334     target_only = {}
  2356 
  2335 
  2357     # walk dirstate.
  2336     # walk dirstate.
  2358 
  2337 
  2359     for src, abs, rel, exact in walk(repo, pats, opts, badmatch=mf.has_key):
  2338     for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
       
  2339                                              badmatch=mf.has_key):
  2360         names[abs] = (rel, exact)
  2340         names[abs] = (rel, exact)
  2361         if src == 'b':
  2341         if src == 'b':
  2362             target_only[abs] = True
  2342             target_only[abs] = True
  2363 
  2343 
  2364     # walk target manifest.
  2344     # walk target manifest.
  2365 
  2345 
  2366     for src, abs, rel, exact in walk(repo, pats, opts, node=node,
  2346     for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, node=node,
  2367                                      badmatch=names.has_key):
  2347                                              badmatch=names.has_key):
  2368         if abs in names: continue
  2348         if abs in names: continue
  2369         names[abs] = (rel, exact)
  2349         names[abs] = (rel, exact)
  2370         target_only[abs] = True
  2350         target_only[abs] = True
  2371 
  2351 
  2372     changes = repo.status(match=names.has_key, wlock=wlock)[:5]
  2352     changes = repo.status(match=names.has_key, wlock=wlock)[:5]
  2574       = the previous added file was copied from here
  2554       = the previous added file was copied from here
  2575     """
  2555     """
  2576 
  2556 
  2577     all = opts['all']
  2557     all = opts['all']
  2578     
  2558     
  2579     files, matchfn, anypats = matchpats(repo, pats, opts)
  2559     files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
  2580     cwd = (pats and repo.getcwd()) or ''
  2560     cwd = (pats and repo.getcwd()) or ''
  2581     modified, added, removed, deleted, unknown, ignored, clean = [
  2561     modified, added, removed, deleted, unknown, ignored, clean = [
  2582         [util.pathto(cwd, x) for x in n]
  2562         [util.pathto(cwd, x) for x in n]
  2583         for n in repo.status(files=files, match=matchfn,
  2563         for n in repo.status(files=files, match=matchfn,
  2584                              list_ignored=all or opts['ignored'],
  2564                              list_ignored=all or opts['ignored'],