mercurial/patch.py
changeset 2933 439fd013360d
parent 2922 773c5b82d052
child 2934 2f190e998eb3
equal deleted inserted replaced
2926:13cd2cdeff6a 2933:439fd013360d
     8 from demandload import demandload
     8 from demandload import demandload
     9 from i18n import gettext as _
     9 from i18n import gettext as _
    10 from node import *
    10 from node import *
    11 demandload(globals(), "cmdutil mdiff util")
    11 demandload(globals(), "cmdutil mdiff util")
    12 demandload(globals(), "cStringIO email.Parser os re shutil sys tempfile")
    12 demandload(globals(), "cStringIO email.Parser os re shutil sys tempfile")
       
    13 
       
    14 # helper functions
       
    15 
       
    16 def copyfile(src, dst, basedir=None):
       
    17     if not basedir:
       
    18         basedir = os.getcwd()
       
    19 
       
    20     abssrc, absdst = [os.path.join(basedir, n) for n in (src, dst)]
       
    21     if os.path.exists(absdst):
       
    22         raise util.Abort(_("cannot create %s: destination already exists") %
       
    23                          dst)
       
    24 
       
    25     targetdir = os.path.dirname(absdst)
       
    26     if not os.path.isdir(targetdir):
       
    27         os.makedirs(targetdir)
       
    28     try:
       
    29         shutil.copyfile(abssrc, absdst)
       
    30         shutil.copymode(abssrc, absdst)
       
    31     except shutil.Error, inst:
       
    32         raise util.Abort(str(inst))
       
    33 
       
    34 # public functions
    13 
    35 
    14 def extract(ui, fileobj):
    36 def extract(ui, fileobj):
    15     '''extract patch from data read from fileobj.
    37     '''extract patch from data read from fileobj.
    16 
    38 
    17     patch can be normal patch or contained in email message.
    39     patch can be normal patch or contained in email message.
   172         for i in range(len(gitpatches)):
   194         for i in range(len(gitpatches)):
   173             p = gitpatches[i]
   195             p = gitpatches[i]
   174             if not p.copymod:
   196             if not p.copymod:
   175                 continue
   197                 continue
   176 
   198 
   177             if os.path.exists(p.path):
   199             copyfile(p.oldpath, p.path)
   178                 raise util.Abort(_("cannot create %s: destination already exists") %
       
   179                             p.path)
       
   180 
       
   181             (src, dst) = [os.path.join(os.getcwd(), n)
       
   182                           for n in (p.oldpath, p.path)]
       
   183 
       
   184             targetdir = os.path.dirname(dst)
       
   185             if not os.path.isdir(targetdir):
       
   186                 os.makedirs(targetdir)
       
   187             try:
       
   188                 shutil.copyfile(src, dst)
       
   189                 shutil.copymode(src, dst)
       
   190             except shutil.Error, inst:
       
   191                 raise util.Abort(str(inst))
       
   192 
   200 
   193             # rewrite patch hunk
   201             # rewrite patch hunk
   194             while pfline < p.lineno:
   202             while pfline < p.lineno:
   195                 tmpfp.write(pf.readline())
   203                 tmpfp.write(pf.readline())
   196                 pfline += 1
   204                 pfline += 1
   278                   ui.configbool('diff', 'ignorews', None)),
   286                   ui.configbool('diff', 'ignorews', None)),
   279         ignorewsamount=(opts.get('ignore_space_change') or
   287         ignorewsamount=(opts.get('ignore_space_change') or
   280                         ui.configbool('diff', 'ignorewsamount', None)),
   288                         ui.configbool('diff', 'ignorewsamount', None)),
   281         ignoreblanklines=(opts.get('ignore_blank_lines') or
   289         ignoreblanklines=(opts.get('ignore_blank_lines') or
   282                           ui.configbool('diff', 'ignoreblanklines', None)))
   290                           ui.configbool('diff', 'ignoreblanklines', None)))
       
   291 
       
   292 def updatedir(ui, repo, patches, wlock=None):
       
   293     '''Update dirstate after patch application according to metadata'''
       
   294     if not patches:
       
   295         return
       
   296     copies = []
       
   297     removes = []
       
   298     cfiles = patches.keys()
       
   299     copts = {'after': False, 'force': False}
       
   300     cwd = repo.getcwd()
       
   301     if cwd:
       
   302         cfiles = [util.pathto(cwd, f) for f in patches.keys()]
       
   303     for f in patches:
       
   304         ctype, gp = patches[f]
       
   305         if ctype == 'RENAME':
       
   306             copies.append((gp.oldpath, gp.path, gp.copymod))
       
   307             removes.append(gp.oldpath)
       
   308         elif ctype == 'COPY':
       
   309             copies.append((gp.oldpath, gp.path, gp.copymod))
       
   310         elif ctype == 'DELETE':
       
   311             removes.append(gp.path)
       
   312     for src, dst, after in copies:
       
   313         if not after:
       
   314             copyfile(src, dst, repo.root)
       
   315         repo.copy(src, dst, wlock=wlock)
       
   316     if removes:
       
   317         repo.remove(removes, True, wlock=wlock)
       
   318     for f in patches:
       
   319         ctype, gp = patches[f]
       
   320         if gp and gp.mode:
       
   321             x = gp.mode & 0100 != 0
       
   322             dst = os.path.join(repo.root, gp.path)
       
   323             util.set_exec(dst, x)
       
   324     cmdutil.addremove(repo, cfiles, wlock=wlock)
       
   325     files = patches.keys()
       
   326     files.extend([r for r in removes if r not in files])
       
   327     files.sort()
       
   328 
       
   329     return files
   283 
   330 
   284 def diff(repo, node1=None, node2=None, files=None, match=util.always,
   331 def diff(repo, node1=None, node2=None, files=None, match=util.always,
   285          fp=None, changes=None, opts=None):
   332          fp=None, changes=None, opts=None):
   286     '''print diff of changes to files between two nodes, or node and
   333     '''print diff of changes to files between two nodes, or node and
   287     working directory.
   334     working directory.