コード例 #1
0
 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"'))
コード例 #2
0
ファイル: test_xml.py プロジェクト: c0ns0le/cygwin
 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"'))
コード例 #3
0
 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')
コード例 #4
0
 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')
コード例 #5
0
 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))
コード例 #6
0
 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')
コード例 #7
0
 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')
コード例 #8
0
 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))
コード例 #9
0
ファイル: xml4.py プロジェクト: c0ns0le/cygwin
    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
コード例 #10
0
    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
コード例 #11
0
 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')
コード例 #12
0
 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')
コード例 #13
0
 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))
コード例 #14
0
 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))
コード例 #15
0
 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)))
コード例 #16
0
 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)))
コード例 #17
0
ファイル: riodemo.py プロジェクト: Distrotech/bzr
def read_inventory(inv_file):
    """Read inventory object from rio formatted inventory file"""
    from bzrlib.inventory import Inventory, InventoryFile
    s = read_stanza(inv_file)
    assert s['inventory_version'] == 7
    inv = Inventory()
    for s in read_stanzas(inv_file):
        kind, file_id = s.items[0]
        parent_id = None
        if 'parent_id' in s:
            parent_id = s['parent_id']
        if kind == 'file':
            ie = InventoryFile(file_id, s['name'], parent_id)
            ie.text_sha1 = s['text_sha1']
            ie.text_size = s['text_size']
        else:
            raise NotImplementedError()
        inv.add(ie)
    return inv
コード例 #18
0
 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)
コード例 #19
0
 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)
コード例 #20
0
def read_inventory(inv_file):
    """Read inventory object from rio formatted inventory file"""
    from bzrlib.inventory import Inventory, InventoryFile
    s = read_stanza(inv_file)
    assert s['inventory_version'] == 7
    inv = Inventory()
    for s in read_stanzas(inv_file):
        kind, file_id = s.items[0]
        parent_id = None
        if 'parent_id' in s:
            parent_id = s['parent_id']
        if kind == 'file':
            ie = InventoryFile(file_id, s['name'], parent_id)
            ie.text_sha1 = s['text_sha1']
            ie.text_size = s['text_size']
        else:
            raise NotImplementedError()
        inv.add(ie)
    return inv
コード例 #21
0
 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)
コード例 #22
0
    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)
コード例 #23
0
    def make_one_file_inventory(self, repo, revision, parents,
                                inv_revision=None, root_revision=None,
                                file_contents=None, make_file_version=True):
        """Make an inventory containing a version of a file with ID 'a-file'.

        The file's ID will be 'a-file', and its filename will be 'a file name',
        stored at the tree root.

        :param repo: a repository to add the new file version to.
        :param revision: the revision ID of the new inventory.
        :param parents: the parents for this revision of 'a-file'.
        :param inv_revision: if not None, the revision ID to store in the
            inventory entry.  Otherwise, this defaults to revision.
        :param root_revision: if not None, the inventory's root.revision will
            be set to this.
        :param file_contents: if not None, the contents of this file version.
            Otherwise a unique default (based on revision ID) will be
            generated.
        """
        inv = Inventory(revision_id=revision)
        if root_revision is not None:
            inv.root.revision = root_revision
        file_id = 'a-file-id'
        entry = InventoryFile(file_id, 'a file name', 'TREE_ROOT')
        if inv_revision is not None:
            entry.revision = inv_revision
        else:
            entry.revision = revision
        entry.text_size = 0
        if file_contents is None:
            file_contents = '%sline\n' % entry.revision
        entry.text_sha1 = osutils.sha_string(file_contents)
        inv.add(entry)
        if make_file_version:
            repo.texts.add_lines((file_id, revision),
                [(file_id, parent) for parent in parents], [file_contents])
        return inv
コード例 #24
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
コード例 #25
0
ファイル: test_xml.py プロジェクト: Distrotech/bzr
 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
