Rev 4548: Fix issues with keys/ids and ghost handling. in http://bazaar.launchpad.net/~jameinel/bzr/1.18-bundle-and-stack-393349

John Arbash Meinel john at arbash-meinel.com
Wed Jul 22 20:44:03 BST 2009


At http://bazaar.launchpad.net/~jameinel/bzr/1.18-bundle-and-stack-393349

------------------------------------------------------------
revno: 4548
revision-id: john at arbash-meinel.com-20090722194355-0rq7hl5tquowejv8
parent: john at arbash-meinel.com-20090722190001-pmvwietxxfgdf214
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: 1.18-bundle-and-stack-393349
timestamp: Wed 2009-07-22 14:43:55 -0500
message:
  Fix issues with keys/ids and ghost handling.
-------------- next part --------------
=== modified file 'bzrlib/bundle/serializer/v4.py'
--- a/bzrlib/bundle/serializer/v4.py	2009-07-22 19:00:01 +0000
+++ b/bzrlib/bundle/serializer/v4.py	2009-07-22 19:43:55 +0000
@@ -332,16 +332,21 @@
         inventory_key_order = [(r,) for r in revision_order]
         parent_map = self.repository.inventories.get_parent_map(
                             inventory_key_order)
+        missing_keys = set(inventory_key_order).difference(parent_map)
+        if missing_keys:
+            raise errors.RevisionNotPresent(list(missing_keys)[0],
+                                            self.repository.inventories)
         inv_to_str = self.repository._serializer.write_inventory_to_string
         # Make sure that we grab the parent texts first
         just_parents = set()
         map(just_parents.update, parent_map.itervalues())
-        just_parents.difference_update(revision_order)
+        just_parents.difference_update(parent_map)
         # Ignore ghost parents
         if _mod_revision.NULL_REVISION in just_parents:
             import pdb; pdb.set_trace()
         present_parents = self.repository.inventories.get_parent_map(
                             just_parents)
+        ghost_keys = just_parents.difference(present_parents)
         needed_inventories = list(present_parents) + inventory_key_order
         needed_inventories = [k[-1] for k in needed_inventories]
         all_lines = {}
@@ -353,17 +358,22 @@
             # form-in-the-repository
             sha1 = osutils.sha_string(as_bytes)
             as_lines = osutils.split_lines(as_bytes)
-            all_lines[revision_id] = as_lines
+            del as_bytes
+            all_lines[key] = as_lines
             if key in just_parents:
                 # We don't transmit those entries
                 continue
             # Create an mpdiff for this text, and add it to the output
             parent_keys = parent_map[key]
-            parent_ids = [k[-1] for k in parent_keys]
-            parent_lines = [all_lines[p_id] for p_id in parent_ids]
+            # See the comment in VF.make_mpdiffs about how this effects
+            # ordering when there are ghosts present. I think we have a latent
+            # bug
+            parent_lines = [all_lines[p_key] for p_key in parent_keys
+                            if p_key not in ghost_keys]
             diff = multiparent.MultiParent.from_lines(
                 as_lines, parent_lines)
             text = ''.join(diff.to_patch())
+            parent_ids = [k[-1] for k in parent_keys]
             self.bundle.add_multiparent_record(text, sha1, parent_ids,
                                                'inventory', revision_id, None)
 

=== modified file 'bzrlib/tests/test_bundle.py'
--- a/bzrlib/tests/test_bundle.py	2009-07-22 19:00:01 +0000
+++ b/bzrlib/tests/test_bundle.py	2009-07-22 19:43:55 +0000
@@ -1434,7 +1434,7 @@
     def bzrdir_format(self):
         return '2a'
 
-    def test_inventories_as_xml_texts(self):
+    def make_merged_branch(self):
         builder = self.make_branch_builder('source',
                                            format=self.bzrdir_format())
         builder.start_series()
@@ -1456,14 +1456,22 @@
         self.b1.lock_read()
         self.addCleanup(self.b1.unlock)
 
+    def make_bundle_just_inventories(self, base_revision_id,
+                                     target_revision_id,
+                                     revision_ids):
         sio = StringIO()
-        writer = v4.BundleWriteOperation('a at cset-0-1', 'a at cset-0-3',
+        writer = v4.BundleWriteOperation(base_revision_id, target_revision_id,
                                          self.b1.repository, sio)
         writer.bundle.begin()
-        writer._add_inventory_mpdiffs_from_serializer(
-            ['a at cset-0-3'])
+        writer._add_inventory_mpdiffs_from_serializer(revision_ids)
         writer.bundle.end()
         sio.seek(0)
+        return sio
+
+    def test_single_inventory_multiple_parents_as_xml(self):
+        self.make_merged_branch()
+        sio = self.make_bundle_just_inventories('a at cset-0-1', 'a at cset-0-3',
+                                                ['a at cset-0-3'])
         reader = v4.BundleReader(sio, stream_input=False)
         records = list(reader.iter_records())
         self.assertEqual(1, len(records))
@@ -1485,6 +1493,93 @@
             'c 0 1 1 1\n'
             'c 1 2 2 2\n', bytes)
 
