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

  • Committer: Jelmer Vernooij
  • Date: 2017-07-23 22:06:41 UTC
  • mfrom: (6738 trunk)
  • mto: This revision was merged to the branch mainline in revision 6739.
  • Revision ID: jelmer@jelmer.uk-20170723220641-69eczax9bmv8d6kk
Merge trunk, address review comments.

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
 
from io import (
18
 
    BytesIO,
19
 
    StringIO,
20
 
    )
21
17
import os
22
 
import re
23
18
 
24
19
from .. import (
25
20
    branchbuilder,
32
27
    gpg,
33
28
    trace,
34
29
    )
 
30
from ..sixish import (
 
31
    BytesIO,
 
32
    )
35
33
 
36
34
 
37
35
class TestLogMixin(object):
43
41
        stamp is incremented at each commit.
44
42
        """
45
43
        if getattr(self, 'timestamp', None) is None:
46
 
            self.timestamp = 1132617600  # Mon 2005-11-22 00:00:00 +0000
 
44
            self.timestamp = 1132617600 # Mon 2005-11-22 00:00:00 +0000
47
45
        else:
48
 
            self.timestamp += 1  # 1 second between each commit
 
46
            self.timestamp += 1 # 1 second between each commit
49
47
        kwargs.setdefault('timestamp', self.timestamp)
50
 
        kwargs.setdefault('timezone', 0)  # UTC
 
48
        kwargs.setdefault('timezone', 0) # UTC
51
49
        kwargs.setdefault('committer', 'Joe Foo <joe@foo.com>')
52
50
 
53
51
        return wt.commit(message, **kwargs)
93
91
        """Helper method for LogFormatter tests"""
94
92
        b = wt.branch
95
93
        b.nick = 'test'
96
 
        self.build_tree_contents([('a', b'hello moto\n')])
97
 
        self.wt_commit(wt, 'simple log message', rev_id=b'a1')
98
 
        self.build_tree_contents([('b', b'goodbye\n')])
 
94
        self.build_tree_contents([('a', 'hello moto\n')])
 
95
        self.wt_commit(wt, 'simple log message', rev_id='a1')
 
96
        self.build_tree_contents([('b', 'goodbye\n')])
99
97
        wt.add('b')
100
 
        self.wt_commit(wt, 'multiline\nlog\nmessage\n', rev_id=b'a2')
 
98
        self.wt_commit(wt, 'multiline\nlog\nmessage\n', rev_id='a2')
101
99
 
102
 
        self.build_tree_contents([('c', b'just another manic monday\n')])
 
100
        self.build_tree_contents([('c', 'just another manic monday\n')])
103
101
        wt.add('c')
104
 
        self.wt_commit(wt, 'single line with trailing newline\n', rev_id=b'a3')
 
102
        self.wt_commit(wt, 'single line with trailing newline\n', rev_id='a3')
105
103
        return b
106
104
 
107
105
    def _prepare_tree_with_merges(self, with_tags=False):
109
107
        wt.lock_write()
110
108
        self.addCleanup(wt.unlock)
111
109
        wt.add('')
112
 
        self.wt_commit(wt, 'rev-1', rev_id=b'rev-1')
113
 
        self.wt_commit(wt, 'rev-merged', rev_id=b'rev-2a')
114
 
        wt.set_parent_ids([b'rev-1', b'rev-2a'])
115
 
        wt.branch.set_last_revision_info(1, b'rev-1')
116
 
        self.wt_commit(wt, 'rev-2', rev_id=b'rev-2b')
 
110
        self.wt_commit(wt, 'rev-1', rev_id='rev-1')
 
111
        self.wt_commit(wt, 'rev-merged', rev_id='rev-2a')
 
112
        wt.set_parent_ids(['rev-1', 'rev-2a'])
 
113
        wt.branch.set_last_revision_info(1, 'rev-1')
 
114
        self.wt_commit(wt, 'rev-2', rev_id='rev-2b')
117
115
        if with_tags:
118
116
            branch = wt.branch
119
 
            branch.tags.set_tag('v0.2', b'rev-2b')
120
 
            self.wt_commit(wt, 'rev-3', rev_id=b'rev-3')
121
 
            branch.tags.set_tag('v1.0rc1', b'rev-3')
122
 
            branch.tags.set_tag('v1.0', b'rev-3')
 
117
            branch.tags.set_tag('v0.2', 'rev-2b')
 
118
            self.wt_commit(wt, 'rev-3', rev_id='rev-3')
 
119
            branch.tags.set_tag('v1.0rc1', 'rev-3')
 
120
            branch.tags.set_tag('v1.0', 'rev-3')
123
121
        return wt
124
122
 
125
123
 
157
155
            # By default we expect an empty list
158
156
            expected = kw.get(n, [])
159
157
            # strip out only the path components
160
 
            got = [x.path[1] or x.path[0] for x in getattr(delta, n)]
 
158
            got = [x[0] for x in getattr(delta, n)]
161
159
            self.assertEqual(expected, got)
162
160
 
163
161
    def assertInvalidRevisonNumber(self, br, start, end):
179
177
        self.assertInvalidRevisonNumber(b, 2, 1)
180
178
        self.assertInvalidRevisonNumber(b, 1, 2)
181
179
        self.assertInvalidRevisonNumber(b, 0, 2)
 
180
        self.assertInvalidRevisonNumber(b, 1, 0)
182
181
        self.assertInvalidRevisonNumber(b, -1, 1)
183
182
        self.assertInvalidRevisonNumber(b, 1, -1)
184
 
        self.assertInvalidRevisonNumber(b, 1, 0)
185
183
 
186
184
    def test_empty_branch(self):
187
185
        wt = self.make_branch_and_tree('.')
222
220
 
223
221
    def test_commit_message_with_control_chars(self):
224
222
        wt = self.make_branch_and_tree('.')
225
 
        msg = u"All 8-bit chars: " + ''.join([chr(x) for x in range(256)])
 
223
        msg = u"All 8-bit chars: " +  ''.join([unichr(x) for x in range(256)])
226
224
        msg = msg.replace(u'\r', u'\n')
227
225
        wt.commit(msg)
228
226
        lf = LogCatcher()
240
238
        # newline conversion, neither LF (\x0A) nor CR (\x0D) are
241
239
        # included in the test commit message, even though they are
242
240
        # valid XML 1.0 characters.
243
 
        msg = "\x09" + ''.join([chr(x) for x in range(0x20, 256)])
 
241
        msg = "\x09" + ''.join([unichr(x) for x in range(0x20, 256)])
244
242
        wt.commit(msg)
245
243
        lf = LogCatcher()
246
244
        log.show_log(wt.branch, lf, verbose=True)
256
254
        wt.commit(message='add file1 and file2')
257
255
        self.run_bzr('branch parent child')
258
256
        os.unlink('child/file1')
259
 
        with open('child/file2', 'wb') as f:
260
 
            f.write(b'hello\n')
 
257
        with file('child/file2', 'wb') as f: f.write('hello\n')
261
258
        self.run_bzr(['commit', '-m', 'remove file1 and modify file2',
262
 
                      'child'])
 
259
            'child'])
263
260
        os.chdir('parent')
264
261
        self.run_bzr('merge ../child')
265
262
        wt.commit('merge child branch')
287
284
        self.assertEqual('add file1 and file2', logentry.rev.message)
288
285
        self.checkDelta(logentry.delta, added=['file1', 'file2'])
289
286
 
290
 
    def test_bug_842695_log_restricted_to_dir(self):
291
 
        # Comments here indicate revision numbers in trunk  # VVVVV
292
 
        trunk = self.make_branch_and_tree('this')
293
 
        trunk.commit('initial trunk')                       # 1
294
 
        adder = trunk.controldir.sprout('adder').open_workingtree()
295
 
        merger = trunk.controldir.sprout('merger').open_workingtree()
296
 
        self.build_tree_contents([
297
 
            ('adder/dir/',),
298
 
            ('adder/dir/file', b'foo'),
299
 
            ])
300
 
        adder.add(['dir', 'dir/file'])
301
 
        adder.commit('added dir')                           # 1.1.1
302
 
        trunk.merge_from_branch(adder.branch)
303
 
        trunk.commit('merged adder into trunk')             # 2
304
 
        merger.merge_from_branch(trunk.branch)
305
 
        merger.commit('merged trunk into merger')           # 1.2.1
306
 
        # Commits are processed in increments of 200 revisions, so
307
 
        # make sure the two merges into trunk are in different chunks.
308
 
        for i in range(200):
309
 
            trunk.commit('intermediate commit %d' % i)      # 3-202
310
 
        trunk.merge_from_branch(merger.branch)
311
 
        trunk.commit('merged merger into trunk')            # 203
312
 
        file_id = trunk.path2id('dir')
313
 
        lf = LogCatcher()
314
 
        lf.supports_merge_revisions = True
315
 
        log.show_log(trunk.branch, lf, file_id)
316
 
        try:
317
 
            self.assertEqual(['2', '1.1.1'], [r.revno for r in lf.revisions])
318
 
        except AssertionError:
319
 
            raise tests.KnownFailure("bug #842695")
320
 
 
321
287
 
322
288
class TestFormatSignatureValidity(tests.TestCaseWithTransport):
323
 
 
324
 
    def verify_revision_signature(self, revid, gpg_strategy):
325
 
        return (gpg.SIGNATURE_VALID,
 
289
    class UTFLoopbackGPGStrategy(gpg.LoopbackGPGStrategy):
 
290
        def verify(self, content, testament):
 
291
            return (gpg.SIGNATURE_VALID,
326
292
                u'UTF8 Test \xa1\xb1\xc1\xd1\xe1\xf1 <jrandom@example.com>')
327
293
 
 
294
    def has_signature_for_revision_id(self, revision_id):
 
295
        return True
 
296
 
 
297
    def get_signature_text(self, revision_id):
 
298
        return ''
 
299
 
328
300
    def test_format_signature_validity_utf(self):
329
301
        """Check that GPG signatures containing UTF-8 names are formatted
