Mercurial > public > mercurial-scm > hg
comparison mercurial/patch.py @ 14351:d54f9bbcc640
patch: add lexists() to backends, use it in selectfile()
At this point, all applydiff() filesystem calls should pass through fsbackend.
author | Patrick Mezard <pmezard@gmail.com> |
---|---|
date | Tue, 17 May 2011 23:46:38 +0200 |
parents | 00da6624e167 |
children | 077cdf172580 |
comparison
equal
deleted
inserted
replaced
14350:00da6624e167 | 14351:d54f9bbcc640 |
---|---|
392 necessary. Files are specified relatively to the patching base | 392 necessary. Files are specified relatively to the patching base |
393 directory. | 393 directory. |
394 """ | 394 """ |
395 raise NotImplementedError | 395 raise NotImplementedError |
396 | 396 |
397 def exists(self, fname): | |
398 raise NotImplementedError | |
399 | |
397 class fsbackend(abstractbackend): | 400 class fsbackend(abstractbackend): |
398 def __init__(self, ui, basedir): | 401 def __init__(self, ui, basedir): |
399 super(fsbackend, self).__init__(ui) | 402 super(fsbackend, self).__init__(ui) |
400 self.opener = scmutil.opener(basedir) | 403 self.opener = scmutil.opener(basedir) |
401 | 404 |
458 except IOError: | 461 except IOError: |
459 raise util.Abort( | 462 raise util.Abort( |
460 _("cannot create %s: unable to create destination directory") | 463 _("cannot create %s: unable to create destination directory") |
461 % dst) | 464 % dst) |
462 util.copyfile(abssrc, absdst) | 465 util.copyfile(abssrc, absdst) |
466 | |
467 def exists(self, fname): | |
468 return os.path.lexists(fname) | |
463 | 469 |
464 # @@ -start,len +start,len @@ or @@ -start +start @@ if len is 1 | 470 # @@ -start,len +start,len @@ or @@ -start +start @@ if len is 1 |
465 unidesc = re.compile('@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))? @@') | 471 unidesc = re.compile('@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))? @@') |
466 contextdesc = re.compile('(---|\*\*\*) (\d+)(,(\d+))? (---|\*\*\*)') | 472 contextdesc = re.compile('(---|\*\*\*) (\d+)(,(\d+))? (---|\*\*\*)') |
467 eolmodes = ['strict', 'crlf', 'lf', 'auto'] | 473 eolmodes = ['strict', 'crlf', 'lf', 'auto'] |
968 while i < pathlen - 1 and path[i] == '/': | 974 while i < pathlen - 1 and path[i] == '/': |
969 i += 1 | 975 i += 1 |
970 count -= 1 | 976 count -= 1 |
971 return path[:i].lstrip(), path[i:].rstrip() | 977 return path[:i].lstrip(), path[i:].rstrip() |
972 | 978 |
973 def selectfile(afile_orig, bfile_orig, hunk, strip): | 979 def selectfile(backend, afile_orig, bfile_orig, hunk, strip): |
974 nulla = afile_orig == "/dev/null" | 980 nulla = afile_orig == "/dev/null" |
975 nullb = bfile_orig == "/dev/null" | 981 nullb = bfile_orig == "/dev/null" |
976 abase, afile = pathstrip(afile_orig, strip) | 982 abase, afile = pathstrip(afile_orig, strip) |
977 gooda = not nulla and os.path.lexists(afile) | 983 gooda = not nulla and backend.exists(afile) |
978 bbase, bfile = pathstrip(bfile_orig, strip) | 984 bbase, bfile = pathstrip(bfile_orig, strip) |
979 if afile == bfile: | 985 if afile == bfile: |
980 goodb = gooda | 986 goodb = gooda |
981 else: | 987 else: |
982 goodb = not nullb and os.path.lexists(bfile) | 988 goodb = not nullb and backend.exists(bfile) |
983 createfunc = hunk.createfile | 989 createfunc = hunk.createfile |
984 missing = not goodb and not gooda and not createfunc() | 990 missing = not goodb and not gooda and not createfunc() |
985 | 991 |
986 # some diff programs apparently produce patches where the afile is | 992 # some diff programs apparently produce patches where the afile is |
987 # not /dev/null, but afile starts with bfile | 993 # not /dev/null, but afile starts with bfile |
1174 elif state == 'file': | 1180 elif state == 'file': |
1175 if current_file: | 1181 if current_file: |
1176 rejects += current_file.close() | 1182 rejects += current_file.close() |
1177 afile, bfile, first_hunk = values | 1183 afile, bfile, first_hunk = values |
1178 try: | 1184 try: |
1179 current_file, missing = selectfile(afile, bfile, | 1185 current_file, missing = selectfile(backend, afile, bfile, |
1180 first_hunk, strip) | 1186 first_hunk, strip) |
1181 current_file = patcher(ui, current_file, backend, | 1187 current_file = patcher(ui, current_file, backend, |
1182 missing=missing, eolmode=eolmode) | 1188 missing=missing, eolmode=eolmode) |
1183 except PatchError, inst: | 1189 except PatchError, inst: |
1184 ui.warn(str(inst) + '\n') | 1190 ui.warn(str(inst) + '\n') |
1345 return internalpatch(ui, repo, patchname, strip, cwd, files, eolmode, | 1351 return internalpatch(ui, repo, patchname, strip, cwd, files, eolmode, |
1346 similarity) | 1352 similarity) |
1347 except PatchError, err: | 1353 except PatchError, err: |
1348 raise util.Abort(str(err)) | 1354 raise util.Abort(str(err)) |
1349 | 1355 |
1350 def changedfiles(patchpath, strip=1): | 1356 def changedfiles(ui, repo, patchpath, strip=1): |
1357 backend = fsbackend(ui, repo.root) | |
1351 fp = open(patchpath, 'rb') | 1358 fp = open(patchpath, 'rb') |
1352 try: | 1359 try: |
1353 changed = set() | 1360 changed = set() |
1354 for state, values in iterhunks(fp): | 1361 for state, values in iterhunks(fp): |
1355 if state == 'hunk': | 1362 if state == 'hunk': |
1356 continue | 1363 continue |
1357 elif state == 'file': | 1364 elif state == 'file': |
1358 afile, bfile, first_hunk = values | 1365 afile, bfile, first_hunk = values |
1359 current_file, missing = selectfile(afile, bfile, | 1366 current_file, missing = selectfile(backend, afile, bfile, |
1360 first_hunk, strip) | 1367 first_hunk, strip) |
1361 changed.add(current_file) | 1368 changed.add(current_file) |
1362 elif state == 'git': | 1369 elif state == 'git': |
1363 for gp in values: | 1370 for gp in values: |
1364 gp.path = pathstrip(gp.path, strip - 1)[1] | 1371 gp.path = pathstrip(gp.path, strip - 1)[1] |