Esempio n. 1
0
 def test_dir_detect_changes(self):
     left = inventory.InventoryDirectory('123', 'hello.c', ROOT_ID)
     left.text_sha1 = 123
     left.executable = True
     left.symlink_target='foo'
     right = inventory.InventoryDirectory('123', 'hello.c', ROOT_ID)
     right.text_sha1 = 321
     right.symlink_target='bar'
     self.assertEqual((False, False), left.detect_changes(right))
     self.assertEqual((False, False), right.detect_changes(left))
Esempio n. 2
0
    def _unpack_entry(self, elt):
        ## original format inventories don't have a parent_id for
        ## nodes in the root directory, but it's cleaner to use one
        ## internally.
        parent_id = elt.get('parent_id')
        if parent_id is None:
            parent_id = ROOT_ID

        kind = elt.get('kind')
        if kind == 'directory':
            ie = inventory.InventoryDirectory(elt.get('file_id'),
                                              elt.get('name'), parent_id)
        elif kind == 'file':
            ie = inventory.InventoryFile(elt.get('file_id'), elt.get('name'),
                                         parent_id)
            ie.text_id = elt.get('text_id')
            ie.text_sha1 = elt.get('text_sha1')
            v = elt.get('text_size')
            ie.text_size = v and int(v)
        elif kind == 'symlink':
            ie = inventory.InventoryLink(elt.get('file_id'), elt.get('name'),
                                         parent_id)
            ie.symlink_target = elt.get('symlink_target')
        else:
            raise BzrError("unknown kind %r" % kind)

        ## mutter("read inventoryentry: %r", elt.attrib)

        return ie
Esempio n. 3
0
    def _unpack_entry(self, elt):
        kind = elt.tag
        if not InventoryEntry.versionable_kind(kind):
            raise AssertionError('unsupported entry kind %s' % kind)

        get_cached = _get_utf8_or_ascii

        parent_id = elt.get('parent_id')
        if parent_id is not None:
            parent_id = get_cached(parent_id)
        file_id = get_cached(elt.get('file_id'))

        if kind == 'directory':
            ie = inventory.InventoryDirectory(file_id, elt.get('name'),
                                              parent_id)
        elif kind == 'file':
            ie = inventory.InventoryFile(file_id, elt.get('name'), parent_id)
            ie.text_sha1 = elt.get('text_sha1')
            if elt.get('executable') == 'yes':
                ie.executable = True
            v = elt.get('text_size')
            ie.text_size = v and int(v)
        elif kind == 'symlink':
            ie = inventory.InventoryLink(file_id, elt.get('name'), parent_id)
            ie.symlink_target = elt.get('symlink_target')
        else:
            raise errors.UnsupportedInventoryKind(kind)
        revision = elt.get('revision')
        if revision is not None:
            revision = get_cached(revision)
        ie.revision = revision

        return ie
Esempio n. 4
0
 def test_revision_tree(self):
     wt = self.make_branch_and_tree('.')
     wt.set_root_id('fixed-root')
     wt.commit('lala!', rev_id='revision-1', allow_pointless=True)
     tree = wt.branch.repository.revision_tree('revision-1')
     tree.lock_read()
     try:
         self.assertEqual('revision-1',
                          tree.get_file_revision(tree.get_root_id()))
         expected = inventory.InventoryDirectory('fixed-root', '', None)
         expected.revision = 'revision-1'
         self.assertEqual([('', 'V', 'directory', 'fixed-root', expected)],
                          list(tree.list_files(include_root=True)))
     finally:
         tree.unlock()
     tree = self.callDeprecated([
         'NULL_REVISION should be used for the null'
         ' revision instead of None, as of bzr 0.91.'
     ], wt.branch.repository.revision_tree, None)
     tree.lock_read()
     try:
         self.assertEqual([], list(tree.list_files(include_root=True)))
     finally:
         tree.unlock()
     tree = wt.branch.repository.revision_tree(_mod_revision.NULL_REVISION)
     tree.lock_read()
     try:
         self.assertEqual([], list(tree.list_files(include_root=True)))
     finally:
         tree.unlock()
