diff -r 926bc0d3b595 -r 650b5b6e75ed mercurial/patch.py --- a/mercurial/patch.py Wed Aug 27 12:30:28 2014 +0200 +++ b/mercurial/patch.py Tue Aug 26 22:03:32 2014 +0200 @@ -382,7 +382,7 @@ def getfile(self, fname): """Return target file data and flags as a (data, (islink, - isexec)) tuple. + isexec)) tuple. Data is None if file is missing/deleted. """ raise NotImplementedError @@ -426,7 +426,12 @@ except OSError, e: if e.errno != errno.ENOENT: raise - return (self.opener.read(fname), (False, isexec)) + try: + return (self.opener.read(fname), (False, isexec)) + except IOError, e: + if e.errno != errno.ENOENT: + raise + return None, None def setfile(self, fname, data, mode, copysource): islink, isexec = mode @@ -528,7 +533,7 @@ if fname in self.data: return self.data[fname] if not self.opener or fname not in self.files: - raise IOError + return None, None, None fn, mode, copied = self.files[fname] return self.opener.read(fn), mode, copied @@ -554,7 +559,7 @@ try: fctx = self.ctx[fname] except error.LookupError: - raise IOError + return None, None flags = fctx.flags() return fctx.data(), ('l' in flags, 'x' in flags) @@ -597,13 +602,12 @@ self.copysource = gp.oldpath self.create = gp.op in ('ADD', 'COPY', 'RENAME') self.remove = gp.op == 'DELETE' - try: - if self.copysource is None: - data, mode = backend.getfile(self.fname) - self.exists = True - else: - data, mode = store.getfile(self.copysource)[:2] - self.exists = backend.exists(self.fname) + if self.copysource is None: + data, mode = backend.getfile(self.fname) + else: + data, mode = store.getfile(self.copysource)[:2] + if data is not None: + self.exists = self.copysource is None or backend.exists(self.fname) self.missing = False if data: self.lines = mdiff.splitnewlines(data) @@ -622,7 +626,7 @@ l = l[:-2] + '\n' nlines.append(l) self.lines = nlines - except IOError: + else: if self.create: self.missing = False if self.mode is None: @@ -1380,6 +1384,8 @@ data, mode = None, None if gp.op in ('RENAME', 'COPY'): data, mode = store.getfile(gp.oldpath)[:2] + # FIXME: failing getfile has never been handled here + assert data is not None if gp.mode: mode = gp.mode if gp.op == 'ADD': @@ -1404,15 +1410,13 @@ elif state == 'git': for gp in values: path = pstrip(gp.oldpath) - try: - data, mode = backend.getfile(path) - except IOError, e: - if e.errno != errno.ENOENT: - raise + data, mode = backend.getfile(path) + if data is None: # The error ignored here will trigger a getfile() # error in a place more appropriate for error # handling, and will not interrupt the patching # process. + pass else: store.setfile(path, data, mode) else: