Rev 2818: * Inventory serialisation no longer double-sha's the content. in http://people.ubuntu.com/~robertc/baz2.0/add_inventory

Robert Collins robertc at robertcollins.net
Thu Sep 13 23:32:00 BST 2007


At http://people.ubuntu.com/~robertc/baz2.0/add_inventory

------------------------------------------------------------
revno: 2818
revision-id: robertc at robertcollins.net-20070913223115-2jt3z24pinb3m54n
parent: pqm at pqm.ubuntu.com-20070912222627-zvqit350mf6gvrbh
committer: Robert Collins <robertc at robertcollins.net>
branch nick: add_inventory
timestamp: Fri 2007-09-14 08:31:15 +1000
message:
  * Inventory serialisation no longer double-sha's the content.
    (Robert Collins)
  
  * XML inventory serialisation is 10 to 15 percent faster while being
    stricter about the contents. (Robert Collins)
  
  * Tree's with bad state such as files with no length or sha will no longer
    be silently accepted by the repository XML serialiser. To serialise
    inventories without such data, pass working=True to write_inventory.
    (Robert Collins)
  
  * New method on xml serialisers, write_inventory_to_lines, which matches the
    API used by knits for adding content. (Robert Collins)
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/benchmarks/tree_creator/kernel_like.py kernel_like.py-20060815024128-b16a7pn542u6b13k-1
  bzrlib/bzrdir.py               bzrdir.py-20060131065624-156dfea39c4387cb
  bzrlib/repofmt/knitrepo.py     knitrepo.py-20070206081537-pyy4a00xdas0j4pf-1
  bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
  bzrlib/tests/test_xml.py       test_xml.py-20050905091053-80b45588931a9b35
  bzrlib/workingtree.py          workingtree.py-20050511021032-29b6ec0a681e02e3
  bzrlib/xml4.py                 xml4.py-20050916091259-db5ab55e7e6ca324
  bzrlib/xml5.py                 xml5.py-20050907032657-aac8f960815b66b1
  bzrlib/xml6.py                 xml6.py-20060823042456-dbaaq4atrche7xy5-1
  bzrlib/xml_serializer.py       xml.py-20050309040759-57d51586fdec365d
=== modified file 'NEWS'
--- a/NEWS	2007-09-12 21:27:42 +0000
+++ b/NEWS	2007-09-13 22:31:15 +0000
@@ -13,6 +13,12 @@
 
   PERFORMANCE:
 
+   * Inventory serialisation no longer double-sha's the content.
+     (Robert Collins)
+
+   * XML inventory serialisation is 10 to 15 percent faster while being
+     stricter about the contents. (Robert Collins)
+
   IMPROVEMENTS:
 
   BUG FIXES:
@@ -22,7 +28,17 @@
    * The ``VersionedFile`` interface now allows content checks to be bypassed
      by supplying check_content=False.  This saves nearly 30% of the minimum
      cost to store a version of a file. (Robert Collins)
-  
+
+   * Tree's with bad state such as files with no length or sha will no longer
+     be silently accepted by the repository XML serialiser. To serialise
+     inventories without such data, pass working=True to write_inventory.
+     (Robert Collins)
+
+  INTERNALS:
+
+   * New method on xml serialisers, write_inventory_to_lines, which matches the
+     API used by knits for adding content. (Robert Collins)
+
   TESTING:
 
 

=== modified file 'bzrlib/benchmarks/tree_creator/kernel_like.py'
--- a/bzrlib/benchmarks/tree_creator/kernel_like.py	2007-07-04 02:43:26 +0000
+++ b/bzrlib/benchmarks/tree_creator/kernel_like.py	2007-09-13 22:31:15 +0000
@@ -210,7 +210,12 @@
                                                  link_bzr=True,
                                                  hot_cache=False)
         tree = creator.create('.')
