Пример #1
0
 def test_set_chunks(self):
     b = Blob()
     b.chunked = [b'te', b'st', b' 5\n']
     self.assertEqual(b'test 5\n', b.data)
     b.chunked = [b'te', b'st', b' 6\n']
     self.assertEqual(b'test 6\n', b.as_raw_string())
     self.assertEqual(b'test 6\n', bytes(b))
Пример #2
0
 def test_set_chunks(self):
     b = Blob()
     b.chunked = [b'te', b'st', b' 5\n']
     self.assertEqual(b'test 5\n', b.data)
     b.chunked = [b'te', b'st', b' 6\n']
     self.assertEqual(b'test 6\n', b.as_raw_string())
     self.assertEqual(b'test 6\n', bytes(b))
Пример #3
0
 def test_splitlines(self):
     for case in [
             [],
             [b'foo\nbar\n'],
             [b'bl\na', b'blie'],
             [b'bl\na', b'blie', b'bloe\n'],
             [b'', b'bl\na', b'blie', b'bloe\n'],
             [b'', b'', b'', b'bla\n'],
             [b'', b'', b'', b'bla\n', b''],
             [b'bl', b'', b'a\naaa'],
             [b'a\naaa', b'a'],
             ]:
         b = Blob()
         b.chunked = case
         self.assertEqual(b.data.splitlines(True), b.splitlines())
Пример #4
0
    def _import_one(self, name, data, message, author=None):
        """Import a single object.

        :param name: Optional name of the object
        :param data: serialized object as bytes
        :param message: optional commit message
        :param author: optional author
        :return: etag
        """
        b = Blob()
        b.chunked = data
        tree = self._get_current_tree()
        name_enc = name.encode(DEFAULT_ENCODING)
        tree[name_enc] = (0o644 | stat.S_IFREG, b.id)
        self.repo.object_store.add_objects([(tree, ''), (b, name_enc)])
        self._commit_tree(tree.id,
                          message.encode(DEFAULT_ENCODING),
                          author=author)
        return b.id
Пример #5
0
    def _reconstruct_blobs(self, keys):
        """Return a Git Blob object from a fileid and revision stored in bzr.

        :param fileid: File id of the text
        :param revision: Revision of the text
        """
        stream = self.repository.iter_files_bytes(
            ((key[0], key[1], key) for key in keys))
        for (file_id, revision, expected_sha), chunks in stream:
            blob = Blob()
            blob.chunked = chunks
            if blob.id != expected_sha and blob.data == "":
                # Perhaps it's a symlink ?
                tree = self.tree_cache.revision_tree(revision)
                path = tree.id2path(file_id)
                if tree.kind(path) == 'symlink':
                    blob = symlink_to_blob(tree.get_symlink_target(path))
            _check_expected_sha(expected_sha, blob)
            yield blob
Пример #6
0
 def test_set_chunks(self):
     b = Blob()
     b.chunked = ['te', 'st', ' 5\n']
     self.assertEqual('test 5\n', b.data)
     b.chunked = ['te', 'st', ' 6\n']
     self.assertEqual('test 6\n', b.as_raw_string())
Пример #7
0
 def test_set_chunks(self):
     b = Blob()
     b.chunked = ['te', 'st', ' 5\n']
     self.assertEqual('test 5\n', b.data)
     b.chunked = ['te', 'st', ' 6\n']
     self.assertEqual('test 6\n', b.as_raw_string())
Пример #8
0
 def test_set_chunks(self):
     b = Blob()
     b.chunked = ["te", "st", " 5\n"]
     self.assertEqual("test 5\n", b.data)
     b.chunked = ["te", "st", " 6\n"]
     self.assertEqual("test 6\n", b.as_raw_string())
