Exemplo n.º 1
0
    def make_broken_repository(self):
        # XXX: This function is borrowed from Aaron's "Reconcile can fix bad
        # parent references" branch which is due to land in bzr.dev soon.  Once
        # it does, this duplication should be removed.
        repo = self.make_repository('broken-repo')
        cleanups = []
        try:
            repo.lock_write()
            cleanups.append(repo.unlock)
            repo.start_write_group()
            cleanups.append(repo.commit_write_group)
            # make rev1a: A well-formed revision, containing 'file1'
            inv = inventory.Inventory(revision_id='rev1a')
            inv.root.revision = 'rev1a'
            self.add_file(repo, inv, 'file1', 'rev1a', [])
            repo.add_inventory('rev1a', inv, [])
            revision = _mod_revision.Revision('rev1a',
                committer='*****@*****.**', timestamp=0,
                inventory_sha1='', timezone=0, message='foo', parent_ids=[])
            repo.add_revision('rev1a',revision, inv)

            # make rev1b, which has no Revision, but has an Inventory, and
            # file1
            inv = inventory.Inventory(revision_id='rev1b')
            inv.root.revision = 'rev1b'
            self.add_file(repo, inv, 'file1', 'rev1b', [])
            repo.add_inventory('rev1b', inv, [])

            # make rev2, with file1 and file2
            # file2 is sane
            # file1 has 'rev1b' as an ancestor, even though this is not
            # mentioned by 'rev1a', making it an unreferenced ancestor
            inv = inventory.Inventory()
            self.add_file(repo, inv, 'file1', 'rev2', ['rev1a', 'rev1b'])
            self.add_file(repo, inv, 'file2', 'rev2', [])
            self.add_revision(repo, 'rev2', inv, ['rev1a'])

            # make ghost revision rev1c
            inv = inventory.Inventory()
            self.add_file(repo, inv, 'file2', 'rev1c', [])

            # make rev3 with file2
            # file2 refers to 'rev1c', which is a ghost in this repository, so
            # file2 cannot have rev1c as its ancestor.
            inv = inventory.Inventory()
            self.add_file(repo, inv, 'file2', 'rev3', ['rev1c'])
            self.add_revision(repo, 'rev3', inv, ['rev1c'])
            return repo
        finally:
            for cleanup in reversed(cleanups):
                cleanup()
Exemplo n.º 2
0
 def test_non_directory_children(self):
     """Test path2id when a parent directory has no children"""
     inv = inventory.Inventory('tree-root')
     inv.add(self.make_file('file-id','file', 'tree-root'))
     inv.add(self.make_link('link-id','link', 'tree-root'))
     self.assertIs(None, inv.path2id('file/subfile'))
     self.assertIs(None, inv.path2id('link/subfile'))
Exemplo n.º 3
0
 def test_add_revision_inventory_sha1(self):
     inv = inventory.Inventory(revision_id='A')
     inv.root.revision = 'A'
     inv.root.file_id = 'fixed-root'
     # Insert the inventory on its own to an identical repository, to get
     # its sha1.
     reference_repo = self.make_repository('reference_repo')
     reference_repo.lock_write()
     reference_repo.start_write_group()
     inv_sha1 = reference_repo.add_inventory('A', inv, [])
     reference_repo.abort_write_group()
     reference_repo.unlock()
     # Now insert a revision with this inventory, and it should get the same
     # sha1.
     repo = self.make_repository('repo')
     repo.lock_write()
     repo.start_write_group()
     root_id = inv.root.file_id
     repo.texts.add_lines(('fixed-root', 'A'), [], [])
     repo.add_revision('A', _mod_revision.Revision(
             'A', committer='B', timestamp=0,
             timezone=0, message='C'), inv=inv)
     repo.commit_write_group()
     repo.unlock()
     repo.lock_read()
     self.assertEqual(inv_sha1, repo.get_revision('A').inventory_sha1)
     repo.unlock()
Exemplo n.º 4
0
def unpack_inventory_flat(elt,
                          format_num,
                          unpack_entry,
                          entry_cache=None,
                          return_from_cache=False):
    """Unpack a flat XML inventory.

    :param elt: XML element for the inventory
    :param format_num: Expected format number
    :param unpack_entry: Function for unpacking inventory entries
    :return: An inventory
    :raise UnexpectedInventoryFormat: When unexpected elements or data is
        encountered
    """
    if elt.tag != 'inventory':
        raise errors.UnexpectedInventoryFormat('Root tag is %r' % elt.tag)
    format = elt.get('format')
    if format != format_num:
        raise errors.UnexpectedInventoryFormat('Invalid format version %r' %
                                               format)
    revision_id = elt.get('revision_id')
    if revision_id is not None:
        revision_id = cache_utf8.encode(revision_id)
    inv = inventory.Inventory(root_id=None, revision_id=revision_id)
    for e in elt:
        ie = unpack_entry(e, entry_cache, return_from_cache)
        inv.add(ie)
    return inv
