changeset 5608:784eadabd985

copy: simplify inner copy - save dirstate lookup and exists check - do all fs work inside a single dryrun clause - move unlinking into inner copy section - move target dir creation - eliminate undelete mess - fix a bug on mv a -> b -> a after merge
author Matt Mackall <mpm@selenic.com>
date Fri, 07 Dec 2007 02:01:13 -0600
parents e9bae5c80ab4
children a783d3627144
files mercurial/cmdutil.py tests/test-rename-after-merge tests/test-rename-after-merge.out
diffstat 3 files changed, 17 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/cmdutil.py	Fri Dec 07 02:01:10 2007 -0600
+++ b/mercurial/cmdutil.py	Fri Dec 07 02:01:13 2007 -0600
@@ -321,6 +321,7 @@
         reltarget = repo.pathto(abstarget, cwd)
         target = repo.wjoin(abstarget)
         src = repo.wjoin(abssrc)
+        state = repo.dirstate[abstarget]
 
         # check for collisions
         prevsrc = targets.get(abstarget)
@@ -331,33 +332,24 @@
             return
 
         # check for overwrites
-        if (not after and os.path.exists(target) or
-            after and repo.dirstate[abstarget] in 'mn'):
+        exists = os.path.exists(target)
+        if (not after and exists or after and state in 'mn'):
             if not opts['force']:
                 ui.warn(_('%s: not overwriting - file exists\n') %
                         reltarget)
                 return
-            if not after and not dryrun:
-                os.unlink(target)
 
         if after:
-            if not os.path.exists(target):
+            if not exists:
                 return
-        else:
-            targetdir = os.path.dirname(target) or '.'
-            if not os.path.isdir(targetdir) and not dryrun:
-                os.makedirs(targetdir)
+        elif not dryrun:
             try:
-                restore = repo.dirstate[abstarget] == 'r'
-                if restore and not dryrun:
-                    repo.undelete([abstarget])
-                try:
-                    if not dryrun:
-                        util.copyfile(src, target)
-                    restore = False
-                finally:
-                    if restore:
-                        repo.remove([abstarget])
+                if exists:
+                    os.unlink(target)
+                targetdir = os.path.dirname(target) or '.'
+                if not os.path.isdir(targetdir):
+                    os.makedirs(targetdir)
+                util.copyfile(src, target)
             except IOError, inst:
                 if inst.errno == errno.ENOENT:
                     ui.warn(_('%s: deleted in working copy\n') % relsrc)
@@ -368,14 +360,14 @@
 
         if ui.verbose or not exact:
             ui.status(_('copying %s to %s\n') % (relsrc, reltarget))
+
         targets[abstarget] = abssrc
 
         # fix up dirstate
         origsrc = repo.dirstate.copied(abssrc) or abssrc
         if abstarget == origsrc: # copying back a copy?
-            if repo.dirstate[abstarget] not in 'mn':
-                if not dryrun:
-                    repo.add([abstarget])
+            if state not in 'mn' and not dryrun:
+                repo.dirstate.normallookup(abstarget)
         else:
             if repo.dirstate[origsrc] == 'a':
                 if not ui.quiet:
--- a/tests/test-rename-after-merge	Fri Dec 07 02:01:10 2007 -0600
+++ b/tests/test-rename-after-merge	Fri Dec 07 02:01:13 2007 -0600
@@ -24,6 +24,7 @@
 echo % merge repositories
 hg pull ../t2
 hg merge
+hg st
 
 echo % rename b as c
 hg mv b c
--- a/tests/test-rename-after-merge.out	Fri Dec 07 02:01:10 2007 -0600
+++ b/tests/test-rename-after-merge.out	Fri Dec 07 02:01:13 2007 -0600
@@ -14,7 +14,9 @@
 (run 'hg heads' to see heads, 'hg merge' to merge)
 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 (branch merge, don't forget to commit)
+M b
 % rename b as c
 A c
 R b
 % rename back c as b
+M b