Show More
@@ -122,8 +122,7 b' class bzr_source(converter_source):' | |||||
122 | kind = revtree.kind(fileid) |
|
122 | kind = revtree.kind(fileid) | |
123 | if kind not in supportedkinds: |
|
123 | if kind not in supportedkinds: | |
124 | # the file is not available anymore - was deleted |
|
124 | # the file is not available anymore - was deleted | |
125 | raise IOError(_('%s is not available in %s anymore') % |
|
125 | return None, None | |
126 | (name, rev)) |
|
|||
127 | mode = self._modecache[(name, rev)] |
|
126 | mode = self._modecache[(name, rev)] | |
128 | if kind == 'symlink': |
|
127 | if kind == 'symlink': | |
129 | target = revtree.get_symlink_target(fileid) |
|
128 | target = revtree.get_symlink_target(fileid) |
@@ -88,8 +88,8 b' class converter_source(object):' | |||||
88 | def getfile(self, name, rev): |
|
88 | def getfile(self, name, rev): | |
89 | """Return a pair (data, mode) where data is the file content |
|
89 | """Return a pair (data, mode) where data is the file content | |
90 | as a string and mode one of '', 'x' or 'l'. rev is the |
|
90 | as a string and mode one of '', 'x' or 'l'. rev is the | |
91 |
identifier returned by a previous call to getchanges(). |
|
91 | identifier returned by a previous call to getchanges(). | |
92 |
|
|
92 | Data is None if file is missing/deleted in rev. | |
93 | """ |
|
93 | """ | |
94 | raise NotImplementedError |
|
94 | raise NotImplementedError | |
95 |
|
95 |
@@ -220,7 +220,7 b' class convert_cvs(converter_source):' | |||||
220 |
|
220 | |||
221 | self._parse() |
|
221 | self._parse() | |
222 | if rev.endswith("(DEAD)"): |
|
222 | if rev.endswith("(DEAD)"): | |
223 | raise IOError |
|
223 | return None, None | |
224 |
|
224 | |||
225 | args = ("-N -P -kk -r %s --" % rev).split() |
|
225 | args = ("-N -P -kk -r %s --" % rev).split() | |
226 | args.append(self.cvsrepo + '/' + name) |
|
226 | args.append(self.cvsrepo + '/' + name) |
@@ -8,7 +8,7 b'' | |||||
8 | from common import NoRepo, checktool, commandline, commit, converter_source |
|
8 | from common import NoRepo, checktool, commandline, commit, converter_source | |
9 | from mercurial.i18n import _ |
|
9 | from mercurial.i18n import _ | |
10 | from mercurial import util |
|
10 | from mercurial import util | |
11 | import os, shutil, tempfile, re |
|
11 | import os, shutil, tempfile, re, errno | |
12 |
|
12 | |||
13 | # The naming drift of ElementTree is fun! |
|
13 | # The naming drift of ElementTree is fun! | |
14 |
|
14 | |||
@@ -192,8 +192,13 b' class darcs_source(converter_source, com' | |||||
192 | if rev != self.lastrev: |
|
192 | if rev != self.lastrev: | |
193 | raise util.Abort(_('internal calling inconsistency')) |
|
193 | raise util.Abort(_('internal calling inconsistency')) | |
194 | path = os.path.join(self.tmppath, name) |
|
194 | path = os.path.join(self.tmppath, name) | |
195 | data = util.readfile(path) |
|
195 | try: | |
196 | mode = os.lstat(path).st_mode |
|
196 | data = util.readfile(path) | |
|
197 | mode = os.lstat(path).st_mode | |||
|
198 | except IOError, inst: | |||
|
199 | if inst.errno == errno.ENOENT: | |||
|
200 | return None, None | |||
|
201 | raise | |||
197 | mode = (mode & 0111) and 'x' or '' |
|
202 | mode = (mode & 0111) and 'x' or '' | |
198 | return data, mode |
|
203 | return data, mode | |
199 |
|
204 |
@@ -135,7 +135,7 b' class convert_git(converter_source):' | |||||
135 |
|
135 | |||
136 | def getfile(self, name, rev): |
|
136 | def getfile(self, name, rev): | |
137 | if rev == hex(nullid): |
|
137 | if rev == hex(nullid): | |
138 | raise IOError |
|
138 | return None, None | |
139 | if name == '.hgsub': |
|
139 | if name == '.hgsub': | |
140 | data = '\n'.join([m.hgsub() for m in self.submoditer()]) |
|
140 | data = '\n'.join([m.hgsub() for m in self.submoditer()]) | |
141 | mode = '' |
|
141 | mode = '' |
@@ -137,9 +137,8 b' class gnuarch_source(converter_source, c' | |||||
137 | if rev != self.lastrev: |
|
137 | if rev != self.lastrev: | |
138 | raise util.Abort(_('internal calling inconsistency')) |
|
138 | raise util.Abort(_('internal calling inconsistency')) | |
139 |
|
139 | |||
140 | # Raise IOError if necessary (i.e. deleted files). |
|
|||
141 | if not os.path.lexists(os.path.join(self.tmppath, name)): |
|
140 | if not os.path.lexists(os.path.join(self.tmppath, name)): | |
142 | raise IOError |
|
141 | return None, None | |
143 |
|
142 | |||
144 | return self._getfile(name, rev) |
|
143 | return self._getfile(name, rev) | |
145 |
|
144 |
@@ -134,6 +134,8 b' class mercurial_sink(converter_sink):' | |||||
134 | def getfilectx(repo, memctx, f): |
|
134 | def getfilectx(repo, memctx, f): | |
135 | v = files[f] |
|
135 | v = files[f] | |
136 | data, mode = source.getfile(f, v) |
|
136 | data, mode = source.getfile(f, v) | |
|
137 | if data is None: | |||
|
138 | return None | |||
137 | if f == '.hgtags': |
|
139 | if f == '.hgtags': | |
138 | data = self._rewritetags(source, revmap, data) |
|
140 | data = self._rewritetags(source, revmap, data) | |
139 | return context.memfilectx(self.repo, f, data, 'l' in mode, |
|
141 | return context.memfilectx(self.repo, f, data, 'l' in mode, | |
@@ -351,8 +353,8 b' class mercurial_source(converter_source)' | |||||
351 | try: |
|
353 | try: | |
352 | fctx = self.changectx(rev)[name] |
|
354 | fctx = self.changectx(rev)[name] | |
353 | return fctx.data(), fctx.flags() |
|
355 | return fctx.data(), fctx.flags() | |
354 |
except error.LookupError |
|
356 | except error.LookupError: | |
355 | raise IOError(err) |
|
357 | return None, None | |
356 |
|
358 | |||
357 | def getchanges(self, rev): |
|
359 | def getchanges(self, rev): | |
358 | ctx = self.changectx(rev) |
|
360 | ctx = self.changectx(rev) |
@@ -282,11 +282,11 b' class monotone_source(converter_source, ' | |||||
282 |
|
282 | |||
283 | def getfile(self, name, rev): |
|
283 | def getfile(self, name, rev): | |
284 | if not self.mtnisfile(name, rev): |
|
284 | if not self.mtnisfile(name, rev): | |
285 | raise IOError # file was deleted or renamed |
|
285 | return None, None | |
286 | try: |
|
286 | try: | |
287 | data = self.mtnrun("get_file_of", name, r=rev) |
|
287 | data = self.mtnrun("get_file_of", name, r=rev) | |
288 | except Exception: |
|
288 | except Exception: | |
289 | raise IOError # file was deleted or renamed |
|
289 | return None, None | |
290 | self.mtnloadmanifest(rev) |
|
290 | self.mtnloadmanifest(rev) | |
291 | node, attr = self.files.get(name, (None, "")) |
|
291 | node, attr = self.files.get(name, (None, "")) | |
292 | return data, attr |
|
292 | return data, attr |
@@ -183,7 +183,7 b' class p4_source(converter_source):' | |||||
183 | contents += data |
|
183 | contents += data | |
184 |
|
184 | |||
185 | if mode is None: |
|
185 | if mode is None: | |
186 | raise IOError(0, "bad stat") |
|
186 | return None, None | |
187 |
|
187 | |||
188 | if keywords: |
|
188 | if keywords: | |
189 | contents = keywords.sub("$\\1$", contents) |
|
189 | contents = keywords.sub("$\\1$", contents) |
@@ -933,7 +933,7 b' class svn_source(converter_source):' | |||||
933 | def getfile(self, file, rev): |
|
933 | def getfile(self, file, rev): | |
934 | # TODO: ra.get_file transmits the whole file instead of diffs. |
|
934 | # TODO: ra.get_file transmits the whole file instead of diffs. | |
935 | if file in self.removed: |
|
935 | if file in self.removed: | |
936 | raise IOError |
|
936 | return None, None | |
937 | mode = '' |
|
937 | mode = '' | |
938 | try: |
|
938 | try: | |
939 | new_module, revnum = revsplit(rev)[1:] |
|
939 | new_module, revnum = revsplit(rev)[1:] | |
@@ -954,7 +954,7 b' class svn_source(converter_source):' | |||||
954 | notfound = (svn.core.SVN_ERR_FS_NOT_FOUND, |
|
954 | notfound = (svn.core.SVN_ERR_FS_NOT_FOUND, | |
955 | svn.core.SVN_ERR_RA_DAV_PATH_NOT_FOUND) |
|
955 | svn.core.SVN_ERR_RA_DAV_PATH_NOT_FOUND) | |
956 | if e.apr_err in notfound: # File not found |
|
956 | if e.apr_err in notfound: # File not found | |
957 |
r |
|
957 | return None, None | |
958 | raise |
|
958 | raise | |
959 | if mode == 'l': |
|
959 | if mode == 'l': | |
960 | link_prefix = "link " |
|
960 | link_prefix = "link " | |
@@ -1236,9 +1236,8 b' class svn_sink(converter_sink, commandli' | |||||
1236 |
|
1236 | |||
1237 | # Apply changes to working copy |
|
1237 | # Apply changes to working copy | |
1238 | for f, v in files: |
|
1238 | for f, v in files: | |
1239 | try: |
|
1239 | data, mode = source.getfile(f, v) | |
1240 | data, mode = source.getfile(f, v) |
|
1240 | if data is None: | |
1241 | except IOError: |
|
|||
1242 | self.delete.append(f) |
|
1241 | self.delete.append(f) | |
1243 | else: |
|
1242 | else: | |
1244 | self.putfile(f, mode, data) |
|
1243 | self.putfile(f, mode, data) |
@@ -283,7 +283,7 b' def collapse(repo, first, last, commitop' | |||||
283 | isexec='x' in flags, |
|
283 | isexec='x' in flags, | |
284 | copied=copied.get(path)) |
|
284 | copied=copied.get(path)) | |
285 | return mctx |
|
285 | return mctx | |
286 | raise IOError() |
|
286 | return None | |
287 |
|
287 | |||
288 | if commitopts.get('message'): |
|
288 | if commitopts.get('message'): | |
289 | message = commitopts['message'] |
|
289 | message = commitopts['message'] |
@@ -146,7 +146,7 b' def _addchangeset(ui, rsrc, rdst, ctx, r' | |||||
146 | try: |
|
146 | try: | |
147 | fctx = ctx.filectx(lfutil.standin(f)) |
|
147 | fctx = ctx.filectx(lfutil.standin(f)) | |
148 | except error.LookupError: |
|
148 | except error.LookupError: | |
149 |
r |
|
149 | return None | |
150 | renamed = fctx.renamed() |
|
150 | renamed = fctx.renamed() | |
151 | if renamed: |
|
151 | if renamed: | |
152 | renamed = lfutil.splitstandin(renamed[0]) |
|
152 | renamed = lfutil.splitstandin(renamed[0]) | |
@@ -248,7 +248,7 b' def _lfconvert_addchangeset(rsrc, rdst, ' | |||||
248 | try: |
|
248 | try: | |
249 | fctx = ctx.filectx(srcfname) |
|
249 | fctx = ctx.filectx(srcfname) | |
250 | except error.LookupError: |
|
250 | except error.LookupError: | |
251 |
r |
|
251 | return None | |
252 | renamed = fctx.renamed() |
|
252 | renamed = fctx.renamed() | |
253 | if renamed: |
|
253 | if renamed: | |
254 | # standin is always a largefile because largefile-ness |
|
254 | # standin is always a largefile because largefile-ness | |
@@ -298,7 +298,7 b' def _getnormalcontext(repo, ctx, f, revm' | |||||
298 | try: |
|
298 | try: | |
299 | fctx = ctx.filectx(f) |
|
299 | fctx = ctx.filectx(f) | |
300 | except error.LookupError: |
|
300 | except error.LookupError: | |
301 |
r |
|
301 | return None | |
302 | renamed = fctx.renamed() |
|
302 | renamed = fctx.renamed() | |
303 | if renamed: |
|
303 | if renamed: | |
304 | renamed = renamed[0] |
|
304 | renamed = renamed[0] |
@@ -2130,7 +2130,7 b' def amend(ui, repo, commitfunc, old, ext' | |||||
2130 | copied=copied.get(path)) |
|
2130 | copied=copied.get(path)) | |
2131 | return mctx |
|
2131 | return mctx | |
2132 | except KeyError: |
|
2132 | except KeyError: | |
2133 |
r |
|
2133 | return None | |
2134 | else: |
|
2134 | else: | |
2135 | ui.note(_('copying changeset %s to %s\n') % (old, base)) |
|
2135 | ui.note(_('copying changeset %s to %s\n') % (old, base)) | |
2136 |
|
2136 | |||
@@ -2139,7 +2139,7 b' def amend(ui, repo, commitfunc, old, ext' | |||||
2139 | try: |
|
2139 | try: | |
2140 | return old.filectx(path) |
|
2140 | return old.filectx(path) | |
2141 | except KeyError: |
|
2141 | except KeyError: | |
2142 |
r |
|
2142 | return None | |
2143 |
|
2143 | |||
2144 | user = opts.get('user') or old.user() |
|
2144 | user = opts.get('user') or old.user() | |
2145 | date = opts.get('date') or old.date() |
|
2145 | date = opts.get('date') or old.date() |
@@ -347,7 +347,10 b' class basectx(object):' | |||||
347 | def makememctx(repo, parents, text, user, date, branch, files, store, |
|
347 | def makememctx(repo, parents, text, user, date, branch, files, store, | |
348 | editor=None): |
|
348 | editor=None): | |
349 | def getfilectx(repo, memctx, path): |
|
349 | def getfilectx(repo, memctx, path): | |
350 |
data, |
|
350 | data, mode, copied = store.getfile(path) | |
|
351 | if data is None: | |||
|
352 | return None | |||
|
353 | islink, isexec = mode | |||
351 | return memfilectx(repo, path, data, islink=islink, isexec=isexec, |
|
354 | return memfilectx(repo, path, data, islink=islink, isexec=isexec, | |
352 | copied=copied, memctx=memctx) |
|
355 | copied=copied, memctx=memctx) | |
353 | extra = {} |
|
356 | extra = {} | |
@@ -1626,7 +1629,9 b' class memctx(committablectx):' | |||||
1626 | self._repo.savecommitmessage(self._text) |
|
1629 | self._repo.savecommitmessage(self._text) | |
1627 |
|
1630 | |||
1628 | def filectx(self, path, filelog=None): |
|
1631 | def filectx(self, path, filelog=None): | |
1629 |
"""get a file context from the working directory |
|
1632 | """get a file context from the working directory | |
|
1633 | ||||
|
1634 | Returns None if file doesn't exist and should be removed.""" | |||
1630 | return self._filectxfn(self._repo, self, path) |
|
1635 | return self._filectxfn(self._repo, self, path) | |
1631 |
|
1636 | |||
1632 | def commit(self): |
|
1637 | def commit(self): |
@@ -1394,9 +1394,12 b' class localrepository(object):' | |||||
1394 | self.ui.note(f + "\n") |
|
1394 | self.ui.note(f + "\n") | |
1395 | try: |
|
1395 | try: | |
1396 | fctx = ctx[f] |
|
1396 | fctx = ctx[f] | |
1397 | new[f] = self._filecommit(fctx, m1, m2, linkrev, trp, |
|
1397 | if fctx is None: | |
1398 |
|
|
1398 | removed.append(f) | |
1399 |
|
|
1399 | else: | |
|
1400 | new[f] = self._filecommit(fctx, m1, m2, linkrev, | |||
|
1401 | trp, changed) | |||
|
1402 | m1.set(f, fctx.flags()) | |||
1400 | except OSError, inst: |
|
1403 | except OSError, inst: | |
1401 | self.ui.warn(_("trouble committing %s!\n") % f) |
|
1404 | self.ui.warn(_("trouble committing %s!\n") % f) | |
1402 | raise |
|
1405 | raise | |
@@ -1404,9 +1407,7 b' class localrepository(object):' | |||||
1404 | errcode = getattr(inst, 'errno', errno.ENOENT) |
|
1407 | errcode = getattr(inst, 'errno', errno.ENOENT) | |
1405 | if error or errcode and errcode != errno.ENOENT: |
|
1408 | if error or errcode and errcode != errno.ENOENT: | |
1406 | self.ui.warn(_("trouble committing %s!\n") % f) |
|
1409 | self.ui.warn(_("trouble committing %s!\n") % f) | |
1407 |
|
|
1410 | raise | |
1408 | else: |
|
|||
1409 | removed.append(f) |
|
|||
1410 |
|
1411 | |||
1411 | # update manifest |
|
1412 | # update manifest | |
1412 | m1.update(new) |
|
1413 | m1.update(new) |
@@ -382,7 +382,7 b' class abstractbackend(object):' | |||||
382 |
|
382 | |||
383 | def getfile(self, fname): |
|
383 | def getfile(self, fname): | |
384 | """Return target file data and flags as a (data, (islink, |
|
384 | """Return target file data and flags as a (data, (islink, | |
385 | isexec)) tuple. |
|
385 | isexec)) tuple. Data is None if file is missing/deleted. | |
386 | """ |
|
386 | """ | |
387 | raise NotImplementedError |
|
387 | raise NotImplementedError | |
388 |
|
388 | |||
@@ -426,7 +426,12 b' class fsbackend(abstractbackend):' | |||||
426 | except OSError, e: |
|
426 | except OSError, e: | |
427 | if e.errno != errno.ENOENT: |
|
427 | if e.errno != errno.ENOENT: | |
428 | raise |
|
428 | raise | |
429 | return (self.opener.read(fname), (False, isexec)) |
|
429 | try: | |
|
430 | return (self.opener.read(fname), (False, isexec)) | |||
|
431 | except IOError, e: | |||
|
432 | if e.errno != errno.ENOENT: | |||
|
433 | raise | |||
|
434 | return None, None | |||
430 |
|
435 | |||
431 | def setfile(self, fname, data, mode, copysource): |
|
436 | def setfile(self, fname, data, mode, copysource): | |
432 | islink, isexec = mode |
|
437 | islink, isexec = mode | |
@@ -528,7 +533,7 b' class filestore(object):' | |||||
528 | if fname in self.data: |
|
533 | if fname in self.data: | |
529 | return self.data[fname] |
|
534 | return self.data[fname] | |
530 | if not self.opener or fname not in self.files: |
|
535 | if not self.opener or fname not in self.files: | |
531 | raise IOError |
|
536 | return None, None, None | |
532 | fn, mode, copied = self.files[fname] |
|
537 | fn, mode, copied = self.files[fname] | |
533 | return self.opener.read(fn), mode, copied |
|
538 | return self.opener.read(fn), mode, copied | |
534 |
|
539 | |||
@@ -554,7 +559,7 b' class repobackend(abstractbackend):' | |||||
554 | try: |
|
559 | try: | |
555 | fctx = self.ctx[fname] |
|
560 | fctx = self.ctx[fname] | |
556 | except error.LookupError: |
|
561 | except error.LookupError: | |
557 | raise IOError |
|
562 | return None, None | |
558 | flags = fctx.flags() |
|
563 | flags = fctx.flags() | |
559 | return fctx.data(), ('l' in flags, 'x' in flags) |
|
564 | return fctx.data(), ('l' in flags, 'x' in flags) | |
560 |
|
565 | |||
@@ -597,13 +602,12 b' class patchfile(object):' | |||||
597 | self.copysource = gp.oldpath |
|
602 | self.copysource = gp.oldpath | |
598 | self.create = gp.op in ('ADD', 'COPY', 'RENAME') |
|
603 | self.create = gp.op in ('ADD', 'COPY', 'RENAME') | |
599 | self.remove = gp.op == 'DELETE' |
|
604 | self.remove = gp.op == 'DELETE' | |
600 | try: |
|
605 | if self.copysource is None: | |
601 | if self.copysource is None: |
|
606 | data, mode = backend.getfile(self.fname) | |
602 | data, mode = backend.getfile(self.fname) |
|
607 | else: | |
603 | self.exists = True |
|
608 | data, mode = store.getfile(self.copysource)[:2] | |
604 |
|
|
609 | if data is not None: | |
605 | data, mode = store.getfile(self.copysource)[:2] |
|
610 | self.exists = self.copysource is None or backend.exists(self.fname) | |
606 | self.exists = backend.exists(self.fname) |
|
|||
607 | self.missing = False |
|
611 | self.missing = False | |
608 | if data: |
|
612 | if data: | |
609 | self.lines = mdiff.splitnewlines(data) |
|
613 | self.lines = mdiff.splitnewlines(data) | |
@@ -622,7 +626,7 b' class patchfile(object):' | |||||
622 | l = l[:-2] + '\n' |
|
626 | l = l[:-2] + '\n' | |
623 | nlines.append(l) |
|
627 | nlines.append(l) | |
624 | self.lines = nlines |
|
628 | self.lines = nlines | |
625 |
e |
|
629 | else: | |
626 | if self.create: |
|
630 | if self.create: | |
627 | self.missing = False |
|
631 | self.missing = False | |
628 | if self.mode is None: |
|
632 | if self.mode is None: | |
@@ -1380,6 +1384,8 b' def _applydiff(ui, fp, patcher, backend,' | |||||
1380 | data, mode = None, None |
|
1384 | data, mode = None, None | |
1381 | if gp.op in ('RENAME', 'COPY'): |
|
1385 | if gp.op in ('RENAME', 'COPY'): | |
1382 | data, mode = store.getfile(gp.oldpath)[:2] |
|
1386 | data, mode = store.getfile(gp.oldpath)[:2] | |
|
1387 | # FIXME: failing getfile has never been handled here | |||
|
1388 | assert data is not None | |||
1383 | if gp.mode: |
|
1389 | if gp.mode: | |
1384 | mode = gp.mode |
|
1390 | mode = gp.mode | |
1385 | if gp.op == 'ADD': |
|
1391 | if gp.op == 'ADD': | |
@@ -1404,15 +1410,13 b' def _applydiff(ui, fp, patcher, backend,' | |||||
1404 | elif state == 'git': |
|
1410 | elif state == 'git': | |
1405 | for gp in values: |
|
1411 | for gp in values: | |
1406 | path = pstrip(gp.oldpath) |
|
1412 | path = pstrip(gp.oldpath) | |
1407 | try: |
|
1413 | data, mode = backend.getfile(path) | |
1408 | data, mode = backend.getfile(path) |
|
1414 | if data is None: | |
1409 | except IOError, e: |
|
|||
1410 | if e.errno != errno.ENOENT: |
|
|||
1411 | raise |
|
|||
1412 | # The error ignored here will trigger a getfile() |
|
1415 | # The error ignored here will trigger a getfile() | |
1413 | # error in a place more appropriate for error |
|
1416 | # error in a place more appropriate for error | |
1414 | # handling, and will not interrupt the patching |
|
1417 | # handling, and will not interrupt the patching | |
1415 | # process. |
|
1418 | # process. | |
|
1419 | pass | |||
1416 | else: |
|
1420 | else: | |
1417 | store.setfile(path, data, mode) |
|
1421 | store.setfile(path, data, mode) | |
1418 | else: |
|
1422 | else: |
General Comments 0
You need to be logged in to leave comments.
Login now