Rev 2448: Implement upgrade for working trees. in http://bazaar.launchpad.net/~bzr/bzr/dirstate
Robert Collins
robertc at robertcollins.net
Tue Mar 6 00:26:34 GMT 2007
At http://bazaar.launchpad.net/~bzr/bzr/dirstate
------------------------------------------------------------
revno: 2448
revision-id: robertc at robertcollins.net-20070306002528-zkvfpjt0dwzwz85l
parent: john at arbash-meinel.com-20070305212803-wowsk4ytx1x836tv
parent: robertc at robertcollins.net-20070305091133-bjk279of5h029hpg
committer: Robert Collins <robertc at robertcollins.net>
branch nick: dirstate.dogfood
timestamp: Tue 2007-03-06 11:25:28 +1100
message:
Implement upgrade for working trees.
modified:
bzrlib/bzrdir.py bzrdir.py-20060131065624-156dfea39c4387cb
bzrlib/tests/test_bzrdir.py test_bzrdir.py-20060131065654-deba40eef51cf220
bzrlib/tests/test_upgrade.py test_upgrade.py-20051004040251-555fe1d2bae1bc71
bzrlib/workingtree_4.py workingtree_4.py-20070208044105-5fgpc5j3ljlh5q6c-1
------------------------------------------------------------
revno: 2446.1.1
merged: robertc at robertcollins.net-20070305091133-bjk279of5h029hpg
parent: mbp at sourcefrog.net-20070305064521-2ewp1qiqp3ils4ff
committer: Robert Collins <robertc at robertcollins.net>
branch nick: dirstate.dogfood
timestamp: Mon 2007-03-05 20:11:33 +1100
message:
Implement upgrade for working trees.
=== modified file 'bzrlib/bzrdir.py'
--- a/bzrlib/bzrdir.py 2007-03-02 09:44:41 +0000
+++ b/bzrlib/bzrdir.py 2007-03-05 09:11:33 +0000
@@ -49,6 +49,8 @@
urlutils,
xml4,
xml5,
+ workingtree,
+ workingtree_4,
)
from bzrlib.osutils import (
safe_unicode,
@@ -1058,11 +1060,17 @@
try:
if not isinstance(self.open_branch()._format,
format.get_branch_format().__class__):
- # the repository needs an upgrade.
- return True
- except errors.NotBranchError:
- pass
- # currently there are no other possible conversions for meta1 formats.
+ # the branch needs an upgrade.
+ return True
+ except errors.NotBranchError:
+ pass
+ try:
+ if not isinstance(self.open_workingtree()._format,
+ format.workingtree_format.__class__):
+ # the workingtree needs an upgrade.
+ return True
+ except errors.NotBranchError:
+ pass
return False
def open_branch(self, unsupported=False):
@@ -2063,6 +2071,8 @@
except errors.NotBranchError:
pass
else:
+ # TODO: conversions of Branch and Tree should be done by
+ # InterXFormat lookups
# Avoid circular imports
from bzrlib import branch as _mod_branch
if (branch._format.__class__ is _mod_branch.BzrBranchFormat5 and
@@ -2070,6 +2080,17 @@
_mod_branch.BzrBranchFormat6):
branch_converter = _mod_branch.Converter5to6()
branch_converter.convert(branch)
+ try:
+ tree = self.bzrdir.open_workingtree()
+ except errors.NotBranchError:
+ pass
+ else:
+ # TODO: conversions of Branch and Tree should be done by
+ # InterXFormat lookups
+ if (isinstance(tree, workingtree.WorkingTree3) and
+ isinstance(self.target_format.workingtree_format,
+ workingtree_4.WorkingTreeFormat4)):
+ workingtree_4.Converter3to4().convert(tree)
return to_convert
@@ -2221,12 +2242,15 @@
deprecated=True)
format_registry.register_metadir('knit',
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
- 'Format using knits. Recommended.',
- branch_format='bzrlib.branch.BzrBranchFormat5')
+ 'Format using knits. Recommended for interoperation with bzr <= 0.14.',
+ branch_format='bzrlib.branch.BzrBranchFormat5',
+ tree_format='bzrlib.workingtree_4.WorkingTreeFormat3')
format_registry.set_default('knit')
format_registry.register_metadir('metaweave',
'bzrlib.repofmt.weaverepo.RepositoryFormat7',
'Transitional format in 0.8. Slower than knit.',
+ branch_format='bzrlib.branch.BzrBranchFormat5',
+ tree_format='bzrlib.workingtree_4.WorkingTreeFormat3',
deprecated=True)
format_registry.register_metadir('experimental-knit2',
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit2',
@@ -2247,3 +2271,18 @@
branch_format='bzrlib.branch.BzrBranchFormat6',
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
)
+format_registry.register_metadir('dirstate',
+ 'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
+ help='New in 0.15: Fast local operations. Compatible with bzr 0.8 and '
+ 'above when accessed over the network.',
+ branch_format='bzrlib.branch.BzrBranchFormat5',
+ tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
+ )
+format_registry.register_metadir('dirstate-with-subtree',
+ 'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
+ help='New in 0.15: Fast local operations and improved scaling for '
+ 'network operations. Additionally adds support for versioning nested '
+ 'bzr branches. Incompatible with bzr < 0.15.',
+ branch_format='bzrlib.branch.BzrBranchFormat6',
+ tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
+ )
=== modified file 'bzrlib/tests/test_bzrdir.py'
--- a/bzrlib/tests/test_bzrdir.py 2007-03-05 04:55:34 +0000
+++ b/bzrlib/tests/test_bzrdir.py 2007-03-05 09:11:33 +0000
@@ -555,7 +555,19 @@
self.assertNotEqual(otherdir2, mydir)
self.assertFalse(otherdir2 == mydir)
-
+ def test_needs_conversion_different_working_tree(self):
+ # meta1dirs need an conversion if any element is not the default.
+ old_format = bzrdir.BzrDirFormat.get_default_format()
+ # test with
+ new_default = bzrdir.format_registry.make_bzrdir('dirstate')
+ bzrdir.BzrDirFormat._set_default_format(new_default)
+ try:
+ tree = self.make_branch_and_tree('tree', format='knit')
+ self.assertTrue(tree.bzrdir.needs_format_conversion())
+ finally:
+ bzrdir.BzrDirFormat._set_default_format(old_format)
+
+
class TestFormat5(TestCaseWithTransport):
"""Tests specific to the version 5 bzrdir format."""
=== modified file 'bzrlib/tests/test_upgrade.py'
--- a/bzrlib/tests/test_upgrade.py 2007-02-09 22:59:51 +0000
+++ b/bzrlib/tests/test_upgrade.py 2007-03-05 09:11:33 +0000
@@ -31,17 +31,17 @@
bzrdir,
progress,
repository,
+ workingtree,
+ workingtree_4,
)
import bzrlib.branch
from bzrlib.branch import Branch
-from bzrlib.revision import is_ancestor
-from bzrlib.tests import TestCase, TestCaseInTempDir
+from bzrlib.tests import TestCaseWithTransport
from bzrlib.transport import get_transport
from bzrlib.upgrade import upgrade
-import bzrlib.workingtree as workingtree
-
-
-class TestUpgrade(TestCaseInTempDir):
+
+
+class TestUpgrade(TestCaseWithTransport):
def test_build_tree(self):
"""Test tree-building test helper"""
@@ -184,6 +184,63 @@
branch2 = self.make_branch('branch2', format='knit')
converter = branch2.bzrdir._format.get_converter(target)
converter.convert(branch2.bzrdir, progress.DummyProgress())
+ branch2 = _mod_branch.Branch.open(self.get_url('branch'))
+ self.assertIs(branch2.__class__, _mod_branch.BzrBranch6)
+
+ def test_convert_knit_dirstate_empty(self):
+ # test that asking for an upgrade from knit to dirstate works.
+ tree = self.make_branch_and_tree('tree', format='knit')
+ target = bzrdir.format_registry.make_bzrdir('dirstate')
+ converter = tree.bzrdir._format.get_converter(target)
+ converter.convert(tree.bzrdir, progress.DummyProgress())
+ new_tree = workingtree.WorkingTree.open('tree')
+ self.assertIs(new_tree.__class__, workingtree_4.WorkingTree4)
+ self.assertEqual(None, new_tree.last_revision())
+
+ def test_convert_knit_dirstate_content(self):
+ # smoke test for dirstate conversion: we call dirstate primitives,
+ # and its there that the core logic is tested.
+ tree = self.make_branch_and_tree('tree', format='knit')
+ self.build_tree(['tree/file'])
+ tree.add(['file'], ['file-id'])
+ target = bzrdir.format_registry.make_bzrdir('dirstate')
+ converter = tree.bzrdir._format.get_converter(target)
+ converter.convert(tree.bzrdir, progress.DummyProgress())
+ new_tree = workingtree.WorkingTree.open('tree')
+ self.assertIs(new_tree.__class__, workingtree_4.WorkingTree4)
+ self.assertEqual(None, new_tree.last_revision())
+
+ def test_convert_knit_one_parent_dirstate(self):
+ # test that asking for an upgrade from knit to dirstate works.
+ tree = self.make_branch_and_tree('tree', format='knit')
+ rev_id = tree.commit('first post')
+ target = bzrdir.format_registry.make_bzrdir('dirstate')
+ converter = tree.bzrdir._format.get_converter(target)
+ converter.convert(tree.bzrdir, progress.DummyProgress())
+ new_tree = workingtree.WorkingTree.open('tree')
+ self.assertIs(new_tree.__class__, workingtree_4.WorkingTree4)
+ self.assertEqual(rev_id, new_tree.last_revision())
+ for path in ['basis-inventory-cache', 'inventory', 'last-revision',
+ 'pending-merges', 'stat-cache']:
+ self.failIfExists('tree/.bzr/checkout/' + path)
+
+ def test_convert_knit_merges_dirstate(self):
+ tree = self.make_branch_and_tree('tree', format='knit')
+ rev_id = tree.commit('first post')
+ merge_tree = tree.bzrdir.sprout('tree2').open_workingtree()
+ rev_id2 = tree.commit('second post')
+ rev_id3 = merge_tree.commit('second merge post')
+ tree.merge_from_branch(merge_tree.branch)
+ target = bzrdir.format_registry.make_bzrdir('dirstate')
+ converter = tree.bzrdir._format.get_converter(target)
+ converter.convert(tree.bzrdir, progress.DummyProgress())
+ new_tree = workingtree.WorkingTree.open('tree')
+ self.assertIs(new_tree.__class__, workingtree_4.WorkingTree4)
+ self.assertEqual(rev_id2, new_tree.last_revision())
+ self.assertEqual([rev_id2, rev_id3], new_tree.get_parent_ids())
+ for path in ['basis-inventory-cache', 'inventory', 'last-revision',
+ 'pending-merges', 'stat-cache']:
+ self.failIfExists('tree/.bzr/checkout/' + path)
_upgrade1_template = \
=== modified file 'bzrlib/workingtree_4.py'
--- a/bzrlib/workingtree_4.py 2007-03-05 21:28:03 +0000
+++ b/bzrlib/workingtree_4.py 2007-03-06 00:25:28 +0000
@@ -2169,3 +2169,42 @@
return True
InterTree.register_optimiser(InterDirStateTree)
+
+
+class Converter3to4(object):
+ """Perform an in-place upgrade of format 3 to format 4 trees."""
+
+ def __init__(self):
+ self.target_format = WorkingTreeFormat4()
+
+ def convert(self, tree):
+ # lock the control files not the tree, so that we dont get tree
+ # on-unlock behaviours, and so that noone else diddles with the
+ # tree during upgrade.
+ tree._control_files.lock_write()
+ try:
+ self.create_dirstate_data(tree)
+ self.update_format(tree)
+ self.remove_xml_files(tree)
+ finally:
+ tree._control_files.unlock()
+
+ def create_dirstate_data(self, tree):
+ """Create the dirstate based data for tree."""
+ local_path = tree.bzrdir.get_workingtree_transport(None
+ ).local_abspath('dirstate')
+ state = dirstate.DirState.from_tree(tree, local_path)
+ state.save()
+ state.unlock()
+
+ def remove_xml_files(self, tree):
+ """Remove the oldformat 3 data."""
+ transport = tree.bzrdir.get_workingtree_transport(None)
+ for path in ['basis-inventory-cache', 'inventory', 'last-revision',
+ 'pending-merges', 'stat-cache']:
+ transport.delete(path)
+
+ def update_format(self, tree):
+ """Change the format marker."""
+ tree._control_files.put_utf8('format',
+ self.target_format.get_format_string())
More information about the bazaar-commits
mailing list