mercurial/commands.py
changeset 2029 d436b21b20dc
parent 2022 a59da8cc35e4
child 2033 e3280d350792
child 2036 c9226bcc288d
equal deleted inserted replaced
2028:1f1fc418a96c 2029:d436b21b20dc
    41         opts['exclude'] = [os.path.join(cwd, x) for x in opts['exclude']]
    41         opts['exclude'] = [os.path.join(cwd, x) for x in opts['exclude']]
    42         cwd = ''
    42         cwd = ''
    43     return util.cmdmatcher(repo.root, cwd, pats or ['.'], opts.get('include'),
    43     return util.cmdmatcher(repo.root, cwd, pats or ['.'], opts.get('include'),
    44                            opts.get('exclude'), head)
    44                            opts.get('exclude'), head)
    45 
    45 
    46 def makewalk(repo, pats, opts, node=None, head=''):
    46 def makewalk(repo, pats, opts, node=None, head='', badmatch=None):
    47     files, matchfn, anypats = matchpats(repo, pats, opts, head)
    47     files, matchfn, anypats = matchpats(repo, pats, opts, head)
    48     exact = dict(zip(files, files))
    48     exact = dict(zip(files, files))
    49     def walk():
    49     def walk():
    50         for src, fn in repo.walk(node=node, files=files, match=matchfn):
    50         for src, fn in repo.walk(node=node, files=files, match=matchfn,
       
    51                                  badmatch=None):
    51             yield src, fn, util.pathto(repo.getcwd(), fn), fn in exact
    52             yield src, fn, util.pathto(repo.getcwd(), fn), fn in exact
    52     return files, matchfn, walk()
    53     return files, matchfn, walk()
    53 
    54 
    54 def walk(repo, pats, opts, node=None, head=''):
    55 def walk(repo, pats, opts, node=None, head='', badmatch=None):
    55     files, matchfn, results = makewalk(repo, pats, opts, node, head)
    56     files, matchfn, results = makewalk(repo, pats, opts, node, head, badmatch)
    56     for r in results:
    57     for r in results:
    57         yield r
    58         yield r
    58 
    59 
    59 def walkchangerevs(ui, repo, pats, opts):
    60 def walkchangerevs(ui, repo, pats, opts):
    60     '''Iterate over files and the revs they changed in.
    61     '''Iterate over files and the revs they changed in.
  2001     requested revision. Files that changed between either parent are
  2002     requested revision. Files that changed between either parent are
  2002     marked as changed for the next commit and a commit must be
  2003     marked as changed for the next commit and a commit must be
  2003     performed before any further updates are allowed.
  2004     performed before any further updates are allowed.
  2004     """
  2005     """
  2005     return update(ui, repo, node=node, merge=True, **opts)
  2006     return update(ui, repo, node=node, merge=True, **opts)
  2006     
  2007 
  2007 def outgoing(ui, repo, dest="default-push", **opts):
  2008 def outgoing(ui, repo, dest="default-push", **opts):
  2008     """show changesets not found in destination
  2009     """show changesets not found in destination
  2009 
  2010 
  2010     Show changesets not found in the specified destination repository or
  2011     Show changesets not found in the specified destination repository or
  2011     the default push location. These are the changesets that would be pushed
  2012     the default push location. These are the changesets that would be pushed
  2086             ui.status(_("not updating, since new heads added\n"))
  2087             ui.status(_("not updating, since new heads added\n"))
  2087     if modheads > 1:
  2088     if modheads > 1:
  2088         ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
  2089         ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
  2089     else:
  2090     else:
  2090         ui.status(_("(run 'hg update' to get a working copy)\n"))
  2091         ui.status(_("(run 'hg update' to get a working copy)\n"))
  2091     
  2092 
  2092 def pull(ui, repo, source="default", **opts):
  2093 def pull(ui, repo, source="default", **opts):
  2093     """pull changes from the specified source
  2094     """pull changes from the specified source
  2094 
  2095 
  2095     Pull changes from a remote repository to a local one.
  2096     Pull changes from a remote repository to a local one.
  2096 
  2097 
  2284 
  2285 
  2285     In its default mode, it reverts any uncommitted modifications made
  2286     In its default mode, it reverts any uncommitted modifications made
  2286     to the named files or directories.  This restores the contents of
  2287     to the named files or directories.  This restores the contents of
  2287     the affected files to an unmodified state.
  2288     the affected files to an unmodified state.
  2288 
  2289 
       
  2290     Modified files have backup copies saved before revert.  To disable
       
  2291     backups, use --no-backup.  To change the name of backup files, use
       
  2292     --backup to give a format string.
       
  2293 
  2289     Using the -r option, it reverts the given files or directories to
  2294     Using the -r option, it reverts the given files or directories to
  2290     their state as of an earlier revision.  This can be helpful to "roll
  2295     their state as of an earlier revision.  This can be helpful to "roll
  2291     back" some or all of a change that should not have been committed.
  2296     back" some or all of a change that should not have been committed.
  2292 
  2297 
  2293     Revert modifies the working directory.  It does not commit any
  2298     Revert modifies the working directory.  It does not commit any
  2298 
  2303 
  2299     If names are given, all files matching the names are reverted.
  2304     If names are given, all files matching the names are reverted.
  2300 
  2305 
  2301     If no arguments are given, all files in the repository are reverted.
  2306     If no arguments are given, all files in the repository are reverted.
  2302     """
  2307     """
  2303     node = opts['rev'] and repo.lookup(opts['rev']) or \
  2308     parent = repo.dirstate.parents()[0]
  2304            repo.dirstate.parents()[0]
  2309     node = opts['rev'] and repo.lookup(opts['rev']) or parent
  2305 
  2310     mf = repo.manifest.read(repo.changelog.read(node)[0])
  2306     files, choose, anypats = matchpats(repo, pats, opts)
  2311 
  2307     modified, added, removed, deleted, unknown = repo.changes(match=choose)
  2312     def backup(name, exact):
  2308     repo.forget(added)
  2313         bakname = make_filename(repo, repo.changelog,
  2309     repo.undelete(removed)
  2314                                 opts['backup_name'] or '%p.orig',
  2310 
  2315                                 node=parent, pathname=name)
  2311     return repo.update(node, False, True, choose, False)
  2316         if os.path.exists(name):
       
  2317             # if backup already exists and is same as backup we want
       
  2318             # to make, do nothing
       
  2319             if os.path.exists(bakname):
       
  2320                 if repo.wread(name) == repo.wread(bakname):
       
  2321                     return
       
  2322                 raise util.Abort(_('cannot save current version of %s - '
       
  2323                                    '%s exists and differs') %
       
  2324                                  (name, bakname))
       
  2325             ui.status(('saving current version of %s as %s\n') %
       
  2326                       (name, bakname))
       
  2327             shutil.copyfile(name, bakname)
       
  2328             shutil.copymode(name, bakname)
       
  2329 
       
  2330     wlock = repo.wlock()
       
  2331 
       
  2332     entries = []
       
  2333     names = {}
       
  2334     for src, abs, rel, exact in walk(repo, pats, opts, badmatch=mf.has_key):
       
  2335         names[abs] = True
       
  2336         entries.append((abs, rel, exact))
       
  2337 
       
  2338     changes = repo.changes(match=names.has_key, wlock=wlock)
       
  2339     modified, added, removed, deleted, unknown = map(dict.fromkeys, changes)
       
  2340 
       
  2341     revert = ([], _('reverting %s\n'))
       
  2342     add = ([], _('adding %s\n'))
       
  2343     remove = ([], _('removing %s\n'))
       
  2344     forget = ([], _('forgetting %s\n'))
       
  2345     undelete = ([], _('undeleting %s\n'))
       
  2346     update = {}
       
  2347 
       
  2348     disptable = (
       
  2349         # dispatch table:
       
  2350         #   file state
       
  2351         #   action if in target manifest
       
  2352         #   action if not in target manifest
       
  2353         #   make backup if in target manifest
       
  2354         #   make backup if not in target manifest
       
  2355         (modified, revert, remove, True, True),
       
  2356         (added, revert, forget, True, True),
       
  2357         (removed, undelete, None, False, False),
       
  2358         (deleted, revert, remove, False, False),
       
  2359         (unknown, add, None, True, False),
       
  2360         )
       
  2361 
       
  2362     for abs, rel, exact in entries:
       
  2363         def handle(xlist, dobackup):
       
  2364             xlist[0].append(abs)
       
  2365             if dobackup and not opts['no_backup']:
       
  2366                 backup(rel, exact)
       
  2367             if ui.verbose or not exact:
       
  2368                 ui.status(xlist[1] % rel)
       
  2369         for table, hitlist, misslist, backuphit, backupmiss in disptable:
       
  2370             if abs not in table: continue
       
  2371             # file has changed in dirstate
       
  2372             if abs in mf:
       
  2373                 handle(hitlist, backuphit)
       
  2374             elif misslist is not None:
       
  2375                 handle(misslist, backupmiss)
       
  2376             else:
       
  2377                 if exact: ui.warn(_('file not managed: %s\n' % rel))
       
  2378             break
       
  2379         else:
       
  2380             # file has not changed in dirstate
       
  2381             if node == parent:
       
  2382                 if exact: ui.warn(_('no changes needed to %s\n' % rel))
       
  2383                 continue
       
  2384             if abs not in mf:
       
  2385                 remove[0].append(abs)
       
  2386         update[abs] = True
       
  2387 
       
  2388     repo.dirstate.forget(forget[0])
       
  2389     r = repo.update(node, False, True, update.has_key, False, wlock=wlock)
       
  2390     repo.dirstate.update(add[0], 'a')
       
  2391     repo.dirstate.update(undelete[0], 'n')
       
  2392     repo.dirstate.update(remove[0], 'r')
       
  2393     return r
  2312 
  2394 
  2313 def root(ui, repo):
  2395 def root(ui, repo):
  2314     """print the root (top) of the current working dir
  2396     """print the root (top) of the current working dir
  2315 
  2397 
  2316     Print the root directory of the current repository.
  2398     Print the root directory of the current repository.
  2927           ('X', 'exclude', [], _('exclude names matching the given patterns'))],
  3009           ('X', 'exclude', [], _('exclude names matching the given patterns'))],
  2928          _('hg rename [OPTION]... SOURCE... DEST')),
  3010          _('hg rename [OPTION]... SOURCE... DEST')),
  2929     "^revert":
  3011     "^revert":
  2930         (revert,
  3012         (revert,
  2931          [('r', 'rev', '', _('revision to revert to')),
  3013          [('r', 'rev', '', _('revision to revert to')),
  2932           ('I', 'include', [], _('include names matching the given patterns')),
  3014           ('', 'backup-name', '', _('save backup with formatted name')),
  2933           ('X', 'exclude', [], _('exclude names matching the given patterns'))],
  3015           ('', 'no-backup', None, _('do not save backup copies of files')),
       
  3016           ('I', 'include', [], _('include names matching given patterns')),
       
  3017           ('X', 'exclude', [], _('exclude names matching given patterns'))],
  2934          _('hg revert [-r REV] [NAME]...')),
  3018          _('hg revert [-r REV] [NAME]...')),
  2935     "root": (root, [], _('hg root')),
  3019     "root": (root, [], _('hg root')),
  2936     "^serve":
  3020     "^serve":
  2937         (serve,
  3021         (serve,
  2938          [('A', 'accesslog', '', _('name of access log file to write to')),
  3022          [('A', 'accesslog', '', _('name of access log file to write to')),