1116
:return: A MemoryTree which is already write-locked, and an unlock has
1117
:return: A BranchBuilder
1119
tree = self.make_branch_and_memory_tree('tree')
1121
self.addCleanup(tree.unlock)
1123
tree.commit('A', rev_id='A-id')
1124
tree.commit('C', rev_id='C-id')
1125
tree.set_parent_ids(['A-id'])
1126
tree.branch.set_last_revision_info(1, 'A-id')
1127
tree.commit('B', rev_id='B-id')
1119
builder = self.make_branch_builder('path')
1120
builder.build_snapshot('A-id', None,
1121
[('add', ('', None, 'directory', None))])
1122
builder.build_snapshot('C-id', ['A-id'], [])
1123
builder.build_snapshot('B-id', ['A-id'], [])
1130
1126
def setup_criss_cross_graph(self):
1131
1127
"""Create a 5-node graph with a criss-cross.
1137
:return: A write locked Memory Tree
1133
:return: A BranchBuilder
1139
tree = self.setup_simple_graph()
1140
tree.branch.set_last_revision_info(2, 'C-id')
1141
tree.set_parent_ids(['C-id', 'B-id'])
1142
tree.commit('E', rev_id='E-id')
1143
tree.set_parent_ids(['B-id', 'C-id'])
1144
tree.branch.set_last_revision_info(2, 'B-id')
1145
tree.commit('D', rev_id='D-id')
1135
builder = self.setup_simple_graph()
1136
builder.build_snapshot('E-id', ['C-id', 'B-id'], [])
1137
builder.build_snapshot('D-id', ['B-id', 'C-id'], [])
1140
def make_merger(self, builder, other_revision_id):
1141
"""Make a Merger object from a branch builder"""
1142
mem_tree = memorytree.MemoryTree.create_on_branch(builder.get_branch())
1143
mem_tree.lock_write()
1144
self.addCleanup(mem_tree.unlock)
1145
return _mod_merge.Merger.from_revision_ids(progress.DummyProgress(),
1146
mem_tree, other_revision_id)
1148
1148
def test_find_base(self):
1149
tree = self.setup_simple_graph()
1150
merger = _mod_merge.Merger.from_revision_ids(progress.DummyProgress(),
1149
merger = self.make_merger(self.setup_simple_graph(), 'C-id')
1152
1150
self.assertEqual('A-id', merger.base_rev_id)
1153
1151
self.assertFalse(merger._is_criss_cross)
1154
1152
self.assertIs(None, merger._lca_trees)
1157
1154
def test_find_base_criss_cross(self):
1158
tree = self.setup_criss_cross_graph()
1159
merger = _mod_merge.Merger.from_revision_ids(progress.DummyProgress(),
1155
merger = self.make_merger(self.setup_criss_cross_graph(), 'E-id')
1161
1156
self.assertEqual('A-id', merger.base_rev_id)
1162
1157
self.assertTrue(merger._is_criss_cross)
1163
1158
self.assertEqual(['B-id', 'C-id'], sorted(merger._lca_trees.keys()))
1166
1161
class LCATreesMerger(LoggingMerger):
1167
1162
supports_lca_trees = True
1169
tree = self.setup_simple_graph()
1170
merger = _mod_merge.Merger.from_revision_ids(progress.DummyProgress(),
1164
merger = self.make_merger(self.setup_simple_graph(), 'C-id')
1172
1165
merger.merge_type = LCATreesMerger
1173
1166
merge_obj = merger.make_merger()
1174
1167
self.assertIsInstance(merge_obj, LCATreesMerger)
1175
1168
self.assertFalse('lca_trees' in merge_obj.kwargs)
1177
1170
def test_criss_cross_passed_to_merge_type(self):
1178
tree = self.setup_criss_cross_graph()
1179
merger = _mod_merge.Merger.from_revision_ids(progress.DummyProgress(),
1171
merger = self.make_merger(self.setup_criss_cross_graph(), 'E-id')
1181
1172
merger.merge_type = _mod_merge.Merge3Merger
1182
1173
merge_obj = merger.make_merger()
1183
1174
self.assertEqual(['B-id', 'C-id'], sorted(merge_obj._lca_trees.keys()))
1199
1188
class UnsupportedLCATreesMerger(LoggingMerger):
1200
1189
supports_lca_trees = False
1202
tree = self.setup_criss_cross_graph()
1203
merger = _mod_merge.Merger.from_revision_ids(progress.DummyProgress(),
1191
merger = self.make_merger(self.setup_criss_cross_graph(), 'E-id')
1205
1192
merger.merge_type = UnsupportedLCATreesMerger
1206
1193
merge_obj = merger.make_merger()
1207
1194
self.assertIsInstance(merge_obj, UnsupportedLCATreesMerger)
1208
1195
self.assertFalse('lca_trees' in merge_obj.kwargs)
1210
1197
def test__entries_lca_simple(self):
1211
tree = self.make_branch_and_memory_tree('tree')
1213
self.addCleanup(tree.unlock)
1215
tree.add(['a'], ['a-id'], ['file'])
1216
tree.put_file_bytes_non_atomic('a-id', 'a\nb\nc\n')
1217
tree.commit('A', rev_id='A-id')
1218
tree.put_file_bytes_non_atomic('a-id', 'a\nb\nC\nc\n')
1219
tree.commit('C', rev_id='C-id')
1220
tree.branch.set_last_revision_info(1, 'A-id')
1221
tree.set_parent_ids(['A-id'])
1222
tree.put_file_bytes_non_atomic('a-id', 'a\nB\nb\nc\n')
1223
tree.commit('B', rev_id='B-id')
1224
tree.set_parent_ids(['B-id', 'C-id'])
1225
tree.put_file_bytes_non_atomic('a-id', 'a\nB\nb\nC\nc\n')
1226
tree.commit('D', rev_id='D-id')
1227
tree.branch.set_last_revision_info(2, 'C-id')
1228
tree.set_parent_ids(['C-id', 'B-id'])
1229
tree.put_file_bytes_non_atomic('a-id', 'a\nB\nb\nC\nc\nE\n')
1230
tree.commit('E', rev_id='E-id')
1231
tree.branch.set_last_revision_info(2, 'D-id')
1232
tree.set_parent_ids(['D-id'])
1234
merger = _mod_merge.Merger.from_revision_ids(progress.DummyProgress(),
1198
builder = self.make_branch_builder('tree')
1199
builder.build_snapshot('A-id', None,
1200
[('add', (u'', 'a-root-id', 'directory', None)),
1201
('add', (u'a', 'a-id', 'file', 'a\nb\nc\n'))])
1202
builder.build_snapshot('C-id', ['A-id'],
1203
[('modify', ('a-id', 'a\nb\nC\nc\n'))])
1204
builder.build_snapshot('B-id', ['A-id'],
1205
[('modify', ('a-id', 'a\nB\nb\nc\n'))])
1206
builder.build_snapshot('E-id', ['C-id', 'B-id'],
1207
[('modify', ('a-id', 'a\nB\nb\nC\nc\nE\n'))])
1208
builder.build_snapshot('D-id', ['B-id', 'C-id'],
1209
[('modify', ('a-id', 'a\nB\nb\nC\nc\n'))])
1210
merger = self.make_merger(builder, 'E-id')
1236
1211
merger.merge_type = _mod_merge.Merge3Merger
1237
1212
merge_obj = merger.make_merger()
1239
1214
entries = list(merge_obj._entries_lca())
1240
root_id = tree.path2id('')
1241
1215
self.assertEqual(['B-id', 'C-id'], sorted(merge_obj._lca_trees.keys()))
1243
1217
# (file_id, changed, parents, names, executable)
1244
1218
# BASE, lca1, lca2, OTHER, THIS
1219
root_id = 'a-root-id'
1245
1220
self.assertEqual([(root_id, True,
1246
1221
((None, [None, None]), None, None),
1247
1222
((u'', [u'', u'']), u'', u''),