Rev 5968: Support merging into empty tree. in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Mon Jun 13 16:25:21 UTC 2011


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

------------------------------------------------------------
revno: 5968 [merge]
revision-id: pqm at pqm.ubuntu.com-20110613162508-yyvo3qc06t9d2wwf
parent: pqm at pqm.ubuntu.com-20110610161957-hh5ni839m7r3wsan
parent: aaron at aaronbentley.com-20110613153904-o63ne91voyl61q1x
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Mon 2011-06-13 16:25:08 +0000
message:
  Support merging into empty tree.
modified:
  bzrlib/merge.py                merge.py-20050513021216-953b65a438527106
  bzrlib/tests/blackbox/test_merge.py test_merge.py-20060323225809-9bc0459c19917f41
  bzrlib/tests/per_workingtree/test_merge_from_branch.py test_merge_from_bran-20060904034200-12jxyk2zlhpufxe1-1
  bzrlib/tests/test_merge.py     testmerge.py-20050905070950-c1b5aa49ff911024
  bzrlib/tests/test_shelf.py     test_prepare_shelf.p-20081005181341-n74qe6gu1e65ad4v-2
  bzrlib/tests/test_shelf_ui.py  test_shelf_ui.py-20081027155203-wtcuazg85wp9u4fv-1
  bzrlib/tests/test_transform.py test_transaction.py-20060105172520-b3ffb3946550e6c4
  bzrlib/transform.py            transform.py-20060105172343-dd99e54394d91687
  doc/en/release-notes/bzr-2.4.txt bzr2.4.txt-20110114053217-k7ym9jfz243fddjm-1
=== modified file 'bzrlib/merge.py'
--- a/bzrlib/merge.py	2011-05-21 16:43:19 +0000
+++ b/bzrlib/merge.py	2011-06-13 14:10:13 +0000
@@ -868,7 +868,7 @@
                     executable3, file_status, resolver=resolver)
         finally:
             child_pb.finished()
-        self.fix_root()
+        self.tt.fixup_new_roots()
         self._finish_computing_transform()
 
     def _finish_computing_transform(self):
@@ -1093,6 +1093,7 @@
                           ))
         return result
 
+    @deprecated_method(deprecated_in((2, 4, 0)))
     def fix_root(self):
         if self.tt.final_kind(self.tt.root) is None:
             self.tt.cancel_deletion(self.tt.root)
@@ -1316,16 +1317,26 @@
             self._raw_conflicts.append(('path conflict', trans_id, file_id,
                                         this_parent, this_name,
                                         other_parent, other_name))
-        if other_name is None:
+        if not self.other_tree.has_id(file_id):
             # it doesn't matter whether the result was 'other' or
-            # 'conflict'-- if there's no 'other', we leave it alone.
+            # 'conflict'-- if it has no file id, we leave it alone.
             return
         parent_id = parents[self.winner_idx[parent_id_winner]]
-        if parent_id is not None:
+        name = names[self.winner_idx[name_winner]]
+        if parent_id is not None or name is not None:
             # if we get here, name_winner and parent_winner are set to safe
             # values.
