Ejemplo n.º 1
0
 def test_some_commits(self):
     branch = self.make_branch('test')
     tree = branch.bzrdir.create_workingtree()
     tree.commit('acommit', rev_id='A')
     tree.commit('bcommit', rev_id='B')
     tree.commit('ccommit', rev_id='C')
     self.assertEquals(
         ['A', 'B', 'C'], branch_revision_history(tree.branch))
Ejemplo n.º 2
0
 def test_some_commits(self):
     branch = self.make_branch('test')
     tree = branch.bzrdir.create_workingtree()
     tree.commit('acommit', rev_id='A')
     tree.commit('bcommit', rev_id='B')
     tree.commit('ccommit', rev_id='C')
     self.assertEquals(['A', 'B', 'C'],
                       branch_revision_history(tree.branch))
Ejemplo n.º 3
0
 def test_revisionsToInsert_linear(self):
     # If the branch has a linear ancestry, revisionsToInsert() should
     # yield each revision along with a sequence number, starting at 1.
     self.commitRevision(rev_id="rev-1")
     bzrsync = self.makeBzrSync(self.db_branch)
     bzr_history = branch_revision_history(self.bzr_branch)
     added_ancestry = bzrsync.getAncestryDelta(self.bzr_branch)[0]
     result = bzrsync.revisionsToInsert(bzr_history, self.bzr_branch.revno(), added_ancestry)
     self.assertEqual({"rev-1": 1}, dict(result))
Ejemplo n.º 4
0
 def test_revisionsToInsert_linear(self):
     # If the branch has a linear ancestry, revisionsToInsert() should
     # yield each revision along with a sequence number, starting at 1.
     self.commitRevision(rev_id='rev-1')
     bzrsync = self.makeBzrSync(self.db_branch)
     bzr_history = branch_revision_history(self.bzr_branch)
     added_ancestry = bzrsync.getAncestryDelta(self.bzr_branch)[0]
     result = bzrsync.revisionsToInsert(
         bzr_history, self.bzr_branch.revno(), added_ancestry)
     self.assertEqual({'rev-1': 1}, dict(result))
Ejemplo n.º 5
0
 def test_revisionsToInsert_branched(self):
     # Confirm that these revisions are generated by getRevisions with None
     # as the sequence 'number'.
     (db_branch, bzr_tree), ignored = self.makeBranchWithMerge("base", "trunk", "branch", "merge")
     bzrsync = self.makeBzrSync(db_branch)
     bzr_history = branch_revision_history(bzr_tree.branch)
     added_ancestry = bzrsync.getAncestryDelta(bzr_tree.branch)[0]
     expected = {"base": 1, "trunk": 2, "merge": 3, "branch": None}
     self.assertEqual(
         expected, dict(bzrsync.revisionsToInsert(bzr_history, bzr_tree.branch.revno(), added_ancestry))
     )
Ejemplo n.º 6
0
 def test_revisionsToInsert_branched(self):
     # Confirm that these revisions are generated by getRevisions with None
     # as the sequence 'number'.
     (db_branch, bzr_tree), ignored = self.makeBranchWithMerge(
         'base', 'trunk', 'branch', 'merge')
     bzrsync = self.makeBzrSync(db_branch)
     bzr_history = branch_revision_history(bzr_tree.branch)
     added_ancestry = bzrsync.getAncestryDelta(bzr_tree.branch)[0]
     expected = {'base': 1, 'trunk': 2, 'merge': 3, 'branch': None}
     self.assertEqual(
         expected, dict(bzrsync.revisionsToInsert(bzr_history,
             bzr_tree.branch.revno(), added_ancestry)))
Ejemplo n.º 7
0
 def iterAddedMainline(self):
     """Iterate through revisions added to the mainline."""
     repository = self.bzr_branch.repository
     added_revisions = repository.get_graph().find_unique_ancestors(
         self.last_revision_id, [self.last_scanned_id])
     # Avoid hitting the database since bzrlib makes it easy to check.
     # There are possibly more efficient ways to get the mainline
     # revisions, but this is simple and it works.
     history = branch_revision_history(self.bzr_branch)
     for num, revid in enumerate(history):
         if revid in added_revisions:
             yield repository.get_revision(revid), num + 1
Ejemplo n.º 8
0
 def iterAddedMainline(self):
     """Iterate through revisions added to the mainline."""
     repository = self.bzr_branch.repository
     added_revisions = repository.get_graph().find_unique_ancestors(
         self.last_revision_id, [self.last_scanned_id])
     # Avoid hitting the database since bzrlib makes it easy to check.
     # There are possibly more efficient ways to get the mainline
     # revisions, but this is simple and it works.
     history = branch_revision_history(self.bzr_branch)
     for num, revid in enumerate(history):
         if revid in added_revisions:
             yield repository.get_revision(revid), num + 1
