Merge lp:~spiv/bzr/hpss-cross-format-fetch-bug-427736 into lp:bzr/2.0

Proposed by Andrew Bennetts
Status: Merged
Merged at revision: not available
Proposed branch: lp:~spiv/bzr/hpss-cross-format-fetch-bug-427736
Merge into: lp:bzr/2.0
Diff against target: 86 lines
3 files modified
NEWS (+4/-0)
bzrlib/remote.py (+3/-2)
bzrlib/tests/per_interrepository/test_fetch.py (+38/-0)
To merge this branch: bzr merge lp:~spiv/bzr/hpss-cross-format-fetch-bug-427736
Reviewer Review Type Date Requested Status
Robert Collins (community) Approve
Review via email: mp+12771@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Andrew Bennetts (spiv) wrote :

This fixes "unknown object type identifier 60" in bencode when pulling some branches.

It turns out that the client-side RemoteStreamSource was using the wrong serialiser to decode revision fulltexts in a stream of a stacked branch (it decodes them to extract the parent_ids so that it knows if there are any missing revisions that it needs to ask the next fallback for). Using the wrong serialiser doesn't matter if the revision serialiser is the same on both sides, and similarly this code doesn't get involved when there is no stacking. So this was just obscure enough a case that the test suite wasn't exercising it.

The fix is a one-liner, and I've added interrepo tests for this case.

Revision history for this message
Robert Collins (lifeless) wrote :

 review +1

perhaps change serialiser to from_serialise to make it unambiguous?

-Rob

review: Approve
Revision history for this message
Andrew Bennetts (spiv) wrote :

Robert Collins wrote:
> Review: Approve
> review +1
>
> perhaps change serialiser to from_serialise to make it unambiguous?

Good idea, done.

Thanks for the swift review!

-Andrew.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'NEWS'
2--- NEWS 2009-10-01 00:56:56 +0000
3+++ NEWS 2009-10-02 03:10:22 +0000
4@@ -22,6 +22,10 @@
5 ``keyboard-interactive`` auth but not ``password`` auth when using
6 Paramiko. (Andrew Bennetts, #433846)
7
8+* Fixed fetches from a stacked branch on a smart server that were failing
9+ with some combinations of remote and local formats. This was causing
10+ "unknown object type identifier 60" errors. (Andrew Bennetts, #427736)
11+
12 * Occasional IndexError on renamed files have been fixed. Operations that
13 set a full inventory in the working tree will now go via the
14 apply_inventory_delta code path which is simpler and easier to
15
16=== modified file 'bzrlib/remote.py'
17--- bzrlib/remote.py 2009-09-10 06:32:42 +0000
18+++ bzrlib/remote.py 2009-10-02 03:10:22 +0000
19@@ -1887,7 +1887,7 @@
20 :param search: The overall search to satisfy with streams.
21 :param sources: A list of Repository objects to query.
22 """
23- self.serialiser = self.to_format._serializer
24+ self.from_serialiser = self.from_repository._format._serializer
25 self.seen_revs = set()
26 self.referenced_revs = set()
27 # If there are heads in the search, or the key count is > 0, we are not
28@@ -1910,7 +1910,8 @@
29 def missing_parents_rev_handler(self, substream):
30 for content in substream:
31 revision_bytes = content.get_bytes_as('fulltext')
32- revision = self.serialiser.read_revision_from_string(revision_bytes)
33+ revision = self.from_serialiser.read_revision_from_string(
34+ revision_bytes)
35 self.seen_revs.add(content.key[-1])
36 self.referenced_revs.update(revision.parent_ids)
37 yield content
38
39=== modified file 'bzrlib/tests/per_interrepository/test_fetch.py'
40--- bzrlib/tests/per_interrepository/test_fetch.py 2009-09-09 02:14:12 +0000
41+++ bzrlib/tests/per_interrepository/test_fetch.py 2009-10-02 03:10:22 +0000
42@@ -134,6 +134,44 @@
43 to_repo.texts.get_record_stream([('foo', revid)],
44 'unordered', True).next().get_bytes_as('fulltext'))
45
46+ def test_fetch_from_stacked_smart(self):
47+ self.setup_smart_server_with_call_log()
48+ self.test_fetch_from_stacked()
49+
50+ def test_fetch_from_stacked_smart_old(self):
51+ self.setup_smart_server_with_call_log()
52+ self.disable_verb('Repository.get_stream_1.19')
53+ self.test_fetch_from_stacked()
54+
55+ def test_fetch_from_stacked(self):
56+ """Fetch from a stacked branch succeeds."""
57+ if not self.repository_format.supports_external_lookups:
58+ raise TestNotApplicable("Need stacking support in the source.")
59+ builder = self.make_branch_builder('full-branch')
60+ builder.start_series()
61+ builder.build_snapshot('first', None, [
62+ ('add', ('', 'root-id', 'directory', '')),
63+ ('add', ('file', 'file-id', 'file', 'content\n'))])
64+ builder.build_snapshot('second', ['first'], [
65+ ('modify', ('file-id', 'second content\n'))])
66+ builder.build_snapshot('third', ['second'], [
67+ ('modify', ('file-id', 'third content\n'))])
68+ builder.finish_series()
69+ branch = builder.get_branch()
70+ repo = self.make_repository('stacking-base')
71+ trunk = repo.bzrdir.create_branch()
72+ trunk.repository.fetch(branch.repository, 'second')
73+ repo = self.make_repository('stacked')
74+ stacked_branch = repo.bzrdir.create_branch()
75+ stacked_branch.set_stacked_on_url(trunk.base)
76+ stacked_branch.repository.fetch(branch.repository, 'third')
77+ target = self.make_to_repository('target')
78+ target.fetch(stacked_branch.repository, 'third')
79+ target.lock_read()
80+ self.addCleanup(target.unlock)
81+ all_revs = set(['first', 'second', 'third'])
82+ self.assertEqual(all_revs, set(target.get_parent_map(all_revs)))
83+
84 def test_fetch_parent_inventories_at_stacking_boundary_smart(self):
85 self.setup_smart_server_with_call_log()
86 self.test_fetch_parent_inventories_at_stacking_boundary()

Subscribers

People subscribed via source and target branches