Rev 4166: Fix bzr failing to stack when a server requests it and the branch it is pushing from cannot stack but the branch it should stack on can. in http://people.ubuntu.com/~robertc/baz2.0/pending/bug-345169
Robert Collins
robertc at robertcollins.net
Thu Mar 19 04:08:27 GMT 2009
At http://people.ubuntu.com/~robertc/baz2.0/pending/bug-345169
------------------------------------------------------------
revno: 4166
revision-id: robertc at robertcollins.net-20090319040821-c1id0avkcpjvr0hw
parent: pqm at pqm.ubuntu.com-20090319035632-3o6ewx7kwnk42b63
committer: Robert Collins <robertc at robertcollins.net>
branch nick: bug-345169
timestamp: Thu 2009-03-19 15:08:21 +1100
message:
Fix bzr failing to stack when a server requests it and the branch it is pushing from cannot stack but the branch it should stack on can.
=== modified file 'NEWS'
--- a/NEWS 2009-03-19 03:13:24 +0000
+++ b/NEWS 2009-03-19 04:08:21 +0000
@@ -83,6 +83,12 @@
* ``merge --force`` works again. (Robert Collins, #342105)
+* Pushing a new branch to a server that has a stacking policy will now
+ upgrade from the local branch format when the stacking policy points at
+ a branch which is itself stackable, because we know the client can read
+ both branches, we know that the trunk for the project can be read too,
+ so the upgrade will not inconvenience users. (Robert Collins, #345169)
+
* The GNU Changelog formatter is slightly improved in the case where
the delta is empty, and now correctly claims not to support tags.
(Andrea Bolognani)
=== modified file 'bzrlib/bzrdir.py'
--- a/bzrlib/bzrdir.py 2009-03-18 15:38:56 +0000
+++ b/bzrlib/bzrdir.py 2009-03-19 04:08:21 +0000
@@ -192,6 +192,8 @@
transport.ensure_base()
require_stacking = (stacked_on is not None)
format = self.cloning_metadir(require_stacking)
+ # Bug: We create a metadir without knowing if it can support stacking,
+ # we should look up the policy needs first.
result = format.initialize_on_transport(transport)
repository_policy = None
try:
@@ -387,8 +389,8 @@
stack_on_pwd=None, require_stacking=False):
"""Return an object representing a policy to use.
- This controls whether a new repository is created, or a shared
- repository used instead.
+ This controls whether a new repository is created, and the format of
+ that repository, or some existing shared repository used instead.
If stack_on is supplied, will not seek a containing shared repo.
@@ -408,8 +410,6 @@
if stack_on is not None:
stack_on_pwd = found_bzrdir.root_transport.base
stop = True
- note('Using default stacking branch %s at %s', stack_on,
- stack_on_pwd)
# does it have a repository ?
try:
repository = found_bzrdir.open_repository()
@@ -418,7 +418,9 @@
else:
if ((found_bzrdir.root_transport.base !=
self.root_transport.base) and not repository.is_shared()):
+ # Don't look higher, can't use a higher shared repo.
repository = None
+ stop = True
else:
stop = True
if not stop:
@@ -2833,14 +2835,15 @@
# Always return a RemoteRepositoryFormat object, but if a specific bzr
# repository format has been asked for, tell the RemoteRepositoryFormat
# that it should use that for init() etc.
- result = remote.RemoteRepositoryFormat()
+ result = remote.RemoteRepositoryFormat()
custom_format = getattr(self, '_repository_format', None)
if custom_format:
- # We will use the custom format to create repositories over the
- # wire; expose its details like rich_root_data for code to query
if isinstance(custom_format, remote.RemoteRepositoryFormat):
- result._custom_format = custom_format._custom_format
+ return custom_format
else:
+ # We will use the custom format to create repositories over the
+ # wire; expose its details like rich_root_data for code to
+ # query
result._custom_format = custom_format
return result
@@ -3148,6 +3151,50 @@
Creates the desired repository in the bzrdir we already have.
"""
+ stack_on = self._get_full_stack_on()
+ if stack_on:
+ # Stacking is desired. requested by the target, but does the place it
+ # points at support stacking? If it doesn't then we should
+ # not implicitly upgrade. We check this here.
+ format = self._bzrdir._format
+ if not (format.repository_format.supports_external_lookups
+ and format.get_branch_format().supports_stacking()):
+ # May need to upgrade - but only do if the target also
+ # supports stacking. Note that this currently wastes
+ # network round trips to check - but we only do this
+ # when the source can't stack so it will fade away
+ # as people do upgrade.
+ try:
+ target_dir = BzrDir.open(stack_on,
+ possible_transports=[self._bzrdir.root_transport])
+ except errors.NotBranchError:
+ # Nothing there, don't change formats
+ pass
+ else:
+ try:
+ target_branch = target_dir.open_branch()
+ except errors.NotBranchError:
+ # No branch, don't change formats
+ pass
+ else:
+ branch_format = target_branch._format
+ repo_format = target_branch.repository._format
+ if not (branch_format.supports_stacking()
+ and repo_format.supports_external_lookups):
+ # Doesn't stack itself, don't force an upgrade
+ pass
+ else:
+ # Does support stacking, use its format.
+ format.repository_format = repo_format
+ format.set_branch_format(branch_format)
+ note('Source format does not support stacking, '
+ 'using format: \'%s\'\n %s\n',
+ branch_format.get_format_description(),
+ repo_format.get_format_description())
+ if not self._require_stacking:
+ # We have picked up automatic stacking somewhere.
+ note('Using default stacking branch %s at %s', self._stack_on,
+ self._stack_on_pwd)
repository = self._bzrdir.create_repository(shared=shared)
self._add_fallback(repository,
possible_transports=[self._bzrdir.transport])
=== modified file 'bzrlib/tests/blackbox/test_push.py'
--- a/bzrlib/tests/blackbox/test_push.py 2009-03-16 05:33:31 +0000
+++ b/bzrlib/tests/blackbox/test_push.py 2009-03-19 04:08:21 +0000
@@ -392,6 +392,23 @@
self.assertContainsRe(err,
'Using default stacking branch stack_on at .*')
+ def test_push_stacks_with_default_stacking_if_target_is_stackable(self):
+ self.make_branch('stack_on', format='1.6')
+ self.make_bzrdir('.').get_config().set_default_stack_on('stack_on')
+ self.make_branch('from', format='pack-0.92')
+ out, err = self.run_bzr('push -d from to')
+ branch = Branch.open('to')
+ self.assertEqual('../stack_on', branch.get_stacked_on_url())
+
+ def test_push_does_not_change_format_with_default_if_target_cannot(self):
+ self.make_branch('stack_on', format='pack-0.92')
+ self.make_bzrdir('.').get_config().set_default_stack_on('stack_on')
+ self.make_branch('from', format='pack-0.92')
+ out, err = self.run_bzr('push -d from to')
+ branch = Branch.open('to')
+ self.assertRaises(errors.UnstackableBranchFormat,
+ branch.get_stacked_on_url)
+
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.
More information about the bazaar-commits
mailing list