Mercurial > hg > pyhgsh
comparison mercurial/commands.py @ 1512:53ad6ee6ede4
generalize copy/rename to handle more than one source directory
author | Robin Farine <robin.farine@terminus.org> |
---|---|
date | Tue, 08 Nov 2005 10:35:05 -0800 |
parents | cd8fadd8c689 |
children | 5c3b93b244aa |
comparison
equal
deleted
inserted
replaced
1511:a91bfbbe88d3 | 1512:53ad6ee6ede4 |
---|---|
785 repo.commit(files, message, opts['user'], opts['date'], match) | 785 repo.commit(files, message, opts['user'], opts['date'], match) |
786 except ValueError, inst: | 786 except ValueError, inst: |
787 raise util.Abort(str(inst)) | 787 raise util.Abort(str(inst)) |
788 | 788 |
789 def docopy(ui, repo, pats, opts): | 789 def docopy(ui, repo, pats, opts): |
790 if not pats: | 790 cwd = repo.getcwd() |
791 raise util.Abort(_('no source or destination specified')) | 791 errors = 0 |
792 elif len(pats) == 1: | 792 copied = [] |
793 raise util.Abort(_('no destination specified')) | |
794 pats = list(pats) | |
795 dest = pats.pop() | |
796 sources = [] | |
797 dir2dir = len(pats) == 1 and os.path.isdir(pats[0]) | |
798 | 793 |
799 def okaytocopy(abs, rel, exact): | 794 def okaytocopy(abs, rel, exact): |
800 reasons = {'?': _('is not managed'), | 795 reasons = {'?': _('is not managed'), |
801 'a': _('has been marked for add')} | 796 'a': _('has been marked for add')} |
802 reason = reasons.get(repo.dirstate.state(abs)) | 797 reason = reasons.get(repo.dirstate.state(abs)) |
803 if reason: | 798 if reason: |
804 if exact: ui.warn(_('%s: not copying - file %s\n') % (rel, reason)) | 799 if exact: ui.warn(_('%s: not copying - file %s\n') % (rel, reason)) |
805 else: | 800 else: |
806 return True | 801 return True |
807 | 802 |
808 for src, abs, rel, exact in walk(repo, pats, opts): | 803 def copy(abssrc, relsrc, target, exact): |
809 if okaytocopy(abs, rel, exact): | 804 abstarget = util.canonpath(repo.root, cwd, target) |
810 sources.append((abs, rel, exact)) | 805 reltarget = util.pathto(cwd, abstarget) |
811 if not sources: | 806 if not opts['force'] and repo.dirstate.state(abstarget) not in 'a?': |
812 raise util.Abort(_('no files to copy')) | 807 ui.warn(_('%s: not overwriting - file already managed\n') % |
813 | 808 reltarget) |
814 cwd = repo.getcwd() | 809 return |
815 absdest = util.canonpath(repo.root, cwd, dest) | 810 if ui.verbose or not exact: |
816 reldest = util.pathto(cwd, absdest) | 811 ui.status(_('copying %s to %s\n') % (relsrc, reltarget)) |
817 if os.path.exists(reldest): | |
818 destisfile = not os.path.isdir(reldest) | |
819 else: | |
820 destisfile = not dir2dir and (len(sources) == 1 | |
821 or repo.dirstate.state(absdest) != '?') | |
822 | |
823 if destisfile and len(sources) > 1: | |
824 raise util.Abort(_('with multiple sources, destination must be a ' | |
825 'directory')) | |
826 | |
827 srcpfxlen = 0 | |
828 if dir2dir: | |
829 srcpfx = util.pathto(cwd, util.canonpath(repo.root, cwd, pats[0])) | |
830 if os.path.exists(reldest): | |
831 srcpfx = os.path.split(srcpfx)[0] | |
832 if srcpfx: | |
833 srcpfx += os.sep | |
834 srcpfxlen = len(srcpfx) | |
835 | |
836 errs, copied = 0, [] | |
837 for abs, rel, exact in sources: | |
838 if destisfile: | |
839 mydest = reldest | |
840 elif dir2dir: | |
841 mydest = os.path.join(dest, rel[srcpfxlen:]) | |
842 else: | |
843 mydest = os.path.join(dest, os.path.basename(rel)) | |
844 myabsdest = util.canonpath(repo.root, cwd, mydest) | |
845 myreldest = util.pathto(cwd, myabsdest) | |
846 if not opts['force'] and repo.dirstate.state(myabsdest) not in 'a?': | |
847 ui.warn(_('%s: not overwriting - file already managed\n') % myreldest) | |
848 continue | |
849 mydestdir = os.path.dirname(myreldest) or '.' | |
850 if not opts['after']: | 812 if not opts['after']: |
813 targetdir = os.path.dirname(reltarget) or '.' | |
814 if not os.path.isdir(targetdir): | |
815 os.makedirs(targetdir) | |
851 try: | 816 try: |
852 if dir2dir: os.makedirs(mydestdir) | 817 shutil.copyfile(relsrc, reltarget) |
853 elif not destisfile: os.mkdir(mydestdir) | 818 shutil.copymode(relsrc, reltarget) |
854 except OSError, inst: | |
855 if inst.errno != errno.EEXIST: raise | |
856 if ui.verbose or not exact: | |
857 ui.status(_('copying %s to %s\n') % (rel, myreldest)) | |
858 if not opts['after']: | |
859 try: | |
860 shutil.copyfile(rel, myreldest) | |
861 shutil.copymode(rel, myreldest) | |
862 except shutil.Error, inst: | 819 except shutil.Error, inst: |
863 raise util.Abort(str(inst)) | 820 raise util.Abort(str(inst)) |
864 except IOError, inst: | 821 except IOError, inst: |
865 if inst.errno == errno.ENOENT: | 822 if inst.errno == errno.ENOENT: |
866 ui.warn(_('%s: deleted in working copy\n') % rel) | 823 ui.warn(_('%s: deleted in working copy\n') % relsrc) |
867 else: | 824 else: |
868 ui.warn(_('%s: cannot copy - %s\n') % (rel, inst.strerror)) | 825 ui.warn(_('%s: cannot copy - %s\n') % |
869 errs += 1 | 826 (relsrc, inst.strerror)) |
870 continue | 827 errors += 1 |
871 repo.copy(abs, myabsdest) | 828 return |
872 copied.append((abs, rel, exact)) | 829 repo.copy(abssrc, abstarget) |
873 if errs: | 830 copied.append((abssrc, relsrc, exact)) |
831 | |
832 pats = list(pats) | |
833 if not pats: | |
834 raise util.Abort(_('no source or destination specified')) | |
835 if len(pats) == 1: | |
836 raise util.Abort(_('no destination specified')) | |
837 dest = pats.pop() | |
838 destdirexists = os.path.isdir(dest) | |
839 if (len(pats) > 1 or not os.path.exists(pats[0])) and not destdirexists: | |
840 raise util.Abort(_('with multiple sources, destination must be an ' | |
841 'existing directory')) | |
842 | |
843 for pat in pats: | |
844 if os.path.isdir(pat): | |
845 if destdirexists: | |
846 striplen = len(os.path.split(pat)[0]) | |
847 else: | |
848 striplen = len(pat) | |
849 if striplen: | |
850 striplen += len(os.sep) | |
851 targetpath = lambda p: os.path.join(dest, p[striplen:]) | |
852 elif destdirexists: | |
853 targetpath = lambda p: os.path.join(dest, os.path.basename(p)) | |
854 else: | |
855 targetpath = lambda p: dest | |
856 for tag, abssrc, relsrc, exact in walk(repo, [pat], opts): | |
857 if okaytocopy(abssrc, relsrc, exact): | |
858 copy(abssrc, relsrc, targetpath(abssrc), exact) | |
859 | |
860 if errors: | |
874 ui.warn(_('(consider using --after)\n')) | 861 ui.warn(_('(consider using --after)\n')) |
875 return errs, copied | 862 if len(copied) == 0: |
863 raise util.Abort(_('no files to copy')) | |
864 return errors, copied | |
876 | 865 |
877 def copy(ui, repo, *pats, **opts): | 866 def copy(ui, repo, *pats, **opts): |
878 """mark files as copied for the next commit | 867 """mark files as copied for the next commit |
879 | 868 |
880 Mark dest as having copies of source files. If dest is a | 869 Mark dest as having copies of source files. If dest is a |