110
106
self.addCleanup(wt.unlock)
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')
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')
287
282
self.assertEqual('add file1 and file2', logentry.rev.message)
288
283
self.checkDelta(logentry.delta, added=['file1', 'file2'])
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([
298
('adder/dir/file', b'foo'),
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.
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')
314
lf.supports_merge_revisions = True
315
log.show_log(trunk.branch, lf, file_id)
317
self.assertEqual(['2', '1.1.1'], [r.revno for r in lf.revisions])
318
except AssertionError:
319
raise tests.KnownFailure("bug #842695")
322
286
class TestFormatSignatureValidity(tests.TestCaseWithTransport):
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>')
292
def has_signature_for_revision_id(self, revision_id):
295
def get_signature_text(self, revision_id):
328
298
def test_format_signature_validity_utf(self):
329
299
"""Check that GPG signatures containing UTF-8 names are formatted
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>',
314
u'valid signature from UTF8 Test \xa1\xb1\xc1\xd1\xe1\xf1 <jrandom@example.com>',
345
318
class TestShortLogFormatter(TestCaseForLogFormatter):
421
wt.branch, log.ShortLogFormatter)
394
wt.branch, log.ShortLogFormatter)
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
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))
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'])
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')
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]
694
wt.branch, log.LongLogFormatter)
665
wt.branch, log.LongLogFormatter)
696
667
def test_properties_in_short_log(self):
697
668
"""Log includes the custom properties returned by the registered
700
671
wt = self.make_standard_commit('test_properties_in_short_log')
702
672
def trivial_custom_prop_handler(revision):
703
return {'test_prop': 'test_value'}
673
return {'test_prop':'test_value'}
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
714
wt.branch, log.ShortLogFormatter)
684
wt.branch, log.ShortLogFormatter)
716
686
def test_error_in_properties_handler(self):
717
687
"""Log includes the custom properties returned by the registered
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)
725
694
def trivial_custom_prop_handler(revision):
726
raise Exception("a test error")
695
raise StandardError("a test error")
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,)
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)
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']}
744
710
log.properties_handler_registry.register(
745
711
'bad_argument_prop_handler',
942
907
wt = self.make_standard_commit('test-line-log',
943
committer='Line-Log-Formatter Tester <test@line.log>',
945
self.assertFormatterResult(b"""\
908
committer='Line-Log-Formatter Tester <test@line.log>',
910
self.assertFormatterResult("""\
946
911
1: Line-Log-Formatte... 2005-11-22 add a
948
wt.branch, log.LineLogFormatter)
913
wt.branch, log.LineLogFormatter)
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
958
b, log.LineLogFormatter)
923
b, log.LineLogFormatter)
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
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))
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
977
wt.branch, log.LineLogFormatter)
942
wt.branch, log.LineLogFormatter)
980
945
class TestLineLogFormatterWithMergeRevisions(TestCaseForLogFormatter):
987
952
wt = self.make_standard_commit('test-line-log',
988
committer='Line-Log-Formatter Tester <test@line.log>',
990
self.assertFormatterResult(b"""\
953
committer='Line-Log-Formatter Tester <test@line.log>',
955
self.assertFormatterResult("""\
991
956
1: Line-Log-Formatte... 2005-11-22 add a
993
wt.branch, log.LineLogFormatter)
958
wt.branch, log.LineLogFormatter)
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
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))
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
1013
wt.branch, log.LineLogFormatter,
1014
formatter_kwargs=dict(levels=0))
978
wt.branch, log.LineLogFormatter,
979
formatter_kwargs=dict(levels=0))
1017
982
class TestGnuChangelogFormatter(TestCaseForLogFormatter):
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>
1027
wt.branch, log.GnuChangelogLogFormatter)
992
wt.branch, log.GnuChangelogLogFormatter)
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>
1039
wt.branch, log.GnuChangelogLogFormatter)
1004
wt.branch, log.GnuChangelogLogFormatter)
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>
1123
1088
Tests use (revno, depth) whil the API expects (revid, revno, depth).
1124
1089
Since the revid is arbitrary, we just duplicate revno
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))
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)])
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), ])
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.
1142
1107
Requesting revisions touching a file can produce "holes" in the depths.
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),])
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),])
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')
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')
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')
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)
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)
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)
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)
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'])
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'])
1228
1193
def test_show_branch_change(self):
1229
1194
tree = self.setup_ab_tree()
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')
1236
1201
def test_show_branch_change_no_change(self):
1237
1202
tree = self.setup_ab_tree()
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')
1243
1208
def test_show_branch_change_no_old(self):
1244
1209
tree = self.setup_ab_tree()
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:')
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')
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:')
1264
1229
self.addCleanup(tree.unlock)
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
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)
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')
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
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)
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)
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
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>
1360
tree.branch, log.ShortLogFormatter, show_log_kwargs={
1361
'start_revision': start_rev, 'end_revision': end_rev
1325
tree.branch, log.ShortLogFormatter, show_log_kwargs={
1326
'start_revision': start_rev, 'end_revision': end_rev
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
1373
tree.branch, log.LineLogFormatter, show_log_kwargs={
1374
'start_revision': start_rev, 'end_revision': end_rev
1338
tree.branch, log.LineLogFormatter, show_log_kwargs={
1339
'start_revision': start_rev, 'end_revision': end_rev
1378
1343
class TestLogWithBugs(TestCaseForLogFormatter, TestLogMixin):
1388
1353
tree = self.make_branch_and_tree(u'.')
1389
1354
self.build_tree(['a', 'b'])
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'})
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'})
1400
def test_bug_broken(self):
1401
tree = self.make_branch_and_tree(u'.')
1402
self.build_tree(['a', 'b'])
1404
self.wt_commit(tree, 'simple log message', rev_id=b'a1',
1405
revprops={u'bugs': 'test://bua g/id fixed'})
1407
logfile = self.make_utf8_encoded_stringio()
1408
formatter = log.LongLogFormatter(to_file=logfile)
1409
log.show_log(tree.branch, formatter)
1411
self.assertContainsRe(
1413
b'brz: ERROR: breezy.bugtracker.InvalidLineInBugsProperty: '
1414
b'Invalid line in bugs property: \'test://bua g/id fixed\'')
1416
text = logfile.getvalue()
1417
self.assertEqualDiff(
1418
text[text.index(b'-' * 60):],
1420
------------------------------------------------------------
1422
committer: Joe Foo <joe@foo.com>
1424
timestamp: Tue 2005-11-22 00:00:00 +0000
1429
1366
def test_long_bugs(self):
1430
1367
tree = self.make_commits_with_bugs()
1431
self.assertFormatterResult(b"""\
1368
self.assertFormatterResult("""\
1432
1369
------------------------------------------------------------
1434
1371
fixes bugs: test://bug/id test://bug/2
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)
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
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
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
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
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
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
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
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
1560
1488
def test_long_default(self):
1561
self.assertFormatterResult(log.LongLogFormatter, None, b"""\
1489
self.assertFormatterResult(log.LongLogFormatter, None, """\
1562
1490
------------------------------------------------------------
1564
1492
author: John Doe <jdoe@example.com>, Jane Rey <jrey@example.com>
1661
1589
builder.start_series()
1662
builder.build_snapshot(None, [
1663
('add', ('', b'TREE_ROOT', 'directory', '')), ],
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()
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
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)
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)