Esempio n. 5
0
    def test_replace_root(self):
        wt = self.make_branch_and_tree('.')
        wt.lock_write()
        self.addCleanup(wt.unlock)

        root_id = wt.get_root_id()
        wt.apply_inventory_delta([('', None, root_id, None),
            (None, '', 'root-id',
             inventory.InventoryDirectory('root-id', '', None))])
Esempio n. 6
0
    def test_rename_swap(self):
        """Test the swap-names edge case.

        foo and bar should swap names, but retain their children.  If this
        works, any simpler rename ought to work.
        """
        wt = self.make_branch_and_tree('.')
        wt.lock_write()
        root_id = wt.get_root_id()
        self.addCleanup(wt.unlock)
        self.build_tree(['foo/', 'foo/bar', 'baz/', 'baz/qux'])
        wt.add(['foo', 'foo/bar', 'baz', 'baz/qux'],
               ['foo-id', 'bar-id', 'baz-id', 'qux-id'])
        wt.apply_inventory_delta([('foo', 'baz', 'foo-id',
            inventory.InventoryDirectory('foo-id', 'baz', root_id)),
            ('baz', 'foo', 'baz-id',
            inventory.InventoryDirectory('baz-id', 'foo', root_id))])
        self.assertEqual('baz/bar', wt.id2path('bar-id'))
        self.assertEqual('foo/qux', wt.id2path('qux-id'))
Esempio n. 7
0
 def test_add(self):
     wt = self.make_branch_and_tree('.')
     wt.lock_write()
     self.addCleanup(wt.unlock)
     root_id = wt.get_root_id()
     wt.apply_inventory_delta([(None, 'bar/foo', 'foo-id',
         inventory.InventoryFile('foo-id', 'foo', parent_id='bar-id')),
         (None, 'bar', 'bar-id', inventory.InventoryDirectory('bar-id',
         'bar', parent_id=root_id))])
     self.assertEqual('bar/foo', wt.id2path('foo-id'))
     self.assertEqual('bar', wt.id2path('bar-id'))
Esempio n. 8
0
 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
Esempio n. 9
0
 def test_rename_dir_with_children_with_children(self):
     wt = self.make_branch_and_tree('.')
     wt.lock_write()
     root_id = wt.get_root_id()
     self.addCleanup(wt.unlock)
     self.build_tree(['foo/', 'foo/bar/', 'foo/bar/baz'])
     wt.add(['foo', 'foo/bar', 'foo/bar/baz'],
            ['foo-id', 'bar-id', 'baz-id'])
     wt.apply_inventory_delta([('foo', 'quux', 'foo-id',
         inventory.InventoryDirectory('foo-id', 'quux', root_id))])
     # foo/bar/baz should have been followed the rename of its parent's
     # parent to quux/bar/baz
     self.assertEqual('quux/bar/baz', wt.id2path('baz-id'))
Esempio n. 10
0
    def test_update_basis_with_invalid_delta(self):
        """When given an invalid delta, it should abort, and not be saved."""
        self.build_tree(['dir/', 'dir/file'])
        tree = self.create_wt4()
        tree.lock_write()
        self.addCleanup(tree.unlock)
        tree.add(['dir', 'dir/file'], ['dir-id', 'file-id'])
        first_revision_id = tree.commit('init')

        root_id = tree.path2id('')
        state = tree.current_dirstate()
        state._read_dirblocks_if_needed()
        self.assertEqual([
            ('', [(('', '', root_id), ['d', 'd'])]),
            ('', [(('', 'dir', 'dir-id'), ['d', 'd'])]),
            ('dir', [(('dir', 'file', 'file-id'), ['f', 'f'])]),
        ], self.get_simple_dirblocks(state))

        tree.remove(['dir/file'])
        self.assertEqual([
            ('', [(('', '', root_id), ['d', 'd'])]),
            ('', [(('', 'dir', 'dir-id'), ['d', 'd'])]),
            ('dir', [(('dir', 'file', 'file-id'), ['a', 'f'])]),
        ], self.get_simple_dirblocks(state))
        # Make sure the removal is written to disk
        tree.flush()

        # self.assertRaises(Exception, tree.update_basis_by_delta,
        new_dir = inventory.InventoryDirectory('dir-id', 'new-dir', root_id)
        new_dir.revision = 'new-revision-id'
        new_file = inventory.InventoryFile('file-id', 'new-file', root_id)
        new_file.revision = 'new-revision-id'
        self.assertRaises(
            errors.InconsistentDelta, tree.update_basis_by_delta,
            'new-revision-id', [
                ('dir', 'new-dir', 'dir-id', new_dir),
                ('dir/file', 'new-dir/new-file', 'file-id', new_file),
            ])
        del state

        # Now when we re-read the file it should not have been modified
        tree.unlock()
        tree.lock_read()
        self.assertEqual(first_revision_id, tree.last_revision())
        state = tree.current_dirstate()
        state._read_dirblocks_if_needed()
        self.assertEqual([
            ('', [(('', '', root_id), ['d', 'd'])]),
            ('', [(('', 'dir', 'dir-id'), ['d', 'd'])]),
            ('dir', [(('dir', 'file', 'file-id'), ['a', 'f'])]),
        ], self.get_simple_dirblocks(state))