Ejemplo n.º 9
0
    def syncBranch(self, bzr_branch):
        """Synchronize the database view of a branch with Bazaar data.

        `bzr_branch` must be read locked.

        Several tables must be updated:

        * Revision: there must be one Revision row for each revision in the
          branch ancestry. If the row for a revision that has just been added
          to the branch is already present, it must be checked for
          consistency.

        * BranchRevision: there must be one BrancheRevision row for each
          revision in the branch ancestry. If history revisions became merged
          revisions, the corresponding rows must be changed.

        * Branch: the branch-scanner status information must be updated when
          the sync is complete.
        """
        self.logger.info("Scanning branch: %s", self.db_branch.unique_name)
        self.logger.info("    from %s", bzr_branch.base)
        # Get the history and ancestry from the branch first, to fail early
        # if something is wrong with the branch.
        self.logger.info("Retrieving history from bzrlib.")
        bzr_history = branch_revision_history(bzr_branch)
        # The BranchRevision, Revision and RevisionParent tables are only
        # written to by the branch-scanner, so they are not subject to
        # write-lock contention. Update them all in a single transaction to
        # improve the performance and allow garbage collection in the future.
        db_ancestry, db_history = self.retrieveDatabaseAncestry()

        (new_ancestry, branchrevisions_to_delete,
         revids_to_insert) = self.planDatabaseChanges(bzr_branch, bzr_history,
                                                      db_ancestry, db_history)
        new_db_revs = (new_ancestry -
                       getUtility(IRevisionSet).onlyPresent(new_ancestry))
        self.logger.info("Adding %s new revisions.", len(new_db_revs))
        for revids in iter_list_chunks(list(new_db_revs), 10000):
            revisions = self.getBazaarRevisions(bzr_branch, revids)
            self.syncRevisions(bzr_branch, revisions, revids_to_insert)
        self.deleteBranchRevisions(branchrevisions_to_delete)
        self.insertBranchRevisions(bzr_branch, revids_to_insert)
        transaction.commit()
        # Synchronize the RevisionCache for this branch.
        getUtility(IRevisionSet).updateRevisionCacheForBranch(self.db_branch)
        transaction.commit()

        # Notify any listeners that the tip of the branch has changed, but
        # before we've actually updated the database branch.
        initial_scan = (len(db_history) == 0)
        notify(events.TipChanged(self.db_branch, bzr_branch, initial_scan))

        # The Branch table is modified by other systems, including the web UI,
        # so we need to update it in a short transaction to avoid causing
        # timeouts in the webapp. This opens a small race window where the
        # revision data is updated in the database, but the Branch table has
        # not been updated. Since this has no ill-effect, and can only err on
        # the pessimistic side (tell the user the data has not yet been
        # updated although it has), the race is acceptable.
        self.updateBranchStatus(bzr_history)
        notify(
            events.ScanCompleted(self.db_branch, bzr_branch, self.logger,
                                 new_ancestry))
        transaction.commit()
Ejemplo n.º 10
0
 def test_empty(self):
     branch = self.make_branch('test')
     self.assertEquals([], branch_revision_history(branch))
Ejemplo n.º 11
0
    def syncBranch(self, bzr_branch):
        """Synchronize the database view of a branch with Bazaar data.

        `bzr_branch` must be read locked.

        Several tables must be updated:

        * Revision: there must be one Revision row for each revision in the
          branch ancestry. If the row for a revision that has just been added
          to the branch is already present, it must be checked for
          consistency.

        * BranchRevision: there must be one BrancheRevision row for each
          revision in the branch ancestry. If history revisions became merged
          revisions, the corresponding rows must be changed.

        * Branch: the branch-scanner status information must be updated when
          the sync is complete.
        """
        self.logger.info("Scanning branch: %s", self.db_branch.unique_name)
        self.logger.info("    from %s", bzr_branch.base)
        # Get the history and ancestry from the branch first, to fail early
        # if something is wrong with the branch.
        self.logger.info("Retrieving history from bzrlib.")
        bzr_history = branch_revision_history(bzr_branch)
        # The BranchRevision, Revision and RevisionParent tables are only
        # written to by the branch-scanner, so they are not subject to
        # write-lock contention. Update them all in a single transaction to
        # improve the performance and allow garbage collection in the future.
        db_ancestry, db_history = self.retrieveDatabaseAncestry()

        (new_ancestry, branchrevisions_to_delete,
            revids_to_insert) = self.planDatabaseChanges(
            bzr_branch, bzr_history, db_ancestry, db_history)
        new_db_revs = (
            new_ancestry - getUtility(IRevisionSet).onlyPresent(new_ancestry))
        self.logger.info("Adding %s new revisions.", len(new_db_revs))
        for revids in iter_list_chunks(list(new_db_revs), 10000):
            revisions = self.getBazaarRevisions(bzr_branch, revids)
            self.syncRevisions(bzr_branch, revisions, revids_to_insert)
        self.deleteBranchRevisions(branchrevisions_to_delete)
        self.insertBranchRevisions(bzr_branch, revids_to_insert)
        transaction.commit()
        # Synchronize the RevisionCache for this branch.
        getUtility(IRevisionSet).updateRevisionCacheForBranch(self.db_branch)
        transaction.commit()

        # Notify any listeners that the tip of the branch has changed, but
        # before we've actually updated the database branch.
        initial_scan = (len(db_history) == 0)
        notify(events.TipChanged(self.db_branch, bzr_branch, initial_scan))

        # The Branch table is modified by other systems, including the web UI,
        # so we need to update it in a short transaction to avoid causing
        # timeouts in the webapp. This opens a small race window where the
        # revision data is updated in the database, but the Branch table has
        # not been updated. Since this has no ill-effect, and can only err on
        # the pessimistic side (tell the user the data has not yet been
        # updated although it has), the race is acceptable.
        self.updateBranchStatus(bzr_history)
        notify(
            events.ScanCompleted(
                self.db_branch, bzr_branch, self.logger, new_ancestry))
        transaction.commit()
Ejemplo n.º 12
0
 def test_empty(self):
     branch = self.make_branch('test')
     self.assertEquals([], branch_revision_history(branch))