19
19
from bzrlib import (
24
from bzrlib.tests.per_branch import TestCaseWithBranch
27
class TestIterMergeSortedRevisions(TestCaseWithBranch):
25
from bzrlib.tests import per_branch
28
class TestIterMergeSortedRevisionsSimpleGraph(per_branch.TestCaseWithBranch):
31
super(TestIterMergeSortedRevisionsSimpleGraph, self).setUp()
32
builder = self.make_builder_with_merges('.')
33
self.branch = builder.get_branch()
34
self.branch.lock_read()
35
self.addCleanup(self.branch.unlock)
37
def make_builder_with_merges(self, relpath):
39
builder = self.make_branch_builder(relpath)
40
except (errors.TransportNotPossible, errors.UninitializableFormat):
41
raise tests.TestNotApplicable('format not directly constructable')
42
builder.start_series()
50
builder.build_snapshot('1', None, [
51
('add', ('', 'TREE_ROOT', 'directory', '')),])
52
builder.build_snapshot('1.1.1', ['1'], [])
53
builder.build_snapshot('2', ['1'], [])
54
builder.build_snapshot('3', ['2', '1.1.1'], [])
55
builder.finish_series()
58
def assertIterRevids(self, expected, *args, **kwargs):
59
# We don't care about depths and revnos here, only about returning the
61
revids = [revid for (revid, depth, revno, eom) in
62
self.branch.iter_merge_sorted_revisions(*args, **kwargs)]
63
self.assertEqual(expected, revids)
29
65
def test_merge_sorted(self):
30
tree = self.create_tree_with_merge()
31
the_branch = tree.bzrdir.open_branch()
33
('rev-3', 0, (3,), False),
34
('rev-1.1.1', 1, (1,1,1), True),
35
('rev-2', 0, (2,), False),
36
('rev-1', 0, (1,), True),
37
], list(the_branch.iter_merge_sorted_revisions()))
66
self.assertIterRevids(['3', '1.1.1', '2', '1'])
39
68
def test_merge_sorted_range(self):
40
tree = self.create_tree_with_merge()
41
the_branch = tree.bzrdir.open_branch()
43
('rev-1.1.1', 1, (1,1,1), True),
44
('rev-2', 0, (2,), False),
45
], list(the_branch.iter_merge_sorted_revisions(
46
start_revision_id='rev-1.1.1', stop_revision_id='rev-1')))
69
self.assertIterRevids(['1.1.1'],
70
start_revision_id='1.1.1', stop_revision_id='1')
48
72
def test_merge_sorted_range_start_only(self):
49
tree = self.create_tree_with_merge()
50
the_branch = tree.bzrdir.open_branch()
52
('rev-1.1.1', 1, (1,1,1), True),
53
('rev-2', 0, (2,), False),
54
('rev-1', 0, (1,), True),
55
], list(the_branch.iter_merge_sorted_revisions(
56
start_revision_id='rev-1.1.1')))
73
self.assertIterRevids(['1.1.1', '1'],
74
start_revision_id='1.1.1')
58
76
def test_merge_sorted_range_stop_exclude(self):
59
tree = self.create_tree_with_merge()
60
the_branch = tree.bzrdir.open_branch()
62
('rev-3', 0, (3,), False),
63
('rev-1.1.1', 1, (1,1,1), True),
64
('rev-2', 0, (2,), False),
65
], list(the_branch.iter_merge_sorted_revisions(
66
stop_revision_id='rev-1')))
77
self.assertIterRevids(['3', '1.1.1', '2'], stop_revision_id='1')
68
79
def test_merge_sorted_range_stop_include(self):
69
tree = self.create_tree_with_merge()
70
the_branch = tree.bzrdir.open_branch()
72
('rev-3', 0, (3,), False),
73
('rev-1.1.1', 1, (1,1,1), True),
74
('rev-2', 0, (2,), False),
75
], list(the_branch.iter_merge_sorted_revisions(
76
stop_revision_id='rev-2', stop_rule='include')))
80
self.assertIterRevids(['3', '1.1.1', '2'],
81
stop_revision_id='2', stop_rule='include')
78
83
def test_merge_sorted_range_stop_with_merges(self):
79
tree = self.create_tree_with_merge()
80
the_branch = tree.bzrdir.open_branch()
82
('rev-3', 0, (3,), False),
83
('rev-1.1.1', 1, (1,1,1), True),
84
], list(the_branch.iter_merge_sorted_revisions(
85
stop_revision_id='rev-3', stop_rule='with-merges')))
84
self.assertIterRevids(['3', '1.1.1'],
85
stop_revision_id='3', stop_rule='with-merges')
87
87
def test_merge_sorted_range_stop_with_merges_can_show_non_parents(self):
88
tree = self.create_tree_with_merge()
89
the_branch = tree.bzrdir.open_branch()
90
# rev-1.1.1 gets logged before the end revision is reached.
91
# so it is returned even though rev-1.1.1 is not a parent of rev-2.
93
('rev-3', 0, (3,), False),
94
('rev-1.1.1', 1, (1,1,1), True),
95
('rev-2', 0, (2,), False),
96
], list(the_branch.iter_merge_sorted_revisions(
97
stop_revision_id='rev-2', stop_rule='with-merges')))
88
# 1.1.1 gets logged before the end revision is reached.
89
# so it is returned even though 1.1.1 is not a parent of 2.
90
self.assertIterRevids(['3', '1.1.1', '2'],
91
stop_revision_id='2', stop_rule='with-merges')
99
93
def test_merge_sorted_range_stop_with_merges_ignore_non_parents(self):
100
tree = self.create_tree_with_merge()
101
the_branch = tree.bzrdir.open_branch()
102
# rev-2 is not a parent of rev-1.1.1 so it must not be returned
104
('rev-3', 0, (3,), False),
105
('rev-1.1.1', 1, (1,1,1), True),
106
], list(the_branch.iter_merge_sorted_revisions(
107
stop_revision_id='rev-1.1.1', stop_rule='with-merges')))
94
# 2 is not a parent of 1.1.1 so it must not be returned
95
self.assertIterRevids(['3', '1.1.1'],
96
stop_revision_id='1.1.1', stop_rule='with-merges')
109
98
def test_merge_sorted_single_stop_exclude(self):
110
99
# from X..X exclusive is an empty result
111
tree = self.create_tree_with_merge()
112
the_branch = tree.bzrdir.open_branch()
113
self.assertEqual([], list(the_branch.iter_merge_sorted_revisions(
114
start_revision_id='rev-3', stop_revision_id='rev-3')))
100
self.assertIterRevids([], start_revision_id='3', stop_revision_id='3')
116
102
def test_merge_sorted_single_stop_include(self):
117
103
# from X..X inclusive is [X]
118
tree = self.create_tree_with_merge()
119
the_branch = tree.bzrdir.open_branch()
121
('rev-3', 0, (3,), False),
122
], list(the_branch.iter_merge_sorted_revisions(
123
start_revision_id='rev-3', stop_revision_id='rev-3',
124
stop_rule='include')))
104
self.assertIterRevids(['3'],
105
start_revision_id='3', stop_revision_id='3',
126
108
def test_merge_sorted_single_stop_with_merges(self):
127
tree = self.create_tree_with_merge()
128
the_branch = tree.bzrdir.open_branch()
130
('rev-3', 0, (3,), False),
131
('rev-1.1.1', 1, (1,1,1), True),
132
], list(the_branch.iter_merge_sorted_revisions(
133
start_revision_id='rev-3', stop_revision_id='rev-3',
134
stop_rule='with-merges')))
109
self.assertIterRevids(['3', '1.1.1'],
110
start_revision_id='3', stop_revision_id='3',
111
stop_rule='with-merges')
136
113
def test_merge_sorted_forward(self):
137
tree = self.create_tree_with_merge()
138
the_branch = tree.bzrdir.open_branch()
140
('rev-1', 0, (1,), True),
141
('rev-2', 0, (2,), False),
142
('rev-1.1.1', 1, (1,1,1), True),
143
('rev-3', 0, (3,), False),
144
], list(the_branch.iter_merge_sorted_revisions(
145
direction='forward')))
114
self.assertIterRevids(['1', '2', '1.1.1', '3'], direction='forward')
147
116
def test_merge_sorted_range_forward(self):
148
tree = self.create_tree_with_merge()
149
the_branch = tree.bzrdir.open_branch()
151
('rev-2', 0, (2,), False),
152
('rev-1.1.1', 1, (1,1,1), True),
153
], list(the_branch.iter_merge_sorted_revisions(
154
start_revision_id='rev-1.1.1', stop_revision_id='rev-1',
155
direction='forward')))
117
self.assertIterRevids(['1.1.1'],
118
start_revision_id='1.1.1', stop_revision_id='1',
157
121
def test_merge_sorted_range_start_only_forward(self):
158
tree = self.create_tree_with_merge()
159
the_branch = tree.bzrdir.open_branch()
161
('rev-1', 0, (1,), True),
162
('rev-2', 0, (2,), False),
163
('rev-1.1.1', 1, (1,1,1), True),
164
], list(the_branch.iter_merge_sorted_revisions(
165
start_revision_id='rev-1.1.1', direction='forward')))
122
self.assertIterRevids(['1', '1.1.1'],
123
start_revision_id='1.1.1', direction='forward')
167
125
def test_merge_sorted_range_stop_exclude_forward(self):
168
tree = self.create_tree_with_merge()
169
the_branch = tree.bzrdir.open_branch()
171
('rev-2', 0, (2,), False),
172
('rev-1.1.1', 1, (1,1,1), True),
173
('rev-3', 0, (3,), False),
174
], list(the_branch.iter_merge_sorted_revisions(
175
stop_revision_id='rev-1', direction='forward')))
126
self.assertIterRevids(['2', '1.1.1', '3'],
127
stop_revision_id='1', direction='forward')
177
129
def test_merge_sorted_range_stop_include_forward(self):
178
tree = self.create_tree_with_merge()
179
the_branch = tree.bzrdir.open_branch()
181
('rev-2', 0, (2,), False),
182
('rev-1.1.1', 1, (1,1,1), True),
183
('rev-3', 0, (3,), False),
184
], list(the_branch.iter_merge_sorted_revisions(
185
stop_revision_id='rev-2', stop_rule='include',
186
direction='forward')))
130
self.assertIterRevids(['2', '1.1.1', '3'],
131
stop_revision_id='2', stop_rule='include',
188
134
def test_merge_sorted_range_stop_with_merges_forward(self):
189
tree = self.create_tree_with_merge()
190
the_branch = tree.bzrdir.open_branch()
192
('rev-1.1.1', 1, (1,1,1), True),
193
('rev-3', 0, (3,), False),
194
], list(the_branch.iter_merge_sorted_revisions(
195
stop_revision_id='rev-3', stop_rule='with-merges',
196
direction='forward')))
135
self.assertIterRevids(['1.1.1', '3'],
136
stop_revision_id='3', stop_rule='with-merges',
140
class TestIterMergeSortedRevisionsBushyGraph(per_branch.TestCaseWithBranch):
142
def make_branch_builder(self, relpath):
144
builder = super(TestIterMergeSortedRevisionsBushyGraph,
145
self).make_branch_builder(relpath)
146
except (errors.TransportNotPossible, errors.UninitializableFormat):
147
raise tests.TestNotApplicable('format not directly constructable')
150
def make_branch_with_embedded_merges(self, relpath='.'):
151
builder = self.make_branch_builder(relpath)
169
builder.start_series()
170
builder.build_snapshot('1', None, [
171
('add', ('', 'TREE_ROOT', 'directory', '')),])
172
builder.build_snapshot('1.1.1', ['1'], [])
173
builder.build_snapshot('2', ['1', '1.1.1'], [])
174
builder.build_snapshot('2.1.1', ['2'], [])
175
builder.build_snapshot('2.1.2', ['2.1.1'], [])
176
builder.build_snapshot('2.2.1', ['2.1.1'], [])
177
builder.build_snapshot('2.1.3', ['2.1.2', '2.2.1'], [])
178
builder.build_snapshot('3', ['2'], [])
179
builder.build_snapshot('4', ['3', '2.1.3'], [])
180
builder.finish_series()
181
br = builder.get_branch()
183
self.addCleanup(br.unlock)
186
def make_branch_with_different_depths_merges(self, relpath='.'):
187
builder = self.make_branch_builder(relpath)
205
builder.start_series()
206
builder.build_snapshot('1', None, [
207
('add', ('', 'TREE_ROOT', 'directory', '')),])
208
builder.build_snapshot('2', ['1'], [])
209
builder.build_snapshot('1.1.1', ['1'], [])
210
builder.build_snapshot('1.1.2', ['1.1.1'], [])
211
builder.build_snapshot('1.2.1', ['1.1.1'], [])
212
builder.build_snapshot('1.2.2', ['1.2.1'], [])
213
builder.build_snapshot('1.3.1', ['1.2.1'], [])
214
builder.build_snapshot('1.3.2', ['1.3.1'], [])
215
builder.build_snapshot('1.4.1', ['1.3.1'], [])
216
builder.build_snapshot('1.3.3', ['1.3.2', '1.4.11'], [])
217
builder.build_snapshot('1.2.3', ['1.2.2', '1.3.3'], [])
218
builder.build_snapshot('2.1.1', ['2'], [])
219
builder.build_snapshot('2.1.2', ['2.1.1'], [])
220
builder.build_snapshot('2.2.1', ['2.1.1'], [])
221
builder.build_snapshot('2.1.3', ['2.1.2', '2.2.1'], [])
222
builder.build_snapshot('3', ['2', '1.2.3'], [])
223
# .. to bring them all and ... bind them
224
builder.build_snapshot('4', ['3', '2.1.3'],
226
builder.finish_series()
227
br = builder.get_branch()
229
self.addCleanup(br.unlock)
232
def assertIterRevids(self, expected, branch, *args, **kwargs):
233
# We don't care about depths and revnos here, only about returning the
235
revs = list(branch.iter_merge_sorted_revisions(*args, **kwargs))
236
revids = [revid for (revid, depth, revno, eom) in revs]
237
self.assertEqual(expected, revids)
239
def test_merge_sorted_starting_at_embedded_merge(self):
240
branch = self.make_branch_with_embedded_merges()
241
self.assertIterRevids(['4', '2.1.3', '2.2.1', '2.1.2', '2.1.1',
242
'3', '2', '1.1.1', '1'],
244
# 3 and 2.1.2 are not part of 2.2.1 ancestry and should not appear
245
self.assertIterRevids(['2.2.1', '2.1.1', '2', '1.1.1', '1'],
246
branch, start_revision_id='2.2.1',
247
stop_rule='with-merges')
249
def test_merge_sorted_with_different_depths_merge(self):
250
branch = self.make_branch_with_different_depths_merges()
251
self.assertIterRevids(['4', '2.1.3', '2.2.1', '2.1.2', '2.1.1',
253
'1.2.3', '1.3.3', '1.3.2', '1.3.1',
254
'1.2.2', '1.2.1', '1.1.1',
257
# 3 (and its descendants) and 2.1.2 are not part of 2.2.1 ancestry and
259
self.assertIterRevids(['2.2.1', '2.1.1', '2', '1'],
260
branch, start_revision_id='2.2.1',
261
stop_rule='with-merges')