Rev 5063: (mbp) merge 2.1 to 2.2 (Martin Pool) in file:///home/pqm/archives/thelove/bzr/2.2/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Wed Jul 21 12:22:54 BST 2010


At file:///home/pqm/archives/thelove/bzr/2.2/

------------------------------------------------------------
revno: 5063 [merge]
revision-id: pqm at pqm.ubuntu.com-20100721112253-4c8u0jdfqsk5o412
parent: pqm at pqm.ubuntu.com-20100720185226-sjt3wlejijg19w9n
parent: mbp at canonical.com-20100721095842-hz0obu8gl0x05nty
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: 2.2
timestamp: Wed 2010-07-21 12:22:53 +0100
message:
  (mbp) merge 2.1 to 2.2 (Martin Pool)
added:
  bzrlib/tests/per_workingtree/test_symlinks.py test_symlinks.py-20100715135626-4lw38d8njbzyec6l-1
  bzrlib/tests/test_treeshape.py test_treeshape.py-20100715135036-z8vz2u7f3w7wg2it-1
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
  bzrlib/chk_map.py              chk_map.py-20081001014447-ue6kkuhofvdecvxa-1
  bzrlib/mutabletree.py          mutabletree.py-20060906023413-4wlkalbdpsxi2r4y-2
  bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
  bzrlib/tests/per_workingtree/__init__.py __init__.py-20060203003124-b2aa5aca21a8bfad
  bzrlib/tests/test_chk_map.py   test_chk_map.py-20081001014447-ue6kkuhofvdecvxa-2
  bzrlib/tests/test_upgrade.py   test_upgrade.py-20051004040251-555fe1d2bae1bc71
  bzrlib/tests/treeshape.py      treeshape.py-20051004094628-312a98f0194306a8
