Rev 2441: Handle the case when a directory has been removed, and isn't the last entry. in http://bazaar.launchpad.net/%7Ebzr/bzr/dirstate
John Arbash Meinel
john at arbash-meinel.com
Wed Feb 28 23:37:44 GMT 2007
At http://bazaar.launchpad.net/%7Ebzr/bzr/dirstate
------------------------------------------------------------
revno: 2441
revision-id: john at arbash-meinel.com-20070228233639-kt8judz9w3x27ve4
parent: john at arbash-meinel.com-20070228224054-11e83q8puulllfuh
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: dirstate
timestamp: Wed 2007-02-28 17:36:39 -0600
message:
Handle the case when a directory has been removed, and isn't the last entry.
modified:
bzrlib/tests/intertree_implementations/test_compare.py test_compare.py-20060724101752-09ysswo1a92uqyoz-2
bzrlib/workingtree_4.py workingtree_4.py-20070208044105-5fgpc5j3ljlh5q6c-1
-------------- next part --------------
=== modified file 'bzrlib/tests/intertree_implementations/test_compare.py'
--- a/bzrlib/tests/intertree_implementations/test_compare.py 2007-02-28 22:40:54 +0000
+++ b/bzrlib/tests/intertree_implementations/test_compare.py 2007-02-28 23:36:39 +0000
@@ -788,3 +788,30 @@
self.content_changed(tree2, 'c-id'),
])
self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
+
+ def test_trees_with_missing_dir(self):
+ tree1 = self.make_branch_and_tree('tree1')
+ tree2 = self.make_to_branch_and_tree('tree2')
+ self.build_tree(['tree1/a', 'tree1/b/', 'tree1/b/c',
+ 'tree1/b/d/', 'tree1/b/d/e', 'tree1/f/', 'tree1/f/g',
+ 'tree2/a', 'tree2/f/', 'tree2/f/g'])
+ tree1.add(['a', 'b', 'b/c', 'b/d/', 'b/d/e', 'f', 'f/g'],
+ ['a-id', 'b-id', 'c-id', 'd-id', 'e-id', 'f-id', 'g-id'])
+ tree2.add(['a', 'f', 'f/g'], ['a-id', 'f-id', 'g-id'])
+
+ tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
+ tree1.lock_read()
+ self.addCleanup(tree1.unlock)
+ tree2.lock_read()
+ self.addCleanup(tree2.unlock)
+ # We should notice that 'b' and all its children are missing
+ expected = sorted([
+ self.content_changed(tree2, 'a-id'),
+ self.content_changed(tree2, 'g-id'),
+ self.deleted(tree1, 'b-id'),
+ self.deleted(tree1, 'c-id'),
+ self.deleted(tree1, 'd-id'),
+ self.deleted(tree1, 'e-id'),
+ ])
+
+ self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
=== modified file 'bzrlib/workingtree_4.py'
--- a/bzrlib/workingtree_4.py 2007-02-28 22:40:54 +0000
+++ b/bzrlib/workingtree_4.py 2007-02-28 23:36:39 +0000
@@ -1771,26 +1771,56 @@
else:
current_block = None
while (current_dir_info is not None or
- current_block is not None):
- if current_dir_info and current_block and current_dir_info[0][0] != current_block[0]:
- if current_block[0] < current_dir_info[0][0]:
- # extra dir on disk: pass for now? should del from info ?
- import pdb;pdb.set_trace()
- print 'unversioned dir'
- else:
- # directory data refers to paths not covered by the dirblock.
+ current_block is not None):
+ if (current_dir_info and current_block
+ and current_dir_info[0][0] != current_block[0]):
+ if current_dir_info[0][0] < current_block[0] :
+ # import pdb; pdb.set_trace()
+ # print 'unversioned dir'
+ # filesystem data refers to paths not covered by the dirblock.
# this has two possibilities:
# A) it is versioned but empty, so there is no block for it
# B) it is not versioned.
# in either case it was processed by the containing directories walk:
# if it is root/foo, when we walked root we emitted it,
# or if we ere given root/foo to walk specifically, we
- # emitted it when checking the walk-root entries
+ # emitted it when checking the walk-root entries
# advance the iterator and loop - we dont need to emit it.
try:
current_dir_info = dir_iterator.next()
except StopIteration:
current_dir_info = None
+ else:
+ # We have a dirblock entry for this location, but there
+ # is no filesystem path for this. This is most likely
+ # because a directory was removed from the disk.
+ # We don't have to report the missing directory,
+ # because that should have already been handled, but we
+ # need to handle all of the files that are contained
+ # within.
+ for current_entry in current_block[1]:
+ # entry referring to file not present on disk.
+ # advance the entry only, after processing.
+ for result in _process_entry(current_entry, None):
+ # this check should probably be outside the loop: one
+ # 'iterate two trees' api, and then _iter_changes filters
+ # unchanged pairs. - RBC 20070226
+ if (include_unchanged
+ or result[2] # content change
+ or result[3][0] != result[3][1] # versioned status
+ or result[4][0] != result[4][1] # parent id
+ or result[5][0] != result[5][1] # name
+ or result[6][0] != result[6][1] # kind
+ or result[7][0] != result[7][1] # executable
+ ):
+ yield result
+ block_index +=1
+ if (block_index < len(state._dirblocks) and
+ osutils.is_inside(current_root,
+ state._dirblocks[block_index][0])):
+ current_block = state._dirblocks[block_index]
+ else:
+ current_block = None
continue
entry_index = 0
if current_block and entry_index < len(current_block[1]):
More information about the bazaar-commits
mailing list