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