def get_manifest_text_by_revid(self, revid): try: return self._get_cached_manifest_text(revid) except KeyError: pass (manifest, flags) = self.get_manifest_and_flags_by_revid(revid) self.remember_manifest(revid, self.repo.get_parent_map([revid])[revid], (manifest, flags)) fulltext = format_manifest(manifest, flags) self.remember_manifest_text(revid, self.repo.get_parent_map([revid])[revid], fulltext) return fulltext
def _reconstruct_manifest_and_flags_by_revid(self, revid): tree = self.repo.revision_tree(revid) lookup_text_node = [] rev = self.repo.get_revision(revid) base_tree = list(self.repo.revision_trees(rev.parent_ids[:2])) for p in rev.parent_ids[:2]: parent_manifest = self.get_manifest_and_flags_by_revid(p)[0] lookup_text_node.append(parent_manifest.__getitem__) while len(lookup_text_node) < 2: lookup_text_node.append(lambda path: mercurial.node.nullid) (manifest, flags) = manifest_and_flags_from_tree(base_tree, tree, self.mapping, lookup_text_node)[:2] self.remember_manifest(revid, rev.parent_ids, (manifest, flags)) self.remember_manifest_text(revid, rev.parent_ids, format_manifest(manifest, flags)) return (manifest, flags)
def dinventories(repo, mapping, revids, manifest_ids, files, overlay, texts, fileids, lossy=True): """Generate manifests from a series of revision trees. :param repo: Bazaar repository to fetch revisions from :param revids: Revision ids to yield manifests for (returned in same order) :param manifest_ids: Dictionary with revid -> file id mappings for known manifests. Used to look up parent manifests not processed :param files: Dictionary to store mercurial file dictionaries in, by revid :param overlay: Mercurial overlay object for the Bazaar repository :param texts: Dictionary with node -> (fileid, revision) tuples :param fileids: Dictionary mapping revision ids to file id lookup dictionaries, for any "unusual" file ids (not matching that predicted by the mapping). (only relevant for non-lossy conversions) :param lossy: Whether or not to do a lossy conversion. """ def get_manifest(revid): if revid in manifest_ids: try: return manifests[manifest_ids[revid]] except KeyError: pass return overlay.get_manifest_and_flags_by_revid(revid) if revids == []: return skip_revid = revids[0] if revids[0] == _mod_revision.NULL_REVISION: yield "", (mercurial.node.nullid, mercurial.node.nullid), revids[0] revids = revids[1:] manifests = {} # TODO: Very naive and slow: for tree in repo.revision_trees(revids): revid = tree.get_revision_id() rev = repo.get_revision(revid) lookup_text_node = [] for parent in rev.parent_ids[:2]: lookup_text_node.append(get_manifest(parent)[0].__getitem__) while len(lookup_text_node) < 2: lookup_text_node.append(lambda path: mercurial.node.nullid) # TODO: This refetches the parent trees, which we'll likely have seen # earlier in this loop. parent_trees = list(repo.revision_trees(rev.parent_ids[:2])) (manifest, flags, extrafileids) = manifest_and_flags_from_tree(parent_trees, tree, mapping, lookup_text_node) fileids[revid] = extrafileids manifests[revid] = (manifest, flags) try: base_tree = parent_trees[0] except IndexError: base_tree = repo.revision_tree(_mod_revision.NULL_REVISION) files[revid] = files_from_delta(tree.changes_from(base_tree), tree, revid) # Avoid sending texts for first revision, it's listed so we get the # base text for the manifest delta's. if revid != skip_revid: for p in files[revid]: fileid = tree.path2id(p) if fileid is not None: # FIXME: This is probably not correct, as 'files' # don't include new revisions that don't include changes # (but are e.g. relevant for parents) texts[p].add((fileid, tree.get_file_revision(p))) text = format_manifest(manifest, flags) node_parents = as_hg_parents(rev.parent_ids, manifest_ids.__getitem__) manifest_id = hghash(text, node_parents[0], node_parents[1]) manifest_ids[revid] = manifest_id if 'check' in debug.debug_flags: assert mapping.export_revision(rev)[0] in (None, manifest_id) yield text, node_parents, revid