Rev 5846: (jameinel) Support RevTree.iter_changes(WT) when WT has a TreeReference (bug in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Tue May 10 09:30:44 UTC 2011


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

------------------------------------------------------------
revno: 5846 [merge]
revision-id: pqm at pqm.ubuntu.com-20110510093033-8u89g79mvfozt4wl
parent: pqm at pqm.ubuntu.com-20110510083940-55j6je6dlqrnhmqf
parent: john at arbash-meinel.com-20110509140952-4ek264yk53pz23q2
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Tue 2011-05-10 09:30:33 +0000
message:
  (jameinel) Support RevTree.iter_changes(WT) when WT has a TreeReference (bug
   #764677) (John A Meinel)
modified:
  bzrlib/tests/per_tree/test_inv.py test_inv.py-20070312023226-0cdvk5uwhutis9vg-1
  bzrlib/tests/per_tree/test_path_content_summary.py test_path_content_su-20070904100855-3vrwedz6akn34kl5-1
  bzrlib/tests/per_workingtree/test_add_reference.py test_add_reference.p-20061211024451-yo9i1691dgbv1eyn-1
  bzrlib/tests/per_workingtree/test_inv.py test_inv.py-20070311221604-ighlq8tbn5xq0kuo-1
  bzrlib/tests/per_workingtree/test_nested_specifics.py test_nested_specific-20070306004443-qut978c488jr11sg-1
  bzrlib/tests/test_workingtree.py testworkingtree.py-20051004024258-b88d0fe8f101d468
  bzrlib/workingtree.py          workingtree.py-20050511021032-29b6ec0a681e02e3
  doc/en/release-notes/bzr-2.4.txt bzr2.4.txt-20110114053217-k7ym9jfz243fddjm-1
=== modified file 'bzrlib/tests/per_tree/test_inv.py'
--- a/bzrlib/tests/per_tree/test_inv.py	2011-04-20 14:58:20 +0000
+++ b/bzrlib/tests/per_tree/test_inv.py	2011-05-06 14:53:40 +0000
@@ -34,41 +34,6 @@
     return tree.iter_entries_by_dir([file_id]).next()[1]
 
 
-class TestPreviousHeads(per_tree.TestCaseWithTree):
-
-    def setUp(self):
-        # we want several inventories, that respectively
-        # give use the following scenarios:
-        # A) fileid not in any inventory (A),
-        # B) fileid present in one inventory (B) and (A,B)
-        # C) fileid present in two inventories, and they
-        #   are not mutual descendents (B, C)
-        # D) fileid present in two inventories and one is
-        #   a descendent of the other. (B, D)
-        super(TestPreviousHeads, self).setUp()
-        self.wt = self.make_branch_and_tree('.')
-        self.branch = self.wt.branch
-        self.build_tree(['file'])
-        self.wt.commit('new branch', allow_pointless=True, rev_id='A')
-        self.inv_A = self.branch.repository.get_inventory('A')
-        self.wt.add(['file'], ['fileid'])
-        self.wt.commit('add file', rev_id='B')
-        self.inv_B = self.branch.repository.get_inventory('B')
-        uncommit(self.branch, tree=self.wt)
-        self.assertEqual(self.branch.revision_history(), ['A'])
-        self.wt.commit('another add of file', rev_id='C')
-        self.inv_C = self.branch.repository.get_inventory('C')
-        self.wt.add_parent_tree_id('B')
-        self.wt.commit('merge in B', rev_id='D')
-        self.inv_D = self.branch.repository.get_inventory('D')
-        self.tree = self.workingtree_to_test_tree(self.wt)
-        self.tree.lock_read()
-        self.addCleanup(self.tree.unlock)
-        self.file_active = get_entry(self.tree, 'fileid')
-
-    # TODO: test two inventories with the same file revision
-
-
 class TestInventoryWithSymlinks(per_tree.TestCaseWithTree):
 
     _test_needs_features = [tests.SymlinkFeature]

=== modified file 'bzrlib/tests/per_tree/test_path_content_summary.py'
--- a/bzrlib/tests/per_tree/test_path_content_summary.py	2010-02-17 17:11:16 +0000
+++ b/bzrlib/tests/per_tree/test_path_content_summary.py	2011-04-18 18:52:19 +0000
@@ -144,10 +144,10 @@
 
     def test_tree_content_summary(self):
         tree = self.make_branch_and_tree('tree')
-        subtree = self.make_branch_and_tree('tree/path')
-        tree.add(['path'])
         if not tree.branch.repository._format.supports_tree_reference:
             raise tests.TestNotApplicable("Tree references not supported.")
+        subtree = self.make_branch_and_tree('tree/path')
+        tree.add(['path'])
         summary = self._convert_tree(tree).path_content_summary('path')
         self.assertEqual(4, len(summary))
         self.assertEqual('tree-reference', summary[0])

=== modified file 'bzrlib/tests/per_workingtree/test_add_reference.py'
--- a/bzrlib/tests/per_workingtree/test_add_reference.py	2011-05-04 20:44:14 +0000
+++ b/bzrlib/tests/per_workingtree/test_add_reference.py	2011-05-06 14:53:40 +0000
@@ -34,7 +34,8 @@
 
     def _references_unsupported(self, tree):
         if not tree.supports_tree_reference():
-            raise tests.TestSkipped('Tree format does not support references')
+            raise tests.TestNotApplicable(
+                'Tree format does not support references')
         else:
             self.fail('%r does not support references but should'
                 % (tree, ))

=== modified file 'bzrlib/tests/per_workingtree/test_inv.py'
--- a/bzrlib/tests/per_workingtree/test_inv.py	2011-04-21 20:32:16 +0000
+++ b/bzrlib/tests/per_workingtree/test_inv.py	2011-05-09 14:09:52 +0000
@@ -19,7 +19,7 @@
 
 import os
 
-from bzrlib import inventory
+from bzrlib import inventory, tests
 from bzrlib.tests.per_workingtree import TestCaseWithWorkingTree
 
 
@@ -151,3 +151,23 @@
         wt.apply_inventory_delta([('', None, root_id, None),
             (None, '', 'root-id',
              inventory.InventoryDirectory('root-id', '', None))])
+
+
+class TestTreeReference(TestCaseWithWorkingTree):
+
+    def test_tree_reference_matches_inv(self):
+        base = self.make_branch_and_tree('base')
+        if not base.supports_tree_reference():
+            raise tests.TestNotApplicable("wt doesn't support nested trees")
+        # We add it as a directory, but it becomes a tree-reference
+        base.add(['subdir'], ['subdir-id'], ['directory'])
+        subdir = self.make_branch_and_tree('base/subdir')
+        self.addCleanup(base.lock_read().unlock)
+        # Note: we aren't strict about ie.kind being 'directory' here, what we
+        # are strict about is that wt.inventory should match
+        # wt.current_dirstate()'s idea about what files are where.
+        ie = base.inventory['subdir-id']
+        self.assertEqual('directory', ie.kind)
+        path, ie = base.iter_entries_by_dir(['subdir-id']).next()
+        self.assertEqual('subdir', path)
+        self.assertEqual('tree-reference', ie.kind)

=== modified file 'bzrlib/tests/per_workingtree/test_nested_specifics.py'
--- a/bzrlib/tests/per_workingtree/test_nested_specifics.py	2011-04-21 01:19:32 +0000
+++ b/bzrlib/tests/per_workingtree/test_nested_specifics.py	2011-05-09 14:09:52 +0000
@@ -16,6 +16,9 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
 
+from bzrlib import (
+    inventory,
+    )
 from bzrlib.tests import TestNotApplicable
 from bzrlib.transform import TreeTransform
 from bzrlib.tests.per_workingtree import TestCaseWithWorkingTree
@@ -65,6 +68,17 @@
 
     def test_comparison_data_does_not_autodetect_subtree(self):
         tree = self.prepare_with_subtree()
-        entry = tree.iter_entries_by_dir(['subtree-id']).next()[1]
+        ie = inventory.InventoryDirectory('subtree-id', 'subtree',
+                                          tree.path2id(''))
         self.assertEqual('directory',
-                         tree._comparison_data(entry, 'subtree')[0])
+                         tree._comparison_data(ie, 'subtree')[0])
+
+    def test_inventory_does_not_autodetect_subtree(self):
+        tree = self.prepare_with_subtree()
+        ie = tree.inventory['subtree-id']
+        self.assertEqual('directory', ie.kind)
+
+    def test_iter_entries_by_dir_autodetects_subtree(self):
+        tree = self.prepare_with_subtree()
+        path, ie = tree.iter_entries_by_dir(['subtree-id']).next()
+        self.assertEqual('tree-reference', ie.kind)

=== modified file 'bzrlib/tests/test_workingtree.py'
--- a/bzrlib/tests/test_workingtree.py	2011-05-05 01:58:00 +0000
+++ b/bzrlib/tests/test_workingtree.py	2011-05-09 13:51:43 +0000
@@ -236,6 +236,47 @@
                 workingtree.WorkingTreeFormat.get_formats))
 
 
