/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/tests/test_annotate.py

  • Committer: John Arbash Meinel
  • Date: 2008-07-09 21:42:24 UTC
  • mto: This revision was merged to the branch mainline in revision 3543.
  • Revision ID: john@arbash-meinel.com-20080709214224-r75k87r6a01pfc3h
Restore a real weave merge to 'bzr merge --weave'.

To do so efficiently, we only add the simple LCAs to the final weave
object, unless we run into complexities with the merge graph.
This gives the same effective result as adding all the texts,
with the advantage of not having to extract all of them.

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
"""Whitebox tests for annotate functionality."""
18
18
 
116
116
#  |\
117
117
#  A B  # line should be annotated as new for A and B
118
118
#  |\|
119
 
#  C D  # line should 'converge' and say A
 
119
#  C D  # line should 'converge' and say D
120
120
#  |/
121
121
#  E    # D should supersede A and stay as D (not become E because C references
122
122
#         A)
150
150
 
151
151
duplicate_D = annotation("""\
152
152
rev-base first
153
 
rev-A alt-second
 
153
rev-D alt-second
154
154
rev-base third
155
155
rev-D fourth-D
156
156
""")
157
157
 
158
158
duplicate_E = annotation("""\
159
159
rev-base first
160
 
rev-A alt-second
 
160
rev-D alt-second
161
161
rev-base third
162
162
rev-E fourth-E
163
163
""")
176
176
         |
177
177
        rev-3
178
178
        """
179
 
        builder = self.make_branch_builder('branch')
180
 
        builder.start_series()
181
 
        self.addCleanup(builder.finish_series)
182
 
        builder.build_snapshot('rev-1', None, [
183
 
            ('add', ('', 'root-id', 'directory', None)),
184
 
            ('add', ('a', 'a-id', 'file', 'first\n')),
185
 
            ], timestamp=1166046000.00, timezone=0, committer="joe@foo.com")
186
 
        builder.build_snapshot('rev-2', ['rev-1'], [
187
 
            ('modify', ('a-id', 'first\nsecond\n')),
188
 
            ], timestamp=1166046001.00, timezone=0, committer="joe@foo.com")
189
 
        builder.build_snapshot('rev-1_1_1', ['rev-1'], [
190
 
            ('modify', ('a-id', 'first\nthird\n')),
191
 
            ], timestamp=1166046002.00, timezone=0, committer="barry@foo.com")
192
 
        builder.build_snapshot('rev-3', ['rev-2', 'rev-1_1_1'], [
193
 
            ('modify', ('a-id', 'first\nsecond\nthird\n')),
194
 
            ], timestamp=1166046003.00, timezone=0, committer="sal@foo.com")
195
 
        return builder
 
179
 
 
180
        tree1 = self.make_branch_and_tree('tree1')
 
181
        self.build_tree_contents([('tree1/a', 'first\n')])
 
182
        tree1.add(['a'], ['a-id'])
 
183
        tree1.commit('a', rev_id='rev-1',
 
184
                     committer="joe@foo.com",
 
185
                     timestamp=1166046000.00, timezone=0)
 
186
 
 
187
        tree2 = tree1.bzrdir.clone('tree2').open_workingtree()
 
188
 
 
189
        self.build_tree_contents([('tree1/a', 'first\nsecond\n')])
 
190
        tree1.commit('b', rev_id='rev-2',
 
191
                     committer='joe@foo.com',
 
192
                     timestamp=1166046001.00, timezone=0)
 
193
 
 
194
        self.build_tree_contents([('tree2/a', 'first\nthird\n')])
 
195
        tree2.commit('c', rev_id='rev-1_1_1',
 
196
                     committer="barry@foo.com",
 
197
                     timestamp=1166046002.00, timezone=0)
 
198
 
 
199
        num_conflicts = tree1.merge_from_branch(tree2.branch)
 
200
        self.assertEqual(1, num_conflicts)
 
201
 
 
202
        self.build_tree_contents([('tree1/a',
 
203
                                 'first\nsecond\nthird\n')])
 
204
        tree1.set_conflicts(conflicts.ConflictList())
 
205
        tree1.commit('merge 2', rev_id='rev-3',
 
206
                     committer='sal@foo.com',
 
207
                     timestamp=1166046003.00, timezone=0)
 
208
        tree1.lock_read()
 
209
        self.addCleanup(tree1.unlock)
 
210
        return tree1, tree2
196
211
 
197
212
    def create_deeply_merged_trees(self):
198
213
        """Create some trees with a more complex merge history.