Exemplo n.º 5
0
 def test_does_something_reconcile(self):
     t = controldir.ControlDir.create_standalone_workingtree('.')
     # an empty inventory with no revision will trigger reconciliation.
     repo = t.branch.repository
     inv = inventory.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, "")
Exemplo n.º 6
0
    def run_action(self, output):
        inv = inventory.Inventory()
        stdout = StringIO()
        action = add.AddAction(to_file=stdout, should_print=bool(output))

        self.apply_redirected(None, stdout, None, action, inv, None, 'path',
                              'file')
        self.assertEqual(stdout.getvalue(), output)
Exemplo n.º 7
0
    def revision_tree(self, revision_id):
        revision_id = revision.ensure_null(revision_id)

        if revision_id == revision.NULL_REVISION:
            inv = inventory.Inventory(root_id=None)
            inv.revision_id = revision_id
            return revisiontree.RevisionTree(self, inv, revision_id)

        return GitRevisionTree(self, self.get_mapping(), revision_id)
Exemplo n.º 8
0
    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.Inventory(revision_id = 'ghost')
        inv.root.revision = 'ghost'
        if repo.supports_rich_root():
            root_id = inv.root.file_id
            repo.texts.add_lines((root_id, 'ghost'), [], [])
        sha1 = repo.add_inventory('ghost', inv, [])
        rev = _mod_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 tests.TestNotApplicable(
                "Cannot test with ghosts for this format.")

        inv = inventory.Inventory(revision_id = 'the_ghost')
        inv.root.revision = 'the_ghost'
        if repo.supports_rich_root():
            root_id = inv.root.file_id
            repo.texts.add_lines((root_id, 'the_ghost'), [], [])
        sha1 = repo.add_inventory('the_ghost', inv, [])
        rev = _mod_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()
Exemplo n.º 9
0
    def _stub_initialize_on_transport(self, transport, file_mode):
        """Workaround: create control files for a remote working tree.

        This ensures that it can later be updated and dealt with locally,
        since BzrDirFormat6 and BzrDirFormat5 cannot represent dirs with
        no working tree.  (See bug #43064).
        """
        sio = StringIO()
        inv = inventory.Inventory()
        xml5.serializer_v5.write_inventory(inv, sio, working=True)
        sio.seek(0)
        transport.put_file('inventory', sio, file_mode)
        transport.put_bytes('pending-merges', '', file_mode)
Exemplo n.º 10
0
    def make_repo_with_extra_ghost_index(self):
        """Make a corrupt repository.

        It will contain one revision, 'revision-id'.  The knit index will claim
        that it has one parent, 'incorrect-parent', but the revision text will
        claim it has no parents.

        Note: only the *cache* of the knit index is corrupted.  Thus the
        corruption will only last while the repository is locked.  For this
        reason, the returned repo is locked.
        """
        if not isinstance(self.repository_format, RepositoryFormatKnit):
            # XXX: Broken revision graphs can happen to weaves too, but they're
            # pretty deprecated.  Ideally these tests should apply to any repo
            # where repo.revision_graph_can_have_wrong_parents() is True, but
            # at the moment we only know how to corrupt knit repos.
            raise TestNotApplicable(
                "%s isn't a knit format" % self.repository_format)

        repo = self.make_repository('broken')
        repo.lock_write()
        repo.start_write_group()
        try:
            inv = inventory.Inventory(revision_id='revision-id')
            inv.root.revision = 'revision-id'
            inv_sha1 = repo.add_inventory('revision-id', inv, [])
            if repo.supports_rich_root():
                root_id = inv.root.file_id
                repo.texts.add_lines((root_id, 'revision-id'), [], [])
            revision = _mod_revision.Revision('revision-id',
                committer='*****@*****.**', timestamp=0,
                inventory_sha1=inv_sha1, timezone=0, message='message',
                parent_ids=[])
            # Manually add the revision text using the RevisionStore API, with
            # bad parents.
            rev_text = repo._serializer.write_revision_to_string(revision)
            repo.revisions.add_lines((revision.revision_id,),
                [('incorrect-parent',)],
                osutils.split_lines(rev_text))
        except:
            repo.abort_write_group()
            repo.unlock()
            raise
        else:
            repo.commit_write_group()
            repo.unlock()

        repo.lock_write()
        self.addCleanup(repo.unlock)
        return repo
