[MERGE] revert DIRECTORY works recursively

John Arbash Meinel john at arbash-meinel.com
Sat Jul 1 17:20:53 BST 2006


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Aaron Bentley wrote:
> Hi all,
> 
> This patch makes revert DIRECTORY work recursively.  Previously, it had
> only reverted the directory itself, which differs from other bzr
> commands and isn't terribly useful.
> 
> The recursion takes a maximally-inclusive approach.  That is, if a
> directory is reverted, all its children in the working tree and all its
> children in the basis tree are reverted.  The same applies to any
> directories among the children, and so on.
> 
> Aaron


I'm really glad to see this. I think it needs a NEWS entry, since it is
a user-visible change.


- ------------------------------------------------------------------------

# Bazaar revision bundle v0.8
#
# message:
#   Handle revert DIRECTORY
# committer: Aaron Bentley <abentley at panoramicfeedback.com>
# date: Fri 2006-06-30 19:14:30.872232914 -0400

=== modified file bzrlib/tests/blackbox/test_revert.py
- --- bzrlib/tests/blackbox/test_revert.py
+++ bzrlib/tests/blackbox/test_revert.py
@@ -18,6 +18,7 @@

 import os

+from bzrlib.workingtree import WorkingTree
 from bzrlib.tests.blackbox import ExternalBase
 from bzrlib.trace import mutter

@@ -43,6 +44,19 @@
         # check status
         self.assertEquals('modified:\n  dir/file\n',
self.capture('status'))

+    def _prepare_rename_mod_tree(self):
+        self.build_tree(['a/', 'a/b', 'a/c', 'a/d/', 'a/d/e', 'f/', 'f/g',
+                         'f/h', 'f/i'])
+        self.run_bzr('init')
+        self.run_bzr('add')
+        self.run_bzr('commit', '-m', '1')
+        wt = WorkingTree.open('.')
+        wt.rename_one('a/b', 'f/b')
+        wt.rename_one('a/d', 'f/d')
+        wt.rename_one('f/g', 'a/g')
+        wt.rename_one('f/h', 'h')
+        wt.rename_one('f', 'j')
+
     def helper(self, param=''):
         self._prepare_tree()
         # change dir
@@ -72,3 +86,16 @@
         self.assertEqual('', self.capture('status'))
         self.runbzr('revert')
         self.assertEqual('', self.capture('status'))
+
+    def test_revert_dirname(self):
+        """Test that revert DIRECTORY does what's expected"""
+        self._prepare_rename_mod_tree()
+        self.run_bzr('revert', 'a')
+        self.failUnlessExists('a/b')
+        self.failUnlessExists('a/d')
+        self.failIfExists('a/g')
+        self.failUnlessExists('j')
+        self.failUnlessExists('h')
+        self.run_bzr('revert', 'f')
+        self.failIfExists('j')
+        self.failIfExists('h')


Looks pretty good. It doesn't look like you are testing to make sure
that 'a/d/e' gets moved around correctly. Since that is a child of 'd'.


=== modified file bzrlib/transform.py
- --- bzrlib/transform.py
+++ bzrlib/transform.py
@@ -987,19 +987,36 @@

 def find_interesting(working_tree, target_tree, filenames):
     """Find the ids corresponding to specified filenames."""
+    trees = (working_tree, target_tree)
     if not filenames:
         interesting_ids = None
     else:
         interesting_ids = set()
         for tree_path in filenames:
             not_found = True
- -            for tree in (working_tree, target_tree):
+            for tree in trees:
                 file_id = tree.inventory.path2id(tree_path)
                 if file_id is not None:
                     interesting_ids.add(file_id)
                     not_found = False
             if not_found:
                 raise NotVersionedError(path=tree_path)
+
+        pending = interesting_ids
+        # now handle children of interesting ids
+        # we loop so that we handle all children of each id in both trees
+        while len(pending) > 0:
+            new_pending = set()
+            for file_id in pending:
+                for tree in trees:
+                    if file_id not in tree:
+                        continue
+                    entry = tree.inventory[file_id]
+                    for child in getattr(entry, 'children',
{}).itervalues():
+                        if child.file_id not in interesting_ids:
+                            new_pending.add(child.file_id)
+            interesting_ids.update(new_pending)
+            pending = new_pending
     return interesting_ids


Looks good. So +1 if you add a NEWS entry.

John
=:->

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (Cygwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFEpqDlJdeBCYSNAAMRAntiAJ40KWSdOrGBhqa1CYjYgP3sKdUxewCguwjz
CtVMwSsp9QRUTKh8NaRlj9c=
=Mynf
-----END PGP SIGNATURE-----




More information about the bazaar mailing list