Rev 4679: Fix bug #322807, teach cicp_canonical_relpath how to handle in http://bazaar.launchpad.net/~jameinel/bzr/2.0.1-322807-branch-at-root
John Arbash Meinel
john at arbash-meinel.com
Tue Oct 6 18:36:16 BST 2009
At http://bazaar.launchpad.net/~jameinel/bzr/2.0.1-322807-branch-at-root
------------------------------------------------------------
revno: 4679
revision-id: john at arbash-meinel.com-20091006173603-geynkwufk5orrap7
parent: john at arbash-meinel.com-20091006173334-rghfzhhwi5t0cwiy
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: 2.0.1-322807-branch-at-root
timestamp: Tue 2009-10-06 12:36:03 -0500
message:
Fix bug #322807, teach cicp_canonical_relpath how to handle
1) relpaths when the base dir is the root of the filesystem
2) when base dir doesn't exist (makes it easier to do testing)
-------------- next part --------------
=== modified file 'NEWS'
--- a/NEWS 2009-10-06 17:33:34 +0000
+++ b/NEWS 2009-10-06 17:36:03 +0000
@@ -26,6 +26,12 @@
with some combinations of remote and local formats. This was causing
"unknown object type identifier 60" errors. (Andrew Bennetts, #427736)
+* Handle things like ``bzr add foo`` and ``bzr rm foo`` when the tree is
+ at the root of a drive. ``osutils._cicp_canonical_relpath`` always
+ assumed that ``abspath()`` returned a path that did not have a trailing
+ ``/``, but that is not true when working at the root of the filesystem.
+ (John Arbash Meinel, Jason Spashett, #322807)
+
* Improve the time for ``bzr log DIR`` for 2a format repositories.
We had been using the same code path as for <2a formats, which required
iterating over all objects in all revisions.
=== modified file 'bzrlib/osutils.py'
--- a/bzrlib/osutils.py 2009-07-23 16:01:17 +0000
+++ b/bzrlib/osutils.py 2009-10-06 17:36:03 +0000
@@ -1083,6 +1083,12 @@
bit_iter = iter(rel.split('/'))
for bit in bit_iter:
lbit = bit.lower()
+ try:
+ next_entries = _listdir(current)
+ except OSError: # enoent
+ # current doesn't match, so just append the non-existing bits
+ current = pathjoin(current, bit, *list(bit_iter))
+ break
for look in _listdir(current):
if lbit == look.lower():
current = pathjoin(current, look)
@@ -1093,7 +1099,7 @@
# the target of a move, for example).
current = pathjoin(current, bit, *list(bit_iter))
break
- return current[len(abs_base)+1:]
+ return current[len(abs_base):].lstrip('/')
# XXX - TODO - we need better detection/integration of case-insensitive
# file-systems; Linux often sees FAT32 devices (or NFS-mounted OSX
=== modified file 'bzrlib/tests/test_osutils.py'
--- a/bzrlib/tests/test_osutils.py 2009-07-23 16:01:17 +0000
+++ b/bzrlib/tests/test_osutils.py 2009-10-06 17:36:03 +0000
@@ -460,6 +460,42 @@
self.failUnlessEqual('work/MixedCaseParent/nochild', actual)
+class Test_CICPCanonicalRelpath(tests.TestCaseWithTransport):
+
+ def assertRelpath(self, expected, base, path):
+ actual = osutils._cicp_canonical_relpath(base, path)
+ self.assertEqual(expected, actual)
+
+ def test_simple(self):
+ self.build_tree(['MixedCaseName'])
+ base = osutils.realpath(self.get_transport('.').local_abspath('.'))
+ self.assertRelpath('MixedCaseName', base, 'mixedcAsename')
+
+ def test_subdir_missing_tail(self):
+ self.build_tree(['MixedCaseParent/', 'MixedCaseParent/a_child'])
+ base = osutils.realpath(self.get_transport('.').local_abspath('.'))
+ self.assertRelpath('MixedCaseParent/a_child', base,
+ 'MixedCaseParent/a_child')
+ self.assertRelpath('MixedCaseParent/a_child', base,
+ 'MixedCaseParent/A_Child')
+ self.assertRelpath('MixedCaseParent/not_child', base,
+ 'MixedCaseParent/not_child')
+
+ def test_at_root(self):
+ # This path probably does not exist
+ # We can't test this on Windows, because it has a 'MIN_ABS_PATHLENGTH'
+ # check...
+ # self.assertRelpath('foo', '/', '/foo')
+
+ # see bug #322807
+ # The specific issue is that when at the root of a drive, 'abspath'
+ # returns "C:/" or just "/". However, the code assumes that abspath
+ # always returns something like "C:/foo" or "/foo" (no trailing slash).
+ self.assertRelpath('foo', 'C:/', 'C:/foo')
+ self.assertRelpath('foo', 'X:/', 'X:/foo')
+ self.assertRelpath('foo', 'X:/', 'X://foo')
+
+
class TestPumpFile(tests.TestCase):
"""Test pumpfile method."""
More information about the bazaar-commits
mailing list