330
302
        correctly."""
 
303
        # Monkey patch to use our UTF-8 generating GPGStrategy
 
304
        self.overrideAttr(gpg, 'GPGStrategy', self.UTFLoopbackGPGStrategy)
331
305
        wt = self.make_branch_and_tree('.')
332
306
        revid = wt.commit('empty commit')
333
307
        repo = wt.branch.repository
334
308
        # Monkey patch out checking if this rev is actually signed, since we
335
309
        # can't sign it without a heavier TestCase and LoopbackGPGStrategy
336
310
        # doesn't care anyways.
337
 
        self.overrideAttr(repo, 'verify_revision_signature',
338
 
                          self.verify_revision_signature)
339
 
        out = log.format_signature_validity(revid, wt.branch)
 
311
        self.overrideAttr(repo, 'has_signature_for_revision_id',
 
312
                self.has_signature_for_revision_id)
 
313
        self.overrideAttr(repo, 'get_signature_text', self.get_signature_text)
 
314
        out = log.format_signature_validity(revid, repo)
340
315
        self.assertEqual(
341
 
            u'valid signature from UTF8 Test \xa1\xb1\xc1\xd1\xe1\xf1 <jrandom@example.com>',
342
 
            out)
 
316
u'valid signature from UTF8 Test \xa1\xb1\xc1\xd1\xe1\xf1 <jrandom@example.com>',
 
317
                out)
343
318
 
344
319
 
345
320
class TestShortLogFormatter(TestCaseForLogFormatter):
347
322
    def test_trailing_newlines(self):
348
323
        wt = self.make_branch_and_tree('.')
349
324
        b = self.make_commits_with_trailing_newlines(wt)
350
 
        self.assertFormatterResult(b"""\
 
325
        self.assertFormatterResult("""\
351
326
    3 Joe Foo\t2005-11-22
352
327
      single line with trailing newline
353
328
 
360
335
      simple log message
361
336
 
362
337
""",
363
 
                                   b, log.ShortLogFormatter)
 
338
            b, log.ShortLogFormatter)
364
339
 
365
340
    def test_short_log_with_merges(self):
366
341
        wt = self._prepare_tree_with_merges()
367
 
        self.assertFormatterResult(b"""\
 
342
        self.assertFormatterResult("""\
368
343
    2 Joe Foo\t2005-11-22 [merge]
369
344
      rev-2
370
345
 
372
347
      rev-1
373
348
 
374
349
""",
375
 
                                   wt.branch, log.ShortLogFormatter)
 
350
            wt.branch, log.ShortLogFormatter)
376
351
 
377
352
    def test_short_log_with_merges_and_advice(self):
378
353
        wt = self._prepare_tree_with_merges()
379
 
        self.assertFormatterResult(b"""\
 
354
        self.assertFormatterResult("""\
380
355
    2 Joe Foo\t2005-11-22 [merge]
381
356
      rev-2
382
357
 
385
360
 
386
361
Use --include-merged or -n0 to see merged revisions.
387
362
""",
388
 
                                   wt.branch, log.ShortLogFormatter,
389
 
                                   formatter_kwargs=dict(show_advice=True))
 
363
            wt.branch, log.ShortLogFormatter,
 
364
            formatter_kwargs=dict(show_advice=True))
390
365
 
391
366
    def test_short_log_with_merges_and_range(self):
392
367
        wt = self._prepare_tree_with_merges()
393
 
        self.wt_commit(wt, 'rev-3a', rev_id=b'rev-3a')
394
 
        wt.branch.set_last_revision_info(2, b'rev-2b')
395
 
        wt.set_parent_ids([b'rev-2b', b'rev-3a'])
396
 
        self.wt_commit(wt, 'rev-3b', rev_id=b'rev-3b')
397
 
        self.assertFormatterResult(b"""\
 
368
        self.wt_commit(wt, 'rev-3a', rev_id='rev-3a')
 
369
        wt.branch.set_last_revision_info(2, 'rev-2b')
 
370
        wt.set_parent_ids(['rev-2b', 'rev-3a'])
 
371
        self.wt_commit(wt, 'rev-3b', rev_id='rev-3b')
 
372
        self.assertFormatterResult("""\
398
373
    3 Joe Foo\t2005-11-22 [merge]
399
374
      rev-3b
400
375
 
402
377
      rev-2
403
378
 
404
379
""",
405
 
                                   wt.branch, log.ShortLogFormatter,
406
 
                                   show_log_kwargs=dict(start_revision=2, end_revision=3))
 
380
            wt.branch, log.ShortLogFormatter,
 
381
            show_log_kwargs=dict(start_revision=2, end_revision=3))
407
382
 
408
383
    def test_short_log_with_tags(self):
409
384
        wt = self._prepare_tree_with_merges(with_tags=True)
410
 
        self.assertFormatterResult(b"""\
 
385
        self.assertFormatterResult("""\
411
386
    3 Joe Foo\t2005-11-22 {v1.0, v1.0rc1}
412
387
      rev-3
413
388
 
418
393
      rev-1
419
394
 
420
395
""",
421
 
                                   wt.branch, log.ShortLogFormatter)
 
396
            wt.branch, log.ShortLogFormatter)
422
397
 
423
398
    def test_short_log_single_merge_revision(self):
424
399
        wt = self._prepare_tree_with_merges()
425
400
        revspec = revisionspec.RevisionSpec.from_string('1.1.1')
426
401
        rev = revspec.in_history(wt.branch)
427
 
        self.assertFormatterResult(b"""\
 
402
        self.assertFormatterResult("""\
428
403
      1.1.1 Joe Foo\t2005-11-22
429
404
            rev-merged
430
405
 
431
406
""",
432
 
                                   wt.branch, log.ShortLogFormatter,
433
 
                                   show_log_kwargs=dict(start_revision=rev, end_revision=rev))
 
407
            wt.branch, log.ShortLogFormatter,
 
408
            show_log_kwargs=dict(start_revision=rev, end_revision=rev))
434
409
 
435
410
    def test_show_ids(self):
436
411
        wt = self.make_branch_and_tree('parent')
437
412
        self.build_tree(['parent/f1', 'parent/f2'])
438
 
        wt.add(['f1', 'f2'])
439
 
        self.wt_commit(wt, 'first post', rev_id=b'a')
 
413
        wt.add(['f1','f2'])
 
414
        self.wt_commit(wt, 'first post', rev_id='a')
440
415
        child_wt = wt.controldir.sprout('child').open_workingtree()
441
 
        self.wt_commit(child_wt, 'branch 1 changes', rev_id=b'b')
 
416
        self.wt_commit(child_wt, 'branch 1 changes', rev_id='b')
442
417
        wt.merge_from_branch(child_wt.branch)
443
 
        self.wt_commit(wt, 'merge branch 1', rev_id=b'c')
444
 
        self.assertFormatterResult(b"""\
 
418
        self.wt_commit(wt, 'merge branch 1', rev_id='c')
 
419
        self.assertFormatterResult("""\
445
420
    2 Joe Foo\t2005-11-22 [merge]
446
421
      revision-id:c
447
422
      merge branch 1
455
430
      first post
456
431
 
457
432
""",
458
 
                                   wt.branch, log.ShortLogFormatter,
459
 
                                   formatter_kwargs=dict(levels=0, show_ids=True))
 
433
            wt.branch, log.ShortLogFormatter,
 
434
            formatter_kwargs=dict(levels=0,show_ids=True))
460
435
 
461
436
 
462
437
class TestShortLogFormatterWithMergeRevisions(TestCaseForLogFormatter):
466
441
        # Note that the 1.1.1 indenting is in fact correct given that
467
442
        # the revision numbers are right justified within 5 characters
468
443
        # for mainline revnos and 9 characters for dotted revnos.
469
 
        self.assertFormatterResult(b"""\
 
444
        self.assertFormatterResult("""\
470
445
    2 Joe Foo\t2005-11-22 [merge]
471
446
      rev-2
472
447
 
477
452
      rev-1
478
453
 
479
454
""",
480
 
                                   wt.branch, log.ShortLogFormatter,
481
 
                                   formatter_kwargs=dict(levels=0))
 
455
            wt.branch, log.ShortLogFormatter,
 
456
            formatter_kwargs=dict(levels=0))
482
457
 
483
458
    def test_short_merge_revs_log_single_merge_revision(self):
484
459
        wt = self._prepare_tree_with_merges()
485
460
        revspec = revisionspec.RevisionSpec.from_string('1.1.1')
486
461
        rev = revspec.in_history(wt.branch)
487
 
        self.assertFormatterResult(b"""\
 
462
        self.assertFormatterResult("""\
488
463
      1.1.1 Joe Foo\t2005-11-22
489
464
            rev-merged
490
465
 
491
466
""",
492
 
                                   wt.branch, log.ShortLogFormatter,
493
 
                                   formatter_kwargs=dict(levels=0),
494
 
                                   show_log_kwargs=dict(start_revision=rev, end_revision=rev))
 
467
            wt.branch, log.ShortLogFormatter,
 
468
            formatter_kwargs=dict(levels=0),
 
469
            show_log_kwargs=dict(start_revision=rev, end_revision=rev))
495
470
 
496
471
 
497
472
class TestLongLogFormatter(TestCaseForLogFormatter):
502
477
        bug #4676
