# HG changeset patch # User Matt Mackall # Date 1197014473 21600 # Node ID 784eadabd9854fafedf74de343ec9f360acb630e # Parent e9bae5c80ab47449bac62ac7c8f7dffd6a737587 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 diff -r e9bae5c80ab4 -r 784eadabd985 mercurial/cmdutil.py --- 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: diff -r e9bae5c80ab4 -r 784eadabd985 tests/test-rename-after-merge --- 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 diff -r e9bae5c80ab4 -r 784eadabd985 tests/test-rename-after-merge.out --- 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