~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/merge.py

  • Committer: Aaron Bentley
  • Date: 2010-05-10 11:34:20 UTC
  • mfrom: (5218 +trunk)
  • mto: This revision was merged to the branch mainline in revision 5221.
  • Revision ID: aaron@aaronbentley.com-20100510113420-toh2d5yioobb5uq1
Merged bzr.dev into transform-commit-full.

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):
 
96
class PerFileMerger(AbstractPerFileMerger):
 
97
    """Merge individual files when self.file_matches returns True.
 
98
 
 
99
    This class is intended to be subclassed.  The file_matches and
 
100
    merge_matching methods should be overridden with concrete implementations.
 
101
    """
 
102
 
 
103
    def file_matches(self, params):
 
104
        """Return True if merge_matching should be called on this file.
 
105
 
 
106
        Only called with merges of plain files with no clear winner.
 
107
 
 
108
        Subclasses must override this.
 
109
        """
 
110
        raise NotImplementedError(self.file_matches)
 
111
 
 
112
    def get_filename(self, params, tree):
 
113
        """Lookup the filename (i.e. basename, not path), given a Tree (e.g.
 
114
        self.merger.this_tree) and a MergeHookParams.
 
115
        """
 
116
        return osutils.basename(tree.id2path(params.file_id))
 
117
 
 
118
    def get_filepath(self, params, tree):
 
119
        """Calculate the path to the file in a tree.
 
120
 
 
121
        :param params: A MergeHookParams describing the file to merge
 
122
        :param tree: a Tree, e.g. self.merger.this_tree.
 
123
        """
 
124
        return tree.id2path(params.file_id)
 
125
 
 
126
    def merge_contents(self, params):
 
127
        """Merge the contents of a single file."""
 
128
        # Check whether this custom merge logic should be used.
 
129
        if (
 
130
            # OTHER is a straight winner, rely on default merge.
 
131
            params.winner == 'other' or
 
132
            # THIS and OTHER aren't both files.
 
133
            not params.is_file_merge() or
 
134
            # The filename doesn't match *.xml
 
135
            not self.file_matches(params)):
 
136
            return 'not_applicable', None
 
137
        return self.merge_matching(params)
 
138
 
 
139
    def merge_matching(self, params):
 
140
        """Merge the contents of a single file that has matched the criteria
 
141
        in PerFileMerger.merge_contents (is a conflict, is a file,
 
142
        self.file_matches is True).
 
143
 
 
144
        Subclasses must override this.
 
145
        """
 
146
        raise NotImplementedError(self.merge_matching)
 
147
 
 
148
 
 
149
class ConfigurableFileMerger(PerFileMerger):
97
150
    """Merge individual files when configured via a .conf file.
98
151
 
99
152
    This is a base class for concrete custom file merging logic. Concrete
122
175
        if self.name_prefix is None:
123
176
            raise ValueError("name_prefix must be set.")
124
177
 
125
 
    def filename_matches_config(self, params):
 
178
    def file_matches(self, params):
126
179
        """Check whether the file should call the merge hook.
127
180
 
128
181
        <name_prefix>_merge_files configuration variable is a list of files
142
195
                affected_files = self.default_files
143
196
            self.affected_files = affected_files
144
197
        if affected_files:
145
 
            filename = self.merger.this_tree.id2path(params.file_id)
146
 
            if filename in affected_files:
 
198
            filepath = self.get_filepath(params, self.merger.this_tree)
 
199
            if filepath in affected_files:
147
200
                return True
148
201
        return False
149
202
 
150
 
    def merge_contents(self, params):
151
 
        """Merge the contents of a single file."""
152
 
        # First, check whether this custom merge logic should be used.  We
153
 
        # expect most files should not be merged by this handler.
154
 
        if (
155
 
            # OTHER is a straight winner, rely on default merge.
156
 
            params.winner == 'other' or
157
 
            # THIS and OTHER aren't both files.
158
 
            not params.is_file_merge() or
159
 
            # The filename isn't listed in the 'NAME_merge_files' config
160
 
            # option.
161
 
            not self.filename_matches_config(params)):
162
 
            return 'not_applicable', None
 
203
    def merge_matching(self, params):
163
204
        return self.merge_text(params)
164
205
 
165
206
    def merge_text(self, params):
704
745
        :param this_tree: The local tree in the merge operation
705
746
        :param base_tree: The common tree in the merge operation
706
747
        :param other_tree: The other tree to merge changes from
707
 
        :param this_branch: The branch associated with this_tree
 
748
        :param this_branch: The branch associated with this_tree.  Defaults to
 
749
            this_tree.branch if not supplied.
708
750
        :param interesting_ids: The file_ids of files that should be
709
751
            participate in the merge.  May not be combined with
710
752
            interesting_files.
728
770
        if interesting_files is not None and interesting_ids is not None:
729
771
            raise ValueError(
730
772
                'specify either interesting_ids or interesting_files')
 
773
        if this_branch is None:
 
774
            this_branch = this_tree.branch
731
775
        self.interesting_ids = interesting_ids
732
776
        self.interesting_files = interesting_files
733
777
        self.this_tree = working_tree