503
478
        """
504
479
        wt = self.make_standard_commit('test_verbose_log', authors=[])
505
 
        self.assertFormatterResult(b'''\
 
480
        self.assertFormatterResult('''\
506
481
------------------------------------------------------------
507
482
revno: 1
508
483
committer: Lorem Ipsum <test@example.com>
513
488
added:
514
489
  a
515
490
''',
516
 
                                   wt.branch, log.LongLogFormatter,
517
 
                                   show_log_kwargs=dict(verbose=True))
 
491
            wt.branch, log.LongLogFormatter,
 
492
            show_log_kwargs=dict(verbose=True))
518
493
 
519
494
    def test_merges_are_indented_by_level(self):
520
495
        wt = self.make_branch_and_tree('parent')
521
496
        self.wt_commit(wt, 'first post')
522
497
        child_wt = wt.controldir.sprout('child').open_workingtree()
523
498
        self.wt_commit(child_wt, 'branch 1')
524
 
        smallerchild_wt = wt.controldir.sprout(
525
 
            'smallerchild').open_workingtree()
 
499
        smallerchild_wt = wt.controldir.sprout('smallerchild').open_workingtree()
526
500
        self.wt_commit(smallerchild_wt, 'branch 2')
527
501
        child_wt.merge_from_branch(smallerchild_wt.branch)
528
502
        self.wt_commit(child_wt, 'merge branch 2')
529
503
        wt.merge_from_branch(child_wt.branch)
530
504
        self.wt_commit(wt, 'merge branch 1')
531
 
        self.assertFormatterResult(b"""\
 
505
        self.assertFormatterResult("""\
532
506
------------------------------------------------------------
533
507
revno: 2 [merge]
534
508
committer: Joe Foo <joe@foo.com>
565
539
message:
566
540
  first post
567
541
""",
568
 
                                   wt.branch, log.LongLogFormatter,
569
 
                                   formatter_kwargs=dict(levels=0),
570
 
                                   show_log_kwargs=dict(verbose=True))
 
542
            wt.branch, log.LongLogFormatter,
 
543
            formatter_kwargs=dict(levels=0),
 
544
            show_log_kwargs=dict(verbose=True))
571
545
 
572
546
    def test_verbose_merge_revisions_contain_deltas(self):
573
547
        wt = self.make_branch_and_tree('parent')
574
548
        self.build_tree(['parent/f1', 'parent/f2'])
575
 
        wt.add(['f1', 'f2'])
 
549
        wt.add(['f1','f2'])
576
550
        self.wt_commit(wt, 'first post')
577
551
        child_wt = wt.controldir.sprout('child').open_workingtree()
578
552
        os.unlink('child/f1')
579
 
        self.build_tree_contents([('child/f2', b'hello\n')])
 
553
        self.build_tree_contents([('child/f2', 'hello\n')])
580
554
        self.wt_commit(child_wt, 'removed f1 and modified f2')
581
555
        wt.merge_from_branch(child_wt.branch)
582
556
        self.wt_commit(wt, 'merge branch 1')
583
 
        self.assertFormatterResult(b"""\
 
557
        self.assertFormatterResult("""\
584
558
------------------------------------------------------------
585
559
revno: 2 [merge]
586
560
committer: Joe Foo <joe@foo.com>
614
588
  f1
615
589
  f2
616
590
""",
617
 
                                   wt.branch, log.LongLogFormatter,
618
 
                                   formatter_kwargs=dict(levels=0),
619
 
                                   show_log_kwargs=dict(verbose=True))
 
591
            wt.branch, log.LongLogFormatter,
 
592
            formatter_kwargs=dict(levels=0),
 
593
            show_log_kwargs=dict(verbose=True))
620
594
 
621
595
    def test_trailing_newlines(self):
622
596
        wt = self.make_branch_and_tree('.')
623
597
        b = self.make_commits_with_trailing_newlines(wt)
624
 
        self.assertFormatterResult(b"""\
 
598
        self.assertFormatterResult("""\
625
599
------------------------------------------------------------
626
600
revno: 3
627
601
committer: Joe Foo <joe@foo.com>
646
620
message:
647
621
  simple log message
648
622
""",
649
 
                                   b, log.LongLogFormatter)
 
623
        b, log.LongLogFormatter)
650
624
 
651
625
    def test_author_in_log(self):
652
626
        """Log includes the author name if it's set in
653
627
        the revision properties
654
628
        """
655
629
        wt = self.make_standard_commit('test_author_log',
656
 
                                       authors=['John Doe <jdoe@example.com>',
657
 
                                                'Jane Rey <jrey@example.com>'])
658
 
        self.assertFormatterResult(b"""\
 
630
            authors=['John Doe <jdoe@example.com>',
 
631
                     'Jane Rey <jrey@example.com>'])
 
632
        self.assertFormatterResult("""\
659
633
------------------------------------------------------------
660
634
revno: 1
661
635
author: John Doe <jdoe@example.com>, Jane Rey <jrey@example.com>
665
639
message:
666
640
  add a
667
641
""",
668
 
                                   wt.branch, log.LongLogFormatter)
 
642
        wt.branch, log.LongLogFormatter)
669
643
 
670
644
    def test_properties_in_log(self):
671
645
        """Log includes the custom properties returned by the registered
672
646
        handlers.
673
647
        """
674
648
        wt = self.make_standard_commit('test_properties_in_log')
675
 
 
676
649
        def trivial_custom_prop_handler(revision):
677
 
            return {'test_prop': 'test_value'}
 
650
            return {'test_prop':'test_value'}
678
651
 
679
652
        # Cleaned up in setUp()
680
653
        log.properties_handler_registry.register(
681
654
            'trivial_custom_prop_handler',
682
655
            trivial_custom_prop_handler)
683
 
        self.assertFormatterResult(b"""\
 
656
        self.assertFormatterResult("""\
684
657
------------------------------------------------------------
685
658
revno: 1
686
659
test_prop: test_value
691
664
message:
692
665
  add a
693
666
""",
694
 
                                   wt.branch, log.LongLogFormatter)
 
667
            wt.branch, log.LongLogFormatter)
695
668
 
696
669
    def test_properties_in_short_log(self):
697
670
        """Log includes the custom properties returned by the registered
698
671
        handlers.
699
672
        """
700
673
        wt = self.make_standard_commit('test_properties_in_short_log')
701
 
 
702
674
        def trivial_custom_prop_handler(revision):
703
 
            return {'test_prop': 'test_value'}
 
675
            return {'test_prop':'test_value'}
704
676
 
705
677
        log.properties_handler_registry.register(
706
678
            'trivial_custom_prop_handler',
707
679
            trivial_custom_prop_handler)
708
 
        self.assertFormatterResult(b"""\
 
680
        self.assertFormatterResult("""\
709
681
    1 John Doe\t2005-11-22
710
682
      test_prop: test_value
711
683
      add a
712
684
 
713
685
""",
714
 
                                   wt.branch, log.ShortLogFormatter)
 
686
            wt.branch, log.ShortLogFormatter)
715
687
 
716
688
    def test_error_in_properties_handler(self):
717
689
        """Log includes the custom properties returned by the registered
718
690
        handlers.
719
691
        """
720
692
        wt = self.make_standard_commit('error_in_properties_handler',
721
 
                                       revprops={u'first_prop': 'first_value'})
 
693
            revprops={'first_prop':'first_value'})
722
694
        sio = self.make_utf8_encoded_stringio()
723
695
        formatter = log.LongLogFormatter(to_file=sio)
724
 
 
725
696
        def trivial_custom_prop_handler(revision):
726
697
            raise Exception("a test error")
727
698
 
728
699
        log.properties_handler_registry.register(
729
700
            'trivial_custom_prop_handler',
730
701
            trivial_custom_prop_handler)
731
 
        log.show_log(wt.branch, formatter)
732
 
        self.assertContainsRe(
733
 
            sio.getvalue(), b'brz: ERROR: Exception: a test error')
 
702
        self.assertRaises(Exception, log.show_log, wt.branch, formatter,)
734
703
 
735
704
    def test_properties_handler_bad_argument(self):
736
705
        wt = self.make_standard_commit('bad_argument',
737
 
                                       revprops={u'a_prop': 'test_value'})
 
706
              revprops={'a_prop':'test_value'})
738
707
        sio = self.make_utf8_encoded_stringio()
739
708
        formatter = log.LongLogFormatter(to_file=sio)
740
 
 
741
709
        def bad_argument_prop_handler(revision):
742
 
            return {'custom_prop_name': revision.properties['a_prop']}
 
710
            return {'custom_prop_name':revision.properties['a_prop']}
743
711
 
744
712
        log.properties_handler_registry.register(
745
713
            'bad_argument_prop_handler',
750
718
 
751
719
        revision = wt.branch.repository.get_revision(wt.branch.last_revision())
752
720
        formatter.show_properties(revision, '')
753
 
        self.assertEqualDiff(b'custom_prop_name: test_value\n',
 
721
        self.assertEqualDiff('''custom_prop_name: test_value\n''',
754
722
                             sio.getvalue())
755
723
 
756
724
    def test_show_ids(self):
757
725
        wt = self.make_branch_and_tree('parent')
758
726
        self.build_tree(['parent/f1', 'parent/f2'])
759
 
        wt.add(['f1', 'f2'])
760
 
        self.wt_commit(wt, 'first post', rev_id=b'a')
 
727
        wt.add(['f1','f2'])
 
728
        self.wt_commit(wt, 'first post', rev_id='a')
761
729
        child_wt = wt.controldir.sprout('child').open_workingtree()
762
 
        self.wt_commit(child_wt, 'branch 1 changes', rev_id=b'b')
 
730
        self.wt_commit(child_wt, 'branch 1 changes', rev_id='b')
763
731
        wt.merge_from_branch(child_wt.branch)
764
 
        self.wt_commit(wt, 'merge branch 1', rev_id=b'c')
765
 
        self.assertFormatterResult(b"""\
 
732
        self.wt_commit(wt, 'merge branch 1', rev_id='c')
 
733
        self.assertFormatterResult("""\
766
734
------------------------------------------------------------
767
735
revno: 2 [merge]
768
736
revision-id: c
791
759
message:
792
760
  first post
793
761
""",
794
 
                                   wt.branch, log.LongLogFormatter,
795
 
                                   formatter_kwargs=dict(levels=0, show_ids=True))
 
762
            wt.branch, log.LongLogFormatter,
 
763
            formatter_kwargs=dict(levels=0,show_ids=True))
