Rev 4598: (robertc) Make committing directly to a stacked branch error rather in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Wed Aug 12 01:13:16 BST 2009


At file:///home/pqm/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 4598 [merge]
revision-id: pqm at pqm.ubuntu.com-20090812001314-0143bmhgop1zt9e3
parent: pqm at pqm.ubuntu.com-20090811040617-g99p5v2wsn13ww8z
parent: robertc at robertcollins.net-20090811052657-flxm64vey8ri3nbq
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Wed 2009-08-12 01:13:14 +0100
message:
  (robertc) Make committing directly to a stacked branch error rather
  	than silently corrupting the branch. (Robert Collins, bug 37013)
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
  bzrlib/tests/blackbox/test_branch.py test_branch.py-20060524161337-noms9gmcwqqrfi8y-1
  bzrlib/tests/per_branch/test_stacking.py test_stacking.py-20080214020755-msjlkb7urobwly0f-1
  bzrlib/tests/per_repository/test_commit_builder.py test_commit_builder.py-20060606110838-76e3ra5slucqus81-1
  bzrlib/tests/per_repository_reference/test_check.py test_check.py-20080220044229-sxxe747gzi6q8fyv-1
  bzrlib/tests/test_pack_repository.py test_pack_repository-20080801043947-eaw0e6h2gu75kwmy-1
  bzrlib/tests/test_remote.py    test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
=== modified file 'NEWS'
--- a/NEWS	2009-08-11 02:58:23 +0000
+++ b/NEWS	2009-08-11 05:26:57 +0000
@@ -12,6 +12,12 @@
 Compatibility Breaks
 ********************
 
