Rev 4293: Merge with .dev. in http://people.ubuntu.com/~robertc/baz2.0/pending/push.roundtrips
Robert Collins
robertc at robertcollins.net
Wed Apr 15 01:01:13 BST 2009
At http://people.ubuntu.com/~robertc/baz2.0/pending/push.roundtrips
------------------------------------------------------------
revno: 4293 [merge]
revision-id: robertc at robertcollins.net-20090415000035-h0xsked0o73un7gi
parent: robertc at robertcollins.net-20090414071101-kmlsxria9ok4ldx5
parent: pqm at pqm.ubuntu.com-20090414031543-gqbs23oebd68p7h7
committer: Robert Collins <robertc at robertcollins.net>
branch nick: push.roundtrips
timestamp: Wed 2009-04-15 10:00:35 +1000
message:
Merge with .dev.
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/branchbuilder.py branchbuilder.py-20070427022007-zlxpqz2lannhk6y8-1
bzrlib/fetch.py fetch.py-20050818234941-26fea6105696365d
bzrlib/remote.py remote.py-20060720103555-yeeg2x51vn0rbtdp-1
bzrlib/repository.py rev_storage.py-20051111201905-119e9401e46257e3
bzrlib/tests/__init__.py selftest.py-20050531073622-8d0e3c8845c97a64
bzrlib/tests/blackbox/test_push.py test_push.py-20060329002750-929af230d5d22663
bzrlib/tests/interrepository_implementations/__init__.py __init__.py-20060220054744-baf49a1f88f17b1a
bzrlib/tests/interrepository_implementations/test_fetch.py test_fetch.py-20080425213627-j60cjh782ufm83ry-1
------------------------------------------------------------
Use --levels 0 (or -n0) to see merged revisions.
=== modified file 'NEWS'
--- a/NEWS 2009-04-14 07:11:01 +0000
+++ b/NEWS 2009-04-15 00:00:35 +0000
@@ -252,6 +252,14 @@
both branches, we know that the trunk for the project can be read too,
so the upgrade will not inconvenience users. (Robert Collins, #345169)
+* Pushing a new stacked branch will also push the parent inventories for
+ revisions at the stacking boundary. This makes sure that the stacked
+ branch has enough data to calculate inventory deltas for all of its
+ revisions (without requiring the fallback branch). This avoids
+ "'AbsentContentFactory' object has no attribute 'get_bytes_as'" errors
+ when fetching the stacked branch from a 1.13 (or later) smart server.
+ This partially fixes #354036. (Andrew Bennetts, Robert Collins)
+
* The full test suite is passing again on OSX. Several minor issues (mostly
test related) have been fixed. (Vincent Ladeuil, #355273).
=== modified file 'bzrlib/branchbuilder.py'
--- a/bzrlib/branchbuilder.py 2009-03-23 14:59:43 +0000
+++ b/bzrlib/branchbuilder.py 2009-04-09 02:59:17 +0000
@@ -56,7 +56,7 @@
a series in progress, it should be None.
"""
- def __init__(self, transport, format=None):
+ def __init__(self, transport=None, format=None, branch=None):
"""Construct a BranchBuilder on transport.
:param transport: The transport the branch should be created on.
@@ -64,15 +64,26 @@
it will be created.
:param format: Either a BzrDirFormat, or the name of a format in the
bzrdir format registry for the branch to be built.
+ :param branch: An already constructed branch to use. This param is
+ mutually exclusive with the transport and format params.
"""
- if not transport.has('.'):
- transport.mkdir('.')
- if format is None:
- format = 'default'
- if isinstance(format, str):
- format = bzrdir.format_registry.make_bzrdir(format)
- self._branch = bzrdir.BzrDir.create_branch_convenience(transport.base,
- format=format, force_new_tree=False)
+ if branch is not None:
+ if format is not None:
+ raise AssertionError(
+ "branch and format kwargs are mutually exclusive")
+ if transport is not None:
+ raise AssertionError(
+ "branch and transport kwargs are mutually exclusive")
+ self._branch = branch
+ else:
+ if not transport.has('.'):
+ transport.mkdir('.')
+ if format is None:
+ format = 'default'
+ if isinstance(format, str):
+ format = bzrdir.format_registry.make_bzrdir(format)
+ self._branch = bzrdir.BzrDir.create_branch_convenience(
+ transport.base, format=format, force_new_tree=False)
self._tree = None
def build_commit(self, **commit_kwargs):
=== modified file 'bzrlib/fetch.py'
--- a/bzrlib/fetch.py 2009-03-30 11:49:32 +0000
+++ b/bzrlib/fetch.py 2009-04-14 03:15:43 +0000
@@ -136,6 +136,18 @@
pb.update("Inserting stream")
resume_tokens, missing_keys = self.sink.insert_stream(
stream, from_format, [])
+ if self.to_repository._fallback_repositories:
+ # Find all the parent revisions referenced by the stream, but
+ # not present in the stream, and make sure we have their
+ # inventories.
+ revision_ids = search.get_keys()
+ parent_maps = self.to_repository.get_parent_map(revision_ids)
+ parents = set()
+ map(parents.update, parent_maps.itervalues())
+ parents.difference_update(revision_ids)
+ parents.discard(NULL_REVISION)
+ missing_keys.update(
+ ('inventories', rev_id) for rev_id in parents)
if missing_keys:
pb.update("Missing keys")
stream = source.get_stream_for_missing_keys(missing_keys)
=== modified file 'bzrlib/remote.py'
--- a/bzrlib/remote.py 2009-04-14 07:11:01 +0000
+++ b/bzrlib/remote.py 2009-04-15 00:00:35 +0000
@@ -1644,7 +1644,7 @@
if response[0][0] == 'missing-basis':
tokens, missing_keys = bencode.bdecode_as_tuple(response[0][1])
resume_tokens = tokens
- return resume_tokens, missing_keys
+ return resume_tokens, set(missing_keys)
else:
self.target_repo.refresh_data()
return [], set()
=== modified file 'bzrlib/repository.py'
--- a/bzrlib/repository.py 2009-04-09 20:23:07 +0000
+++ b/bzrlib/repository.py 2009-04-14 03:15:43 +0000
@@ -3362,7 +3362,7 @@
@classmethod
def _get_repo_format_to_test(self):
from bzrlib.repofmt import pack_repo
- return pack_repo.RepositoryFormatKnitPack1()
+ return pack_repo.RepositoryFormatKnitPack6RichRoot()
@staticmethod
def is_compatible(source, target):
@@ -3626,9 +3626,28 @@
to_texts.insert_record_stream(from_texts.get_record_stream(
text_keys, self.target._format._fetch_order,
not self.target._format._fetch_uses_deltas))
- # insert deltas
+ # insert inventory deltas
for delta in pending_deltas:
self.target.add_inventory_by_delta(*delta)
+ if self.target._fallback_repositories:
+ # Make sure this stacked repository has all the parent inventories
+ # for the new revisions that we are about to insert. We do this
+ # before adding the revisions so that no revision is added until
+ # all the inventories it may depend on are added.
+ parent_ids = set()
+ revision_ids = set()
+ for revision in pending_revisions:
+ revision_ids.add(revision.revision_id)
+ parent_ids.update(revision.parent_ids)
+ parent_ids.difference_update(revision_ids)
+ parent_ids.discard(_mod_revision.NULL_REVISION)
+ parent_map = self.source.get_parent_map(parent_ids)
+ for parent_tree in self.source.revision_trees(parent_ids):
+ basis_id, delta = self._get_delta_for_revision(tree, parent_ids, basis_id, cache)
+ current_revision_id = parent_tree.get_revision_id()
+ parents_parents = parent_map[current_revision_id]
+ self.target.add_inventory_by_delta(
+ basis_id, delta, current_revision_id, parents_parents)
# insert signatures and revisions
for revision in pending_revisions:
try:
=== modified file 'bzrlib/tests/__init__.py'
--- a/bzrlib/tests/__init__.py 2009-04-09 23:12:55 +0000
+++ b/bzrlib/tests/__init__.py 2009-04-14 03:15:43 +0000
@@ -2154,8 +2154,8 @@
return memorytree.MemoryTree.create_on_branch(b)
def make_branch_builder(self, relpath, format=None):
- return branchbuilder.BranchBuilder(self.get_transport(relpath),
- format=format)
+ branch = self.make_branch(relpath, format=format)
+ return branchbuilder.BranchBuilder(branch=branch)
def overrideEnvironmentForTesting(self):
os.environ['HOME'] = self.test_home_dir
=== modified file 'bzrlib/tests/blackbox/test_push.py'
--- a/bzrlib/tests/blackbox/test_push.py 2009-04-14 07:11:01 +0000
+++ b/bzrlib/tests/blackbox/test_push.py 2009-04-15 00:00:35 +0000
@@ -217,7 +217,7 @@
# being too low. If rpc_count increases, more network roundtrips have
# become necessary for this use case. Please do not adjust this number
# upwards without agreement from bzr's network support maintainers.
- self.assertLength(36, self.hpss_calls)
+ self.assertLength(37, self.hpss_calls)
remote = Branch.open('public')
self.assertEndsWith(remote.get_stacked_on_url(), '/parent')
=== modified file 'bzrlib/tests/interrepository_implementations/__init__.py'
--- a/bzrlib/tests/interrepository_implementations/__init__.py 2009-03-23 14:59:43 +0000
+++ b/bzrlib/tests/interrepository_implementations/__init__.py 2009-04-09 02:59:17 +0000
@@ -32,9 +32,10 @@
)
from bzrlib.repository import (
- InterKnitRepo,
- InterRepository,
- )
+ InterDifferingSerializer,
+ InterKnitRepo,
+ InterRepository,
+ )
from bzrlib.tests import (
default_transport,
multiply_tests,
@@ -107,6 +108,9 @@
result.append((InterKnitRepo,
pack_repo.RepositoryFormatKnitPack3(),
pack_repo.RepositoryFormatKnitPack4()))
+ result.append((InterDifferingSerializer,
+ pack_repo.RepositoryFormatKnitPack1(),
+ pack_repo.RepositoryFormatKnitPack6RichRoot()))
return result
=== modified file 'bzrlib/tests/interrepository_implementations/test_fetch.py'
--- a/bzrlib/tests/interrepository_implementations/test_fetch.py 2009-03-30 11:49:32 +0000
+++ b/bzrlib/tests/interrepository_implementations/test_fetch.py 2009-04-14 03:15:43 +0000
@@ -124,6 +124,44 @@
to_repo.texts.get_record_stream([('foo', revid)],
'unordered', True).next().get_bytes_as('fulltext'))
+ def test_fetch_parent_inventories_at_stacking_boundary(self):
+ """Fetch to a stacked branch copies inventories for parents of
+ revisions at the stacking boundary.
+
+ This is necessary so that the server is able to determine the file-ids
+ altered by all revisions it contains, which means that it needs both
+ the inventory for any revision it has, and the inventories of all that
+ revision's parents.
+ """
+ to_repo = self.make_to_repository('to')
+ if not to_repo._format.supports_external_lookups:
+ raise TestNotApplicable("Need stacking support in the target.")
+ builder = self.make_branch_builder('branch')
+ builder.start_series()
+ builder.build_snapshot('base', None, [
+ ('add', ('', 'root-id', 'directory', ''))])
+ builder.build_snapshot('left', ['base'], [])
+ builder.build_snapshot('right', ['base'], [])
+ builder.build_snapshot('merge', ['left', 'right'], [])
+ builder.finish_series()
+ branch = builder.get_branch()
+ repo = self.make_to_repository('trunk')
+ trunk = repo.bzrdir.create_branch()
+ trunk.repository.fetch(branch.repository, 'left')
+ trunk.repository.fetch(branch.repository, 'right')
+ repo = self.make_to_repository('stacked')
+ stacked_branch = repo.bzrdir.create_branch()
+ stacked_branch.set_stacked_on_url(trunk.base)
+ stacked_branch.repository.fetch(branch.repository, 'merge')
+ unstacked_repo = stacked_branch.bzrdir.open_repository()
+ unstacked_repo.lock_read()
+ self.addCleanup(unstacked_repo.unlock)
+ self.assertFalse(unstacked_repo.has_revision('left'))
+ self.assertFalse(unstacked_repo.has_revision('right'))
+ self.assertEqual(
+ set([('left',), ('right',), ('merge',)]),
+ unstacked_repo.inventories.keys())
+
def test_fetch_missing_basis_text(self):
"""If fetching a delta, we should die if a basis is not present."""
tree = self.make_branch_and_tree('tree')
More information about the bazaar-commits
mailing list