-            self.tt.adjust_path(names[self.winner_idx[name_winner]],
-                                self.tt.trans_id_file_id(parent_id),
+            if parent_id is None and name is not None:
+                # if parent_id is None and name is non-None, current file is
+                # the tree root.
+                if names[self.winner_idx[parent_id_winner]] != '':
+                    raise AssertionError(
+                        'File looks like a root, but named %s' %
+                        names[self.winner_idx[parent_id_winner]])
+                parent_trans_id = transform.ROOT_PARENT
+            else:
+                parent_trans_id = self.tt.trans_id_file_id(parent_id)
+            self.tt.adjust_path(name, parent_trans_id,
                                 self.tt.trans_id_file_id(file_id))
 
     def _do_merge_contents(self, file_id):

=== modified file 'bzrlib/tests/blackbox/test_merge.py'
--- a/bzrlib/tests/blackbox/test_merge.py	2011-05-27 09:45:44 +0000
+++ b/bzrlib/tests/blackbox/test_merge.py	2011-06-09 18:56:55 +0000
@@ -668,8 +668,9 @@
             self.build_tree([f])
             tree.add(f)
             tree.commit("added "+f)
-        for context in (".", "", "a"):
-            self.run_bzr("merge -r 1..0 " + context)
+        for context in (".", "", 'a'):
+            retcode = 1 if context == '.' or context == '' else 0
+            self.run_bzr("merge -r 1..0 " + context, retcode=retcode)
             self.assertPathDoesNotExist("a")
             tree.revert()
             self.assertPathExists("a")

=== modified file 'bzrlib/tests/per_workingtree/test_merge_from_branch.py'
--- a/bzrlib/tests/per_workingtree/test_merge_from_branch.py	2011-04-13 14:33:56 +0000
+++ b/bzrlib/tests/per_workingtree/test_merge_from_branch.py	2011-06-13 13:41:49 +0000
@@ -162,6 +162,8 @@
         outer.commit('added foo')
         inner = self.make_inner_branch()
         outer.merge_from_branch(inner, to_revision='1', from_revision='null:')
+        #retain original root id.
+        outer.set_root_id(outer.basis_tree().get_root_id())
         outer.commit('merge inner branch')
         outer.mkdir('dir-outer', 'dir-outer-id')
         outer.move(['dir', 'file3'], to_dir='dir-outer')

=== modified file 'bzrlib/tests/test_merge.py'
--- a/bzrlib/tests/test_merge.py	2011-05-26 08:05:45 +0000
+++ b/bzrlib/tests/test_merge.py	2011-06-09 18:56:55 +0000
@@ -121,6 +121,20 @@
         finally:
             wt1.unlock()
 
+    def test_merge_into_null_tree(self):
+        wt = self.make_branch_and_tree('tree')
+        null_tree = wt.basis_tree()
+        self.build_tree(['tree/file'])
+        wt.add('file')
+        wt.commit('tree with root')
+        merger = _mod_merge.Merge3Merger(null_tree, null_tree, null_tree, wt,
+                                         this_branch=wt.branch,
+                                         do_merge=False)
+        with merger.make_preview_transform() as tt:
+            self.assertEqual([], tt.find_conflicts())
+            preview = tt.get_preview_tree()
+            self.assertEqual(wt.get_root_id(), preview.get_root_id())
+
     def test_create_rename(self):
         """Rename an inventory entry while creating the file"""
         tree =self.make_branch_and_tree('.')
@@ -387,6 +401,26 @@
                              '>>>>>>> MERGE-SOURCE\n',
                              'this/file')
 
+    def test_merge_reverse_revision_range(self):
+        tree = self.make_branch_and_tree(".")
+        tree.lock_write()
+        self.addCleanup(tree.unlock)
+        self.build_tree(['a'])
+        tree.add('a')
+        tree.commit("added a")
+        first_rev = tree.branch.revision_history()[0]
+        merger = _mod_merge.Merger.from_revision_ids(None, tree,
+                                          _mod_revision.NULL_REVISION,
+                                          first_rev)
+        merger.merge_type = _mod_merge.Merge3Merger
+        merger.interesting_files = 'a'
+        conflict_count = merger.do_merge()
+        self.assertEqual(0, conflict_count)
+
+        self.assertPathDoesNotExist("a")
+        tree.revert()
+        self.assertPathExists("a")
+
     def test_make_merger(self):
         this_tree = self.make_branch_and_tree('this')
         this_tree.commit('rev1', rev_id='rev1')

=== modified file 'bzrlib/tests/test_shelf.py'
--- a/bzrlib/tests/test_shelf.py	2011-05-13 12:51:05 +0000
+++ b/bzrlib/tests/test_shelf.py	2011-06-10 08:58:30 +0000
@@ -568,19 +568,18 @@
         list(creator.iter_shelvable())
         creator.shelve_deletion('foo-id')
         creator.shelve_deletion('bar-id')
-        shelf_file = open('shelf', 'w+b')
-        self.addCleanup(shelf_file.close)
-        creator.write_shelf(shelf_file)
-        creator.transform()
-        creator.finalize()
+        with open('shelf', 'w+b') as shelf_file:
+            creator.write_shelf(shelf_file)
+            creator.transform()
+            creator.finalize()
         # validate the test setup
         self.assertTrue('foo-id' in tree)
         self.assertTrue('bar-id' in tree)
         self.assertFileEqual('baz', 'tree/foo/bar')
-        shelf_file.seek(0)
-        unshelver = shelf.Unshelver.from_tree_and_shelf(tree, shelf_file)
-        self.addCleanup(unshelver.finalize)
-        unshelver.make_merger().do_merge()
+        with open('shelf', 'r+b') as shelf_file:
+            unshelver = shelf.Unshelver.from_tree_and_shelf(tree, shelf_file)
+            self.addCleanup(unshelver.finalize)
+            unshelver.make_merger().do_merge()
         self.assertFalse('foo-id' in tree)
         self.assertFalse('bar-id' in tree)
 

