Exemple #1
0
 def test_symlink_detect_changes(self):
     left = inventory.InventoryLink('123', 'hello.c', ROOT_ID)
     left.text_sha1 = 123
     left.executable = True
     left.symlink_target='foo'
     right = inventory.InventoryLink('123', 'hello.c', ROOT_ID)
     right.text_sha1 = 321
     right.symlink_target='foo'
     self.assertEqual((False, False), left.detect_changes(right))
     self.assertEqual((False, False), right.detect_changes(left))
     left.symlink_target = 'different'
     self.assertEqual((True, False), left.detect_changes(right))
     self.assertEqual((True, False), right.detect_changes(left))
Exemple #2
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
Exemple #3
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
Exemple #4
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
Exemple #5
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)
Exemple #6
0
 def test_link_has_text(self):
     link = inventory.InventoryLink('123', 'hello.c', ROOT_ID)
     self.failIf(link.has_text())
Exemple #7
0
 def test_link_kind_character(self):
     dir = inventory.InventoryLink('123', 'hello.c', ROOT_ID)
     self.assertEqual(dir.kind_character(), '')
Exemple #8
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