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