Rev 2: Move the code out into a separate file for easier testing in http://bzr.arbash-meinel.com/plugins/per_file_remerge

John Arbash Meinel john at arbash-meinel.com
Wed Jun 18 14:50:49 BST 2008


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

------------------------------------------------------------
revno: 2
revision-id: john at arbash-meinel.com-20080618135040-6d22o4pkjgxffoy0
parent: john at arbash-meinel.com-20080618052913-t3ww5vj3a5q75uj0
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: per_file_remerge
timestamp: Wed 2008-06-18 08:50:40 -0500
message:
  Move the code out into a separate file for easier testing
-------------- next part --------------
=== modified file '__init__.py'
--- a/__init__.py	2008-06-18 05:29:13 +0000
+++ b/__init__.py	2008-06-18 13:50:40 +0000
@@ -31,11 +31,11 @@
 
     def run(self, filename, merge_type=None):
         from bzrlib import (
-            conflicts,
             merge,
             ui,
             workingtree,
             )
+        import per_file_remerge
         if merge_type is None:
             merge_type = merge.Merge3Merger
         tree, relpath = workingtree.WorkingTree.open_containing(filename)
@@ -46,44 +46,8 @@
                 raise errors.BzrCommandError(
                     "Sorry, per-file-remerge only works after normal"
                     " merges.  Not cherrypicking or multi-merges.")
-            merge_revision_id = parent_ids[1]
-
-            # This tricks the merge algorithm into using the per-file graph,
-            # rather than using the global graph.
-            file_id = tree.path2id(relpath)
-            if file_id is None:
-                raise errors.NotVersionedError(relpath)
-
-            per_file_graph = self._get_per_file_graph(tree, file_id)
-            this_modifed, base_revision_id, other_modified = \
-                self._find_revision_ids(tree, file_id, merge_revision_id,
-                                        per_file_graph)
-
-            print this_modifed, base_revision_id, other_modified
-            self._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,
-                    # Should we fake it here, or just assume that it is going
-                    # to be handled properly?
-                    base=base_revision_id,
-                    # other_branch=???,
-                    # base_branch=???,
-                    revision_graph=per_file_graph,
-                    )
-                merger.interesting_ids = set([file_id])
-                merger.merge_type = merge_type
-                # merger.show_base = show_base
-                # merger.reprocess = reprocess
-                num_conflicts = merger.do_merge()
-            finally:
-                tree.set_parent_ids(parent_ids)
-                pb.finished()
+            num_conflicts = per_file_remerge._remerge_file(tree, relpath,
+                                                           merge_type)
         finally:
             tree.unlock()
 
@@ -92,62 +56,6 @@
         else:
             return 0
 