+class TestWorkingTreeIterEntriesByDir_wSubtrees(TestCaseWithTransport):
+
+    def make_simple_tree(self):
+        tree = self.make_branch_and_tree('tree', format='development-subtree')
+        self.build_tree(['tree/a/', 'tree/a/b/', 'tree/a/b/c'])
+        tree.set_root_id('root-id')
+        tree.add(['a', 'a/b', 'a/b/c'], ['a-id', 'b-id', 'c-id'])
+        tree.commit('initial')
+        return tree
+
+    def test_just_directory(self):
+        tree = self.make_simple_tree()
+        self.assertEqual([('directory', 'root-id'),
+                          ('directory', 'a-id'),
+                          ('directory', 'b-id'),
+                          ('file', 'c-id')],
+                         [(ie.kind, ie.file_id)
+                          for path, ie in tree.iter_entries_by_dir()])
+        subtree = self.make_branch_and_tree('tree/a/b')
+        self.assertEqual([('tree-reference', 'b-id')],
+                         [(ie.kind, ie.file_id)
+                          for path, ie in tree.iter_entries_by_dir(['b-id'])])
+
+    def test_direct_subtree(self):
+        tree = self.make_simple_tree()
+        subtree = self.make_branch_and_tree('tree/a/b')
+        self.assertEqual([('directory', 'root-id'),
+                          ('directory', 'a-id'),
+                          ('tree-reference', 'b-id')],
+                         [(ie.kind, ie.file_id)
+                          for path, ie in tree.iter_entries_by_dir()])
+
+    def test_indirect_subtree(self):
+        tree = self.make_simple_tree()
+        subtree = self.make_branch_and_tree('tree/a')
+        self.assertEqual([('directory', 'root-id'),
+                          ('tree-reference', 'a-id')],
+                         [(ie.kind, ie.file_id)
+                          for path, ie in tree.iter_entries_by_dir()])
+
+
 class TestWorkingTreeFormatRegistry(TestCase):
 
     def setUp(self):