796
764
 
797
765
 
798
766
class TestLongLogFormatterWithoutMergeRevisions(TestCaseForLogFormatter):
803
771
        bug #4676
804
772
        """
805
773
        wt = self.make_standard_commit('test_long_verbose_log', authors=[])
806
 
        self.assertFormatterResult(b"""\
 
774
        self.assertFormatterResult("""\
807
775
------------------------------------------------------------
808
776
revno: 1
809
777
committer: Lorem Ipsum <test@example.com>
814
782
added:
815
783
  a
816
784
""",
817
 
                                   wt.branch, log.LongLogFormatter,
818
 
                                   formatter_kwargs=dict(levels=1),
819
 
                                   show_log_kwargs=dict(verbose=True))
 
785
            wt.branch, log.LongLogFormatter,
 
786
            formatter_kwargs=dict(levels=1),
 
787
            show_log_kwargs=dict(verbose=True))
820
788
 
821
789
    def test_long_verbose_contain_deltas(self):
822
790
        wt = self.make_branch_and_tree('parent')
823
791
        self.build_tree(['parent/f1', 'parent/f2'])
824
 
        wt.add(['f1', 'f2'])
 
792
        wt.add(['f1','f2'])
825
793
        self.wt_commit(wt, 'first post')
826
794
        child_wt = wt.controldir.sprout('child').open_workingtree()
827
795
        os.unlink('child/f1')
828
 
        self.build_tree_contents([('child/f2', b'hello\n')])
 
796
        self.build_tree_contents([('child/f2', 'hello\n')])
829
797
        self.wt_commit(child_wt, 'removed f1 and modified f2')
830
798
        wt.merge_from_branch(child_wt.branch)
831
799
        self.wt_commit(wt, 'merge branch 1')
832
 
        self.assertFormatterResult(b"""\
 
800
        self.assertFormatterResult("""\
833
801
------------------------------------------------------------
834
802
revno: 2 [merge]
835
803
committer: Joe Foo <joe@foo.com>
852
820
  f1
853
821
  f2
854
822
""",
855
 
                                   wt.branch, log.LongLogFormatter,
856
 
                                   formatter_kwargs=dict(levels=1),
857
 
                                   show_log_kwargs=dict(verbose=True))
 
823
            wt.branch, log.LongLogFormatter,
 
824
            formatter_kwargs=dict(levels=1),
 
825
            show_log_kwargs=dict(verbose=True))
858
826
 
859
827
    def test_long_trailing_newlines(self):
860
828
        wt = self.make_branch_and_tree('.')
861
829
        b = self.make_commits_with_trailing_newlines(wt)
862
 
        self.assertFormatterResult(b"""\
 
830
        self.assertFormatterResult("""\
863
831
------------------------------------------------------------
864
832
revno: 3
865
833
committer: Joe Foo <joe@foo.com>
884
852
message:
885
853
  simple log message
886
854
""",
887
 
                                   b, log.LongLogFormatter,
888
 
                                   formatter_kwargs=dict(levels=1))
 
855
        b, log.LongLogFormatter,
 
856
        formatter_kwargs=dict(levels=1))
889
857
 
890
858
    def test_long_author_in_log(self):
891
859
        """Log includes the author name if it's set in
892
860
        the revision properties
893
861
        """
894
862
        wt = self.make_standard_commit('test_author_log')
895
 
        self.assertFormatterResult(b"""\
 
863
        self.assertFormatterResult("""\
896
864
------------------------------------------------------------
897
865
revno: 1
898
866
author: John Doe <jdoe@example.com>
902
870
message:
903
871
  add a
904
872
""",
905
 
                                   wt.branch, log.LongLogFormatter,
906
 
                                   formatter_kwargs=dict(levels=1))
 
873
            wt.branch, log.LongLogFormatter,
 
874
            formatter_kwargs=dict(levels=1))
907
875
 
908
876
    def test_long_properties_in_log(self):
909
877
        """Log includes the custom properties returned by the registered
910
878
        handlers.
911
879
        """
912
880
        wt = self.make_standard_commit('test_properties_in_log')
913
 
 
914
881
        def trivial_custom_prop_handler(revision):
915
 
            return {'test_prop': 'test_value'}
 
882
            return {'test_prop':'test_value'}
916
883
 
917
884
        log.properties_handler_registry.register(
918
885
            'trivial_custom_prop_handler',
919
886
            trivial_custom_prop_handler)
920
 
        self.assertFormatterResult(b"""\
 
887
        self.assertFormatterResult("""\
921
888
------------------------------------------------------------
922
889
revno: 1
923
890
test_prop: test_value
928
895
message:
929
896
  add a
930
897
""",
931
 
                                   wt.branch, log.LongLogFormatter,
932
 
                                   formatter_kwargs=dict(levels=1))
 
898
            wt.branch, log.LongLogFormatter,
 
899
            formatter_kwargs=dict(levels=1))
933
900
 
934
901
 
935
902
class TestLineLogFormatter(TestCaseForLogFormatter):
940
907
        bug #5162
941
908
        """
942
909
        wt = self.make_standard_commit('test-line-log',
943
 
                                       committer='Line-Log-Formatter Tester <test@line.log>',
944
 
                                       authors=[])
945
 
        self.assertFormatterResult(b"""\
 
910
                committer='Line-Log-Formatter Tester <test@line.log>',
 
911
                authors=[])
 
912
        self.assertFormatterResult("""\
946
913
1: Line-Log-Formatte... 2005-11-22 add a
947
914
""",
948
 
                                   wt.branch, log.LineLogFormatter)
 
915
            wt.branch, log.LineLogFormatter)
949
916
 
950
917
    def test_trailing_newlines(self):
951
918
        wt = self.make_branch_and_tree('.')
952
919
        b = self.make_commits_with_trailing_newlines(wt)
953
 
        self.assertFormatterResult(b"""\
 
920
        self.assertFormatterResult("""\
954
921
3: Joe Foo 2005-11-22 single line with trailing newline
955
922
2: Joe Foo 2005-11-22 multiline
956
923
1: Joe Foo 2005-11-22 simple log message
957
924
""",
958
 
                                   b, log.LineLogFormatter)
 
925
            b, log.LineLogFormatter)
959
926
 
960
927
    def test_line_log_single_merge_revision(self):
961
928
        wt = self._prepare_tree_with_merges()
962
929
        revspec = revisionspec.RevisionSpec.from_string('1.1.1')
963
930
        rev = revspec.in_history(wt.branch)
964
 
        self.assertFormatterResult(b"""\
 
931
        self.assertFormatterResult("""\
965
932
1.1.1: Joe Foo 2005-11-22 rev-merged
966
933
""",
967
 
                                   wt.branch, log.LineLogFormatter,
968
 
                                   show_log_kwargs=dict(start_revision=rev, end_revision=rev))
 
934
            wt.branch, log.LineLogFormatter,
 
935
            show_log_kwargs=dict(start_revision=rev, end_revision=rev))
969
936
 
970
937
    def test_line_log_with_tags(self):
971
938
        wt = self._prepare_tree_with_merges(with_tags=True)
