Rev 2728: Specific file support. in http://people.ubuntu.com/~robertc/baz2.0/commit-candidates

Robert Collins robertc at robertcollins.net
Thu Aug 23 07:32:26 BST 2007


At http://people.ubuntu.com/~robertc/baz2.0/commit-candidates

------------------------------------------------------------
revno: 2728
revision-id: robertc at robertcollins.net-20070823063224-1048jolgyv7qyrt1
parent: robertc at robertcollins.net-20070823024154-dcw2d74cxtcmsg4b
committer: Robert Collins <robertc at robertcollins.net>
branch nick: commit-candidates
timestamp: Thu 2007-08-23 16:32:24 +1000
message:
  Specific file support.
modified:
  bzrlib/mutabletree.py          mutabletree.py-20060906023413-4wlkalbdpsxi2r4y-2
  bzrlib/tests/workingtree_implementations/test_iter_commit_candidates.py test_iter_commit_can-20070822055451-ygz697i0te0mcg8p-1
=== modified file 'bzrlib/mutabletree.py'
--- a/bzrlib/mutabletree.py	2007-08-23 02:41:54 +0000
+++ b/bzrlib/mutabletree.py	2007-08-23 06:32:24 +0000
@@ -211,7 +211,7 @@
             revprops=revprops, *args, **kwargs)
         return committed_id
 
