Rev 3910: Fix pushing an unstackable branch + stackable repo when there is a in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Wed Dec 17 10:21:43 GMT 2008


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

------------------------------------------------------------
revno: 3910
revision-id: pqm at pqm.ubuntu.com-20081217102138-pz7pfli9o3k50zq7
parent: pqm at pqm.ubuntu.com-20081216173612-rj1jkrqcezr6sb3b
parent: andrew.bennetts at canonical.com-20081217094328-ps24qf79zvl3f23q
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Wed 2008-12-17 10:21:38 +0000
message:
  Fix pushing an unstackable branch + stackable repo when there is a
  	default stacking policy. (Andrew Bennetts)
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
  bzrlib/bzrdir.py               bzrdir.py-20060131065624-156dfea39c4387cb
  bzrlib/tests/blackbox/test_push.py test_push.py-20060329002750-929af230d5d22663
  bzrlib/tests/branch_implementations/__init__.py __init__.py-20060123013057-b12a52c3f361daf4
  bzrlib/tests/branch_implementations/test_push.py test_push.py-20070130153159-fhfap8uoifevg30j-1
  bzrlib/tests/per_repository/test_repository.py test_repository.py-20060131092128-ad07f494f5c9d26c
    ------------------------------------------------------------
    revno: 3904.3.9
    revision-id: andrew.bennetts at canonical.com-20081217094328-ps24qf79zvl3f23q
    parent: andrew.bennetts at canonical.com-20081217084010-zhnl6i5o40yet8lu
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: broken-stacking-fix
    timestamp: Wed 2008-12-17 20:43:28 +1100
    message:
      Add NEWS entry.
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
    ------------------------------------------------------------
    revno: 3904.3.8
    revision-id: andrew.bennetts at canonical.com-20081217084010-zhnl6i5o40yet8lu
    parent: andrew.bennetts at canonical.com-20081216041339-ri040jpm4xs25kl2
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: broken-stacking-fix
    timestamp: Wed 2008-12-17 19:40:10 +1100
    message:
      Add test requested by John, and fix whitespace nit.
    modified:
      bzrlib/bzrdir.py               bzrdir.py-20060131065624-156dfea39c4387cb
      bzrlib/tests/per_repository/test_repository.py test_repository.py-20060131092128-ad07f494f5c9d26c
    ------------------------------------------------------------
    revno: 3904.3.7
    revision-id: andrew.bennetts at canonical.com-20081216041339-ri040jpm4xs25kl2
    parent: andrew.bennetts at canonical.com-20081216025831-vgwlxfoz7n9b8fyh
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: broken-stacking-fix
    timestamp: Tue 2008-12-16 15:13:39 +1100
    message:
      Comment the new tests.
    modified:
      bzrlib/tests/blackbox/test_push.py test_push.py-20060329002750-929af230d5d22663
      bzrlib/tests/branch_implementations/test_push.py test_push.py-20070130153159-fhfap8uoifevg30j-1
    ------------------------------------------------------------
    revno: 3904.3.6
    revision-id: andrew.bennetts at canonical.com-20081216025831-vgwlxfoz7n9b8fyh
    parent: andrew.bennetts at canonical.com-20081216022704-1ntb6qvqfhbecat3
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: broken-stacking-fix
    timestamp: Tue 2008-12-16 13:58:31 +1100
    message:
      Skip test for two formats, and fix format 5 by avoiding a full history sync with non-format5 branches.
    modified:
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
      bzrlib/tests/branch_implementations/test_push.py test_push.py-20070130153159-fhfap8uoifevg30j-1
    ------------------------------------------------------------
    revno: 3904.3.5
    revision-id: andrew.bennetts at canonical.com-20081216022704-1ntb6qvqfhbecat3
    parent: andrew.bennetts at canonical.com-20081216021506-mj4a4qi6mpk3b3x5
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: broken-stacking-fix
    timestamp: Tue 2008-12-16 13:27:04 +1100
    message:
      Improve the test; now 4/7 passing.
    modified:
      bzrlib/tests/branch_implementations/test_push.py test_push.py-20070130153159-fhfap8uoifevg30j-1
    ------------------------------------------------------------
    revno: 3904.3.4
    revision-id: andrew.bennetts at canonical.com-20081216021506-mj4a4qi6mpk3b3x5
    parent: andrew.bennetts at canonical.com-20081216013823-c38v5thz201516iv
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: broken-stacking-fix
    timestamp: Tue 2008-12-16 13:15:06 +1100
    message:
      First cut of a branch_implementations test.  It fails.
    modified:
      bzrlib/tests/branch_implementations/__init__.py __init__.py-20060123013057-b12a52c3f361daf4
      bzrlib/tests/branch_implementations/test_push.py test_push.py-20070130153159-fhfap8uoifevg30j-1
    ------------------------------------------------------------
    revno: 3904.3.3
    revision-id: andrew.bennetts at canonical.com-20081216013823-c38v5thz201516iv
    parent: andrew.bennetts at canonical.com-20081215090640-g4ochmddwvxzl7pp
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: broken-stacking-fix
    timestamp: Tue 2008-12-16 12:38:23 +1100
    message:
      Simplify test slightly.
    modified:
      bzrlib/tests/blackbox/test_push.py test_push.py-20060329002750-929af230d5d22663
    ------------------------------------------------------------
    revno: 3904.3.2
    revision-id: andrew.bennetts at canonical.com-20081215090640-g4ochmddwvxzl7pp
    parent: andrew.bennetts at canonical.com-20081215014836-j5sr891os3sq3sh8
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: broken-stacking-fix
    timestamp: Mon 2008-12-15 20:06:40 +1100
    message:
      Blackbox test that triggers the bug.  Should get replaced with a unit test.
    modified:
      bzrlib/tests/blackbox/test_push.py test_push.py-20060329002750-929af230d5d22663
    ------------------------------------------------------------
    revno: 3904.3.1
    revision-id: andrew.bennetts at canonical.com-20081215014836-j5sr891os3sq3sh8
    parent: pqm at pqm.ubuntu.com-20081213000403-r1acnqhux25xhil1
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: broken-stacking-fix
    timestamp: Mon 2008-12-15 12:48:36 +1100
    message:
      Probable fix for GaryvdM's bug when pushing a stacked qbzr branch to Launchpad.
    modified:
      bzrlib/bzrdir.py               bzrdir.py-20060131065624-156dfea39c4387cb
