Rev 6395: (jelmer) Add pre_merge and post_merge hooks in Merger.hooks. (Jelmer in file:///srv/pqm.bazaar-vcs.org/archives/thelove/bzr/%2Btrunk/
Patch Queue Manager
pqm at pqm.ubuntu.com
Wed Dec 21 15:32:36 UTC 2011
At file:///srv/pqm.bazaar-vcs.org/archives/thelove/bzr/%2Btrunk/
------------------------------------------------------------
revno: 6395 [merge]
revision-id: pqm at pqm.ubuntu.com-20111221153234-kbq1axff8pe224vt
parent: pqm at pqm.ubuntu.com-20111221141733-gmep8iobns97q3eo
parent: jelmer at samba.org-20111221144339-8j56mzd82yekrm0i
committer: Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Wed 2011-12-21 15:32:34 +0000
message:
(jelmer) Add pre_merge and post_merge hooks in Merger.hooks. (Jelmer
Vernooij)
modified:
bzrlib/merge.py merge.py-20050513021216-953b65a438527106
bzrlib/plugins/changelog_merge/tests/test_changelog_merge.py test_changelog_merge-20110310080015-9c3muqni567c1qux-3
bzrlib/tests/test_merge.py testmerge.py-20050905070950-c1b5aa49ff911024
doc/en/release-notes/bzr-2.5.txt bzr2.5.txt-20110708125756-587p0hpw7oke4h05-1
=== modified file 'bzrlib/merge.py'
--- a/bzrlib/merge.py 2011-12-20 11:45:12 +0000
+++ b/bzrlib/merge.py 2011-12-20 13:13:25 +0000
@@ -78,6 +78,15 @@
"See the AbstractPerFileMerger API docs for details on how it is "
"used by merge.",
(2, 1))
+ self.add_hook('pre_merge',
+ 'Called before a merge. '
+ 'Receives a Merger object as the single argument.',
+ (2, 5))
+ self.add_hook('post_merge',
+ 'Called after a merge. '
+ 'Receives a Merger object as the single argument. '
+ 'The return value is ignored.',
+ (2, 5))
class AbstractPerFileMerger(object):
@@ -95,7 +104,7 @@
def merge_contents(self, merge_params):
"""Attempt to merge the contents of a single file.
- :param merge_params: A bzrlib.merge.MergeHookParams
+ :param merge_params: A bzrlib.merge.MergeFileHookParams
:return: A tuple of (status, chunks), where status is one of
'not_applicable', 'success', 'conflicted', or 'delete'. If status
is 'success' or 'conflicted', then chunks should be an iterable of
@@ -122,14 +131,14 @@
def get_filename(self, params, tree):
"""Lookup the filename (i.e. basename, not path), given a Tree (e.g.
- self.merger.this_tree) and a MergeHookParams.
+ self.merger.this_tree) and a MergeFileHookParams.
"""
return osutils.basename(tree.id2path(params.file_id))
def get_filepath(self, params, tree):
"""Calculate the path to the file in a tree.
- :param params: A MergeHookParams describing the file to merge
+ :param params: A MergeFileHookParams describing the file to merge
:param tree: a Tree, e.g. self.merger.this_tree.
"""
return tree.id2path(params.file_id)
@@ -224,7 +233,7 @@
raise NotImplementedError(self.merge_text)
-class MergeHookParams(object):
+class MergeFileHookParams(object):
"""Object holding parameters passed to merge_file_content hooks.
There are some fields hooks can access:
@@ -603,7 +612,7 @@
self._maybe_fetch(base_branch, self.this_branch, self.base_rev_id)
def make_merger(self):
- kwargs = {'working_tree':self.this_tree, 'this_tree': self.this_tree,
+ kwargs = {'working_tree': self.this_tree, 'this_tree': self.this_tree,
'other_tree': self.other_tree,
'interesting_ids': self.interesting_ids,
'interesting_files': self.interesting_files,
@@ -639,7 +648,11 @@
merge = self.make_merger()
if self.other_branch is not None:
self.other_branch.update_references(self.this_branch)
+ for hook in Merger.hooks['pre_merge']:
+ hook(merge)
merge.do_merge()
+ for hook in Merger.hooks['post_merge']:
+ hook(merge)
if self.recurse == 'down':
for relpath, file_id in self.this_tree.iter_references():
sub_tree = self.this_tree.get_nested_tree(file_id, relpath)
@@ -1343,7 +1356,7 @@
# We have a hypothetical conflict, but if we have files, then we
# can try to merge the content
trans_id = self.tt.trans_id_file_id(file_id)
- params = MergeHookParams(self, file_id, trans_id, this_pair[0],
+ params = MergeFileHookParams(self, file_id, trans_id, this_pair[0],
other_pair[0], winner)
hooks = self.active_hooks
hook_status = 'not_applicable'
=== modified file 'bzrlib/plugins/changelog_merge/tests/test_changelog_merge.py'
--- a/bzrlib/plugins/changelog_merge/tests/test_changelog_merge.py 2011-05-13 06:34:55 +0000
+++ b/bzrlib/plugins/changelog_merge/tests/test_changelog_merge.py 2011-12-21 14:43:39 +0000
@@ -188,7 +188,7 @@
merger = builder.make_merger(merge.Merge3Merger, ['clog-id'])
merger.this_branch.get_config().set_user_option(
'changelog_merge_files', 'ChangeLog')
- merge_hook_params = merge.MergeHookParams(merger, 'clog-id', None,
+ merge_hook_params = merge.MergeFileHookParams(merger, 'clog-id', None,
'file', 'file', 'conflict')
changelog_merger = changelog_merge.ChangeLogMerger(merger)
return changelog_merger, merge_hook_params
=== modified file 'bzrlib/tests/test_merge.py'
--- a/bzrlib/tests/test_merge.py 2011-10-14 13:56:45 +0000
+++ b/bzrlib/tests/test_merge.py 2011-12-21 12:34:21 +0000
@@ -3242,3 +3242,46 @@
# The dest tree is unmodified.
self.assertEqual(['r1-dest'], dest_wt.get_parent_ids())
self.assertTreeEntriesEqual([('', 'dest-root-id')], dest_wt)
+
+
+class TestMergeHooks(TestCaseWithTransport):
+
+ def setUp(self):
+ super(TestMergeHooks, self).setUp()
+ self.tree_a = self.make_branch_and_tree('tree_a')
+ self.build_tree_contents([('tree_a/file', 'content_1')])
+ self.tree_a.add('file', 'file-id')
+ self.tree_a.commit('added file')
+
+ self.tree_b = self.tree_a.bzrdir.sprout('tree_b').open_workingtree()
+ self.build_tree_contents([('tree_b/file', 'content_2')])
+ self.tree_b.commit('modify file')
+
+ def test_pre_merge_hook_inject_different_tree(self):
+ tree_c = self.tree_b.bzrdir.sprout('tree_c').open_workingtree()
+ self.build_tree_contents([('tree_c/file', 'content_3')])
+ tree_c.commit("more content")
+ calls = []
+ def factory(merger):
+ self.assertIsInstance(merger, _mod_merge.Merge3Merger)
+ merger.other_tree = tree_c
+ calls.append(merger)
+ _mod_merge.Merger.hooks.install_named_hook('pre_merge',
+ factory, 'test factory')
+ self.tree_a.merge_from_branch(self.tree_b.branch)
+
+ self.assertFileEqual("content_3", 'tree_a/file')
+ self.assertLength(1, calls)
+
+ def test_post_merge_hook_called(self):
+ calls = []
+ def factory(merger):
+ self.assertIsInstance(merger, _mod_merge.Merge3Merger)
+ calls.append(merger)
+ _mod_merge.Merger.hooks.install_named_hook('post_merge',
+ factory, 'test factory')
+
+ self.tree_a.merge_from_branch(self.tree_b.branch)
+
+ self.assertFileEqual("content_2", 'tree_a/file')
+ self.assertLength(1, calls)
=== modified file 'doc/en/release-notes/bzr-2.5.txt'
--- a/doc/en/release-notes/bzr-2.5.txt 2011-12-21 00:07:49 +0000
+++ b/doc/en/release-notes/bzr-2.5.txt 2011-12-21 15:32:34 +0000
@@ -36,6 +36,11 @@
* New HPSS call for ``Repository.reconcile``. (Jelmer Vernooij, #894455)
+* Merge now has two new hooks ``pre_merge`` and ``post_merge``
+ that are called before and after a merge and can make
+ additional modifications to the trees involved.
+ (Jelmer Vernooij, #906877)
+
* Override the value returned by ``sys.getfilesystemencoding()`` for the bzr
script to utf-8 when it would otherwise be ascii on a posix system. This
will mean bzr works with non-ascii files when no locale or an incorrect
More information about the bazaar-commits
mailing list