214
builder.build_snapshot(None, [
215
('add', ('', b'root-id', 'directory', ''))],
217
builder.build_snapshot([b'1'], [], revision_id=b'2')
216
builder.build_snapshot('1', None, [
217
('add', ('', 'root-id', 'directory', ''))])
218
builder.build_snapshot('2', ['1'], [])
219
builder.build_snapshot([b'1'], [], revision_id=b'1.1.1')
220
builder.build_snapshot('1.1.1', ['1'], [])
220
221
# merge branch into mainline
221
builder.build_snapshot([b'2', b'1.1.1'], [], revision_id=b'3')
222
builder.build_snapshot('3', ['2', '1.1.1'], [])
222
223
# new commits in branch
223
builder.build_snapshot([b'1.1.1'], [], revision_id=b'1.1.2')
224
builder.build_snapshot([b'1.1.2'], [], revision_id=b'1.1.3')
224
builder.build_snapshot('1.1.2', ['1.1.1'], [])
225
builder.build_snapshot('1.1.3', ['1.1.2'], [])
225
226
# merge branch into mainline
226
builder.build_snapshot([b'3', b'1.1.3'], [], revision_id=b'4')
227
builder.build_snapshot('4', ['3', '1.1.3'], [])
227
228
# merge mainline into branch
228
builder.build_snapshot([b'1.1.3', b'4'], [], revision_id=b'1.1.4')
229
builder.build_snapshot('1.1.4', ['1.1.3', '4'], [])
229
230
# merge branch into mainline
230
builder.build_snapshot([b'4', b'1.1.4'], [], revision_id=b'5')
231
builder.build_snapshot([b'5'], [], revision_id=b'5.1.1')
232
builder.build_snapshot([b'5', b'5.1.1'], [], revision_id=b'6')
231
builder.build_snapshot('5', ['4', '1.1.4'], [])
232
builder.build_snapshot('5.1.1', ['5'], [])
233
builder.build_snapshot('6', ['5', '5.1.1'], [])
233
234
builder.finish_series()
235
236
def test_n0(self):
236
237
self.assertLogRevnos(['-n0', '-r1.1.1..1.1.4'],
237
238
['1.1.4', '4', '1.1.3', '1.1.2', '3', '1.1.1'])
239
239
def test_n0_forward(self):
240
240
self.assertLogRevnos(['-n0', '-r1.1.1..1.1.4', '--forward'],
241
241
['3', '1.1.1', '4', '1.1.2', '1.1.3', '1.1.4'])
287
builder.build_snapshot(None, [
288
('add', ('', b'root-id', 'directory', ''))], revision_id=b'1')
289
builder.build_snapshot([b'1'], [], revision_id=b'2')
290
builder.build_snapshot([b'1'], [], revision_id=b'1.1.1')
291
builder.build_snapshot([b'2'], [], revision_id=b'2.1.1')
292
builder.build_snapshot([b'2', b'1.1.1'], [], revision_id=b'3')
293
builder.build_snapshot([b'2.1.1'], [], revision_id=b'2.1.2')
294
builder.build_snapshot([b'2.1.1'], [], revision_id=b'2.2.1')
295
builder.build_snapshot([b'2.1.2', b'2.2.1'], [], revision_id=b'2.1.3')
296
builder.build_snapshot([b'3', b'2.1.3'], [], revision_id=b'4')
297
builder.build_snapshot([b'4', b'2.1.2'], [], revision_id=b'5')
287
builder.build_snapshot('1', None, [
288
('add', ('', 'root-id', 'directory', ''))])
289
builder.build_snapshot('2', ['1'], [])
290
builder.build_snapshot('1.1.1', ['1'], [])
291
builder.build_snapshot('2.1.1', ['2'], [])
292
builder.build_snapshot('3', ['2', '1.1.1'], [])
293
builder.build_snapshot('2.1.2', ['2.1.1'], [])
294
builder.build_snapshot('2.2.1', ['2.1.1'], [])
295
builder.build_snapshot('2.1.3', ['2.1.2', '2.2.1'], [])
296
builder.build_snapshot('4', ['3', '2.1.3'], [])
297
builder.build_snapshot('5', ['4', '2.1.2'], [])
298
298
builder.finish_series()
301
301
def test_not_an_ancestor(self):
302
self.assertRaises(errors.CommandError,
302
self.assertRaises(errors.BzrCommandError,
303
303
log._generate_all_revisions,
304
304
self.branch, '1.1.1', '2.1.3', 'reverse',
305
305
delayed_graph_generation=True)
307
307
def test_wrong_order(self):
308
self.assertRaises(errors.CommandError,
308
self.assertRaises(errors.BzrCommandError,
309
309
log._generate_all_revisions,
310
310
self.branch, '5', '2.1.3', 'reverse',
311
311
delayed_graph_generation=True)
382
382
def test_log_change_single_revno_only(self):
383
383
self.make_minimal_branch()
384
384
self.run_bzr_error(['brz: ERROR: Option --change does not'
385
' accept revision ranges'],
385
' accept revision ranges'],
386
386
['log', '--change', '2..3'])
388
388
def test_log_change_incompatible_with_revision(self):
389
389
self.run_bzr_error(['brz: ERROR: --revision and --change'
390
' are mutually exclusive'],
390
' are mutually exclusive'],
391
391
['log', '--change', '2', '--revision', '3'])
393
393
def test_log_nonexistent_file(self):
504
502
def assertUseShortDeltaFormat(self, cmd):
505
503
log = self.run_bzr(cmd)[0]
506
504
# Check that we use the short status format
507
self.assertContainsRe(log, '(?m)^\\s*A hello.txt$')
508
self.assertNotContainsRe(log, '(?m)^\\s*added:$')
505
self.assertContainsRe(log, '(?m)^\s*A hello.txt$')
506
self.assertNotContainsRe(log, '(?m)^\s*added:$')
510
508
def assertUseLongDeltaFormat(self, cmd):
511
509
log = self.run_bzr(cmd)[0]
512
510
# Check that we use the long status format
513
self.assertNotContainsRe(log, '(?m)^\\s*A hello.txt$')
514
self.assertContainsRe(log, '(?m)^\\s*added:$')
511
self.assertNotContainsRe(log, '(?m)^\s*A hello.txt$')
512
self.assertContainsRe(log, '(?m)^\s*added:$')
516
514
def test_log_short_verbose(self):
517
515
self.assertUseShortDeltaFormat(['log', '--short', '-v'])
588
586
def test_merges_partial_range(self):
589
587
self.assertLogRevnosAndDepths(
590
['-n0', '-r1.1.1..1.1.2'],
591
[('1.1.2', 0), ('1.2.1', 1), ('1.1.1', 0)],
592
working_dir='level0')
588
['-n0', '-r1.1.1..1.1.2'],
589
[('1.1.2', 0), ('1.2.1', 1), ('1.1.1', 0)],
590
working_dir='level0')
594
592
def test_merges_partial_range_ignore_before_lower_bound(self):
595
593
"""Dont show revisions before the lower bound's merged revs"""
596
594
self.assertLogRevnosAndDepths(
597
['-n0', '-r1.1.2..2'],
598
[('2', 0), ('1.1.2', 1), ('1.2.1', 2)],
599
working_dir='level0')
595
['-n0', '-r1.1.2..2'],
596
[('2', 0), ('1.1.2', 1), ('1.2.1', 2)],
597
working_dir='level0')
601
599
def test_omit_merges_with_sidelines(self):
602
600
self.assertLogRevnos(['--omit-merges', '-n0'], ['1.2.1', '1.1.1', '1'],
625
623
self.wt_commit(level0, 'in branch level0')
627
625
level1 = level0.controldir.sprout('level1').open_workingtree()
628
self.build_tree_contents([('level1/file2', b'hello\n')])
626
self.build_tree_contents([('level1/file2', 'hello\n')])
629
627
self.wt_commit(level1, 'in branch level1')
630
628
level0.merge_from_branch(level1.branch)
631
629
self.wt_commit(level0, 'merge branch level1')
633
631
def _diff_file1_revno1(self):
634
return b"""=== added file 'file1'
632
return """=== added file 'file1'
635
633
--- file1\t1970-01-01 00:00:00 +0000
636
634
+++ file1\t2005-11-22 00:00:00 +0000
671
669
def assertLogRevnosAndDiff(self, args, expected,
673
671
self.run_bzr(['log', '-p'] + args, working_dir=working_dir)
674
672
expected_revnos_and_depths = [
675
673
(revno, depth) for revno, depth, diff in expected]
676
674
# Check the revnos and depths first to make debugging easier
677
675
self.assertEqual(expected_revnos_and_depths,
678
676
[(r.revno, r.merge_depth)
679
for r in self.get_captured_revisions()])
677
for r in self.get_captured_revisions()])
680
678
# Now check the diffs, adding the revno in case of failure
681
679
fmt = 'In revno %s\n%s'
682
680
for expected_rev, actual_rev in zip(expected,
692
690
[('2', 0, self._diff_file2_revno2()),
693
691
('1.1.1', 1, self._diff_file2_revno1_1_1()),
694
('1', 0, self._diff_file1_revno1() +
695
self._diff_file2_revno1())],
692
('1', 0, self._diff_file1_revno1()
693
+ self._diff_file2_revno1())],
696
694
working_dir='level0')
698
697
def test_log_diff_file1(self):
699
698
self.assertLogRevnosAndDiff(['-n0', 'file1'],
700
699
[('1', 0, self._diff_file1_revno1())],
712
711
def test_log_show_diff_non_ascii(self):
713
712
# Smoke test for bug #328007 UnicodeDecodeError on 'log -p'
714
713
message = u'Message with \xb5'
715
body = b'Body with \xb5\n'
714
body = 'Body with \xb5\n'
716
715
wt = self.make_branch_and_tree('.')
717
716
self.build_tree_contents([('foo', body)])
719
718
wt.commit(message=message)
720
719
# check that command won't fail with unicode error
721
720
# don't care about exact output because we have other tests for this
722
out, err = self.run_bzr('log -p --long')
723
self.assertNotEqual('', out)
724
self.assertEqual('', err)
725
out, err = self.run_bzr('log -p --short')
726
self.assertNotEqual('', out)
727
self.assertEqual('', err)
728
out, err = self.run_bzr('log -p --line')
721
out,err = self.run_bzr('log -p --long')
722
self.assertNotEqual('', out)
723
self.assertEqual('', err)
724
out,err = self.run_bzr('log -p --short')
725
self.assertNotEqual('', out)
726
self.assertEqual('', err)
727
out,err = self.run_bzr('log -p --line')
729
728
self.assertNotEqual('', out)
730
729
self.assertEqual('', err)
986
987
super(MainlineGhostTests, self).setUp()
987
988
tree = self.make_branch_and_tree('')
988
tree.set_parent_ids([b"spooky"], allow_leftmost_as_ghost=True)
989
tree.set_parent_ids(["spooky"], allow_leftmost_as_ghost=True)
990
tree.commit('msg1', rev_id=b'rev1')
991
tree.commit('msg2', rev_id=b'rev2')
991
tree.commit('msg1', rev_id='rev1')
992
tree.commit('msg2', rev_id='rev2')
993
994
def test_log_range(self):
994
995
self.assertLogRevnos(["-r1..2"], ["2", "1"])
1029
1028
self.assertLogRevnos(["--match-message", "message1"], ["1"])
1030
1029
self.assertLogRevnos(["--match-message", "message2"], ["2"])
1031
1030
self.assertLogRevnos(["--match-message", "message"], ["2", "1"])
1032
self.assertLogRevnos(["--match-message", "message1",
1031
self.assertLogRevnos(["--match-message", "message1",
1033
1032
"--match-message", "message2"], ["2", "1"])
1034
1033
self.assertLogRevnos(["--message", "message1"], ["1"])
1035
1034
self.assertLogRevnos(["--message", "message2"], ["2"])
1036
1035
self.assertLogRevnos(["--message", "message"], ["2", "1"])
1037
self.assertLogRevnos(["--match-message", "message1",
1036
self.assertLogRevnos(["--match-message", "message1",
1038
1037
"--message", "message2"], ["2", "1"])
1039
self.assertLogRevnos(["--message", "message1",
1038
self.assertLogRevnos(["--message", "message1",
1040
1039
"--match-message", "message2"], ["2", "1"])
1042
1041
def test_committer(self):
1044
1043
self.assertLogRevnos(["-m", "committer1"], ["1"])
1045
1044
self.assertLogRevnos(["-m", "committer2"], ["2"])
1046
1045
self.assertLogRevnos(["-m", "committer"], ["2", "1"])
1047
self.assertLogRevnos(["-m", "committer1", "-m", "committer2"],
1046
self.assertLogRevnos(["-m", "committer1", "-m", "committer2"],
1049
1048
self.assertLogRevnos(["--match-committer", "committer1"], ["1"])
1050
1049
self.assertLogRevnos(["--match-committer", "committer2"], ["2"])
1051
1050
self.assertLogRevnos(["--match-committer", "committer"], ["2", "1"])
1052
self.assertLogRevnos(["--match-committer", "committer1",
1051
self.assertLogRevnos(["--match-committer", "committer1",
1053
1052
"--match-committer", "committer2"], ["2", "1"])
1055
1054
def test_author(self):
1057
1056
self.assertLogRevnos(["-m", "author1"], ["1"])
1058
1057
self.assertLogRevnos(["-m", "author2"], ["2"])
1059
1058
self.assertLogRevnos(["-m", "author"], ["2", "1"])
1060
self.assertLogRevnos(["-m", "author1", "-m", "author2"],
1059
self.assertLogRevnos(["-m", "author1", "-m", "author2"],
1062
1061
self.assertLogRevnos(["--match-author", "author1"], ["1"])
1063
1062
self.assertLogRevnos(["--match-author", "author2"], ["2"])
1064
1063
self.assertLogRevnos(["--match-author", "author"], ["2", "1"])
1065
self.assertLogRevnos(["--match-author", "author1",
1064
self.assertLogRevnos(["--match-author", "author1",
1066
1065
"--match-author", "author2"], ["2", "1"])
1068
class TestSmartServerLog(tests.TestCaseWithTransport):
1070
def test_standard_log(self):
1071
self.setup_smart_server_with_call_log()
1072
t = self.make_branch_and_tree('branch')
1073
self.build_tree_contents([('branch/foo', 'thecontents')])
1076
self.reset_smart_call_log()
1077
out, err = self.run_bzr(['log', self.get_url('branch')])
1078
# This figure represent the amount of work to perform this use case. It
1079
# is entirely ok to reduce this number if a test fails due to rpc_count
1080
# being too low. If rpc_count increases, more network roundtrips have
1081
# become necessary for this use case. Please do not adjust this number
1082
# upwards without agreement from bzr's network support maintainers.
1083
self.assertThat(self.hpss_calls, ContainsNoVfsCalls)
1084
self.assertLength(1, self.hpss_connections)
1085
self.assertLength(9, self.hpss_calls)
1087
def test_verbose_log(self):
1088
self.setup_smart_server_with_call_log()
1089
t = self.make_branch_and_tree('branch')
1090
self.build_tree_contents([('branch/foo', 'thecontents')])
1093
self.reset_smart_call_log()
1094
out, err = self.run_bzr(['log', '-v', self.get_url('branch')])
1095
# This figure represent the amount of work to perform this use case. It
1096
# is entirely ok to reduce this number if a test fails due to rpc_count
1097
# being too low. If rpc_count increases, more network roundtrips have
1098
# become necessary for this use case. Please do not adjust this number
1099
# upwards without agreement from bzr's network support maintainers.
1100
self.assertLength(10, self.hpss_calls)
1101
self.assertLength(1, self.hpss_connections)
1102
self.assertThat(self.hpss_calls, ContainsNoVfsCalls)
1104
def test_per_file(self):
1105
self.setup_smart_server_with_call_log()
1106
t = self.make_branch_and_tree('branch')
1107
self.build_tree_contents([('branch/foo', 'thecontents')])
1110
self.reset_smart_call_log()
1111
out, err = self.run_bzr(['log', '-v', self.get_url('branch') + "/foo"])
1112
# This figure represent the amount of work to perform this use case. It
1113
# is entirely ok to reduce this number if a test fails due to rpc_count
1114
# being too low. If rpc_count increases, more network roundtrips have
1115
# become necessary for this use case. Please do not adjust this number
1116
# upwards without agreement from bzr's network support maintainers.
1117
self.assertLength(14, self.hpss_calls)
1118
self.assertLength(1, self.hpss_connections)
1119
self.assertThat(self.hpss_calls, ContainsNoVfsCalls)