1229
1234
# OTHER deleted the file
1230
1235
self.tt.unversion_file(trans_id)
1231
1236
return "deleted"
1233
hooks = Merger.hooks['merge_file_content']
1234
params = MergeHookParams(self, file_id, trans_id)
1237
hook_status, lines = hook(params)
1238
if hook_status == 'not_applicable':
1240
elif hook_status == 'success':
1241
self.tt.create_file(lines, trans_id)
1242
elif hook_status == 'conflicted':
1243
# XXX: perhaps the hook should be able to provide
1244
# the BASE/THIS/OTHER files?
1245
self.tt.create_file(lines, trans_id)
1246
self._raw_conflicts.append(('text conflict', trans_id))
1247
name = self.tt.final_name(trans_id)
1248
parent_id = self.tt.final_parent(trans_id)
1249
file_group = self._dump_conflicts(name, parent_id, file_id)
1250
file_group.append(trans_id)
1251
elif hook_status == 'delete':
1252
self.tt.unversion_file(trans_id)
1253
if file_id in self.this_tree:
1254
self.tt.delete_contents(trans_id)
1257
raise AssertionError(
1258
'unknown hook_status: %r' % (hook_status,))
1259
# This hook function applied, so don't try any other
1237
# We have a hypothetical conflict, but if we have files, then we
1238
# can try to merge the content
1239
hooks = Merger.hooks['merge_file_content']
1240
hooks = list(hooks) + [self.default_text_merge]
1241
params = MergeHookParams(self, file_id, trans_id, this_pair,
1243
hook_status = 'not_applicable'
1245
hook_status, lines = hook(params)
1246
if hook_status != 'not_applicable':
1247
# Don't try any more hooks, this one applies.
1263
# We have a hypothetical conflict, but if we have files, then we
1264
# can try to merge the content
1265
if (this_pair[0] == 'file' and other_pair[0] == 'file') or hook_ran:
1266
# THIS and OTHER are both files, so text merge. Either
1267
# BASE is a file, or both converted to files, so at least we
1268
# have agreement that output should be a file.
1271
# if no hook functions applied, do the default merge.
1272
self.text_merge(file_id, trans_id)
1273
except errors.BinaryFile:
1274
return contents_conflict()
1275
if file_id not in self.this_tree:
1276
self.tt.version_file(file_id, trans_id)
1278
self.tt.tree_kind(trans_id)
1279
self.tt.delete_contents(trans_id)
1280
except errors.NoSuchFile:
1284
return contents_conflict()
1249
if hook_status == 'not_applicable':
1250
# No function to merge the file's contents was found, so this must
1251
# be a contents conflict.
1254
elif hook_status == 'success':
1255
self.tt.create_file(lines, trans_id)
1256
elif hook_status == 'conflicted':
1257
# XXX: perhaps the hook should be able to provide
1258
# the BASE/THIS/OTHER files?
1259
self.tt.create_file(lines, trans_id)
1260
self._raw_conflicts.append(('text conflict', trans_id))
1261
name = self.tt.final_name(trans_id)
1262
parent_id = self.tt.final_parent(trans_id)
1263
file_group = self._dump_conflicts(name, parent_id, file_id)
1264
file_group.append(trans_id)
1265
elif hook_status == 'delete':
1266
self.tt.unversion_file(trans_id)
1267
if file_id in self.this_tree:
1268
self.tt.delete_contents(trans_id)
1270
elif hook_status == 'done':
1271
# The hook function did whatever it needs to do directly, no
1272
# further action needed here.
1275
raise AssertionError(
1276
'unknown hook_status: %r' % (hook_status,))
1277
if file_id not in self.this_tree:
1278
self.tt.version_file(file_id, trans_id)
1280
self.tt.tree_kind(trans_id)
1281
self.tt.delete_contents(trans_id)
1282
except errors.NoSuchFile:
1286
def default_text_merge(self, merge_hook_params):
1287
if merge_hook_params.is_file_merge():
1288
# THIS and OTHER are both files, so text merge. Either
1289
# BASE is a file, or both converted to files, so at least we
1290
# have agreement that output should be a file.
1292
self.text_merge(merge_hook_params.file_id,
1293
merge_hook_params.trans_id)
1294
except errors.BinaryFile:
1295
return 'not_applicable', None
1297
return 'not_applicable', None
1286
1300
def get_lines(self, tree, file_id):
1287
1301
"""Return the lines in a file, or an empty list."""