Rev 25: Monkey patch bzrlib to convert in-place when we can. in http://people.ubuntu.com/~robertc/baz2.0/plugins/index2/trunk

Robert Collins robertc at robertcollins.net
Fri Jul 4 05:23:35 BST 2008


At http://people.ubuntu.com/~robertc/baz2.0/plugins/index2/trunk

------------------------------------------------------------
revno: 25
revision-id: robertc at robertcollins.net-20080704042330-cwuwgduay58trd71
parent: robertc at robertcollins.net-20080704030406-zb19krvf26p3htzy
committer: Robert Collins <robertc at robertcollins.net>
branch nick: trunk
timestamp: Fri 2008-07-04 14:23:30 +1000
message:
  Monkey patch bzrlib to convert in-place when we can.
modified:
  repofmt.py                     repofmt.py-20080701113732-m1iu3n94ikbxdelb-1
  tests/test_repofmt.py          test_repofmt.py-20080704030345-bza6rrd6nf4sdmyy-1
=== modified file 'repofmt.py'
--- a/repofmt.py	2008-07-04 03:04:06 +0000
+++ b/repofmt.py	2008-07-04 04:23:30 +0000
@@ -24,7 +24,7 @@
 import md5
 import time
 
-from bzrlib import debug, errors, pack
+from bzrlib import debug, errors, pack, repository
 from bzrlib.index import GraphIndexBuilder
 from bzrlib.inter import InterObject
 from bzrlib.plugins.index2.btree_index import BTreeGraphIndex, BTreeBuilder
@@ -40,6 +40,8 @@
     RepositoryPackCollection,
     RepositoryFormatPackDevelopment0,
     RepositoryFormatPackDevelopment0Subtree,
+    RepositoryFormatKnitPack1,
+    RepositoryFormatKnitPack3,
     RepositoryFormatKnitPack4,
     Packer,
     ReconcilePacker,
@@ -431,9 +433,16 @@
 class InterRepositoryRepositoryFormat(InterObject):
     """This class is used for conversions from a repository to a new format."""
 
+    original_converter = repository.CopyConverter
+
     _optimisers = []
     """The available optimisers for conversion."""
 
+    def convert(self, pb):
+        """Convert source to be of format target."""
+        converter = InterRepositoryRepositoryFormat.original_converter(self.target)
+        converter.convert(self.source, pb)
+
 
 class InterKnitPackBTreeFormat(InterRepositoryRepositoryFormat):
     """Convertsions from KnitPack foramts to BTree formats."""
@@ -506,7 +515,7 @@
         self.source._transport.delete_tree('oldindices')
         self.unlock()
 
-    def convert(self):
+    def convert(self, pb):
         """Convert source to be of format target."""
         try:
             self._prep_conversion()
@@ -573,3 +582,42 @@
     def _set_format(self):
         self.source._transport.put_bytes('format',
             self.target.get_format_string())
+
+    @staticmethod
+    def is_compatible(source, target):
+        # only convert formats we know we can do:
+        if source._format.__class__ not in (
+            RepositoryFormatPackDevelopment0,
+            RepositoryFormatPackDevelopment0Subtree,
+            RepositoryFormatKnitPack1,
+            RepositoryFormatKnitPack3,
+            RepositoryFormatKnitPack4,
+            ):
+            return False
+        # And of course, we write btree indices!
+        if target not in (RepositoryFormatPackBTreePlain,
+            RepositoryFormatPackBTreeRichRoot,
+            RepositoryFormatPackBTreeSubtrees,
+            ):
+            return False
+        # Can never convert different model
+        if not (source._format.rich_root_data == target.rich_root_data and
+            source._format.supports_tree_reference == target.supports_tree_reference and
+            source._serializer == target._serializer):
+            return False
+        return True
+
+
+InterRepositoryRepositoryFormat.register_optimiser(InterKnitPackBTreeFormat)
+
+
+class ReplacementConverter(repository.CopyConverter):
+    """A InterRepositoryRepositoryFormat using replacement for CopyConverter"""
+
+    def convert(self, repo, pb):
+        """Perform a conversion using an optimiser if possible."""
+        inter = InterRepositoryRepositoryFormat.get(repo, self.target_format)
+        inter.convert(pb)
+
+
+repository.CopyConverter = ReplacementConverter

=== modified file 'tests/test_repofmt.py'
--- a/tests/test_repofmt.py	2008-07-04 03:04:06 +0000
+++ b/tests/test_repofmt.py	2008-07-04 04:23:30 +0000
@@ -23,9 +23,16 @@
 
 from bzrlib import index, tests
 from bzrlib import errors as bzrerrors
+from bzrlib import ui
 from bzrlib.plugins import index2
 from bzrlib.plugins.index2 import btree_index, errors, repofmt
 from bzrlib.repository import Repository