コード例 #26
0
class MemoryTree(mutabletree.MutableInventoryTree):
    """A MemoryTree is a specialisation of MutableTree.

    It maintains nearly no state outside of read_lock and write_lock
    transactions. (it keeps a reference to the branch, and its last-revision
    only).
    """

    def __init__(self, branch, revision_id):
        """Construct a MemoryTree for branch using revision_id."""
        self.branch = branch
        self.bzrdir = branch.bzrdir
        self._branch_revision_id = revision_id
        self._locks = 0
        self._lock_mode = None

    def get_config_stack(self):
        return self.branch.get_config_stack()

    def is_control_filename(self, filename):
        # Memory tree doesn't have any control filenames
        return False

    @needs_tree_write_lock
    def _add(self, files, ids, kinds):
        """See MutableTree._add."""
        for f, file_id, kind in zip(files, ids, kinds):
            if kind is None:
                kind = 'file'
            if file_id is None:
                self._inventory.add_path(f, kind=kind)
            else:
                self._inventory.add_path(f, kind=kind, file_id=file_id)

    def basis_tree(self):
        """See Tree.basis_tree()."""
        return self._basis_tree

    @staticmethod
    def create_on_branch(branch):
        """Create a MemoryTree for branch, using the last-revision of branch."""
        revision_id = _mod_revision.ensure_null(branch.last_revision())
        return MemoryTree(branch, revision_id)

    def _gather_kinds(self, files, kinds):
        """See MutableTree._gather_kinds.

        This implementation does not care about the file kind of
        missing files, so is a no-op.
        """

    def get_file(self, file_id, path=None):
        """See Tree.get_file."""
        if path is None:
            path = self.id2path(file_id)
        return self._file_transport.get(path)

    def get_file_sha1(self, file_id, path=None, stat_value=None):
        """See Tree.get_file_sha1()."""
        if path is None:
            path = self.id2path(file_id)
        stream = self._file_transport.get(path)
        return sha_file(stream)

    def get_root_id(self):
        return self.path2id('')

    def _comparison_data(self, entry, path):
        """See Tree._comparison_data."""
        if entry is None:
            return None, False, None
        return entry.kind, entry.executable, None

    @needs_tree_write_lock
    def rename_one(self, from_rel, to_rel):
        file_id = self.path2id(from_rel)
        to_dir, to_tail = os.path.split(to_rel)
        to_parent_id = self.path2id(to_dir)
        self._file_transport.move(from_rel, to_rel)
        self._inventory.rename(file_id, to_parent_id, to_tail)

    def path_content_summary(self, path):
        """See Tree.path_content_summary."""
        id = self.path2id(path)
        if id is None:
            return 'missing', None, None, None
        kind = self.kind(id)
        if kind == 'file':
            bytes = self._file_transport.get_bytes(path)
            size = len(bytes)
            executable = self._inventory[id].executable
            sha1 = None # no stat cache
            return (kind, size, executable, sha1)
        elif kind == 'directory':
            # memory tree does not support nested trees yet.
            return kind, None, None, None
        elif kind == 'symlink':
            raise NotImplementedError('symlink support')
        else:
            raise NotImplementedError('unknown kind')

    def _file_size(self, entry, stat_value):
        """See Tree._file_size."""
        if entry is None:
            return 0
        return entry.text_size

    @needs_read_lock
    def get_parent_ids(self):
        """See Tree.get_parent_ids.

        This implementation returns the current cached value from
            self._parent_ids.
        """
        return list(self._parent_ids)

    def has_filename(self, filename):
        """See Tree.has_filename()."""
        return self._file_transport.has(filename)

    def is_executable(self, file_id, path=None):
        return self._inventory[file_id].executable

    def kind(self, file_id):
        return self._inventory[file_id].kind

    def mkdir(self, path, file_id=None):
        """See MutableTree.mkdir()."""
        self.add(path, file_id, 'directory')
        if file_id is None:
            file_id = self.path2id(path)
        self._file_transport.mkdir(path)
        return file_id

    @needs_read_lock
    def last_revision(self):
        """See MutableTree.last_revision."""
        return self._branch_revision_id

    def lock_read(self):
        """Lock the memory tree for reading.

        This triggers population of data from the branch for its revision.
        """
        self._locks += 1
        try:
            if self._locks == 1:
                self.branch.lock_read()
                self._lock_mode = "r"
                self._populate_from_branch()
        except:
            self._locks -= 1
            raise

    def lock_tree_write(self):
        """See MutableTree.lock_tree_write()."""
        self._locks += 1
        try:
            if self._locks == 1:
                self.branch.lock_read()
                self._lock_mode = "w"
                self._populate_from_branch()
            elif self._lock_mode == "r":
                raise errors.ReadOnlyError(self)
        except:
            self._locks -= 1
            raise

    def lock_write(self):
        """See MutableTree.lock_write()."""
        self._locks += 1
        try:
            if self._locks == 1:
                self.branch.lock_write()
                self._lock_mode = "w"
                self._populate_from_branch()
            elif self._lock_mode == "r":
                raise errors.ReadOnlyError(self)
        except:
            self._locks -= 1
            raise

    def _populate_from_branch(self):
        """Populate the in-tree state from the branch."""
        self._set_basis()
        if self._branch_revision_id == _mod_revision.NULL_REVISION:
            self._parent_ids = []
        else:
            self._parent_ids = [self._branch_revision_id]
        self._inventory = Inventory(None, self._basis_tree.get_revision_id())
        self._file_transport = MemoryTransport()
        # TODO copy the revision trees content, or do it lazy, or something.
        inventory_entries = self._basis_tree.iter_entries_by_dir()
        for path, entry in inventory_entries:
            self._inventory.add(entry.copy())
            if path == '':
                continue
            if entry.kind == 'directory':
                self._file_transport.mkdir(path)
            elif entry.kind == 'file':
                self._file_transport.put_file(path,
                    self._basis_tree.get_file(entry.file_id))
            else:
                raise NotImplementedError(self._populate_from_branch)

    def put_file_bytes_non_atomic(self, file_id, bytes):
        """See MutableTree.put_file_bytes_non_atomic."""
        self._file_transport.put_bytes(self.id2path(file_id), bytes)

    def unlock(self):
        """Release a lock.

        This frees all cached state when the last lock context for the tree is
        left.
        """
        if self._locks == 1:
            self._basis_tree = None
            self._parent_ids = []
            self._inventory = None
            try:
                self.branch.unlock()
            finally:
                self._locks = 0
                self._lock_mode = None
        else:
            self._locks -= 1

    @needs_tree_write_lock
    def unversion(self, file_ids):
        """Remove the file ids in file_ids from the current versioned set.

        When a file_id is unversioned, all of its children are automatically
        unversioned.

        :param file_ids: The file ids to stop versioning.
        :raises: NoSuchId if any fileid is not currently versioned.
        """
        # XXX: This should be in mutabletree, but the inventory-save action
        # is not relevant to memory tree. Until that is done in unlock by
        # working tree, we cannot share the implementation.
        for file_id in file_ids:
            if self._inventory.has_id(file_id):
                self._inventory.remove_recursive_id(file_id)
            else:
                raise errors.NoSuchId(self, file_id)

    def set_parent_ids(self, revision_ids, allow_leftmost_as_ghost=False):
        """See MutableTree.set_parent_trees()."""
        for revision_id in revision_ids:
            _mod_revision.check_not_reserved_id(revision_id)
        if len(revision_ids) == 0:
            self._parent_ids = []
            self._branch_revision_id = _mod_revision.NULL_REVISION
        else:
            self._parent_ids = revision_ids
            self._branch_revision_id = revision_ids[0]
        self._allow_leftmost_as_ghost = allow_leftmost_as_ghost
        self._set_basis()
    
    def _set_basis(self):
        try:
            self._basis_tree = self.branch.repository.revision_tree(
                self._branch_revision_id)
        except errors.NoSuchRevision:
            if self._allow_leftmost_as_ghost:
                self._basis_tree = self.branch.repository.revision_tree(
                    _mod_revision.NULL_REVISION)
            else:
                raise

    def set_parent_trees(self, parents_list, allow_leftmost_as_ghost=False):
        """See MutableTree.set_parent_trees()."""
        if len(parents_list) == 0:
            self._parent_ids = []
            self._basis_tree = self.branch.repository.revision_tree(
                                   _mod_revision.NULL_REVISION)
        else:
            if parents_list[0][1] is None and not allow_leftmost_as_ghost:
                # a ghost in the left most parent
                raise errors.GhostRevisionUnusableHere(parents_list[0][0])
            self._parent_ids = [parent_id for parent_id, tree in parents_list]
            if parents_list[0][1] is None or parents_list[0][1] == 'null:':
                self._basis_tree = self.branch.repository.revision_tree(
                                       _mod_revision.NULL_REVISION)
            else:
                self._basis_tree = parents_list[0][1]
            self._branch_revision_id = parents_list[0][0]
