comparison mercurial/patch.py @ 14381:d4192500586a

patch: merge _updatedir() into externalpatch()
author Patrick Mezard <pmezard@gmail.com>
date Thu, 19 May 2011 22:44:01 +0200
parents 17cea10c343e
children 2d16f15da7bd
comparison
equal deleted inserted replaced
14380:10546bb7d201 14381:d4192500586a
1279 1279
1280 if rejects: 1280 if rejects:
1281 return -1 1281 return -1
1282 return err 1282 return err
1283 1283
1284 def _updatedir(ui, repo, patches, similarity=0): 1284 def _externalpatch(ui, repo, patcher, patchname, strip, cwd, files,
1285 '''Update dirstate after patch application according to metadata''' 1285 similarity):
1286 if not patches:
1287 return []
1288 copies = []
1289 removes = set()
1290 cfiles = patches.keys()
1291 cwd = repo.getcwd()
1292 if cwd:
1293 cfiles = [util.pathto(repo.root, cwd, f) for f in patches.keys()]
1294 for f in patches:
1295 gp = patches[f]
1296 if not gp:
1297 continue
1298 if gp.op == 'RENAME':
1299 copies.append((gp.oldpath, gp.path))
1300 removes.add(gp.oldpath)
1301 elif gp.op == 'COPY':
1302 copies.append((gp.oldpath, gp.path))
1303 elif gp.op == 'DELETE':
1304 removes.add(gp.path)
1305
1306 wctx = repo[None]
1307 for src, dst in copies:
1308 scmutil.dirstatecopy(ui, repo, wctx, src, dst, cwd=cwd)
1309 if (not similarity) and removes:
1310 wctx.remove(sorted(removes))
1311
1312 scmutil.addremove(repo, cfiles, similarity=similarity)
1313 files = patches.keys()
1314 files.extend([r for r in removes if r not in files])
1315 return sorted(files)
1316
1317 def _externalpatch(patcher, patchname, ui, strip, cwd, files):
1318 """use <patcher> to apply <patchname> to the working directory. 1286 """use <patcher> to apply <patchname> to the working directory.
1319 returns whether patch was applied with fuzz factor.""" 1287 returns whether patch was applied with fuzz factor."""
1320 1288
1321 fuzz = False 1289 fuzz = False
1322 args = [] 1290 args = []
1323 if cwd: 1291 if cwd:
1324 args.append('-d %s' % util.shellquote(cwd)) 1292 args.append('-d %s' % util.shellquote(cwd))
1325 fp = util.popen('%s %s -p%d < %s' % (patcher, ' '.join(args), strip, 1293 fp = util.popen('%s %s -p%d < %s' % (patcher, ' '.join(args), strip,
1326 util.shellquote(patchname))) 1294 util.shellquote(patchname)))
1327 1295 try:
1328 for line in fp: 1296 for line in fp:
1329 line = line.rstrip() 1297 line = line.rstrip()
1330 ui.note(line + '\n') 1298 ui.note(line + '\n')
1331 if line.startswith('patching file '): 1299 if line.startswith('patching file '):
1332 pf = util.parsepatchoutput(line) 1300 pf = util.parsepatchoutput(line)
1333 printed_file = False 1301 printed_file = False
1334 files.setdefault(pf, None) 1302 files.setdefault(pf, None)
1335 elif line.find('with fuzz') >= 0: 1303 elif line.find('with fuzz') >= 0:
1336 fuzz = True 1304 fuzz = True
1337 if not printed_file: 1305 if not printed_file:
1338 ui.warn(pf + '\n') 1306 ui.warn(pf + '\n')
1339 printed_file = True 1307 printed_file = True
1340 ui.warn(line + '\n') 1308 ui.warn(line + '\n')
1341 elif line.find('saving rejects to file') >= 0: 1309 elif line.find('saving rejects to file') >= 0:
1342 ui.warn(line + '\n') 1310 ui.warn(line + '\n')
1343 elif line.find('FAILED') >= 0: 1311 elif line.find('FAILED') >= 0:
1344 if not printed_file: 1312 if not printed_file:
1345 ui.warn(pf + '\n') 1313 ui.warn(pf + '\n')
1346 printed_file = True 1314 printed_file = True
1347 ui.warn(line + '\n') 1315 ui.warn(line + '\n')
1316 finally:
1317 if files:
1318 cfiles = list(files)
1319 cwd = repo.getcwd()
1320 if cwd:
1321 cfiles = [util.pathto(repo.root, cwd, f)
1322 for f in cfile]
1323 scmutil.addremove(repo, cfiles, similarity=similarity)
1348 code = fp.close() 1324 code = fp.close()
1349 if code: 1325 if code:
1350 raise PatchError(_("patch command failed: %s") % 1326 raise PatchError(_("patch command failed: %s") %
1351 util.explainexit(code)[0]) 1327 util.explainexit(code)[0])
1352 return fuzz 1328 return fuzz
1395 patcher = ui.config('ui', 'patch') 1371 patcher = ui.config('ui', 'patch')
1396 if files is None: 1372 if files is None:
1397 files = {} 1373 files = {}
1398 try: 1374 try:
1399 if patcher: 1375 if patcher:
1400 try: 1376 return _externalpatch(ui, repo, patcher, patchname, strip,
1401 return _externalpatch(patcher, patchname, ui, strip, cwd, 1377 cwd, files, similarity)
1402 files)
1403 finally:
1404 touched = _updatedir(ui, repo, files, similarity)
1405 files.update(dict.fromkeys(touched))
1406 return internalpatch(ui, repo, patchname, strip, files, eolmode, 1378 return internalpatch(ui, repo, patchname, strip, files, eolmode,
1407 similarity) 1379 similarity)
1408 except PatchError, err: 1380 except PatchError, err:
1409 raise util.Abort(str(err)) 1381 raise util.Abort(str(err))
1410 1382