Rev 6408: (jelmer) Add {Repository, Branch, WorkingTree, in file:///srv/pqm.bazaar-vcs.org/archives/thelove/bzr/%2Btrunk/
Patch Queue Manager
pqm at pqm.ubuntu.com
Fri Dec 30 15:52:00 UTC 2011
At file:///srv/pqm.bazaar-vcs.org/archives/thelove/bzr/%2Btrunk/
------------------------------------------------------------
revno: 6408 [merge]
revision-id: pqm at pqm.ubuntu.com-20111230155159-qrgafyvytuitiq8u
parent: pqm at pqm.ubuntu.com-20111230152351-mgfr73vrn8jrqh53
parent: jelmer at samba.org-20111230152618-afeyhel5dn4hfnxb
committer: Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Fri 2011-12-30 15:51:59 +0000
message:
(jelmer) Add {Repository, Branch, WorkingTree,
BzrDir}.update_feature_flags methods. (Jelmer Vernooij)
modified:
bzrlib/branch.py branch.py-20050309040759-e4baf4e0d046576e
bzrlib/bzrdir.py bzrdir.py-20060131065624-156dfea39c4387cb
bzrlib/repository.py rev_storage.py-20051111201905-119e9401e46257e3
bzrlib/tests/blackbox/test_annotate.py testannotate.py-20051013044000-457f44801bfa9d39
bzrlib/tests/blackbox/test_commit.py test_commit.py-20060212094538-ae88fc861d969db0
bzrlib/tests/test_branch.py test_branch.py-20060116013032-97819aa07b8ab3b5
bzrlib/tests/test_bzrdir.py test_bzrdir.py-20060131065654-deba40eef51cf220
bzrlib/tests/test_remote.py test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
bzrlib/tests/test_repository.py test_repository.py-20060131075918-65c555b881612f4d
bzrlib/tests/test_workingtree.py testworkingtree.py-20051004024258-b88d0fe8f101d468
bzrlib/workingtree.py workingtree.py-20050511021032-29b6ec0a681e02e3
doc/developers/feature-flags.txt featureflags.txt-20111014011252-hvtwde3cv5dusxnb-1
=== modified file 'bzrlib/branch.py'
--- a/bzrlib/branch.py 2011-12-22 18:52:58 +0000
+++ b/bzrlib/branch.py 2011-12-30 15:00:07 +0000
@@ -2721,6 +2721,16 @@
self._transport.put_bytes('last-revision', out_string,
mode=self.bzrdir._get_file_mode())
+ @needs_write_lock
+ def update_feature_flags(self, updated_flags):
+ """Update the feature flags for this branch.
+
+ :param updated_flags: Dictionary mapping feature names to necessities
+ A necessity can be None to indicate the feature should be removed
+ """
+ self._format._update_feature_flags(updated_flags)
+ self.control_transport.put_bytes('format', self._format.as_string())
+
class FullHistoryBzrBranch(BzrBranch):
"""Bzr branch which contains the full revision history."""
=== modified file 'bzrlib/bzrdir.py'
--- a/bzrlib/bzrdir.py 2011-12-22 15:33:16 +0000
+++ b/bzrlib/bzrdir.py 2011-12-22 19:54:56 +0000
@@ -786,6 +786,19 @@
def __repr__(self):
return "<%s at %r>" % (self.__class__.__name__, self.user_url)
+ def update_feature_flags(self, updated_flags):
+ """Update the features required by this bzrdir.
+
+ :param updated_flags: Dictionary mapping feature names to necessities
+ A necessity can be None to indicate the feature should be removed
+ """
+ self.control_files.lock_write()
+ try:
+ self._format._update_feature_flags(updated_flags)
+ self.transport.put_bytes('branch-format', self._format.as_string())
+ finally:
+ self.control_files.unlock()
+
class BzrDirMeta1(BzrDir):
"""A .bzr meta version 1 control object.
@@ -796,6 +809,11 @@
present within a BzrDir.
"""
+ def __init__(self, _transport, _format):
+ super(BzrDirMeta1, self).__init__(_transport, _format)
+ self.control_files = lockable_files.LockableFiles(self.control_transport,
+ self._format._lock_file_name, self._format._lock_class)
+
def can_convert_format(self):
"""See BzrDir.can_convert_format()."""
return True
@@ -993,11 +1011,6 @@
BzrDirMeta1.
"""
- def __init__(self, _transport, _format):
- super(BzrDirMeta1Colo, self).__init__(_transport, _format)
- self.control_files = lockable_files.LockableFiles(self.control_transport,
- self._format._lock_file_name, self._format._lock_class)
-
def _get_branch_path(self, name):
"""Obtain the branch path to use.
@@ -1213,6 +1226,20 @@
return (self.__class__ is other.__class__ and
self.features == other.features)
+ def _update_feature_flags(self, updated_flags):
+ """Update the feature flags in this format.
+
+ :param updated_flags: Updated feature flags
+ """
+ for name, necessity in updated_flags.iteritems():
+ if necessity is None:
+ try:
+ del self.features[name]
+ except KeyError:
+ pass
+ else:
+ self.features[name] = necessity
+
class BzrProber(controldir.Prober):
"""Prober for formats that use a .bzr/ control directory."""
@@ -1451,7 +1478,7 @@
"This is a Bazaar control directory.\n"
"Do not change any files in this directory.\n"
"See http://bazaar.canonical.com/ for more information about Bazaar.\n"),
- ('branch-format', self.get_format_string()),
+ ('branch-format', self.as_string()),
]
# NB: no need to escape relative paths that are url safe.
control_files = lockable_files.LockableFiles(bzrdir_transport,
@@ -1866,7 +1893,7 @@
def convert(self, to_convert, pb):
"""See Converter.convert()."""
to_convert.transport.put_bytes('branch-format',
- self.target_format.get_format_string())
+ self.target_format.as_string())
return BzrDir.open_from_transport(to_convert.root_transport)
@@ -1892,7 +1919,7 @@
finally:
to_convert.control_files.unlock()
to_convert.transport.put_bytes('branch-format',
- self.target_format.get_format_string())
+ self.target_format.as_string())
return BzrDir.open_from_transport(to_convert.root_transport)
=== modified file 'bzrlib/repository.py'
--- a/bzrlib/repository.py 2011-12-19 19:15:58 +0000
+++ b/bzrlib/repository.py 2011-12-30 00:15:51 +0000
@@ -1293,6 +1293,16 @@
"""Returns the policy for making working trees on new branches."""
return not self._transport.has('no-working-trees')
+ @needs_write_lock
+ def update_feature_flags(self, updated_flags):
+ """Update the feature flags for this branch.
+
+ :param updated_flags: Dictionary mapping feature names to necessities
+ A necessity can be None to indicate the feature should be removed
+ """
+ self._format._update_feature_flags(updated_flags)
+ self.control_transport.put_bytes('format', self._format.as_string())
+
class RepositoryFormatRegistry(controldir.ControlComponentFormatRegistry):
"""Repository format registry."""
=== modified file 'bzrlib/tests/blackbox/test_annotate.py'
--- a/bzrlib/tests/blackbox/test_annotate.py 2011-12-14 21:57:37 +0000
+++ b/bzrlib/tests/blackbox/test_annotate.py 2011-12-30 15:26:18 +0000
@@ -326,7 +326,7 @@
# being too low. If rpc_count increases, more network roundtrips have
# become necessary for this use case. Please do not adjust this number
# upwards without agreement from bzr's network support maintainers.
- self.assertLength(15, self.hpss_calls)
+ self.assertLength(16, self.hpss_calls)
self.assertLength(1, self.hpss_connections)
self.expectFailure("annotate accesses inventories, which require VFS access",
self.assertThat, self.hpss_calls, ContainsNoVfsCalls)
=== modified file 'bzrlib/tests/blackbox/test_commit.py'
--- a/bzrlib/tests/blackbox/test_commit.py 2011-12-30 14:19:53 +0000
+++ b/bzrlib/tests/blackbox/test_commit.py 2011-12-30 15:26:18 +0000
@@ -889,7 +889,7 @@
# being too low. If rpc_count increases, more network roundtrips have
# become necessary for this use case. Please do not adjust this number
# upwards without agreement from bzr's network support maintainers.
- self.assertLength(213, self.hpss_calls)
+ self.assertLength(214, self.hpss_calls)
self.assertLength(2, self.hpss_connections)
self.expectFailure("commit still uses VFS calls",
self.assertThat, self.hpss_calls, ContainsNoVfsCalls)
=== modified file 'bzrlib/tests/test_branch.py'
--- a/bzrlib/tests/test_branch.py 2011-12-22 18:52:58 +0000
+++ b/bzrlib/tests/test_branch.py 2011-12-30 15:00:07 +0000
@@ -219,12 +219,13 @@
def test_find_format_with_features(self):
tree = self.make_branch_and_tree('.', format='2a')
- tree.branch.control_transport.put_bytes('format',
- tree.branch._format.get_format_string() +
- "optional name\n")
+ tree.branch.update_feature_flags({"name": "optional"})
found_format = _mod_branch.BranchFormatMetadir.find_format(tree.bzrdir)
self.assertIsInstance(found_format, _mod_branch.BranchFormatMetadir)
self.assertEquals(found_format.features.get("name"), "optional")
+ tree.branch.update_feature_flags({"name": None})
+ branch = _mod_branch.Branch.open('.')
+ self.assertEquals(branch._format.features, {})
def test_register_unregister_format(self):
# Test the deprecated format registration functions
=== modified file 'bzrlib/tests/test_bzrdir.py'
--- a/bzrlib/tests/test_bzrdir.py 2011-12-22 15:33:16 +0000
+++ b/bzrlib/tests/test_bzrdir.py 2011-12-22 18:02:01 +0000
@@ -1027,14 +1027,15 @@
def test_with_features(self):
tree = self.make_branch_and_tree('tree', format='2a')
- tree.bzrdir.control_transport.put_bytes(
- 'branch-format',
- tree.bzrdir._format.get_format_string() + "required bar\n")
+ tree.bzrdir.update_feature_flags({"bar": "required"})
self.assertRaises(errors.MissingFeature, bzrdir.BzrDir.open, 'tree')
bzrdir.BzrDirMetaFormat1.register_feature('bar')
self.addCleanup(bzrdir.BzrDirMetaFormat1.unregister_feature, 'bar')
dir = bzrdir.BzrDir.open('tree')
self.assertEquals("required", dir._format.features.get("bar"))
+ tree.bzrdir.update_feature_flags({"bar": None, "nonexistant": None})
+ dir = bzrdir.BzrDir.open('tree')
+ self.assertEquals({}, dir._format.features)
def test_needs_conversion_different_working_tree(self):
# meta1dirs need an conversion if any element is not the default.
=== modified file 'bzrlib/tests/test_remote.py'
--- a/bzrlib/tests/test_remote.py 2011-12-15 12:59:56 +0000
+++ b/bzrlib/tests/test_remote.py 2011-12-30 00:30:43 +0000
@@ -933,6 +933,7 @@
# name.
client.add_success_response_with_body(
"Bazaar-NG meta directory, format 1\n", 'ok')
+ client.add_success_response('stat', '0', '65535')
client.add_success_response_with_body(
reference_format.get_format_string(), 'ok')
# PackRepository wants to do a stat
@@ -947,6 +948,7 @@
('call', 'BzrDir.find_repositoryV2', ('quack/',)),
('call', 'BzrDir.find_repository', ('quack/',)),
('call_expecting_body', 'get', ('/quack/.bzr/branch-format',)),
+ ('call', 'stat', ('/quack/.bzr',)),
('call_expecting_body', 'get', ('/quack/.bzr/repository/format',)),
('call', 'stat', ('/quack/.bzr/repository',)),
],
@@ -966,6 +968,7 @@
# name.
client.add_success_response_with_body(
"Bazaar-NG meta directory, format 1\n", 'ok')
+ client.add_success_response('stat', '0', '65535')
client.add_success_response_with_body(
reference_format.get_format_string(), 'ok')
# PackRepository wants to do a stat
@@ -979,6 +982,7 @@
[('call', 'BzrDir.find_repositoryV3', ('quack/',)),
('call', 'BzrDir.find_repositoryV2', ('quack/',)),
('call_expecting_body', 'get', ('/quack/.bzr/branch-format',)),
+ ('call', 'stat', ('/quack/.bzr',)),
('call_expecting_body', 'get', ('/quack/.bzr/repository/format',)),
('call', 'stat', ('/quack/.bzr/repository',)),
],
@@ -1270,7 +1274,7 @@
verb = 'Branch.set_parent_location'
self.disable_verb(verb)
branch.set_parent('http://foo/')
- self.assertLength(12, self.hpss_calls)
+ self.assertLength(13, self.hpss_calls)
class TestBranchGetTagsBytes(RemoteBranchTestCase):
@@ -1998,7 +2002,7 @@
self.addCleanup(branch.unlock)
self.reset_smart_call_log()
branch._get_config().set_option('value', 'name')
- self.assertLength(10, self.hpss_calls)
+ self.assertLength(11, self.hpss_calls)
self.assertEqual('value', branch._get_config().get_option('name'))
def test_backwards_compat_set_option_with_dict(self):
@@ -2012,7 +2016,7 @@
config = branch._get_config()
value_dict = {'ascii': 'a', u'unicode \N{WATCH}': u'\N{INTERROBANG}'}
config.set_option(value_dict, 'name')
- self.assertLength(10, self.hpss_calls)
+ self.assertLength(11, self.hpss_calls)
self.assertEqual(value_dict, branch._get_config().get_option('name'))
@@ -2138,7 +2142,7 @@
self.reset_smart_call_log()
self.assertEquals((0, ),
branch.revision_id_to_dotted_revno('null:'))
- self.assertLength(7, self.hpss_calls)
+ self.assertLength(8, self.hpss_calls)
class TestBzrDirGetSetConfig(RemoteBzrDirTestCase):
@@ -2160,7 +2164,7 @@
self.reset_smart_call_log()
config = bzrdir.get_config()
config.set_default_stack_on('/')
- self.assertLength(3, self.hpss_calls)
+ self.assertLength(4, self.hpss_calls)
def test_backwards_compat_get_option(self):
self.setup_smart_server_with_call_log()
@@ -2170,7 +2174,7 @@
self.reset_smart_call_log()
self.assertEqual(None,
bzrdir._get_config().get_option('default_stack_on'))
- self.assertLength(3, self.hpss_calls)
+ self.assertLength(4, self.hpss_calls)
class TestTransportIsReadonly(tests.TestCase):
=== modified file 'bzrlib/tests/test_repository.py'
--- a/bzrlib/tests/test_repository.py 2011-12-22 16:21:25 +0000
+++ b/bzrlib/tests/test_repository.py 2011-12-22 19:54:56 +0000
@@ -166,9 +166,7 @@
def test_find_format_with_features(self):
tree = self.make_branch_and_tree('.', format='2a')
- tree.branch.repository.control_transport.put_bytes('format',
- tree.branch.repository._format.get_format_string() +
- "necessity name\n")
+ tree.branch.repository.update_feature_flags({"name": "necessity"})
found_format = repository.RepositoryFormatMetaDir.find_format(tree.bzrdir)
self.assertIsInstance(found_format, repository.RepositoryFormatMetaDir)
self.assertEquals(found_format.features.get("name"), "necessity")
=== modified file 'bzrlib/tests/test_workingtree.py'
--- a/bzrlib/tests/test_workingtree.py 2011-12-22 17:30:20 +0000
+++ b/bzrlib/tests/test_workingtree.py 2011-12-22 19:54:56 +0000
@@ -245,8 +245,7 @@
def test_find_format_with_features(self):
tree = self.make_branch_and_tree('.', format='2a')
- tree.control_transport.put_bytes('format',
- tree._format.get_format_string() + "necessity name\n")
+ tree.update_feature_flags({"name": "necessity"})
found_format = workingtree.WorkingTreeFormatMetaDir.find_format(
tree.bzrdir)
self.assertIsInstance(found_format, workingtree.WorkingTreeFormat)
=== modified file 'bzrlib/workingtree.py'
--- a/bzrlib/workingtree.py 2011-12-19 19:15:58 +0000
+++ b/bzrlib/workingtree.py 2011-12-22 19:54:56 +0000
@@ -2977,6 +2977,16 @@
if dir[2] == _directory:
pending.append(dir)
+ @needs_write_lock
+ def update_feature_flags(self, updated_flags):
+ """Update the feature flags for this branch.
+
+ :param updated_flags: Dictionary mapping feature names to necessities
+ A necessity can be None to indicate the feature should be removed
+ """
+ self._format._update_feature_flags(updated_flags)
+ self.control_transport.put_bytes('format', self._format.as_string())
+
class WorkingTreeFormatRegistry(controldir.ControlComponentFormatRegistry):
"""Registry for working tree formats."""
=== modified file 'doc/developers/feature-flags.txt'
--- a/doc/developers/feature-flags.txt 2011-12-22 14:25:34 +0000
+++ b/doc/developers/feature-flags.txt 2011-12-24 12:51:20 +0000
@@ -129,6 +129,16 @@
* BzrFormat.features.set(name, necessity)
* BzrFormat.features.get(name) -> necessity
+Enabling features
+-----------------
+
+Features are enabled through the ``update_feature_flags`` method on
+``Repository``, ``Branch``, ``WorkingTree`` and ``BzrDir``.
+
+These methods are called by whatever needs to enable features.
+When they do that is up to them - e.g. bzr-search would enable its
+feature when ``bzr index`` is first run.
+
See also
--------
More information about the bazaar-commits
mailing list