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

  • Committer: Jelmer Vernooij
  • Date: 2017-05-21 12:41:27 UTC
  • mto: This revision was merged to the branch mainline in revision 6623.
  • Revision ID: jelmer@jelmer.uk-20170521124127-iv8etg0vwymyai6y
s/bzr/brz/ in apport config.

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