Rev 6150: Merge bzr.dev to get the latest test_smart_transport cleanups. in http://bazaar.launchpad.net/~jameinel/bzr/drop-idle-connections-824797

John Arbash Meinel john at arbash-meinel.com
Thu Sep 15 10:10:24 UTC 2011


At http://bazaar.launchpad.net/~jameinel/bzr/drop-idle-connections-824797

------------------------------------------------------------
revno: 6150 [merge]
revision-id: john at arbash-meinel.com-20110915101011-8y6g65ltp5wxvj1t
parent: john at arbash-meinel.com-20110915095532-ayzf3aub59k9roh2
parent: pqm at pqm.ubuntu.com-20110915093518-a0vh2pu5emme5kh1
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: drop-idle-connections-824797
timestamp: Thu 2011-09-15 12:10:11 +0200
message:
  Merge bzr.dev to get the latest test_smart_transport cleanups.
modified:
  bzrlib/commit.py               commit.py-20050511101309-79ec1a0168e0e825
  bzrlib/i18n.py                 i18n.py-20110429130428-eblvodng604h3dzi-1
  bzrlib/mutabletree.py          mutabletree.py-20060906023413-4wlkalbdpsxi2r4y-2
  bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
  bzrlib/tests/per_workingtree/test_smart_add.py test_smart_add.py-20070215175752-9s5mxoz8aqpd80fm-1
  bzrlib/tests/test_commit.py    test_commit.py-20050914060732-279f057f8c295434
  bzrlib/tests/test_i18n.py      test_i18n.py-20110517012016-wjj0ai7qrasnj49p-1
  bzrlib/tests/test_smart_transport.py test_ssh_transport.py-20060608202016-c25gvf1ob7ypbus6-2
  doc/developers/releasing.txt   releasing.txt-20080502015919-fnrcav8fwy8ccibu-1
  doc/developers/testing.txt     testing.txt-20080812140359-i70zzh6v2z7grqex-1
  doc/en/release-notes/bzr-2.2.txt bzr2.2.txt-20101008081016-21wd86gpfhllpue3-39
  doc/en/release-notes/bzr-2.4.txt bzr2.4.txt-20110114053217-k7ym9jfz243fddjm-1
  doc/en/release-notes/bzr-2.5.txt bzr2.5.txt-20110708125756-587p0hpw7oke4h05-1
  doc/en/whats-new/whats-new-in-2.2.txt whatsnewin2.2.txt-20100304041442-cj7jdn23zakcw08l-1
  doc/en/whats-new/whats-new-in-2.4.txt whatsnewin2.4.txt-20110114044330-nipk1og7j729fy89-1
-------------- next part --------------
=== modified file 'bzrlib/commit.py'
--- a/bzrlib/commit.py	2011-08-31 17:11:32 +0000
+++ b/bzrlib/commit.py	2011-09-09 02:12:38 +0000
@@ -695,6 +695,8 @@
                 # Reset the new path (None) and new versioned flag (False)
                 change = (change[0], (change[1][0], None), change[2],
                     (change[3][0], False)) + change[4:]
+                new_path = change[1][1]
+                versioned = False
             elif kind == 'tree-reference':
                 if self.recursive == 'down':
                     self._commit_nested_tree(change[0], change[1][1])

=== modified file 'bzrlib/i18n.py'
--- a/bzrlib/i18n.py	2011-09-07 14:01:16 +0000
+++ b/bzrlib/i18n.py	2011-09-14 17:19:48 +0000
@@ -26,7 +26,7 @@
 import os
 import sys
 
-_translations = _gettext.NullTranslations()
+_translations = None
 
 
 def gettext(message):
@@ -34,6 +34,7 @@
     
     :returns: translated message as unicode.
     """
+    install()
     return _translations.ugettext(message)
 
 
@@ -46,6 +47,7 @@
 
     :returns: translated message as unicode.
     """
+    install()
     return _translations.ungettext(singular, plural, number)
 
 