=== modified file 'NEWS'
--- a/NEWS	2008-12-16 17:36:12 +0000
+++ b/NEWS	2008-12-17 10:21:38 +0000
@@ -42,6 +42,10 @@
     * Don't call iteritems on transport_list_registry, because it may
       change during iteration.  (Martin Pool, #277048)
 
+    * Don't make a broken branch when pushing an unstackable-format branch
+      that's in a stackable shared repository to a location with default
+      stack-on location.  (Andrew Bennetts, #291046)
+
     * Fix compilation error in ``_dirstate_helpers_c`` on SunOS/Solaris.
       (Jari Aalto)
 

=== modified file 'bzrlib/branch.py'
--- a/bzrlib/branch.py	2008-12-01 23:50:52 +0000
+++ b/bzrlib/branch.py	2008-12-16 02:58:31 +0000
@@ -1614,6 +1614,10 @@
         :param revision_id: The revision-id to truncate history at.  May
           be None to copy complete history.
         """
+        if not isinstance(destination._format, BzrBranchFormat5):
+            super(BzrBranch, self)._synchronize_history(
+                destination, revision_id)
+            return
         if revision_id == _mod_revision.NULL_REVISION:
             new_history = []
         else:

=== modified file 'bzrlib/bzrdir.py'
--- a/bzrlib/bzrdir.py	2008-12-15 04:37:10 +0000
+++ b/bzrlib/bzrdir.py	2008-12-17 10:21:38 +0000
@@ -218,6 +218,9 @@
             make_working_trees = local_repo.make_working_trees()
             result_repo = repository_policy.acquire_repository(
                 make_working_trees, local_repo.is_shared())
+            if not require_stacking and repository_policy._require_stacking:
+                require_stacking = True
+                result._format.require_stacking()
             result_repo.fetch(local_repo, revision_id=revision_id)
         else:
             result_repo = None
@@ -1035,25 +1038,8 @@
                 return format
             tree_format = repository._format._matchingbzrdir.workingtree_format
             format.workingtree_format = tree_format.__class__()
-        if (require_stacking and not
-            format.get_branch_format().supports_stacking()):
-            # We need to make a stacked branch, but the default format for the
-            # target doesn't support stacking.  So force a branch that *can*
-            # support stacking.
-            from bzrlib.branch import BzrBranchFormat7
-            format._branch_format = BzrBranchFormat7()
-            mutter("using %r for stacking" % (format._branch_format,))
-            from bzrlib.repofmt import pack_repo
-            if format.repository_format.rich_root_data:
-                bzrdir_format_name = '1.6.1-rich-root'
-                repo_format = pack_repo.RepositoryFormatKnitPack5RichRoot()
-            else:
-                bzrdir_format_name = '1.6'
-                repo_format = pack_repo.RepositoryFormatKnitPack5()
-            note('Source format does not support stacking, using format:'
-                 ' \'%s\'\n  %s\n',
-                 bzrdir_format_name, repo_format.get_format_description())
-            format.repository_format = repo_format
+        if require_stacking:
+            format.require_stacking()
         return format
 
     def checkout_metadir(self):
@@ -2026,6 +2012,26 @@
     def set_branch_format(self, format):
         self._branch_format = format
 
+    def require_stacking(self):
+        if not self.get_branch_format().supports_stacking():
+            # We need to make a stacked branch, but the default format for the
+            # target doesn't support stacking.  So force a branch that *can*
+            # support stacking.
+            from bzrlib.branch import BzrBranchFormat7
+            self._branch_format = BzrBranchFormat7()
+            mutter("using %r for stacking" % (self._branch_format,))
+            from bzrlib.repofmt import pack_repo
+            if self.repository_format.rich_root_data:
+                bzrdir_format_name = '1.6.1-rich-root'
+                repo_format = pack_repo.RepositoryFormatKnitPack5RichRoot()
+            else:
+                bzrdir_format_name = '1.6'
+                repo_format = pack_repo.RepositoryFormatKnitPack5()
+            note('Source format does not support stacking, using format:'
+                 ' \'%s\'\n  %s\n',
+                 bzrdir_format_name, repo_format.get_format_description())
+            self.repository_format = repo_format
+
     def get_converter(self, format=None):
         """See BzrDirFormat.get_converter()."""
         if format is None:
@@ -2906,6 +2912,8 @@
         except errors.UnstackableRepositoryFormat:
             if self._require_stacking:
                 raise
+        else:
+            self._require_stacking = True
 
     def acquire_repository(self, make_working_trees=None, shared=False):
         """Acquire a repository for this bzrdir.

=== modified file 'bzrlib/tests/blackbox/test_push.py'
--- a/bzrlib/tests/blackbox/test_push.py	2008-12-04 16:02:51 +0000
+++ b/bzrlib/tests/blackbox/test_push.py	2008-12-16 04:13:39 +0000
@@ -350,6 +350,38 @@
         self.assertContainsRe(err,
                               'Using default stacking branch stack_on at .*')
 
+    def test_push_doesnt_create_broken_branch(self):
+        """Pushing a new standalone branch works even when there's a default
+        stacking policy at the destination.
+
+        The new branch will preserve the repo format (even if it isn't the
+        default for the branch), and will be stacked when the repo format
+        allows (which means that the branch format isn't necessarly preserved).
+        """
+        self.make_repository('repo', shared=True, format='1.6')
+        builder = self.make_branch_builder('repo/local', format='pack-0.92')
+        builder.start_series()
+        builder.build_snapshot('rev-1', None, [
+            ('add', ('', 'root-id', 'directory', '')),
+            ('add', ('filename', 'f-id', 'file', 'content\n'))])
+        builder.build_snapshot('rev-2', ['rev-1'], [])
+        builder.build_snapshot('rev-3', ['rev-2'],
+            [('modify', ('f-id', 'new-content\n'))])
+        builder.finish_series()
+        branch = builder.get_branch()
+        # Push rev-1 to "trunk", so that we can stack on it.
+        self.run_bzr('push -d repo/local trunk -r 1')
+        # Set a default stacking policy so that new branches will automatically
+        # stack on trunk.
+        self.make_bzrdir('.').get_config().set_default_stack_on('trunk')
+        # Push rev-2 to a new branch "remote".  It will be stacked on "trunk".
+        out, err = self.run_bzr('push -d repo/local remote -r 2')
+        self.assertContainsRe(
+            err, 'Using default stacking branch trunk at .*')
+        # Push rev-3 onto "remote".  If "remote" not stacked and is missing the
+        # fulltext record for f-id @ rev-1, then this will fail.
+        out, err = self.run_bzr('push -d repo/local remote -r 3')
+
 
 class RedirectingMemoryTransport(MemoryTransport):
 

=== modified file 'bzrlib/tests/branch_implementations/__init__.py'
--- a/bzrlib/tests/branch_implementations/__init__.py	2008-11-18 18:43:04 +0000
+++ b/bzrlib/tests/branch_implementations/__init__.py	2008-12-16 02:15:06 +0000
@@ -101,6 +101,12 @@
         except errors.UninitializableFormat:
             raise tests.TestSkipped('Uninitializable branch format')
 
+    def make_branch_builder(self, relpath, format=None):
+        if format is None:
+            format = self.branch_format._matchingbzrdir
+        return super(TestCaseWithBranch, self).make_branch_builder(
+            relpath, format=format)
+
     def make_repository(self, relpath, shared=False, format=None):
         made_control = self.make_bzrdir(relpath, format=format)
         return made_control.create_repository(shared=shared)

=== modified file 'bzrlib/tests/branch_implementations/test_push.py'
--- a/bzrlib/tests/branch_implementations/test_push.py	2008-09-22 05:33:45 +0000
+++ b/bzrlib/tests/branch_implementations/test_push.py	2008-12-16 04:13:39 +0000
@@ -16,6 +16,7 @@
 
 """Tests for branch.push behaviour."""
 
+from cStringIO import StringIO
 import os
  
 from bzrlib import (
@@ -24,6 +25,7 @@
     bzrdir,
     debug,
     errors,
+    push,
     tests,
     )
 from bzrlib.branch import Branch
@@ -177,6 +179,51 @@
         source.branch.push(target, stop_revision='rev-2', overwrite=True)
         self.assertEqual('rev-2', target.last_revision())
 
+    def test_push_with_default_stacking_does_not_create_broken_branch(self):
+        """Pushing a new standalone branch works even when there's a default
+        stacking policy at the destination.
+
+        The new branch will preserve the repo format (even if it isn't the
+        default for the branch), and will be stacked when the repo format
+        allows (which means that the branch format isn't necessarly preserved).
+        """
+        if isinstance(self.branch_format, branch.BzrBranchFormat4):
+            raise tests.TestNotApplicable('Not a metadir format.')
+        if isinstance(self.branch_format, branch.BranchReferenceFormat):
+            # This test could in principle apply to BranchReferenceFormat, but
+            # make_branch_builder doesn't support it.
+            raise tests.TestSkipped(
+                "BranchBuilder can't make reference branches.")
+        # Make a branch called "local" in a stackable repository
+        # The branch has 3 revisions:
+        #   - rev-1, adds a file
+        #   - rev-2, no changes
+        #   - rev-3, modifies the file.
+        repo = self.make_repository('repo', shared=True, format='1.6')
+        builder = self.make_branch_builder('repo/local')
+        builder.start_series()
+        builder.build_snapshot('rev-1', None, [
+            ('add', ('', 'root-id', 'directory', '')),
+            ('add', ('filename', 'f-id', 'file', 'content\n'))])
+        builder.build_snapshot('rev-2', ['rev-1'], [])
+        builder.build_snapshot('rev-3', ['rev-2'],
+            [('modify', ('f-id', 'new-content\n'))])
+        builder.finish_series()
+        trunk = builder.get_branch()
+        # Sprout rev-1 to "trunk", so that we can stack on it.
+        trunk.bzrdir.sprout(self.get_url('trunk'), revision_id='rev-1')
+        # Set a default stacking policy so that new branches will automatically
+        # stack on trunk.
+        self.make_bzrdir('.').get_config().set_default_stack_on('trunk')
+        # Push rev-2 to a new branch "remote".  It will be stacked on "trunk".
+        output = StringIO()
+        push._show_push_branch(trunk, 'rev-2', self.get_url('remote'), output)
+        # Push rev-3 onto "remote".  If "remote" not stacked and is missing the
+        # fulltext record for f-id @ rev-1, then this will fail.
+        remote_branch = Branch.open(self.get_url('remote'))
+        trunk.push(remote_branch)
+        remote_branch.check()
+
 
 class TestPushHook(TestCaseWithBranch):
 

=== modified file 'bzrlib/tests/per_repository/test_repository.py'
--- a/bzrlib/tests/per_repository/test_repository.py	2008-12-10 03:21:33 +0000
+++ b/bzrlib/tests/per_repository/test_repository.py	2008-12-17 08:40:10 +0000
@@ -28,6 +28,7 @@
     remote,
     repository,
     )
+from bzrlib.branch import BzrBranchFormat6
 from bzrlib.delta import TreeDelta
 from bzrlib.inventory import Inventory, InventoryDirectory
 from bzrlib.repofmt.weaverepo import (
@@ -786,6 +787,35 @@
         local_repo = local_bzrdir.open_repository()
         self.assertEqual(remote_backing_repo._format, local_repo._format)
 
+    def test_clone_unstackable_branch_preserves_stackable_repo_format(self):
+        """Cloning an unstackable branch format to a somewhere with a default
+        stack-on branch preserves the repository format.  (i.e. if the source
+        repository is stackable, the branch format is upgraded but the
+        repository format is preserved.)
+        """
+        try:
+            repo = self.make_repository('repo', shared=True)
+        except errors.IncompatibleFormat:
+            raise TestNotApplicable('Cannot make a shared repository')
+        # Make a source branch in 'repo' in an unstackable branch format
+        bzrdir_format = self.repository_format._matchingbzrdir
+        transport = self.get_transport('repo/branch')
+        transport.mkdir('.')
+        target_bzrdir = bzrdir_format.initialize_on_transport(transport)
+        branch = BzrBranchFormat6().initialize(target_bzrdir)
+        #branch = self.make_branch('repo/branch', format='pack-0.92')
+        self.make_branch('stack-on-me')
+        self.make_bzrdir('.').get_config().set_default_stack_on('stack-on-me')
+        target = branch.bzrdir.clone(self.get_url('target'))
+        # The target branch supports stacking if the source repository does.
+        self.assertEqual(repo._format.supports_external_lookups,
+                         target.open_branch()._format.supports_stacking())
+        if isinstance(repo, remote.RemoteRepository):
+            repo._ensure_real()
+            repo = repo._real_repository
+        # The repository format is preserved.
+        self.assertEqual(repo._format, target.open_repository()._format)
+
     def test__make_parents_provider(self):
         """Repositories must have a _make_parents_provider method that returns
         an object with a get_parent_map method.




More information about the bazaar-commits mailing list