~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/merge.py

  • Committer: Jelmer Vernooij
  • Date: 2011-12-20 12:47:20 UTC
  • mto: This revision was merged to the branch mainline in revision 6395.
  • Revision ID: jelmer@canonical.com-20111220124720-kya9ilr0dle3tve2
Add pre and post merge hooks.

Show diffs side-by-side

added added

removed removed

Lines of Context:
78
78
            "See the AbstractPerFileMerger API docs for details on how it is "
79
79
            "used by merge.",
80
80
            (2, 1))
 
81
        self.add_hook('pre_merge',
 
82
            'Called before a merge.',
 
83
            (2, 5))
 
84
        self.add_hook('post_merge',
 
85
            'Called after a merge. Receives a Merger object as a single argument. '
 
86
            'The return value is ignored.',
 
87
            (2, 5))
81
88
 
82
89
 
83
90
class AbstractPerFileMerger(object):
95
102
    def merge_contents(self, merge_params):
96
103
        """Attempt to merge the contents of a single file.
97
104
        
98
 
        :param merge_params: A bzrlib.merge.MergeHookParams
 
105
        :param merge_params: A bzrlib.merge.MergeFileHookParams
99
106
        :return: A tuple of (status, chunks), where status is one of
100
107
            'not_applicable', 'success', 'conflicted', or 'delete'.  If status
101
108
            is 'success' or 'conflicted', then chunks should be an iterable of
122
129
 
123
130
    def get_filename(self, params, tree):
124
131
        """Lookup the filename (i.e. basename, not path), given a Tree (e.g.
125
 
        self.merger.this_tree) and a MergeHookParams.
 
132
        self.merger.this_tree) and a MergeFileHookParams.
126
133
        """
127
134
        return osutils.basename(tree.id2path(params.file_id))
128
135
 
129
136
    def get_filepath(self, params, tree):
130
137
        """Calculate the path to the file in a tree.
131
138
 
132
 
        :param params: A MergeHookParams describing the file to merge
 
139
        :param params: A MergeFileHookParams describing the file to merge
133
140
        :param tree: a Tree, e.g. self.merger.this_tree.
134
141
        """
135
142
        return tree.id2path(params.file_id)
224
231
        raise NotImplementedError(self.merge_text)
225
232
 
226
233
 
227
 
class MergeHookParams(object):
 
234
class MergeFileHookParams(object):
228
235
    """Object holding parameters passed to merge_file_content hooks.
229
236
 
230
237
    There are some fields hooks can access:
265
272
        return self._merger.get_lines(self._merger.other_tree, self.file_id)
266
273
 
267
274
 
 
275
class PreMergeHookParams(object):
 
276
    """Object holding parameters passed to the `pre_merge` hook.
 
277
 
 
278
    """
 
279
 
 
280
    def __init__(self):
 
281
        """Create a PreMergeHookParams object.
 
282
 
 
283
        """
 
284
 
 
285
    def __eq__(self, other):
 
286
        return self.__dict__ == other.__dict__
 
287
 
 
288
    def __repr__(self):
 
289
        return "<%s>" % (
 
290
            self.__class__.__name__)
 
291
 
 
292
 
268
293
class Merger(object):
269
294
 
270
295
    hooks = MergeHooks()
603
628
            self._maybe_fetch(base_branch, self.this_branch, self.base_rev_id)
604
629
 
605
630
    def make_merger(self):
606
 
        kwargs = {'working_tree':self.this_tree, 'this_tree': self.this_tree,
 
631
        params = PreMergeHookParams()
 
632
        for hook in Merger.hooks['pre_merge']:
 
633
            hook(params)
 
634
        kwargs = {'working_tree': self.this_tree, 'this_tree': self.this_tree,
607
635
                  'other_tree': self.other_tree,
608
636
                  'interesting_ids': self.interesting_ids,
609
637
                  'interesting_files': self.interesting_files,
640
668
        if self.other_branch is not None:
641
669
            self.other_branch.update_references(self.this_branch)
642
670
        merge.do_merge()
 
671
        for hook in Merger.hooks['post_merge']:
 
672
            hook(merge)
643
673
        if self.recurse == 'down':
644
674
            for relpath, file_id in self.this_tree.iter_references():
645
675
                sub_tree = self.this_tree.get_nested_tree(file_id, relpath)
1343
1373
        # We have a hypothetical conflict, but if we have files, then we
1344
1374
        # can try to merge the content
1345
1375
        trans_id = self.tt.trans_id_file_id(file_id)
1346
 
        params = MergeHookParams(self, file_id, trans_id, this_pair[0],
 
1376
        params = MergeFileHookParams(self, file_id, trans_id, this_pair[0],
1347
1377
            other_pair[0], winner)
1348
1378
        hooks = self.active_hooks
1349
1379
        hook_status = 'not_applicable'