972
 
        self.assertFormatterResult(b"""\
 
939
        self.assertFormatterResult("""\
973
940
3: Joe Foo 2005-11-22 {v1.0, v1.0rc1} rev-3
974
941
2: Joe Foo 2005-11-22 [merge] {v0.2} rev-2
975
942
1: Joe Foo 2005-11-22 rev-1
976
943
""",
977
 
                                   wt.branch, log.LineLogFormatter)
 
944
            wt.branch, log.LineLogFormatter)
978
945
 
979
946
 
980
947
class TestLineLogFormatterWithMergeRevisions(TestCaseForLogFormatter):
985
952
        bug #5162
986
953
        """
987
954
        wt = self.make_standard_commit('test-line-log',
988
 
                                       committer='Line-Log-Formatter Tester <test@line.log>',
989
 
                                       authors=[])
990
 
        self.assertFormatterResult(b"""\
 
955
                committer='Line-Log-Formatter Tester <test@line.log>',
 
956
                authors=[])
 
957
        self.assertFormatterResult("""\
991
958
1: Line-Log-Formatte... 2005-11-22 add a
992
959
""",
993
 
                                   wt.branch, log.LineLogFormatter)
 
960
            wt.branch, log.LineLogFormatter)
994
961
 
995
962
    def test_line_merge_revs_log_single_merge_revision(self):
996
963
        wt = self._prepare_tree_with_merges()
997
964
        revspec = revisionspec.RevisionSpec.from_string('1.1.1')
998
965
        rev = revspec.in_history(wt.branch)
999
 
        self.assertFormatterResult(b"""\
 
966
        self.assertFormatterResult("""\
1000
967
1.1.1: Joe Foo 2005-11-22 rev-merged
1001
968
""",
1002
 
                                   wt.branch, log.LineLogFormatter,
1003
 
                                   formatter_kwargs=dict(levels=0),
1004
 
                                   show_log_kwargs=dict(start_revision=rev, end_revision=rev))
 
969
            wt.branch, log.LineLogFormatter,
 
970
            formatter_kwargs=dict(levels=0),
 
971
            show_log_kwargs=dict(start_revision=rev, end_revision=rev))
1005
972
 
1006
973
    def test_line_merge_revs_log_with_merges(self):
1007
974
        wt = self._prepare_tree_with_merges()
1008
 
        self.assertFormatterResult(b"""\
 
975
        self.assertFormatterResult("""\
1009
976
2: Joe Foo 2005-11-22 [merge] rev-2
1010
977
  1.1.1: Joe Foo 2005-11-22 rev-merged
1011
978
1: Joe Foo 2005-11-22 rev-1
1012
979
""",
1013
 
                                   wt.branch, log.LineLogFormatter,
1014
 
                                   formatter_kwargs=dict(levels=0))
 
980
            wt.branch, log.LineLogFormatter,
 
981
            formatter_kwargs=dict(levels=0))
1015
982
 
1016
983
 
1017
984
class TestGnuChangelogFormatter(TestCaseForLogFormatter):
1018
985
 
1019
986
    def test_gnu_changelog(self):
1020
987
        wt = self.make_standard_commit('nicky', authors=[])
1021
 
        self.assertFormatterResult(b'''\
 
988
        self.assertFormatterResult('''\
1022
989
2005-11-22  Lorem Ipsum  <test@example.com>
1023
990
 
1024
991
\tadd a
1025
992
 
1026
993
''',
1027
 
                                   wt.branch, log.GnuChangelogLogFormatter)
 
994
            wt.branch, log.GnuChangelogLogFormatter)
1028
995
 
1029
996
    def test_with_authors(self):
1030
997
        wt = self.make_standard_commit('nicky',
1031
 
                                       authors=['Fooa Fooz <foo@example.com>',
1032
 
                                                'Bari Baro <bar@example.com>'])
1033
 
        self.assertFormatterResult(b'''\
 
998
            authors=['Fooa Fooz <foo@example.com>',
 
999
                     'Bari Baro <bar@example.com>'])
 
1000
        self.assertFormatterResult('''\
1034
1001
2005-11-22  Fooa Fooz  <foo@example.com>
1035
1002
 
1036
1003
\tadd a
1037
1004
 
1038
1005
''',
1039
 
                                   wt.branch, log.GnuChangelogLogFormatter)
 
1006
            wt.branch, log.GnuChangelogLogFormatter)
1040
1007
 
1041
1008
    def test_verbose(self):
1042
1009
        wt = self.make_standard_commit('nicky')
1043
 
        self.assertFormatterResult(b'''\
 
1010
        self.assertFormatterResult('''\
1044
1011
2005-11-22  John Doe  <jdoe@example.com>
1045
1012
 
1046
1013
\t* a:
1048
1015
\tadd a
1049
1016
 
1050
1017
''',
1051
 
                                   wt.branch, log.GnuChangelogLogFormatter,
1052
 
                                   show_log_kwargs=dict(verbose=True))
 
1018
            wt.branch, log.GnuChangelogLogFormatter,
 
1019
            show_log_kwargs=dict(verbose=True))
1053
1020
 
1054
1021
 
1055
1022
class TestShowChangedRevisions(tests.TestCaseWithTransport):
1058
1025
        tree = self.make_branch_and_tree('tree_a')
1059
1026
        self.build_tree(['tree_a/foo'])
1060
1027
        tree.add('foo')
1061
 
        tree.commit('bar', rev_id=b'bar-id')
 
1028
        tree.commit('bar', rev_id='bar-id')
1062
1029
        s = self.make_utf8_encoded_stringio()
1063
 
        log.show_changed_revisions(tree.branch, [], [b'bar-id'], s)
1064
 
        self.assertContainsRe(s.getvalue(), b'bar')
1065
 
        self.assertNotContainsRe(s.getvalue(), b'foo')
 
1030
        log.show_changed_revisions(tree.branch, [], ['bar-id'], s)
 
1031
        self.assertContainsRe(s.getvalue(), 'bar')
 
1032
        self.assertNotContainsRe(s.getvalue(), 'foo')
1066
1033
 
1067
1034
 
1068
1035
class TestLogFormatter(tests.TestCase):
1069
1036
 
1070
1037
    def setUp(self):
1071
1038
        super(TestLogFormatter, self).setUp()
1072
 
        self.rev = revision.Revision(b'a-id')
 
1039
        self.rev = revision.Revision('a-id')
1073
1040
        self.lf = log.LogFormatter(None)
1074
1041
 
1075
1042
    def test_short_committer(self):
1123
1090
            Tests use (revno, depth) whil the API expects (revid, revno, depth).
1124
1091
            Since the revid is arbitrary, we just duplicate revno
1125
1092
            """
1126
 
            return [(r, r, d) for r, d in l]
 
1093
            return [ (r, r, d) for r, d in l]
1127
1094
        forward = complete_revisions(forward)
1128
 
        backward = complete_revisions(backward)
 
1095
        backward= complete_revisions(backward)
1129
1096
        self.assertEqual(forward, log.reverse_by_depth(backward))
1130
1097
 
 
1098
 
1131
1099
    def test_mainline_revisions(self):
1132
 
        self.assertReversed([('1', 0), ('2', 0)],
 
1100
        self.assertReversed([( '1', 0), ('2', 0)],
1133
1101
                            [('2', 0), ('1', 0)])
1134
1102
 
1135
1103
    def test_merged_revisions(self):
1136
 
        self.assertReversed([('1', 0), ('2', 0), ('2.2', 1), ('2.1', 1), ],
1137
 
                            [('2', 0), ('2.1', 1), ('2.2', 1), ('1', 0), ])
1138
 
 
 
1104
        self.assertReversed([('1', 0), ('2', 0), ('2.2', 1), ('2.1', 1),],
 
1105
                            [('2', 0), ('2.1', 1), ('2.2', 1), ('1', 0),])
1139
1106
    def test_shifted_merged_revisions(self):
1140
1107
        """Test irregular layout.
1141
1108
 
1142
1109
        Requesting revisions touching a file can produce "holes" in the depths.
1143
1110
        """
1144
 
        self.assertReversed([('1', 0), ('2', 0), ('1.1', 2), ('1.2', 2), ],
1145
 
                            [('2', 0), ('1.2', 2), ('1.1', 2), ('1', 0), ])
 
1111
        self.assertReversed([('1', 0), ('2', 0), ('1.1', 2), ('1.2', 2),],
 
1112
                            [('2', 0), ('1.2', 2), ('1.1', 2), ('1', 0),])
1146
1113
 
1147
1114
    def test_merged_without_child_revisions(self):
1148
1115
        """Test irregular layout.
1152
1119
        # When a revision of higher depth doesn't follow one of lower depth, we
1153
1120
        # assume a lower depth one is virtually there
1154
1121
        self.assertReversed([('1', 2), ('2', 2), ('3', 3), ('4', 4)],
1155
 
                            [('4', 4), ('3', 3), ('2', 2), ('1', 2), ])
 
1122
                            [('4', 4), ('3', 3), ('2', 2), ('1', 2),])
1156
1123
        # So we get the same order after reversing below even if the original
1157
1124
        # revisions are not in the same order.
1158
1125
        self.assertReversed([('1', 2), ('2', 2), ('3', 3), ('4', 4)],
1159
 
                            [('3', 3), ('4', 4), ('2', 2), ('1', 2), ])
 
1126
                            [('3', 3), ('4', 4), ('2', 2), ('1', 2),])
1160
1127
 
1161
1128
 
1162
1129
class TestHistoryChange(tests.TestCaseWithTransport):
1165
1132
        tree = self.make_branch_and_tree('tree')
1166
1133
        tree.lock_write()
1167
1134
        self.addCleanup(tree.unlock)
1168
 
        tree.commit('1a', rev_id=b'1a')
1169
 
        tree.commit('2a', rev_id=b'2a')
1170
 
        tree.commit('3a', rev_id=b'3a')
 
1135
        tree.commit('1a', rev_id='1a')
 
1136
        tree.commit('2a', rev_id='2a')
 
1137
        tree.commit('3a', rev_id='3a')
1171
1138
        return tree
1172
1139
 
1173
1140
    def setup_ab_tree(self):
1174
1141
        tree = self.setup_a_tree()
1175
 
        tree.set_last_revision(b'1a')
1176
 
        tree.branch.set_last_revision_info(1, b'1a')
1177
 
        tree.commit('2b', rev_id=b'2b')
1178
 
        tree.commit('3b', rev_id=b'3b')
 
1142
        tree.set_last_revision('1a')
 
1143
        tree.branch.set_last_revision_info(1, '1a')
 
1144
        tree.commit('2b', rev_id='2b')
 
1145
        tree.commit('3b', rev_id='3b')
1179
1146
        return tree
1180
1147
 
1181
1148
    def setup_ac_tree(self):
1182
1149
        tree = self.setup_a_tree()
1183
1150
        tree.set_last_revision(revision.NULL_REVISION)
1184
1151
        tree.branch.set_last_revision_info(0, revision.NULL_REVISION)
1185
 
        tree.commit('1c', rev_id=b'1c')
1186
 
        tree.commit('2c', rev_id=b'2c')
1187
 
        tree.commit('3c', rev_id=b'3c')
 
1152
        tree.commit('1c', rev_id='1c')
 
1153
        tree.commit('2c', rev_id='2c')
 
1154
        tree.commit('3c', rev_id='3c')
1188
1155
        return tree
1189
1156
 
1190
1157
    def test_all_new(self):
1191
1158
        tree = self.setup_ab_tree()
1192
 
        old, new = log.get_history_change(b'1a', b'3a', tree.branch.repository)
 
1159
        old, new = log.get_history_change('1a', '3a', tree.branch.repository)
1193
1160
        self.assertEqual([], old)
1194
 
        self.assertEqual([b'2a', b'3a'], new)
 
1161
        self.assertEqual(['2a', '3a'], new)
1195
1162
 
1196
1163
    def test_all_old(self):
1197
1164
        tree = self.setup_ab_tree()
1198
 
        old, new = log.get_history_change(b'3a', b'1a', tree.branch.repository)
 
1165
        old, new = log.get_history_change('3a', '1a', tree.branch.repository)
1199
1166
        self.assertEqual([], new)
1200
 
        self.assertEqual([b'2a', b'3a'], old)
 
1167
        self.assertEqual(['2a', '3a'], old)
1201
1168
 
1202
1169
    def test_null_old(self):
1203
1170
        tree = self.setup_ab_tree()
1204
1171
        old, new = log.get_history_change(revision.NULL_REVISION,
1205
 
                                          b'3a', tree.branch.repository)
 
1172
                                          '3a', tree.branch.repository)
1206
1173
        self.assertEqual([], old)
1207
 
        self.assertEqual([b'1a', b'2a', b'3a'], new)
 
1174
        self.assertEqual(['1a', '2a', '3a'], new)
1208
1175
 
1209
1176
    def test_null_new(self):
1210
1177
        tree = self.setup_ab_tree()
1211
 
        old, new = log.get_history_change(b'3a', revision.NULL_REVISION,
 
1178
        old, new = log.get_history_change('3a', revision.NULL_REVISION,
1212
1179
                                          tree.branch.repository)
1213
1180
        self.assertEqual([], new)
1214
 
        self.assertEqual([b'1a', b'2a', b'3a'], old)
 
1181
        self.assertEqual(['1a', '2a', '3a'], old)
1215
1182
 
1216
1183
    def test_diverged(self):
1217
1184
        tree = self.setup_ab_tree()
1218
 
        old, new = log.get_history_change(b'3a', b'3b', tree.branch.repository)
1219
 
        self.assertEqual(old, [b'2a', b'3a'])
1220
 
        self.assertEqual(new, [b'2b', b'3b'])
 
1185
        old, new = log.get_history_change('3a', '3b', tree.branch.repository)
 
1186
        self.assertEqual(old, ['2a', '3a'])
 
1187
        self.assertEqual(new, ['2b', '3b'])
1221
1188
 
1222
1189
    def test_unrelated(self):
1223
1190
        tree = self.setup_ac_tree()
1224
 
        old, new = log.get_history_change(b'3a', b'3c', tree.branch.repository)
1225
 
        self.assertEqual(old, [b'1a', b'2a', b'3a'])
1226
 
        self.assertEqual(new, [b'1c', b'2c', b'3c'])
 
1191
        old, new = log.get_history_change('3a', '3c', tree.branch.repository)
 
1192
        self.assertEqual(old, ['1a', '2a', '3a'])
 
1193
        self.assertEqual(new, ['1c', '2c', '3c'])
1227
1194
 
1228
1195
    def test_show_branch_change(self):
1229
1196
        tree = self.setup_ab_tree()
1230
 
        s = StringIO()
1231
 
        log.show_branch_change(tree.branch, s, 3, b'3a')
 
1197
        s = BytesIO()
 
1198
        log.show_branch_change(tree.branch, s, 3, '3a')
1232
1199
        self.assertContainsRe(s.getvalue(),
1233
 
                              '[*]{60}\nRemoved Revisions:\n(.|\n)*2a(.|\n)*3a(.|\n)*'
1234
 
                              '[*]{60}\n\nAdded Revisions:\n(.|\n)*2b(.|\n)*3b')
 
1200
            '[*]{60}\nRemoved Revisions:\n(.|\n)*2a(.|\n)*3a(.|\n)*'
 
1201
            '[*]{60}\n\nAdded Revisions:\n(.|\n)*2b(.|\n)*3b')
1235
1202
 
1236
1203
    def test_show_branch_change_no_change(self):
1237
1204
        tree = self.setup_ab_tree()
1238
 
        s = StringIO()
1239
 
        log.show_branch_change(tree.branch, s, 3, b'3b')
 
1205
        s = BytesIO()
 
1206
        log.show_branch_change(tree.branch, s, 3, '3b')
1240
1207
        self.assertEqual(s.getvalue(),
1241
 
                         'Nothing seems to have changed\n')
 
1208
            'Nothing seems to have changed\n')
1242
1209
 
1243
1210
    def test_show_branch_change_no_old(self):
1244
1211
        tree = self.setup_ab_tree()
1245
 
        s = StringIO()
1246
 
        log.show_branch_change(tree.branch, s, 2, b'2b')
 
1212
        s = BytesIO()
 
1213
        log.show_branch_change(tree.branch, s, 2, '2b')
1247
1214
        self.assertContainsRe(s.getvalue(), 'Added Revisions:')
1248
1215
        self.assertNotContainsRe(s.getvalue(), 'Removed Revisions:')
1249
1216
 
1250
1217
    def test_show_branch_change_no_new(self):
1251
1218
        tree = self.setup_ab_tree()
1252
 
        tree.branch.set_last_revision_info(2, b'2b')
1253
 
        s = StringIO()
1254
 
        log.show_branch_change(tree.branch, s, 3, b'3b')
 
1219
        tree.branch.set_last_revision_info(2, '2b')
 
1220
        s = BytesIO()
 
1221
        log.show_branch_change(tree.branch, s, 3, '3b')
1255
1222
        self.assertContainsRe(s.getvalue(), 'Removed Revisions:')
1256
1223
        self.assertNotContainsRe(s.getvalue(), 'Added Revisions:')
1257
1224
 
1264
1231
        self.addCleanup(tree.unlock)
1265
1232
        kwargs = {
1266
1233
            'committer': 'Joe Foo <joe@foo.com>',
1267
 
            'timestamp': 1132617600,  # Mon 2005-11-22 00:00:00 +0000
1268
 
            'timezone': 0,  # UTC
 
1234
            'timestamp': 1132617600, # Mon 2005-11-22 00:00:00 +0000
 
1235
            'timezone': 0, # UTC
1269
1236
        }
1270
 
        tree.commit('commit 1a', rev_id=b'1a', **kwargs)
1271
 
        tree.commit('commit 2a', rev_id=b'2a', **kwargs)
1272
 
        tree.commit('commit 3a', rev_id=b'3a', **kwargs)
 
1237
        tree.commit('commit 1a', rev_id='1a', **kwargs)
 
1238
        tree.commit('commit 2a', rev_id='2a', **kwargs)
 
1239
        tree.commit('commit 3a', rev_id='3a', **kwargs)
1273
1240
        return tree
1274
1241
 
1275
1242
    def setup_ab_tree(self):
1276
1243
        tree = self.setup_a_tree()
1277
 
        tree.set_last_revision(b'1a')
1278
 
        tree.branch.set_last_revision_info(1, b'1a')
 
1244
        tree.set_last_revision('1a')
 
1245
        tree.branch.set_last_revision_info(1, '1a')
1279
1246
        kwargs = {
1280
1247
            'committer': 'Joe Foo <joe@foo.com>',
1281
 
            'timestamp': 1132617600,  # Mon 2005-11-22 00:00:00 +0000
1282
 
            'timezone': 0,  # UTC
 
1248
            'timestamp': 1132617600, # Mon 2005-11-22 00:00:00 +0000
 
1249
            'timezone': 0, # UTC
1283
1250
        }
1284
 
        tree.commit('commit 2b', rev_id=b'2b', **kwargs)
1285
 
        tree.commit('commit 3b', rev_id=b'3b', **kwargs)
 
1251
        tree.commit('commit 2b', rev_id='2b', **kwargs)
 
1252
        tree.commit('commit 3b', rev_id='3b', **kwargs)
1286
1253
        return tree
1287
1254
 
1288
1255
    def test_one_revision(self):
1289
1256
        tree = self.setup_ab_tree()
1290
1257
        lf = LogCatcher()
1291
 
        rev = revisionspec.RevisionInfo(tree.branch, None, b'3a')
 
1258
        rev = revisionspec.RevisionInfo(tree.branch, None, '3a')
1292
1259
        log.show_log(tree.branch, lf, verbose=True, start_revision=rev,
1293
1260
                     end_revision=rev)
1294
1261
        self.assertEqual(1, len(lf.revisions))
1295
1262
        self.assertEqual(None, lf.revisions[0].revno)   # Out-of-branch
1296
 
        self.assertEqual(b'3a', lf.revisions[0].rev.revision_id)
 
1263
        self.assertEqual('3a', lf.revisions[0].rev.revision_id)
1297
1264
 
1298
1265
    def test_many_revisions(self):
1299
1266
        tree = self.setup_ab_tree()
1300
1267
        lf = LogCatcher()
1301
 
        start_rev = revisionspec.RevisionInfo(tree.branch, None, b'1a')
1302
 
        end_rev = revisionspec.RevisionInfo(tree.branch, None, b'3a')
 
1268
        start_rev = revisionspec.RevisionInfo(tree.branch, None, '1a')
 
1269
        end_rev = revisionspec.RevisionInfo(tree.branch, None, '3a')
1303
1270
        log.show_log(tree.branch, lf, verbose=True, start_revision=start_rev,
1304
1271
                     end_revision=end_rev)
1305
1272
        self.assertEqual(3, len(lf.revisions))
1306
1273
        self.assertEqual(None, lf.revisions[0].revno)   # Out-of-branch
1307
 
        self.assertEqual(b'3a', lf.revisions[0].rev.revision_id)
 
1274
        self.assertEqual('3a', lf.revisions[0].rev.revision_id)
1308
1275
        self.assertEqual(None, lf.revisions[1].revno)   # Out-of-branch
1309
 
        self.assertEqual(b'2a', lf.revisions[1].rev.revision_id)
 
1276
        self.assertEqual('2a', lf.revisions[1].rev.revision_id)
1310
1277
        self.assertEqual('1', lf.revisions[2].revno)    # In-branch
1311
1278
 
1312
1279
    def test_long_format(self):
1313
1280
        tree = self.setup_ab_tree()
1314
 
        start_rev = revisionspec.RevisionInfo(tree.branch, None, b'1a')
1315
 
        end_rev = revisionspec.RevisionInfo(tree.branch, None, b'3a')
1316
 
        self.assertFormatterResult(b"""\
 
1281
        start_rev = revisionspec.RevisionInfo(tree.branch, None, '1a')
 
1282
        end_rev = revisionspec.RevisionInfo(tree.branch, None, '3a')
 
1283
        self.assertFormatterResult("""\
1317
1284
------------------------------------------------------------
1318
1285
revision-id: 3a
1319
1286
committer: Joe Foo <joe@foo.com>
1336
1303
message:
1337
1304
  commit 1a
1338
1305
""",
1339
 
                                   tree.branch, log.LongLogFormatter, show_log_kwargs={
1340
 
                                       'start_revision': start_rev, 'end_revision': end_rev
1341
 
                                       })
 
1306
            tree.branch, log.LongLogFormatter, show_log_kwargs={
 
1307
                'start_revision': start_rev, 'end_revision': end_rev
 
1308
            })
1342
1309
 
1343
1310
    def test_short_format(self):
1344
1311
        tree = self.setup_ab_tree()
1345
 
        start_rev = revisionspec.RevisionInfo(tree.branch, None, b'1a')
1346
 
        end_rev = revisionspec.RevisionInfo(tree.branch, None, b'3a')
1347
 
        self.assertFormatterResult(b"""\
 
1312
        start_rev = revisionspec.RevisionInfo(tree.branch, None, '1a')
 
1313
        end_rev = revisionspec.RevisionInfo(tree.branch, None, '3a')
 
1314
        self.assertFormatterResult("""\
1348
1315
      Joe Foo\t2005-11-22
1349
1316
      revision-id:3a
1350
1317
      commit 3a
1357
1324
      commit 1a
1358
1325
 
1359
1326
""",
1360
 
                                   tree.branch, log.ShortLogFormatter, show_log_kwargs={
1361
 
                                       'start_revision': start_rev, 'end_revision': end_rev
1362
 
                                       })
 
1327
            tree.branch, log.ShortLogFormatter, show_log_kwargs={
 
1328
                'start_revision': start_rev, 'end_revision': end_rev
 
1329
            })
1363
1330
 
1364
1331
    def test_line_format(self):
1365
1332
        tree = self.setup_ab_tree()
1366
 
        start_rev = revisionspec.RevisionInfo(tree.branch, None, b'1a')
1367
 
        end_rev = revisionspec.RevisionInfo(tree.branch, None, b'3a')
1368
 
        self.assertFormatterResult(b"""\
 
1333
        start_rev = revisionspec.RevisionInfo(tree.branch, None, '1a')
 
1334
        end_rev = revisionspec.RevisionInfo(tree.branch, None, '3a')
 
1335
        self.assertFormatterResult("""\
1369
1336
Joe Foo 2005-11-22 commit 3a
1370
1337
Joe Foo 2005-11-22 commit 2a
1371
1338
1: Joe Foo 2005-11-22 commit 1a
1372
1339
""",
1373
 
                                   tree.branch, log.LineLogFormatter, show_log_kwargs={
1374
 
                                       'start_revision': start_rev, 'end_revision': end_rev
1375
 
                                       })
 
1340
            tree.branch, log.LineLogFormatter, show_log_kwargs={
 
1341
                'start_revision': start_rev, 'end_revision': end_rev
 
1342
            })
1376
1343
 
1377
1344
 
1378
1345
class TestLogWithBugs(TestCaseForLogFormatter, TestLogMixin):
1388
1355
        tree = self.make_branch_and_tree(u'.')
1389
1356
        self.build_tree(['a', 'b'])
1390
1357
        tree.add('a')
1391
 
        self.wt_commit(tree, 'simple log message', rev_id=b'a1',
1392
 
                       revprops={u'bugs': 'test://bug/id fixed'})
 
1358
        self.wt_commit(tree, 'simple log message', rev_id='a1',
 
1359
                       revprops={'bugs': 'test://bug/id fixed'})
1393
1360
        tree.add('b')
1394
 
        self.wt_commit(tree, 'multiline\nlog\nmessage\n', rev_id=b'a2',
 
1361
        self.wt_commit(tree, 'multiline\nlog\nmessage\n', rev_id='a2',
1395
1362
                       authors=['Joe Bar <joe@bar.com>'],
1396
 
                       revprops={u'bugs': 'test://bug/id fixed\n'
 
1363
                       revprops={'bugs': 'test://bug/id fixed\n'
1397
1364
                                 'test://bug/2 fixed'})
1398
1365
        return tree
1399
1366
 
1400
 
    def test_bug_broken(self):
1401
 
        tree = self.make_branch_and_tree(u'.')
1402
 
        self.build_tree(['a', 'b'])
1403
 
        tree.add('a')
1404
 
        self.wt_commit(tree, 'simple log message', rev_id=b'a1',
1405
 
                       revprops={u'bugs': 'test://bua g/id fixed'})
1406
 
 
1407
 
        logfile = self.make_utf8_encoded_stringio()
1408
 
        formatter = log.LongLogFormatter(to_file=logfile)
1409
 
        log.show_log(tree.branch, formatter)
1410
 
 
1411
 
        self.assertContainsRe(
1412
 
            logfile.getvalue(),
1413
 
            b'brz: ERROR: breezy.bugtracker.InvalidLineInBugsProperty: '
1414
 
            b'Invalid line in bugs property: \'test://bua g/id fixed\'')
1415
 
 
1416
 
        text = logfile.getvalue()
1417
 
        self.assertEqualDiff(
1418
 
            text[text.index(b'-' * 60):],
1419
 
            b"""\
1420
 
------------------------------------------------------------
1421
 
revno: 1
1422
 
committer: Joe Foo <joe@foo.com>
1423
 
branch nick: work
1424
 
timestamp: Tue 2005-11-22 00:00:00 +0000
1425
 
message:
1426
 
  simple log message
1427
 
""")
1428
1367
 
1429
1368
    def test_long_bugs(self):
1430
1369
        tree = self.make_commits_with_bugs()
1431
 
        self.assertFormatterResult(b"""\
 
1370
        self.assertFormatterResult("""\
1432
1371
------------------------------------------------------------
1433
1372
revno: 2
1434
1373
fixes bugs: test://bug/id test://bug/2
1449
1388
message:
1450
1389
  simple log message
1451
1390
""",
1452
 
                                   tree.branch, log.LongLogFormatter)
 
1391
            tree.branch, log.LongLogFormatter)
1453
1392
 
1454
1393
    def test_short_bugs(self):
1455
1394
        tree = self.make_commits_with_bugs()
1456
 
        self.assertFormatterResult(b"""\
 
1395
        self.assertFormatterResult("""\
1457
1396
    2 Joe Bar\t2005-11-22
1458
1397
      fixes bugs: test://bug/id test://bug/2
1459
1398
      multiline
1465
1404
      simple log message
1466
1405
 
1467
1406
""",
1468
 
                                   tree.branch, log.ShortLogFormatter)
 
1407
            tree.branch, log.ShortLogFormatter)
1469
1408
 
1470
1409
    def test_wrong_bugs_property(self):
1471
1410
        tree = self.make_branch_and_tree(u'.')
1472
1411
        self.build_tree(['foo'])
1473
 
        self.wt_commit(tree, 'simple log message', rev_id=b'a1',
1474
 
                       revprops={u'bugs': 'test://bug/id invalid_value'})
1475
 
 
1476
 
        logfile = self.make_utf8_encoded_stringio()
1477
 
        formatter = log.ShortLogFormatter(to_file=logfile)
1478
 
        log.show_log(tree.branch, formatter)
1479
 
 
1480
 
        lines = logfile.getvalue().splitlines()
1481
 
 
1482
 
        self.assertEqual(
1483
 
            lines[0], b'    1 Joe Foo\t2005-11-22')
1484
 
 
1485
 
        self.assertEqual(
1486
 
            lines[1],
1487
 
            b'brz: ERROR: breezy.bugtracker.InvalidBugStatus: Invalid '
1488
 
            b'bug status: \'invalid_value\'')
1489
 
 
1490
 
        self.assertEqual(lines[-2], b"      simple log message")
 
1412
        self.wt_commit(tree, 'simple log message', rev_id='a1',
 
1413
                       revprops={'bugs': 'test://bug/id invalid_value'})
 
1414
        self.assertFormatterResult("""\
 
1415
    1 Joe Foo\t2005-11-22
 
1416
      simple log message
 
1417
 
 
1418
""",
 
1419
            tree.branch, log.ShortLogFormatter)
1491
1420
 
1492
1421
    def test_bugs_handler_present(self):
1493
1422
        self.properties_handler_registry.get('bugs_properties_handler')
1498
1427
    def setUp(self):
1499
1428
        super(TestLogForAuthors, self).setUp()
1500
1429
        self.wt = self.make_standard_commit('nicky',
1501
 
                                            authors=['John Doe <jdoe@example.com>',
1502
 
                                                     'Jane Rey <jrey@example.com>'])
 
1430
            authors=['John Doe <jdoe@example.com>',
 
1431
                     'Jane Rey <jrey@example.com>'])
1503
1432
 
1504
1433
    def assertFormatterResult(self, formatter, who, result):
1505
1434
        formatter_kwargs = dict()
1507
1436
            author_list_handler = log.author_list_registry.get(who)
1508
1437
            formatter_kwargs['author_list_handler'] = author_list_handler
1509
1438
        TestCaseForLogFormatter.assertFormatterResult(self, result,
1510
 
                                                      self.wt.branch, formatter, formatter_kwargs=formatter_kwargs)
 
1439
            self.wt.branch, formatter, formatter_kwargs=formatter_kwargs)
1511
1440
 
1512
1441
    def test_line_default(self):
1513
 
        self.assertFormatterResult(log.LineLogFormatter, None, b"""\
 
1442
        self.assertFormatterResult(log.LineLogFormatter, None, """\
1514
1443
1: John Doe 2005-11-22 add a
1515
1444
""")
1516
1445
 
1517
1446
    def test_line_committer(self):
1518
 
        self.assertFormatterResult(log.LineLogFormatter, 'committer', b"""\
 
1447
        self.assertFormatterResult(log.LineLogFormatter, 'committer', """\
1519
1448
1: Lorem Ipsum 2005-11-22 add a
1520
1449
""")
1521
1450
 
1522
1451
    def test_line_first(self):
1523
 
        self.assertFormatterResult(log.LineLogFormatter, 'first', b"""\
 
1452
        self.assertFormatterResult(log.LineLogFormatter, 'first', """\
1524
1453
1: John Doe 2005-11-22 add a
1525
1454
""")
1526
1455
 
1527
1456
    def test_line_all(self):
1528
 
        self.assertFormatterResult(log.LineLogFormatter, 'all', b"""\
 
1457
        self.assertFormatterResult(log.LineLogFormatter, 'all', """\
1529
1458
1: John Doe, Jane Rey 2005-11-22 add a
1530
1459
""")
1531
1460
 
 
1461
 
1532
1462
    def test_short_default(self):
1533
 
        self.assertFormatterResult(log.ShortLogFormatter, None, b"""\
 
1463
        self.assertFormatterResult(log.ShortLogFormatter, None, """\
1534
1464
    1 John Doe\t2005-11-22
1535
1465
      add a
1536
1466
 
1537
1467
""")
1538
1468
 
1539
1469
    def test_short_committer(self):
1540
 
        self.assertFormatterResult(log.ShortLogFormatter, 'committer', b"""\
 
1470
        self.assertFormatterResult(log.ShortLogFormatter, 'committer', """\
1541
1471
    1 Lorem Ipsum\t2005-11-22
1542
1472
      add a
1543
1473
 
1544
1474
""")
1545
1475
 
1546
1476
    def test_short_first(self):
1547
 
        self.assertFormatterResult(log.ShortLogFormatter, 'first', b"""\
 
1477
        self.assertFormatterResult(log.ShortLogFormatter, 'first', """\
1548
1478
    1 John Doe\t2005-11-22
1549
1479
      add a
1550
1480
 
1551
1481
""")
1552
1482
 
1553
1483
    def test_short_all(self):
1554
 
        self.assertFormatterResult(log.ShortLogFormatter, 'all', b"""\
 
1484
        self.assertFormatterResult(log.ShortLogFormatter, 'all', """\
1555
1485
    1 John Doe, Jane Rey\t2005-11-22
1556
1486
      add a
1557
1487
 
1558
1488
""")
1559
1489
 
1560
1490
    def test_long_default(self):
1561
 
        self.assertFormatterResult(log.LongLogFormatter, None, b"""\
 
1491
        self.assertFormatterResult(log.LongLogFormatter, None, """\
1562
1492
------------------------------------------------------------
1563
1493
revno: 1
1564
1494
author: John Doe <jdoe@example.com>, Jane Rey <jrey@example.com>
1570
1500
""")
1571
1501
 
1572
1502
    def test_long_committer(self):
1573
 
        self.assertFormatterResult(log.LongLogFormatter, 'committer', b"""\
 
1503
        self.assertFormatterResult(log.LongLogFormatter, 'committer', """\
1574
1504
------------------------------------------------------------
1575
1505
revno: 1
1576
1506
committer: Lorem Ipsum <test@example.com>
1581
1511
""")
1582
1512
 
1583
1513
    def test_long_first(self):
1584
 
        self.assertFormatterResult(log.LongLogFormatter, 'first', b"""\
 
1514
        self.assertFormatterResult(log.LongLogFormatter, 'first', """\
1585
1515
------------------------------------------------------------
1586
1516
revno: 1
1587
1517
author: John Doe <jdoe@example.com>
1593
1523
""")
1594
1524
 
1595
1525
    def test_long_all(self):
1596
 
        self.assertFormatterResult(log.LongLogFormatter, 'all', b"""\
 
1526
        self.assertFormatterResult(log.LongLogFormatter, 'all', """\
1597
1527
------------------------------------------------------------
1598
1528
revno: 1
1599
1529
author: John Doe <jdoe@example.com>, Jane Rey <jrey@example.com>
1605
1535
""")
1606
1536
 
1607
1537
    def test_gnu_changelog_default(self):
1608
 
        self.assertFormatterResult(log.GnuChangelogLogFormatter, None, b"""\
 
1538
        self.assertFormatterResult(log.GnuChangelogLogFormatter, None, """\
1609
1539
2005-11-22  John Doe  <jdoe@example.com>
1610
1540
 
1611
1541
\tadd a
1613
1543
""")
1614
1544
 
1615
1545
    def test_gnu_changelog_committer(self):
1616
 
        self.assertFormatterResult(log.GnuChangelogLogFormatter, 'committer', b"""\
 
1546
        self.assertFormatterResult(log.GnuChangelogLogFormatter, 'committer', """\
1617
1547
2005-11-22  Lorem Ipsum  <test@example.com>
1618
1548
 
1619
1549
\tadd a
1621
1551
""")
1622
1552
 
1623
1553
    def test_gnu_changelog_first(self):
1624
 
        self.assertFormatterResult(log.GnuChangelogLogFormatter, 'first', b"""\
 
1554
        self.assertFormatterResult(log.GnuChangelogLogFormatter, 'first', """\
1625
1555
2005-11-22  John Doe  <jdoe@example.com>
1626
1556
 
1627
1557
\tadd a
1629
1559
""")
1630
1560
 
1631
1561
    def test_gnu_changelog_all(self):
1632
 
        self.assertFormatterResult(log.GnuChangelogLogFormatter, 'all', b"""\
 
1562
        self.assertFormatterResult(log.GnuChangelogLogFormatter, 'all', """\
1633
1563
2005-11-22  John Doe  <jdoe@example.com>, Jane Rey  <jrey@example.com>
1634
1564
 
1635
1565
\tadd a
1659
1589
        # | /
1660
1590
        # 3
1661
1591
        builder.start_series()
1662
 
        builder.build_snapshot(None, [
1663
 
            ('add', ('', b'TREE_ROOT', 'directory', '')), ],
1664
 
            revision_id=b'1')
1665
 
        builder.build_snapshot([b'1'], [], revision_id=b'1.1.1')
1666
 
        builder.build_snapshot([b'1'], [], revision_id=b'2')
1667
 
        builder.build_snapshot([b'1.1.1'], [], revision_id=b'1.2.1')
1668
 
        builder.build_snapshot([b'1.1.1', b'1.2.1'], [], revision_id=b'1.1.2')
1669
 
        builder.build_snapshot([b'2', b'1.1.2'], [], revision_id=b'3')
 
1592
        builder.build_snapshot('1', None, [
 
1593
            ('add', ('', 'TREE_ROOT', 'directory', '')),])
 
1594
        builder.build_snapshot('1.1.1', ['1'], [])
 
1595
        builder.build_snapshot('2', ['1'], [])
 
1596
        builder.build_snapshot('1.2.1', ['1.1.1'], [])
 
1597
        builder.build_snapshot('1.1.2', ['1.1.1', '1.2.1'], [])
 
1598
        builder.build_snapshot('3', ['2', '1.1.2'], [])
1670
1599
        builder.finish_series()
1671
1600
        br = builder.get_branch()
1672
1601
        br.lock_read()
1687
1616
 
1688
1617
    def test_merge_sorted_exclude_ancestry(self):
1689
1618
        b = self.make_branch_with_alternate_ancestries()
1690
 
        self.assertLogRevnos([b'3', b'1.1.2', b'1.2.1', b'1.1.1', b'2', b'1'],
1691
 
                             b, b'1', b'3', exclude_common_ancestry=False)
 
1619
        self.assertLogRevnos(['3', '1.1.2', '1.2.1', '1.1.1', '2', '1'],
 
1620
                             b, '1', '3', exclude_common_ancestry=False)
1692
1621
        # '2' is part of the '3' ancestry but not part of '1.1.1' ancestry so
1693
1622
        # it should be mentioned even if merge_sort order will make it appear
1694
1623
        # after 1.1.1
1695
 
        self.assertLogRevnos([b'3', b'1.1.2', b'1.2.1', b'2'],
1696
 
                             b, b'1.1.1', b'3', exclude_common_ancestry=True)
 
1624
        self.assertLogRevnos(['3', '1.1.2', '1.2.1', '2'],
 
1625
                             b, '1.1.1', '3', exclude_common_ancestry=True)
1697
1626
 
1698
1627
    def test_merge_sorted_simple_revnos_exclude_ancestry(self):
1699
1628
        b = self.make_branch_with_alternate_ancestries()
1700
 
        self.assertLogRevnos([b'3', b'2'],
1701
 
                             b, b'1', b'3', exclude_common_ancestry=True,
 
1629
        self.assertLogRevnos(['3', '2'],
 
1630
                             b, '1', '3', exclude_common_ancestry=True,
1702
1631
                             generate_merge_revisions=False)
1703
 
        self.assertLogRevnos([b'3', b'1.1.2', b'1.2.1', b'1.1.1', b'2'],
1704
 
                             b, b'1', b'3', exclude_common_ancestry=True,
 
1632
        self.assertLogRevnos(['3', '1.1.2', '1.2.1', '1.1.1', '2'],
 
1633
                             b, '1', '3', exclude_common_ancestry=True,
1705
1634
                             generate_merge_revisions=True)
1706
1635
 
1707
1636
 
1720
1649
            def __init__(self, *args, **kwargs):
1721
1650
                super(CustomLogFormatter, self).__init__(*args, **kwargs)
1722
1651
                self.revisions = []
1723
 
 
1724
1652
            def get_levels(self):
1725
1653
                # log formatter supports all levels:
1726
1654
                return 0
1727
 
 
1728
1655
            def log_revision(self, revision):
1729
1656
                self.revisions.append(revision)
1730
1657
 
1744
1671
        log.Logger(b, request).show(log_formatter)
1745
1672
        # should now only have 2 revisions:
1746
1673
        self.assertEqual(len(log_formatter.revisions), 2)
 
1674