Rev 5977: (spiv) "bzr mv --after old_name new_name" now works if new_name is newly in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Thu Jun 16 07:51:33 UTC 2011


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

------------------------------------------------------------
revno: 5977 [merge]
revision-id: pqm at pqm.ubuntu.com-20110616075128-g8hdusp4sr0bwipz
parent: pqm at pqm.ubuntu.com-20110616061029-e58iq1gyvk3pl4yz
parent: benoit.pierre at gmail.com-20110614164044-tlk6pxjz5a5y53t1
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Thu 2011-06-16 07:51:28 +0000
message:
  (spiv) "bzr mv --after old_name new_name" now works if new_name is newly
   added. (Benoit PIERRE)
modified:
  bzrlib/tests/per_workingtree/test_rename_one.py test_rename_one.py-20070226161242-2d8ibdedl700jgio-1
  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_workingtree/test_rename_one.py'
--- a/bzrlib/tests/per_workingtree/test_rename_one.py	2011-05-13 12:51:05 +0000
+++ b/bzrlib/tests/per_workingtree/test_rename_one.py	2011-05-24 21:09:26 +0000
@@ -220,6 +220,51 @@
         self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id')],
                               tree.basis_tree())
 
+    def test_rename_one_after_dest_versioned(self):
+        tree = self.make_branch_and_tree('.')
+        self.build_tree(['a'])
+        tree.add(['a'], ['a-id'])
+        tree.commit('initial', rev_id='rev-1')
+        root_id = tree.get_root_id()
+        os.rename('a', 'b')
+        tree.add(['b'], ['b-id'])
+
+        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id')],
+                               tree)
+        e = self.assertRaises(errors.BzrMoveFailedError,
+            tree.rename_one, 'a', 'b')
+        self.assertIsInstance(e.extra, errors.AlreadyVersionedError)
+
+    def test_rename_one_after_with_after_dest_versioned(self):
+        ''' using after with an already versioned file should fail '''
+        tree = self.make_branch_and_tree('.')
+        self.build_tree(['a', 'b'])
+        tree.add(['a', 'b'], ['a-id', 'b-id'])
+        tree.commit('initial', rev_id='rev-1')
+        root_id = tree.get_root_id()
+        os.unlink('a')
+
+        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id')],
+                               tree)
+        e = self.assertRaises(errors.BzrMoveFailedError,
+            tree.rename_one, 'a', 'b', after=True)
+        self.assertIsInstance(e.extra, errors.AlreadyVersionedError)
+
+    def test_rename_one_after_with_after_dest_added(self):
+        ''' using after with a newly added file should work '''
+        tree = self.make_branch_and_tree('.')
+        self.build_tree(['a'])
+        tree.add(['a'], ['a-id'])
+        tree.commit('initial', rev_id='rev-1')
+        root_id = tree.get_root_id()
+        os.rename('a', 'b')
+        tree.add(['b'], ['b-id'])
+
+        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id')],
+                               tree)
+        tree.rename_one('a', 'b', after=True)
+        self.assertTreeLayout([('', root_id), ('b', 'a-id')], tree)
+
     def test_rename_one_after_source_removed(self):
         """Rename even if the source was already unversioned."""
         tree = self.make_branch_and_tree('.')

=== modified file 'bzrlib/workingtree.py'
--- a/bzrlib/workingtree.py	2011-06-15 11:36:05 +0000
+++ b/bzrlib/workingtree.py	2011-06-16 07:51:28 +0000
@@ -973,8 +973,8 @@
         file and change the file_id. That is the normal mode. Second, it can
         only change the file_id without touching any physical file.
 
-        rename_one uses the second mode if 'after == True' and 'to_rel' is not
-        versioned but present in the working tree.
+        rename_one uses the second mode if 'after == True' and 'to_rel' is
+        either not versioned or newly added, and present in the working tree.
 
         rename_one uses the second mode if 'after == False' and 'from_rel' is
         versioned but no longer in the working tree, and 'to_rel' is not
@@ -2568,8 +2568,8 @@
         inventory. The second mode only updates the inventory without
         touching the file on the filesystem.
 
-        move uses the second mode if 'after == True' and the target is not
-        versioned but present in the working tree.
+        move uses the second mode if 'after == True' and the target is
+        either not versioned or newly added, and present in the working tree.
 
         move uses the second mode if 'after == False' and the source is
         versioned but no longer in the working tree, and the target is not
@@ -2722,7 +2722,8 @@
 
     class _RenameEntry(object):
         def __init__(self, from_rel, from_id, from_tail, from_parent_id,
-                     to_rel, to_tail, to_parent_id, only_change_inv=False):
+                     to_rel, to_tail, to_parent_id, only_change_inv=False,
+                     change_id=False):
             self.from_rel = from_rel
             self.from_id = from_id
             self.from_tail = from_tail
@@ -2730,6 +2731,7 @@
             self.to_rel = to_rel
             self.to_tail = to_tail
             self.to_parent_id = to_parent_id
+            self.change_id = change_id
             self.only_change_inv = only_change_inv
 
     def _determine_mv_mode(self, rename_entries, after=False):
@@ -2747,14 +2749,27 @@
             to_rel = rename_entry.to_rel
             to_id = inv.path2id(to_rel)
             only_change_inv = False
+            change_id = False
 
             # check the inventory for source and destination
             if from_id is None:
                 raise errors.BzrMoveFailedError(from_rel,to_rel,
                     errors.NotVersionedError(path=from_rel))
             if to_id is not None:
-                raise errors.BzrMoveFailedError(from_rel,to_rel,
-                    errors.AlreadyVersionedError(path=to_rel))
+                allowed = False
+                # allow it with --after but only if dest is newly added
+                if after:
+                    basis = self.basis_tree()
+                    basis.lock_read()
+                    try:
+                        if not basis.has_id(to_id):
+                            rename_entry.change_id = True
+                            allowed = True
+                    finally:
+                        basis.unlock()
+                if not allowed:
+                    raise errors.BzrMoveFailedError(from_rel,to_rel,
+                        errors.AlreadyVersionedError(path=to_rel))
 
             # try to determine the mode for rename (only change inv or change
             # inv and file system)
@@ -2831,6 +2846,9 @@
             except OSError, e:
                 raise errors.BzrMoveFailedError(entry.from_rel,
                     entry.to_rel, e[1])
+        if entry.change_id:
+            to_id = inv.path2id(entry.to_rel)
+            inv.remove_recursive_id(to_id)
         inv.rename(entry.from_id, entry.to_parent_id, entry.to_tail)
 
     @needs_tree_write_lock

=== modified file 'doc/en/release-notes/bzr-2.4.txt'
--- a/doc/en/release-notes/bzr-2.4.txt	2011-06-16 05:21:36 +0000
+++ b/doc/en/release-notes/bzr-2.4.txt	2011-06-16 07:51:28 +0000
@@ -295,6 +295,9 @@
   not load the whole inventory, which can take 10+s with large trees.
   (Jonathan Riddell, John Arbash Meinel, #781168)
 
+* ``bzr mv --after old_name new_name`` now works if "new_name" is newly
+  added. (Benoît Pierre)
+
 
 Documentation
 *************




More information about the bazaar-commits mailing list