=== modified file 'NEWS'
--- a/NEWS	2010-07-20 15:17:58 +0000
+++ b/NEWS	2010-07-21 09:58:42 +0000
@@ -1032,6 +1032,11 @@
 * Don't traceback trying to unversion children files of an already
   unversioned directory.  (Vincent Ladeuil, #494221)
 
+* Prevent ``CHKMap.apply_delta`` from generating non-canonical CHK maps,
+  which can result in "missing referenced chk root keys" errors when
+  fetching from repositories with affected revisions.
+  (Andrew Bennetts, #522637)
+
 * Raise ValueError instead of a string exception.
   (John Arbash Meinel, #586926)
 
@@ -1537,6 +1542,10 @@
   history no longer crash when deleted files are involved.
   (Vincent Ladeuil, John Arbash Meinel, #375898)
 
+* ``bzr commit SYMLINK`` now works, rather than trying to commit the
+  target of the symlink.
+  (Martin Pool, John Arbash Meinel, #128562)
+
 * ``bzr revert`` now only takes write lock on working tree, instead of on 
   both working tree and branch.
   (Danny van Heumen, #498409)
@@ -1548,6 +1557,11 @@
 * Don't traceback trying to unversion children files of an already
   unversioned directory.  (Vincent Ladeuil, #494221)
 
+* Prevent ``CHKMap.apply_delta`` from generating non-canonical CHK maps,
+  which can result in "missing referenced chk root keys" errors when
+  fetching from repositories with affected revisions.
+  (Andrew Bennetts, #522637)
+
 * Raise ValueError instead of a string exception.
   (John Arbash Meinel, #586926)
 
@@ -1571,6 +1585,13 @@
   (John Arbash Meinel, #583486)
 
 
+Testing
+*******
+
+* ``build_tree_contents`` can create symlinks.
+  (Martin Pool, John Arbash Meinel)
+
+
 bzr 2.0.5
 #########
 

=== modified file 'bzrlib/builtins.py'
--- a/bzrlib/builtins.py	2010-07-18 14:22:34 +0000
+++ b/bzrlib/builtins.py	2010-07-21 09:58:42 +0000
@@ -180,7 +180,7 @@
                 view_str = views.view_display_str(view_files)
                 note("Ignoring files outside view. View is %s" % view_str)
         return tree, file_list
-    tree = WorkingTree.open_containing(osutils.realpath(file_list[0]))[0]
+    tree = WorkingTree.open_containing(file_list[0])[0]
     return tree, safe_relpath_files(tree, file_list, canonicalize,
         apply_view=apply_view)
 

=== modified file 'bzrlib/chk_map.py'
--- a/bzrlib/chk_map.py	2010-05-11 10:45:26 +0000
+++ b/bzrlib/chk_map.py	2010-07-21 09:58:42 +0000
@@ -90,8 +90,6 @@
 _INTERESTING_NEW_SIZE = 50
 # If a ChildNode shrinks by more than this amount, we check for a remap
 _INTERESTING_SHRINKAGE_LIMIT = 20
-# If we delete more than this many nodes applying a delta, we check for a remap
-_INTERESTING_DELETES_LIMIT = 5
 
 
 def _search_key_plain(key):
@@ -135,7 +133,7 @@
             into the map; if old_key is not None, then the old mapping
             of old_key is removed.
         """
-        delete_count = 0
+        has_deletes = False
         # Check preconditions first.
         as_st = StaticTuple.from_sequence
         new_items = set([as_st(key) for (old, key, value) in delta
@@ -148,12 +146,11 @@
         for old, new, value in delta:
             if old is not None and old != new:
                 self.unmap(old, check_remap=False)
-                delete_count += 1
+                has_deletes = True
         for old, new, value in delta:
             if new is not None:
                 self.map(new, value)
-        if delete_count > _INTERESTING_DELETES_LIMIT:
-            trace.mutter("checking remap as %d deletions", delete_count)
+        if has_deletes:
             self._check_remap()
         return self._save()
 
@@ -573,7 +570,7 @@
         """Check if nodes can be collapsed."""
         self._ensure_root()
         if type(self._root_node) is InternalNode:
-            self._root_node._check_remap(self._store)
+            self._root_node = self._root_node._check_remap(self._store)
 
     def _save(self):
         """Save the map completely.

=== modified file 'bzrlib/mutabletree.py'
--- a/bzrlib/mutabletree.py	2010-05-10 11:34:20 +0000
+++ b/bzrlib/mutabletree.py	2010-07-21 09:58:42 +0000
@@ -375,6 +375,10 @@
         This is designed more towards DWIM for humans than API clarity.
         For the specific behaviour see the help for cmd_add().
 
+        :param file_list: List of zero or more paths.  *NB: these are 
+            interpreted relative to the process cwd, not relative to the 
+            tree.*  (Add and most other tree methods use tree-relative
+            paths.)
         :param action: A reporter to be called with the inventory, parent_ie,
             path and kind of the path being added. It may return a file_id if
             a specific one should be used.

=== modified file 'bzrlib/tests/__init__.py'
--- a/bzrlib/tests/__init__.py	2010-07-18 14:28:12 +0000
+++ b/bzrlib/tests/__init__.py	2010-07-21 09:58:42 +0000
@@ -3813,6 +3813,7 @@
         'bzrlib.tests.test_transport_log',
         'bzrlib.tests.test_tree',
         'bzrlib.tests.test_treebuilder',
+        'bzrlib.tests.test_treeshape',
         'bzrlib.tests.test_tsort',
         'bzrlib.tests.test_tuned_gzip',
         'bzrlib.tests.test_ui',

=== modified file 'bzrlib/tests/per_workingtree/__init__.py'
--- a/bzrlib/tests/per_workingtree/__init__.py	2010-04-01 12:53:53 +0000
+++ b/bzrlib/tests/per_workingtree/__init__.py	2010-07-21 09:58:42 +0000
@@ -101,6 +101,7 @@
         'revision_tree',
         'set_root_id',
         'smart_add',
+        'symlinks',
         'uncommit',
         'unversion',
         'views',

=== added file 'bzrlib/tests/per_workingtree/test_symlinks.py'
--- a/bzrlib/tests/per_workingtree/test_symlinks.py	1970-01-01 00:00:00 +0000
+++ b/bzrlib/tests/per_workingtree/test_symlinks.py	2010-07-16 10:48:51 +0000
@@ -0,0 +1,98 @@
+# Copyright (C) 2010 Canonical Ltd
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+"""Test symlink support.
+
+See eg <https://bugs.launchpad.net/bzr/+bug/192859>
+"""
+
+from bzrlib import (
+    builtins,
+    tests,
+    workingtree,
+    )
+from bzrlib.tests.per_workingtree import TestCaseWithWorkingTree
+
+
+class TestSmartAddTree(TestCaseWithWorkingTree):
+
+    _test_needs_features = [tests.SymlinkFeature]
+
+    def test_smart_add_symlink(self):
+        tree = self.make_branch_and_tree('tree')
+        self.build_tree_contents([
+            ('tree/link@', 'target'),
+            ])
+        tree.smart_add(['tree/link'])
+        self.assertIsNot(None, tree.path2id('link'))
+        self.assertIs(None, tree.path2id('target'))
+        self.assertEqual('symlink',
+            tree.kind(tree.path2id('link')))
+
+    def test_smart_add_symlink_pointing_outside(self):
+        tree = self.make_branch_and_tree('tree')
+        self.build_tree_contents([
+            ('tree/link@', '../../../../target'),
+            ])
+        tree.smart_add(['tree/link'])
+        self.assertIsNot(None, tree.path2id('link'))
+        self.assertIs(None, tree.path2id('target'))
+        self.assertEqual('symlink',
+            tree.kind(tree.path2id('link')))
+
+    def test_open_containing_through_symlink(self):
+        self.make_test_tree()
+        self.check_open_containing('link/content', 'tree', 'content')
+        self.check_open_containing('link/sublink', 'tree', 'sublink')
+        # this next one is a bit debatable, but arguably it's better that
+        # open_containing is only concerned with opening the tree 
+        # and then you can deal with symlinks along the way if you want
+        self.check_open_containing('link/sublink/subcontent', 'tree',
+            'sublink/subcontent')
+
+    def check_open_containing(self, to_open, expected_tree_name,
+        expected_relpath):
+        wt, relpath = workingtree.WorkingTree.open_containing(to_open)
+        self.assertEquals(relpath, expected_relpath)
+        self.assertEndsWith(wt.basedir, expected_tree_name)
+
+    def test_tree_files(self):
+        # not strictly a WorkingTree method, but it should be
+        # probably the root cause for
+        # <https://bugs.launchpad.net/bzr/+bug/128562>
+        self.make_test_tree()
+        self.check_tree_files(['tree/outerlink'],
+            'tree', ['outerlink'])
+        self.check_tree_files(['link/outerlink'],
+            'tree', ['outerlink'])
+        self.check_tree_files(['link/sublink/subcontent'],
+            'tree', ['subdir/subcontent'])
+
+    def check_tree_files(self, to_open, expected_tree, expect_paths):
+        tree, relpaths = builtins.tree_files(to_open)
+        self.assertEndsWith(tree.basedir, expected_tree)
+        self.assertEquals(expect_paths, relpaths)
+
+    def make_test_tree(self):
+        tree = self.make_branch_and_tree('tree')
+        self.build_tree_contents([
+            ('link@', 'tree'),
+            ('tree/outerlink@', '/not/there'),
+            ('tree/content', 'hello'),
+            ('tree/sublink@', 'subdir'),
+            ('tree/subdir/',),
+            ('tree/subdir/subcontent', 'subcontent stuff')
+            ])

=== modified file 'bzrlib/tests/test_chk_map.py'
--- a/bzrlib/tests/test_chk_map.py	2010-02-23 07:43:11 +0000
+++ b/bzrlib/tests/test_chk_map.py	2010-07-21 09:58:42 +0000
@@ -467,6 +467,25 @@
         # updated key.
         self.assertEqual(new_root, chkmap._root_node._key)
 
+    def test_apply_delete_to_internal_node(self):
+        # applying a delta should be convert an internal root node to a leaf
+        # node if the delta shrinks the map enough.
+        store = self.get_chk_bytes()
+        chkmap = CHKMap(store, None)
+        # Add three items: 2 small enough to fit in one node, and one huge to
+        # force multiple nodes.
+        chkmap._root_node.set_maximum_size(100)
+        chkmap.map(('small',), 'value')
+        chkmap.map(('little',), 'value')
+        chkmap.map(('very-big',), 'x' * 100)
+        # (Check that we have constructed the scenario we want to test)
+        self.assertIsInstance(chkmap._root_node, InternalNode)
+        # Delete the huge item so that the map fits in one node again.
+        delta = [(('very-big',), None, None)]
+        chkmap.apply_delta(delta)
+        self.assertCanonicalForm(chkmap)
+        self.assertIsInstance(chkmap._root_node, LeafNode)
+
     def test_apply_new_keys_must_be_new(self):
         # applying a delta (None, "a", "b") to a map with 'a' in it generates
         # an error.

=== added file 'bzrlib/tests/test_treeshape.py'
--- a/bzrlib/tests/test_treeshape.py	1970-01-01 00:00:00 +0000
+++ b/bzrlib/tests/test_treeshape.py	2010-07-15 13:55:46 +0000
@@ -0,0 +1,41 @@
+# Copyright (C) 2010 Canonical Ltd
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+import os
+
+
+from bzrlib import tests
+
+
+class TestTreeShape(tests.TestCaseWithTransport):
+
+    def test_build_tree(self):
+        """Test tree-building test helper"""
+        self.build_tree_contents([
+            ('foo', 'new contents'),
+            ('.bzr/',),
+            ('.bzr/README', 'hello'),
+            ])
+        self.failUnlessExists('foo')
+        self.failUnlessExists('.bzr/README')
+        self.assertFileEqual('hello', '.bzr/README')
+
+    def test_build_tree_symlink(self):
+        self.requireFeature(tests.SymlinkFeature)
+        self.build_tree_contents([('link@', 'target')])
+        self.assertEqual('target',
+            os.readlink('link'))

=== modified file 'bzrlib/tests/test_upgrade.py'
--- a/bzrlib/tests/test_upgrade.py	2010-06-20 11:18:38 +0000
+++ b/bzrlib/tests/test_upgrade.py	2010-07-21 09:58:42 +0000
@@ -43,12 +43,6 @@
 
 class TestUpgrade(TestCaseWithTransport):
 
-    def test_build_tree(self):
-        """Test tree-building test helper"""
-        self.build_tree_contents(_upgrade1_template)
-        self.failUnlessExists('foo')
-        self.failUnlessExists('.bzr/README')
-
     def test_upgrade_simple(self):
         """Upgrade simple v0.0.4 format to latest format"""
         eq = self.assertEquals

=== modified file 'bzrlib/tests/treeshape.py'
--- a/bzrlib/tests/treeshape.py	2010-05-05 00:05:29 +0000
+++ b/bzrlib/tests/treeshape.py	2010-07-21 09:58:42 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2005 Canonical Ltd
+# Copyright (C) 2005, 2010 Canonical Ltd
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -51,7 +51,7 @@
         if name[-1] == '/':
             os.mkdir(name)
         elif name[-1] == '@':
-            raise NotImplementedError('symlinks not handled yet')
+            os.symlink(tt[1], tt[0][:-1])
         else:
             f = file(name, 'wb')
             try:




More information about the bazaar-commits mailing list