/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/merge.py

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
import warnings
18
18
 
 
19
from bzrlib.lazy_import import lazy_import
 
20
lazy_import(globals(), """
19
21
from bzrlib import (
20
22
    branch as _mod_branch,
21
23
    conflicts as _mod_conflicts,
22
24
    debug,
23
 
    decorators,
24
25
    errors,
25
26
    graph as _mod_graph,
26
 
    hooks,
27
27
    merge3,
28
28
    osutils,
29
29
    patiencediff,
34
34
    tree as _mod_tree,
35
35
    tsort,
36
36
    ui,
37
 
    versionedfile
 
37
    versionedfile,
38
38
    )
39
39
from bzrlib.cleanup import OperationWithCleanups
 
40
""")
 
41
from bzrlib import (
 
42
    decorators,
 
43
    hooks,
 
44
    )
40
45
from bzrlib.symbol_versioning import (
41
46
    deprecated_in,
42
47
    deprecated_method,
93
98
        return ('not applicable', None)
94
99
 
95
100
 
96
 
class ConfigurableFileMerger(AbstractPerFileMerger):
 
101
class PerFileMerger(AbstractPerFileMerger):
 
102
    """Merge individual files when self.file_matches returns True.
 
103
 
 
104
    This class is intended to be subclassed.  The file_matches and
 
105
    merge_matching methods should be overridden with concrete implementations.
 
106
    """
 
107
 
 
108
    def file_matches(self, params):
 
109
        """Return True if merge_matching should be called on this file.
 
110
 
 
111
        Only called with merges of plain files with no clear winner.
 
112
 
 
113
        Subclasses must override this.
 
114
        """
 
115
        raise NotImplementedError(self.file_matches)
 
116
 
 
117
    def get_filename(self, params, tree):
 
118
        """Lookup the filename (i.e. basename, not path), given a Tree (e.g.
 
119
        self.merger.this_tree) and a MergeHookParams.
 
120
        """
 
121
        return osutils.basename(tree.id2path(params.file_id))
 
122
 
 
123
    def get_filepath(self, params, tree):
 
124
        """Calculate the path to the file in a tree.
 
125
 
 
126
        :param params: A MergeHookParams describing the file to merge
 
127
        :param tree: a Tree, e.g. self.merger.this_tree.
 
128
        """
 
129
        return tree.id2path(params.file_id)
 
130
 
 
131
    def merge_contents(self, params):
 
132
        """Merge the contents of a single file."""
 
133
        # Check whether this custom merge logic should be used.
 
134
        if (
 
135
            # OTHER is a straight winner, rely on default merge.
 
136
            params.winner == 'other' or
 
137
            # THIS and OTHER aren't both files.
 
138
            not params.is_file_merge() or
 
139
            # The filename doesn't match *.xml
 
140
            not self.file_matches(params)):
 
141
            return 'not_applicable', None
 
142
        return self.merge_matching(params)
 
143
 
 
144
    def merge_matching(self, params):
 
145
        """Merge the contents of a single file that has matched the criteria
 
146
        in PerFileMerger.merge_contents (is a conflict, is a file,
 
147
        self.file_matches is True).
 
148
 
 
149
        Subclasses must override this.
 
150
        """
 
151
        raise NotImplementedError(self.merge_matching)
 
152
 
 
153
 
 
154
class ConfigurableFileMerger(PerFileMerger):
97
155
    """Merge individual files when configured via a .conf file.
98
156
 
99
157
    This is a base class for concrete custom file merging logic. Concrete
122
180
        if self.name_prefix is None:
123
181
            raise ValueError("name_prefix must be set.")
124
182
 
125
 
    def filename_matches_config(self, params):
 
183
    def file_matches(self, params):
126
184
        """Check whether the file should call the merge hook.
127
185
 
128
186
        <name_prefix>_merge_files configuration variable is a list of files
142
200
                affected_files = self.default_files
143
201
            self.affected_files = affected_files
144
202
        if affected_files:
145
 
            filename = self.merger.this_tree.id2path(params.file_id)
146
 
            if filename in affected_files:
 
203
            filepath = self.get_filepath(params, self.merger.this_tree)
 
204
            if filepath in affected_files:
147
205
                return True
148
206
        return False
149
207
 
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
 
208
    def merge_matching(self, params):
163
209
        return self.merge_text(params)
164
210
 
165
211
    def merge_text(self, params):
704
750
        :param this_tree: The local tree in the merge operation
705
751
        :param base_tree: The common tree in the merge operation
706
752
        :param other_tree: The other tree to merge changes from
707
 
        :param this_branch: The branch associated with this_tree
 
753
        :param this_branch: The branch associated with this_tree.  Defaults to
 
754
            this_tree.branch if not supplied.
708
755
        :param interesting_ids: The file_ids of files that should be
709
756
            participate in the merge.  May not be combined with
710
757
            interesting_files.
728
775
        if interesting_files is not None and interesting_ids is not None:
729
776
            raise ValueError(
730
777
                'specify either interesting_ids or interesting_files')
 
778
        if this_branch is None:
 
779
            this_branch = this_tree.branch
731
780
        self.interesting_ids = interesting_ids
732
781
        self.interesting_files = interesting_files
733
782
        self.this_tree = working_tree
1411
1460
    def get_lines(self, tree, file_id):
1412
1461
        """Return the lines in a file, or an empty list."""
1413
1462
        if tree.has_id(file_id):
1414
 
            return tree.get_file(file_id).readlines()
 
1463
            return tree.get_file_lines(file_id)
1415
1464
        else:
1416
1465
            return []
1417
1466