Mercurial > hg
changeset 1822:64df4220b349
copy/rename to a removed destination file
When the destination of a copy or rename operation has been
marked for removal, we need to restore it before we overwrite
it with the new content. This also handles the case of
idempotent renames, i.e.
hg rename "a" "b"
hg rename "b" "a"
author | Robin Farine <robin.farine@terminus.org> |
---|---|
date | Tue, 28 Feb 2006 23:47:40 -0800 |
parents | 3e2a2f230296 |
children | adef8661c8f9 |
files | mercurial/commands.py tests/test-rename tests/test-rename.out |
diffstat | 3 files changed, 42 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/commands.py Wed Mar 01 01:45:05 2006 +0100 +++ b/mercurial/commands.py Tue Feb 28 23:47:40 2006 -0800 @@ -825,7 +825,8 @@ except ValueError, inst: raise util.Abort(str(inst)) -def docopy(ui, repo, pats, opts): +def docopy(ui, repo, pats, opts, wlock): + # called with the repo lock held cwd = repo.getcwd() errors = 0 copied = [] @@ -871,8 +872,16 @@ if not os.path.isdir(targetdir): os.makedirs(targetdir) try: - shutil.copyfile(relsrc, reltarget) - shutil.copymode(relsrc, reltarget) + restore = repo.dirstate.state(abstarget) == 'r' + if restore: + repo.undelete([abstarget], wlock) + try: + shutil.copyfile(relsrc, reltarget) + shutil.copymode(relsrc, reltarget) + restore = False + finally: + if restore: + repo.remove([abstarget], wlock) except shutil.Error, inst: raise util.Abort(str(inst)) except IOError, inst: @@ -886,7 +895,8 @@ if ui.verbose or not exact: ui.status(_('copying %s to %s\n') % (relsrc, reltarget)) targets[abstarget] = abssrc - repo.copy(origsrc, abstarget) + if abstarget != origsrc: + repo.copy(origsrc, abstarget, wlock) copied.append((abssrc, relsrc, exact)) def targetpathfn(pat, dest, srcs): @@ -994,7 +1004,12 @@ should properly record copied files, this information is not yet fully used by merge, nor fully reported by log. """ - errs, copied = docopy(ui, repo, pats, opts) + try: + wlock = repo.wlock(0) + errs, copied = docopy(ui, repo, pats, opts, wlock) + except lock.LockHeld, inst: + ui.warn(_("repository lock held by %s\n") % inst.args[0]) + errs = 1 return errs def debugancestor(ui, index, rev1, rev2): @@ -1953,13 +1968,18 @@ should properly record rename files, this information is not yet fully used by merge, nor fully reported by log. """ - errs, copied = docopy(ui, repo, pats, opts) - names = [] - for abs, rel, exact in copied: - if ui.verbose or not exact: - ui.status(_('removing %s\n') % rel) - names.append(abs) - repo.remove(names, unlink=True) + try: + wlock = repo.wlock(0) + errs, copied = docopy(ui, repo, pats, opts, wlock) + names = [] + for abs, rel, exact in copied: + if ui.verbose or not exact: + ui.status(_('removing %s\n') % rel) + names.append(abs) + repo.remove(names, True, wlock) + except lock.LockHeld, inst: + ui.warn(_("repository lock held by %s\n") % inst.args[0]) + errs = 1 return errs def revert(ui, repo, *pats, **opts):
--- a/tests/test-rename Wed Mar 01 01:45:05 2006 +0100 +++ b/tests/test-rename Tue Feb 28 23:47:40 2006 -0800 @@ -171,3 +171,11 @@ hg rename --after d1/bb d1/bc hg status hg update -C + +echo "# idempotent renames (d1/b -> d1/bb followed by d1/bb -> d1/b)" +hg rename d1/b d1/bb +echo "some stuff added to d1/bb" >> d1/bb +hg rename d1/bb d1/b +hg status +hg debugstate | grep copy +hg update -C