-        return tree.basis_tree().inventory
+        basis = tree.basis_tree()
+        basis.lock_read()
+        try:
+            return basis.inventory
+        finally:
+            basis.unlock()
 
     def _open_cached(self, cache_dir):
         f = open(cache_dir + '/inventory', 'rb')

=== modified file 'bzrlib/bzrdir.py'
--- a/bzrlib/bzrdir.py	2007-09-10 12:12:47 +0000
+++ b/bzrlib/bzrdir.py	2007-09-13 22:31:15 +0000
@@ -1805,7 +1805,7 @@
     def _convert_working_inv(self):
         inv = xml4.serializer_v4.read_inventory(
                     self.branch.control_files.get('inventory'))
-        new_inv_xml = xml5.serializer_v5.write_inventory_to_string(inv)
+        new_inv_xml = xml5.serializer_v5.write_inventory_to_string(inv, working=True)
         # FIXME inventory is a working tree change.
         self.branch.control_files.put('inventory', StringIO(new_inv_xml))
 
@@ -1890,10 +1890,10 @@
         present_parents = [p for p in rev.parent_ids
                            if p not in self.absent_revisions]
         self._convert_revision_contents(rev, inv, present_parents)
-        self._store_new_weave(rev, inv, present_parents)
+        self._store_new_inv(rev, inv, present_parents)
         self.converted_revs.add(rev_id)
 
-    def _store_new_weave(self, rev, inv, present_parents):
+    def _store_new_inv(self, rev, inv, present_parents):
         # the XML is now updated with text versions
         if __debug__:
             entries = inv.iter_entries()
@@ -1904,7 +1904,7 @@
                     (file_id, rev.revision_id)
         new_inv_xml = xml5.serializer_v5.write_inventory_to_string(inv)
         new_inv_sha1 = sha_string(new_inv_xml)
