comparison mercurial/commands.py @ 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 a81f99dfaa2a
children adef8661c8f9
comparison
equal deleted inserted replaced
1815:3e2a2f230296 1822:64df4220b349
823 try: 823 try:
824 repo.commit(files, message, opts['user'], opts['date'], match) 824 repo.commit(files, message, opts['user'], opts['date'], match)
825 except ValueError, inst: 825 except ValueError, inst:
826 raise util.Abort(str(inst)) 826 raise util.Abort(str(inst))
827 827
828 def docopy(ui, repo, pats, opts): 828 def docopy(ui, repo, pats, opts, wlock):
829 # called with the repo lock held
829 cwd = repo.getcwd() 830 cwd = repo.getcwd()
830 errors = 0 831 errors = 0
831 copied = [] 832 copied = []
832 targets = {} 833 targets = {}
833 834
869 else: 870 else:
870 targetdir = os.path.dirname(reltarget) or '.' 871 targetdir = os.path.dirname(reltarget) or '.'
871 if not os.path.isdir(targetdir): 872 if not os.path.isdir(targetdir):
872 os.makedirs(targetdir) 873 os.makedirs(targetdir)
873 try: 874 try:
874 shutil.copyfile(relsrc, reltarget) 875 restore = repo.dirstate.state(abstarget) == 'r'
875 shutil.copymode(relsrc, reltarget) 876 if restore:
877 repo.undelete([abstarget], wlock)
878 try:
879 shutil.copyfile(relsrc, reltarget)
880 shutil.copymode(relsrc, reltarget)
881 restore = False
882 finally:
883 if restore:
884 repo.remove([abstarget], wlock)
876 except shutil.Error, inst: 885 except shutil.Error, inst:
877 raise util.Abort(str(inst)) 886 raise util.Abort(str(inst))
878 except IOError, inst: 887 except IOError, inst:
879 if inst.errno == errno.ENOENT: 888 if inst.errno == errno.ENOENT:
880 ui.warn(_('%s: deleted in working copy\n') % relsrc) 889 ui.warn(_('%s: deleted in working copy\n') % relsrc)
884 errors += 1 893 errors += 1
885 return 894 return
886 if ui.verbose or not exact: 895 if ui.verbose or not exact:
887 ui.status(_('copying %s to %s\n') % (relsrc, reltarget)) 896 ui.status(_('copying %s to %s\n') % (relsrc, reltarget))
888 targets[abstarget] = abssrc 897 targets[abstarget] = abssrc
889 repo.copy(origsrc, abstarget) 898 if abstarget != origsrc:
899 repo.copy(origsrc, abstarget, wlock)
890 copied.append((abssrc, relsrc, exact)) 900 copied.append((abssrc, relsrc, exact))
891 901
892 def targetpathfn(pat, dest, srcs): 902 def targetpathfn(pat, dest, srcs):
893 if os.path.isdir(pat): 903 if os.path.isdir(pat):
894 abspfx = util.canonpath(repo.root, cwd, pat) 904 abspfx = util.canonpath(repo.root, cwd, pat)
992 1002
993 NOTE: This command should be treated as experimental. While it 1003 NOTE: This command should be treated as experimental. While it
994 should properly record copied files, this information is not yet 1004 should properly record copied files, this information is not yet
995 fully used by merge, nor fully reported by log. 1005 fully used by merge, nor fully reported by log.
996 """ 1006 """
997 errs, copied = docopy(ui, repo, pats, opts) 1007 try:
1008 wlock = repo.wlock(0)
1009 errs, copied = docopy(ui, repo, pats, opts, wlock)
1010 except lock.LockHeld, inst:
1011 ui.warn(_("repository lock held by %s\n") % inst.args[0])
1012 errs = 1
998 return errs 1013 return errs
999 1014
1000 def debugancestor(ui, index, rev1, rev2): 1015 def debugancestor(ui, index, rev1, rev2):
1001 """find the ancestor revision of two revisions in a given index""" 1016 """find the ancestor revision of two revisions in a given index"""
1002 r = revlog.revlog(util.opener(os.getcwd()), index, "") 1017 r = revlog.revlog(util.opener(os.getcwd()), index, "")
1951 1966
1952 NOTE: This command should be treated as experimental. While it 1967 NOTE: This command should be treated as experimental. While it
1953 should properly record rename files, this information is not yet 1968 should properly record rename files, this information is not yet
1954 fully used by merge, nor fully reported by log. 1969 fully used by merge, nor fully reported by log.
1955 """ 1970 """
1956 errs, copied = docopy(ui, repo, pats, opts) 1971 try:
1957 names = [] 1972 wlock = repo.wlock(0)
1958 for abs, rel, exact in copied: 1973 errs, copied = docopy(ui, repo, pats, opts, wlock)
1959 if ui.verbose or not exact: 1974 names = []
1960 ui.status(_('removing %s\n') % rel) 1975 for abs, rel, exact in copied:
1961 names.append(abs) 1976 if ui.verbose or not exact:
1962 repo.remove(names, unlink=True) 1977 ui.status(_('removing %s\n') % rel)
1978 names.append(abs)
1979 repo.remove(names, True, wlock)
1980 except lock.LockHeld, inst:
1981 ui.warn(_("repository lock held by %s\n") % inst.args[0])
1982 errs = 1
1963 return errs 1983 return errs
1964 1984
1965 def revert(ui, repo, *pats, **opts): 1985 def revert(ui, repo, *pats, **opts):
1966 """revert modified files or dirs back to their unmodified states 1986 """revert modified files or dirs back to their unmodified states
1967 1987