~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/merge.py

  • Committer: Robert Collins
  • Date: 2010-01-28 18:01:03 UTC
  • mto: (4797.2.5 2.1)
  • mto: This revision was merged to the branch mainline in revision 4989.
  • Revision ID: robertc@robertcollins.net-20100128180103-kj106kj55vsbqxu1
Refactor NewsMerger into a reusable base class merge.ConfigurableFileMerger.

Show diffs side-by-side

added added

removed removed

Lines of Context:
93
93
        return ('not applicable', None)
94
94
 
95
95
 
 
96
class ConfigurableFileMerger(AbstractPerFileMerger):
 
97
    """Merge individual files when configured via a .conf file.
 
98
 
 
99
    This is a base class for concrete custom file merging logic. Concrete
 
100
    classes should implement ``merge_text``.
 
101
 
 
102
    :ivar affected_files: The configured file paths to merge.
 
103
    :ivar name_prefix: The prefix to use when looking up configuration
 
104
        details.
 
105
    :ivar default_files: The default file paths to merge when no configuration
 
106
        is present.
 
107
    """
 
108
 
 
109
    def __init__(self, merger, name_prefix, default_files=None):
 
110
        super(ConfigurableFileMerger, self).__init__(merger)
 
111
        self.affected_files = None
 
112
        self.default_files = default_files or []
 
113
        self.name_prefix = name_prefix
 
114
 
 
115
    def filename_matches_config(self, params):
 
116
        affected_files = self.affected_files
 
117
        if affected_files is None:
 
118
            config = self.merger.this_tree.branch.get_config()
 
119
            # Until bzr provides a better policy for caching the config, we
 
120
            # just add the part we're interested in to the params to avoid
 
121
            # reading the config files repeatedly (bazaar.conf, location.conf,
 
122
            # branch.conf).
 
123
            config_key = self.name_prefix + '_merge_files'
 
124
            affected_files = config.get_user_option_as_list(config_key)
 
125
            if affected_files is None:
 
126
                # If nothing was specified in the config, use the default.
 
127
                affected_files = self.default_files
 
128
            self.affected_files = affected_files
 
129
        if affected_files:
 
130
            filename = self.merger.this_tree.id2path(params.file_id)
 
131
            if filename in affected_files:
 
132
                return True
 
133
        return False
 
134
 
 
135
    def merge_contents(self, params):
 
136
        """Merge the contents of a single file."""
 
137
        # First, check whether this custom merge logic should be used.  We
 
138
        # expect most files should not be merged by this handler.
 
139
        if (
 
140
            # OTHER is a straight winner, rely on default merge.
 
141
            params.winner == 'other' or
 
142
            # THIS and OTHER aren't both files.
 
143
            not params.is_file_merge() or
 
144
            # The filename isn't listed in the 'NAME_merge_files' config
 
145
            # option.
 
146
            not self.filename_matches_config(params)):
 
147
            return 'not_applicable', None
 
148
        return self.merge_text(self, params)
 
149
 
 
150
    def merge_text(self, params):
 
151
        """Merge the byte contents of a single file.
 
152
 
 
153
        This is called after checking that the merge should be performed in
 
154
        merge_contents, and it should behave as per
 
155
        ``bzrlib.merge.AbstractPerFileMerger.merge_contents``.
 
156
        """
 
157
        raise NotImplementedError(self.merge_text)
 
158
 
 
159
 
96
160
class MergeHookParams(object):
97
161
    """Object holding parameters passed to merge_file_content hooks.
98
162