Rev 4051: Fix race condition with branch hooks during cloning when the new branch is stacked. in http://people.ubuntu.com/~robertc/baz2.0/clone.branch-takes-strategy
Robert Collins
robertc at robertcollins.net
Wed Feb 25 22:17:30 GMT 2009
At http://people.ubuntu.com/~robertc/baz2.0/clone.branch-takes-strategy
------------------------------------------------------------
revno: 4051
revision-id: robertc at robertcollins.net-20090225221725-0795sbskjouaxbm5
parent: pqm at pqm.ubuntu.com-20090225171156-l63eiz2bz51ialsg
committer: Robert Collins <robertc at robertcollins.net>
branch nick: clone.branch-takes-strategy
timestamp: Thu 2009-02-26 09:17:25 +1100
message:
Fix race condition with branch hooks during cloning when the new branch is stacked.
=== modified file 'NEWS'
--- a/NEWS 2009-02-25 14:36:59 +0000
+++ b/NEWS 2009-02-25 22:17:25 +0000
@@ -88,6 +88,13 @@
via RPC calls rather than VFS calls, reducing round trips for
pushing new branches substantially. (Robert Collins)
+ * ``Branch.clone`` now takes the ``repository_policy`` formerly used
+ inside ``BzrDir.clone_on_transport``, allowing stacking to be
+ configured before the branch tags and revision tip are set. This
+ fixes a race condition cloning stacked branches that would cause
+ plugins to have hooks called on non-stacked instances.
+ (Robert Collins, #334187)
+
* ``BzrDirFormat.__str__`` now uses the human readable description
rather than the sometimes-absent disk label. (Robert Collins)
=== modified file 'bzrlib/__init__.py'
--- a/bzrlib/__init__.py 2009-02-13 21:21:25 +0000
+++ b/bzrlib/__init__.py 2009-02-25 22:17:25 +0000
@@ -53,8 +53,8 @@
version_info = (1, 13, 0, 'dev', 0)
-# API compatibility version: bzrlib is currently API compatible with 1.11.
-api_minimum_version = (1, 11, 0)
+# API compatibility version: bzrlib is currently API compatible with 1.13.
+api_minimum_version = (1, 13, 0)
def _format_version_tuple(version_info):
=== modified file 'bzrlib/branch.py'
--- a/bzrlib/branch.py 2009-02-25 15:36:48 +0000
+++ b/bzrlib/branch.py 2009-02-25 22:17:25 +0000
@@ -913,7 +913,7 @@
raise errors.InvalidRevisionNumber(revno)
@needs_read_lock
- def clone(self, to_bzrdir, revision_id=None):
+ def clone(self, to_bzrdir, revision_id=None, repository_policy=None):
"""Clone this branch into to_bzrdir preserving all semantic values.
Most API users will want 'create_clone_on_transport', which creates a
@@ -923,6 +923,8 @@
be truncated to end with revision_id.
"""
result = to_bzrdir.create_branch()
+ if repository_policy is not None:
+ repository_policy.configure_branch(result)
self.copy_content_into(result, revision_id=revision_id)
return result
=== modified file 'bzrlib/bzrdir.py'
--- a/bzrlib/bzrdir.py 2009-02-25 05:36:18 +0000
+++ b/bzrlib/bzrdir.py 2009-02-25 22:17:25 +0000
@@ -229,9 +229,8 @@
# make sure its content is available in the target repository
# clone it.
if local_branch is not None:
- result_branch = local_branch.clone(result, revision_id=revision_id)
- if repository_policy is not None:
- repository_policy.configure_branch(result_branch)
+ result_branch = local_branch.clone(result, revision_id=revision_id,
+ repository_policy=repository_policy)
try:
# Cheaper to check if the target is not local, than to try making
# the tree and fail.
=== modified file 'bzrlib/tests/branch_implementations/test_create_clone.py'
--- a/bzrlib/tests/branch_implementations/test_create_clone.py 2009-02-25 03:22:12 +0000
+++ b/bzrlib/tests/branch_implementations/test_create_clone.py 2009-02-25 22:17:25 +0000
@@ -16,7 +16,9 @@
"""Tests for branch.create_clone behaviour."""
+from bzrlib.branch import Branch
from bzrlib.tests.branch_implementations.test_branch import TestCaseWithBranch
+from bzrlib import remote
class TestCreateClone(TestCaseWithBranch):
@@ -54,3 +56,30 @@
stacked_on=trunk.base)
self.assertEqual(revid, result.last_revision())
self.assertEqual(trunk.base, result.get_stacked_on_url())
+
+ def assertBranchHookBranchIsStacked(self, pre_change_params):
+ # Just calling will either succeed or fail.
+ pre_change_params.branch.get_stacked_on_url()
+ self.hook_calls.append(pre_change_params)
+
+ def test_create_clone_on_transport_stacked_hooks_get_stacked_branch(self):
+ tree = self.make_branch_and_tree('source')
+ tree.commit('a commit')
+ trunk = tree.branch.create_clone_on_transport(
+ self.get_transport('trunk'))
+ revid = tree.commit('a second commit')
+ source = tree.branch
+ target_transport = self.get_transport('target')
+ self.hook_calls = []
+ Branch.hooks.install_named_hook("pre_change_branch_tip",
+ self.assertBranchHookBranchIsStacked, None)
+ result = tree.branch.create_clone_on_transport(target_transport,
+ stacked_on=trunk.base)
+ self.assertEqual(revid, result.last_revision())
+ self.assertEqual(trunk.base, result.get_stacked_on_url())
+ # Smart servers invoke hooks on both sides
+ if isinstance(result, remote.RemoteBranch):
+ expected_calls = 2
+ else:
+ expected_calls = 1
+ self.assertEqual(expected_calls, len(self.hook_calls))
More information about the bazaar-commits
mailing list