-    def iter_commit_candidates(self, parent_trees):
+    def iter_commit_candidates(self, parent_trees, specific_files=None):
         """Iterate over the items which may need to be committed.
 
         This iterator will examine each path currently versioned in the tree.
@@ -265,6 +265,9 @@
             is a ghost and unavailable. Note that the absence of a parent will
             cause every path to be considered to have its last-modified
             changed.
+        :param specific_files: An optional limit for the paths to include during
+            commit. If provided it should be a list of relative paths within the
+            tree.
         :return: An iterator over paths in the tree which are not excluded from
             being recorded during commit. Each item that the iterator yields
             contains a three-tuple. The first element is a tuple:
@@ -294,7 +297,6 @@
         # XXX: When time permits, consolidate the new features of this generic
         #      implementation as part of Tree.iter_changes ? they are somewhat
         #      different. RBC 20070821
-        specific_files = None
         parent_ids = self.get_parent_ids()
         trees = [parent_trees[rev_id] for rev_id in parent_ids]
         if not trees:
@@ -324,10 +326,6 @@
                 (basis_name, name), (basis_kind, kind), (basis_exec, executable)
                 ) in input_iterator:
                 parent_vector = []
-                # strip out unchanged entries which have the same last_modified.
-                if parent_count < 2:
-                    if not content_change:
-                        continue
                 # special case first parent as its always present with the curent
                 # structure; and is the common case
                 if basis_parent is not None:
@@ -337,14 +335,17 @@
                          entry.text_sha1, entry.revision))
                 else:
                     parent_vector.append((None, None, None, None, None, None))
-                if parent_count > 1:
+                if include_unchanged:
                     # check last_modified flags across parents here.
-                    pass
+                    skip = False
+                    #
+                    if skip:
+                        continue
                 # TODO: get the file hash IFF it is available. This requires
                 #       layering changes to allow querying for this - typically
                 #       we need a stat fingerprint, and thats not available here.
                 yield ((path, file_id, parent, name, kind, executable, None),
-                    parent_vector, content_change)
+                    tuple(parent_vector), content_change)
         finally:
             for tree in trees:
                 tree.unlock()

=== modified file 'bzrlib/tests/workingtree_implementations/test_iter_commit_candidates.py'
--- a/bzrlib/tests/workingtree_implementations/test_iter_commit_candidates.py	2007-08-23 02:41:54 +0000
+++ b/bzrlib/tests/workingtree_implementations/test_iter_commit_candidates.py	2007-08-23 06:32:24 +0000
@@ -58,7 +58,7 @@
         if len(result) != 0:
             self.assertEqual([
                 ((u'', tree_root, None, u'', 'directory', False, None),
-                 [(None, None, None, None, None, None)],
+                 ((None, None, None, None, None, None),),
                  True)], result)
 
     def test_iter_commit_candidates_empty(self):
@@ -101,11 +101,11 @@
 #             [(tree_root, 'dir', 'directory', False, None, rev_id1)],
 #             False),
             ((u'file', 'fileid', tree_root, 'file', 'file', False, None),
-             [(tree_root, 'file', 'file', False,
-              'fdd68fdc095181052aaa4f74fdb2db4a2ce6eb9f', rev_id1)],
+             ((tree_root, 'file', 'file', False,
+              'fdd68fdc095181052aaa4f74fdb2db4a2ce6eb9f', rev_id1),),
              True),
             ((u'link', 'linkid', tree_root, 'link', 'symlink', False, None),
-             [(tree_root, 'link', 'symlink', False, None, rev_id1)],
+             ((tree_root, 'link', 'symlink', False, None, rev_id1),),
              True)]
         try:
             self.assertEqual(expected_result,
@@ -113,8 +113,111 @@
         finally:
             tree.unlock()
 
+    def test_single_parent_renames_followed(self):
+        tree = self.make_branch_and_tree('tree')
+        # get a tree with one symlink/file/dir committed, so we can 
+        # delta them
+        paths = ['dir', 'file']
+        ids = ['dirid', 'fileid']
+        self.build_tree(['tree/dir/', 'tree/file'])
+        if has_symlinks():
+            paths.append('link')
+            ids.append('linkid')
+            os.symlink('target', 'tree/link')
+        tree.add(paths, ids)
+        rev_id1 = tree.commit('commit')
+        # now change paths
+        tree.rename_one('file', 'file_to')
+        tree.rename_one('dir', 'dir_to')
+        if has_symlinks():
+            tree.rename_one('link', 'link_to')
+        tree.lock_write()
+        tree_root = tree.path2id('')
+        expected_results = list([
+            ((u'dir_to', 'dirid', tree_root, 'dir_to', 'directory', False, None),
+             ((tree_root, 'dir', 'directory', False, None, rev_id1),),
+             False),
+            ((u'file_to', 'fileid', tree_root, 'file_to', 'file', False, None),
+             ((tree_root, 'file', 'file', False,
+              'fdd68fdc095181052aaa4f74fdb2db4a2ce6eb9f', rev_id1),),
+             False)])
+        if has_symlinks:
+            expected_results.append(
+                ((u'link_to', 'linkid', tree_root, 'link_to', 'symlink', False, None),
+                 ((tree_root, 'link', 'symlink', False, None, rev_id1),),
+                 False))
+        try:
+            old_specific_files = ['dir', 'file']
+            new_specific_files = ['dir_to', 'file_to']
+            if has_symlinks:
+                old_specific_files.append('link')
+                new_specific_files.append('link_to')
+
+            self._check_specific_permutations(expected_results, tree,
+                new_specific_files, old_specific_files)
+        finally:
+            tree.unlock()
+
+    def _check_specific_permutations(self, expected_results, tree,
+        new_specific_files, old_specific_files):
+        """Test that we get expected results where specific_files might break."""
+        # all renamed, no specific paths.
+        self.assertEqual(expected_results,
+            list(tree.iter_commit_candidates(
+                {tree.last_revision():tree.basis_tree()},
+                )))
+        # NB: we use sets below because following renames etc does
+        # not have our constraint of alphabetical ordering.
+        # all by old name
+        self.assertEqual(set(expected_results),
+            set(tree.iter_commit_candidates(
+                {tree.last_revision():tree.basis_tree()},
+                specific_files=old_specific_files,
+                )))
+        # all by new name
+        self.assertEqual(set(expected_results),
+            set(tree.iter_commit_candidates(
+                {tree.last_revision():tree.basis_tree()},
+                specific_files=new_specific_files,
+                )))
+        # dir only by old name
+        self.assertEqual(set(expected_results[0:1]),
+            set(tree.iter_commit_candidates(
+                {tree.last_revision():tree.basis_tree()},
+                specific_files=old_specific_files[0:1],
+                )))
+        # dir only by new name
+        self.assertEqual(set(expected_results[0:1]),
+            set(tree.iter_commit_candidates(
+                {tree.last_revision():tree.basis_tree()},
+                specific_files=new_specific_files[0:1],
+                )))
+        # file only by old name
+        self.assertEqual(set(expected_results[1:2]),
+            set(tree.iter_commit_candidates(
+                {tree.last_revision():tree.basis_tree()},
+                specific_files=old_specific_files[1:2],
+                )))
+        # file only by new name
+        self.assertEqual(set(expected_results[1:2]),
+            set(tree.iter_commit_candidates(
+                {tree.last_revision():tree.basis_tree()},
+                specific_files=new_specific_files[1:2],
+                )))
+        if has_symlinks:
+            # link only by old name
+            self.assertEqual(set(expected_results[2:3]),
+                set(tree.iter_commit_candidates(
+                    {tree.last_revision():tree.basis_tree()},
+                    specific_files=old_specific_files[2:3],
+                    )))
+            # link only by new name
+            self.assertEqual(set(expected_results[2:3]),
+                set(tree.iter_commit_candidates(
+                    {tree.last_revision():tree.basis_tree()},
+                    specific_files=new_specific_files[2:3],
+                    )))
 # tests to write:
 # strict
-# specific files
 # on directory callback
 # deleted items



More information about the bazaar-commits mailing list