diff mercurial/cmdutil.py @ 14259:df9ccd39828c

patch: move updatedir() from cmdutil into patch Also, create an artificial wdutil.py to avoid import cycles between patch.py and cmdutil.py.
author Patrick Mezard <pmezard@gmail.com>
date Sun, 08 May 2011 17:48:30 +0200
parents d035ede73434
children 66257848c154
line wrap: on
line diff
--- a/mercurial/cmdutil.py	Sun May 08 17:48:29 2011 +0200
+++ b/mercurial/cmdutil.py	Sun May 08 17:48:30 2011 +0200
@@ -8,10 +8,17 @@
 from node import hex, nullid, nullrev, short
 from i18n import _
 import os, sys, errno, re, glob, tempfile
-import util, scmutil, templater, patch, error, templatekw
+import util, scmutil, templater, patch, error, templatekw, wdutil
 import match as matchmod
 import similar, revset, subrepo
 
+expandpats = wdutil.expandpats
+match = wdutil.match
+matchall = wdutil.matchall
+matchfiles = wdutil.matchfiles
+addremove = wdutil.addremove
+dirstatecopy = wdutil.dirstatecopy
+
 revrangesep = ':'
 
 def parsealiases(cmd):
@@ -243,157 +250,6 @@
                               pathname),
                 mode)
 
-def expandpats(pats):
-    if not util.expandglobs:
-        return list(pats)
-    ret = []
-    for p in pats:
-        kind, name = matchmod._patsplit(p, None)
-        if kind is None:
-            try:
-                globbed = glob.glob(name)
-            except re.error:
-                globbed = [name]
-            if globbed:
-                ret.extend(globbed)
-                continue
-        ret.append(p)
-    return ret
-
-def match(repo, pats=[], opts={}, globbed=False, default='relpath'):
-    if pats == ("",):
-        pats = []
-    if not globbed and default == 'relpath':
-        pats = expandpats(pats or [])
-    m = matchmod.match(repo.root, repo.getcwd(), pats,
-                       opts.get('include'), opts.get('exclude'), default,
-                       auditor=repo.auditor)
-    def badfn(f, msg):
-        repo.ui.warn("%s: %s\n" % (m.rel(f), msg))
-    m.bad = badfn
-    return m
-
-def matchall(repo):
-    return matchmod.always(repo.root, repo.getcwd())
-
-def matchfiles(repo, files):
-    return matchmod.exact(repo.root, repo.getcwd(), files)
-
-def addremove(repo, pats=[], opts={}, dry_run=None, similarity=None):
-    if dry_run is None:
-        dry_run = opts.get('dry_run')
-    if similarity is None:
-        similarity = float(opts.get('similarity') or 0)
-    # we'd use status here, except handling of symlinks and ignore is tricky
-    added, unknown, deleted, removed = [], [], [], []
-    audit_path = scmutil.pathauditor(repo.root)
-    m = match(repo, pats, opts)
-    for abs in repo.walk(m):
-        target = repo.wjoin(abs)
-        good = True
-        try:
-            audit_path(abs)
-        except (OSError, util.Abort):
-            good = False
-        rel = m.rel(abs)
-        exact = m.exact(abs)
-        if good and abs not in repo.dirstate:
-            unknown.append(abs)
-            if repo.ui.verbose or not exact:
-                repo.ui.status(_('adding %s\n') % ((pats and rel) or abs))
-        elif repo.dirstate[abs] != 'r' and (not good or not os.path.lexists(target)
-            or (os.path.isdir(target) and not os.path.islink(target))):
-            deleted.append(abs)
-            if repo.ui.verbose or not exact:
-                repo.ui.status(_('removing %s\n') % ((pats and rel) or abs))
-        # for finding renames
-        elif repo.dirstate[abs] == 'r':
-            removed.append(abs)
-        elif repo.dirstate[abs] == 'a':
-            added.append(abs)
-    copies = {}
-    if similarity > 0:
-        for old, new, score in similar.findrenames(repo,
-                added + unknown, removed + deleted, similarity):
-            if repo.ui.verbose or not m.exact(old) or not m.exact(new):
-                repo.ui.status(_('recording removal of %s as rename to %s '
-                                 '(%d%% similar)\n') %
-                               (m.rel(old), m.rel(new), score * 100))
-            copies[new] = old
-
-    if not dry_run:
-        wctx = repo[None]
-        wlock = repo.wlock()
-        try:
-            wctx.remove(deleted)
-            wctx.add(unknown)
-            for new, old in copies.iteritems():
-                wctx.copy(old, new)
-        finally:
-            wlock.release()
-
-def updatedir(ui, repo, patches, similarity=0):
-    '''Update dirstate after patch application according to metadata'''
-    if not patches:
-        return []
-    copies = []
-    removes = set()
-    cfiles = patches.keys()
-    cwd = repo.getcwd()
-    if cwd:
-        cfiles = [util.pathto(repo.root, cwd, f) for f in patches.keys()]
-    for f in patches:
-        gp = patches[f]
-        if not gp:
-            continue
-        if gp.op == 'RENAME':
-            copies.append((gp.oldpath, gp.path))
-            removes.add(gp.oldpath)
-        elif gp.op == 'COPY':
-            copies.append((gp.oldpath, gp.path))
-        elif gp.op == 'DELETE':
-            removes.add(gp.path)
-
-    wctx = repo[None]
-    for src, dst in copies:
-        dirstatecopy(ui, repo, wctx, src, dst, cwd=cwd)
-    if (not similarity) and removes:
-        wctx.remove(sorted(removes), True)
-
-    for f in patches:
-        gp = patches[f]
-        if gp and gp.mode:
-            islink, isexec = gp.mode
-            dst = repo.wjoin(gp.path)
-            # patch won't create empty files
-            if gp.op == 'ADD' and not os.path.lexists(dst):
-                flags = (isexec and 'x' or '') + (islink and 'l' or '')
-                repo.wwrite(gp.path, '', flags)
-            util.setflags(dst, islink, isexec)
-    addremove(repo, cfiles, similarity=similarity)
-    files = patches.keys()
-    files.extend([r for r in removes if r not in files])
-    return sorted(files)
-
-def dirstatecopy(ui, repo, wctx, src, dst, dryrun=False, cwd=None):
-    """Update the dirstate to reflect the intent of copying src to dst. For
-    different reasons it might not end with dst being marked as copied from src.
-    """
-    origsrc = repo.dirstate.copied(src) or src
-    if dst == origsrc: # copying back a copy?
-        if repo.dirstate[dst] not in 'mn' and not dryrun:
-            repo.dirstate.normallookup(dst)
-    else:
-        if repo.dirstate[origsrc] == 'a' and origsrc == src:
-            if not ui.quiet:
-                ui.warn(_("%s has not been committed yet, so no copy "
-                          "data will be stored for %s.\n")
-                        % (repo.pathto(origsrc, cwd), repo.pathto(dst, cwd)))
-            if repo.dirstate[dst] in '?r' and not dryrun:
-                wctx.add([dst])
-        elif not dryrun:
-            wctx.copy(origsrc, dst)
-
 def copy(ui, repo, pats, opts, rename=False):
     # called with the repo lock held
     #