Rev 4557: (robertc) Add interface enforcement for the behaviour of iter_changes in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Wed Jul 22 02:36:45 BST 2009


At file:///home/pqm/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 4557 [merge]
revision-id: pqm at pqm.ubuntu.com-20090722013642-hejy07x9ub06tioj
parent: pqm at pqm.ubuntu.com-20090720224242-jo0rxbt5f0jecj4d
parent: robertc at robertcollins.net-20090722003444-vcci9yub1ypc5n6k
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Wed 2009-07-22 02:36:42 +0100
message:
  (robertc) Add interface enforcement for the behaviour of iter_changes
  	with missing subtrees with explicit paths - the whole subtree
  	is returned. (Robert Collins)
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/tests/per_intertree/test_compare.py test_compare.py-20060724101752-09ysswo1a92uqyoz-2
  bzrlib/transform.py            transform.py-20060105172343-dd99e54394d91687
  bzrlib/tree.py                 tree.py-20050309040759-9d5f2496be663e77
  bzrlib/workingtree_4.py        workingtree_4.py-20070208044105-5fgpc5j3ljlh5q6c-1
=== modified file 'NEWS'
--- a/NEWS	2009-07-20 21:21:10 +0000
+++ b/NEWS	2009-07-22 01:36:42 +0000
@@ -38,6 +38,9 @@
 * ``bzr mv`` no longer takes out branch locks, which allows it to work
   when the branch is readonly. (Robert Collins, #216541)
 
+* ``bzr revert .`` no longer generates an InconsistentDelta error when
+  there are missing subtrees. (Robert Collins, #367632)
+
 * Fixed a NameError that occurs when merging or pulling from a URL that
   causes a redirection loop when bzr tries to read a URL as a bundle.
   (Andrew Bennetts, #400847)

=== modified file 'bzrlib/tests/per_intertree/test_compare.py'
--- a/bzrlib/tests/per_intertree/test_compare.py	2009-07-14 10:12:30 +0000
+++ b/bzrlib/tests/per_intertree/test_compare.py	2009-07-17 06:04:35 +0000
@@ -757,6 +757,29 @@
             (None, root_id), (None, 'file'), (None, None), (None, False))]
         self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
 
+    def test_only_in_target_missing_subtree_specific_bug_367632(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/a-dir/', 'tree2/a-dir/a-file'])
+        tree2.add(['a-dir', 'a-dir/a-file'], ['dir-id', 'file-id'])
+        os.unlink('tree2/a-dir/a-file')
+        os.rmdir('tree2/a-dir')
+        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
+        self.not_applicable_if_missing_in('a-dir', tree2)
+        root_id = tree1.path2id('')
+        expected = [
+            ('dir-id', (None, 'a-dir'), False, (False, True),
+            (None, root_id), (None, 'a-dir'), (None, None), (None, False)),
+            ('file-id', (None, 'a-dir/a-file'), False, (False, True),
+            (None, 'dir-id'), (None, 'a-file'), (None, None), (None, False))
+            ]
+        # bug 367632 showed that specifying the root broke some code paths,
+        # so we check this contract with and without it.
+        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
+        self.assertEqual(expected,
+            self.do_iter_changes(tree1, tree2, specific_files=['']))
+
     def test_unchanged_with_renames_and_modifications(self):
         """want_unchanged should generate a list of unchanged entries."""
         tree1 = self.make_branch_and_tree('1')
@@ -765,7 +788,6 @@
         tree2 = self.get_tree_no_parents_abc_content_5(tree2)
         tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
         root_id = tree1.path2id('')
-
         self.assertEqual(sorted([self.unchanged(tree1, root_id),
             self.unchanged(tree1, 'b-id'),
             ('a-id', ('a', 'd'), True, (True, True),

=== modified file 'bzrlib/transform.py'
--- a/bzrlib/transform.py	2009-07-20 06:06:22 +0000
+++ b/bzrlib/transform.py	2009-07-22 00:34:44 +0000
@@ -1718,14 +1718,20 @@
     def __iter__(self):
         return iter(self.all_file_ids())
 
-    def has_id(self, file_id):
+    def _has_id(self, file_id, fallback_check):
         if file_id in self._transform._r_new_id:
             return True
         elif file_id in set([self._transform.tree_file_id(trans_id) for
             trans_id in self._transform._removed_id]):
             return False
         else:
-            return self._transform._tree.has_id(file_id)
+            return fallback_check(file_id)
+
+    def has_id(self, file_id):
+        return self._has_id(file_id, self._transform._tree.has_id)
+
+    def has_or_had_id(self, file_id):
+        return self._has_id(file_id, self._transform._tree.has_or_had_id)
 
     def _path2trans_id(self, path):
         # We must not use None here, because that is a valid value to store.

=== modified file 'bzrlib/tree.py'
--- a/bzrlib/tree.py	2009-07-10 08:33:11 +0000
+++ b/bzrlib/tree.py	2009-07-17 06:04:35 +0000
@@ -133,8 +133,6 @@
         return self.has_id(file_id)
 
     def has_or_had_id(self, file_id):
-        if file_id == self.inventory.root.file_id:
-            return True
         return self.inventory.has_id(file_id)
 
     def is_ignored(self, filename):
@@ -825,7 +823,7 @@
         new_pending = set()
         for file_id in pending:
             for tree in trees:
-                if not tree.has_id(file_id):
+                if not tree.has_or_had_id(file_id):
                     continue
                 for child_id in tree.iter_children(file_id):
                     if child_id not in interesting_ids:

=== modified file 'bzrlib/workingtree_4.py'
--- a/bzrlib/workingtree_4.py	2009-07-15 04:33:14 +0000
+++ b/bzrlib/workingtree_4.py	2009-07-17 06:04:35 +0000
@@ -435,6 +435,11 @@
         return osutils.lexists(pathjoin(
                     self.basedir, row[0].decode('utf8'), row[1].decode('utf8')))
 
+    def has_or_had_id(self, file_id):
+        state = self.current_dirstate()
+        row, parents = self._get_entry(file_id=file_id)
+        return row is not None
+
     @needs_read_lock
     def id2path(self, file_id):
         "Convert a file-id to a path."




More information about the bazaar-commits mailing list