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] |