Rev 2404: Fix _iter_changes to properly handle versioned (but empty) directories in http://bzr.arbash-meinel.com/branches/bzr/0.16-dev/iter_changes_unknowns_104257

John Arbash Meinel john at arbash-meinel.com
Wed Apr 11 18:50:40 BST 2007


At http://bzr.arbash-meinel.com/branches/bzr/0.16-dev/iter_changes_unknowns_104257

------------------------------------------------------------
revno: 2404
revision-id: john at arbash-meinel.com-20070411175022-gdznyinz160vx05e
parent: john at arbash-meinel.com-20070411170244-qael9owa2l2rcneh
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: iter_changes_unknowns_104257
timestamp: Wed 2007-04-11 12:50:22 -0500
message:
  Fix _iter_changes to properly handle versioned (but empty) directories
  so that it yields files from there as unknown.
  Also check to make sure we don't recurse into subdirectories of these dirs.
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-04-11 17:02:44 +0000
+++ b/bzrlib/tests/intertree_implementations/test_compare.py	2007-04-11 17:50:22 +0000
@@ -1220,18 +1220,24 @@
 
         # Create an empty directory 'a', followed by a directory with content
         # 'b'.
-        self.build_tree(['tree1/a/', 'tree1/b/', 'tree1/b/file'])
-        self.build_tree(['tree2/a/', 'tree2/a/file', 'tree2/b/', 'tree2/b/file'])
+        self.build_tree(['tree1/a/', 'tree1/b/'])
+        self.build_tree_contents([('tree1/b/file', 'contents\n')])
+        self.build_tree(['tree2/a/', 'tree2/b/'])
+        self.build_tree_contents([('tree2/b/file', 'contents\n')])
+
         tree1.add(['a', 'b', 'b/file'], ['a-id', 'b-id', 'b-file-id'])
         tree2.add(['a', 'b', 'b/file'], ['a-id', 'b-id', 'b-file-id'])
 
+        # Now create some unknowns in tree2
+        # We should find both a/file and a/dir as unknown, but we shouldn't
+        # recurse into a/dir to find that a/dir/subfile is also unknown.
+        self.build_tree(['tree2/a/file', 'tree2/a/dir/', 'tree2/a/dir/subfile'])
+
         tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
 
         expected = sorted([
             self.unversioned(tree2, u'a/file'),
-            # This isn't strictly important, but it is easier to let it happen,
-            # than to work around it.
-            self.content_changed(tree2, 'b-file-id'),
+            self.unversioned(tree2, u'a/dir'),
             ])
         self.assertEqual(expected,
                          self.do_iter_changes(tree1, tree2,

=== modified file 'bzrlib/workingtree_4.py'
--- a/bzrlib/workingtree_4.py	2007-03-31 03:19:39 +0000
+++ b/bzrlib/workingtree_4.py	2007-04-11 17:50:22 +0000
@@ -2114,11 +2114,40 @@
                         # 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
-                        # advance the iterator and loop - we dont need to emit it.
+
+                        # if (A) then we need to recurse into it to check for
+                        # new unknown files or directories.
+                        # if (B) then we should ignore it, because we don't
+                        # recurse into unknown directories.
+                        if want_unversioned:
+                            path_index = 0
+                            while path_index < len(current_dir_info[1]):
+                                    current_path_info = current_dir_info[1][path_index]
+                                    if current_path_info[2] == 'directory':
+                                        if self.target._directory_is_tree_reference(
+                                            current_path_info[0].decode('utf8')):
+                                            current_path_info = current_path_info[:2] + \
+                                                ('tree-reference',) + current_path_info[3:]
+                                    new_executable = bool(
+                                        stat.S_ISREG(current_path_info[3].st_mode)
+                                        and stat.S_IEXEC & current_path_info[3].st_mode)
+                                    yield (None,
+                                        (None, utf8_decode_or_none(current_path_info[0])),
+                                        True,
+                                        (False, False),
+                                        (None, None),
+                                        (None, utf8_decode_or_none(current_path_info[1])),
+                                        (None, current_path_info[2]),
+                                        (None, new_executable))
+                                    # dont descend into this unversioned path if it is
+                                    # a dir
+                                    if current_path_info[2] in ('directory',
+                                                                'tree-reference'):
+                                        del current_dir_info[1][path_index]
+                                        path_index -= 1
+                                    path_index += 1
+
+                        # This dir info has been handled, go to the next
                         try:
                             current_dir_info = dir_iterator.next()
                         except StopIteration:
@@ -2287,15 +2316,14 @@
                                 new_executable = bool(
                                     stat.S_ISREG(current_path_info[3].st_mode)
                                     and stat.S_IEXEC & current_path_info[3].st_mode)
-                                if want_unversioned:
-                                    yield (None,
-                                        (None, utf8_decode_or_none(current_path_info[0])),
-                                        True,
-                                        (False, False),
-                                        (None, None),
-                                        (None, utf8_decode_or_none(current_path_info[1])),
-                                        (None, current_path_info[2]),
-                                        (None, new_executable))
+                                yield (None,
+                                    (None, utf8_decode_or_none(current_path_info[0])),
+                                    True,
+                                    (False, False),
+                                    (None, None),
+                                    (None, utf8_decode_or_none(current_path_info[1])),
+                                    (None, current_path_info[2]),
+                                    (None, new_executable))
                             # dont descend into this unversioned path if it is
                             # a dir
                             if current_path_info[2] in ('directory'):



More information about the bazaar-commits mailing list