Esempio n. 11
0
    def test_child_rename_ordering(self):
        """Test the rename-parent, move child edge case.

        (A naive implementation may move the parent first, and then be
         unable to find the child.)
        """
        wt = self.make_branch_and_tree('.')
        root_id = wt.get_root_id()
        self.build_tree(['dir/', 'dir/child', 'other/'])
        wt.add(['dir', 'dir/child', 'other'],
               ['dir-id', 'child-id', 'other-id'])
        # this delta moves dir-id to dir2 and reparents
        # child-id to a parent of other-id
        wt.apply_inventory_delta([('dir', 'dir2', 'dir-id',
            inventory.InventoryDirectory('dir-id', 'dir2', root_id)),
            ('dir/child', 'other/child', 'child-id',
             inventory.InventoryFile('child-id', 'child', 'other-id'))])
        self.assertEqual('dir2', wt.id2path('dir-id'))
        self.assertEqual('other/child', wt.id2path('child-id'))
Esempio n. 12
0
 def _build_inventory(self, tree_id, ie, path):
     assert isinstance(path, str)
     tree = self._repository._git.tree(tree_id)
     for mode, name, hexsha in tree.entries():
         basename = name.decode("utf-8")
         if path == "":
             child_path = name
         else:
             child_path = urlutils.join(path, name)
         file_id = self.mapping.generate_file_id(child_path)
         entry_kind = (mode & 0700000) / 0100000
         if entry_kind == 0:
             child_ie = inventory.InventoryDirectory(
                 file_id, basename, ie.file_id)
         elif entry_kind == 1:
             file_kind = (mode & 070000) / 010000
             b = self._repository._git.get_blob(hexsha)
             if file_kind == 0:
                 child_ie = inventory.InventoryFile(file_id, basename,
                                                    ie.file_id)
                 child_ie.text_sha1 = osutils.sha_string(b.data)
             elif file_kind == 2:
                 child_ie = inventory.InventoryLink(file_id, basename,
                                                    ie.file_id)
                 child_ie.text_sha1 = osutils.sha_string("")
             else:
                 raise AssertionError("Unknown file kind, perms=%o." %
                                      (mode, ))
             child_ie.text_id = b.id
             child_ie.text_size = len(b.data)
         else:
             raise AssertionError("Unknown blob kind, perms=%r." % (mode, ))
         fs_mode = mode & 0777
         child_ie.executable = bool(fs_mode & 0111)
         child_ie.revision = self.revision_id
         self._inventory.add(child_ie)
         if entry_kind == 0:
             self._build_inventory(hexsha, child_ie, child_path)
Esempio n. 13
0
 def test_directory_has_text(self):
     dir = inventory.InventoryDirectory('123', 'hello.c', ROOT_ID)
     self.failIf(dir.has_text())