Exemplo n.º 11
0
class GitRevisionTree(revisiontree.RevisionTree):
    def __init__(self, repository, mapping, revision_id):
        self._repository = repository
        self.revision_id = revision_id
        assert isinstance(revision_id, str)
        self.mapping = mapping
        git_id = repository.lookup_git_revid(revision_id, self.mapping)
        try:
            commit = repository._git.commit(git_id)
        except KeyError, r:
            raise errors.NoSuchRevision(repository, revision_id)
        self.tree = commit.tree
        self._inventory = inventory.Inventory(revision_id=revision_id)
        self._inventory.root.revision = revision_id
        self._build_inventory(self.tree, self._inventory.root, "")
Exemplo n.º 12
0
 def test_ids(self):
     """Test detection of files within selected directories."""
     inv = inventory.Inventory('TREE_ROOT')
     for args in [('src', 'directory', 'src-id'),
                  ('doc', 'directory', 'doc-id'),
                  ('src/hello.c', 'file'),
                  ('src/bye.c', 'file', 'bye-id'),
                  ('Makefile', 'file')]:
         ie = inv.add_path(*args)
         if args[1] == 'file':
             ie.text_sha1 = osutils.sha_string('content\n')
             ie.text_size = len('content\n')
     inv = self.inv_to_test_inv(inv)
     self.assertEqual(inv.path2id('src'), 'src-id')
     self.assertEqual(inv.path2id('src/bye.c'), 'bye-id')
Exemplo n.º 13
0
 def _unpack_inventory(self, elt, revision_id=None):
     """Construct from XML Element"""
     if elt.tag != 'inventory':
         raise errors.UnexpectedInventoryFormat('Root tag is %r' % elt.tag)
     format = elt.get('format')
     if format != self.format_num:
         raise errors.UnexpectedInventoryFormat(
             'Invalid format version %r' % format)
     revision_id = elt.get('revision_id')
     if revision_id is not None:
         revision_id = cache_utf8.encode(revision_id)
     inv = inventory.Inventory(root_id=None, revision_id=revision_id)
     for e in elt:
         ie = self._unpack_entry(e)
         inv.add(ie)
     return inv
Exemplo n.º 14
0
 def prepare_inv_with_nested_dirs(self):
     inv = inventory.Inventory('tree-root')
     for args in [('src', 'directory', 'src-id'),
                  ('doc', 'directory', 'doc-id'),
                  ('src/hello.c', 'file', 'hello-id'),
                  ('src/bye.c', 'file', 'bye-id'),
                  ('zz', 'file', 'zz-id'),
                  ('src/sub/', 'directory', 'sub-id'),
                  ('src/zz.c', 'file', 'zzc-id'),
                  ('src/sub/a', 'file', 'a-id'),
                  ('Makefile', 'file', 'makefile-id')]:
         ie = inv.add_path(*args)
         if args[1] == 'file':
             ie.text_sha1 = osutils.sha_string('content\n')
             ie.text_size = len('content\n')
     return self.inv_to_test_inv(inv)
Exemplo n.º 15
0
    def _unpack_inventory(self, elt, revision_id, entry_cache=None,
                          return_from_cache=False):
        """Construct from XML Element
        """
        root_id = elt.get('file_id') or inventory.ROOT_ID
        root_id = get_utf8_or_ascii(root_id)

        format = elt.get('format')
        if format is not None:
            if format != '5':
                raise errors.BzrError("invalid format version %r on inventory"
                                      % format)
        data_revision_id = elt.get('revision_id')
        if data_revision_id is not None:
            revision_id = cache_utf8.encode(data_revision_id)
        inv = inventory.Inventory(root_id, revision_id=revision_id)
        # Optimizations tested
        #   baseline w/entry cache  2.85s
        #   using inv._byid         2.55s
        #   avoiding attributes     2.46s
        #   adding assertions       2.50s
        #   last_parent cache       2.52s (worse, removed)
        byid = inv._byid
        for e in elt:
            ie = unpack_inventory_entry(e, entry_cache=entry_cache,
                              return_from_cache=return_from_cache)
            parent_id = ie.parent_id
            if parent_id is None:
                ie.parent_id = parent_id = root_id
            try:
                parent = byid[parent_id]
            except KeyError:
                raise errors.BzrError("parent_id {%s} not in inventory"
                                      % (parent_id,))
            if ie.file_id in byid:
                raise errors.DuplicateFileId(ie.file_id,
                                             byid[ie.file_id])
            if ie.name in parent.children:
                raise errors.BzrError("%s is already versioned"
                    % (osutils.pathjoin(inv.id2path(parent_id),
                       ie.name).encode('utf-8'),))
            parent.children[ie.name] = ie
            byid[ie.file_id] = ie
        if revision_id is not None:
            inv.root.revision = revision_id
        self._check_cache_size(len(inv), entry_cache)
        return inv
