diff --git a/hgext/convert/bzr.py b/hgext/convert/bzr.py --- a/hgext/convert/bzr.py +++ b/hgext/convert/bzr.py @@ -109,18 +109,16 @@ class bzr_source(converter_source): # the file is not available anymore - was deleted raise IOError(_('%s is not available in %s anymore') % (name, rev)) + mode = self._modecache[(name, rev)] if kind == 'symlink': target = revtree.get_symlink_target(fileid) if target is None: raise util.Abort(_('%s.%s symlink has no target') % (name, rev)) - return target + return target, mode else: sio = revtree.get_file(fileid) - return sio.read() - - def getmode(self, name, rev): - return self._modecache[(name, rev)] + return sio.read(), mode def getchanges(self, version): # set up caches: modecache and revtree diff --git a/hgext/convert/common.py b/hgext/convert/common.py --- a/hgext/convert/common.py +++ b/hgext/convert/common.py @@ -77,15 +77,10 @@ class converter_source(object): raise NotImplementedError() def getfile(self, name, rev): - """Return file contents as a string. rev is the identifier returned - by a previous call to getchanges(). Raise IOError to indicate that - name was deleted in rev. - """ - raise NotImplementedError() - - def getmode(self, name, rev): - """Return file mode, eg. '', 'x', or 'l'. rev is the identifier - returned by a previous call to getchanges(). + """Return a pair (data, mode) where data is the file content + as a string and mode one of '', 'x' or 'l'. rev is the + identifier returned by a previous call to getchanges(). Raise + IOError to indicate that name was deleted in rev. """ raise NotImplementedError() @@ -192,8 +187,8 @@ class converter_sink(object): changeset. 'files' is a list of (path, version) tuples, 'copies' is a dictionary mapping destinations to sources, 'source' is the source repository, and 'revmap' is a mapfile - of source revisions to converted revisions. Only getfile(), - getmode(), and lookuprev() should be called on 'source'. + of source revisions to converted revisions. Only getfile() and + lookuprev() should be called on 'source'. Note that the sink repository is not told to update itself to a particular revision (or even what that revision would be) diff --git a/hgext/convert/cvs.py b/hgext/convert/cvs.py --- a/hgext/convert/cvs.py +++ b/hgext/convert/cvs.py @@ -200,7 +200,7 @@ class convert_cvs(converter_source): self._parse() return self.heads - def _getfile(self, name, rev): + def getfile(self, name, rev): def chunkedread(fp, count): # file-objects returned by socked.makefile() do not handle @@ -216,6 +216,7 @@ class convert_cvs(converter_source): output.write(data) return output.getvalue() + self._parse() if rev.endswith("(DEAD)"): raise IOError @@ -255,18 +256,8 @@ class convert_cvs(converter_source): else: raise util.Abort(_("unknown CVS response: %s") % line) - def getfile(self, file, rev): - self._parse() - data, mode = self._getfile(file, rev) - self.modecache[(file, rev)] = mode - return data - - def getmode(self, file, rev): - return self.modecache[(file, rev)] - def getchanges(self, rev): self._parse() - self.modecache = {} return sorted(self.files[rev].iteritems()), {} def getcommit(self, rev): diff --git a/hgext/convert/darcs.py b/hgext/convert/darcs.py --- a/hgext/convert/darcs.py +++ b/hgext/convert/darcs.py @@ -157,11 +157,11 @@ class darcs_source(converter_source, com def getfile(self, name, rev): if rev != self.lastrev: raise util.Abort(_('internal calling inconsistency')) - return open(os.path.join(self.tmppath, name), 'rb').read() - - def getmode(self, name, rev): - mode = os.lstat(os.path.join(self.tmppath, name)).st_mode - return (mode & 0111) and 'x' or '' + path = os.path.join(self.tmppath, name) + data = open(path, 'rb').read() + mode = os.lstat(path).st_mode + mode = (mode & 0111) and 'x' or '' + return data, mode def gettags(self): return self.tags diff --git a/hgext/convert/filemap.py b/hgext/convert/filemap.py --- a/hgext/convert/filemap.py +++ b/hgext/convert/filemap.py @@ -100,8 +100,7 @@ class filemapper(object): # # - Filter and rename files. This is mostly wrapped by the filemapper # class above. We hide the original filename in the revision that is -# returned by getchanges to be able to find things later in getfile -# and getmode. +# returned by getchanges to be able to find things later in getfile. # # - Return only revisions that matter for the files we're interested in. # This involves rewriting the parents of the original revision to @@ -318,10 +317,9 @@ class filemap_source(converter_source): self.convertedorder.append((rev, True, None)) self._discard(*parents) - # Get the real changes and do the filtering/mapping. - # To be able to get the files later on in getfile and getmode, - # we hide the original filename in the rev part of the return - # value. + # Get the real changes and do the filtering/mapping. To be + # able to get the files later on in getfile, we hide the + # original filename in the rev part of the return value. changes, copies = self.base.getchanges(rev) newnames = {} files = [] @@ -345,10 +343,6 @@ class filemap_source(converter_source): realname, realrev = rev return self.base.getfile(realname, realrev) - def getmode(self, name, rev): - realname, realrev = rev - return self.base.getmode(realname, realrev) - def gettags(self): return self.base.gettags() diff --git a/hgext/convert/git.py b/hgext/convert/git.py --- a/hgext/convert/git.py +++ b/hgext/convert/git.py @@ -67,10 +67,9 @@ class convert_git(converter_source): return data def getfile(self, name, rev): - return self.catfile(rev, "blob") - - def getmode(self, name, rev): - return self.modecache[(name, rev)] + data = self.catfile(rev, "blob") + mode = self.modecache[(name, rev)] + return data, mode def getchanges(self, version): self.modecache = {} diff --git a/hgext/convert/gnuarch.py b/hgext/convert/gnuarch.py --- a/hgext/convert/gnuarch.py +++ b/hgext/convert/gnuarch.py @@ -54,7 +54,6 @@ class gnuarch_source(converter_source, c self.changes = {} self.parents = {} self.tags = {} - self.modecache = {} self.catlogparser = Parser() self.locale = locale.getpreferredencoding() self.archives = [] @@ -142,16 +141,9 @@ class gnuarch_source(converter_source, c if not os.path.exists(os.path.join(self.tmppath, name)): raise IOError - data, mode = self._getfile(name, rev) - self.modecache[(name, rev)] = mode - - return data - - def getmode(self, name, rev): - return self.modecache[(name, rev)] + return self._getfile(name, rev) def getchanges(self, rev): - self.modecache = {} self._update(rev) changes = [] copies = {} diff --git a/hgext/convert/hg.py b/hgext/convert/hg.py --- a/hgext/convert/hg.py +++ b/hgext/convert/hg.py @@ -134,11 +134,11 @@ class mercurial_sink(converter_sink): files = dict(files) def getfilectx(repo, memctx, f): v = files[f] - data = source.getfile(f, v) - e = source.getmode(f, v) + data, mode = source.getfile(f, v) if f == '.hgtags': data = self._rewritetags(source, revmap, data) - return context.memfilectx(f, data, 'l' in e, 'x' in e, copies.get(f)) + return context.memfilectx(f, data, 'l' in mode, 'x' in mode, + copies.get(f)) pl = [] for p in parents: @@ -266,13 +266,11 @@ class mercurial_source(converter_source) def getfile(self, name, rev): try: - return self.changectx(rev)[name].data() + fctx = self.changectx(rev)[name] + return fctx.data(), fctx.flags() except error.LookupError, err: raise IOError(err) - def getmode(self, name, rev): - return self.changectx(rev).manifest().flags(name) - def getchanges(self, rev): ctx = self.changectx(rev) parents = self.parents(ctx) diff --git a/hgext/convert/monotone.py b/hgext/convert/monotone.py --- a/hgext/convert/monotone.py +++ b/hgext/convert/monotone.py @@ -192,18 +192,16 @@ class monotone_source(converter_source, return (files.items(), copies) - def getmode(self, name, rev): - self.mtnloadmanifest(rev) - node, attr = self.files.get(name, (None, "")) - return attr - def getfile(self, name, rev): if not self.mtnisfile(name, rev): raise IOError() # file was deleted or renamed try: - return self.mtnrun("get_file_of", name, r=rev) + data = self.mtnrun("get_file_of", name, r=rev) except: raise IOError() # file was deleted or renamed + self.mtnloadmanifest(rev) + node, attr = self.files.get(name, (None, "")) + return data, attr def getcommit(self, rev): certs = self.mtngetcerts(rev) diff --git a/hgext/convert/p4.py b/hgext/convert/p4.py --- a/hgext/convert/p4.py +++ b/hgext/convert/p4.py @@ -41,7 +41,6 @@ class p4_source(converter_source): self.parent = {} self.encoding = "latin_1" self.depotname = {} # mapping from local name to depot name - self.modecache = {} self.re_type = re.compile( "([a-z]+)?(text|binary|symlink|apple|resource|unicode|utf\d+)" "(\+\w+)?$") @@ -183,17 +182,12 @@ class p4_source(converter_source): if mode is None: raise IOError(0, "bad stat") - self.modecache[(name, rev)] = mode - if keywords: contents = keywords.sub("$\\1$", contents) if mode == "l" and contents.endswith("\n"): contents = contents[:-1] - return contents - - def getmode(self, name, rev): - return self.modecache[(name, rev)] + return contents, mode def getchanges(self, rev): return self.files[rev], {} diff --git a/hgext/convert/subversion.py b/hgext/convert/subversion.py --- a/hgext/convert/subversion.py +++ b/hgext/convert/subversion.py @@ -371,19 +371,10 @@ class svn_source(converter_source): return self.heads - def getfile(self, file, rev): - data, mode = self._getfile(file, rev) - self.modecache[(file, rev)] = mode - return data - - def getmode(self, file, rev): - return self.modecache[(file, rev)] - def getchanges(self, rev): if self._changescache and self._changescache[0] == rev: return self._changescache[1] self._changescache = None - self.modecache = {} (paths, parents) = self.paths[rev] if parents: files, self.removed, copies = self.expandpaths(rev, paths, parents) @@ -826,10 +817,10 @@ class svn_source(converter_source): raise util.Abort(_('svn: branch has no revision %s') % to_revnum) raise - def _getfile(self, file, rev): + def getfile(self, file, rev): # TODO: ra.get_file transmits the whole file instead of diffs. if file in self.removed: - raise IOError() + raise IOError() mode = '' try: new_module, revnum = self.revsplit(rev)[1:] @@ -1100,12 +1091,11 @@ class svn_sink(converter_sink, commandli # Apply changes to working copy for f, v in files: try: - data = source.getfile(f, v) + data, mode = source.getfile(f, v) except IOError: self.delete.append(f) else: - e = source.getmode(f, v) - self.putfile(f, e, data) + self.putfile(f, mode, data) if f in copies: self.copies.append([copies[f], f]) files = [f[0] for f in files]