@@ -59,6 +61,7 @@
 
     :returns: concatenated translated message as unicode.
     """
+    install()
     paragraphs = message.split(u'\n\n')
     ugettext = _translations.ugettext
     # Be careful not to translate the empty string -- it holds the
@@ -66,11 +69,20 @@
     return u'\n\n'.join(ugettext(p) if p else u'' for p in paragraphs)
 
 
+def disable_i18n():
+    """Do not allow i18n to be enabled.  Useful for third party users
+    of bzrlib."""
+    global _translations
+    _translations = _gettext.NullTranslations()
+
+
 def installed():
-    return not isinstance(_translations, _gettext.NullTranslations)
+    """Returns whether translations are in use or not."""
+    return _translations is not None
 
 
 def install(lang=None):
+    """Enables gettext translations."""
     global _translations
     if installed():
         return
@@ -88,8 +100,9 @@
 
 
 def uninstall():
+    """Disables gettext translations."""
     global _translations
-    _translations = _gettext.NullTranslations()
+    _translations = None
 
 
 def _get_locale_dir():

=== modified file 'bzrlib/mutabletree.py'
--- a/bzrlib/mutabletree.py	2011-08-15 20:10:03 +0000
+++ b/bzrlib/mutabletree.py	2011-09-06 09:51:45 +0000
@@ -746,9 +746,10 @@
                 # which is perhaps reasonable: adding a new reference is a
                 # special operation and can have a special behaviour.  mbp
                 # 20070306
-                trace.mutter("%r is a nested bzr tree", abspath)
+                trace.warning("skipping nested tree %r", abspath)
             else:
-                this_ie = self._add_one_and_parent(parent_ie, directory, kind, inv_path)
+                this_ie = self._add_one_and_parent(parent_ie, directory, kind,
+                    inv_path)
 
             if kind == 'directory' and not sub_tree:
                 if this_ie.kind != 'directory':

=== modified file 'bzrlib/tests/__init__.py'
--- a/bzrlib/tests/__init__.py	2011-09-15 09:50:23 +0000
+++ b/bzrlib/tests/__init__.py	2011-09-15 10:10:11 +0000
@@ -1007,7 +1007,7 @@
         if 'config_stats' in selftest_debug_flags:
             self._install_config_stats_hooks()
         # Do not use i18n for tests (unless the test reverses this)
-        self.overrideAttr(i18n, 'installed', lambda: True)
+        i18n.disable_i18n()
 
     def debug(self):
         # debug a frame up.

=== modified file 'bzrlib/tests/per_workingtree/test_smart_add.py'
--- a/bzrlib/tests/per_workingtree/test_smart_add.py	2011-06-14 01:26:41 +0000
+++ b/bzrlib/tests/per_workingtree/test_smart_add.py	2011-09-06 09:51:45 +0000
@@ -25,6 +25,7 @@
     ignores,
     osutils,
     tests,
+    trace,
     )
 from bzrlib.tests import (
     features,
@@ -91,6 +92,19 @@
         for path in paths:
             self.assertNotEqual(wt.path2id(path), None)
 
+    def test_skip_nested_trees(self):
+        """Test smart-adding a nested tree ignors it and warns."""
+        wt = self.make_branch_and_tree('.')
+        nested_wt = self.make_branch_and_tree('nested')
+        warnings = []
+        def warning(*args):
+            warnings.append(args[0] % args[1:])
+        self.overrideAttr(trace, 'warning', warning)
+        wt.smart_add((u".",))
+        self.assertIs(wt.path2id("nested"), None)
+        self.assertEquals(
+            ['skipping nested tree %r' % nested_wt.basedir], warnings)
+
     def test_add_dot_from_subdir(self):
         """Test adding . from a subdir of the tree."""
         paths = ("original/", "original/file1", "original/file2")
@@ -150,7 +164,8 @@
         self.build_tree(tree_shape)
         wt.smart_add(add_paths)
         for path in expected_paths:
-            self.assertNotEqual(wt.path2id(path), None, "No id added for %s" % path)
+            self.assertNotEqual(wt.path2id(path), None,
+                "No id added for %s" % path)
 
     def test_add_non_existant(self):
         """Test smart-adding a file that does not exist."""

=== modified file 'bzrlib/tests/test_commit.py'
--- a/bzrlib/tests/test_commit.py	2011-07-08 23:01:39 +0000
+++ b/bzrlib/tests/test_commit.py	2011-09-09 02:12:38 +0000
@@ -161,7 +161,11 @@
         wt.commit(message='add hello')
 
         os.remove('hello')
-        wt.commit('removed hello', rev_id='rev2')
+        reporter = CapturingReporter()
+        wt.commit('removed hello', rev_id='rev2', reporter=reporter)
+        self.assertEquals(
+            [('missing', u'hello'), ('deleted', u'hello')],
+            reporter.calls)
 
         tree = b.repository.revision_tree('rev2')
         self.assertFalse(tree.has_id('hello-id'))

=== modified file 'bzrlib/tests/test_i18n.py'
--- a/bzrlib/tests/test_i18n.py	2011-09-07 16:32:11 +0000
+++ b/bzrlib/tests/test_i18n.py	2011-09-14 17:17:25 +0000
@@ -97,17 +97,36 @@
 
 class TestInstall(tests.TestCase):
 
+    def setUp(self):
+        super(TestInstall, self).setUp()
+        # Restore a proper env to test translation installation
+        self.overrideAttr(i18n, '_translations', None)
+
     def test_custom_languages(self):
-        self.addCleanup(i18n.install)
         i18n.install('nl:fy')
+        # Whether we found a valid tranlsation or not doesn't matter, we got
+        # one and _translations is not None anymore.
+        self.assertIsInstance(i18n._translations,
+                              i18n._gettext.NullTranslations)
 
     def test_no_env_variables(self):
-        self.addCleanup(i18n.install)
         self.overrideEnv('LANGUAGE', None)
         self.overrideEnv('LC_ALL', None)
         self.overrideEnv('LC_MESSAGES', None)
         self.overrideEnv('LANG', None)
         i18n.install()
+        # Whether we found a valid tranlsation or not doesn't matter, we got
+        # one and _translations is not None anymore.
+        self.assertIsInstance(i18n._translations,
+                              i18n._gettext.NullTranslations)
+
+    def test_disable_i18n(self):
+        i18n.disable_i18n()
+        i18n.install()
+        # It's disabled, you can't install anything and we fallback to null
+        self.assertIsInstance(i18n._translations,
+                              i18n._gettext.NullTranslations)
+
 
 class TestTranslate(tests.TestCaseWithTransport):
 
@@ -119,7 +138,6 @@
         """do errors get translated?"""
         err = None
         tree = self.make_branch_and_tree('.')
-        self.overrideAttr(i18n, '_translations', ZzzTranslations())
         try:
             workingtree.WorkingTree.open('./foo')
         except errors.NotBranchError,e:
@@ -130,8 +148,6 @@
     def test_topic_help_translation(self):
         """does topic help get translated?"""
         from bzrlib import help
-        i18n.install()
-        self.overrideAttr(i18n, '_translations', ZzzTranslations())
         from StringIO import StringIO
         out = StringIO()
         help.help("authentication", out)

=== modified file 'bzrlib/tests/test_smart_transport.py'
--- a/bzrlib/tests/test_smart_transport.py	2011-09-15 09:55:32 +0000
+++ b/bzrlib/tests/test_smart_transport.py	2011-09-15 10:10:11 +0000
@@ -29,7 +29,7 @@
         errors,
         osutils,
         tests,
-        transport,
+        transport as _mod_transport,
         urlutils,
         )
 from bzrlib.smart import (
@@ -38,7 +38,7 @@
         message,
         protocol,
         request as _mod_request,
-        server,
+        server as _mod_server,
         vfs,
 )
 from bzrlib.tests import (
@@ -1126,15 +1126,15 @@
             mem_server.start_server()
             self.addCleanup(mem_server.stop_server)
             self.permit_url(mem_server.get_url())
-            self.backing_transport = transport.get_transport_from_url(
+            self.backing_transport = _mod_transport.get_transport_from_url(
                 mem_server.get_url())
         else:
             self.backing_transport = backing_transport
         if readonly:
             self.real_backing_transport = self.backing_transport
-            self.backing_transport = transport.get_transport_from_url(
+            self.backing_transport = _mod_transport.get_transport_from_url(
                 "readonly+" + self.backing_transport.abspath('.'))
-        self.server = server.SmartTCPServer(self.backing_transport)
+        self.server = _mod_server.SmartTCPServer(self.backing_transport)
         self.server.start_server('127.0.0.1', 0)
         self.server.start_background_thread('-' + self.id())
         self.transport = remote.RemoteTCPTransport(self.server.get_url())
@@ -1274,7 +1274,7 @@
     def test_server_started_hook_memory(self):
         """The server_started hook fires when the server is started."""
         self.hook_calls = []
-        server.SmartTCPServer.hooks.install_named_hook('server_started',
+        _mod_server.SmartTCPServer.hooks.install_named_hook('server_started',
             self.capture_server_call, None)
         self.start_server()
         # at this point, the server will be starting a thread up.
@@ -1288,10 +1288,10 @@
     def test_server_started_hook_file(self):
         """The server_started hook fires when the server is started."""
         self.hook_calls = []
-        server.SmartTCPServer.hooks.install_named_hook('server_started',
+        _mod_server.SmartTCPServer.hooks.install_named_hook('server_started',
             self.capture_server_call, None)
         self.start_server(
-            backing_transport=transport.get_transport_from_path("."))
+            backing_transport=_mod_transport.get_transport_from_path("."))
         # at this point, the server will be starting a thread up.
         # there is no indicator at the moment, so bodge it by doing a request.
         self.transport.has('.')
@@ -1305,7 +1305,7 @@
     def test_server_stopped_hook_simple_memory(self):
         """The server_stopped hook fires when the server is stopped."""
         self.hook_calls = []
-        server.SmartTCPServer.hooks.install_named_hook('server_stopped',
+        _mod_server.SmartTCPServer.hooks.install_named_hook('server_stopped',
             self.capture_server_call, None)
         self.start_server()
         result = [([self.backing_transport.base], self.transport.base)]
@@ -1322,10 +1322,10 @@
     def test_server_stopped_hook_simple_file(self):
         """The server_stopped hook fires when the server is stopped."""
         self.hook_calls = []
-        server.SmartTCPServer.hooks.install_named_hook('server_stopped',
+        _mod_server.SmartTCPServer.hooks.install_named_hook('server_stopped',
             self.capture_server_call, None)
         self.start_server(
-            backing_transport=transport.get_transport_from_path("."))
+            backing_transport=_mod_transport.get_transport_from_path("."))
         result = [(
             [self.backing_transport.base, self.backing_transport.external_url()]
             , self.transport.base)]
@@ -1467,13 +1467,13 @@
 class RemoteTransportRegistration(tests.TestCase):
 
     def test_registration(self):
-        t = transport.get_transport_from_url('bzr+ssh://example.com/path')
+        t = _mod_transport.get_transport_from_url('bzr+ssh://example.com/path')
         self.assertIsInstance(t, remote.RemoteSSHTransport)
         self.assertEqual('example.com', t._parsed_url.host)
 
     def test_bzr_https(self):
         # https://bugs.launchpad.net/bzr/+bug/128456
-        t = transport.get_transport_from_url('bzr+https://example.com/path')
+        t = _mod_transport.get_transport_from_url('bzr+https://example.com/path')
         self.assertIsInstance(t, remote.RemoteHTTPTransport)
         self.assertStartsWith(
             t._http_transport.base,

=== modified file 'doc/developers/releasing.txt'
--- a/doc/developers/releasing.txt	2011-09-06 09:11:54 +0000
+++ b/doc/developers/releasing.txt	2011-09-13 12:38:44 +0000
@@ -246,6 +246,18 @@
    this slow you down too much. This script accepts options you may find
    useful, use ``./tools/check-newsbugs.py`` to display its usage.
 
+#. For beta releases update the translation template::
+
+     make -f po/bzr.pot
+
+   This is especially important for the final beta release which is
+   when translations are frozen and translators are requested to make
+   the translations.
+
+#. For stable releases update the translations::
+
+     bzr merge lp:~bzr-core/bzr/bzr-translations-export-x.y
+
 #. Commit these changes to the release branch, using a command like::
 
      bzr commit -m "Release 2.3.1"
@@ -406,6 +418,9 @@
 You may also need to do `At the start of a series cycle`_ if you're starting
 a new series.
 
+The final beta - branching and translations
+-------------------------------------------
+
 A word of caution: the instructions above works well for all releases but
 there is one special case that requires a bit more care: when you release
 the *last* beta for a given ``x.y`` series (from trunk aka lp:bzr), you need
@@ -436,6 +451,26 @@
 
 #. Open ``lp:bzr/x.y`` for bug fixes
 
+You also need to ensure Launchpad is set up to import/export
+translations for the new branch and inform translators.
+
+#. Push a branch::
+
+     bzr push lp:~bzr-core/bzr/bzr-translations-export-x.y
+
+#. On the translations series synchronization settings page
+   <https://translations.launchpad.net/bzr/x.y/+translations-settings>
+   turn on ``Import template files`` then for exports click ``Choose a
+   target branch`` and point it at the branch you just pushed.
+
+#. E-mail translators to announce that the forthcoming stable release
+   of bzr is ready for translations.  Send to
+   ``translators at lists.launchpad.net`` and
+   ``ubuntu-translators at lists.ubuntu.com``.
+
+#. The series is now frozen for strings and API, see below for adding
+   that to the announcement.
+
 Announcing the source freeze
 ----------------------------
 
@@ -452,6 +487,10 @@
    the freeze. For older series supported only via SRUs for Ubuntu, we don't
    control the process as tightly so guessing the date is not appropriate.
 
+   For the final beta release include in your announcement a notice of
+   API and translation freezes nothing that public methods should not
+   be removed or changed and strings should not be added or changed.
+
 #. Pause for a few days. 
 
 

=== modified file 'doc/developers/testing.txt'
--- a/doc/developers/testing.txt	2011-08-04 00:28:09 +0000
+++ b/doc/developers/testing.txt	2011-09-14 16:38:55 +0000
@@ -745,6 +745,22 @@
         _test_needs_features = [features.apport]
 
 
+Testing translations
+-----------------------
+
+Translations are disabled by default in tests.  If you want to test
+that code is translated you can use the ``ZzzTranslations`` class from
+``test_i18n``::
+
+    self.overrideAttr(i18n, '_translations', ZzzTranslations())
+
+And check the output strings look like ``u"zz\xe5{{output}}"``.
+
+To test the gettext setup and usage you override i18n.installed back
+to self.i18nInstalled and _translations to None, see
+test_i18n.TestInstall.
+
+
 Testing deprecated code
 -----------------------
 

=== modified file 'doc/en/release-notes/bzr-2.2.txt'
--- a/doc/en/release-notes/bzr-2.2.txt	2011-07-06 09:22:00 +0000
+++ b/doc/en/release-notes/bzr-2.2.txt	2011-09-09 13:30:12 +0000
@@ -5,18 +5,56 @@
 .. toctree::
    :maxdepth: 1
 
+bzr 2.2.6
+#########
+
+:2.2.6: NOT RELEASED YET
+
+Compatibility Breaks
+********************
+
+New Features
+************
+
+Bug Fixes
+*********
+
+Improvements
+************
+
+Documentation
+*************
+
+API Changes
+***********
+
+Internals
+*********
+
+Testing
+*******
+
+
 bzr 2.2.5
 #########
 
-:Codename: Suggestions welcome
-:2.2.5: NOT RELEASED YET
+:2.2.5: 2011-09-01
+
+This is a bugfix release. One regression introduced in 2.2b1 has been fixed
+for some rare conflict resolutions. Also a warning is now emmitted when
+branching an out-of-date ubuntu packaging branch. Upgrading is recommended
+for all users on earlier 2.2 releases.
 
 Compatibility Breaks
 ********************
 
+None.
+
 New Features
 ************
 
+None.
+
 Bug Fixes
 *********
 
@@ -27,15 +65,6 @@
 * Don't crash while merging and encountering obscure path conflicts
   involving different root-ids. (Vincent Ladeuil, #805809)
 
-Improvements
-************
-
-Documentation
-*************
-
-API Changes
-***********
-
 Internals
 *********
 
@@ -43,9 +72,6 @@
   in the value string. Fix suggested by ConfigObj's author Michael Foord.
   (Alexander Belchenko, #710410)
 
-Testing
-*******
-
 
 bzr 2.2.4
 #########

=== modified file 'doc/en/release-notes/bzr-2.4.txt'
--- a/doc/en/release-notes/bzr-2.4.txt	2011-09-06 11:01:30 +0000
+++ b/doc/en/release-notes/bzr-2.4.txt	2011-09-13 12:29:22 +0000
@@ -5,10 +5,69 @@
 .. toctree::
    :maxdepth: 1
 
+bzr 2.4.2
+#########
+
+:2.4.2: NOT RELEASED YET
+
+External Compatibility Breaks
+*****************************
+
+.. These may require users to change the way they use Bazaar.
+
+New Features
+************
+
+.. New commands, options, etc that users may wish to try out.
+
+Improvements
+************
+
+.. Improvements to existing commands, especially improved performance 
+   or memory usage, or better results.
+
+Bug Fixes
+*********
+
+* Fixed loading of external merge tools from config to properly decode
+  command-lines which contain embedded quotes. (Gordon Tyler, #828803)
+
+Documentation
+*************
+
+.. Improved or updated documentation.
+
+API Changes
+***********
+
+.. Changes that may require updates in plugins or other code that uses
+   bzrlib.
+
+Internals
+*********
+
+.. Major internal changes, unlikely to be visible to users or plugin 
+   developers, but interesting for bzr developers.
+
+Testing
+*******
+
+.. Fixes and changes that are only relevant to bzr's test framework and 
+   suite.  This can include new facilities for writing tests, fixes to 
+   spurious test failures and changes to the way things should be tested.
+
+
 bzr 2.4.1
 #########
 
-:2.4.1: NOT RELEASED YET
+:2.4.1: 2011-09-08
+
+This is a bugfix release. Upgrading is recommended for all users of earlier
+2.4 releases.
+
+It includes fixes from previous stable releases and address some issues with
+the test suite.
+
 
 External Compatibility Breaks
 *****************************

=== modified file 'doc/en/release-notes/bzr-2.5.txt'
--- a/doc/en/release-notes/bzr-2.5.txt	2011-09-15 09:33:39 +0000
+++ b/doc/en/release-notes/bzr-2.5.txt	2011-09-15 10:10:11 +0000
@@ -97,11 +97,9 @@
   option. A value of 0 disables skipping. Named items passed to add are
   never skipped. (Shannon Weyrick, #54624)
 
-* bzr now ships with translations for command help.  (Jonathan
-  Riddell, INADA Naoki, #83941)
-
-* bzr now ships with translations for command errors. (Jonathan
-  Riddell, INADA Naoki)
+* Translations are now enabled for command help, errors and globally
+  for any message using gettext given on output.  (Jonathan Riddell,
+  INADA Naoki, #83941)
 
 Improvements
 ************
@@ -109,6 +107,9 @@
 .. Improvements to existing commands, especially improved performance 
    or memory usage, or better results.
 
+* ``bzr add`` will now warn about nested subtrees that are skipped.
+  (Jelmer Vernooij, #187342)
+
 * ``bzr commit -m ''`` can now be used to force an empty commit message.
   Entering an empty commit message in the message editor still triggers
   an error. (Jelmer Vernooij)
@@ -150,6 +151,9 @@
 .. Fixes for situations where bzr would previously crash or give incorrect
    or undesirable results.
 
+* ``bzr commit`` now correctly reports missing files as "removed", not
+  "modified". (Jelmer Vernooij, #553955)
+
 * ``bzr reconfigure`` will now allow multiple non-conflicting requests
   in a single invocation, e.g. ``--branch`` and ``--use-shared``.
   (Martin von Gagern, #842993)

=== modified file 'doc/en/whats-new/whats-new-in-2.2.txt'
--- a/doc/en/whats-new/whats-new-in-2.2.txt	2011-07-05 11:54:54 +0000
+++ b/doc/en/whats-new/whats-new-in-2.2.txt	2011-09-09 12:32:08 +0000
@@ -38,6 +38,9 @@
 Bazaar 2.2.4 fixed a regression for some interactions with the launchpad
 server.
 
+Bazaar 2.2.5 fixed a regression in some rare conflict resolutions and warns
+when branching an out-of-date ubuntu packaging branch.
+
 See the :doc:`../release-notes/index` for details.
 
 Bazaar 2.2 is fully compatible both locally and on the network with 2.0

=== modified file 'doc/en/whats-new/whats-new-in-2.4.txt'
--- a/doc/en/whats-new/whats-new-in-2.4.txt	2011-08-12 09:49:24 +0000
+++ b/doc/en/whats-new/whats-new-in-2.4.txt	2011-09-13 12:29:22 +0000
@@ -20,6 +20,11 @@
 2.1, 2.2 and 2.3, and can read and write repositories generated by all
 previous versions.
 
+Bazaar 2.4.1 includes all the fixes in the un-released 2.0.7, 2.1.5, 2.2.6
+and 2.3.5 versions that weren't included in 2.4.0 and fixes some bugs on its
+own.
+
+
 Dropping Python2.4 and Python2.5 support
 ****************************************
 



More information about the bazaar-commits mailing list