=== modified file 'bzrlib/tests/test_shelf_ui.py'
--- a/bzrlib/tests/test_shelf_ui.py	2011-06-09 14:40:22 +0000
+++ b/bzrlib/tests/test_shelf_ui.py	2011-06-13 14:44:22 +0000
@@ -311,10 +311,15 @@
                                 from_revision=revision.NULL_REVISION)
         tree1.commit('Replaced root entry')
         # This is essentially assertNotRaises(InconsistentDelta)
-        self.expectFailure('Cannot shelve replacing a root entry',
-                           self.assertRaises, AssertionError,
-                           self.assertRaises, errors.InconsistentDelta,
-                           self.shelve_all, tree1, rev2)
+        # With testtools 0.99, it can be rewritten as:
+        # with ExpectedException(AssertionError,
+        #                        'InconsistentDelta not raised'):
+        #     with ExpectedException(errors.InconsistentDelta, ''):
+        #         self.shelve_all(tree1, rev2)
+        e = self.assertRaises(AssertionError, self.assertRaises,
+                              errors.InconsistentDelta, self.shelve_all, tree1,
+                              rev2)
+        self.assertContainsRe('InconsistentDelta not raised', str(e))
 
     def test_shelve_split(self):
         outer_tree = self.make_branch_and_tree('outer')

=== modified file 'bzrlib/tests/test_transform.py'
--- a/bzrlib/tests/test_transform.py	2011-06-10 16:19:57 +0000
+++ b/bzrlib/tests/test_transform.py	2011-06-13 16:25:08 +0000
@@ -285,6 +285,23 @@
         new_trans_id = transform.new_directory('', ROOT_PARENT, 'alt-root-id')
         self.assertRaises(ValueError, transform.fixup_new_roots)
 
+    def test_add_unversioned_root(self):
+        transform, root = self.get_transform()
+        new_trans_id = transform.new_directory('', ROOT_PARENT, None)
+        transform.fixup_new_roots()
+        self.assertNotIn(transform.root, transform._new_id)
+
+    def test_apply_retains_root_directory(self):
+        # Do not attempt to delete the physical root directory, because that
+        # is impossible.
+        transform, root = self.get_transform()
+        with transform:
+            transform.delete_contents(root)
+            e = self.assertRaises(AssertionError, self.assertRaises,
+                                  errors.TransformRenameFailed,
+                                  transform.apply)
+        self.assertContainsRe('TransformRenameFailed not raised', str(e))
+
     def test_hardlink(self):
         self.requireFeature(HardlinkFeature)
         transform, root = self.get_transform()

=== modified file 'bzrlib/transform.py'
--- a/bzrlib/transform.py	2011-06-10 16:19:57 +0000
+++ b/bzrlib/transform.py	2011-06-13 16:25:08 +0000
@@ -252,7 +252,8 @@
         if (self.tree_file_id(self._new_root) is not None and
             self._new_root not in self._removed_id):
             self.unversion_file(self._new_root)
-        self.version_file(file_id, self._new_root)
+        if file_id is not None:
+            self.version_file(file_id, self._new_root)
 
         # Now move children of new root into old root directory.
         # Ensure all children are registered with the transaction, but don't
@@ -1826,8 +1827,10 @@
         tree_paths.sort(reverse=True)
         child_pb = ui.ui_factory.nested_progress_bar()
         try:
-            for num, data in enumerate(tree_paths):
-                path, trans_id = data
+            for num, (path, trans_id) in enumerate(tree_paths):
+                # do not attempt to move root into a subdirectory of itself.
+                if path == '':
+                    continue
                 child_pb.update('removing file', num, len(tree_paths))
                 full_path = self._tree.abspath(path)
                 if trans_id in self._removed_contents:

=== modified file 'doc/en/release-notes/bzr-2.4.txt'
--- a/doc/en/release-notes/bzr-2.4.txt	2011-06-09 11:59:08 +0000
+++ b/doc/en/release-notes/bzr-2.4.txt	2011-06-13 16:25:08 +0000
@@ -73,6 +73,8 @@
   ``UIFactory.get_password`` and ``UIFactory.get_boolean`` now require a
   unicode prompt to be passed in. (Jelmer Vernooij, #592083)
 
+* Support merging into the empty tree. (Aaron Bentley, #595328)
+
 Documentation
 *************
 




More information about the bazaar-commits mailing list