+* Committing directly to a stacked branch from a lightweight checkout will
+  no longer work. In previous versions this would appear to work but would
+  generate repositories with insufficient data to create deltas, leading
+  to later errors when branching or reading from the repository.
+  (Robert Collins, bug #375013)
+
 New Features
 ************
 

=== modified file 'bzrlib/repository.py'
--- a/bzrlib/repository.py	2009-08-06 02:23:37 +0000
+++ b/bzrlib/repository.py	2009-08-11 02:45:36 +0000
@@ -1695,6 +1695,10 @@
         :param revprops: Optional dictionary of revision properties.
         :param revision_id: Optional revision id.
         """
+        if self._fallback_repositories:
+            raise errors.BzrError("Cannot commit from a lightweight checkout "
+                "to a stacked branch. See "
+                "https://bugs.launchpad.net/bzr/+bug/375013 for details.")
         result = self._commit_builder_class(self, parents, config,
             timestamp, timezone, committer, revprops, revision_id)
         self.start_write_group()

=== modified file 'bzrlib/tests/blackbox/test_branch.py'
--- a/bzrlib/tests/blackbox/test_branch.py	2009-08-03 04:19:03 +0000
+++ b/bzrlib/tests/blackbox/test_branch.py	2009-08-11 05:26:57 +0000
@@ -149,29 +149,6 @@
 class TestBranchStacked(ExternalBase):
     """Tests for branch --stacked"""
 
-    def check_shallow_branch(self, branch_revid, stacked_on):
-        """Assert that the branch 'newbranch' has been published correctly.
-
-        :param stacked_on: url of a branch this one is stacked upon.
-        :param branch_revid: a revision id that should be the only
-            revision present in the stacked branch, and it should not be in
-            the reference branch.
-        """
-        new_branch = branch.Branch.open('newbranch')
-        # The branch refers to the mainline
-        self.assertEqual(stacked_on, new_branch.get_stacked_on_url())
-        # and the branch's work was pushed
-        self.assertTrue(new_branch.repository.has_revision(branch_revid))
-        # The newly committed revision shoud be present in the stacked branch,
-        # but not in the stacked-on branch.  Because stacking is set up by the
-        # branch object, if we open the stacked branch's repository directly,
-        # bypassing the branch, we see only what's in the stacked repository.
-        stacked_repo = bzrdir.BzrDir.open('newbranch').open_repository()
-        stacked_repo_revisions = set(stacked_repo.all_revision_ids())
-        if len(stacked_repo_revisions) != 1:
-            self.fail("wrong revisions in stacked repository: %r"
-                % (stacked_repo_revisions,))
-
     def assertRevisionInRepository(self, repo_path, revid):
         """Check that a revision is in a repository, disregarding stacking."""
         repo = bzrdir.BzrDir.open(repo_path).open_repository()
@@ -198,12 +175,14 @@
             format='1.9')
         branch_tree.branch.set_stacked_on_url(trunk_tree.branch.base)
         # with some work on it
-        branch_tree.commit('moar work plz')
+        work_tree = trunk_tree.branch.bzrdir.sprout('local').open_workingtree()
+        work_tree.commit('moar work plz')
+        work_tree.branch.push(branch_tree.branch)
         # branching our local branch gives us a new stacked branch pointing at
         # mainline.
         out, err = self.run_bzr(['branch', 'branch', 'newbranch'])
         self.assertEqual('', out)
-        self.assertEqual('Branched 1 revision(s).\n',
+        self.assertEqual('Branched 2 revision(s).\n',
             err)
         # it should have preserved the branch format, and so it should be
         # capable of supporting stacking, but not actually have a stacked_on
@@ -222,7 +201,9 @@
             format='1.9')
         branch_tree.branch.set_stacked_on_url(trunk_tree.branch.base)
         # with some work on it
-        branch_revid = branch_tree.commit('moar work plz')
+        work_tree = trunk_tree.branch.bzrdir.sprout('local').open_workingtree()
+        branch_revid = work_tree.commit('moar work plz')
+        work_tree.branch.push(branch_tree.branch)
         # you can chain branches on from there
         out, err = self.run_bzr(['branch', 'branch', '--stacked', 'branch2'])
         self.assertEqual('', out)
@@ -231,7 +212,8 @@
         self.assertEqual(branch_tree.branch.base,
             branch.Branch.open('branch2').get_stacked_on_url())
         branch2_tree = WorkingTree.open('branch2')
-        branch2_revid = branch2_tree.commit('work on second stacked branch')
+        branch2_revid = work_tree.commit('work on second stacked branch')
+        work_tree.branch.push(branch2_tree.branch)
         self.assertRevisionInRepository('branch2', branch2_revid)
         self.assertRevisionsInBranchRepository(
             [trunk_revid, branch_revid, branch2_revid],
@@ -250,9 +232,8 @@
         self.assertEqual('Created new stacked branch referring to %s.\n' %
             trunk_tree.branch.base, err)
         self.assertRevisionNotInRepository('newbranch', original_revid)
-        new_tree = WorkingTree.open('newbranch')
-        new_revid = new_tree.commit('new work')
-        self.check_shallow_branch(new_revid, trunk_tree.branch.base)
+        new_branch = branch.Branch.open('newbranch')
+        self.assertEqual(trunk_tree.branch.base, new_branch.get_stacked_on_url())
 
     def test_branch_stacked_from_smart_server(self):
         # We can branch stacking on a smart server
@@ -329,7 +310,9 @@
             t.commit(message='commit %d' % count)
         tree2 = t.branch.bzrdir.sprout('feature', stacked=True
             ).open_workingtree()
-        tree2.commit('feature change')
+        local_tree = t.branch.bzrdir.sprout('local-working').open_workingtree()
+        local_tree.commit('feature change')
+        local_tree.branch.push(tree2.branch)
         self.reset_smart_call_log()
         out, err = self.run_bzr(['branch', self.get_url('feature'),
             'local-target'])

=== modified file 'bzrlib/tests/per_branch/test_stacking.py'
--- a/bzrlib/tests/per_branch/test_stacking.py	2009-08-05 02:30:59 +0000
+++ b/bzrlib/tests/per_branch/test_stacking.py	2009-08-11 05:26:57 +0000
@@ -150,8 +150,8 @@
             raise TestNotApplicable(e)
         # stacked repository
         self.assertRevisionNotInRepository('newbranch', trunk_revid)
-        new_tree = new_dir.open_workingtree()
-        new_branch_revid = new_tree.commit('something local')
+        tree = new_dir.open_branch().create_checkout('local')
+        new_branch_revid = tree.commit('something local')
         self.assertRevisionNotInRepository('mainline', new_branch_revid)
         self.assertRevisionInRepository('newbranch', new_branch_revid)
 
@@ -173,8 +173,8 @@
         new_dir = remote_bzrdir.sprout('newbranch', stacked=True)
         # stacked repository
         self.assertRevisionNotInRepository('newbranch', trunk_revid)
-        new_tree = new_dir.open_workingtree()
-        new_branch_revid = new_tree.commit('something local')
+        tree = new_dir.open_branch().create_checkout('local')
+        new_branch_revid = tree.commit('something local')
         self.assertRevisionNotInRepository('mainline', new_branch_revid)
         self.assertRevisionInRepository('newbranch', new_branch_revid)
 
@@ -333,7 +333,8 @@
 
     def test_fetch_copies_from_stacked_on_and_stacked(self):
         stacked, unstacked = self.prepare_stacked_on_fetch()
-        stacked.commit('second commit', rev_id='rev2')
+        tree = stacked.branch.create_checkout('local')
+        tree.commit('second commit', rev_id='rev2')
         unstacked.fetch(stacked.branch.repository, 'rev2')
         unstacked.get_revision('rev1')
         unstacked.get_revision('rev2')
@@ -355,13 +356,15 @@
         stack_on.add('a')
         stack_on.commit('base commit')
         stacked_dir = stack_on.bzrdir.sprout('stacked', stacked=True)
-        stacked_tree = stacked_dir.open_workingtree()
+        stacked_branch = stacked_dir.open_branch()
+        local_tree = stack_on.bzrdir.sprout('local').open_workingtree()
         for i in range(20):
             text_lines[0] = 'changed in %d\n' % i
-            self.build_tree_contents([('stacked/a', ''.join(text_lines))])
-            stacked_tree.commit('commit %d' % i)
-        stacked_tree.branch.repository.pack()
-        check.check_dwim(stacked_tree.branch.base, False, True, True)
+            self.build_tree_contents([('local/a', ''.join(text_lines))])
+            local_tree.commit('commit %d' % i)
+            local_tree.branch.push(stacked_branch)
+        stacked_branch.repository.pack()
+        check.check_dwim(stacked_branch.base, False, True, True)
 
     def test_pull_delta_when_stacked(self):
         if not self.branch_format.supports_stacking():
@@ -470,7 +473,8 @@
         except errors.NoWorkingTree:
             stacked = stacked_dir.open_branch().create_checkout(
                 'stacked-checkout', lightweight=True)
-        stacked.commit('second commit', rev_id='rev2')
+        tree = stacked.branch.create_checkout('local')
+        tree.commit('second commit', rev_id='rev2')
         # Sanity check: stacked's repo should not contain rev1, otherwise this
         # test isn't testing what it's supposed to.
         repo = stacked.branch.repository.bzrdir.open_repository()

=== modified file 'bzrlib/tests/per_repository/test_commit_builder.py'
--- a/bzrlib/tests/per_repository/test_commit_builder.py	2009-05-06 05:36:28 +0000
+++ b/bzrlib/tests/per_repository/test_commit_builder.py	2009-08-11 02:45:36 +0000
@@ -1267,3 +1267,19 @@
         self.addCleanup(branch.repository.abort_write_group)
         self.assertRaises(ValueError, builder.commit,
             u'Invalid\r\ncommit message\r\n')
+
+    def test_stacked_repositories_reject_commit_builder(self):
+        # As per bug 375013, committing to stacked repositories is currently
+        # broken, so repositories with fallbacks refuse to hand out a commit
+        # builder.
+        repo_basis = self.make_repository('basis')
+        branch = self.make_branch('local')
+        repo_local = branch.repository
+        try:
+            repo_local.add_fallback_repository(repo_basis)
+        except errors.UnstackableRepositoryFormat:
+            raise tests.TestNotApplicable("not a stackable format.")
+        repo_local.lock_write()
+        self.addCleanup(repo_local.unlock)
+        self.assertRaises(errors.BzrError, repo_local.get_commit_builder,
+            branch, [], branch.get_config())

=== modified file 'bzrlib/tests/per_repository_reference/test_check.py'
--- a/bzrlib/tests/per_repository_reference/test_check.py	2009-03-23 14:59:43 +0000
+++ b/bzrlib/tests/per_repository_reference/test_check.py	2009-08-11 05:26:57 +0000
@@ -33,8 +33,9 @@
         referring = self.make_branch_and_tree('referring')
         readonly_base = self.readonly_repository('base')
         referring.branch.repository.add_fallback_repository(readonly_base)
-        self.build_tree_contents([('referring/file', 'change')])
-        rev2_id = referring.commit('two')
+        local_tree = referring.branch.create_checkout('local')
+        self.build_tree_contents([('local/file', 'change')])
+        rev2_id = local_tree.commit('two')
         check_result = referring.branch.repository.check(
             referring.branch.repository.all_revision_ids())
         check_result.report_results(verbose=False)

=== modified file 'bzrlib/tests/test_pack_repository.py'
--- a/bzrlib/tests/test_pack_repository.py	2009-07-17 10:38:41 +0000
+++ b/bzrlib/tests/test_pack_repository.py	2009-08-11 05:26:57 +0000
@@ -865,7 +865,8 @@
         base.commit('foo')
         referencing = self.make_branch_and_tree('repo', format=self.get_format())
         referencing.branch.repository.add_fallback_repository(base.branch.repository)
-        referencing.commit('bar')
+        local_tree = referencing.branch.create_checkout('local')
+        local_tree.commit('bar')
         new_instance = referencing.bzrdir.open_repository()
         new_instance.lock_read()
         self.addCleanup(new_instance.unlock)
@@ -884,13 +885,14 @@
         # and max packs policy - so we are checking the policy is honoured
         # in the test. But for now 11 commits is not a big deal in a single
         # test.
+        local_tree = tree.branch.create_checkout('local')
         for x in range(9):
-            tree.commit('commit %s' % x)
+            local_tree.commit('commit %s' % x)
         # there should be 9 packs:
         index = self.index_class(trans, 'pack-names', None)
         self.assertEqual(9, len(list(index.iter_all_entries())))
         # committing one more should coalesce to 1 of 10.
-        tree.commit('commit triggering pack')
+        local_tree.commit('commit triggering pack')
         index = self.index_class(trans, 'pack-names', None)
         self.assertEqual(1, len(list(index.iter_all_entries())))
         # packing should not damage data
@@ -909,7 +911,7 @@
         # in the obsolete_packs directory.
         large_pack_name = list(index.iter_all_entries())[0][1][0]
         # finally, committing again should not touch the large pack.
-        tree.commit('commit not triggering pack')
+        local_tree.commit('commit not triggering pack')
         index = self.index_class(trans, 'pack-names', None)
         self.assertEqual(2, len(list(index.iter_all_entries())))
         pack_names = [node[1][0] for node in index.iter_all_entries()]

=== modified file 'bzrlib/tests/test_remote.py'
--- a/bzrlib/tests/test_remote.py	2009-07-30 04:27:05 +0000
+++ b/bzrlib/tests/test_remote.py	2009-08-11 05:26:57 +0000
@@ -2651,7 +2651,8 @@
         tree1.commit('rev1', rev_id='rev1')
         tree2 = tree1.branch.bzrdir.sprout('tree2', stacked=True
             ).open_workingtree()
-        tree2.commit('local changes make me feel good.')
+        local_tree = tree2.branch.create_checkout('local')
+        local_tree.commit('local changes make me feel good.')
         branch2 = Branch.open(self.get_url('tree2'))
         branch2.lock_read()
         self.addCleanup(branch2.unlock)
@@ -2727,7 +2728,8 @@
             _, stacked = self.prepare_stacked_remote_branch()
             tree = stacked.bzrdir.sprout('tree3', stacked=True
                 ).open_workingtree()
-            tree.commit('more local changes are better')
+            local_tree = tree.branch.create_checkout('local-tree3')
+            local_tree.commit('more local changes are better')
             branch = Branch.open(self.get_url('tree3'))
             branch.lock_read()
             return None, branch
@@ -2744,8 +2746,9 @@
         # stacked upon sources in topological order.
         rev_ord, expected_revs = self.get_ordered_revs('knit', 'topological')
         self.assertEqual(expected_revs, rev_ord)
-        # Getting topological sort requires VFS calls still
-        self.assertLength(12, self.hpss_calls)
+        # Getting topological sort requires VFS calls still - one of which is
+        # pushing up from the bound branch.
+        self.assertLength(13, self.hpss_calls)
 
     def test_stacked_get_stream_groupcompress(self):
         # Repository._get_source.get_stream() from a stacked repository with




More information about the bazaar-commits mailing list