256
256
def assertUseShortDeltaFormat(self, cmd):
257
257
log = self.run_bzr(cmd)[0]
258
258
# Check that we use the short status format
259
self.assertContainsRe(log, '(?m)^A hello.txt$')
260
self.assertNotContainsRe(log, '(?m)^added:$')
259
self.assertContainsRe(log, '(?m)^\s*A hello.txt$')
260
self.assertNotContainsRe(log, '(?m)^\s*added:$')
262
262
def assertUseLongDeltaFormat(self, cmd):
263
263
log = self.run_bzr(cmd)[0]
264
264
# Check that we use the long status format
265
self.assertNotContainsRe(log, '(?m)^A hello.txt$')
266
self.assertContainsRe(log, '(?m)^added:$')
265
self.assertNotContainsRe(log, '(?m)^\s*A hello.txt$')
266
self.assertContainsRe(log, '(?m)^\s*added:$')
268
268
def test_log_short_verbose(self):
269
269
self.assertUseShortDeltaFormat(['log', '--short', '-v'])
298
298
parent_tree.commit(message='merge branch 1')
299
299
os.chdir('parent')
301
def _prepare_short(self):
302
parent_tree = self.make_branch_and_tree('parent')
303
parent_tree.commit(message='first post',
304
timestamp=1132586700, timezone=36000,
305
committer='Joe Foo <joe@foo.com>')
306
child_tree = parent_tree.bzrdir.sprout('child').open_workingtree()
307
child_tree.commit(message='branch 1',
308
timestamp=1132586800, timezone=36000,
309
committer='Joe Foo <joe@foo.com>')
311
child_tree.bzrdir.sprout('smallerchild').open_workingtree()
312
smaller_tree.commit(message='branch 2',
313
timestamp=1132586900, timezone=36000,
314
committer='Joe Foo <joe@foo.com>')
315
child_tree.merge_from_branch(smaller_tree.branch)
316
child_tree.commit(message='merge branch 2',
317
timestamp=1132587000, timezone=36000,
318
committer='Joe Foo <joe@foo.com>')
319
parent_tree.merge_from_branch(child_tree.branch)
320
parent_tree.commit(message='merge branch 1',
321
timestamp=1132587100, timezone=36000,
322
committer='Joe Foo <joe@foo.com>')
301
325
def test_merges_are_indented_by_level(self):
303
327
out,err = self.run_bzr('log')
368
def test_force_merge_revisions_off(self):
370
out,err = self.run_bzr('log --long -n1')
371
self.assertEqual('', err)
372
log = normalize_log(out)
373
self.assertEqualDiff(log, """\
374
------------------------------------------------------------
376
committer: Lorem Ipsum <test@example.com>
381
------------------------------------------------------------
383
committer: Lorem Ipsum <test@example.com>
390
def test_force_merge_revisions_on(self):
391
self._prepare_short()
392
out,err = self.run_bzr('log --short -n0')
393
self.assertEqual('', err)
394
log = normalize_log(out)
395
self.assertEqualDiff(log, """\
396
2 Joe Foo\t2005-11-22 [merge]
399
1.1.2 Joe Foo\t2005-11-22 [merge]
402
1.2.1 Joe Foo\t2005-11-22
405
1.1.1 Joe Foo\t2005-11-22
408
1 Joe Foo\t2005-11-22
413
def test_force_merge_revisions_N(self):
414
self._prepare_short()
415
out,err = self.run_bzr('log --short -n2')
416
self.assertEqual('', err)
417
log = normalize_log(out)
418
self.assertEqualDiff(log, """\
419
2 Joe Foo\t2005-11-22 [merge]
422
1.1.2 Joe Foo\t2005-11-22 [merge]
425
1.1.1 Joe Foo\t2005-11-22
428
1 Joe Foo\t2005-11-22
344
433
def test_merges_single_merge_rev(self):
346
435
out,err = self.run_bzr('log -r1.1.2')
403
496
self.assertContainsRe(err, err_msg)
499
def subst_dates(string):
500
"""Replace date strings with constant values."""
501
return re.sub(r'\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} [-\+]\d{4}',
502
'YYYY-MM-DD HH:MM:SS +ZZZZ', string)
505
class TestLogDiff(TestCaseWithoutPropsHandler):
508
parent_tree = self.make_branch_and_tree('parent')
509
self.build_tree(['parent/file1', 'parent/file2'])
510
parent_tree.add('file1')
511
parent_tree.add('file2')
512
parent_tree.commit(message='first post',
513
timestamp=1132586655, timezone=36000,
514
committer='Lorem Ipsum <test@example.com>')
515
child_tree = parent_tree.bzrdir.sprout('child').open_workingtree()
516
self.build_tree_contents([('child/file2', 'hello\n')])
517
child_tree.commit(message='branch 1',
518
timestamp=1132586700, timezone=36000,
519
committer='Lorem Ipsum <test@example.com>')
520
parent_tree.merge_from_branch(child_tree.branch)
521
parent_tree.commit(message='merge branch 1',
522
timestamp=1132586800, timezone=36000,
523
committer='Lorem Ipsum <test@example.com>')
526
def test_log_show_diff_long(self):
528
out,err = self.run_bzr('log -p')
529
self.assertEqual('', err)
530
log = normalize_log(out)
531
self.assertEqualDiff(subst_dates(log), """\
532
------------------------------------------------------------
534
committer: Lorem Ipsum <test@example.com>
540
=== modified file 'file2'
541
--- file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
542
+++ file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
544
-contents of parent/file2
546
------------------------------------------------------------
548
committer: Lorem Ipsum <test@example.com>
554
=== modified file 'file2'
555
--- file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
556
+++ file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
558
-contents of parent/file2
560
------------------------------------------------------------
562
committer: Lorem Ipsum <test@example.com>
568
=== added file 'file1'
569
--- file1\tYYYY-MM-DD HH:MM:SS +ZZZZ
570
+++ file1\tYYYY-MM-DD HH:MM:SS +ZZZZ
572
+contents of parent/file1
574
=== added file 'file2'
575
--- file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
576
+++ file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
578
+contents of parent/file2
581
def test_log_show_diff_short(self):
583
out,err = self.run_bzr('log -p --short')
584
self.assertEqual('', err)
585
log = normalize_log(out)
586
self.assertEqualDiff(subst_dates(log), """\
587
2 Lorem Ipsum\t2005-11-22 [merge]
589
=== modified file 'file2'
590
--- file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
591
+++ file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
593
-contents of parent/file2
596
1 Lorem Ipsum\t2005-11-22
598
=== added file 'file1'
599
--- file1\tYYYY-MM-DD HH:MM:SS +ZZZZ
600
+++ file1\tYYYY-MM-DD HH:MM:SS +ZZZZ
602
+contents of parent/file1
603
\x20\x20\x20\x20\x20\x20
604
=== added file 'file2'
605
--- file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
606
+++ file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
608
+contents of parent/file2
612
def test_log_show_diff_line(self):
614
out,err = self.run_bzr('log -p --line')
615
self.assertEqual('', err)
616
log = normalize_log(out)
617
# Not supported by this formatter so expect plain output
618
self.assertEqualDiff(subst_dates(log), """\
619
2: Lorem Ipsum 2005-11-22 [merge] merge branch 1
620
1: Lorem Ipsum 2005-11-22 first post
623
def test_log_show_diff_file(self):
624
"""Only the diffs for the given file are to be shown"""
626
out,err = self.run_bzr('log -p --short file2')
627
self.assertEqual('', err)
628
log = normalize_log(out)
629
self.assertEqualDiff(subst_dates(log), """\
630
2 Lorem Ipsum\t2005-11-22 [merge]
632
=== modified file 'file2'
633
--- file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
634
+++ file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
636
-contents of parent/file2
639
1 Lorem Ipsum\t2005-11-22
641
=== added file 'file2'
642
--- file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
643
+++ file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
645
+contents of parent/file2
648
out,err = self.run_bzr('log -p --short file1')
649
self.assertEqual('', err)
650
log = normalize_log(out)
651
self.assertEqualDiff(subst_dates(log), """\
652
1 Lorem Ipsum\t2005-11-22
654
=== added file 'file1'
655
--- file1\tYYYY-MM-DD HH:MM:SS +ZZZZ
656
+++ file1\tYYYY-MM-DD HH:MM:SS +ZZZZ
658
+contents of parent/file1
662
def test_log_show_diff_non_ascii(self):
663
# Smoke test for bug #328007 UnicodeDecodeError on 'log -p'
664
message = u'Message with \xb5'
665
body = 'Body with \xb5\n'
666
wt = self.make_branch_and_tree('.')
667
self.build_tree_contents([('foo', body)])
669
wt.commit(message=message)
670
# check that command won't fail with unicode error
671
# don't care about exact output because we have other tests for this
672
out,err = self.run_bzr('log -p --long')
673
self.assertNotEqual('', out)
674
self.assertEqual('', err)
675
out,err = self.run_bzr('log -p --short')
676
self.assertNotEqual('', out)
677
self.assertEqual('', err)
678
out,err = self.run_bzr('log -p --line')
679
self.assertNotEqual('', out)
680
self.assertEqual('', err)
406
683
class TestLogEncodings(TestCaseInTempDir):
577
862
self.assertNotContainsRe(log, 'revno: 3.1.1\n')
578
863
self.assertNotContainsRe(log, 'revno: 4\n')
865
def test_log_file_historical_missing(self):
866
# Check logging a deleted file gives an error if the
867
# file isn't found at the end or start of the revision range
868
self.prepare_tree(complex=True)
869
err_msg = "Path unknown at end or start of revision range: file2"
870
err = self.run_bzr('log file2', retcode=3)[1]
871
self.assertContainsRe(err, err_msg)
873
def test_log_file_historical_end(self):
874
# Check logging a deleted file is ok if the file existed
875
# at the end the revision range
876
self.prepare_tree(complex=True)
877
log, err = self.run_bzr('log -r..4 file2')
878
self.assertEquals('', err)
879
self.assertNotContainsRe(log, 'revno: 1\n')
880
self.assertContainsRe(log, 'revno: 2\n')
881
self.assertNotContainsRe(log, 'revno: 3\n')
882
self.assertContainsRe(log, 'revno: 3.1.1\n')
883
self.assertContainsRe(log, 'revno: 4\n')
885
def test_log_file_historical_start(self):
886
# Check logging a deleted file is ok if the file existed
887
# at the start of the revision range
888
self.prepare_tree(complex=True)
889
log, err = self.run_bzr('log file1')
890
self.assertEquals('', err)
891
self.assertContainsRe(log, 'revno: 1\n')
892
self.assertNotContainsRe(log, 'revno: 2\n')
893
self.assertNotContainsRe(log, 'revno: 3\n')
894
self.assertNotContainsRe(log, 'revno: 3.1.1\n')
895
self.assertNotContainsRe(log, 'revno: 4\n')
897
def test_log_file_renamed(self):
898
"""File matched against revision range, not current tree."""
899
self.prepare_tree(complex=True)
901
# Check logging a renamed file gives an error by default
902
err_msg = "Path unknown at end or start of revision range: file3"
903
err = self.run_bzr('log file3', retcode=3)[1]
904
self.assertContainsRe(err, err_msg)
906
# Check we can see a renamed file if we give the right end revision
907
log, err = self.run_bzr('log -r..4 file3')
908
self.assertEquals('', err)
909
self.assertNotContainsRe(log, 'revno: 1\n')
910
self.assertNotContainsRe(log, 'revno: 2\n')
911
self.assertContainsRe(log, 'revno: 3\n')
912
self.assertNotContainsRe(log, 'revno: 3.1.1\n')
913
self.assertNotContainsRe(log, 'revno: 4\n')
580
915
def test_line_log_file(self):
581
916
"""The line log for a file should only list relevant mainline revs"""
582
917
# Note: this also implicitly covers the short logging case.