Rev 7: Change the code so that we pass in the RevisionTree of the merge. in http://bzr.arbash-meinel.com/plugins/per_file_remerge

John Arbash Meinel john at arbash-meinel.com
Wed Jun 18 16:27:59 BST 2008


At http://bzr.arbash-meinel.com/plugins/per_file_remerge

------------------------------------------------------------
revno: 7
revision-id: john at arbash-meinel.com-20080618152746-0o45ad0xxu9x77xg
parent: john at arbash-meinel.com-20080618150645-yjm7co1x5i6whdac
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: per_file_remerge
timestamp: Wed 2008-06-18 10:27:46 -0500
message:
  Change the code so that we pass in the RevisionTree of the merge.
  It was costing us a lot to extract this for every file we were correcting.
-------------- next part --------------
=== modified file '__init__.py'
--- a/__init__.py	2008-06-18 15:06:45 +0000
+++ b/__init__.py	2008-06-18 15:27:46 +0000
@@ -52,6 +52,7 @@
                 raise errors.BzrCommandError(
                     "Sorry, per-file-remerge only works after normal"
                     " merges.  Not cherrypicking or multi-merges.")
+            merge_revision_id = parent_ids[1]
             if not relpaths:
                 # use the list of conflicted files
                 trace.mutter('Doing per-file remerge using the conflict list')
@@ -59,16 +60,23 @@
                 for conflict in tree.conflicts():
                     if conflict.typestring == 'text conflict':
                         relpaths.append(conflict.path)
+            merge_tree = tree.branch.repository.revision_tree(merge_revision_id)
             num_conflicts = 0
             pb = ui.ui_factory.nested_progress_bar()
+            # While remerging, we need to pretend nothing is merged,
+            # but restore it at the end
+            tree.set_parent_ids(parent_ids[:1])
             try:
                 num_conflicted = len(relpaths)
                 for idx, relpath in enumerate(relpaths):
                     pb.update('resolving', idx, num_conflicted)
                     trace.mutter('processing file: %s', relpath)
                     num_conflicts += per_file_remerge._remerge_file(tree,
-                                        relpath, merge_type)
+                                        relpath, merge_type,
+                                        merge_revision_id,
+                                        merge_tree)
             finally:
+                tree.set_parent_ids(parent_ids)
                 pb.finished()
         finally:
             tree.unlock()

=== modified file 'per_file_remerge.py'
--- a/per_file_remerge.py	2008-06-18 15:06:04 +0000
+++ b/per_file_remerge.py	2008-06-18 15:27:46 +0000
@@ -27,11 +27,9 @@
     )
 
 
-def _remerge_file(tree, relpath, merge_type):
+def _remerge_file(tree, relpath, merge_type, merge_revision_id, merge_tree):
     # This tricks the merge algorithm into using the per-file graph,
     # rather than using the global graph.
-    parent_ids = tree.get_parent_ids()
-    merge_revision_id = parent_ids[1]
 
     file_id = tree.path2id(relpath)
     if file_id is None:
@@ -39,14 +37,13 @@
 
     per_file_graph = _get_per_file_graph(tree, file_id)
     this_modifed, base_revision_id, other_modified = _find_revision_ids(
-        tree, file_id, merge_revision_id, per_file_graph)
+        tree, file_id, merge_tree, per_file_graph)
 
     _restore_file_id_to_pristine(tree, file_id, relpath)
 
     # At this point, we have reverted the content of the file, now lets
     # do the merge
     pb = ui.ui_factory.nested_progress_bar()
-    tree.set_parent_ids(parent_ids[:1])
     try:
         merger = merge.Merger.from_revision_ids(pb, tree,
             other=other_modified,
@@ -63,7 +60,6 @@
         merger.reprocess = True
         num_conflicts = merger.do_merge()
     finally:
-        tree.set_parent_ids(parent_ids)
         pb.finished()
     return num_conflicts
 
@@ -87,25 +83,25 @@
     """Get a Graph object for this file's history."""
     repo = tree.branch.repository
     weave = repo.weave_store.get_weave(file_id, repo.get_transaction())
+    # TODO: Do we want to use a CachingParentsProvider inbetween weave and
+    #       Graph?
     graph_obj = graph.Graph(weave)
     return graph_obj
 
 
-def _find_revision_ids(tree, file_id, merge_revision_id, graph_obj):
+def _find_revision_ids(tree, file_id, merge_tree, graph_obj):
     """Find the revision ids that are going to be merged.
 
     :param tree: The working tree in question
     :param file_id: The file in question
-    :param merge_revision_id: The revision which is merged into tree
+    :param merge_tree: The tree which was merged into this one
     :param graph_obj: The per-file graph, given by _get_per_file_graph
     :return: revision ids for (this, base, other)
     """
     # Use tree.inventory[file_id].revision to find the revision id in the
     # per-file graph
     # TODO: Is there a better way to get this than going to the inventory?
-    other_tree = tree.branch.repository.revision_tree(
-        merge_revision_id)
-    other_last_modified_revision_id = other_tree.inventory[file_id].revision
+    other_last_modified_revision_id = merge_tree.inventory[file_id].revision
 
     basis_tree = tree.basis_tree()
     basis_tree.lock_read()

=== modified file 'test_per_file_remerge.py'
--- a/test_per_file_remerge.py	2008-06-18 15:06:04 +0000
+++ b/test_per_file_remerge.py	2008-06-18 15:27:46 +0000
@@ -88,16 +88,19 @@
         tree1.merge_from_branch(tree2.branch)
         tree1.lock_read()
         self.addCleanup(tree1.unlock)
+        merge_tree = tree1.branch.repository.revision_tree('rev-F')
+        merge_tree.lock_read()
+        self.addCleanup(merge_tree.unlock)
         graph_obj = per_file_remerge._get_per_file_graph(
             tree1, 'a-id')
         self.assertEqual(('rev-E', 'rev-A', 'rev-A'),
             per_file_remerge._find_revision_ids(
-                tree1, 'a-id', 'rev-F', graph_obj))
+                tree1, 'a-id', merge_tree, graph_obj))
         graph_obj = per_file_remerge._get_per_file_graph(
             tree1, 'b-id')
         self.assertEqual(('rev-B', 'rev-B', 'rev-F'),
             per_file_remerge._find_revision_ids(
-                tree1, 'b-id', 'rev-F', graph_obj))
+                tree1, 'b-id', merge_tree, graph_obj))
 
     def test_merge_criss_cross(self):
         tree1, tree2 = self.create_criss_cross_merge()



More information about the bazaar-commits mailing list