Rev 2496: Add unversioned path reporting to TreeDelta. in http://bazaar.launchpad.net/~bzr/bzr/dirstate

Robert Collins robertc at robertcollins.net
Fri Mar 2 03:49:03 GMT 2007


At http://bazaar.launchpad.net/~bzr/bzr/dirstate

------------------------------------------------------------
revno: 2496
revision-id: robertc at robertcollins.net-20070302034756-kkqil9dftr9t14sv
parent: john at arbash-meinel.com-20070302031949-02axv3fix1qfkuqq
committer: Robert Collins <robertc at robertcollins.net>
branch nick: dirstate.dogfood
timestamp: Fri 2007-03-02 14:47:56 +1100
message:
  Add unversioned path reporting to TreeDelta.
modified:
  bzrlib/delta.py                delta.py-20050729221636-54cf14ef94783d0a
  bzrlib/tests/intertree_implementations/test_compare.py test_compare.py-20060724101752-09ysswo1a92uqyoz-2
  bzrlib/tests/test_delta.py     test_delta.py-20070110134455-sqpd1y7mbjndelxf-1
  bzrlib/tests/test_tree.py      test_tree.py-20060724065232-khgrr0vvmt6ih0mi-1
  bzrlib/tree.py                 tree.py-20050309040759-9d5f2496be663e77
=== modified file 'bzrlib/delta.py'
--- a/bzrlib/delta.py	2007-02-26 01:06:36 +0000
+++ b/bzrlib/delta.py	2007-03-02 03:47:56 +0000
@@ -38,6 +38,8 @@
         (path, id, kind, text_modified, meta_modified)
     unchanged
         (path, id, kind)
+    unversioned
+        (path, kind)
 
     Each id is listed only once.
 
@@ -59,6 +61,7 @@
         self.kind_changed = []
         self.modified = []
         self.unchanged = []
+        self.unversioned = []
 
     def __eq__(self, other):
         if not isinstance(other, TreeDelta):
@@ -68,16 +71,18 @@
                and self.renamed == other.renamed \
                and self.modified == other.modified \
                and self.unchanged == other.unchanged \
-               and self.kind_changed == other.kind_changed
+               and self.kind_changed == other.kind_changed \
+               and self.unversioned == other.unversioned
 
     def __ne__(self, other):
         return not (self == other)
 
     def __repr__(self):
         return "TreeDelta(added=%r, removed=%r, renamed=%r," \
-            " kind_changed=%r, modified=%r, unchanged=%r)" % (self.added,
+            " kind_changed=%r, modified=%r, unchanged=%r," \
+            " unversioned=%r)" % (self.added,
             self.removed, self.renamed, self.kind_changed, self.modified,
-            self.unchanged)
+            self.unchanged, self.unversioned)
 
     def has_changed(self):
         return bool(self.modified
@@ -201,13 +206,19 @@
 
 
 def _compare_trees(old_tree, new_tree, want_unchanged, specific_files,
-                   include_root, extra_trees=None):
+                   include_root, extra_trees=None,
+                   want_unversioned=False):
+    """Worker function that implements Tree.changes_from."""
     delta = TreeDelta()
     # mutter('start compare_trees')
 
     for (file_id, path, content_change, versioned, parent_id, name, kind,
          executable) in new_tree._iter_changes(old_tree, want_unchanged,
-            specific_files, extra_trees=extra_trees):
+            specific_files, extra_trees=extra_trees,
+            want_unversioned=want_unversioned):
+        if versioned == (False, False):
+            delta.unversioned.append((path, kind[1]))
+            continue
         if not include_root and (None, None) == parent_id:
             continue
         fully_present = tuple((versioned[x] and kind[x] is not None) for

=== modified file 'bzrlib/tests/intertree_implementations/test_compare.py'
--- a/bzrlib/tests/intertree_implementations/test_compare.py	2007-03-02 02:58:30 +0000
+++ b/bzrlib/tests/intertree_implementations/test_compare.py	2007-03-02 03:47:56 +0000
@@ -38,7 +38,6 @@
 #       (it should not follow the link)
 # TODO: test specific_files when the target tree has a file and the source a
 #       dir with children, same id and same path. 
-# TODO: test specific_files with a new unversioned path.
 
 class TestCompare(TestCaseWithTwoTrees):
 
@@ -286,6 +285,43 @@
             specific_files=['d'],
             require_versioned=True)
 
