# HG changeset patch # User Robin Farine # Date 1130369050 25200 # Node ID 407bd229f00399aedf542aebff107e60947f35d5 # Parent f4250806dbeb5dbf8761accd7b508a16bc5add56 [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". diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -788,6 +788,7 @@ def docopy(ui, repo, pats, opts): pats = list(pats) dest = pats.pop() sources = [] + dir2dir = not opts['parents'] and len(pats) == 1 and os.path.isdir(pats[0]) def okaytocopy(abs, rel, exact): reasons = {'?': _('is not managed'), @@ -810,7 +811,8 @@ def docopy(ui, repo, pats, opts): if os.path.exists(reldest): destisfile = not os.path.isdir(reldest) else: - destisfile = len(sources) == 1 or repo.dirstate.state(absdest) != '?' + destisfile = not dir2dir and (len(sources) == 1 + or repo.dirstate.state(absdest) != '?') if destisfile: if opts['parents']: @@ -818,12 +820,23 @@ def docopy(ui, repo, pats, opts): elif len(sources) > 1: raise util.Abort(_('with multiple sources, destination must be a ' 'directory')) + srcpfxlen = 0 + if dir2dir: + srcpfx = util.pathto(cwd, util.canonpath(repo.root, cwd, pats[0])) + if os.path.exists(reldest): + srcpfx = os.path.split(srcpfx)[0] + if srcpfx: + srcpfx += os.sep + srcpfxlen = len(srcpfx) + errs, copied = 0, [] for abs, rel, exact in sources: if opts['parents']: mydest = os.path.join(dest, rel) elif destisfile: mydest = reldest + elif dir2dir: + mydest = os.path.join(dest, rel[srcpfxlen:]) else: mydest = os.path.join(dest, os.path.basename(rel)) myabsdest = util.canonpath(repo.root, cwd, mydest) @@ -834,7 +847,7 @@ def docopy(ui, repo, pats, opts): mydestdir = os.path.dirname(myreldest) or '.' if not opts['after']: try: - if opts['parents']: os.makedirs(mydestdir) + if opts['parents'] or dir2dir: os.makedirs(mydestdir) elif not destisfile: os.mkdir(mydestdir) except OSError, inst: if inst.errno != errno.EEXIST: raise