コード例 #27
0
ファイル: memorytree.py プロジェクト: pombreda/dist-packages
class MemoryTree(mutabletree.MutableInventoryTree):
    """A MemoryTree is a specialisation of MutableTree.

    It maintains nearly no state outside of read_lock and write_lock
    transactions. (it keeps a reference to the branch, and its last-revision
    only).
    """
    def __init__(self, branch, revision_id):
        """Construct a MemoryTree for branch using revision_id."""
        self.branch = branch
        self.bzrdir = branch.bzrdir
        self._branch_revision_id = revision_id
        self._locks = 0
        self._lock_mode = None

    def get_config_stack(self):
        return self.branch.get_config_stack()

    def is_control_filename(self, filename):
        # Memory tree doesn't have any control filenames
        return False

    @needs_tree_write_lock
    def _add(self, files, ids, kinds):
        """See MutableTree._add."""
        for f, file_id, kind in zip(files, ids, kinds):
            if kind is None:
                kind = 'file'
            if file_id is None:
                self._inventory.add_path(f, kind=kind)
            else:
                self._inventory.add_path(f, kind=kind, file_id=file_id)

    def basis_tree(self):
        """See Tree.basis_tree()."""
        return self._basis_tree

    @staticmethod
    def create_on_branch(branch):
        """Create a MemoryTree for branch, using the last-revision of branch."""
        revision_id = _mod_revision.ensure_null(branch.last_revision())
        return MemoryTree(branch, revision_id)

    def _gather_kinds(self, files, kinds):
        """See MutableTree._gather_kinds.

        This implementation does not care about the file kind of
        missing files, so is a no-op.
        """

    def get_file(self, file_id, path=None):
        """See Tree.get_file."""
        if path is None:
            path = self.id2path(file_id)
        return self._file_transport.get(path)

    def get_file_sha1(self, file_id, path=None, stat_value=None):
        """See Tree.get_file_sha1()."""
        if path is None:
            path = self.id2path(file_id)
        stream = self._file_transport.get(path)
        return sha_file(stream)

    def get_root_id(self):
        return self.path2id('')

    def _comparison_data(self, entry, path):
        """See Tree._comparison_data."""
        if entry is None:
            return None, False, None
        return entry.kind, entry.executable, None

    @needs_tree_write_lock
    def rename_one(self, from_rel, to_rel):
        file_id = self.path2id(from_rel)
        to_dir, to_tail = os.path.split(to_rel)
        to_parent_id = self.path2id(to_dir)
        self._file_transport.move(from_rel, to_rel)
        self._inventory.rename(file_id, to_parent_id, to_tail)

    def path_content_summary(self, path):
        """See Tree.path_content_summary."""
        id = self.path2id(path)
        if id is None:
            return 'missing', None, None, None
        kind = self.kind(id)
        if kind == 'file':
            bytes = self._file_transport.get_bytes(path)
            size = len(bytes)
            executable = self._inventory[id].executable
            sha1 = None  # no stat cache
            return (kind, size, executable, sha1)
        elif kind == 'directory':
            # memory tree does not support nested trees yet.
            return kind, None, None, None
        elif kind == 'symlink':
            raise NotImplementedError('symlink support')
        else:
            raise NotImplementedError('unknown kind')

    def _file_size(self, entry, stat_value):
        """See Tree._file_size."""
        if entry is None:
            return 0
        return entry.text_size

    @needs_read_lock
    def get_parent_ids(self):
        """See Tree.get_parent_ids.

        This implementation returns the current cached value from
            self._parent_ids.
        """
        return list(self._parent_ids)

    def has_filename(self, filename):
        """See Tree.has_filename()."""
        return self._file_transport.has(filename)

    def is_executable(self, file_id, path=None):
        return self._inventory[file_id].executable

    def kind(self, file_id):
        return self._inventory[file_id].kind

    def mkdir(self, path, file_id=None):
        """See MutableTree.mkdir()."""
        self.add(path, file_id, 'directory')
        if file_id is None:
            file_id = self.path2id(path)
        self._file_transport.mkdir(path)
        return file_id

    @needs_read_lock
    def last_revision(self):
        """See MutableTree.last_revision."""
        return self._branch_revision_id

    def lock_read(self):
        """Lock the memory tree for reading.

        This triggers population of data from the branch for its revision.
        """
        self._locks += 1
        try:
            if self._locks == 1:
                self.branch.lock_read()
                self._lock_mode = "r"
                self._populate_from_branch()
        except:
            self._locks -= 1
            raise

    def lock_tree_write(self):
        """See MutableTree.lock_tree_write()."""
        self._locks += 1
        try:
            if self._locks == 1:
                self.branch.lock_read()
                self._lock_mode = "w"
                self._populate_from_branch()
            elif self._lock_mode == "r":
                raise errors.ReadOnlyError(self)
        except:
            self._locks -= 1
            raise

    def lock_write(self):
        """See MutableTree.lock_write()."""
        self._locks += 1
        try:
            if self._locks == 1:
                self.branch.lock_write()
                self._lock_mode = "w"
                self._populate_from_branch()
            elif self._lock_mode == "r":
                raise errors.ReadOnlyError(self)
        except:
            self._locks -= 1
            raise

    def _populate_from_branch(self):
        """Populate the in-tree state from the branch."""
        self._set_basis()
        if self._branch_revision_id == _mod_revision.NULL_REVISION:
            self._parent_ids = []
        else:
            self._parent_ids = [self._branch_revision_id]
        self._inventory = Inventory(None, self._basis_tree.get_revision_id())
        self._file_transport = MemoryTransport()
        # TODO copy the revision trees content, or do it lazy, or something.
        inventory_entries = self._basis_tree.iter_entries_by_dir()
        for path, entry in inventory_entries:
            self._inventory.add(entry.copy())
            if path == '':
                continue
            if entry.kind == 'directory':
                self._file_transport.mkdir(path)
            elif entry.kind == 'file':
                self._file_transport.put_file(
                    path, self._basis_tree.get_file(entry.file_id))
            else:
                raise NotImplementedError(self._populate_from_branch)

    def put_file_bytes_non_atomic(self, file_id, bytes):
        """See MutableTree.put_file_bytes_non_atomic."""
        self._file_transport.put_bytes(self.id2path(file_id), bytes)

    def unlock(self):
        """Release a lock.

        This frees all cached state when the last lock context for the tree is
        left.
        """
        if self._locks == 1:
            self._basis_tree = None
            self._parent_ids = []
            self._inventory = None
            try:
                self.branch.unlock()
            finally:
                self._locks = 0
                self._lock_mode = None
        else:
            self._locks -= 1

    @needs_tree_write_lock
    def unversion(self, file_ids):
        """Remove the file ids in file_ids from the current versioned set.

        When a file_id is unversioned, all of its children are automatically
        unversioned.

        :param file_ids: The file ids to stop versioning.
        :raises: NoSuchId if any fileid is not currently versioned.
        """
        # XXX: This should be in mutabletree, but the inventory-save action
        # is not relevant to memory tree. Until that is done in unlock by
        # working tree, we cannot share the implementation.
        for file_id in file_ids:
            if self._inventory.has_id(file_id):
                self._inventory.remove_recursive_id(file_id)
            else:
                raise errors.NoSuchId(self, file_id)

    def set_parent_ids(self, revision_ids, allow_leftmost_as_ghost=False):
        """See MutableTree.set_parent_trees()."""
        for revision_id in revision_ids:
            _mod_revision.check_not_reserved_id(revision_id)
        if len(revision_ids) == 0:
            self._parent_ids = []
            self._branch_revision_id = _mod_revision.NULL_REVISION
        else:
            self._parent_ids = revision_ids
            self._branch_revision_id = revision_ids[0]
        self._allow_leftmost_as_ghost = allow_leftmost_as_ghost
        self._set_basis()

    def _set_basis(self):
        try:
            self._basis_tree = self.branch.repository.revision_tree(
                self._branch_revision_id)
        except errors.NoSuchRevision:
            if self._allow_leftmost_as_ghost:
                self._basis_tree = self.branch.repository.revision_tree(
                    _mod_revision.NULL_REVISION)
            else:
                raise

    def set_parent_trees(self, parents_list, allow_leftmost_as_ghost=False):
        """See MutableTree.set_parent_trees()."""
        if len(parents_list) == 0:
            self._parent_ids = []
            self._basis_tree = self.branch.repository.revision_tree(
                _mod_revision.NULL_REVISION)
        else:
            if parents_list[0][1] is None and not allow_leftmost_as_ghost:
                # a ghost in the left most parent
                raise errors.GhostRevisionUnusableHere(parents_list[0][0])
            self._parent_ids = [parent_id for parent_id, tree in parents_list]
            if parents_list[0][1] is None or parents_list[0][1] == 'null:':
                self._basis_tree = self.branch.repository.revision_tree(
                    _mod_revision.NULL_REVISION)
            else:
                self._basis_tree = parents_list[0][1]
            self._branch_revision_id = parents_list[0][0]