comparison mercurial/patch.py @ 14260:00a881581400

patch: make patch()/internalpatch() always update the dirstate
author Patrick Mezard <pmezard@gmail.com>
date Sun, 08 May 2011 17:48:31 +0200
parents df9ccd39828c
children 003d63bb4fa5
comparison
equal deleted inserted replaced
14259:df9ccd39828c 14260:00a881581400
426 finally: 426 finally:
427 fp.close() 427 fp.close()
428 428
429 def writelines(self, fname, lines): 429 def writelines(self, fname, lines):
430 # Ensure supplied data ends in fname, being a regular file or 430 # Ensure supplied data ends in fname, being a regular file or
431 # a symlink. cmdutil.updatedir will -too magically- take care 431 # a symlink. _updatedir will -too magically- take care
432 # of setting it to the proper type afterwards. 432 # of setting it to the proper type afterwards.
433 st_mode = None 433 st_mode = None
434 islink = os.path.islink(fname) 434 islink = os.path.islink(fname)
435 if islink: 435 if islink:
436 fp = cStringIO.StringIO() 436 fp = cStringIO.StringIO()
1099 1099
1100 If 'eolmode' is 'strict', the patch content and patched file are 1100 If 'eolmode' is 'strict', the patch content and patched file are
1101 read in binary mode. Otherwise, line endings are ignored when 1101 read in binary mode. Otherwise, line endings are ignored when
1102 patching then normalized according to 'eolmode'. 1102 patching then normalized according to 'eolmode'.
1103 1103
1104 Callers probably want to call 'cmdutil.updatedir' after this to 1104 Callers probably want to call '_updatedir' after this to
1105 apply certain categories of changes not done by this function. 1105 apply certain categories of changes not done by this function.
1106 """ 1106 """
1107 return _applydiff(ui, fp, patchfile, copyfile, changed, strip=strip, 1107 return _applydiff(ui, fp, patchfile, copyfile, changed, strip=strip,
1108 eolmode=eolmode) 1108 eolmode=eolmode)
1109 1109
1155 1155
1156 if rejects: 1156 if rejects:
1157 return -1 1157 return -1
1158 return err 1158 return err
1159 1159
1160 def updatedir(ui, repo, patches, similarity=0): 1160 def _updatedir(ui, repo, patches, similarity=0):
1161 '''Update dirstate after patch application according to metadata''' 1161 '''Update dirstate after patch application according to metadata'''
1162 if not patches: 1162 if not patches:
1163 return [] 1163 return []
1164 copies = [] 1164 copies = []
1165 removes = set() 1165 removes = set()
1235 if code: 1235 if code:
1236 raise PatchError(_("patch command failed: %s") % 1236 raise PatchError(_("patch command failed: %s") %
1237 util.explainexit(code)[0]) 1237 util.explainexit(code)[0])
1238 return fuzz 1238 return fuzz
1239 1239
1240 def internalpatch(patchobj, ui, strip, cwd, files=None, eolmode='strict'): 1240 def internalpatch(ui, repo, patchobj, strip, cwd, files=None, eolmode='strict',
1241 similarity=0):
1241 """use builtin patch to apply <patchobj> to the working directory. 1242 """use builtin patch to apply <patchobj> to the working directory.
1242 returns whether patch was applied with fuzz factor.""" 1243 returns whether patch was applied with fuzz factor."""
1243 1244
1244 if files is None: 1245 if files is None:
1245 files = {} 1246 files = {}
1261 finally: 1262 finally:
1262 if cwd: 1263 if cwd:
1263 os.chdir(curdir) 1264 os.chdir(curdir)
1264 if fp != patchobj: 1265 if fp != patchobj:
1265 fp.close() 1266 fp.close()
1267 touched = _updatedir(ui, repo, files, similarity)
1268 files.update(dict.fromkeys(touched))
1266 if ret < 0: 1269 if ret < 0:
1267 raise PatchError(_('patch failed to apply')) 1270 raise PatchError(_('patch failed to apply'))
1268 return ret > 0 1271 return ret > 0
1269 1272
1270 def patch(patchname, ui, strip=1, cwd=None, files=None, eolmode='strict'): 1273 def patch(ui, repo, patchname, strip=1, cwd=None, files=None, eolmode='strict',
1274 similarity=0):
1271 """Apply <patchname> to the working directory. 1275 """Apply <patchname> to the working directory.
1272 1276
1273 'eolmode' specifies how end of lines should be handled. It can be: 1277 'eolmode' specifies how end of lines should be handled. It can be:
1274 - 'strict': inputs are read in binary mode, EOLs are preserved 1278 - 'strict': inputs are read in binary mode, EOLs are preserved
1275 - 'crlf': EOLs are ignored when patching and reset to CRLF 1279 - 'crlf': EOLs are ignored when patching and reset to CRLF
1282 patcher = ui.config('ui', 'patch') 1286 patcher = ui.config('ui', 'patch')
1283 if files is None: 1287 if files is None:
1284 files = {} 1288 files = {}
1285 try: 1289 try:
1286 if patcher: 1290 if patcher:
1287 return _externalpatch(patcher, patchname, ui, strip, cwd, files) 1291 try:
1288 return internalpatch(patchname, ui, strip, cwd, files, eolmode) 1292 return _externalpatch(patcher, patchname, ui, strip, cwd,
1293 files)
1294 finally:
1295 touched = _updatedir(ui, repo, files, similarity)
1296 files.update(dict.fromkeys(touched))
1297 return internalpatch(ui, repo, patchname, strip, cwd, files, eolmode,
1298 similarity)
1289 except PatchError, err: 1299 except PatchError, err:
1290 raise util.Abort(str(err)) 1300 raise util.Abort(str(err))
1291 1301
1292 def changedfiles(patchpath, strip=1): 1302 def changedfiles(patchpath, strip=1):
1293 fp = open(patchpath, 'rb') 1303 fp = open(patchpath, 'rb')