+    def test_default_ignores_unversioned_files(self):
+        tree1 = self.make_branch_and_tree('tree1')
+        tree2 = self.make_to_branch_and_tree('tree2')
+        self.build_tree(['tree1/a', 'tree1/c',
+                         'tree2/a', 'tree2/b', 'tree2/c'])
+        tree1.add(['a', 'c'], ['a-id', 'c-id'])
+        tree2.add(['a', 'c'], ['a-id', 'c-id'])
+
+        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
+        d = self.intertree_class(tree1, tree2).compare(want_unversioned=True)
+        self.assertEqual([], d.added)
+        self.assertEqual([(u'a', 'a-id', 'file', True, False),
+            (u'c', 'c-id', 'file', True, False)], d.modified)
+        self.assertEqual([], d.removed)
+        self.assertEqual([], d.renamed)
+        self.assertEqual([], d.unchanged)
+        self.assertEqual([], d.unversioned)
+
+    def test_unversioned_paths_in_tree(self):
+        tree1 = self.make_branch_and_tree('tree1')
+        tree2 = self.make_to_branch_and_tree('tree2')
+        self.build_tree(['tree2/file', 'tree2/dir/'])
+        # try:
+        os.symlink('target', 'tree2/link')
+        links_supported = True
+        # except ???:
+        #   links_supported = False
+        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
+        d = self.intertree_class(tree1, tree2).compare(want_unversioned=True)
+        self.assertEqual([], d.added)
+        self.assertEqual([], d.modified)
+        self.assertEqual([], d.removed)
+        self.assertEqual([], d.renamed)
+        self.assertEqual([], d.unchanged)
+        self.assertEqual([(u'dir', 'directory'), (u'file', 'file'),
+            (u'link', 'symlink')], d.unversioned)
+
 
 class TestIterChanges(TestCaseWithTwoTrees):
     """Test the comparison iterator"""

=== modified file 'bzrlib/tests/test_delta.py'
--- a/bzrlib/tests/test_delta.py	2007-02-08 22:42:45 +0000
+++ b/bzrlib/tests/test_delta.py	2007-03-02 03:47:56 +0000
@@ -197,7 +197,7 @@
         self.assertEqual(other_delta, delta)
         self.assertEqualDiff("TreeDelta(added=[], removed=[], renamed=[],"
             " kind_changed=[(u'filename', 'file-id', 'file', 'directory')],"
-            " modified=[], unchanged=[])", repr(delta))
+            " modified=[], unchanged=[], unversioned=[])", repr(delta))
         self.assertEqual('K  filename (file => directory) file-id\n',
                          self.show_string(delta, show_ids=True,
                          short_status=True))

=== modified file 'bzrlib/tests/test_tree.py'
--- a/bzrlib/tests/test_tree.py	2006-10-16 01:50:48 +0000
+++ b/bzrlib/tests/test_tree.py	2007-03-02 03:47:56 +0000
@@ -62,11 +62,12 @@
     calls = []
 
     def compare(self, want_unchanged=False, specific_files=None,
-        extra_trees=None, require_versioned=False, include_root=False):
+        extra_trees=None, require_versioned=False, include_root=False,
+        want_unversioned=False):
         self.calls.append(
             ('compare', self.source, self.target, want_unchanged,
              specific_files, extra_trees, require_versioned, 
-             include_root)
+             include_root, want_unversioned)
             )
     
     @classmethod
