mercurial/patch.py
changeset 12266 00658492e2aa
parent 12167 d2c5b0927c28
child 12345 e0ee3e822a9a
equal deleted inserted replaced
12265:1ed2dc9d4368 12266:00658492e2aa
     9 import cStringIO, email.Parser, os, re
     9 import cStringIO, email.Parser, os, re
    10 import tempfile, zlib
    10 import tempfile, zlib
    11 
    11 
    12 from i18n import _
    12 from i18n import _
    13 from node import hex, nullid, short
    13 from node import hex, nullid, short
    14 import base85, cmdutil, mdiff, util, diffhelpers, copies, encoding
    14 import base85, mdiff, util, diffhelpers, copies, encoding
    15 
    15 
    16 gitre = re.compile('diff --git a/(.*) b/(.*)')
    16 gitre = re.compile('diff --git a/(.*) b/(.*)')
    17 
    17 
    18 class PatchError(Exception):
    18 class PatchError(Exception):
    19     pass
    19     pass
   442         finally:
   442         finally:
   443             fp.close()
   443             fp.close()
   444 
   444 
   445     def writelines(self, fname, lines):
   445     def writelines(self, fname, lines):
   446         # Ensure supplied data ends in fname, being a regular file or
   446         # Ensure supplied data ends in fname, being a regular file or
   447         # a symlink. updatedir() will -too magically- take care of
   447         # a symlink. cmdutil.updatedir will -too magically- take care
   448         # setting it to the proper type afterwards.
   448         # of setting it to the proper type afterwards.
   449         islink = os.path.islink(fname)
   449         islink = os.path.islink(fname)
   450         if islink:
   450         if islink:
   451             fp = cStringIO.StringIO()
   451             fp = cStringIO.StringIO()
   452         else:
   452         else:
   453             fp = self.opener(fname, 'w')
   453             fp = self.opener(fname, 'w')
  1127 
  1127 
  1128     If 'eolmode' is 'strict', the patch content and patched file are
  1128     If 'eolmode' is 'strict', the patch content and patched file are
  1129     read in binary mode. Otherwise, line endings are ignored when
  1129     read in binary mode. Otherwise, line endings are ignored when
  1130     patching then normalized according to 'eolmode'.
  1130     patching then normalized according to 'eolmode'.
  1131 
  1131 
  1132     Callers probably want to call 'updatedir' after this to apply
  1132     Callers probably want to call 'cmdutil.updatedir' after this to
  1133     certain categories of changes not done by this function.
  1133     apply certain categories of changes not done by this function.
  1134     """
  1134     """
  1135     return _applydiff(
  1135     return _applydiff(
  1136         ui, fp, patchfile, copyfile,
  1136         ui, fp, patchfile, copyfile,
  1137         changed, strip=strip, sourcefile=sourcefile, eolmode=eolmode)
  1137         changed, strip=strip, sourcefile=sourcefile, eolmode=eolmode)
  1138 
  1138 
  1193     rejects += closefile()
  1193     rejects += closefile()
  1194 
  1194 
  1195     if rejects:
  1195     if rejects:
  1196         return -1
  1196         return -1
  1197     return err
  1197     return err
  1198 
       
  1199 def updatedir(ui, repo, patches, similarity=0):
       
  1200     '''Update dirstate after patch application according to metadata'''
       
  1201     if not patches:
       
  1202         return
       
  1203     copies = []
       
  1204     removes = set()
       
  1205     cfiles = patches.keys()
       
  1206     cwd = repo.getcwd()
       
  1207     if cwd:
       
  1208         cfiles = [util.pathto(repo.root, cwd, f) for f in patches.keys()]
       
  1209     for f in patches:
       
  1210         gp = patches[f]
       
  1211         if not gp:
       
  1212             continue
       
  1213         if gp.op == 'RENAME':
       
  1214             copies.append((gp.oldpath, gp.path))
       
  1215             removes.add(gp.oldpath)
       
  1216         elif gp.op == 'COPY':
       
  1217             copies.append((gp.oldpath, gp.path))
       
  1218         elif gp.op == 'DELETE':
       
  1219             removes.add(gp.path)
       
  1220 
       
  1221     wctx = repo[None]
       
  1222     for src, dst in copies:
       
  1223         wctx.copy(src, dst)
       
  1224     if (not similarity) and removes:
       
  1225         wctx.remove(sorted(removes), True)
       
  1226 
       
  1227     for f in patches:
       
  1228         gp = patches[f]
       
  1229         if gp and gp.mode:
       
  1230             islink, isexec = gp.mode
       
  1231             dst = repo.wjoin(gp.path)
       
  1232             # patch won't create empty files
       
  1233             if gp.op == 'ADD' and not os.path.exists(dst):
       
  1234                 flags = (isexec and 'x' or '') + (islink and 'l' or '')
       
  1235                 repo.wwrite(gp.path, '', flags)
       
  1236             util.set_flags(dst, islink, isexec)
       
  1237     cmdutil.addremove(repo, cfiles, similarity=similarity)
       
  1238     files = patches.keys()
       
  1239     files.extend([r for r in removes if r not in files])
       
  1240     return sorted(files)
       
  1241 
  1198 
  1242 def externalpatch(patcher, args, patchname, ui, strip, cwd, files):
  1199 def externalpatch(patcher, args, patchname, ui, strip, cwd, files):
  1243     """use <patcher> to apply <patchname> to the working directory.
  1200     """use <patcher> to apply <patchname> to the working directory.
  1244     returns whether patch was applied with fuzz factor."""
  1201     returns whether patch was applied with fuzz factor."""
  1245 
  1202