mercurial/commands.py
changeset 1565 4bcbc126b80b
parent 1561 9c6d0abdb94e
child 1567 b4956bbbadc9
equal deleted inserted replaced
1564:34579a67fa71 1565:4bcbc126b80b
   819         prevsrc = targets.get(abstarget)
   819         prevsrc = targets.get(abstarget)
   820         if prevsrc is not None:
   820         if prevsrc is not None:
   821             ui.warn(_('%s: not overwriting - %s collides with %s\n') %
   821             ui.warn(_('%s: not overwriting - %s collides with %s\n') %
   822                     (reltarget, abssrc, prevsrc))
   822                     (reltarget, abssrc, prevsrc))
   823             return
   823             return
   824         elif os.path.exists(reltarget):
   824         if (not opts['after'] and os.path.exists(reltarget) or
   825             if opts['force']:
   825             opts['after'] and repo.dirstate.state(abstarget) not in '?r'):
   826                 os.unlink(reltarget)
   826             if not opts['force']:
   827             else:
       
   828                 ui.warn(_('%s: not overwriting - file exists\n') %
   827                 ui.warn(_('%s: not overwriting - file exists\n') %
   829                         reltarget)
   828                         reltarget)
   830                 return
   829                 return
   831         if ui.verbose or not exact:
   830             if not opts['after']:
   832             ui.status(_('copying %s to %s\n') % (relsrc, reltarget))
   831                 os.unlink(reltarget)
   833         if not opts['after']:
   832         if opts['after']:
       
   833             if not os.path.exists(reltarget):
       
   834                 return
       
   835         else:
   834             targetdir = os.path.dirname(reltarget) or '.'
   836             targetdir = os.path.dirname(reltarget) or '.'
   835             if not os.path.isdir(targetdir):
   837             if not os.path.isdir(targetdir):
   836                 os.makedirs(targetdir)
   838                 os.makedirs(targetdir)
   837             try:
   839             try:
   838                 shutil.copyfile(relsrc, reltarget)
   840                 shutil.copyfile(relsrc, reltarget)
   845                 else:
   847                 else:
   846                     ui.warn(_('%s: cannot copy - %s\n') %
   848                     ui.warn(_('%s: cannot copy - %s\n') %
   847                             (relsrc, inst.strerror))
   849                             (relsrc, inst.strerror))
   848                     errors += 1
   850                     errors += 1
   849                     return
   851                     return
       
   852         if ui.verbose or not exact:
       
   853             ui.status(_('copying %s to %s\n') % (relsrc, reltarget))
   850         targets[abstarget] = abssrc
   854         targets[abstarget] = abssrc
   851         repo.copy(abssrc, abstarget)
   855         repo.copy(abssrc, abstarget)
   852         copied.append((abssrc, relsrc, exact))
   856         copied.append((abssrc, relsrc, exact))
       
   857 
       
   858     def targetpathfn(pat, dest, srcs):
       
   859         if os.path.isdir(pat):
       
   860             if pat.endswith(os.sep):
       
   861                 pat = pat[:-len(os.sep)]
       
   862             if destdirexists:
       
   863                 striplen = len(os.path.split(pat)[0])
       
   864             else:
       
   865                 striplen = len(pat)
       
   866             if striplen:
       
   867                 striplen += len(os.sep)
       
   868             res = lambda p: os.path.join(dest, p[striplen:])
       
   869         elif destdirexists:
       
   870             res = lambda p: os.path.join(dest, os.path.basename(p))
       
   871         else:
       
   872             res = lambda p: dest
       
   873         return res
       
   874 
       
   875     def targetpathafterfn(pat, dest, srcs):
       
   876         if util.patkind(pat, None)[0]:
       
   877             # a mercurial pattern
       
   878             res = lambda p: os.path.join(dest, os.path.basename(p))
       
   879         elif len(util.canonpath(repo.root, cwd, pat)) < len(srcs[0][0]):
       
   880             # A directory. Either the target path contains the last
       
   881             # component of the source path or it does not.
       
   882             def evalpath(striplen):
       
   883                 score = 0
       
   884                 for s in srcs:
       
   885                     t = os.path.join(dest, s[1][striplen:])
       
   886                     if os.path.exists(t):
       
   887                         score += 1
       
   888                 return score
       
   889 
       
   890             if pat.endswith(os.sep):
       
   891                 pat = pat[:-len(os.sep)]
       
   892             striplen = len(pat) + len(os.sep)
       
   893             if os.path.isdir(os.path.join(dest, os.path.split(pat)[1])):
       
   894                 score = evalpath(striplen)
       
   895                 striplen1 = len(os.path.split(pat)[0])
       
   896                 if striplen1:
       
   897                     striplen1 += len(os.sep)
       
   898                 if evalpath(striplen1) > score:
       
   899                     striplen = striplen1
       
   900             res = lambda p: os.path.join(dest, p[striplen:])
       
   901         else:
       
   902             # a file
       
   903             if destdirexists:
       
   904                 res = lambda p: os.path.join(dest, os.path.basename(p))
       
   905             else:
       
   906                 res = lambda p: dest
       
   907         return res
       
   908 
   853 
   909 
   854     pats = list(pats)
   910     pats = list(pats)
   855     if not pats:
   911     if not pats:
   856         raise util.Abort(_('no source or destination specified'))
   912         raise util.Abort(_('no source or destination specified'))
   857     if len(pats) == 1:
   913     if len(pats) == 1:
   858         raise util.Abort(_('no destination specified'))
   914         raise util.Abort(_('no destination specified'))
   859     dest = pats.pop()
   915     dest = pats.pop()
   860     destdirexists = os.path.isdir(dest)
   916     destdirexists = os.path.isdir(dest)
   861     if (len(pats) > 1 or not os.path.exists(pats[0])) and not destdirexists:
   917     if (len(pats) > 1 or util.patkind(pats[0], None)[0]) and not destdirexists:
   862         raise util.Abort(_('with multiple sources, destination must be an '
   918         raise util.Abort(_('with multiple sources, destination must be an '
   863                          'existing directory'))
   919                          'existing directory'))
   864 
   920     if opts['after']:
       
   921         tfn = targetpathafterfn
       
   922     else:
       
   923         tfn = targetpathfn
       
   924     copylist = []
   865     for pat in pats:
   925     for pat in pats:
   866         if os.path.isdir(pat):
   926         srcs = []
   867             if destdirexists:
       
   868                 striplen = len(os.path.split(pat)[0])
       
   869             else:
       
   870                 striplen = len(pat)
       
   871             if striplen:
       
   872                 striplen += len(os.sep)
       
   873             targetpath = lambda p: os.path.join(dest, p[striplen:])
       
   874         elif destdirexists:
       
   875             targetpath = lambda p: os.path.join(dest, os.path.basename(p))
       
   876         else:
       
   877             targetpath = lambda p: dest
       
   878         for tag, abssrc, relsrc, exact in walk(repo, [pat], opts):
   927         for tag, abssrc, relsrc, exact in walk(repo, [pat], opts):
   879             if okaytocopy(abssrc, relsrc, exact):
   928             if okaytocopy(abssrc, relsrc, exact):
   880                 copy(abssrc, relsrc, targetpath(abssrc), exact)
   929                 srcs.append((abssrc, relsrc, exact))
       
   930         if not srcs:
       
   931             continue
       
   932         copylist.append((tfn(pat, dest, srcs), srcs))
       
   933     if not copylist:
       
   934         raise util.Abort(_('no files to copy'))
       
   935 
       
   936     for targetpath, srcs in copylist:
       
   937         for abssrc, relsrc, exact in srcs:
       
   938             copy(abssrc, relsrc, targetpath(relsrc), exact)
   881 
   939 
   882     if errors:
   940     if errors:
   883         ui.warn(_('(consider using --after)\n'))
   941         ui.warn(_('(consider using --after)\n'))
   884     if len(copied) == 0:
       
   885         raise util.Abort(_('no files to copy'))
       
   886     return errors, copied
   942     return errors, copied
   887 
   943 
   888 def copy(ui, repo, *pats, **opts):
   944 def copy(ui, repo, *pats, **opts):
   889     """mark files as copied for the next commit
   945     """mark files as copied for the next commit
   890 
   946