Rev 2416: Handle the case when we are adding a file to an empty directory. in http://bazaar.launchpad.net/%7Ebzr/bzr/dirstate
John Arbash Meinel
john at arbash-meinel.com
Mon Feb 26 16:54:19 GMT 2007
At http://bazaar.launchpad.net/%7Ebzr/bzr/dirstate
------------------------------------------------------------
revno: 2416
revision-id: john at arbash-meinel.com-20070226165316-2zipahl3tlihiij9
parent: john at arbash-meinel.com-20070226161902-onqljoh62n5r80gh
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: dirstate
timestamp: Mon 2007-02-26 10:53:16 -0600
message:
Handle the case when we are adding a file to an empty directory.
Add a suite of tests for WorkingTree.add()
added:
bzrlib/tests/workingtree_implementations/test_add.py test_add.py-20070226165239-4vo178spkrnhavc7-1
modified:
bzrlib/dirstate.py dirstate.py-20060728012006-d6mvoihjb3je9peu-1
bzrlib/tests/workingtree_implementations/__init__.py __init__.py-20060203003124-b2aa5aca21a8bfad
-------------- next part --------------
=== added file 'bzrlib/tests/workingtree_implementations/test_add.py'
--- a/bzrlib/tests/workingtree_implementations/test_add.py 1970-01-01 00:00:00 +0000
+++ b/bzrlib/tests/workingtree_implementations/test_add.py 2007-02-26 16:53:16 +0000
@@ -0,0 +1,123 @@
+# Copyright (C) 2007 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""Tests for interface conformance of 'WorkingTree.add'"""
+
+import os
+
+from bzrlib import (
+ errors,
+ osutils,
+ )
+
+from bzrlib.workingtree_4 import WorkingTreeFormat4
+from bzrlib.tests.workingtree_implementations import TestCaseWithWorkingTree
+
+
+class TestAdd(TestCaseWithWorkingTree):
+
+ def get_tree_layout(self, tree):
+ """Get the (path, file_id) pairs for the current tree."""
+ tree.lock_read()
+ try:
+ return [(path, ie.file_id) for path, ie
+ in tree.iter_entries_by_dir()]
+ finally:
+ tree.unlock()
+
+ def assertTreeLayout(self, expected, tree):
+ """Check that the tree has the correct layout."""
+ actual = self.get_tree_layout(tree)
+ self.assertEqual(expected, actual)
+
+ def test_add_one(self):
+ tree = self.make_branch_and_tree('.')
+ self.build_tree(['one'])
+ tree.add('one', 'one-id')
+ root_id = tree.get_root_id()
+
+ self.assertTreeLayout([('', root_id), ('one', 'one-id')], tree)
+
+ def test_add_one_list(self):
+ tree = self.make_branch_and_tree('.')
+ self.build_tree(['one'])
+ tree.add(['one'], ['one-id'])
+ root_id = tree.get_root_id()
+
+ self.assertTreeLayout([('', root_id), ('one', 'one-id')], tree)
+
+ def test_add_one_new_id(self):
+ tree = self.make_branch_and_tree('.')
+ self.build_tree(['one'])
+ tree.add(['one'])
+ root_id = tree.get_root_id()
+ one_id = tree.path2id('one')
+
+ self.assertTreeLayout([('', root_id), ('one', one_id)], tree)
+
+ def test_add_unicode(self):
+ tree = self.make_branch_and_tree('.')
+ try:
+ self.build_tree([u'f\xf6'])
+ except UnicodeError:
+ raise tests.TestSkipped('Filesystem does not support filename.')
+ tree.add([u'f\xf6'])
+ root_id = tree.get_root_id()
+ foo_id = tree.path2id(u'f\xf6')
+
+ self.assertTreeLayout([('', root_id), (u'f\xf6', foo_id)], tree)
+
+ def test_add_subdir(self):
+ tree = self.make_branch_and_tree('.')
+ self.build_tree(['dir/', 'dir/subdir/', 'dir/subdir/foo'])
+ tree.add(['dir'], ['dir-id'])
+ tree.add(['dir/subdir'], ['subdir-id'])
+ tree.add(['dir/subdir/foo'], ['foo-id'])
+ root_id = tree.get_root_id()
+
+ self.assertTreeLayout([('', root_id), ('dir', 'dir-id'),
+ ('dir/subdir', 'subdir-id'),
+ ('dir/subdir/foo', 'foo-id')], tree)
+
+ def test_add_multiple(self):
+ tree = self.make_branch_and_tree('.')
+ self.build_tree(['a', 'b', 'dir/', 'dir/subdir/', 'dir/subdir/foo'])
+ tree.add(['a', 'b', 'dir', 'dir/subdir', 'dir/subdir/foo'],
+ ['a-id', 'b-id', 'dir-id', 'subdir-id', 'foo-id'])
+ root_id = tree.get_root_id()
+
+ self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id'),
+ ('dir', 'dir-id'), ('dir/subdir', 'subdir-id'),
+ ('dir/subdir/foo', 'foo-id')], tree)
+
+ def test_add_invalid(self):
+ tree = self.make_branch_and_tree('.')
+ self.build_tree(['dir/', 'dir/subdir/', 'dir/subdir/foo'])
+ root_id = tree.get_root_id()
+
+ self.assertRaises(errors.NotVersionedError,
+ tree.add, ['dir/subdir'])
+ self.assertTreeLayout([('', root_id)], tree)
+
+ def test_add_after_remove(self):
+ tree = self.make_branch_and_tree('.')
+ self.build_tree(['dir/', 'dir/subdir/', 'dir/subdir/foo'])
+ root_id = tree.get_root_id()
+ tree.add(['dir'], ['dir-id'])
+ tree.commit('dir', rev_id='rev-1')
+ tree.unversion(['dir-id'])
+ self.assertRaises(errors.NotVersionedError,
+ tree.add, ['dir/subdir'])
=== modified file 'bzrlib/dirstate.py'
--- a/bzrlib/dirstate.py 2007-02-26 00:45:31 +0000
+++ b/bzrlib/dirstate.py 2007-02-26 16:53:16 +0000
@@ -324,11 +324,15 @@
self._read_dirblocks_if_needed()
block_index, present = self._find_block_index_from_key(entry_key)
if not present:
- # TODO: This test is not complete - an empty directory, or a
- # directory for a parent tree will fool it.
- # some parent path has not been added - its an error to add this
- # child
- raise errors.NotVersionedError(path, str(self))
+ # The block where we want to put the file is not present. But it
+ # might be because the directory was empty, or not loaded yet. Look
+ # for a parent entry, if not found, raise NotVersionedError
+ parent_dir, parent_base = osutils.split(dirname)
+ parent_block_idx, parent_entry_idx, _, parent_present = \
+ self._get_block_entry_index(parent_dir, parent_base, 0)
+ if not parent_present:
+ raise errors.NotVersionedError(path, str(self))
+ self._ensure_block(parent_block_idx, parent_entry_idx, dirname)
block = self._dirblocks[block_index][1]
if stat is None:
size = 0
=== modified file 'bzrlib/tests/workingtree_implementations/__init__.py'
--- a/bzrlib/tests/workingtree_implementations/__init__.py 2007-02-26 16:19:02 +0000
+++ b/bzrlib/tests/workingtree_implementations/__init__.py 2007-02-26 16:53:16 +0000
@@ -49,6 +49,7 @@
def test_suite():
result = TestSuite()
test_workingtree_implementations = [
+ 'bzrlib.tests.workingtree_implementations.test_add',
'bzrlib.tests.workingtree_implementations.test_basis_inventory',
'bzrlib.tests.workingtree_implementations.test_basis_tree',
'bzrlib.tests.workingtree_implementations.test_break_lock',
More information about the bazaar-commits
mailing list