Exemplo n.º 16
0
 def add_commit(repo, revision_id, parent_ids):
     repo.lock_write()
     repo.start_write_group()
     inv = inventory.Inventory(revision_id=revision_id)
     inv.root.revision = revision_id
     root_id = inv.root.file_id
     sha1 = repo.add_inventory(revision_id, inv, [])
     repo.texts.add_lines((root_id, revision_id), [], [])
     rev = _mod_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()
Exemplo n.º 17
0
 def _inventory_delta_stream(self, repository, ordering, revids):
     prev_inv = _mod_inventory.Inventory(root_id=None,
         revision_id=_mod_revision.NULL_REVISION)
     serializer = inventory_delta.InventoryDeltaSerializer(
         repository.supports_rich_root(),
         repository._format.supports_tree_reference)
     repository.lock_read()
     try:
         for inv, revid in repository._iter_inventories(revids, ordering):
             if inv is None:
                 continue
             inv_delta = inv._make_delta(prev_inv)
             lines = serializer.delta_to_lines(
                 prev_inv.revision_id, inv.revision_id, inv_delta)
             yield ChunkedContentFactory(inv.revision_id, None, None, lines)
             prev_inv = inv
     finally:
         repository.unlock()
Exemplo n.º 18
0
 def initialize(self,
                a_bzrdir,
                revision_id=None,
                from_branch=None,
                accelerator_tree=None,
                hardlink=False):
     """See WorkingTreeFormat.initialize()."""
     if not isinstance(a_bzrdir.transport, LocalTransport):
         raise errors.NotLocalUrl(a_bzrdir.transport.base)
     if from_branch is not None:
         branch = from_branch
     else:
         branch = a_bzrdir.open_branch()
     if revision_id is None:
         revision_id = _mod_revision.ensure_null(branch.last_revision())
     branch.lock_write()
     try:
         branch.generate_revision_history(revision_id)
     finally:
         branch.unlock()
     inv = inventory.Inventory()
     wt = WorkingTree2(a_bzrdir.root_transport.local_abspath('.'),
                       branch,
                       inv,
                       _internal=True,
                       _format=self,
                       _bzrdir=a_bzrdir,
                       _control_files=branch.control_files)
     basis_tree = branch.repository.revision_tree(revision_id)
     if basis_tree.get_root_id() is not None:
         wt.set_root_id(basis_tree.get_root_id())
     # set the parent list and cache the basis tree.
     if _mod_revision.is_null(revision_id):
         parent_trees = []
     else:
         parent_trees = [(revision_id, basis_tree)]
     wt.set_parent_trees(parent_trees)
     transform.build_tree(basis_tree, wt)
     for hook in MutableTree.hooks['post_build_tree']:
         hook(wt)
     return wt
Exemplo n.º 19
0
    def _unpack_inventory(self, elt, revision_id):
        """Construct from XML Element
        """
        root_id = elt.get('file_id') or inventory.ROOT_ID
        root_id = xml8._get_utf8_or_ascii(root_id)

        format = elt.get('format')
        if format is not None:
            if format != '5':
                raise BzrError("invalid format version %r on inventory" %
                               format)
        data_revision_id = elt.get('revision_id')
        if data_revision_id is not None:
            revision_id = cache_utf8.encode(data_revision_id)
        inv = inventory.Inventory(root_id, revision_id=revision_id)
        for e in elt:
            ie = self._unpack_entry(e)
            if ie.parent_id is None:
                ie.parent_id = root_id
            inv.add(ie)
        if revision_id is not None:
            inv.root.revision = revision_id
        return inv
Exemplo n.º 20
0
 def _initial_inventory(self):
     return inventory.Inventory()
Exemplo n.º 21
0
 def make_init_inventory(self):
     inv = inventory.Inventory('tree-root')
     inv.revision = 'initial-rev'
     inv.root.revision = 'initial-rev'
     return self.inv_to_test_inv(inv)
Exemplo n.º 22
0
 def _get_inventory(self):
     return inventory.Inventory()