Rev 5732: (spiv) Merge lp:bzr/2.3, in file:///home/pqm/archives/thelove/bzr/%2Btrunk/
Canonical.com Patch Queue Manager
pqm at pqm.ubuntu.com
Wed Mar 23 05:55:54 UTC 2011
At file:///home/pqm/archives/thelove/bzr/%2Btrunk/
------------------------------------------------------------
revno: 5732 [merge]
revision-id: pqm at pqm.ubuntu.com-20110323055551-yy88m30tldulmg2t
parent: pqm at pqm.ubuntu.com-20110322163939-lju83ajjj2eh7n60
parent: andrew.bennetts at canonical.com-20110323051548-rit3h3i274gszs2n
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Wed 2011-03-23 05:55:51 +0000
message:
(spiv) Merge lp:bzr/2.3,
including fixes for #465517 and #733350. (Andrew Bennetts)
modified:
bzrlib/branch.py branch.py-20050309040759-e4baf4e0d046576e
bzrlib/controldir.py controldir.py-20100802102926-hvtvh0uae5epuibp-1
bzrlib/tests/blackbox/test_push.py test_push.py-20060329002750-929af230d5d22663
bzrlib/tests/per_branch/test_branch.py testbranch.py-20050711070244-121d632bc37d7253
bzrlib/tests/per_branch/test_push.py test_push.py-20070130153159-fhfap8uoifevg30j-1
doc/en/release-notes/bzr-2.3.txt NEWS-20050323055033-4e00b5db738777ff
=== modified file 'bzrlib/branch.py'
--- a/bzrlib/branch.py 2011-03-09 01:31:04 +0000
+++ b/bzrlib/branch.py 2011-03-23 05:15:48 +0000
@@ -79,8 +79,9 @@
:ivar base:
Base directory/url of the branch; using control_url and
control_transport is more standardized.
-
- hooks: An instance of BranchHooks.
+ :ivar hooks: An instance of BranchHooks.
+ :ivar _master_branch_cache: cached result of get_master_branch, see
+ _clear_cached_state.
"""
# this is really an instance variable - FIXME move it there
# - RBC 20060112
@@ -102,6 +103,7 @@
self._partial_revision_history_cache = []
self._tags_bytes = None
self._last_revision_info_cache = None
+ self._master_branch_cache = None
self._merge_sorted_revisions_cache = None
self._open_hook()
hooks = Branch.hooks['open']
@@ -937,6 +939,7 @@
self._revision_history_cache = None
self._revision_id_to_revno_cache = None
self._last_revision_info_cache = None
+ self._master_branch_cache = None
self._merge_sorted_revisions_cache = None
self._partial_revision_history_cache = []
self._partial_revision_id_to_revno_cache = {}
@@ -2637,8 +2640,7 @@
target.update_revisions(self, stop_revision,
overwrite=overwrite, graph=graph)
if self._push_should_merge_tags():
- result.tag_conflicts = self.tags.merge_to(target.tags,
- overwrite)
+ result.tag_conflicts = self.tags.merge_to(target.tags, overwrite)
result.new_revno, result.new_revid = target.last_revision_info()
return result
@@ -2676,12 +2678,13 @@
"""Return the branch we are bound to.
:return: Either a Branch, or None
-
- This could memoise the branch, but if thats done
- it must be revalidated on each new lock.
- So for now we just don't memoise it.
- # RBC 20060304 review this decision.
"""
+ if self._master_branch_cache is None:
+ self._master_branch_cache = self._get_master_branch(
+ possible_transports)
+ return self._master_branch_cache
+
+ def _get_master_branch(self, possible_transports):
bound_loc = self.get_bound_location()
if not bound_loc:
return None
@@ -2698,6 +2701,7 @@
:param location: URL to the target branch
"""
+ self._master_branch_cache = None
if location:
self._transport.put_bytes('bound', location+'\n',
mode=self.bzrdir._get_file_mode())
@@ -2955,6 +2959,7 @@
def set_bound_location(self, location):
"""See Branch.set_push_location."""
+ self._master_branch_cache = None
result = None
config = self.get_config()
if location is None:
=== modified file 'bzrlib/controldir.py'
--- a/bzrlib/controldir.py 2011-03-12 21:22:14 +0000
+++ b/bzrlib/controldir.py 2011-03-23 05:15:48 +0000
@@ -480,6 +480,10 @@
if br_to is None:
# We have a repository but no branch, copy the revisions, and then
# create a branch.
+ if revision_id is None:
+ # No revision supplied by the user, default to the branch
+ # revision
+ revision_id = source.last_revision()
repository_to.fetch(source.repository, revision_id=revision_id)
br_to = source.clone(self, revision_id=revision_id)
if source.get_push_location() is None or remember:
=== modified file 'bzrlib/tests/blackbox/test_push.py'
--- a/bzrlib/tests/blackbox/test_push.py 2011-01-10 22:20:12 +0000
+++ b/bzrlib/tests/blackbox/test_push.py 2011-03-21 14:35:33 +0000
@@ -204,6 +204,22 @@
% tuple(map(urlutils.local_path_to_url, ['from', 'to-two'])))
self.failUnlessExists('to-two')
+ def test_push_repository_no_branch_doesnt_fetch_all_revs(self):
+ # See https://bugs.launchpad.net/bzr/+bug/465517
+ target_repo = self.make_repository('target')
+ source = self.make_branch_builder('source')
+ source.start_series()
+ source.build_snapshot('A', None, [
+ ('add', ('', 'root-id', 'directory', None))])
+ source.build_snapshot('B', ['A'], [])
+ source.build_snapshot('C', ['A'], [])
+ source.finish_series()
+ self.run_bzr('push target -d source')
+ self.addCleanup(target_repo.lock_read().unlock)
+ # We should have pushed 'C', but not 'B', since it isn't in the
+ # ancestry
+ self.assertEqual([('A',), ('C',)], sorted(target_repo.revisions.keys()))
+
def test_push_smart_non_stacked_streaming_acceptance(self):
self.setup_smart_server_with_call_log()
t = self.make_branch_and_tree('from')
=== modified file 'bzrlib/tests/per_branch/test_branch.py'
--- a/bzrlib/tests/per_branch/test_branch.py 2011-02-21 07:27:20 +0000
+++ b/bzrlib/tests/per_branch/test_branch.py 2011-03-23 05:15:48 +0000
@@ -736,6 +736,66 @@
except errors.UpgradeRequired:
raise tests.TestNotApplicable('Format does not support binding')
+ def test_unbind_clears_cached_master_branch(self):
+ """b.unbind clears any cached value of b.get_master_branch."""
+ master = self.make_branch('master')
+ branch = self.make_branch('branch')
+ try:
+ branch.bind(master)
+ except errors.UpgradeRequired:
+ raise tests.TestNotApplicable('Format does not support binding')
+ self.addCleanup(branch.lock_write().unlock)
+ self.assertNotEqual(None, branch.get_master_branch())
+ branch.unbind()
+ self.assertEqual(None, branch.get_master_branch())
+
+ def test_unlocked_does_not_cache_master_branch(self):
+ """Unlocked branches do not cache the result of get_master_branch."""
+ master = self.make_branch('master')
+ branch1 = self.make_branch('branch')
+ try:
+ branch1.bind(master)
+ except errors.UpgradeRequired:
+ raise tests.TestNotApplicable('Format does not support binding')
+ # Open branch1 again
+ branch2 = branch1.bzrdir.open_branch()
+ self.assertNotEqual(None, branch1.get_master_branch())
+ # Unbind the branch via branch2. branch1 isn't locked so will
+ # immediately return the new value for get_master_branch.
+ branch2.unbind()
+ self.assertEqual(None, branch1.get_master_branch())
+
+ def test_bind_clears_cached_master_branch(self):
+ """b.bind clears any cached value of b.get_master_branch."""
+ master1 = self.make_branch('master1')
+ master2 = self.make_branch('master2')
+ branch = self.make_branch('branch')
+ try:
+ branch.bind(master1)
+ except errors.UpgradeRequired:
+ raise tests.TestNotApplicable('Format does not support binding')
+ self.addCleanup(branch.lock_write().unlock)
+ self.assertNotEqual(None, branch.get_master_branch())
+ branch.bind(master2)
+ self.assertEqual('.', urlutils.relative_url(self.get_url('master2'),
+ branch.get_master_branch().base))
+
+ def test_set_bound_location_clears_cached_master_branch(self):
+ """b.set_bound_location clears any cached value of b.get_master_branch.
+ """
+ master1 = self.make_branch('master1')
+ master2 = self.make_branch('master2')
+ branch = self.make_branch('branch')
+ try:
+ branch.bind(master1)
+ except errors.UpgradeRequired:
+ raise tests.TestNotApplicable('Format does not support binding')
+ self.addCleanup(branch.lock_write().unlock)
+ self.assertNotEqual(None, branch.get_master_branch())
+ branch.set_bound_location(self.get_url('master2'))
+ self.assertEqual('.', urlutils.relative_url(self.get_url('master2'),
+ branch.get_master_branch().base))
+
class TestStrict(per_branch.TestCaseWithBranch):
=== modified file 'bzrlib/tests/per_branch/test_push.py'
--- a/bzrlib/tests/per_branch/test_push.py 2011-02-24 16:45:27 +0000
+++ b/bzrlib/tests/per_branch/test_push.py 2011-03-23 05:15:48 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2007-2010 Canonical Ltd
+# Copyright (C) 2007-2011 Canonical Ltd
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -114,6 +114,23 @@
self.assertRaises(errors.BoundBranchConnectionFailure,
other.branch.push, checkout.branch)
+ def test_push_new_tag_to_bound_branch(self):
+ master = self.make_branch('master')
+ bound = self.make_branch('bound')
+ try:
+ bound.bind(master)
+ except errors.UpgradeRequired:
+ raise tests.TestNotApplicable(
+ 'Format does not support bound branches')
+ other = bound.bzrdir.sprout('other').open_branch()
+ try:
+ other.tags.set_tag('new-tag', 'some-rev')
+ except errors.TagsNotSupported:
+ raise tests.TestNotApplicable('Format does not support tags')
+ other.push(bound)
+ self.assertEqual({'new-tag': 'some-rev'}, bound.tags.get_tag_dict())
+ self.assertEqual({'new-tag': 'some-rev'}, master.tags.get_tag_dict())
+
def test_push_uses_read_lock(self):
"""Push should only need a read lock on the source side."""
source = self.make_branch_and_tree('source')
@@ -201,6 +218,41 @@
source.branch.push(target, stop_revision='rev-2', overwrite=True)
self.assertEqual('rev-2', target.last_revision())
+ def test_push_repository_no_branch_doesnt_fetch_all_revs(self):
+ # See https://bugs.launchpad.net/bzr/+bug/465517
+ t = self.get_transport('target')
+ t.ensure_base()
+ bzrdir = self.bzrdir_format.initialize_on_transport(t)
+ try:
+ bzrdir.open_branch()
+ except errors.NotBranchError:
+ pass
+ else:
+ raise tests.TestNotApplicable('older formats can\'t have a repo'
+ ' without a branch')
+ try:
+ source = self.make_branch_builder('source',
+ format=self.bzrdir_format)
+ except errors.UninitializableFormat:
+ raise tests.TestNotApplicable('cannot initialize this format')
+ source.start_series()
+ source.build_snapshot('A', None, [
+ ('add', ('', 'root-id', 'directory', None))])
+ source.build_snapshot('B', ['A'], [])
+ source.build_snapshot('C', ['A'], [])
+ source.finish_series()
+ b = source.get_branch()
+ # Note: We can't read lock the source branch. Some formats take a write
+ # lock to 'set_push_location', which breaks
+ self.addCleanup(b.lock_write().unlock)
+ repo = bzrdir.create_repository()
+ # This means 'push the source branch into this dir'
+ bzrdir.push_branch(b)
+ self.addCleanup(repo.lock_read().unlock)
+ # We should have pushed 'C', but not 'B', since it isn't in the
+ # ancestry
+ self.assertEqual([('A',), ('C',)], sorted(repo.revisions.keys()))
+
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.
=== modified file 'doc/en/release-notes/bzr-2.3.txt'
--- a/doc/en/release-notes/bzr-2.3.txt 2011-03-14 14:45:42 +0000
+++ b/doc/en/release-notes/bzr-2.3.txt 2011-03-23 05:15:48 +0000
@@ -32,6 +32,15 @@
.. Fixes for situations where bzr would previously crash or give incorrect
or undesirable results.
+* ``bzr push`` into a repository (that doesn't have a branch), will no
+ longer copy all revisions in the repository. Only the ones in the
+ ancestry of the source branch, like it does in all other cases.
+ (John Arbash Meinel, #465517)
+
+* Fix "Unable to obtain lock" error when pushing to a bound branch if tags
+ had changed. Bazaar was attempting to open and lock the master branch
+ twice in this case. (Andrew Bennetts, #733350)
+
Documentation
*************
More information about the bazaar-commits
mailing list