=== modified file 'bzrlib/workingtree.py'
--- a/bzrlib/workingtree.py	2011-05-09 11:59:04 +0000
+++ b/bzrlib/workingtree.py	2011-05-10 09:30:33 +0000
@@ -572,6 +572,34 @@
     def id2abspath(self, file_id):
         return self.abspath(self.id2path(file_id))
 
+    def _check_for_tree_references(self, iterator):
+        """See if directories have become tree-references."""
+        blocked_parent_ids = set()
+        for path, ie in iterator:
+            if ie.parent_id in blocked_parent_ids:
+                # This entry was pruned because one of its parents became a
+                # TreeReference. If this is a directory, mark it as blocked.
+                if ie.kind == 'directory':
+                    blocked_parent_ids.add(ie.file_id)
+                continue
+            if ie.kind == 'directory' and self._directory_is_tree_reference(path):
+                # This InventoryDirectory needs to be a TreeReference
+                ie = inventory.TreeReference(ie.file_id, ie.name, ie.parent_id)
+                blocked_parent_ids.add(ie.file_id)
+            yield path, ie
+
+    def iter_entries_by_dir(self, specific_file_ids=None, yield_parents=False):
+        """See Tree.iter_entries_by_dir()"""
+        # The only trick here is that if we supports_tree_reference then we
+        # need to detect if a directory becomes a tree-reference.
+        iterator = super(WorkingTree, self).iter_entries_by_dir(
+                specific_file_ids=specific_file_ids,
+                yield_parents=yield_parents)
+        if not self.supports_tree_reference():
+            return iterator
+        else:
+            return self._check_for_tree_references(iterator)
+
     def get_file_size(self, file_id):
         """See Tree.get_file_size"""
         # XXX: this returns the on-disk size; it should probably return the

=== modified file 'doc/en/release-notes/bzr-2.4.txt'
--- a/doc/en/release-notes/bzr-2.4.txt	2011-05-10 07:46:15 +0000
+++ b/doc/en/release-notes/bzr-2.4.txt	2011-05-10 09:30:33 +0000
@@ -52,6 +52,11 @@
 * Correct parent is now set when using 'switch -b' with bound branches.
   (A. S. Budden, #513709)
 
+* ``WT.inventory`` and ``WT.iter_entries_by_dir()`` was not correctly
+  reporting subdirectories that were tree references (in formats that
+  supported them). (John Arbash Meinel, #764677)
+
+
 Documentation
 *************
 
@@ -371,7 +376,6 @@
   of CHK data, down to just 150MB.) This has noticeable affects for things
   like building checkouts, etc.  (John Arbash Meinel, #737234)
 
-
 Bug Fixes
 *********
 




More information about the bazaar-commits mailing list