Rev 3044: TreeTransform handles case-insensitive filesystems well in file:///home/pqm/archives/thelove/bzr/%2Btrunk/
Canonical.com Patch Queue Manager
pqm at pqm.ubuntu.com
Wed Nov 28 23:08:47 GMT 2007
At file:///home/pqm/archives/thelove/bzr/%2Btrunk/
------------------------------------------------------------
revno: 3044
revision-id:pqm at pqm.ubuntu.com-20071128230840-b2ra2nso0qtqxon6
parent: pqm at pqm.ubuntu.com-20071128171926-dafi3r2iq6e4vle1
parent: bialix at ukr.net-20071128210408-bfc2z901pk1e6fje
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Wed 2007-11-28 23:08:40 +0000
message:
TreeTransform handles case-insensitive filesystems well
modified:
bzrlib/tests/__init__.py selftest.py-20050531073622-8d0e3c8845c97a64
bzrlib/tests/test_transform.py test_transaction.py-20060105172520-b3ffb3946550e6c4
bzrlib/tests/workingtree_implementations/test_workingtree.py test_workingtree.py-20060203003124-817757d3e31444fb
bzrlib/transform.py transform.py-20060105172343-dd99e54394d91687
bzrlib/workingtree.py workingtree.py-20050511021032-29b6ec0a681e02e3
bzrlib/workingtree_4.py workingtree_4.py-20070208044105-5fgpc5j3ljlh5q6c-1
------------------------------------------------------------
revno: 3034.4.9
revision-id:bialix at ukr.net-20071128210408-bfc2z901pk1e6fje
parent: bialix at ukr.net-20071128205924-ozm9qxt0texyc4ln
committer: Alexander Belchenko <bialix at ukr.net>
branch nick: aaron
timestamp: Wed 2007-11-28 23:04:08 +0200
message:
skip test_workingtree.TestWorkingTree.test_case_sensitive for WT2
modified:
bzrlib/tests/workingtree_implementations/test_workingtree.py test_workingtree.py-20060203003124-817757d3e31444fb
------------------------------------------------------------
revno: 3034.4.8
revision-id:bialix at ukr.net-20071128205924-ozm9qxt0texyc4ln
parent: abentley at panoramicfeedback.com-20071128145615-6ckqqiymro15jbb1
committer: Alexander Belchenko <bialix at ukr.net>
branch nick: aaron
timestamp: Wed 2007-11-28 22:59:24 +0200
message:
TestCaseInTempDir.build_tree now checks type of shape argument.
modified:
bzrlib/tests/__init__.py selftest.py-20050531073622-8d0e3c8845c97a64
------------------------------------------------------------
revno: 3034.4.7
revision-id:abentley at panoramicfeedback.com-20071128145615-6ckqqiymro15jbb1
parent: abentley at panoramicfeedback.com-20071128142240-kkw4ft7p545p0a0k
committer: Aaron Bentley <abentley at panoramicfeedback.com>
branch nick: transform-case
timestamp: Wed 2007-11-28 09:56:15 -0500
message:
Add test for filename conflicts with existing files
modified:
bzrlib/tests/test_transform.py test_transaction.py-20060105172520-b3ffb3946550e6c4
------------------------------------------------------------
revno: 3034.4.6
revision-id:abentley at panoramicfeedback.com-20071128142240-kkw4ft7p545p0a0k
parent: abentley at panoramicfeedback.com-20071128141636-bbm7lusqat2ek2ao
committer: Aaron Bentley <abentley at panoramicfeedback.com>
branch nick: transform-case
timestamp: Wed 2007-11-28 09:22:40 -0500
message:
Update apply_case_conflict tests
modified:
bzrlib/tests/test_transform.py test_transaction.py-20060105172520-b3ffb3946550e6c4
------------------------------------------------------------
revno: 3034.4.5
revision-id:abentley at panoramicfeedback.com-20071128141636-bbm7lusqat2ek2ao
parent: aaron.bentley at utoronto.ca-20071128022527-juav8ud1712wphwz
committer: Aaron Bentley <abentley at panoramicfeedback.com>
branch nick: transform-case
timestamp: Wed 2007-11-28 09:16:36 -0500
message:
Add workingtree test for case_insensitive var
modified:
bzrlib/tests/workingtree_implementations/test_workingtree.py test_workingtree.py-20060203003124-817757d3e31444fb
------------------------------------------------------------
revno: 3034.4.4
revision-id:aaron.bentley at utoronto.ca-20071128022527-juav8ud1712wphwz
parent: aaron.bentley at utoronto.ca-20071128012128-gz9ep3oyvh1xt38n
committer: Aaron Bentley <aaron.bentley at utoronto.ca>
branch nick: transform-case
timestamp: Tue 2007-11-27 21:25:27 -0500
message:
Fix case-sensitivity detection
modified:
bzrlib/workingtree.py workingtree.py-20050511021032-29b6ec0a681e02e3
------------------------------------------------------------
revno: 3034.4.3
revision-id:aaron.bentley at utoronto.ca-20071128012128-gz9ep3oyvh1xt38n
parent: aaron.bentley at utoronto.ca-20071128000531-mq2lgadv5c9471nf
committer: Aaron Bentley <aaron.bentley at utoronto.ca>
branch nick: transform-case
timestamp: Tue 2007-11-27 20:21:28 -0500
message:
Add case-sensitivity handling to WorkingTree
modified:
bzrlib/tests/test_transform.py test_transaction.py-20060105172520-b3ffb3946550e6c4
bzrlib/workingtree.py workingtree.py-20050511021032-29b6ec0a681e02e3
bzrlib/workingtree_4.py workingtree_4.py-20070208044105-5fgpc5j3ljlh5q6c-1
------------------------------------------------------------
revno: 3034.4.2
revision-id:aaron.bentley at utoronto.ca-20071128000531-mq2lgadv5c9471nf
parent: aaron.bentley at utoronto.ca-20071127132444-zq5nq2cs13ljnm6z
committer: Aaron Bentley <aaron.bentley at utoronto.ca>
branch nick: transform-case
timestamp: Tue 2007-11-27 19:05:31 -0500
message:
Get conflict handling and case-insensitive tree creation under test
modified:
bzrlib/tests/test_transform.py test_transaction.py-20060105172520-b3ffb3946550e6c4
------------------------------------------------------------
revno: 3034.4.1
revision-id:aaron.bentley at utoronto.ca-20071127132444-zq5nq2cs13ljnm6z
parent: pqm at pqm.ubuntu.com-20071127023739-a1ajr28wi7so2up6
committer: Aaron Bentley <aaron.bentley at utoronto.ca>
branch nick: transform-case
timestamp: Tue 2007-11-27 08:24:44 -0500
message:
Start handling case-insensitivity
modified:
bzrlib/tests/test_transform.py test_transaction.py-20060105172520-b3ffb3946550e6c4
bzrlib/transform.py transform.py-20060105172343-dd99e54394d91687
bzrlib/workingtree.py workingtree.py-20050511021032-29b6ec0a681e02e3
bzrlib/workingtree_4.py workingtree_4.py-20070208044105-5fgpc5j3ljlh5q6c-1
=== modified file 'bzrlib/tests/__init__.py'
--- a/bzrlib/tests/__init__.py 2007-11-23 00:19:02 +0000
+++ b/bzrlib/tests/__init__.py 2007-11-28 20:59:24 +0000
@@ -2046,6 +2046,7 @@
This doesn't add anything to a branch.
+ :type shape: list or tuple.
:param line_endings: Either 'binary' or 'native'
in binary mode, exact contents are written in native mode, the
line endings match the default platform endings.
@@ -2053,6 +2054,8 @@
If the transport is readonly or None, "." is opened automatically.
:return: None
"""
+ assert type(shape) in (list, tuple), ("Parameter 'shape' should be "
+ "a list or a tuple. Got %s instead" % type(shape))
# It's OK to just create them using forward slashes on windows.
if transport is None or transport.is_readonly():
transport = get_transport(".")
=== modified file 'bzrlib/tests/test_transform.py'
--- a/bzrlib/tests/test_transform.py 2007-11-28 02:06:15 +0000
+++ b/bzrlib/tests/test_transform.py 2007-11-28 23:08:40 +0000
@@ -44,7 +44,7 @@
from bzrlib.transform import (TreeTransform, ROOT_PARENT, FinalPaths,
resolve_conflicts, cook_conflicts,
find_interesting, build_tree, get_backup_name,
- change_entry, _FileMover)
+ change_entry, _FileMover, resolve_checkout)
class TestTreeTransform(tests.TestCaseWithTransport):
@@ -237,6 +237,105 @@
transform3.adjust_path('tip', root_id, tip_id)
transform3.apply()
+ def test_conflict_on_case_insensitive(self):
+ tree = self.make_branch_and_tree('tree')
+ # Don't try this at home, kids!
+ # Force the tree to report that it is case sensitive, for conflict
+ # resolution tests
+ tree.case_sensitive = True
+ transform = TreeTransform(tree)
+ self.addCleanup(transform.finalize)
+ transform.new_file('file', transform.root, 'content')
+ transform.new_file('FiLe', transform.root, 'content')
+ result = transform.find_conflicts()
+ self.assertEqual([], result)
+ # Force the tree to report that it is case insensitive, for conflict
+ # generation tests
+ tree.case_sensitive = False
+ result = transform.find_conflicts()
+ self.assertEqual([('duplicate', 'new-1', 'new-2', 'file')], result)
+
+ def test_conflict_on_case_insensitive_existing(self):
+ tree = self.make_branch_and_tree('tree')
+ self.build_tree(['tree/FiLe'])
+ # Don't try this at home, kids!
+ # Force the tree to report that it is case sensitive, for conflict
+ # resolution tests
+ tree.case_sensitive = True
+ transform = TreeTransform(tree)
+ self.addCleanup(transform.finalize)
+ transform.new_file('file', transform.root, 'content')
+ result = transform.find_conflicts()
+ self.assertEqual([], result)
+ # Force the tree to report that it is case insensitive, for conflict
+ # generation tests
+ tree.case_sensitive = False
+ result = transform.find_conflicts()
+ self.assertEqual([('duplicate', 'new-1', 'new-2', 'file')], result)
+
+ def test_resolve_case_insensitive_conflict(self):
+ tree = self.make_branch_and_tree('tree')
+ # Don't try this at home, kids!
+ # Force the tree to report that it is case insensitive, for conflict
+ # resolution tests
+ tree.case_sensitive = False
+ transform = TreeTransform(tree)
+ self.addCleanup(transform.finalize)
+ transform.new_file('file', transform.root, 'content')
+ transform.new_file('FiLe', transform.root, 'content')
+ resolve_conflicts(transform)
+ transform.apply()
+ self.failUnlessExists('tree/file')
+ self.failUnlessExists('tree/FiLe.moved')
+
+ def test_resolve_checkout_case_conflict(self):
+ tree = self.make_branch_and_tree('tree')
+ # Don't try this at home, kids!
+ # Force the tree to report that it is case insensitive, for conflict
+ # resolution tests
+ tree.case_sensitive = False
+ transform = TreeTransform(tree)
+ self.addCleanup(transform.finalize)
+ transform.new_file('file', transform.root, 'content')
+ transform.new_file('FiLe', transform.root, 'content')
+ resolve_conflicts(transform,
+ pass_func=lambda t, c: resolve_checkout(t, c, []))
+ transform.apply()
+ self.failUnlessExists('tree/file')
+ self.failUnlessExists('tree/FiLe.moved')
+
+ def test_apply_case_conflict(self):
+ """Ensure that a transform with case conflicts can always be applied"""
+ tree = self.make_branch_and_tree('tree')
+ transform = TreeTransform(tree)
+ self.addCleanup(transform.finalize)
+ transform.new_file('file', transform.root, 'content')
+ transform.new_file('FiLe', transform.root, 'content')
+ dir = transform.new_directory('dir', transform.root)
+ transform.new_file('dirfile', dir, 'content')
+ transform.new_file('dirFiLe', dir, 'content')
+ resolve_conflicts(transform)
+ transform.apply()
+ self.failUnlessExists('tree/file')
+ if not os.path.exists('tree/FiLe.moved'):
+ self.failUnlessExists('tree/FiLe')
+ self.failUnlessExists('tree/dir/dirfile')
+ if not os.path.exists('tree/dir/dirFiLe.moved'):
+ self.failUnlessExists('tree/dir/dirFiLe')
+
+ def test_case_insensitive_limbo(self):
+ tree = self.make_branch_and_tree('tree')
+ # Don't try this at home, kids!
+ # Force the tree to report that it is case insensitive
+ tree.case_sensitive = False
+ transform = TreeTransform(tree)
+ self.addCleanup(transform.finalize)
+ dir = transform.new_directory('dir', transform.root)
+ first = transform.new_file('file', dir, 'content')
+ second = transform.new_file('FiLe', dir, 'content')
+ self.assertContainsRe(transform._limbo_name(first), 'new-1/file')
+ self.assertNotContainsRe(transform._limbo_name(second), 'new-1/FiLe')
+
def test_add_del(self):
start, root = self.get_transform()
start.new_directory('a', root, 'a')
=== modified file 'bzrlib/tests/workingtree_implementations/test_workingtree.py'
--- a/bzrlib/tests/workingtree_implementations/test_workingtree.py 2007-11-13 17:48:49 +0000
+++ b/bzrlib/tests/workingtree_implementations/test_workingtree.py 2007-11-28 21:04:08 +0000
@@ -30,11 +30,10 @@
from bzrlib.tests.workingtree_implementations import TestCaseWithWorkingTree
from bzrlib.trace import mutter
from bzrlib.workingtree import (TreeEntry, TreeDirectory, TreeFile, TreeLink,
- WorkingTree)
+ WorkingTree, WorkingTree2)
from bzrlib.conflicts import ConflictList, TextConflict, ContentsConflict
-
class TestWorkingTree(TestCaseWithWorkingTree):
def test_list_files(self):
@@ -848,3 +847,19 @@
tree.commit('foo')
tree.remove('file')
self.assertRaises(errors.NoSuchId, tree.get_file_sha1, 'file-id')
+
+ def test_case_sensitive(self):
+ """If filesystem is case-sensitive, tree should report this.
+
+ We check case-sensitivity by creating a file with a lowercase name,
+ then testing whether it exists with an uppercase name.
+ """
+ self.build_tree(['filename'])
+ if os.path.exists('FILENAME'):
+ case_sensitive = False
+ else:
+ case_sensitive = True
+ tree = self.make_branch_and_tree('test')
+ if tree.__class__ == WorkingTree2:
+ raise TestSkipped('WorkingTree2 is not supported')
+ self.assertEqual(case_sensitive, tree.case_sensitive)
=== modified file 'bzrlib/transform.py'
--- a/bzrlib/transform.py 2007-11-26 19:54:09 +0000
+++ b/bzrlib/transform.py 2007-11-27 13:24:44 +0000
@@ -798,6 +798,8 @@
return conflicts
for children in by_parent.itervalues():
name_ids = [(self.final_name(t), t) for t in children]
+ if not self._tree.case_sensitive:
+ name_ids = [(n.lower(), t) for n, t in name_ids]
name_ids.sort()
last_name = None
last_trans_id = None
@@ -924,9 +926,20 @@
# the direct path can only be used if no other file has
# already taken this pathname, i.e. if the name is unused, or
# if it is already associated with this trans_id.
- elif (self._limbo_children_names[parent].get(filename)
- in (trans_id, None)):
- use_direct_path = True
+ elif self._tree.case_sensitive:
+ if (self._limbo_children_names[parent].get(filename)
+ in (trans_id, None)):
+ use_direct_path = True
+ else:
+ for l_filename, l_trans_id in\
+ self._limbo_children_names[parent].iteritems():
+ if l_trans_id == trans_id:
+ continue
+ if l_filename.lower() == filename.lower():
+ break
+ else:
+ use_direct_path = True
+
if use_direct_path:
limbo_name = pathjoin(self._limbo_files[parent], filename)
self._limbo_children[parent].add(trans_id)
@@ -1787,16 +1800,15 @@
conflict[1], conflict[2], ))
elif c_type == 'duplicate':
# files that were renamed take precedence
- new_name = tt.final_name(conflict[1])+'.moved'
final_parent = tt.final_parent(conflict[1])
if tt.path_changed(conflict[1]):
- tt.adjust_path(new_name, final_parent, conflict[2])
- new_conflicts.add((c_type, 'Moved existing file to',
- conflict[2], conflict[1]))
+ existing_file, new_file = conflict[2], conflict[1]
else:
- tt.adjust_path(new_name, final_parent, conflict[1])
- new_conflicts.add((c_type, 'Moved existing file to',
- conflict[1], conflict[2]))
+ existing_file, new_file = conflict[1], conflict[2]
+ new_name = tt.final_name(existing_file)+'.moved'
+ tt.adjust_path(new_name, final_parent, existing_file)
+ new_conflicts.add((c_type, 'Moved existing file to',
+ existing_file, new_file))
elif c_type == 'parent loop':
# break the loop by undoing one of the ops that caused the loop
cur = conflict[1]
=== modified file 'bzrlib/workingtree.py'
--- a/bzrlib/workingtree.py 2007-11-23 20:19:57 +0000
+++ b/bzrlib/workingtree.py 2007-11-28 02:25:27 +0000
@@ -270,6 +270,16 @@
# the Format factory and creation methods that are
# permitted to do this.
self._set_inventory(_inventory, dirty=False)
+ self._detect_case_handling()
+
+ def _detect_case_handling(self):
+ wt_trans = self.bzrdir.get_workingtree_transport(None)
+ try:
+ wt_trans.stat("FoRMaT")
+ except errors.NoSuchFile:
+ self.case_sensitive = True
+ else:
+ self.case_sensitive = False
branch = property(
fget=lambda self: self._branch,
=== modified file 'bzrlib/workingtree_4.py'
--- a/bzrlib/workingtree_4.py 2007-11-27 20:35:02 +0000
+++ b/bzrlib/workingtree_4.py 2007-11-28 23:08:40 +0000
@@ -151,6 +151,7 @@
self._dirstate = None
self._inventory = None
#-------------
+ self._detect_case_handling()
@needs_tree_write_lock
def _add(self, files, ids, kinds):
More information about the bazaar-commits
mailing list