Пример #9
0
def _tree_to_objects(tree,
                     parent_trees,
                     idmap,
                     unusual_modes,
                     dummy_file_name=None,
                     add_cache_entry=None):
    """Iterate over the objects that were introduced in a revision.

    :param idmap: id map
    :param parent_trees: Parent revision trees
    :param unusual_modes: Unusual file modes dictionary
    :param dummy_file_name: File name to use for dummy files
        in empty directories. None to skip empty directories
    :return: Yields (path, object, ie) entries
    """
    dirty_dirs = set()
    new_blobs = []
    shamap = {}
    try:
        base_tree = parent_trees[0]
        other_parent_trees = parent_trees[1:]
    except IndexError:
        base_tree = tree._repository.revision_tree(NULL_REVISION)
        other_parent_trees = []

    def find_unchanged_parent_ie(file_id, kind, other, parent_trees):
        for ptree in parent_trees:
            try:
                ppath = ptree.id2path(file_id)
            except errors.NoSuchId:
                pass
            else:
                pkind = ptree.kind(ppath)
                if kind == "file":
                    if (pkind == "file"
                            and ptree.get_file_sha1(ppath) == other):
                        return (file_id, ptree.get_file_revision(ppath))
                if kind == "symlink":
                    if (pkind == "symlink"
                            and ptree.get_symlink_target(ppath) == other):
                        return (file_id, ptree.get_file_revision(ppath))
        raise KeyError

    # Find all the changed blobs
    for (file_id, path, changed_content, versioned, parent, name, kind,
         executable) in tree.iter_changes(base_tree):
        if name[1] in BANNED_FILENAMES:
            continue
        if kind[1] == "file":
            sha1 = tree.get_file_sha1(path[1])
            blob_id = None
            try:
                (pfile_id,
                 prevision) = find_unchanged_parent_ie(file_id, kind[1], sha1,
                                                       other_parent_trees)
            except KeyError:
                pass
            else:
                # It existed in one of the parents, with the same contents.
                # So no need to yield any new git objects.
                try:
                    blob_id = idmap.lookup_blob_id(pfile_id, prevision)
                except KeyError:
                    if not changed_content:
                        # no-change merge ?
                        blob = Blob()
                        blob.data = tree.get_file_text(path[1])
                        blob_id = blob.id
            if blob_id is None:
                new_blobs.append((path[1], file_id))
            else:
                shamap[path[1]] = blob_id
                if add_cache_entry is not None:
                    add_cache_entry(("blob", blob_id),
                                    (file_id, tree.get_file_revision(path[1])),
                                    path[1])
        elif kind[1] == "symlink":
            target = tree.get_symlink_target(path[1])
            blob = symlink_to_blob(target)
            shamap[path[1]] = blob.id
            if add_cache_entry is not None:
                add_cache_entry(blob,
                                (file_id, tree.get_file_revision(path[1])),
                                path[1])
            try:
                find_unchanged_parent_ie(file_id, kind[1], target,
                                         other_parent_trees)
            except KeyError:
                if changed_content:
                    yield (path[1], blob, (file_id,
                                           tree.get_file_revision(path[1])))
        elif kind[1] is None:
            shamap[path[1]] = None
        elif kind[1] != 'directory':
            raise AssertionError(kind[1])
        for p in path:
            if p is None:
                continue
            dirty_dirs.add(osutils.dirname(p))

    # Fetch contents of the blobs that were changed
    for (path, file_id), chunks in tree.iter_files_bytes([
        (path, (path, file_id)) for (path, file_id) in new_blobs
    ]):
        obj = Blob()
        obj.chunked = chunks
        if add_cache_entry is not None:
            add_cache_entry(obj, (file_id, tree.get_file_revision(path)), path)
        yield path, obj, (file_id, tree.get_file_revision(path))
        shamap[path] = obj.id

    for path in unusual_modes:
        dirty_dirs.add(posixpath.dirname(path))

    for dir in list(dirty_dirs):
        for parent in osutils.parent_directories(dir):
            if parent in dirty_dirs:
                break
            dirty_dirs.add(parent)

    if dirty_dirs:
        dirty_dirs.add('')

    def ie_to_hexsha(path, ie):
        try:
            return shamap[path]
        except KeyError:
            pass
        # FIXME: Should be the same as in parent
        if ie.kind in ("file", "symlink"):
            try:
                return idmap.lookup_blob_id(ie.file_id, ie.revision)
            except KeyError:
                # no-change merge ?
                blob = Blob()
                blob.data = tree.get_file_text(path)
                if add_cache_entry is not None:
                    add_cache_entry(blob, (ie.file_id, ie.revision), path)
                return blob.id
        elif ie.kind == "directory":
            # Not all cache backends store the tree information,
            # calculate again from scratch
            ret = directory_to_tree(path, ie.children.values(), ie_to_hexsha,
                                    unusual_modes, dummy_file_name,
                                    ie.parent_id is None)
            if ret is None:
                return ret
            return ret.id
        else:
            raise AssertionError

    for path in sorted(dirty_dirs, reverse=True):
        if not tree.has_filename(path):
            continue

        if tree.kind(path) != 'directory':
            raise AssertionError

        obj = Tree()
        for value in tree.iter_child_entries(path):
            if value.name in BANNED_FILENAMES:
                trace.warning('not exporting %s with banned filename %s',
                              value.kind, value.name)
                continue
            child_path = osutils.pathjoin(path, value.name)
            try:
                mode = unusual_modes[child_path]
            except KeyError:
                mode = entry_mode(value)
            hexsha = ie_to_hexsha(child_path, value)
            if hexsha is not None:
                obj.add(value.name.encode("utf-8"), mode, hexsha)

        if len(obj) > 0:
            file_id = tree.path2id(path)
            if add_cache_entry is not None:
                add_cache_entry(obj, (file_id, tree.get_revision_id()), path)
            yield path, obj, (file_id, tree.get_revision_id())
            shamap[path] = obj.id