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