Esempio n. 14
0
 def test_dir_kind_character(self):
     dir = inventory.InventoryDirectory('123', 'hello.c', ROOT_ID)
     self.assertEqual(dir.kind_character(), '/')
 def test_comparison_data_does_not_autodetect_subtree(self):
     tree = self.prepare_with_subtree()
     ie = inventory.InventoryDirectory('subtree-id', 'subtree',
                                       tree.path2id(''))
     self.assertEqual('directory', tree._comparison_data(ie, 'subtree')[0])
Esempio n. 16
0
def unpack_inventory_entry(elt, entry_cache=None, return_from_cache=False):
    elt_get = elt.get
    file_id = elt_get('file_id')
    revision = elt_get('revision')
    # Check and see if we have already unpacked this exact entry
    # Some timings for "repo.revision_trees(last_100_revs)"
    #               bzr     mysql
    #   unmodified  4.1s    40.8s
    #   using lru   3.5s
    #   using fifo  2.83s   29.1s
    #   lru._cache  2.8s
    #   dict        2.75s   26.8s
    #   inv.add     2.5s    26.0s
    #   no_copy     2.00s   20.5s
    #   no_c,dict   1.95s   18.0s
    # Note that a cache of 10k nodes is more than sufficient to hold all of
    # the inventory for the last 100 revs for bzr, but not for mysql (20k
    # is enough for mysql, which saves the same 2s as using a dict)

    # Breakdown of mysql using time.clock()
    #   4.1s    2 calls to element.get for file_id, revision_id
    #   4.5s    cache_hit lookup
    #   7.1s    InventoryFile.copy()
    #   2.4s    InventoryDirectory.copy()
    #   0.4s    decoding unique entries
    #   1.6s    decoding entries after FIFO fills up
    #   0.8s    Adding nodes to FIFO (including flushes)
    #   0.1s    cache miss lookups
    # Using an LRU cache
    #   4.1s    2 calls to element.get for file_id, revision_id
    #   9.9s    cache_hit lookup
    #   10.8s   InventoryEntry.copy()
    #   0.3s    cache miss lookus
    #   1.2s    decoding entries
    #   1.0s    adding nodes to LRU
    if entry_cache is not None and revision is not None:
        key = (file_id, revision)
        try:
            # We copy it, because some operations may mutate it
            cached_ie = entry_cache[key]
        except KeyError:
            pass
        else:
            # Only copying directory entries drops us 2.85s => 2.35s
            if return_from_cache:
                if cached_ie.kind == 'directory':
                    return cached_ie.copy()
                return cached_ie
            return cached_ie.copy()

    kind = elt.tag
    if not inventory.InventoryEntry.versionable_kind(kind):
        raise AssertionError('unsupported entry kind %s' % kind)

    file_id = get_utf8_or_ascii(file_id)
    if revision is not None:
        revision = get_utf8_or_ascii(revision)
    parent_id = elt_get('parent_id')
    if parent_id is not None:
        parent_id = get_utf8_or_ascii(parent_id)

    if kind == 'directory':
        ie = inventory.InventoryDirectory(file_id, elt_get('name'), parent_id)
    elif kind == 'file':
        ie = inventory.InventoryFile(file_id, elt_get('name'), parent_id)
        ie.text_sha1 = elt_get('text_sha1')
        if elt_get('executable') == 'yes':
            ie.executable = True
        v = elt_get('text_size')
        ie.text_size = v and int(v)
    elif kind == 'symlink':
        ie = inventory.InventoryLink(file_id, elt_get('name'), parent_id)
        ie.symlink_target = elt_get('symlink_target')
    elif kind == 'tree-reference':
        file_id = elt.attrib['file_id']
        name = elt.attrib['name']
        parent_id = elt.attrib['parent_id']
        revision = elt.get('revision')
        reference_revision = elt.get('reference_revision')
        ie = inventory.TreeReference(file_id, name, parent_id, revision,
                                     reference_revision)
    else:
        raise errors.UnsupportedInventoryKind(kind)
    ie.revision = revision
    if revision is not None and entry_cache is not None:
        # We cache a copy() because callers like to mutate objects, and
        # that would cause the item in cache to mutate as well.
        # This has a small effect on many-inventory performance, because
        # the majority fraction is spent in cache hits, not misses.
        entry_cache[key] = ie.copy()

    return ie