+    def test_single_inv_no_parents_as_xml(self):
+        self.make_merged_branch()
+        sio = self.make_bundle_just_inventories('null:', 'a at cset-0-1',
+                                                ['a at cset-0-1'])
+        reader = v4.BundleReader(sio, stream_input=False)
+        records = list(reader.iter_records())
+        self.assertEqual(1, len(records))
+        (bytes, metadata, repo_kind, revision_id,
+         file_id) = records[0]
+        self.assertIs(None, file_id)
+        self.assertEqual('a at cset-0-1', revision_id)
+        self.assertEqual('inventory', repo_kind)
+        self.assertEqual({'parents': [],
+                          'sha1': 'f6ed523eebc7d813d1adbdaf3754c00e1de49446',
+                          'storage_kind': 'mpdiff',
+                         }, metadata)
+        # We should have an mpdiff that takes some lines from both parents.
+        self.assertEqualDiff(
+            'i 3\n'
+            '<inventory file_id="root-id" format="5"'
+                ' revision_id="a at cset-0-1">\n'
+            '<file file_id="file-id" name="file" parent_id="root-id"'
+                ' revision="a at cset-0-1"'
+                ' text_sha1="09c2f8647e14e49e922b955c194102070597c2d1"'
+                ' text_size="17" />\n'
+            '</inventory>\n'
+            '\n', bytes)
+
+    def test_multiple_inventories_as_xml(self):
+        self.make_merged_branch()
+        sio = self.make_bundle_just_inventories('a at cset-0-1', 'a at cset-0-3',
+            ['a at cset-0-2a', 'a at cset-0-2b', 'a at cset-0-3'])
+        reader = v4.BundleReader(sio, stream_input=False)
+        records = list(reader.iter_records())
+        self.assertEqual(3, len(records))
+        revision_ids = [rev_id for b, m, k, rev_id, f in records]
+        self.assertEqual(['a at cset-0-2a', 'a at cset-0-2b', 'a at cset-0-3'],
+                         revision_ids)
+        metadata_2a = records[0][1]
+        self.assertEqual({'parents': ['a at cset-0-1'],
+                          'sha1': 'a699b8d8fe87361ad758e99655afab44aca287b2',
+                          'storage_kind': 'mpdiff',
+                         }, metadata_2a)
+        metadata_2b = records[1][1]
+        self.assertEqual({'parents': ['a at cset-0-1'],
+                          'sha1': 'c2bab5eda6a31f206042f0fcacc175b76c65a376',
+                          'storage_kind': 'mpdiff',
+                         }, metadata_2b)
+        metadata_3 = records[2][1]
+        self.assertEqual({'parents': ['a at cset-0-2a', 'a at cset-0-2b'],
+                          'sha1': 'c08b0f8cc256107f0229c98931d1d69c0e843196',
+                          'storage_kind': 'mpdiff',
+                         }, metadata_3)
+        bytes_2a = records[0][0]
+        self.assertEqualDiff(
+            'i 2\n'
+            '<inventory file_id="root-id" format="5"'
+                ' revision_id="a at cset-0-2a">\n'
+            '<file file_id="file-id" name="file" parent_id="root-id"'
+                ' revision="a at cset-0-2a"'
+                ' text_sha1="50f545ff40e57b6924b1f3174b267ffc4576e9a9"'
+                ' text_size="12" />\n'
+            '\n'
+            'c 0 2 2 1\n', bytes_2a)
+        bytes_2b = records[1][0]
+        self.assertEqualDiff(
+            'i 1\n'
+            '<inventory file_id="root-id" format="5"'
+                ' revision_id="a at cset-0-2b">\n'
+            '\n'
+            'c 0 1 1 1\n'
+            'i 1\n'
+            '<file file_id="file2-id" name="other-file" parent_id="root-id"'
+                ' revision="a at cset-0-2b"'
+                ' text_sha1="b46c0c8ea1e5ef8e46fc8894bfd4752a88ec939e"'
+                ' text_size="14" />\n'
+            '\n'
+            'c 0 2 3 1\n', bytes_2b)
+        bytes_3 = records[2][0]
+        self.assertEqualDiff(
+            'i 1\n'
+            '<inventory file_id="root-id" format="5"'
+                ' revision_id="a at cset-0-3">\n'
+            '\n'
+            'c 0 1 1 1\n'
+            'c 1 2 2 2\n', bytes_3)
+
 
 class MungedBundleTester(object):
 



More information about the bazaar-commits mailing list