+from bzrlib.repofmt.knitrepo import (
+    RepositoryFormatKnit3,
+    )
+from bzrlib.repofmt.pack_repo import (
+    RepositoryFormatKnitPack4,
+    )
 from bzrlib.tests import (
     TestCaseWithTransport,
     )
@@ -281,7 +288,7 @@
         self.inter._pivot = self.make_log_call('pivot', calls)
         self.inter._complete = self.make_log_call('complete', calls)
         self.inter._cancel_conversion = self.make_log_call('cancel', calls)
-        self.inter.convert()
+        self.inter.convert(None)
         self.assertEqual(['prep', 'convert', 'pivot', 'complete'], calls)
 
     def test_convert_prep_error_cancels(self):
@@ -292,7 +299,7 @@
         self.inter._pivot = self.make_log_call('pivot', calls)
         self.inter._complete = self.make_log_call('complete', calls)
         self.inter._cancel_conversion = self.make_log_call('cancel', calls)
-        error = self.assertRaises(Exception, self.inter.convert)
+        error = self.assertRaises(Exception, self.inter.convert, None)
         self.assertEqual(error.args, ('prep',))
         self.assertEqual(['prep', 'cancel'], calls)
 
@@ -304,7 +311,7 @@
         self.inter._pivot = self.make_log_call('pivot', calls)
         self.inter._complete = self.make_log_call('complete', calls)
         self.inter._cancel_conversion = self.make_log_call('cancel', calls)
-        error = self.assertRaises(Exception, self.inter.convert)
+        error = self.assertRaises(Exception, self.inter.convert, None)
         self.assertEqual(error.args, ('convert',))
         self.assertEqual(['prep', 'convert', 'cancel'], calls)
 
@@ -316,7 +323,7 @@
         self.inter._pivot = self.make_error_log_call('pivot', calls)
         self.inter._complete = self.make_log_call('complete', calls)
         self.inter._cancel_conversion = self.make_log_call('cancel', calls)
-        error = self.assertRaises(Exception, self.inter.convert)
+        error = self.assertRaises(Exception, self.inter.convert, None)
         self.assertEqual(error.args, ('pivot',))
         self.assertEqual(['prep', 'convert', 'pivot', 'cancel'], calls)
 
@@ -328,6 +335,53 @@
         self.inter._pivot = self.make_log_call('pivot', calls)
         self.inter._complete = self.make_error_log_call('complete', calls)
         self.inter._cancel_conversion = self.make_log_call('cancel', calls)
-        error = self.assertRaises(Exception, self.inter.convert)
+        error = self.assertRaises(Exception, self.inter.convert, None)
         self.assertEqual(error.args, ('complete',))
         self.assertEqual(['prep', 'convert', 'pivot', 'complete'], calls)
+
+
+class TestReplacementConverter(TestCaseWithTransport):
+
+    def assertConverts(self, source_name, format):
+        tree = self.make_branch_and_tree('.', format=source_name)
+        revid = tree.commit('first post')
+        repo = tree.branch.repository
+        converter = repofmt.ReplacementConverter(format)
+        converter.convert(repo, ui.ui_factory.nested_progress_bar())
+        repo = Repository.open('.')
+        self.assertIsInstance(repo._format, format.__class__)
+        repo.lock_read()
+        self.assertEqual([revid], list(repo.all_revision_ids()))
+        repo.unlock()
+        return tree
+
+    def test_trivial_plain(self):
+        self.assertConverts(
+            'pack-0.92', repofmt.RepositoryFormatPackBTreePlain())
+
+    def test_trivial_rich(self):
+        self.assertConverts(
+            'rich-root-pack', repofmt.RepositoryFormatPackBTreeRichRoot())
+
+    def test_rich_converts(self):
+        # check we haven't broken existing conversions:
+        tree = self.assertConverts('pack-0.92', RepositoryFormatKnitPack4())
+        tree.lock_read()
+        revid = tree.last_revision()
+        root = tree.path2id('')
+        self.assertEqual({(root, revid):()},
+            tree.branch.repository.texts.get_parent_map([(root, revid)]))
+        tree.unlock()
+
+    def test_trivial_subtree(self):
+        self.assertConverts(
+            'pack-0.92-subtree', repofmt.RepositoryFormatPackBTreeSubtrees())
+
+    def test_trivial_weave(self):
+        self.assertConverts(
+            'metaweave', repofmt.RepositoryFormatPackBTreePlain())
+
+    def test_trivial_pack_knit(self):
+        # only convert to targets we grok
+        self.assertConverts(
+            'pack-0.92-subtree', RepositoryFormatKnit3())




More information about the bazaar-commits mailing list