217
232
         |
218
233
        rev-6
219
234
        """
220
 
        builder = self.create_merged_trees()
221
 
        builder.build_snapshot('rev-1_1_2', ['rev-1_1_1'], [])
222
 
        builder.build_snapshot('rev-4', ['rev-3', 'rev-1_1_2'], [])
223
 
        builder.build_snapshot('rev-1_2_1', ['rev-1_1_1'], [
224
 
            ('modify', ('a-id', 'first\nthird\nfourth\n')),
225
 
            ], timestamp=1166046003.00, timezone=0, committer="jerry@foo.com")
226
 
        builder.build_snapshot('rev-1_2_2', ['rev-1_2_1'], [],
227
 
            timestamp=1166046004.00, timezone=0, committer="jerry@foo.com")
228
 
        builder.build_snapshot('rev-5', ['rev-4', 'rev-1_2_2'], [
229
 
            ('modify', ('a-id', 'first\nsecond\nthird\nfourth\n')),
230
 
            ], timestamp=1166046004.00, timezone=0, committer="jerry@foo.com")
231
 
        builder.build_snapshot('rev-1_3_1', ['rev-1_2_1'], [
232
 
            ('modify', ('a-id', 'first\nthird\nfourth\nfifth\nsixth\n')),
233
 
            ], timestamp=1166046005.00, timezone=0, committer="george@foo.com")
234
 
        builder.build_snapshot('rev-6', ['rev-5', 'rev-1_3_1'], [
235
 
            ('modify', ('a-id',
236
 
                        'first\nsecond\nthird\nfourth\nfifth\nsixth\n')),
237
 
            ])
238
 
        return builder
 
235
        tree1, tree2 = self.create_merged_trees()
 
236
        tree1.unlock()
 
237
 
 
238
        tree3 = tree2.bzrdir.clone('tree3').open_workingtree()
 
239
 
 
240
        tree2.commit('noop', rev_id='rev-1_1_2')
 
241
        self.assertEqual(0, tree1.merge_from_branch(tree2.branch))
 
242
        tree1.commit('noop merge', rev_id='rev-4')
 
243
 
 
244
        self.build_tree_contents([('tree3/a', 'first\nthird\nfourth\n')])
 
245
        tree3.commit('four', rev_id='rev-1_2_1',
 
246
                     committer='jerry@foo.com',
 
247
                     timestamp=1166046003.00, timezone=0)
 
248
 
 
249
        tree4 = tree3.bzrdir.clone('tree4').open_workingtree()
 
250
 
 
251
        tree3.commit('noop', rev_id='rev-1_2_2',
 
252
                     committer='jerry@foo.com',
 
253
                     timestamp=1166046004.00, timezone=0)
 
254
        self.assertEqual(0, tree1.merge_from_branch(tree3.branch))
 
255
        tree1.commit('merge four', rev_id='rev-5')
 
256
 
 
257
        self.build_tree_contents([('tree4/a',
 
258
                                   'first\nthird\nfourth\nfifth\nsixth\n')])
 
259
        tree4.commit('five and six', rev_id='rev-1_3_1',
 
260
                     committer='george@foo.com',
 
261
                     timestamp=1166046005.00, timezone=0)
 
262
        self.assertEqual(0, tree1.merge_from_branch(tree4.branch))
 
263
        tree1.commit('merge five and six', rev_id='rev-6')
 
264
        tree1.lock_read()
 
265
        return tree1
239
266
 
240
267
    def create_duplicate_lines_tree(self):
241
 
        builder = self.make_branch_builder('branch')
242
 
        builder.start_series()
243
 
        self.addCleanup(builder.finish_series)
 
268
        tree1 = self.make_branch_and_tree('tree1')
244
269
        base_text = ''.join(l for r, l in duplicate_base)
245
270
        a_text = ''.join(l for r, l in duplicate_A)
246
271
        b_text = ''.join(l for r, l in duplicate_B)
247
272
        c_text = ''.join(l for r, l in duplicate_C)
248
273
        d_text = ''.join(l for r, l in duplicate_D)
249
274
        e_text = ''.join(l for r, l in duplicate_E)
250
 
        builder.build_snapshot('rev-base', None, [
251
 
            ('add', ('', 'root-id', 'directory', None)),
252
 
            ('add', ('file', 'file-id', 'file', base_text)),
253
 
            ])
254
 
        builder.build_snapshot('rev-A', ['rev-base'], [
255
 
            ('modify', ('file-id', a_text))])
256
 
        builder.build_snapshot('rev-B', ['rev-base'], [
257
 
            ('modify', ('file-id', b_text))])
258
 
        builder.build_snapshot('rev-C', ['rev-A'], [
259
 
            ('modify', ('file-id', c_text))])
260
 
        builder.build_snapshot('rev-D', ['rev-B', 'rev-A'], [
261
 
            ('modify', ('file-id', d_text))])
262
 
        builder.build_snapshot('rev-E', ['rev-C', 'rev-D'], [
263
 
            ('modify', ('file-id', e_text))])
264
 
        return builder
 
275
        self.build_tree_contents([('tree1/file', base_text)])
 
276
        tree1.add(['file'], ['file-id'])
 
277
        tree1.commit('base', rev_id='rev-base')
 
278
        tree2 = tree1.bzrdir.clone('tree2').open_workingtree()
 
279
 
 
280
        self.build_tree_contents([('tree1/file', a_text),
 
281
                                  ('tree2/file', b_text)])
 
282
        tree1.commit('A', rev_id='rev-A')
 
283
        tree2.commit('B', rev_id='rev-B')
 
284
 
 
285
        tree2.merge_from_branch(tree1.branch)
 
286
        conflicts.resolve(tree2, None) # Resolve the conflicts
 
287
        self.build_tree_contents([('tree2/file', d_text)])
 
288
        tree2.commit('D', rev_id='rev-D')
 
289
 
 
290
        self.build_tree_contents([('tree1/file', c_text)])
 
291
        tree1.commit('C', rev_id='rev-C')
 
292
 
 
293
        tree1.merge_from_branch(tree2.branch)
 
294
        conflicts.resolve(tree1, None) # Resolve the conflicts
 
295
        self.build_tree_contents([('tree1/file', e_text)])
 
296
        tree1.commit('E', rev_id='rev-E')
 
297
        return tree1
265
298
 
266
299
    def assertRepoAnnotate(self, expected, repo, file_id, revision_id):
267
300
        """Assert that the revision is properly annotated."""
273
306
                                 ''.join('\t'.join(l) for l in actual))
274
307
 
275
308
    def test_annotate_duplicate_lines(self):
276
 
        # XXX: Should this be a per_repository test?
277
 
        builder = self.create_duplicate_lines_tree()
278
 
        repo = builder.get_branch().repository
 
309
        # XXX: Should this be a repository_implementations test?
 
310
        tree1 = self.create_duplicate_lines_tree()
 
311
        repo = tree1.branch.repository
279
312
        repo.lock_read()
280
313
        self.addCleanup(repo.unlock)
281
314
        self.assertRepoAnnotate(duplicate_base, repo, 'file-id', 'rev-base')
286
319
        self.assertRepoAnnotate(duplicate_E, repo, 'file-id', 'rev-E')
287
320
 
288
321
    def test_annotate_shows_dotted_revnos(self):
289
 
        builder = self.create_merged_trees()
 
322
        tree1, tree2 = self.create_merged_trees()
290
323
 
291
324
        sio = StringIO()
292
 
        annotate.annotate_file(builder.get_branch(), 'rev-3', 'a-id',
 
325
        annotate.annotate_file(tree1.branch, 'rev-3', 'a-id',
293
326
                               to_file=sio)
294
327
        self.assertEqualDiff('1     joe@foo | first\n'
295
328
                             '2     joe@foo | second\n'
298
331
 
299
332
    def test_annotate_limits_dotted_revnos(self):
300
333
        """Annotate should limit dotted revnos to a depth of 12"""
301
 
        builder = self.create_deeply_merged_trees()
 
334
        tree1 = self.create_deeply_merged_trees()
302
335
 
303
336
        sio = StringIO()
304
 
        annotate.annotate_file(builder.get_branch(), 'rev-6', 'a-id',
 
337
        annotate.annotate_file(tree1.branch, 'rev-6', 'a-id',
305
338
                               to_file=sio, verbose=False, full=False)
306
339
        self.assertEqualDiff('1     joe@foo | first\n'
307
340
                             '2     joe@foo | second\n'
312
345
                             sio.getvalue())
313
346
 
314
347
        sio = StringIO()
315
 
        annotate.annotate_file(builder.get_branch(), 'rev-6', 'a-id',
 
348
        annotate.annotate_file(tree1.branch, 'rev-6', 'a-id',
316
349
                               to_file=sio, verbose=False, full=True)
317
350
        self.assertEqualDiff('1     joe@foo | first\n'
318
351
                             '2     joe@foo | second\n'
324
357
 
325
358
        # verbose=True shows everything, the full revno, user id, and date
326
359
        sio = StringIO()
327
 
        annotate.annotate_file(builder.get_branch(), 'rev-6', 'a-id',
 
360
        annotate.annotate_file(tree1.branch, 'rev-6', 'a-id',
328
361
                               to_file=sio, verbose=True, full=False)
329
362
        self.assertEqualDiff('1     joe@foo.com    20061213 | first\n'
330
363
                             '2     joe@foo.com    20061213 | second\n'
335
368
                             sio.getvalue())
336
369
 
337
370
        sio = StringIO()
338
 
        annotate.annotate_file(builder.get_branch(), 'rev-6', 'a-id',
 
371
        annotate.annotate_file(tree1.branch, 'rev-6', 'a-id',
339
372
                               to_file=sio, verbose=True, full=True)
340
373
        self.assertEqualDiff('1     joe@foo.com    20061213 | first\n'
341
374
                             '2     joe@foo.com    20061213 | second\n'
351
384
        When annotating a non-mainline revision, the annotation should still
352
385
        use dotted revnos from the mainline.
353
386
        """
