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