110
108
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')
110
self.wt_commit(wt, 'rev-1', rev_id='rev-1')
111
self.wt_commit(wt, 'rev-merged', rev_id='rev-2a')
112
wt.set_parent_ids(['rev-1', 'rev-2a'])
113
wt.branch.set_last_revision_info(1, 'rev-1')
114
self.wt_commit(wt, 'rev-2', rev_id='rev-2b')
118
116
branch = wt.branch
119
branch.tags.set_tag('v0.2', b'rev-2b')
120
self.wt_commit(wt, 'rev-3', rev_id=b'rev-3')
121
branch.tags.set_tag('v1.0rc1', b'rev-3')
122
branch.tags.set_tag('v1.0', b'rev-3')
117
branch.tags.set_tag('v0.2', 'rev-2b')
118
self.wt_commit(wt, 'rev-3', rev_id='rev-3')
119
branch.tags.set_tag('v1.0rc1', 'rev-3')
120
branch.tags.set_tag('v1.0', 'rev-3')
287
284
self.assertEqual('add file1 and file2', logentry.rev.message)
288
285
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
288
class TestFormatSignatureValidity(tests.TestCaseWithTransport):
324
def verify_revision_signature(self, revid, gpg_strategy):
325
return (gpg.SIGNATURE_VALID,
289
class UTFLoopbackGPGStrategy(gpg.LoopbackGPGStrategy):
290
def verify(self, content, testament):
291
return (gpg.SIGNATURE_VALID,
326
292
u'UTF8 Test \xa1\xb1\xc1\xd1\xe1\xf1 <jrandom@example.com>')
294
def has_signature_for_revision_id(self, revision_id):
297
def get_signature_text(self, revision_id):
328
300
def test_format_signature_validity_utf(self):
329
301
"""Check that GPG signatures containing UTF-8 names are formatted
303
# Monkey patch to use our UTF-8 generating GPGStrategy
304
self.overrideAttr(gpg, 'GPGStrategy', self.UTFLoopbackGPGStrategy)
331
305
wt = self.make_branch_and_tree('.')
332
306
revid = wt.commit('empty commit')
333
307
repo = wt.branch.repository
334
308
# Monkey patch out checking if this rev is actually signed, since we
335
309
# can't sign it without a heavier TestCase and LoopbackGPGStrategy
336
310
# doesn't care anyways.
337
self.overrideAttr(repo, 'verify_revision_signature',
338
self.verify_revision_signature)
339
out = log.format_signature_validity(revid, wt.branch)
311
self.overrideAttr(repo, 'has_signature_for_revision_id',
312
self.has_signature_for_revision_id)
313
self.overrideAttr(repo, 'get_signature_text', self.get_signature_text)
314
out = log.format_signature_validity(revid, repo)
340
315
self.assertEqual(
341
u'valid signature from UTF8 Test \xa1\xb1\xc1\xd1\xe1\xf1 <jrandom@example.com>',
316
u'valid signature from UTF8 Test \xa1\xb1\xc1\xd1\xe1\xf1 <jrandom@example.com>',
345
320
class TestShortLogFormatter(TestCaseForLogFormatter):
421
wt.branch, log.ShortLogFormatter)
396
wt.branch, log.ShortLogFormatter)
423
398
def test_short_log_single_merge_revision(self):
424
399
wt = self._prepare_tree_with_merges()
425
400
revspec = revisionspec.RevisionSpec.from_string('1.1.1')
426
401
rev = revspec.in_history(wt.branch)
427
self.assertFormatterResult(b"""\
402
self.assertFormatterResult("""\
428
403
1.1.1 Joe Foo\t2005-11-22
432
wt.branch, log.ShortLogFormatter,
433
show_log_kwargs=dict(start_revision=rev, end_revision=rev))
407
wt.branch, log.ShortLogFormatter,
408
show_log_kwargs=dict(start_revision=rev, end_revision=rev))
435
410
def test_show_ids(self):
436
411
wt = self.make_branch_and_tree('parent')
437
412
self.build_tree(['parent/f1', 'parent/f2'])
439
self.wt_commit(wt, 'first post', rev_id=b'a')
414
self.wt_commit(wt, 'first post', rev_id='a')
440
415
child_wt = wt.controldir.sprout('child').open_workingtree()
441
self.wt_commit(child_wt, 'branch 1 changes', rev_id=b'b')
416
self.wt_commit(child_wt, 'branch 1 changes', rev_id='b')
442
417
wt.merge_from_branch(child_wt.branch)
443
self.wt_commit(wt, 'merge branch 1', rev_id=b'c')
444
self.assertFormatterResult(b"""\
418
self.wt_commit(wt, 'merge branch 1', rev_id='c')
419
self.assertFormatterResult("""\
445
420
2 Joe Foo\t2005-11-22 [merge]
694
wt.branch, log.LongLogFormatter)
667
wt.branch, log.LongLogFormatter)
696
669
def test_properties_in_short_log(self):
697
670
"""Log includes the custom properties returned by the registered
700
673
wt = self.make_standard_commit('test_properties_in_short_log')
702
674
def trivial_custom_prop_handler(revision):
703
return {'test_prop': 'test_value'}
675
return {'test_prop':'test_value'}
705
677
log.properties_handler_registry.register(
706
678
'trivial_custom_prop_handler',
707
679
trivial_custom_prop_handler)
708
self.assertFormatterResult(b"""\
680
self.assertFormatterResult("""\
709
681
1 John Doe\t2005-11-22
710
682
test_prop: test_value
714
wt.branch, log.ShortLogFormatter)
686
wt.branch, log.ShortLogFormatter)
716
688
def test_error_in_properties_handler(self):
717
689
"""Log includes the custom properties returned by the registered
720
692
wt = self.make_standard_commit('error_in_properties_handler',
721
revprops={u'first_prop': 'first_value'})
693
revprops={'first_prop':'first_value'})
722
694
sio = self.make_utf8_encoded_stringio()
723
695
formatter = log.LongLogFormatter(to_file=sio)
725
696
def trivial_custom_prop_handler(revision):
726
697
raise Exception("a test error")
728
699
log.properties_handler_registry.register(
729
700
'trivial_custom_prop_handler',
730
701
trivial_custom_prop_handler)
731
log.show_log(wt.branch, formatter)
732
self.assertContainsRe(
733
sio.getvalue(), b'brz: ERROR: Exception: a test error')
702
self.assertRaises(Exception, log.show_log, wt.branch, formatter,)
735
704
def test_properties_handler_bad_argument(self):
736
705
wt = self.make_standard_commit('bad_argument',
737
revprops={u'a_prop': 'test_value'})
706
revprops={'a_prop':'test_value'})
738
707
sio = self.make_utf8_encoded_stringio()
739
708
formatter = log.LongLogFormatter(to_file=sio)
741
709
def bad_argument_prop_handler(revision):
742
return {'custom_prop_name': revision.properties['a_prop']}
710
return {'custom_prop_name':revision.properties['a_prop']}
744
712
log.properties_handler_registry.register(
745
713
'bad_argument_prop_handler',
942
909
wt = self.make_standard_commit('test-line-log',
943
committer='Line-Log-Formatter Tester <test@line.log>',
945
self.assertFormatterResult(b"""\
910
committer='Line-Log-Formatter Tester <test@line.log>',
912
self.assertFormatterResult("""\
946
913
1: Line-Log-Formatte... 2005-11-22 add a
948
wt.branch, log.LineLogFormatter)
915
wt.branch, log.LineLogFormatter)
950
917
def test_trailing_newlines(self):
951
918
wt = self.make_branch_and_tree('.')
952
919
b = self.make_commits_with_trailing_newlines(wt)
953
self.assertFormatterResult(b"""\
920
self.assertFormatterResult("""\
954
921
3: Joe Foo 2005-11-22 single line with trailing newline
955
922
2: Joe Foo 2005-11-22 multiline
956
923
1: Joe Foo 2005-11-22 simple log message
958
b, log.LineLogFormatter)
925
b, log.LineLogFormatter)
960
927
def test_line_log_single_merge_revision(self):
961
928
wt = self._prepare_tree_with_merges()
962
929
revspec = revisionspec.RevisionSpec.from_string('1.1.1')
963
930
rev = revspec.in_history(wt.branch)
964
self.assertFormatterResult(b"""\
931
self.assertFormatterResult("""\
965
932
1.1.1: Joe Foo 2005-11-22 rev-merged
967
wt.branch, log.LineLogFormatter,
968
show_log_kwargs=dict(start_revision=rev, end_revision=rev))
934
wt.branch, log.LineLogFormatter,
935
show_log_kwargs=dict(start_revision=rev, end_revision=rev))
970
937
def test_line_log_with_tags(self):
971
938
wt = self._prepare_tree_with_merges(with_tags=True)
972
self.assertFormatterResult(b"""\
939
self.assertFormatterResult("""\
973
940
3: Joe Foo 2005-11-22 {v1.0, v1.0rc1} rev-3
974
941
2: Joe Foo 2005-11-22 [merge] {v0.2} rev-2
975
942
1: Joe Foo 2005-11-22 rev-1
977
wt.branch, log.LineLogFormatter)
944
wt.branch, log.LineLogFormatter)
980
947
class TestLineLogFormatterWithMergeRevisions(TestCaseForLogFormatter):
987
954
wt = self.make_standard_commit('test-line-log',
988
committer='Line-Log-Formatter Tester <test@line.log>',
990
self.assertFormatterResult(b"""\
955
committer='Line-Log-Formatter Tester <test@line.log>',
957
self.assertFormatterResult("""\
991
958
1: Line-Log-Formatte... 2005-11-22 add a
993
wt.branch, log.LineLogFormatter)
960
wt.branch, log.LineLogFormatter)
995
962
def test_line_merge_revs_log_single_merge_revision(self):
996
963
wt = self._prepare_tree_with_merges()
997
964
revspec = revisionspec.RevisionSpec.from_string('1.1.1')
998
965
rev = revspec.in_history(wt.branch)
999
self.assertFormatterResult(b"""\
966
self.assertFormatterResult("""\
1000
967
1.1.1: Joe Foo 2005-11-22 rev-merged
1002
wt.branch, log.LineLogFormatter,
1003
formatter_kwargs=dict(levels=0),
1004
show_log_kwargs=dict(start_revision=rev, end_revision=rev))
969
wt.branch, log.LineLogFormatter,
970
formatter_kwargs=dict(levels=0),
971
show_log_kwargs=dict(start_revision=rev, end_revision=rev))
1006
973
def test_line_merge_revs_log_with_merges(self):
1007
974
wt = self._prepare_tree_with_merges()
1008
self.assertFormatterResult(b"""\
975
self.assertFormatterResult("""\
1009
976
2: Joe Foo 2005-11-22 [merge] rev-2
1010
977
1.1.1: Joe Foo 2005-11-22 rev-merged
1011
978
1: Joe Foo 2005-11-22 rev-1
1013
wt.branch, log.LineLogFormatter,
1014
formatter_kwargs=dict(levels=0))
980
wt.branch, log.LineLogFormatter,
981
formatter_kwargs=dict(levels=0))
1017
984
class TestGnuChangelogFormatter(TestCaseForLogFormatter):
1019
986
def test_gnu_changelog(self):
1020
987
wt = self.make_standard_commit('nicky', authors=[])
1021
self.assertFormatterResult(b'''\
988
self.assertFormatterResult('''\
1022
989
2005-11-22 Lorem Ipsum <test@example.com>
1027
wt.branch, log.GnuChangelogLogFormatter)
994
wt.branch, log.GnuChangelogLogFormatter)
1029
996
def test_with_authors(self):
1030
997
wt = self.make_standard_commit('nicky',
1031
authors=['Fooa Fooz <foo@example.com>',
1032
'Bari Baro <bar@example.com>'])
1033
self.assertFormatterResult(b'''\
998
authors=['Fooa Fooz <foo@example.com>',
999
'Bari Baro <bar@example.com>'])
1000
self.assertFormatterResult('''\
1034
1001
2005-11-22 Fooa Fooz <foo@example.com>
1039
wt.branch, log.GnuChangelogLogFormatter)
1006
wt.branch, log.GnuChangelogLogFormatter)
1041
1008
def test_verbose(self):
1042
1009
wt = self.make_standard_commit('nicky')
1043
self.assertFormatterResult(b'''\
1010
self.assertFormatterResult('''\
1044
1011
2005-11-22 John Doe <jdoe@example.com>
1123
1090
Tests use (revno, depth) whil the API expects (revid, revno, depth).
1124
1091
Since the revid is arbitrary, we just duplicate revno
1126
return [(r, r, d) for r, d in l]
1093
return [ (r, r, d) for r, d in l]
1127
1094
forward = complete_revisions(forward)
1128
backward = complete_revisions(backward)
1095
backward= complete_revisions(backward)
1129
1096
self.assertEqual(forward, log.reverse_by_depth(backward))
1131
1099
def test_mainline_revisions(self):
1132
self.assertReversed([('1', 0), ('2', 0)],
1100
self.assertReversed([( '1', 0), ('2', 0)],
1133
1101
[('2', 0), ('1', 0)])
1135
1103
def test_merged_revisions(self):
1136
self.assertReversed([('1', 0), ('2', 0), ('2.2', 1), ('2.1', 1), ],
1137
[('2', 0), ('2.1', 1), ('2.2', 1), ('1', 0), ])
1104
self.assertReversed([('1', 0), ('2', 0), ('2.2', 1), ('2.1', 1),],
1105
[('2', 0), ('2.1', 1), ('2.2', 1), ('1', 0),])
1139
1106
def test_shifted_merged_revisions(self):
1140
1107
"""Test irregular layout.
1142
1109
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), ])
1111
self.assertReversed([('1', 0), ('2', 0), ('1.1', 2), ('1.2', 2),],
1112
[('2', 0), ('1.2', 2), ('1.1', 2), ('1', 0),])
1147
1114
def test_merged_without_child_revisions(self):
1148
1115
"""Test irregular layout.
1152
1119
# When a revision of higher depth doesn't follow one of lower depth, we
1153
1120
# assume a lower depth one is virtually there
1154
1121
self.assertReversed([('1', 2), ('2', 2), ('3', 3), ('4', 4)],
1155
[('4', 4), ('3', 3), ('2', 2), ('1', 2), ])
1122
[('4', 4), ('3', 3), ('2', 2), ('1', 2),])
1156
1123
# So we get the same order after reversing below even if the original
1157
1124
# revisions are not in the same order.
1158
1125
self.assertReversed([('1', 2), ('2', 2), ('3', 3), ('4', 4)],
1159
[('3', 3), ('4', 4), ('2', 2), ('1', 2), ])
1126
[('3', 3), ('4', 4), ('2', 2), ('1', 2),])
1162
1129
class TestHistoryChange(tests.TestCaseWithTransport):
1165
1132
tree = self.make_branch_and_tree('tree')
1166
1133
tree.lock_write()
1167
1134
self.addCleanup(tree.unlock)
1168
tree.commit('1a', rev_id=b'1a')
1169
tree.commit('2a', rev_id=b'2a')
1170
tree.commit('3a', rev_id=b'3a')
1135
tree.commit('1a', rev_id='1a')
1136
tree.commit('2a', rev_id='2a')
1137
tree.commit('3a', rev_id='3a')
1173
1140
def setup_ab_tree(self):
1174
1141
tree = self.setup_a_tree()
1175
tree.set_last_revision(b'1a')
1176
tree.branch.set_last_revision_info(1, b'1a')
1177
tree.commit('2b', rev_id=b'2b')
1178
tree.commit('3b', rev_id=b'3b')
1142
tree.set_last_revision('1a')
1143
tree.branch.set_last_revision_info(1, '1a')
1144
tree.commit('2b', rev_id='2b')
1145
tree.commit('3b', rev_id='3b')
1181
1148
def setup_ac_tree(self):
1182
1149
tree = self.setup_a_tree()
1183
1150
tree.set_last_revision(revision.NULL_REVISION)
1184
1151
tree.branch.set_last_revision_info(0, revision.NULL_REVISION)
1185
tree.commit('1c', rev_id=b'1c')
1186
tree.commit('2c', rev_id=b'2c')
1187
tree.commit('3c', rev_id=b'3c')
1152
tree.commit('1c', rev_id='1c')
1153
tree.commit('2c', rev_id='2c')
1154
tree.commit('3c', rev_id='3c')
1190
1157
def test_all_new(self):
1191
1158
tree = self.setup_ab_tree()
1192
old, new = log.get_history_change(b'1a', b'3a', tree.branch.repository)
1159
old, new = log.get_history_change('1a', '3a', tree.branch.repository)
1193
1160
self.assertEqual([], old)
1194
self.assertEqual([b'2a', b'3a'], new)
1161
self.assertEqual(['2a', '3a'], new)
1196
1163
def test_all_old(self):
1197
1164
tree = self.setup_ab_tree()
1198
old, new = log.get_history_change(b'3a', b'1a', tree.branch.repository)
1165
old, new = log.get_history_change('3a', '1a', tree.branch.repository)
1199
1166
self.assertEqual([], new)
1200
self.assertEqual([b'2a', b'3a'], old)
1167
self.assertEqual(['2a', '3a'], old)
1202
1169
def test_null_old(self):
1203
1170
tree = self.setup_ab_tree()
1204
1171
old, new = log.get_history_change(revision.NULL_REVISION,
1205
b'3a', tree.branch.repository)
1172
'3a', tree.branch.repository)
1206
1173
self.assertEqual([], old)
1207
self.assertEqual([b'1a', b'2a', b'3a'], new)
1174
self.assertEqual(['1a', '2a', '3a'], new)
1209
1176
def test_null_new(self):
1210
1177
tree = self.setup_ab_tree()
1211
old, new = log.get_history_change(b'3a', revision.NULL_REVISION,
1178
old, new = log.get_history_change('3a', revision.NULL_REVISION,
1212
1179
tree.branch.repository)
1213
1180
self.assertEqual([], new)
1214
self.assertEqual([b'1a', b'2a', b'3a'], old)
1181
self.assertEqual(['1a', '2a', '3a'], old)
1216
1183
def test_diverged(self):
1217
1184
tree = self.setup_ab_tree()
1218
old, new = log.get_history_change(b'3a', b'3b', tree.branch.repository)
1219
self.assertEqual(old, [b'2a', b'3a'])
1220
self.assertEqual(new, [b'2b', b'3b'])
1185
old, new = log.get_history_change('3a', '3b', tree.branch.repository)
1186
self.assertEqual(old, ['2a', '3a'])
1187
self.assertEqual(new, ['2b', '3b'])
1222
1189
def test_unrelated(self):
1223
1190
tree = self.setup_ac_tree()
1224
old, new = log.get_history_change(b'3a', b'3c', tree.branch.repository)
1225
self.assertEqual(old, [b'1a', b'2a', b'3a'])
1226
self.assertEqual(new, [b'1c', b'2c', b'3c'])
1191
old, new = log.get_history_change('3a', '3c', tree.branch.repository)
1192
self.assertEqual(old, ['1a', '2a', '3a'])
1193
self.assertEqual(new, ['1c', '2c', '3c'])
1228
1195
def test_show_branch_change(self):
1229
1196
tree = self.setup_ab_tree()
1231
log.show_branch_change(tree.branch, s, 3, b'3a')
1198
log.show_branch_change(tree.branch, s, 3, '3a')
1232
1199
self.assertContainsRe(s.getvalue(),
1233
'[*]{60}\nRemoved Revisions:\n(.|\n)*2a(.|\n)*3a(.|\n)*'
1234
'[*]{60}\n\nAdded Revisions:\n(.|\n)*2b(.|\n)*3b')
1200
'[*]{60}\nRemoved Revisions:\n(.|\n)*2a(.|\n)*3a(.|\n)*'
1201
'[*]{60}\n\nAdded Revisions:\n(.|\n)*2b(.|\n)*3b')
1236
1203
def test_show_branch_change_no_change(self):
1237
1204
tree = self.setup_ab_tree()
1239
log.show_branch_change(tree.branch, s, 3, b'3b')
1206
log.show_branch_change(tree.branch, s, 3, '3b')
1240
1207
self.assertEqual(s.getvalue(),
1241
'Nothing seems to have changed\n')
1208
'Nothing seems to have changed\n')
1243
1210
def test_show_branch_change_no_old(self):
1244
1211
tree = self.setup_ab_tree()
1246
log.show_branch_change(tree.branch, s, 2, b'2b')
1213
log.show_branch_change(tree.branch, s, 2, '2b')
1247
1214
self.assertContainsRe(s.getvalue(), 'Added Revisions:')
1248
1215
self.assertNotContainsRe(s.getvalue(), 'Removed Revisions:')
1250
1217
def test_show_branch_change_no_new(self):
1251
1218
tree = self.setup_ab_tree()
1252
tree.branch.set_last_revision_info(2, b'2b')
1254
log.show_branch_change(tree.branch, s, 3, b'3b')
1219
tree.branch.set_last_revision_info(2, '2b')
1221
log.show_branch_change(tree.branch, s, 3, '3b')
1255
1222
self.assertContainsRe(s.getvalue(), 'Removed Revisions:')
1256
1223
self.assertNotContainsRe(s.getvalue(), 'Added Revisions:')
1264
1231
self.addCleanup(tree.unlock)
1266
1233
'committer': 'Joe Foo <joe@foo.com>',
1267
'timestamp': 1132617600, # Mon 2005-11-22 00:00:00 +0000
1268
'timezone': 0, # UTC
1234
'timestamp': 1132617600, # Mon 2005-11-22 00:00:00 +0000
1235
'timezone': 0, # UTC
1270
tree.commit('commit 1a', rev_id=b'1a', **kwargs)
1271
tree.commit('commit 2a', rev_id=b'2a', **kwargs)
1272
tree.commit('commit 3a', rev_id=b'3a', **kwargs)
1237
tree.commit('commit 1a', rev_id='1a', **kwargs)
1238
tree.commit('commit 2a', rev_id='2a', **kwargs)
1239
tree.commit('commit 3a', rev_id='3a', **kwargs)
1275
1242
def setup_ab_tree(self):
1276
1243
tree = self.setup_a_tree()
1277
tree.set_last_revision(b'1a')
1278
tree.branch.set_last_revision_info(1, b'1a')
1244
tree.set_last_revision('1a')
1245
tree.branch.set_last_revision_info(1, '1a')
1280
1247
'committer': 'Joe Foo <joe@foo.com>',
1281
'timestamp': 1132617600, # Mon 2005-11-22 00:00:00 +0000
1282
'timezone': 0, # UTC
1248
'timestamp': 1132617600, # Mon 2005-11-22 00:00:00 +0000
1249
'timezone': 0, # UTC
1284
tree.commit('commit 2b', rev_id=b'2b', **kwargs)
1285
tree.commit('commit 3b', rev_id=b'3b', **kwargs)
1251
tree.commit('commit 2b', rev_id='2b', **kwargs)
1252
tree.commit('commit 3b', rev_id='3b', **kwargs)
1288
1255
def test_one_revision(self):
1289
1256
tree = self.setup_ab_tree()
1290
1257
lf = LogCatcher()
1291
rev = revisionspec.RevisionInfo(tree.branch, None, b'3a')
1258
rev = revisionspec.RevisionInfo(tree.branch, None, '3a')
1292
1259
log.show_log(tree.branch, lf, verbose=True, start_revision=rev,
1293
1260
end_revision=rev)
1294
1261
self.assertEqual(1, len(lf.revisions))
1295
1262
self.assertEqual(None, lf.revisions[0].revno) # Out-of-branch
1296
self.assertEqual(b'3a', lf.revisions[0].rev.revision_id)
1263
self.assertEqual('3a', lf.revisions[0].rev.revision_id)
1298
1265
def test_many_revisions(self):
1299
1266
tree = self.setup_ab_tree()
1300
1267
lf = LogCatcher()
1301
start_rev = revisionspec.RevisionInfo(tree.branch, None, b'1a')
1302
end_rev = revisionspec.RevisionInfo(tree.branch, None, b'3a')
1268
start_rev = revisionspec.RevisionInfo(tree.branch, None, '1a')
1269
end_rev = revisionspec.RevisionInfo(tree.branch, None, '3a')
1303
1270
log.show_log(tree.branch, lf, verbose=True, start_revision=start_rev,
1304
1271
end_revision=end_rev)
1305
1272
self.assertEqual(3, len(lf.revisions))
1306
1273
self.assertEqual(None, lf.revisions[0].revno) # Out-of-branch
1307
self.assertEqual(b'3a', lf.revisions[0].rev.revision_id)
1274
self.assertEqual('3a', lf.revisions[0].rev.revision_id)
1308
1275
self.assertEqual(None, lf.revisions[1].revno) # Out-of-branch
1309
self.assertEqual(b'2a', lf.revisions[1].rev.revision_id)
1276
self.assertEqual('2a', lf.revisions[1].rev.revision_id)
1310
1277
self.assertEqual('1', lf.revisions[2].revno) # In-branch
1312
1279
def test_long_format(self):
1313
1280
tree = self.setup_ab_tree()
1314
start_rev = revisionspec.RevisionInfo(tree.branch, None, b'1a')
1315
end_rev = revisionspec.RevisionInfo(tree.branch, None, b'3a')
1316
self.assertFormatterResult(b"""\
1281
start_rev = revisionspec.RevisionInfo(tree.branch, None, '1a')
1282
end_rev = revisionspec.RevisionInfo(tree.branch, None, '3a')
1283
self.assertFormatterResult("""\
1317
1284
------------------------------------------------------------
1318
1285
revision-id: 3a
1319
1286
committer: Joe Foo <joe@foo.com>
1360
tree.branch, log.ShortLogFormatter, show_log_kwargs={
1361
'start_revision': start_rev, 'end_revision': end_rev
1327
tree.branch, log.ShortLogFormatter, show_log_kwargs={
1328
'start_revision': start_rev, 'end_revision': end_rev
1364
1331
def test_line_format(self):
1365
1332
tree = self.setup_ab_tree()
1366
start_rev = revisionspec.RevisionInfo(tree.branch, None, b'1a')
1367
end_rev = revisionspec.RevisionInfo(tree.branch, None, b'3a')
1368
self.assertFormatterResult(b"""\
1333
start_rev = revisionspec.RevisionInfo(tree.branch, None, '1a')
1334
end_rev = revisionspec.RevisionInfo(tree.branch, None, '3a')
1335
self.assertFormatterResult("""\
1369
1336
Joe Foo 2005-11-22 commit 3a
1370
1337
Joe Foo 2005-11-22 commit 2a
1371
1338
1: Joe Foo 2005-11-22 commit 1a
1373
tree.branch, log.LineLogFormatter, show_log_kwargs={
1374
'start_revision': start_rev, 'end_revision': end_rev
1340
tree.branch, log.LineLogFormatter, show_log_kwargs={
1341
'start_revision': start_rev, 'end_revision': end_rev
1378
1345
class TestLogWithBugs(TestCaseForLogFormatter, TestLogMixin):
1388
1355
tree = self.make_branch_and_tree(u'.')
1389
1356
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'})
1358
self.wt_commit(tree, 'simple log message', rev_id='a1',
1359
revprops={'bugs': 'test://bug/id fixed'})
1394
self.wt_commit(tree, 'multiline\nlog\nmessage\n', rev_id=b'a2',
1361
self.wt_commit(tree, 'multiline\nlog\nmessage\n', rev_id='a2',
1395
1362
authors=['Joe Bar <joe@bar.com>'],
1396
revprops={u'bugs': 'test://bug/id fixed\n'
1363
revprops={'bugs': 'test://bug/id fixed\n'
1397
1364
'test://bug/2 fixed'})
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
1368
def test_long_bugs(self):
1430
1369
tree = self.make_commits_with_bugs()
1431
self.assertFormatterResult(b"""\
1370
self.assertFormatterResult("""\
1432
1371
------------------------------------------------------------
1434
1373
fixes bugs: test://bug/id test://bug/2
1507
1436
author_list_handler = log.author_list_registry.get(who)
1508
1437
formatter_kwargs['author_list_handler'] = author_list_handler
1509
1438
TestCaseForLogFormatter.assertFormatterResult(self, result,
1510
self.wt.branch, formatter, formatter_kwargs=formatter_kwargs)
1439
self.wt.branch, formatter, formatter_kwargs=formatter_kwargs)
1512
1441
def test_line_default(self):
1513
self.assertFormatterResult(log.LineLogFormatter, None, b"""\
1442
self.assertFormatterResult(log.LineLogFormatter, None, """\
1514
1443
1: John Doe 2005-11-22 add a
1517
1446
def test_line_committer(self):
1518
self.assertFormatterResult(log.LineLogFormatter, 'committer', b"""\
1447
self.assertFormatterResult(log.LineLogFormatter, 'committer', """\
1519
1448
1: Lorem Ipsum 2005-11-22 add a
1522
1451
def test_line_first(self):
1523
self.assertFormatterResult(log.LineLogFormatter, 'first', b"""\
1452
self.assertFormatterResult(log.LineLogFormatter, 'first', """\
1524
1453
1: John Doe 2005-11-22 add a
1527
1456
def test_line_all(self):
1528
self.assertFormatterResult(log.LineLogFormatter, 'all', b"""\
1457
self.assertFormatterResult(log.LineLogFormatter, 'all', """\
1529
1458
1: John Doe, Jane Rey 2005-11-22 add a
1532
1462
def test_short_default(self):
1533
self.assertFormatterResult(log.ShortLogFormatter, None, b"""\
1463
self.assertFormatterResult(log.ShortLogFormatter, None, """\
1534
1464
1 John Doe\t2005-11-22
1539
1469
def test_short_committer(self):
1540
self.assertFormatterResult(log.ShortLogFormatter, 'committer', b"""\
1470
self.assertFormatterResult(log.ShortLogFormatter, 'committer', """\
1541
1471
1 Lorem Ipsum\t2005-11-22
1546
1476
def test_short_first(self):
1547
self.assertFormatterResult(log.ShortLogFormatter, 'first', b"""\
1477
self.assertFormatterResult(log.ShortLogFormatter, 'first', """\
1548
1478
1 John Doe\t2005-11-22
1553
1483
def test_short_all(self):
1554
self.assertFormatterResult(log.ShortLogFormatter, 'all', b"""\
1484
self.assertFormatterResult(log.ShortLogFormatter, 'all', """\
1555
1485
1 John Doe, Jane Rey\t2005-11-22
1560
1490
def test_long_default(self):
1561
self.assertFormatterResult(log.LongLogFormatter, None, b"""\
1491
self.assertFormatterResult(log.LongLogFormatter, None, """\
1562
1492
------------------------------------------------------------
1564
1494
author: John Doe <jdoe@example.com>, Jane Rey <jrey@example.com>
1661
1591
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')
1592
builder.build_snapshot('1', None, [
1593
('add', ('', 'TREE_ROOT', 'directory', '')),])
1594
builder.build_snapshot('1.1.1', ['1'], [])
1595
builder.build_snapshot('2', ['1'], [])
1596
builder.build_snapshot('1.2.1', ['1.1.1'], [])
1597
builder.build_snapshot('1.1.2', ['1.1.1', '1.2.1'], [])
1598
builder.build_snapshot('3', ['2', '1.1.2'], [])
1670
1599
builder.finish_series()
1671
1600
br = builder.get_branch()
1688
1617
def test_merge_sorted_exclude_ancestry(self):
1689
1618
b = self.make_branch_with_alternate_ancestries()
1690
self.assertLogRevnos([b'3', b'1.1.2', b'1.2.1', b'1.1.1', b'2', b'1'],
1691
b, b'1', b'3', exclude_common_ancestry=False)
1619
self.assertLogRevnos(['3', '1.1.2', '1.2.1', '1.1.1', '2', '1'],
1620
b, '1', '3', exclude_common_ancestry=False)
1692
1621
# '2' is part of the '3' ancestry but not part of '1.1.1' ancestry so
1693
1622
# it should be mentioned even if merge_sort order will make it appear
1695
self.assertLogRevnos([b'3', b'1.1.2', b'1.2.1', b'2'],
1696
b, b'1.1.1', b'3', exclude_common_ancestry=True)
1624
self.assertLogRevnos(['3', '1.1.2', '1.2.1', '2'],
1625
b, '1.1.1', '3', exclude_common_ancestry=True)
1698
1627
def test_merge_sorted_simple_revnos_exclude_ancestry(self):
1699
1628
b = self.make_branch_with_alternate_ancestries()
1700
self.assertLogRevnos([b'3', b'2'],
1701
b, b'1', b'3', exclude_common_ancestry=True,
1629
self.assertLogRevnos(['3', '2'],
1630
b, '1', '3', exclude_common_ancestry=True,
1702
1631
generate_merge_revisions=False)
1703
self.assertLogRevnos([b'3', b'1.1.2', b'1.2.1', b'1.1.1', b'2'],
1704
b, b'1', b'3', exclude_common_ancestry=True,
1632
self.assertLogRevnos(['3', '1.1.2', '1.2.1', '1.1.1', '2'],
1633
b, '1', '3', exclude_common_ancestry=True,
1705
1634
generate_merge_revisions=True)