~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/plugins/news_merge/__init__.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2010-01-20 17:19:44 UTC
  • mfrom: (4973.1.1 integration)
  • Revision ID: pqm@pqm.ubuntu.com-20100120171944-8gkub20gotjcye67
(spiv) Implement a per-file merge hook

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2010 Canonical Ltd
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
16
 
 
17
"""Merge hook for bzr's NEWS file.
 
18
 
 
19
To enable this plugin, add a section to your branch.conf or location.conf
 
20
like::
 
21
 
 
22
    [/home/user/code/bzr]
 
23
    news_merge_files = NEWS
 
24
    news_merge_files:policy = recurse
 
25
 
 
26
The news_merge_files config option takes a list of file paths, separated by
 
27
commas.
 
28
 
 
29
Limitations:
 
30
 
 
31
* if there's a conflict in more than just bullet points, this doesn't yet know
 
32
  how to resolve that, so bzr will fallback to the default line-based merge.
 
33
"""
 
34
 
 
35
# Since we are a built-in plugin we share the bzrlib version
 
36
from bzrlib import version_info
 
37
 
 
38
# Put most of the code in a separate module that we lazy-import to keep the
 
39
# overhead of this plugin as minimal as possible.
 
40
from bzrlib.lazy_import import lazy_import
 
41
lazy_import(globals(), """
 
42
from bzrlib.plugins.news_merge.news_merge import news_merger
 
43
""")
 
44
 
 
45
from bzrlib.merge import Merger
 
46
 
 
47
 
 
48
def news_merge_hook(params):
 
49
    """Merger.merge_file_content hook function for bzr-format NEWS files."""
 
50
    # First, check whether this custom merge logic should be used.  We expect
 
51
    # most files should not be merged by this file.
 
52
    if params.winner == 'other':
 
53
        # OTHER is a straight winner, rely on default merge.
 
54
        return 'not_applicable', None
 
55
    elif not params.is_file_merge():
 
56
        # THIS and OTHER aren't both files.
 
57
        return 'not_applicable', None
 
58
    elif not filename_matches_config(params):
 
59
        # The filename isn't listed in the 'news_merge_files' config option.
 
60
        return 'not_applicable', None
 
61
    return news_merger(params)
 
62
 
 
63
 
 
64
def filename_matches_config(params):
 
65
    affected_files = getattr(params, '_news_merge_affected_files', None)
 
66
    if affected_files is None:
 
67
        config = params.merger.this_tree.branch.get_config()
 
68
        # Until bzr provides a better policy for caching the config, we just
 
69
        # add the part we're interested in to the params to avoid reading the
 
70
        # config files repeatedly (bazaar.conf, location.conf, branch.conf).
 
71
        affected_files = config.get_user_option_as_list('news_merge_files')
 
72
        if affected_files is None:
 
73
            # If nothing was specified in the config, we have nothing to do,
 
74
            # but we use None in the params to start the caching.
 
75
            affected_files = []
 
76
        params._news_merge_affected_files = affected_files
 
77
    if affected_files:
 
78
        filename = params.merger.this_tree.id2path(params.file_id)
 
79
        if filename in affected_files:
 
80
            return True
 
81
    return False
 
82
 
 
83
def install_hook():
 
84
    Merger.hooks.install_named_hook(
 
85
        'merge_file_content', news_merge_hook, 'NEWS file merge')
 
86
install_hook()
 
87
 
 
88
 
 
89
def load_tests(basic_tests, module, loader):
 
90
    testmod_names = [
 
91
        'tests',
 
92
        ]
 
93
    basic_tests.addTest(loader.loadTestsFromModuleNames(
 
94
            ["%s.%s" % (__name__, tmn) for tmn in testmod_names]))
 
95
    return basic_tests
 
96