354
 
        builder = self.create_deeply_merged_trees()
 
387
        tree1 = self.create_deeply_merged_trees()
355
388
 
356
389
        sio = StringIO()
357
 
        annotate.annotate_file(builder.get_branch(), 'rev-1_3_1', 'a-id',
 
390
        annotate.annotate_file(tree1.branch, 'rev-1_3_1', 'a-id',
358
391
                               to_file=sio, verbose=False, full=False)
359
392
        self.assertEqualDiff('1     joe@foo | first\n'
360
393
                             '1.1.1 barry@f | third\n'
364
397
                             sio.getvalue())
365
398
 
366
399
    def test_annotate_show_ids(self):
367
 
        builder = self.create_deeply_merged_trees()
 
400
        tree1 = self.create_deeply_merged_trees()
368
401
 
369
402
        sio = StringIO()
370
 
        annotate.annotate_file(builder.get_branch(), 'rev-6', 'a-id',
 
403
        annotate.annotate_file(tree1.branch, 'rev-6', 'a-id',
371
404
                               to_file=sio, show_ids=True, full=False)
372
405
 
373
406
        # It looks better with real revision ids :)
380
413
                             sio.getvalue())
381
414
 
382
415
        sio = StringIO()
383
 
        annotate.annotate_file(builder.get_branch(), 'rev-6', 'a-id',
 
416
        annotate.annotate_file(tree1.branch, 'rev-6', 'a-id',
384
417
                               to_file=sio, show_ids=True, full=True)
385
418
 
386
419
        self.assertEqualDiff('    rev-1 | first\n'
442
475
        tree1.add(['b'], ['b-id'])
443
476
        tree1.commit('b', rev_id='rev-2',
444
477
                     committer='Committer <committer@example.com>',
445
 
                     authors=['Author <author@example.com>'],
 
478
                     author='Author <author@example.com>',
446
479
                     timestamp=1166046000.00, timezone=0)
447
480
 
448
481
        tree1.lock_read()
469
502
    def test_reannotate(self):
470
503
        self.annotateEqual(parent_1, [parent_1], new_1, 'blahblah')
471
504
        self.annotateEqual(expected_2_1, [parent_2], new_1, 'blahblah')
472
 
        self.annotateEqual(expected_1_2_2, [parent_1, parent_2], new_2,
 
505
        self.annotateEqual(expected_1_2_2, [parent_1, parent_2], new_2, 
473
506
                           'blahblah')
474
507
 
475
508
    def test_reannotate_no_parents(self):