comparison mercurial/commands.py @ 1455:407bd229f003

[PATCH] copy/rename a directory This patch adds support for 'hg copy dir1 dir2' or 'hg rename dir1 dir2'. When "dir2" exists, "dir1" is recursively copied (or moved) to "dir2/dir1". When "dir2" does not exists, "dir1" is copied to (renamed as) "dir2".
author Robin Farine <robin.farine@terminus.org>
date Wed, 26 Oct 2005 16:24:10 -0700
parents 6fbb13b7a59f
children 214f42f23a3b
comparison
equal deleted inserted replaced
1454:f4250806dbeb 1455:407bd229f003
786 elif len(pats) == 1: 786 elif len(pats) == 1:
787 raise util.Abort(_('no destination specified')) 787 raise util.Abort(_('no destination specified'))
788 pats = list(pats) 788 pats = list(pats)
789 dest = pats.pop() 789 dest = pats.pop()
790 sources = [] 790 sources = []
791 dir2dir = not opts['parents'] and len(pats) == 1 and os.path.isdir(pats[0])
791 792
792 def okaytocopy(abs, rel, exact): 793 def okaytocopy(abs, rel, exact):
793 reasons = {'?': _('is not managed'), 794 reasons = {'?': _('is not managed'),
794 'a': _('has been marked for add')} 795 'a': _('has been marked for add')}
795 reason = reasons.get(repo.dirstate.state(abs)) 796 reason = reasons.get(repo.dirstate.state(abs))
808 absdest = util.canonpath(repo.root, cwd, dest) 809 absdest = util.canonpath(repo.root, cwd, dest)
809 reldest = util.pathto(cwd, absdest) 810 reldest = util.pathto(cwd, absdest)
810 if os.path.exists(reldest): 811 if os.path.exists(reldest):
811 destisfile = not os.path.isdir(reldest) 812 destisfile = not os.path.isdir(reldest)
812 else: 813 else:
813 destisfile = len(sources) == 1 or repo.dirstate.state(absdest) != '?' 814 destisfile = not dir2dir and (len(sources) == 1
815 or repo.dirstate.state(absdest) != '?')
814 816
815 if destisfile: 817 if destisfile:
816 if opts['parents']: 818 if opts['parents']:
817 raise util.Abort(_('with --parents, destination must be a directory')) 819 raise util.Abort(_('with --parents, destination must be a directory'))
818 elif len(sources) > 1: 820 elif len(sources) > 1:
819 raise util.Abort(_('with multiple sources, destination must be a ' 821 raise util.Abort(_('with multiple sources, destination must be a '
820 'directory')) 822 'directory'))
823 srcpfxlen = 0
824 if dir2dir:
825 srcpfx = util.pathto(cwd, util.canonpath(repo.root, cwd, pats[0]))
826 if os.path.exists(reldest):
827 srcpfx = os.path.split(srcpfx)[0]
828 if srcpfx:
829 srcpfx += os.sep
830 srcpfxlen = len(srcpfx)
831
821 errs, copied = 0, [] 832 errs, copied = 0, []
822 for abs, rel, exact in sources: 833 for abs, rel, exact in sources:
823 if opts['parents']: 834 if opts['parents']:
824 mydest = os.path.join(dest, rel) 835 mydest = os.path.join(dest, rel)
825 elif destisfile: 836 elif destisfile:
826 mydest = reldest 837 mydest = reldest
838 elif dir2dir:
839 mydest = os.path.join(dest, rel[srcpfxlen:])
827 else: 840 else:
828 mydest = os.path.join(dest, os.path.basename(rel)) 841 mydest = os.path.join(dest, os.path.basename(rel))
829 myabsdest = util.canonpath(repo.root, cwd, mydest) 842 myabsdest = util.canonpath(repo.root, cwd, mydest)
830 myreldest = util.pathto(cwd, myabsdest) 843 myreldest = util.pathto(cwd, myabsdest)
831 if not opts['force'] and repo.dirstate.state(myabsdest) not in 'a?': 844 if not opts['force'] and repo.dirstate.state(myabsdest) not in 'a?':
832 ui.warn(_('%s: not overwriting - file already managed\n') % myreldest) 845 ui.warn(_('%s: not overwriting - file already managed\n') % myreldest)
833 continue 846 continue
834 mydestdir = os.path.dirname(myreldest) or '.' 847 mydestdir = os.path.dirname(myreldest) or '.'
835 if not opts['after']: 848 if not opts['after']:
836 try: 849 try:
837 if opts['parents']: os.makedirs(mydestdir) 850 if opts['parents'] or dir2dir: os.makedirs(mydestdir)
838 elif not destisfile: os.mkdir(mydestdir) 851 elif not destisfile: os.mkdir(mydestdir)
839 except OSError, inst: 852 except OSError, inst:
840 if inst.errno != errno.EEXIST: raise 853 if inst.errno != errno.EEXIST: raise
841 if ui.verbose or not exact: 854 if ui.verbose or not exact:
842 ui.status(_('copying %s to %s\n') % (rel, myreldest)) 855 ui.status(_('copying %s to %s\n') % (rel, myreldest))