-        self.inv_weave.add_lines(rev.revision_id, 
+        self.inv_weave.add_lines(rev.revision_id,
                                  present_parents,
                                  new_inv_xml.splitlines(True))
         rev.inventory_sha1 = new_inv_sha1

=== modified file 'bzrlib/repofmt/knitrepo.py'
--- a/bzrlib/repofmt/knitrepo.py	2007-09-12 04:21:51 +0000
+++ b/bzrlib/repofmt/knitrepo.py	2007-09-13 22:31:15 +0000
@@ -75,8 +75,8 @@
         pass
 
     def _inventory_add_lines(self, inv_vf, revid, parents, lines, check_content):
-        inv_vf.add_lines_with_ghosts(revid, parents, lines,
-            check_content=check_content)
+        return inv_vf.add_lines_with_ghosts(revid, parents, lines,
+            check_content=check_content)[0]
 
     @needs_read_lock
     def _all_revision_ids(self):

=== modified file 'bzrlib/repository.py'
--- a/bzrlib/repository.py	2007-09-12 21:27:42 +0000
+++ b/bzrlib/repository.py	2007-09-13 22:31:15 +0000
@@ -120,22 +120,20 @@
             "Mismatch between inventory revision" \
             " id and insertion revid (%r, %r)" % (inv.revision_id, revision_id)
         assert inv.root is not None
-        inv_text = self.serialise_inventory(inv)
-        inv_sha1 = osutils.sha_string(inv_text)
-        inv_vf = self.control_weaves.get_weave('inventory',
-                                               self.get_transaction())
-        self._inventory_add_lines(inv_vf, revision_id, parents,
-            osutils.split_lines(inv_text), check_content=False)
-        return inv_sha1
+        inv_lines = self._serialise_inventory_to_lines(inv)
+        inv_vf = self.get_inventory_weave()
+        return self._inventory_add_lines(inv_vf, revision_id, parents,
+            inv_lines, check_content=False)
 
     def _inventory_add_lines(self, inv_vf, revision_id, parents, lines,
         check_content=True):
+        """Store lines in inv_vf and return the sha1 of the inventory."""
         final_parents = []
         for parent in parents:
             if parent in inv_vf:
                 final_parents.append(parent)
-        inv_vf.add_lines(revision_id, final_parents, lines,
-            check_content=check_content)
+        return inv_vf.add_lines(revision_id, final_parents, lines,
+            check_content=check_content)[0]
 
     @needs_write_lock
     def add_revision(self, revision_id, rev, inv=None, config=None):
@@ -842,6 +840,9 @@
     def serialise_inventory(self, inv):
         return self._serializer.write_inventory_to_string(inv)
 
+    def _serialise_inventory_to_lines(self, inv):
+        return self._serializer.write_inventory_to_lines(inv)
+
     def get_serializer_format(self):
         return self._serializer.format_num
 

=== modified file 'bzrlib/tests/test_xml.py'
--- a/bzrlib/tests/test_xml.py	2007-06-26 19:31:00 +0000
+++ b/bzrlib/tests/test_xml.py	2007-09-13 22:31:15 +0000
@@ -81,14 +81,16 @@
 _committed_inv_v5 = """<inventory>
 <file file_id="bar-20050901064931-73b4b1138abc9cd2" 
       name="bar" parent_id="TREE_ROOT" 
-      revision="mbp at foo-123123"/>
+      revision="mbp at foo-123123"
+      text_sha1="A" text_size="1"/>
 <directory name="subdir"
            file_id="foo-20050801201819-4139aa4a272f4250"
            parent_id="TREE_ROOT" 
            revision="mbp at foo-00"/>
 <file executable="yes" file_id="bar-20050824000535-6bc48cfad47ed134" 
       name="bar" parent_id="foo-20050801201819-4139aa4a272f4250" 
-      revision="mbp at foo-00"/>
+      revision="mbp at foo-00"
+      text_sha1="B" text_size="0"/>
 </inventory>
 """
 
@@ -121,25 +123,26 @@
 
 # DO NOT REFLOW THIS. Its the exact inventory we want.
 _expected_inv_v5 = """<inventory format="5">
-<file file_id="bar-20050901064931-73b4b1138abc9cd2" name="bar" revision="mbp at foo-123123" />
+<file file_id="bar-20050901064931-73b4b1138abc9cd2" name="bar" revision="mbp at foo-123123" text_sha1="A" text_size="1" />
 <directory file_id="foo-20050801201819-4139aa4a272f4250" name="subdir" revision="mbp at foo-00" />
-<file executable="yes" file_id="bar-20050824000535-6bc48cfad47ed134" name="bar" parent_id="foo-20050801201819-4139aa4a272f4250" revision="mbp at foo-00" />
+<file executable="yes" file_id="bar-20050824000535-6bc48cfad47ed134" name="bar" parent_id="foo-20050801201819-4139aa4a272f4250" revision="mbp at foo-00" text_sha1="B" text_size="0" />
 </inventory>
 """
 
 
 _expected_inv_v5_root = """<inventory file_id="f&lt;" format="5" revision_id="mother!">
-<file file_id="bar-20050901064931-73b4b1138abc9cd2" name="bar" parent_id="f&lt;" revision="mbp at foo-123123" />
+<file file_id="bar-20050901064931-73b4b1138abc9cd2" name="bar" parent_id="f&lt;" revision="mbp at foo-123123" text_sha1="A" text_size="1" />
 <directory file_id="foo-20050801201819-4139aa4a272f4250" name="subdir" parent_id="f&lt;" revision="mbp at foo-00" />
-<file executable="yes" file_id="bar-20050824000535-6bc48cfad47ed134" name="bar" parent_id="foo-20050801201819-4139aa4a272f4250" revision="mbp at foo-00" />
+<file executable="yes" file_id="bar-20050824000535-6bc48cfad47ed134" name="bar" parent_id="foo-20050801201819-4139aa4a272f4250" revision="mbp at foo-00" text_sha1="B" text_size="0" />
+<symlink file_id="link-1" name="link" parent_id="foo-20050801201819-4139aa4a272f4250" revision="mbp at foo-00" symlink_target="a" />
 </inventory>
 """
 
 _expected_inv_v7 = """<inventory format="7" revision_id="rev_outer">
 <directory file_id="tree-root-321" name="" revision="rev_outer" />
 <directory file_id="dir-id" name="dir" parent_id="tree-root-321" revision="rev_outer" />
-<file file_id="file-id" name="file" parent_id="tree-root-321" revision="rev_outer" />
-<symlink file_id="link-id" name="link" parent_id="tree-root-321" revision="rev_outer" />
+<file file_id="file-id" name="file" parent_id="tree-root-321" revision="rev_outer" text_sha1="A" text_size="1" />
+<symlink file_id="link-id" name="link" parent_id="tree-root-321" revision="rev_outer" symlink_target="a" />
 <tree-reference file_id="nested-id" name="nested" parent_id="tree-root-321" revision="rev_outer" reference_revision="rev_inner" />
 </inventory>
 """
@@ -258,6 +261,9 @@
         outp = StringIO()
         bzrlib.xml5.serializer_v5.write_inventory(inv, outp)
         self.assertEqualDiff(xml_string, outp.getvalue())
+        lines = bzrlib.xml5.serializer_v5.write_inventory_to_lines(inv)
+        outp.seek(0)
+        self.assertEqual(outp.readlines(), lines)
         inv2 = bzrlib.xml5.serializer_v5.read_inventory(StringIO(outp.getvalue()))
         self.assertEqual(inv, inv2)
 
@@ -314,8 +320,13 @@
         inv['tree-root-321'].revision = 'rev_outer'
         inv['dir-id'].revision = 'rev_outer'
         inv['file-id'].revision = 'rev_outer'
+        inv['file-id'].text_sha1 = 'A'
+        inv['file-id'].text_size = 1
         inv['link-id'].revision = 'rev_outer'
+        inv['link-id'].symlink_target = 'a'
         txt = xml7.serializer_v7.write_inventory_to_string(inv)
+        lines = xml7.serializer_v7.write_inventory_to_lines(inv)
+        self.assertEqual(bzrlib.osutils.split_lines(txt), lines)
         self.assertEqualDiff(_expected_inv_v7, txt)
         inv2 = xml7.serializer_v7.read_inventory_from_string(txt)
         self.assertEqual(5, len(inv2))
@@ -335,14 +346,17 @@
         s_v5 = bzrlib.xml5.serializer_v5
         s_v6 = bzrlib.xml6.serializer_v6
         s_v7 = xml7.serializer_v7
-        inv = Inventory('tree-root-321')
+        inv = Inventory('tree-root-321', revision_id='rev-outer')
+        inv.root.revision = 'root-rev'
         inv.add(inventory.TreeReference('nested-id', 'nested', 'tree-root-321',
                                         'rev-outer', 'rev-inner'))
-        self.assertRaises(errors.UnsupportedInventoryKind, 
+        self.assertRaises(errors.UnsupportedInventoryKind,
                           s_v5.write_inventory_to_string, inv)
-        self.assertRaises(errors.UnsupportedInventoryKind, 
+        self.assertRaises(errors.UnsupportedInventoryKind,
                           s_v6.write_inventory_to_string, inv)
         txt = s_v7.write_inventory_to_string(inv)
+        lines = s_v7.write_inventory_to_lines(inv)
+        self.assertEqual(bzrlib.osutils.split_lines(txt), lines)
         inv2 = s_v7.read_inventory_from_string(txt)
         self.assertEqual('tree-root-321', inv2['nested-id'].parent_id)
         self.assertEqual('rev-outer', inv2['nested-id'].revision)

=== modified file 'bzrlib/workingtree.py'
--- a/bzrlib/workingtree.py	2007-09-10 12:12:47 +0000
+++ b/bzrlib/workingtree.py	2007-09-13 22:31:15 +0000
@@ -995,7 +995,8 @@
         return wt
 
     def _serialize(self, inventory, out_file):
-        xml5.serializer_v5.write_inventory(self._inventory, out_file)
+        xml5.serializer_v5.write_inventory(self._inventory, out_file,
+            working=True)
 
     def _deserialize(selt, in_file):
         return xml5.serializer_v5.read_inventory(in_file)
@@ -2640,7 +2641,7 @@
         """
         sio = StringIO()
         inv = Inventory()
-        xml5.serializer_v5.write_inventory(inv, sio)
+        xml5.serializer_v5.write_inventory(inv, sio, working=True)
         sio.seek(0)
         control_files.put('inventory', sio)
 

=== modified file 'bzrlib/xml4.py'
--- a/bzrlib/xml4.py	2007-02-02 04:49:38 +0000
+++ b/bzrlib/xml4.py	2007-09-13 22:31:15 +0000
@@ -17,30 +17,20 @@
 from bzrlib.xml_serializer import ElementTree, SubElement, Element, Serializer
 from bzrlib.inventory import ROOT_ID, Inventory, InventoryEntry
 import bzrlib.inventory as inventory
-from bzrlib.revision import Revision        
+from bzrlib.revision import Revision
 from bzrlib.errors import BzrError
 
 
 class _Serializer_v4(Serializer):
     """Version 0.0.4 serializer
 
-    You should use the serializer_v4 singleton."""
+    You should use the serializer_v4 singleton.
+    
+    v4 serialisation is no longer supported, only deserialisation.
+    """
     
     __slots__ = []
     
-    def _pack_inventory(self, inv):
-        """Convert to XML Element"""
-        # v4 serialization is not used any more.
-        raise NotImplementedError(self._pack_inventory)
-        e = Element('inventory')
-        e.text = '\n'
-        if inv.root.file_id not in (None, ROOT_ID):
-            e.set('file_id', inv.root.file_id)
-        for path, ie in inv.iter_entries():
-            e.append(self._pack_entry(ie))
-        return e
-
-
     def _pack_entry(self, ie):
         """Convert InventoryEntry to XML element"""
         e = Element('entry')

=== modified file 'bzrlib/xml5.py'
--- a/bzrlib/xml5.py	2007-07-17 13:27:14 +0000
+++ b/bzrlib/xml5.py	2007-09-13 22:31:15 +0000
@@ -146,6 +146,7 @@
     
     __slots__ = []
 
+    root_id = ROOT_ID
     support_altered_by_hack = True
     # This format supports the altered-by hack that reads file ids directly out
     # of the versionedfile, without doing XML parsing.
@@ -153,17 +154,29 @@
     supported_kinds = set(['file', 'directory', 'symlink'])
     format_num = '5'
 
-    def write_inventory_to_string(self, inv):
-        """Just call write_inventory with a StringIO and return the value"""
+    def write_inventory_to_lines(self, inv):
+        """Return a list of lines with the encoded inventory."""
+        return self.write_inventory(inv, None)
+
+    def write_inventory_to_string(self, inv, working=False):
+        """Just call write_inventory with a StringIO and return the value.
+
+        :param working: If True skip history data - text_sha1, text_size,
+            reference_revision, symlink_target.
+        """
         sio = cStringIO.StringIO()
-        self.write_inventory(inv, sio)
+        self.write_inventory(inv, sio, working)
         return sio.getvalue()
 
-    def write_inventory(self, inv, f):
+    def write_inventory(self, inv, f, working=False):
         """Write inventory to a file.
         
         :param inv: the inventory to write.
-        :param f: the file to write.
+        :param f: the file to write. (May be None if the lines are the desired
+            output).
+        :param working: If True skip history data - text_sha1, text_size,
+            reference_revision, symlink_target.
+        :return: The inventory as a list of lines.
         """
         _ensure_utf8_re()
         output = []
@@ -173,64 +186,102 @@
         # Skip the root
         root_path, root_ie = entries.next()
         for path, ie in entries:
-            self._append_entry(append, ie)
+            self._append_entry(append, ie, working)
         append('</inventory>\n')
-        f.writelines(output)
+        if f is not None:
+            f.writelines(output)
         # Just to keep the cache from growing without bounds
         # but we may actually not want to do clear the cache
         #_clear_cache()
+        return output
 
     def _append_inventory_root(self, append, inv):
         """Append the inventory root to output."""
-        append('<inventory')
         if inv.root.file_id not in (None, ROOT_ID):
-            append(' file_id="')
-            append(_encode_and_escape(inv.root.file_id))
-        append(' format="5"')
+            fileid1 = ' file_id="'
+            fileid2 = _encode_and_escape(inv.root.file_id)
+        else:
+            fileid1 = ""
+            fileid2 = ""
         if inv.revision_id is not None:
-            append(' revision_id="')
-            append(_encode_and_escape(inv.revision_id))
-        append('>\n')
+            revid1 = ' revision_id="'
+            revid2 = _encode_and_escape(inv.revision_id)
+        else:
+            revid1 = ""
+            revid2 = ""
+        append('<inventory%s%s format="5"%s%s>\n' % (
+            fileid1, fileid2, revid1, revid2))
         
-    def _append_entry(self, append, ie):
+    def _append_entry(self, append, ie, working):
         """Convert InventoryEntry to XML element and append to output."""
-        # TODO: should just be a plain assertion
-        if ie.kind not in self.supported_kinds:
+        if ie.parent_id != self.root_id:
+            parent_str = ' parent_id="'
+            parent_id  = _encode_and_escape(ie.parent_id)
+        else:
+            parent_str = ''
+            parent_id  = ''
+        if ie.kind == 'file':
+            if ie.executable:
+                executable = ' executable="yes"'
+            else:
+                executable = ''
+            if not working:
+                append('<file%s file_id="%s name="%s%s%s revision="%s '
+                    'text_sha1="%s" text_size="%d" />\n' % (
+                    executable, _encode_and_escape(ie.file_id),
+                    _encode_and_escape(ie.name), parent_str, parent_id,
+                    _encode_and_escape(ie.revision), ie.text_sha1,
+                    ie.text_size))
+            else:
+                append('<file%s file_id="%s name="%s%s%s />\n' % (
+                    executable, _encode_and_escape(ie.file_id),
+                    _encode_and_escape(ie.name), parent_str, parent_id))
+        elif ie.kind == 'directory':
+            if not working:
+                append('<directory file_id="%s name="%s%s%s revision="%s '
+                    '/>\n' % (
+                    _encode_and_escape(ie.file_id),
+                    _encode_and_escape(ie.name),
+                    parent_str, parent_id,
+                    _encode_and_escape(ie.revision)))
+            else:
+                append('<directory file_id="%s name="%s%s%s />\n' % (
+                    _encode_and_escape(ie.file_id),
+                    _encode_and_escape(ie.name),
+                    parent_str, parent_id))
+        elif ie.kind == 'symlink':
+            if not working:
+                append('<symlink file_id="%s name="%s%s%s revision="%s '
+                    'symlink_target="%s />\n' % (
+                    _encode_and_escape(ie.file_id),
+                    _encode_and_escape(ie.name),
+                    parent_str, parent_id,
+                    _encode_and_escape(ie.revision),
+                    _encode_and_escape(ie.symlink_target)))
+            else:
+                append('<symlink file_id="%s name="%s%s%s />\n' % (
+                    _encode_and_escape(ie.file_id),
+                    _encode_and_escape(ie.name),
+                    parent_str, parent_id))
+        elif ie.kind == 'tree-reference':
+            if ie.kind not in self.supported_kinds:
+                raise errors.UnsupportedInventoryKind(ie.kind)
+            if not working:
+                append('<tree-reference file_id="%s name="%s%s%s revision="%s '
+                    'reference_revision="%s />\n' % (
+                    _encode_and_escape(ie.file_id),
+                    _encode_and_escape(ie.name),
+                    parent_str, parent_id,
+                    _encode_and_escape(ie.revision),
+                    _encode_and_escape(ie.reference_revision)))
+            else:
+                append('<tree-reference file_id="%s name="%s%s%s />\n' % (
+                    _encode_and_escape(ie.file_id),
+                    _encode_and_escape(ie.name),
+                    parent_str, parent_id))
+        else:
             raise errors.UnsupportedInventoryKind(ie.kind)
 
-        append("<")
-        append(ie.kind)
-        if ie.executable:
-            append(' executable="yes"')
-        append(' file_id="')
-        append(_encode_and_escape(ie.file_id))
-        append(' name="')
-        append(_encode_and_escape(ie.name))
-        if self._parent_condition(ie):
-            assert isinstance(ie.parent_id, basestring)
-            append(' parent_id="')
-            append(_encode_and_escape(ie.parent_id))
-        if ie.revision is not None:
-            append(' revision="')
-            append(_encode_and_escape(ie.revision))
-        if ie.symlink_target is not None:
-            append(' symlink_target="')
-            append(_encode_and_escape(ie.symlink_target))
-        if ie.text_sha1 is not None:
-            append(' text_sha1="')
-            append(ie.text_sha1)
-            append('"')
-        if ie.text_size is not None:
-            append(' text_size="%d"' % ie.text_size)
-        if getattr(ie, 'reference_revision', None) is not None:
-            append(' reference_revision="')
-            append(_encode_and_escape(ie.reference_revision))
-        append(" />\n")
-        return
-
-    def _parent_condition(self, ie):
-        return ie.parent_id != ROOT_ID
-
     def _pack_revision(self, rev):
         """Revision object -> xml tree"""
         # For the XML format, we need to write them as Unicode rather than as

=== modified file 'bzrlib/xml6.py'
--- a/bzrlib/xml6.py	2007-03-02 08:55:16 +0000
+++ b/bzrlib/xml6.py	2007-09-13 22:31:15 +0000
@@ -20,19 +20,22 @@
 class Serializer_v6(xml5.Serializer_v5):
 
     format_num = '6'
+    root_id = None
 
     def _append_inventory_root(self, append, inv):
         """Append the inventory root to output."""
-        append('<inventory')
-        append(' format="%s"' % self.format_num)
         if inv.revision_id is not None:
-            append(' revision_id="')
-            append(xml5._encode_and_escape(inv.revision_id))
-        append('>\n')
-        self._append_entry(append, inv.root)
-
-    def _parent_condition(self, ie):
-        return ie.parent_id is not None
+            revid1 = ' revision_id="'
+            revid2 = xml5._encode_and_escape(inv.revision_id)
+        else:
+            revid1 = ""
+            revid2 = ""
+        append('<inventory format="%s"%s%s>\n' % (
+            self.format_num, revid1, revid2))
+        append('<directory file_id="%s name="%s revision="%s />\n' % (
+            xml5._encode_and_escape(inv.root.file_id),
+            xml5._encode_and_escape(inv.root.name),
+            xml5._encode_and_escape(inv.root.revision)))
 
     def _unpack_inventory(self, elt):
         """Construct from XML Element"""

=== modified file 'bzrlib/xml_serializer.py'
--- a/bzrlib/xml_serializer.py	2007-06-26 19:31:00 +0000
+++ b/bzrlib/xml_serializer.py	2007-09-13 22:31:15 +0000
@@ -51,13 +51,13 @@
 
 class Serializer(object):
     """Abstract object serialize/deserialize"""
+
     def write_inventory(self, inv, f):
         """Write inventory to a file"""
-        elt = self._pack_inventory(inv)
-        self._write_element(elt, f)
+        raise NotImplementedError(self.write_inventory)
 
     def write_inventory_to_string(self, inv):
-        return tostring(self._pack_inventory(inv)) + '\n'
+        raise NotImplementedError(self.write_inventory_to_string)
 
     def read_inventory_from_string(self, xml_string):
         try:



More information about the bazaar-commits mailing list