def test_path_swap(self): # test a A->B and B->A path swap. old_revid = 'old-parent' basis_shape = Inventory(root_id=None) self.add_dir(basis_shape, old_revid, 'root-id', None, '') self.add_dir(basis_shape, old_revid, 'dir-id-A', 'root-id', 'A') self.add_dir(basis_shape, old_revid, 'dir-id-B', 'root-id', 'B') self.add_link(basis_shape, old_revid, 'link-id-C', 'root-id', 'C', 'C') self.add_link(basis_shape, old_revid, 'link-id-D', 'root-id', 'D', 'D') self.add_file(basis_shape, old_revid, 'file-id-E', 'root-id', 'E', '1' * 32, 12) self.add_file(basis_shape, old_revid, 'file-id-F', 'root-id', 'F', '2' * 32, 24) new_revid = 'new-parent' new_shape = Inventory(root_id=None) self.add_new_root(new_shape, old_revid, new_revid) self.add_dir(new_shape, new_revid, 'dir-id-A', 'root-id', 'B') self.add_dir(new_shape, new_revid, 'dir-id-B', 'root-id', 'A') self.add_link(new_shape, new_revid, 'link-id-C', 'root-id', 'D', 'C') self.add_link(new_shape, new_revid, 'link-id-D', 'root-id', 'C', 'D') self.add_file(new_shape, new_revid, 'file-id-E', 'root-id', 'F', '1' * 32, 12) self.add_file(new_shape, new_revid, 'file-id-F', 'root-id', 'E', '2' * 32, 24) self.assertTransitionFromBasisToShape(basis_shape, old_revid, new_shape, new_revid)
def test_kind_changes(self): def do_file(inv, revid): self.add_file(inv, revid, 'path-id', 'root-id', 'path', '1' * 32, 12) def do_link(inv, revid): self.add_link(inv, revid, 'path-id', 'root-id', 'path', 'target') def do_dir(inv, revid): self.add_dir(inv, revid, 'path-id', 'root-id', 'path') for old_factory in (do_file, do_link, do_dir): for new_factory in (do_file, do_link, do_dir): if old_factory == new_factory: continue old_revid = 'old-parent' basis_shape = Inventory(root_id=None) self.add_dir(basis_shape, old_revid, 'root-id', None, '') old_factory(basis_shape, old_revid) new_revid = 'new-parent' new_shape = Inventory(root_id=None) self.add_new_root(new_shape, old_revid, new_revid) new_factory(new_shape, new_revid) self.assertTransitionFromBasisToShape(basis_shape, old_revid, new_shape, new_revid)
def test_empty_delta_to_lines(self): old_inv = Inventory(None) new_inv = Inventory(None) delta = new_inv._make_delta(old_inv) serializer = inventory_delta.InventoryDeltaSerializer( versioned_root=True, tree_references=True) self.assertEqual( StringIO(empty_lines).readlines(), serializer.delta_to_lines(NULL_REVISION, NULL_REVISION, delta))
def test_richroot_unversioned_root_errors(self): old_inv = Inventory(None) new_inv = Inventory(None) root = new_inv.make_entry('directory', '', None, 'TREE_ROOT') new_inv.add(root) delta = new_inv._make_delta(old_inv) serializer = inventory_delta.InventoryDeltaSerializer( versioned_root=True, tree_references=True) err = self.assertRaises(InventoryDeltaError, serializer.delta_to_lines, NULL_REVISION, 'entry-version', delta) self.assertEqual(str(err), 'no version for fileid TREE_ROOT')
def test_nonrichroot_versioned_root_errors(self): old_inv = Inventory(None) new_inv = Inventory(None) root = new_inv.make_entry('directory', '', None, 'TREE_ROOT') root.revision = 'a@e\xc3\xa5ample.com--2004' new_inv.add(root) delta = new_inv._make_delta(old_inv) serializer = inventory_delta.InventoryDeltaSerializer( versioned_root=False, tree_references=True) err = self.assertRaises(InventoryDeltaError, serializer.delta_to_lines, NULL_REVISION, 'entry-version', delta) self.assertStartsWith(str(err), 'Version present for / in TREE_ROOT')
def test_move_to_added_dir(self): old_revid = 'old-parent' basis_shape = Inventory(root_id=None) self.add_dir(basis_shape, old_revid, 'root-id', None, '') self.add_link(basis_shape, old_revid, 'link-id-B', 'root-id', 'B', 'C') new_revid = 'new-parent' new_shape = Inventory(root_id=None) self.add_new_root(new_shape, old_revid, new_revid) self.add_dir(new_shape, new_revid, 'dir-id-A', 'root-id', 'A') self.add_link(new_shape, new_revid, 'link-id-B', 'dir-id-A', 'B', 'C') self.assertTransitionFromBasisToShape(basis_shape, old_revid, new_shape, new_revid)
def test_root_only_to_lines(self): old_inv = Inventory(None) new_inv = Inventory(None) root = new_inv.make_entry('directory', '', None, 'an-id') root.revision = 'a@e\xc3\xa5ample.com--2004' new_inv.add(root) delta = new_inv._make_delta(old_inv) serializer = inventory_delta.InventoryDeltaSerializer( versioned_root=True, tree_references=True) self.assertEqual( StringIO(root_only_lines).readlines(), serializer.delta_to_lines(NULL_REVISION, 'entry-version', delta))
def test_file_content_change(self): old_revid = 'old-parent' basis_shape = Inventory(root_id=None) self.add_dir(basis_shape, old_revid, 'root-id', None, '') self.add_file(basis_shape, old_revid, 'file-id', 'root-id', 'file', '1' * 32, 12) new_revid = 'new-parent' new_shape = Inventory(root_id=None) self.add_new_root(new_shape, old_revid, new_revid) self.add_file(new_shape, new_revid, 'file-id', 'root-id', 'file', '2' * 32, 24) self.assertTransitionFromBasisToShape(basis_shape, old_revid, new_shape, new_revid)
def test_link_content_change(self): old_revid = 'old-parent' basis_shape = Inventory(root_id=None) self.add_dir(basis_shape, old_revid, 'root-id', None, '') self.add_link(basis_shape, old_revid, 'link-id', 'root-id', 'link', 'old-target') new_revid = 'new-parent' new_shape = Inventory(root_id=None) self.add_new_root(new_shape, old_revid, new_revid) self.add_link(new_shape, new_revid, 'link-id', 'root-id', 'link', 'new-target') self.assertTransitionFromBasisToShape(basis_shape, old_revid, new_shape, new_revid)
def test_unversioned_non_root_errors(self): old_inv = Inventory(None) new_inv = Inventory(None) root = new_inv.make_entry('directory', '', None, 'TREE_ROOT') root.revision = 'a@e\xc3\xa5ample.com--2004' new_inv.add(root) non_root = new_inv.make_entry('directory', 'foo', root.file_id, 'id') new_inv.add(non_root) delta = new_inv._make_delta(old_inv) serializer = inventory_delta.InventoryDeltaSerializer( versioned_root=True, tree_references=True) err = self.assertRaises(InventoryDeltaError, serializer.delta_to_lines, NULL_REVISION, 'entry-version', delta) self.assertEqual(str(err), 'no version for fileid id')
def test_no_parents_full_tree(self): """Test doing a regular initial commit with files and dirs.""" basis_shape = Inventory(root_id=None) # empty tree revid = 'new-parent' new_shape = Inventory(root_id=None) self.add_dir(new_shape, revid, 'root-id', None, '') self.add_link(new_shape, revid, 'link-id', 'root-id', 'link', 'target') self.add_file(new_shape, revid, 'file-id', 'root-id', 'file', '1' * 32, 12) self.add_dir(new_shape, revid, 'dir-id', 'root-id', 'dir') self.add_file(new_shape, revid, 'subfile-id', 'dir-id', 'subfile', '2' * 32, 24) self.assertTransitionFromBasisToShape(basis_shape, None, new_shape, revid)
def test_name_changed(self): # test that when the only change to an entry is its name changing that # it is handled correctly (that is it keeps the same parent id) old_revid = 'old-parent' basis_shape = Inventory(root_id=None) self.add_dir(basis_shape, old_revid, 'root-id', None, '') self.add_dir(basis_shape, old_revid, 'parent-id', 'root-id', 'origdir') self.add_dir(basis_shape, old_revid, 'dir-id', 'parent-id', 'olddir') new_revid = 'new-parent' new_shape = Inventory(root_id=None) self.add_new_root(new_shape, old_revid, new_revid) self.add_dir(new_shape, new_revid, 'parent-id', 'root-id', 'newdir') self.add_dir(new_shape, new_revid, 'dir-id', 'parent-id', 'newdir') self.assertTransitionFromBasisToShape(basis_shape, old_revid, new_shape, new_revid)
def test__write_inventory(self): # The private interface _write_inventory is currently used by transform. tree = self.make_branch_and_tree('.') # if we write write an inventory then do a walkdirs we should get back # missing entries, and actual, and unknowns as appropriate. self.build_tree(['present', 'unknown']) inventory = Inventory(tree.get_root_id()) inventory.add_path('missing', 'file', 'missing-id') inventory.add_path('present', 'file', 'present-id') # there is no point in being able to write an inventory to an unlocked # tree object - its a low level api not a convenience api. tree.lock_write() tree._write_inventory(inventory) tree.unlock() tree.lock_read() try: present_stat = os.lstat('present') unknown_stat = os.lstat('unknown') expected_results = [(('', tree.get_root_id()), [ ('missing', 'missing', 'unknown', None, 'missing-id', 'file'), ('present', 'present', 'file', present_stat, 'present-id', 'file'), ('unknown', 'unknown', 'file', unknown_stat, None, None), ])] self.assertEqual(expected_results, list(tree.walkdirs())) finally: tree.unlock()
def test_text_from_ghost_revision(self): repo = self.make_repository('text-from-ghost') inv = Inventory(revision_id='final-revid') inv.root.revision = 'root-revid' ie = inv.add_path('bla', 'file', 'myfileid') ie.revision = 'ghostrevid' ie.text_size = 42 ie.text_sha1 = "bee68c8acd989f5f1765b4660695275948bf5c00" rev = bzrlib.revision.Revision(timestamp=0, timezone=None, committer="Foo Bar <*****@*****.**>", message="Message", revision_id='final-revid') repo.lock_write() try: repo.start_write_group() try: repo.add_revision('final-revid', rev, inv) try: repo.texts.add_lines(('myfileid', 'ghostrevid'), (('myfileid', 'ghost-text-parent'), ), ["line1\n", "line2\n"]) except errors.RevisionNotPresent: raise TestSkipped("text ghost parents not supported") if repo.supports_rich_root(): root_id = inv.root.file_id repo.texts.add_lines((inv.root.file_id, inv.root.revision), [], []) finally: repo.commit_write_group() finally: repo.unlock() repo.reconcile(thorough=True)
def test_does_something_reconcile(self): t = bzrdir.BzrDir.create_standalone_workingtree('.') # an empty inventory with no revision will trigger reconciliation. repo = t.branch.repository inv = Inventory(revision_id='missing') inv.root.revision = 'missing' repo.lock_write() repo.start_write_group() repo.add_inventory('missing', inv, []) repo.commit_write_group() repo.unlock() (out, err) = self.run_bzr('reconcile') if repo._reconcile_backsup_inventory: does_backup_text = ("Backup Inventory created.\n" "Inventory regenerated.\n") else: does_backup_text = "" expected = ( "Reconciling branch %s\n" "revision_history ok.\n" "Reconciling repository %s\n" "%s" "Reconciliation complete.\n" % (t.branch.base, t.bzrdir.root_transport.base, does_backup_text)) self.assertEqualDiff(expected, out) self.assertEqualDiff(err, "")
def test_parent_deleted_child_renamed(self): # test a A->None and A/B->A. old_revid = 'old-parent' basis_shape = Inventory(root_id=None) self.add_dir(basis_shape, old_revid, 'root-id', None, '') self.add_dir(basis_shape, old_revid, 'dir-id-A', 'root-id', 'A') self.add_dir(basis_shape, old_revid, 'dir-id-B', 'dir-id-A', 'B') self.add_link(basis_shape, old_revid, 'link-id-C', 'dir-id-B', 'C', 'C') new_revid = 'new-parent' new_shape = Inventory(root_id=None) self.add_new_root(new_shape, old_revid, new_revid) self.add_dir(new_shape, new_revid, 'dir-id-B', 'root-id', 'A') self.add_link(new_shape, old_revid, 'link-id-C', 'dir-id-B', 'C', 'C') self.assertTransitionFromBasisToShape(basis_shape, old_revid, new_shape, new_revid)
def test_tree_reference(self): s_v5 = bzrlib.xml5.serializer_v5 s_v6 = bzrlib.xml6.serializer_v6 s_v7 = xml7.serializer_v7 inv = Inventory('tree-root-321', revision_id='rev-outer') inv.root.revision = 'root-rev' inv.add( inventory.TreeReference('nested-id', 'nested', 'tree-root-321', 'rev-outer', 'rev-inner')) self.assertRaises(errors.UnsupportedInventoryKind, s_v5.write_inventory_to_string, inv) self.assertRaises(errors.UnsupportedInventoryKind, s_v6.write_inventory_to_string, inv) txt = s_v7.write_inventory_to_string(inv) lines = s_v7.write_inventory_to_lines(inv) self.assertEqual(bzrlib.osutils.split_lines(txt), lines) inv2 = s_v7.read_inventory_from_string(txt) self.assertEqual('tree-root-321', inv2['nested-id'].parent_id) self.assertEqual('rev-outer', inv2['nested-id'].revision) self.assertEqual('rev-inner', inv2['nested-id'].reference_revision) self.assertRaises(errors.UnsupportedInventoryKind, s_v6.read_inventory_from_string, txt.replace('format="7"', 'format="6"')) self.assertRaises(errors.UnsupportedInventoryKind, s_v5.read_inventory_from_string, txt.replace('format="7"', 'format="5"'))
def test_add_files_to_empty_directory(self): old_revid = 'old-parent' basis_shape = Inventory(root_id=None) self.add_dir(basis_shape, old_revid, 'root-id', None, '') self.add_dir(basis_shape, old_revid, 'dir-id-A', 'root-id', 'A') new_revid = 'new-parent' new_shape = Inventory(root_id=None) self.add_new_root(new_shape, old_revid, new_revid) self.add_dir(new_shape, old_revid, 'dir-id-A', 'root-id', 'A') self.add_file(new_shape, new_revid, 'file-id-B', 'dir-id-A', 'B', '1' * 32, 24) self.assertTransitionFromBasisToShape(basis_shape, old_revid, new_shape, new_revid, set_current_inventory=False)
def test_removes(self): # test removing paths, including paths that are within other also # removed paths. old_revid = 'old-parent' basis_shape = Inventory(root_id=None) self.add_dir(basis_shape, old_revid, 'root-id', None, '') self.add_dir(basis_shape, old_revid, 'dir-id-A', 'root-id', 'A') self.add_link(basis_shape, old_revid, 'link-id-B', 'root-id', 'B', 'C') self.add_file(basis_shape, old_revid, 'file-id-C', 'root-id', 'C', '1' * 32, 12) self.add_file(basis_shape, old_revid, 'file-id-D', 'dir-id-A', 'D', '2' * 32, 24) new_revid = 'new-parent' new_shape = Inventory(root_id=None) self.add_new_root(new_shape, old_revid, new_revid) self.assertTransitionFromBasisToShape(basis_shape, old_revid, new_shape, new_revid)
def test_adds(self): # test adding paths and dirs, including adding to a newly added dir. old_revid = 'old-parent' basis_shape = Inventory(root_id=None) # with a root, so its a commit after the first. self.add_dir(basis_shape, old_revid, 'root-id', None, '') new_revid = 'new-parent' new_shape = Inventory(root_id=None) self.add_new_root(new_shape, old_revid, new_revid) self.add_dir(new_shape, new_revid, 'dir-id-A', 'root-id', 'A') self.add_link(new_shape, new_revid, 'link-id-B', 'root-id', 'B', 'C') self.add_file(new_shape, new_revid, 'file-id-C', 'root-id', 'C', '1' * 32, 12) self.add_file(new_shape, new_revid, 'file-id-D', 'dir-id-A', 'D', '2' * 32, 24) self.assertTransitionFromBasisToShape(basis_shape, old_revid, new_shape, new_revid)
def test_tree_reference_enabled(self): old_inv = Inventory(None) new_inv = Inventory(None) root = new_inv.make_entry('directory', '', None, 'TREE_ROOT') root.revision = 'a@e\xc3\xa5ample.com--2004' new_inv.add(root) non_root = new_inv.make_entry('tree-reference', 'foo', root.file_id, 'id') non_root.revision = 'changed' non_root.reference_revision = 'subtree-version' new_inv.add(non_root) delta = new_inv._make_delta(old_inv) serializer = inventory_delta.InventoryDeltaSerializer( versioned_root=True, tree_references=True) self.assertEqual( StringIO(reference_lines).readlines(), serializer.delta_to_lines(NULL_REVISION, 'entry-version', delta))
def test_move_moves_children_recursively(self): old_revid = 'old-parent' basis_shape = Inventory(root_id=None) self.add_dir(basis_shape, old_revid, 'root-id', None, '') self.add_dir(basis_shape, old_revid, 'dir-id-A', 'root-id', 'A') self.add_dir(basis_shape, old_revid, 'dir-id-B', 'dir-id-A', 'B') self.add_link(basis_shape, old_revid, 'link-id-C', 'dir-id-B', 'C', 'D') new_revid = 'new-parent' new_shape = Inventory(root_id=None) self.add_new_root(new_shape, old_revid, new_revid) # the moved path: self.add_dir(new_shape, new_revid, 'dir-id-A', 'root-id', 'B') # unmoved children. self.add_dir(new_shape, old_revid, 'dir-id-B', 'dir-id-A', 'B') self.add_link(new_shape, old_revid, 'link-id-C', 'dir-id-B', 'C', 'D') self.assertTransitionFromBasisToShape(basis_shape, old_revid, new_shape, new_revid)
def test_unversioned_root(self): old_inv = Inventory(None) new_inv = Inventory(None) root = new_inv.make_entry('directory', '', None, 'TREE_ROOT') # Implicit roots are considered modified in every revision. root.revision = 'entry-version' new_inv.add(root) delta = new_inv._make_delta(old_inv) serializer = inventory_delta.InventoryDeltaSerializer( versioned_root=False, tree_references=False) serialized_lines = serializer.delta_to_lines(NULL_REVISION, 'entry-version', delta) self.assertEqual( StringIO(root_only_unversioned).readlines(), serialized_lines) deserializer = inventory_delta.InventoryDeltaDeserializer() self.assertEqual( (NULL_REVISION, 'entry-version', False, False, delta), deserializer.parse_text_bytes(''.join(serialized_lines)))
def setUp(self): super(TestsNeedingReweave, self).setUp() t = get_transport(self.get_url()) # an empty inventory with no revision for testing with. repo = self.make_repository('inventory_without_revision') repo.lock_write() repo.start_write_group() inv = Inventory(revision_id='missing') inv.root.revision = 'missing' repo.add_inventory('missing', inv, []) repo.commit_write_group() repo.unlock() def add_commit(repo, revision_id, parent_ids): repo.lock_write() repo.start_write_group() inv = Inventory(revision_id=revision_id) inv.root.revision = revision_id root_id = inv.root.file_id sha1 = repo.add_inventory(revision_id, inv, parent_ids) repo.texts.add_lines((root_id, revision_id), [], []) rev = bzrlib.revision.Revision( timestamp=0, timezone=None, committer="Foo Bar <*****@*****.**>", message="Message", inventory_sha1=sha1, revision_id=revision_id) rev.parent_ids = parent_ids repo.add_revision(revision_id, rev) repo.commit_write_group() repo.unlock() # an empty inventory with no revision for testing with. # this is referenced by 'references_missing' to let us test # that all the cached data is correctly converted into ghost links # and the referenced inventory still cleaned. repo = self.make_repository('inventory_without_revision_and_ghost') repo.lock_write() repo.start_write_group() repo.add_inventory('missing', inv, []) repo.commit_write_group() repo.unlock() add_commit(repo, 'references_missing', ['missing']) # a inventory with no parents and the revision has parents.. # i.e. a ghost. repo = self.make_repository('inventory_one_ghost') add_commit(repo, 'ghost', ['the_ghost']) # a inventory with a ghost that can be corrected now. t.copy_tree('inventory_one_ghost', 'inventory_ghost_present') bzrdir_url = self.get_url('inventory_ghost_present') bzrdir = bzrlib.bzrdir.BzrDir.open(bzrdir_url) repo = bzrdir.open_repository() add_commit(repo, 'the_ghost', [])
def run_action(self, output): from bzrlib.add import AddAction from bzrlib.mutabletree import _FastPath inv = Inventory() stdout = StringIO() action = AddAction(to_file=stdout, should_print=bool(output)) self.apply_redirected(None, stdout, None, action, inv, None, _FastPath('path'), 'file') self.assertEqual(stdout.getvalue(), output)
def test_tree_reference_disabled(self): old_inv = Inventory(None) new_inv = Inventory(None) root = new_inv.make_entry('directory', '', None, 'TREE_ROOT') root.revision = 'a@e\xc3\xa5ample.com--2004' new_inv.add(root) non_root = new_inv.make_entry('tree-reference', 'foo', root.file_id, 'id') non_root.revision = 'changed' non_root.reference_revision = 'subtree-version' new_inv.add(non_root) delta = new_inv._make_delta(old_inv) serializer = inventory_delta.InventoryDeltaSerializer( versioned_root=True, tree_references=False) # we expect keyerror because there is little value wrapping this. # This test aims to prove that it errors more than how it errors. err = self.assertRaises(KeyError, serializer.delta_to_lines, NULL_REVISION, 'entry-version', delta) self.assertEqual(('tree-reference', ), err.args)
def setUp(self): super(TestCaseWithCorruptRepository, self).setUp() # a inventory with no parents and the revision has parents.. # i.e. a ghost. repo = self.make_repository('inventory_with_unnecessary_ghost') repo.lock_write() repo.start_write_group() inv = Inventory(revision_id='ghost') inv.root.revision = 'ghost' sha1 = repo.add_inventory('ghost', inv, []) rev = bzrlib.revision.Revision(timestamp=0, timezone=None, committer="Foo Bar <*****@*****.**>", message="Message", inventory_sha1=sha1, revision_id='ghost') rev.parent_ids = ['the_ghost'] try: repo.add_revision('ghost', rev) except (errors.NoSuchRevision, errors.RevisionNotPresent): raise TestNotApplicable("Cannot test with ghosts for this format.") inv = Inventory(revision_id='the_ghost') inv.root.revision = 'the_ghost' sha1 = repo.add_inventory('the_ghost', inv, []) rev = bzrlib.revision.Revision(timestamp=0, timezone=None, committer="Foo Bar <*****@*****.**>", message="Message", inventory_sha1=sha1, revision_id='the_ghost') rev.parent_ids = [] repo.add_revision('the_ghost', rev) # check its setup usefully inv_weave = repo.inventories possible_parents = (None, (('ghost', ), )) self.assertSubset( inv_weave.get_parent_map([('ghost', )])[('ghost', )], possible_parents) repo.commit_write_group() repo.unlock()
def test_unknown_kind_errors(self): old_inv = Inventory(None) new_inv = Inventory(None) root = new_inv.make_entry('directory', '', None, 'my-rich-root-id') root.revision = 'changed' new_inv.add(root) class StrangeInventoryEntry(inventory.InventoryEntry): kind = 'strange' non_root = StrangeInventoryEntry('id', 'foo', root.file_id) non_root.revision = 'changed' new_inv.add(non_root) delta = new_inv._make_delta(old_inv) serializer = inventory_delta.InventoryDeltaSerializer( versioned_root=True, tree_references=True) # we expect keyerror because there is little value wrapping this. # This test aims to prove that it errors more than how it errors. err = self.assertRaises(KeyError, serializer.delta_to_lines, NULL_REVISION, 'entry-version', delta) self.assertEqual(('strange', ), err.args)
def get_sample_inventory(self): inv = Inventory('tree-root-321', revision_id='rev_outer') inv.add(inventory.InventoryFile('file-id', 'file', 'tree-root-321')) inv.add(inventory.InventoryDirectory('dir-id', 'dir', 'tree-root-321')) inv.add(inventory.InventoryLink('link-id', 'link', 'tree-root-321')) inv['tree-root-321'].revision = 'rev_outer' inv['dir-id'].revision = 'rev_outer' inv['file-id'].revision = 'rev_outer' inv['file-id'].text_sha1 = 'A' inv['file-id'].text_size = 1 inv['link-id'].revision = 'rev_outer' inv['link-id'].symlink_target = 'a' return inv
def _unpack_inventory(self, elt, revision_id=None): """Construct from XML Element :param revision_id: Ignored parameter used by xml5. """ root_id = elt.get('file_id') or ROOT_ID inv = Inventory(root_id) for e in elt: ie = self._unpack_entry(e) if ie.parent_id == ROOT_ID: ie.parent_id = root_id inv.add(ie) return inv