~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/merge.py

Move handling of winner==OTHER case into generic hook path too.

Show diffs side-by-side

added added

removed removed

Lines of Context:
83
83
        params.merger.get_lines(params.merger.this_tree, params.file_id)
84
84
    """
85
85
 
86
 
    def __init__(self, merger, file_id, trans_id, this_pair, other_pair):
 
86
    def __init__(self, merger, file_id, trans_id, this_pair, other_pair,
 
87
            winner):
87
88
        self.merger = merger
88
89
        self.file_id = file_id
89
90
        self.trans_id = trans_id
90
91
        self.this_pair = this_pair
91
92
        self.other_pair = other_pair
 
93
        self.winner = winner
92
94
        
93
95
    def is_file_merge(self):
94
96
        return self.this_pair[0] == 'file' and self.other_pair[0] == 'file'
1202
1204
        if winner == 'this':
1203
1205
            # No interesting changes introduced by OTHER
1204
1206
            return "unmodified"
1205
 
        trans_id = self.tt.trans_id_file_id(file_id)
1206
 
        if winner == 'other':
1207
 
            # OTHER is a straight winner, so replace this contents with other
1208
 
            file_in_this = file_id in self.this_tree
1209
 
            if file_in_this:
1210
 
                # Remove any existing contents
1211
 
                self.tt.delete_contents(trans_id)
1212
 
            if file_id in self.other_tree:
1213
 
                # OTHER changed the file
1214
 
                wt = self.this_tree
1215
 
                if wt.supports_content_filtering():
1216
 
                    # We get the path from the working tree if it exists.
1217
 
                    # That fails though when OTHER is adding a file, so
1218
 
                    # we fall back to the other tree to find the path if
1219
 
                    # it doesn't exist locally.
1220
 
                    try:
1221
 
                        filter_tree_path = wt.id2path(file_id)
1222
 
                    except errors.NoSuchId:
1223
 
                        filter_tree_path = self.other_tree.id2path(file_id)
1224
 
                else:
1225
 
                    # Skip the id2path lookup for older formats
1226
 
                    filter_tree_path = None
1227
 
                transform.create_from_tree(self.tt, trans_id,
1228
 
                                 self.other_tree, file_id,
1229
 
                                 filter_tree_path=filter_tree_path)
1230
 
                if not file_in_this:
1231
 
                    self.tt.version_file(file_id, trans_id)
1232
 
                return "modified"
1233
 
            elif file_in_this:
1234
 
                # OTHER deleted the file
1235
 
                self.tt.unversion_file(trans_id)
1236
 
                return "deleted"
1237
1207
        # We have a hypothetical conflict, but if we have files, then we
1238
1208
        # can try to merge the content
 
1209
        trans_id = self.tt.trans_id_file_id(file_id)
 
1210
        params = MergeHookParams(self, file_id, trans_id, this_pair,
 
1211
            other_pair, winner)
1239
1212
        hooks = Merger.hooks['merge_file_content']
1240
1213
        hooks = list(hooks) + [self.default_text_merge]
1241
 
        params = MergeHookParams(self, file_id, trans_id, this_pair,
1242
 
            other_pair)
1243
1214
        hook_status = 'not_applicable'
1244
1215
        for hook in hooks:
1245
1216
            hook_status, lines = hook(params)
1283
1254
            pass
1284
1255
        return "modified"
1285
1256
 
 
1257
    def _default_other_winner_merge(self, merge_hook_params):
 
1258
        """Replace this contents with other."""
 
1259
        file_id = merge_hook_params.file_id
 
1260
        trans_id = merge_hook_params.trans_id
 
1261
        file_in_this = file_id in self.this_tree
 
1262
        if file_id in self.other_tree:
 
1263
            # OTHER changed the file
 
1264
            wt = self.this_tree
 
1265
            if wt.supports_content_filtering():
 
1266
                # We get the path from the working tree if it exists.
 
1267
                # That fails though when OTHER is adding a file, so
 
1268
                # we fall back to the other tree to find the path if
 
1269
                # it doesn't exist locally.
 
1270
                try:
 
1271
                    filter_tree_path = wt.id2path(file_id)
 
1272
                except errors.NoSuchId:
 
1273
                    filter_tree_path = self.other_tree.id2path(file_id)
 
1274
            else:
 
1275
                # Skip the id2path lookup for older formats
 
1276
                filter_tree_path = None
 
1277
            transform.create_from_tree(self.tt, trans_id,
 
1278
                             self.other_tree, file_id,
 
1279
                             filter_tree_path=filter_tree_path)
 
1280
            return 'done', None
 
1281
        elif file_in_this:
 
1282
            # OTHER deleted the file
 
1283
            return 'delete', None
 
1284
        else:
 
1285
            raise AssertionError(
 
1286
                'winner is OTHER, but file_id %r not in THIS or OTHER tree'
 
1287
                % (file_id,))
 
1288
 
1286
1289
    def default_text_merge(self, merge_hook_params):
1287
 
        if merge_hook_params.is_file_merge():
 
1290
        if merge_hook_params.winner == 'other':
 
1291
            # OTHER is a straight winner, so replace this contents with other
 
1292
            return self._default_other_winner_merge(merge_hook_params)
 
1293
        elif merge_hook_params.is_file_merge():
1288
1294
            # THIS and OTHER are both files, so text merge.  Either
1289
1295
            # BASE is a file, or both converted to files, so at least we
1290
1296
            # have agreement that output should be a file.
1293
1299
                    merge_hook_params.trans_id)
1294
1300
            except errors.BinaryFile:
1295
1301
                return 'not_applicable', None
 
1302
            return 'done', None
1296
1303
        else:
1297
1304
            return 'not_applicable', None
1298
 
        return 'done', None
1299
1305
 
1300
1306
    def get_lines(self, tree, file_id):
1301
1307
        """Return the lines in a file, or an empty list."""