-    def _restore_file_id_to_pristine(self, tree, file_id, relpath):
-        """Restore the given file to its pristine state."""
-        from bzrlib import conflicts, merge
-        # Now that we have the file, restore it to the original value, and
-        # reset the conflict list
-        cur_conflicts = tree.conflicts()
-        other_conflicts, matching_conflicts = cur_conflicts.select_conflicts(
-            tree, [relpath])
-        merge.transform_tree(tree, tree.basis_tree(), [file_id])
-        tree.set_conflicts(conflicts.ConflictList(other_conflicts))
-        try:
-            conflicts.restore(tree.abspath(relpath))
-        except errors.NotConflicted:
-            pass
-
-    @staticmethod
-    def _get_per_file_graph(tree, file_id):
-        """Get a Graph object for this file's history."""
-        from bzrlib import graph
-        repo = tree.branch.repository
-        weave = repo.weave_store.get_weave(file_id, repo.get_transaction())
-        graph_obj = graph.Graph(weave)
-        return graph_obj
-
-    @staticmethod
-    def _find_revision_ids(tree, file_id, merge_revision_id, 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 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
-
-        basis_tree = tree.basis_tree()
-        basis_tree.lock_read()
-        try:
-            this_last_modified_revision_id = basis_tree.inventory[file_id].revision
-        finally:
-            basis_tree.unlock()
-
-        base_revision_id, num_steps = graph_obj.find_unique_lca(
-            this_last_modified_revision_id,
-            other_last_modified_revision_id,
-            count_steps=True)
-        return (this_last_modified_revision_id, base_revision_id,
-                other_last_modified_revision_id)
-
-
 commands.register_command(cmd_per_file_remerge)
 
 

=== added file 'per_file_remerge.py'
--- a/per_file_remerge.py	1970-01-01 00:00:00 +0000
+++ b/per_file_remerge.py	2008-06-18 13:50:40 +0000
@@ -0,0 +1,121 @@
+# Copyright (C) 2008 Canonical Development Ltd
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+"""Recompute a merge, using the per-file graph."""
+
+from bzrlib import (
+    conflicts,
+    errors,
+    graph,
+    merge,
+    ui,
+    )
+
+
+def _remerge_file(tree, relpath, merge_type):
+    # 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:
+        raise errors.NotVersionedError(relpath)
+
+    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)
+
+    _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,
+            # Should we fake it here, or just assume that it is going
+            # to be handled properly?
+            base=base_revision_id,
+            # other_branch=???,
+            # base_branch=???,
+            revision_graph=per_file_graph,
+            )
+        merger.interesting_ids = set([file_id])
+        merger.merge_type = merge_type
+        # merger.show_base = show_base
+        # merger.reprocess = reprocess
+        num_conflicts = merger.do_merge()
+    finally:
+        tree.set_parent_ids(parent_ids)
+        pb.finished()
+    return num_conflicts
+
+
+def _restore_file_id_to_pristine(tree, file_id, relpath):
+    """Restore the given file to its pristine state."""
+    # Now that we have the file, restore it to the original value, and
+    # reset the conflict list
+    cur_conflicts = tree.conflicts()
+    other_conflicts, matching_conflicts = cur_conflicts.select_conflicts(
+        tree, [relpath])
+    merge.transform_tree(tree, tree.basis_tree(), [file_id])
+    tree.set_conflicts(conflicts.ConflictList(other_conflicts))
+    try:
+        conflicts.restore(tree.abspath(relpath))
+    except errors.NotConflicted:
+        pass
+
+
+def _get_per_file_graph(tree, file_id):
+    """Get a Graph object for this file's history."""
+    repo = tree.branch.repository
+    weave = repo.weave_store.get_weave(file_id, repo.get_transaction())
+    graph_obj = graph.Graph(weave)
+    return graph_obj
+
+
+def _find_revision_ids(tree, file_id, merge_revision_id, 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 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
+
+    basis_tree = tree.basis_tree()
+    basis_tree.lock_read()
+    try:
+        this_last_modified_revision_id = basis_tree.inventory[file_id].revision
+    finally:
+        basis_tree.unlock()
+
+    base_revision_id, num_steps = graph_obj.find_unique_lca(
+        this_last_modified_revision_id,
+        other_last_modified_revision_id,
+        count_steps=True)
+    return (this_last_modified_revision_id, base_revision_id,
+            other_last_modified_revision_id)
+

=== modified file 'test_per_file_remerge.py'
--- a/test_per_file_remerge.py	2008-06-18 05:29:13 +0000
+++ b/test_per_file_remerge.py	2008-06-18 13:50:40 +0000
@@ -18,7 +18,7 @@
 
 from bzrlib import tests
 
-from bzrlib.plugins import per_file_remerge
+import per_file_remerge
 
 
 class TestPerFileRemerge(tests.TestCaseWithTransport):
@@ -74,11 +74,11 @@
         tree1.merge_from_branch(tree2.branch)
         tree1.lock_read()
         self.addCleanup(tree1.unlock)
-        graph_obj = per_file_remerge.cmd_per_file_remerge._get_per_file_graph(
+        graph_obj = per_file_remerge._get_per_file_graph(
             tree1, 'a-id')
         self.assertEqual({'rev-E': ('rev-A',), 'rev-A': ('rev-base',)},
                          graph_obj.get_parent_map(['rev-E', 'rev-A']))
-        graph_obj = per_file_remerge.cmd_per_file_remerge._get_per_file_graph(
+        graph_obj = per_file_remerge._get_per_file_graph(
             tree1, 'b-id')
         self.assertEqual({'rev-F': ('rev-B',), 'rev-B': ('rev-base',)},
                          graph_obj.get_parent_map(['rev-F', 'rev-B']))
@@ -88,15 +88,15 @@
         tree1.merge_from_branch(tree2.branch)
         tree1.lock_read()
         self.addCleanup(tree1.unlock)
-        graph_obj = per_file_remerge.cmd_per_file_remerge._get_per_file_graph(
+        graph_obj = per_file_remerge._get_per_file_graph(
             tree1, 'a-id')
         self.assertEqual(('rev-E', 'rev-A', 'rev-A'),
-            per_file_remerge.cmd_per_file_remerge._find_revision_ids(
+            per_file_remerge._find_revision_ids(
                 tree1, 'a-id', 'rev-F', graph_obj))
-        graph_obj = per_file_remerge.cmd_per_file_remerge._get_per_file_graph(
+        graph_obj = per_file_remerge._get_per_file_graph(
             tree1, 'b-id')
         self.assertEqual(('rev-B', 'rev-B', 'rev-F'),
-            per_file_remerge.cmd_per_file_remerge._find_revision_ids(
+            per_file_remerge._find_revision_ids(
                 tree1, 'b-id', 'rev-F', graph_obj))
 
     def test_merge_criss_cross(self):



More information about the bazaar-commits mailing list