diff mercurial/patch.py @ 2933:439fd013360d

Move import's working dir update code into patch.updatedir
author Brendan Cully <brendan@kublai.com>
date Wed, 16 Aug 2006 19:46:18 -0700
parents 773c5b82d052
children 2f190e998eb3
line wrap: on
line diff
--- a/mercurial/patch.py
+++ b/mercurial/patch.py
@@ -11,6 +11,28 @@ from node import *
 demandload(globals(), "cmdutil mdiff util")
 demandload(globals(), "cStringIO email.Parser os re shutil sys tempfile")
 
+# helper functions
+
+def copyfile(src, dst, basedir=None):
+    if not basedir:
+        basedir = os.getcwd()
+
+    abssrc, absdst = [os.path.join(basedir, n) for n in (src, dst)]
+    if os.path.exists(absdst):
+        raise util.Abort(_("cannot create %s: destination already exists") %
+                         dst)
+
+    targetdir = os.path.dirname(absdst)
+    if not os.path.isdir(targetdir):
+        os.makedirs(targetdir)
+    try:
+        shutil.copyfile(abssrc, absdst)
+        shutil.copymode(abssrc, absdst)
+    except shutil.Error, inst:
+        raise util.Abort(str(inst))
+
+# public functions
+
 def extract(ui, fileobj):
     '''extract patch from data read from fileobj.
 
@@ -174,21 +196,7 @@ def dogitpatch(patchname, gitpatches):
             if not p.copymod:
                 continue
 
-            if os.path.exists(p.path):
-                raise util.Abort(_("cannot create %s: destination already exists") %
-                            p.path)
-
-            (src, dst) = [os.path.join(os.getcwd(), n)
-                          for n in (p.oldpath, p.path)]
-
-            targetdir = os.path.dirname(dst)
-            if not os.path.isdir(targetdir):
-                os.makedirs(targetdir)
-            try:
-                shutil.copyfile(src, dst)
-                shutil.copymode(src, dst)
-            except shutil.Error, inst:
-                raise util.Abort(str(inst))
+            copyfile(p.oldpath, p.path)
 
             # rewrite patch hunk
             while pfline < p.lineno:
@@ -281,6 +289,45 @@ def diffopts(ui, opts={}):
         ignoreblanklines=(opts.get('ignore_blank_lines') or
                           ui.configbool('diff', 'ignoreblanklines', None)))
 
+def updatedir(ui, repo, patches, wlock=None):
+    '''Update dirstate after patch application according to metadata'''
+    if not patches:
+        return
+    copies = []
+    removes = []
+    cfiles = patches.keys()
+    copts = {'after': False, 'force': False}
+    cwd = repo.getcwd()
+    if cwd:
+        cfiles = [util.pathto(cwd, f) for f in patches.keys()]
+    for f in patches:
+        ctype, gp = patches[f]
+        if ctype == 'RENAME':
+            copies.append((gp.oldpath, gp.path, gp.copymod))
+            removes.append(gp.oldpath)
+        elif ctype == 'COPY':
+            copies.append((gp.oldpath, gp.path, gp.copymod))
+        elif ctype == 'DELETE':
+            removes.append(gp.path)
+    for src, dst, after in copies:
+        if not after:
+            copyfile(src, dst, repo.root)
+        repo.copy(src, dst, wlock=wlock)
+    if removes:
+        repo.remove(removes, True, wlock=wlock)
+    for f in patches:
+        ctype, gp = patches[f]
+        if gp and gp.mode:
+            x = gp.mode & 0100 != 0
+            dst = os.path.join(repo.root, gp.path)
+            util.set_exec(dst, x)
+    cmdutil.addremove(repo, cfiles, wlock=wlock)
+    files = patches.keys()
+    files.extend([r for r in removes if r not in files])
+    files.sort()
+
+    return files
+
 def diff(repo, node1=None, node2=None, files=None, match=util.always,
          fp=None, changes=None, opts=None):
     '''print diff of changes to files between two nodes, or node and