Rev 3620: Improve tests for the behaviour of Tree.iter_changes for missing paths that are only present in one tree, and fix found bugs. (Robert Collins) in http://people.ubuntu.com/~robertc/baz2.0/intertree.missing

Robert Collins robertc at robertcollins.net
Wed Aug 13 04:21:24 BST 2008


At http://people.ubuntu.com/~robertc/baz2.0/intertree.missing

------------------------------------------------------------
revno: 3620
revision-id: robertc at robertcollins.net-20080813032119-09pl9q0t9gxng5t6
parent: pqm at pqm.ubuntu.com-20080811083307-tbibm26paa3r4hg8
committer: Robert Collins <robertc at robertcollins.net>
branch nick: intertree.missing
timestamp: Wed 2008-08-13 13:21:19 +1000
message:
  Improve tests for the behaviour of Tree.iter_changes for missing paths that are only present in one tree, and fix found bugs. (Robert Collins)
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/tests/intertree_implementations/test_compare.py test_compare.py-20060724101752-09ysswo1a92uqyoz-2
  bzrlib/tree.py                 tree.py-20050309040759-9d5f2496be663e77
  bzrlib/workingtree_4.py        workingtree_4.py-20070208044105-5fgpc5j3ljlh5q6c-1
=== modified file 'NEWS'
--- a/NEWS	2008-08-11 03:39:25 +0000
+++ b/NEWS	2008-08-13 03:21:19 +0000
@@ -32,10 +32,18 @@
       choice is arbitrary but stable, so merges in different directions
       will get the same results.  (John Arbash Meinel, #232188)
 
+    * ``WorkingTree4`` trees will now correctly report missing-and-new
+      paths in the output of ``iter_changes``. (Robert Collins)
+
   API CHANGES:
 
     * Exporters now take 4 parameters. (Robert Collins)
 
+    * ``Tree.iter_changes`` will now return False for the content change
+      field when a file is missing in the basis tree and not present in
+      the target tree. Previously it returned True unconditionally.
+      (Robert Collins)
+
   INTERNALS:
 
 

=== modified file 'bzrlib/tests/intertree_implementations/test_compare.py'
--- a/bzrlib/tests/intertree_implementations/test_compare.py	2008-03-07 14:25:46 +0000
+++ b/bzrlib/tests/intertree_implementations/test_compare.py	2008-08-13 03:21:19 +0000
@@ -695,6 +695,38 @@
             ])
         self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
 
+    def test_only_in_source_and_missing(self):
+        tree1 = self.make_branch_and_tree('tree1')
+        tree2 = self.make_to_branch_and_tree('tree2')
+        tree2.set_root_id(tree1.get_root_id())
+        self.build_tree(['tree1/file'])
+        tree1.add(['file'], ['file-id'])
+        os.unlink('tree1/file')
+        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
+        root_id = tree1.path2id('')
+        if not tree1.path2id('file'):
+            # The locked test trees conversion could not preserve the missing
+            # file status. This is normal (e.g. InterDirstateTree falls back
+            # to InterTree if the basis is not a DirstateRevisionTree, and
+            # revision trees cannot have missing files. 
+            return
+        expected = [('file-id', ('file', None), False, (True, False),
+            (root_id, None), ('file', None), (None, None), (False, None))]
+        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
+
+    def test_only_in_target_and_missing(self):
+        tree1 = self.make_branch_and_tree('tree1')
+        tree2 = self.make_to_branch_and_tree('tree2')
+        tree2.set_root_id(tree1.get_root_id())
+        self.build_tree(['tree2/file'])
+        tree2.add(['file'], ['file-id'])
+        os.unlink('tree2/file')
+        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
+        root_id = tree1.path2id('')
+        expected = [('file-id', (None, 'file'), False, (False, True),
+            (None, root_id), (None, 'file'), (None, None), (None, False))]
+        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
+
     def test_unchanged_with_renames_and_modifications(self):
         """want_unchanged should generate a list of unchanged entries."""
         tree1 = self.make_branch_and_tree('1')

=== modified file 'bzrlib/tree.py'
--- a/bzrlib/tree.py	2008-08-01 18:19:44 +0000
+++ b/bzrlib/tree.py	2008-08-13 03:21:19 +0000
@@ -953,7 +953,7 @@
                 self.source._comparison_data(from_entry, path)
             kind = (from_kind, None)
             executable = (from_executable, None)
-            changed_content = True
+            changed_content = from_kind is not None
             # the parent's path is necessarily known at this point.
             yield(file_id, (path, to_path), changed_content, versioned, parent,
                   name, kind, executable)

=== modified file 'bzrlib/workingtree_4.py'
--- a/bzrlib/workingtree_4.py	2008-07-29 13:03:44 +0000
+++ b/bzrlib/workingtree_4.py	2008-08-13 03:21:19 +0000
@@ -1980,7 +1980,6 @@
         # record is handled, but isn't interesting to process (unchanged)
         uninteresting = object()
 
-
         old_dirname_to_file_id = {}
         new_dirname_to_file_id = {}
         # TODO: jam 20070516 - Avoid the _get_entry lookup overhead by
@@ -2169,14 +2168,15 @@
                     return uninteresting
             elif source_minikind in 'a' and target_minikind in 'fdlt':
                 # looks like a new file
+                path = pathjoin(entry[0][0], entry[0][1])
+                # parent id is the entry for the path in the target tree
+                # TODO: these are the same for an entire directory: cache em.
+                parent_id = state._get_entry(target_index,
+                                             path_utf8=entry[0][0])[0][2]
+                if parent_id == entry[0][2]:
+                    parent_id = None
                 if path_info is not None:
-                    path = pathjoin(entry[0][0], entry[0][1])
-                    # parent id is the entry for the path in the target tree
-                    # TODO: these are the same for an entire directory: cache em.
-                    parent_id = state._get_entry(target_index,
-                                                 path_utf8=entry[0][0])[0][2]
-                    if parent_id == entry[0][2]:
-                        parent_id = None
+                    # Present on disk:
                     if use_filesystem_for_exec:
                         # We need S_ISREG here, because we aren't sure if this
                         # is a file or not.
@@ -2194,9 +2194,15 @@
                            (None, path_info[2]),
                            (None, target_exec))
                 else:
-                    # but its not on disk: we deliberately treat this as just
-                    # never-present. (Why ?! - RBC 20070224)
-                    pass
+                    # Its a missing file, report it as such.
+                    return (entry[0][2],
+                           (None, utf8_decode(path)[0]),
+                           False,
+                           (False, True),
+                           (None, parent_id),
+                           (None, utf8_decode(entry[0][1])[0]),
+                           (None, None),
+                           (None, False))
             elif source_minikind in 'fdlt' and target_minikind in 'a':
                 # unversioned, possibly, or possibly not deleted: we dont care.
                 # if its still on disk, *and* theres no other entry at this
@@ -2521,7 +2527,6 @@
                     except StopIteration:
                         current_dir_info = None
 
-
     @staticmethod
     def is_compatible(source, target):
         # the target must be a dirstate working tree




More information about the bazaar-commits mailing list