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)) |