@@ -98,16 +99,17 @@
                 extra_trees='extra',
                 require_versioned='require',
                 include_root=True,
+                want_unversioned=True,
                 )
         finally:
             InterTree._optimisers = old_optimisers
         self.assertEqual(
             [
-             ('compare', tree2, tree, False, None, None, False, False),
-             ('compare', tree2, tree, 'unchanged', 'specific', 'extra',
-              'require', True),
-             ('compare', tree2, tree, 'unchanged', 'specific', 'extra',
-              'require', True),
+             ('compare', tree2, tree, False, None, None, False, False, False),
+             ('compare', tree2, tree, 'unchanged', 'specific', 'extra',
+              'require', True, False),
+             ('compare', tree2, tree, 'unchanged', 'specific', 'extra',
+              'require', True, True),
             ], RecordingOptimiser.calls)
 
     def test_changes_from_with_root(self):

=== modified file 'bzrlib/tree.py'
--- a/bzrlib/tree.py	2007-03-02 01:06:12 +0000
+++ b/bzrlib/tree.py	2007-03-02 03:47:56 +0000
@@ -58,7 +58,8 @@
     """
     
     def changes_from(self, other, want_unchanged=False, specific_files=None,
-        extra_trees=None, require_versioned=False, include_root=False):
+        extra_trees=None, require_versioned=False, include_root=False,
+        want_unversioned=False):
         """Return a TreeDelta of the changes from other to this tree.
 
         :param other: A tree to compare with.
@@ -73,6 +74,7 @@
         :param require_versioned: An optional boolean (defaults to False). When
             supplied and True all the 'specific_files' must be versioned, or
             a PathsNotVersionedError will be thrown.
+        :param want_unversioned: Scan for unversioned paths.
 
         The comparison will be performed by an InterTree object looked up on 
         self and other.
@@ -85,7 +87,8 @@
             specific_files=specific_files,
             extra_trees=extra_trees,
             require_versioned=require_versioned,
-            include_root=include_root
+            include_root=include_root,
+            want_unversioned=want_unversioned,
             )
 
     def _iter_changes(self, from_tree, include_unchanged=False,
@@ -93,7 +96,7 @@
                      require_versioned=True, want_unversioned=False):
         intertree = InterTree.get(from_tree, self)
         return intertree._iter_changes(include_unchanged, specific_files, pb,
-            extra_trees, require_versioned)
+            extra_trees, require_versioned, want_unversioned=want_unversioned)
     
     def conflicts(self):
         """Get a list of the conflicts in the tree.
@@ -525,7 +528,8 @@
 
     @needs_read_lock
     def compare(self, want_unchanged=False, specific_files=None,
-        extra_trees=None, require_versioned=False, include_root=False):
+        extra_trees=None, require_versioned=False, include_root=False,
+        want_unversioned=False):
         """Return the changes from source to target.
 
         :return: A TreeDelta.
@@ -540,6 +544,7 @@
         :param require_versioned: An optional boolean (defaults to False). When
             supplied and True all the 'specific_files' must be versioned, or
             a PathsNotVersionedError will be thrown.
+        :param want_unversioned: Scan for unversioned paths.
         """
         # NB: show_status depends on being able to pass in non-versioned files
         # and report them as unknown
@@ -552,9 +557,12 @@
         if specific_files and not specific_file_ids:
             # All files are unversioned, so just return an empty delta
             # _compare_trees would think we want a complete delta
-            return delta.TreeDelta()
+            result = delta.TreeDelta()
+            result.unversioned = list(specific_files)
+            return result
         return delta._compare_trees(self.source, self.target, want_unchanged,
-            specific_files, include_root, extra_trees=extra_trees)
+            specific_files, include_root, extra_trees=extra_trees,
+            want_unversioned=want_unversioned)
 
     def _iter_changes(self, include_unchanged=False,
                       specific_files=None, pb=None, extra_trees=[],



More information about the bazaar-commits mailing list