mercurial/patch.py
changeset 14351 d54f9bbcc640
parent 14350 00da6624e167
child 14352 077cdf172580
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]