Mercurial > public > mercurial-scm > hg
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 |