65
63
tree.commit(message='merge')
69
class TestLogWithLogCatcher(TestLog):
72
super(TestLogWithLogCatcher, self).setUp()
73
# Capture log formatter creations
74
class MyLogFormatter(test_log.LogCatcher):
76
def __new__(klass, *args, **kwargs):
77
self.log_catcher = test_log.LogCatcher(*args, **kwargs)
78
# Always return our own log formatter
79
return self.log_catcher
82
# Always return our own log formatter class hijacking the
83
# default behavior (which requires setting up a config
86
self.overrideAttr(log.log_formatter_registry, 'get_default', getme)
88
def get_captured_revisions(self):
89
return self.log_catcher.revisions
91
def assertLogRevnos(self, args, expected_revnos, working_dir='.'):
92
self.run_bzr(['log'] + args, working_dir=working_dir)
93
self.assertEqual(expected_revnos,
94
[r.revno for r in self.get_captured_revisions()])
96
def assertLogRevnosAndDepths(self, args, expected_revnos_and_depths,
98
self.run_bzr(['log'] + args, working_dir=working_dir)
99
self.assertEqual(expected_revnos_and_depths,
100
[(r.revno, r.merge_depth)
101
for r in self.get_captured_revisions()])
104
class TestLogRevSpecs(TestLogWithLogCatcher):
106
def test_log_no_revspec(self):
107
self.make_linear_branch()
108
self.assertLogRevnos([], ['3', '2', '1'])
66
def assertRevnos(self, log, must_have=(), must_not_have=()):
67
"""Check if revnos are in or not in the log output"""
68
for revno in must_have:
69
self.assertTrue(('revno: %s\n' % revno) in log,
70
'Does not contain expected revno %s' % revno)
71
for revno in must_not_have:
72
self.assertFalse(('revno: %s\n' % revno) in log,
73
'Contains unexpected revno %s' % revno)
75
def commit_options(self):
76
"""Use some mostly fixed values for commits to simplify tests.
78
Tests can use this function to get some commit attributes. The time
79
stamp is incremented at each commit.
81
self.timestamp += 1 # 1 second between each commit
82
return dict(committer='Lorem Ipsum <joe@foo.com>',
83
timezone=self.timezone,
84
timestamp=self.timestamp,
87
def check_log(self, expected, args, working_dir='level0'):
88
out, err = self.run_bzr(['log', '--timezone', 'utc'] + args,
89
working_dir=working_dir)
90
self.assertEqual('', err)
91
self.assertEqualDiff(expected, test_log.normalize_log(out))
94
class TestLogRevSpecs(TestLog):
110
96
def test_log_null_end_revspec(self):
111
97
self.make_linear_branch()
112
self.assertLogRevnos(['-r1..'], ['3', '2', '1'])
98
log = self.run_bzr(['log'])[0]
99
self.assertTrue('revno: 1\n' in log)
100
self.assertTrue('revno: 2\n' in log)
101
self.assertTrue('revno: 3\n' in log)
102
self.assertTrue('message:\n message1\n' in log)
103
self.assertTrue('message:\n message2\n' in log)
104
self.assertTrue('message:\n message3\n' in log)
106
full_log = self.run_bzr(['log'])[0]
107
log = self.run_bzr("log -r 1..")[0]
108
self.assertEqualDiff(log, full_log)
114
110
def test_log_null_begin_revspec(self):
115
111
self.make_linear_branch()
116
self.assertLogRevnos(['-r..3'], ['3', '2', '1'])
112
full_log = self.run_bzr(['log'])[0]
113
log = self.run_bzr("log -r ..3")[0]
114
self.assertEqualDiff(full_log, log)
118
116
def test_log_null_both_revspecs(self):
119
117
self.make_linear_branch()
120
self.assertLogRevnos(['-r..'], ['3', '2', '1'])
118
full_log = self.run_bzr(['log'])[0]
119
log = self.run_bzr("log -r ..")[0]
120
self.assertEqualDiff(full_log, log)
122
def test_log_zero_revspec(self):
123
self.make_minimal_branch()
124
self.run_bzr_error(['bzr: ERROR: Logging revision 0 is invalid.'],
127
def test_log_zero_begin_revspec(self):
128
self.make_linear_branch()
129
self.run_bzr_error(['bzr: ERROR: Logging revision 0 is invalid.'],
132
def test_log_zero_end_revspec(self):
133
self.make_linear_branch()
134
self.run_bzr_error(['bzr: ERROR: Logging revision 0 is invalid.'],
122
137
def test_log_negative_begin_revspec_full_log(self):
123
138
self.make_linear_branch()
124
self.assertLogRevnos(['-r-3..'], ['3', '2', '1'])
139
full_log = self.run_bzr(['log'])[0]
140
log = self.run_bzr("log -r -3..")[0]
141
self.assertEqualDiff(full_log, log)
126
143
def test_log_negative_both_revspec_full_log(self):
127
144
self.make_linear_branch()
128
self.assertLogRevnos(['-r-3..-1'], ['3', '2', '1'])
145
full_log = self.run_bzr(['log'])[0]
146
log = self.run_bzr("log -r -3..-1")[0]
147
self.assertEqualDiff(full_log, log)
130
149
def test_log_negative_both_revspec_partial(self):
131
150
self.make_linear_branch()
132
self.assertLogRevnos(['-r-3..-2'], ['2', '1'])
151
log = self.run_bzr("log -r -3..-2")[0]
152
self.assertTrue('revno: 1\n' in log)
153
self.assertTrue('revno: 2\n' in log)
154
self.assertTrue('revno: 3\n' not in log)
134
156
def test_log_negative_begin_revspec(self):
135
157
self.make_linear_branch()
136
self.assertLogRevnos(['-r-2..'], ['3', '2'])
158
log = self.run_bzr("log -r -2..")[0]
159
self.assertTrue('revno: 1\n' not in log)
160
self.assertTrue('revno: 2\n' in log)
161
self.assertTrue('revno: 3\n' in log)
138
163
def test_log_positive_revspecs(self):
139
164
self.make_linear_branch()
140
self.assertLogRevnos(['-r1..3'], ['3', '2', '1'])
165
full_log = self.run_bzr(['log'])[0]
166
log = self.run_bzr("log -r 1..3")[0]
167
self.assertEqualDiff(full_log, log)
142
169
def test_log_dotted_revspecs(self):
143
170
self.make_merged_branch()
144
self.assertLogRevnos(['-n0', '-r1..1.1.1'], ['1.1.1', '1'])
146
def test_log_limit(self):
147
tree = self.make_branch_and_tree('.')
148
# We want more commits than our batch size starts at
149
for pos in range(10):
150
tree.commit("%s" % pos)
151
self.assertLogRevnos(['--limit', '2'], ['10', '9'])
153
def test_log_limit_short(self):
154
self.make_linear_branch()
155
self.assertLogRevnos(['-l', '2'], ['3', '2'])
157
def test_log_change_revno(self):
158
self.make_linear_branch()
159
self.assertLogRevnos(['-c1'], ['1'])
162
class TestLogMergedLinearAncestry(TestLogWithLogCatcher):
165
super(TestLogMergedLinearAncestry, self).setUp()
166
# FIXME: Using a MemoryTree would be even better here (but until we
167
# stop calling run_bzr, there is no point) --vila 100118.
168
builder = branchbuilder.BranchBuilder(self.get_transport())
169
builder.start_series()
171
builder.build_snapshot('1', None, [
172
('add', ('', 'root-id', 'directory', ''))])
173
builder.build_snapshot('2', ['1'], [])
175
builder.build_snapshot('1.1.1', ['1'], [])
176
# merge branch into mainline
177
builder.build_snapshot('3', ['2', '1.1.1'], [])
178
# new commits in branch
179
builder.build_snapshot('1.1.2', ['1.1.1'], [])
180
builder.build_snapshot('1.1.3', ['1.1.2'], [])
181
# merge branch into mainline
182
builder.build_snapshot('4', ['3', '1.1.3'], [])
183
# merge mainline into branch
184
builder.build_snapshot('1.1.4', ['1.1.3', '4'], [])
185
# merge branch into mainline
186
builder.build_snapshot('5', ['4', '1.1.4'], [])
187
builder.finish_series()
190
self.assertLogRevnos(['-n0', '-r1.1.1..1.1.4'],
191
['1.1.4', '4', '1.1.3', '1.1.2', '3', '1.1.1'])
192
def test_n0_forward(self):
193
self.assertLogRevnos(['-n0', '-r1.1.1..1.1.4', '--forward'],
194
['3', '1.1.1', '4', '1.1.2', '1.1.3', '1.1.4'])
197
# starting from 1.1.4 we follow the left-hand ancestry
198
self.assertLogRevnos(['-n1', '-r1.1.1..1.1.4'],
199
['1.1.4', '1.1.3', '1.1.2', '1.1.1'])
201
def test_n1_forward(self):
202
self.assertLogRevnos(['-n1', '-r1.1.1..1.1.4', '--forward'],
203
['1.1.1', '1.1.2', '1.1.3', '1.1.4'])
206
class Test_GenerateAllRevisions(TestLogWithLogCatcher):
208
def make_branch_with_many_merges(self, path='.', format=None):
209
builder = branchbuilder.BranchBuilder(self.get_transport())
210
builder.start_series()
211
# The graph below may look a bit complicated (and it may be but I've
212
# banged my head enough on it) but the bug requires at least dotted
213
# revnos *and* merged revisions below that.
214
builder.build_snapshot('1', None, [
215
('add', ('', 'root-id', 'directory', ''))])
216
builder.build_snapshot('2', ['1'], [])
217
builder.build_snapshot('1.1.1', ['1'], [])
218
builder.build_snapshot('2.1.1', ['2'], [])
219
builder.build_snapshot('3', ['2', '1.1.1'], [])
220
builder.build_snapshot('2.1.2', ['2.1.1'], [])
221
builder.build_snapshot('2.2.1', ['2.1.1'], [])
222
builder.build_snapshot('2.1.3', ['2.1.2', '2.2.1'], [])
223
builder.build_snapshot('4', ['3', '2.1.3'], [])
224
builder.build_snapshot('5', ['4', '2.1.2'], [])
225
builder.finish_series()
228
def test_not_an_ancestor(self):
229
builder = self.make_branch_with_many_merges()
230
b = builder.get_branch()
232
self.addCleanup(b.unlock)
233
self.assertRaises(errors.BzrCommandError,
234
log._generate_all_revisions,
235
b, '1.1.1', '2.1.3', 'reverse',
236
delayed_graph_generation=True)
238
def test_wrong_order(self):
239
builder = self.make_branch_with_many_merges()
240
b = builder.get_branch()
242
self.addCleanup(b.unlock)
243
self.assertRaises(errors.BzrCommandError,
244
log._generate_all_revisions,
245
b, '5', '2.1.3', 'reverse',
246
delayed_graph_generation=True)
249
class TestLogRevSpecsWithPaths(TestLogWithLogCatcher):
251
def test_log_revno_n_path_wrong_namespace(self):
171
log = self.run_bzr("log -n0 -r 1..1.1.1")[0]
172
self.assertRevnos(log, (1, '1.1.1'), (2, 3, '1.1.2', 4))
174
def test_log_reversed_revspecs(self):
175
self.make_linear_branch()
176
self.run_bzr_error(('bzr: ERROR: Start revision must be older than '
177
'the end revision.\n',),
180
def test_log_reversed_dotted_revspecs(self):
181
self.make_merged_branch()
182
self.run_bzr_error(('bzr: ERROR: Start revision not found in '
183
'left-hand history of end revision.\n',),
186
def test_log_revno_n_path(self):
252
187
self.make_linear_branch('branch1')
253
188
self.make_linear_branch('branch2')
254
# There is no guarantee that a path exist between two arbitrary
256
self.run_bzr("log -r revno:2:branch1..revno:3:branch2", retcode=3)
258
def test_log_revno_n_path_correct_order(self):
259
self.make_linear_branch('branch2')
260
self.assertLogRevnos(['-rrevno:1:branch2..revno:3:branch2'],
263
def test_log_revno_n_path(self):
264
self.make_linear_branch('branch2')
265
self.assertLogRevnos(['-rrevno:1:branch2'],
267
rev_props = self.log_catcher.revisions[0].rev.properties
268
self.assertEqual('branch2', rev_props['branch-nick'])
271
class TestLogErrors(TestLog):
273
def test_log_zero_revspec(self):
274
self.make_minimal_branch()
275
self.run_bzr_error(['bzr: ERROR: Logging revision 0 is invalid.'],
278
def test_log_zero_begin_revspec(self):
279
self.make_linear_branch()
280
self.run_bzr_error(['bzr: ERROR: Logging revision 0 is invalid.'],
283
def test_log_zero_end_revspec(self):
284
self.make_linear_branch()
285
self.run_bzr_error(['bzr: ERROR: Logging revision 0 is invalid.'],
190
self.run_bzr("log -r revno:2:branch1..revno:3:branch2", retcode=3)[0]
192
log = self.run_bzr("log -r revno:1:branch2..revno:3:branch2")[0]
193
full_log = self.run_bzr(['log'], working_dir='branch2')[0]
194
self.assertEqualDiff(full_log, log)
195
log = self.run_bzr("log -r revno:1:branch2")[0]
196
self.assertTrue('revno: 1\n' in log)
197
self.assertTrue('revno: 2\n' not in log)
198
self.assertTrue('branch nick: branch2\n' in log)
199
self.assertTrue('branch nick: branch1\n' not in log)
288
201
def test_log_nonexistent_revno(self):
289
202
self.make_minimal_branch()
290
self.run_bzr_error(["bzr: ERROR: Requested revision: '1234' "
291
"does not exist in branch:"],
203
(out, err) = self.run_bzr_error(
204
["bzr: ERROR: Requested revision: '1234' "
205
"does not exist in branch:"],
294
208
def test_log_nonexistent_dotted_revno(self):
295
209
self.make_minimal_branch()
296
self.run_bzr_error(["bzr: ERROR: Requested revision: '123.123' "
297
"does not exist in branch:"],
298
['log', '-r123.123'])
210
(out, err) = self.run_bzr_error(
211
["bzr: ERROR: Requested revision: '123.123' "
212
"does not exist in branch:"],
213
['log', '-r123.123'])
215
def test_log_change_revno(self):
216
self.make_linear_branch()
217
expected_log = self.run_bzr("log -r 1")[0]
218
log = self.run_bzr("log -c 1")[0]
219
self.assertEqualDiff(expected_log, log)
300
221
def test_log_change_nonexistent_revno(self):
301
222
self.make_minimal_branch()
302
self.run_bzr_error(["bzr: ERROR: Requested revision: '1234' "
303
"does not exist in branch:"],
223
(out, err) = self.run_bzr_error(
224
["bzr: ERROR: Requested revision: '1234' "
225
"does not exist in branch:"],
306
228
def test_log_change_nonexistent_dotted_revno(self):
307
229
self.make_minimal_branch()
308
self.run_bzr_error(["bzr: ERROR: Requested revision: '123.123' "
309
"does not exist in branch:"],
310
['log', '-c123.123'])
230
(out, err) = self.run_bzr_error(
231
["bzr: ERROR: Requested revision: '123.123' "
232
"does not exist in branch:"],
233
['log', '-c123.123'])
312
235
def test_log_change_single_revno_only(self):
313
236
self.make_minimal_branch()
438
373
def make_branches_with_merges(self):
439
374
level0 = self.make_branch_and_tree('level0')
440
self.wt_commit(level0, 'in branch level0')
375
level0.commit(message='in branch level0', **self.commit_options())
441
377
level1 = level0.bzrdir.sprout('level1').open_workingtree()
442
self.wt_commit(level1, 'in branch level1')
378
level1.commit(message='in branch level1', **self.commit_options())
443
380
level2 = level1.bzrdir.sprout('level2').open_workingtree()
444
self.wt_commit(level2, 'in branch level2')
381
level2.commit(message='in branch level2', **self.commit_options())
445
383
level1.merge_from_branch(level2.branch)
446
self.wt_commit(level1, 'merge branch level2')
384
level1.commit(message='merge branch level2', **self.commit_options())
447
386
level0.merge_from_branch(level1.branch)
448
self.wt_commit(level0, 'merge branch level1')
387
level0.commit(message='merge branch level1', **self.commit_options())
450
389
def test_merges_are_indented_by_level(self):
451
self.run_bzr(['log', '-n0'], working_dir='level0')
452
revnos_and_depth = [(r.revno, r.merge_depth)
453
for r in self.get_captured_revisions()]
454
self.assertEqual([('2', 0), ('1.1.2', 1), ('1.2.1', 2), ('1.1.1', 1),
456
[(r.revno, r.merge_depth)
457
for r in self.get_captured_revisions()])
391
------------------------------------------------------------
393
committer: Lorem Ipsum <test@example.com>
398
------------------------------------------------------------
400
committer: Lorem Ipsum <test@example.com>
405
------------------------------------------------------------
407
committer: Lorem Ipsum <test@example.com>
412
------------------------------------------------------------
414
committer: Lorem Ipsum <test@example.com>
419
------------------------------------------------------------
421
committer: Lorem Ipsum <test@example.com>
427
self.check_log(expected, ['-n0'])
459
429
def test_force_merge_revisions_off(self):
460
self.assertLogRevnos(['-n1'], ['2', '1'], working_dir='level0')
431
------------------------------------------------------------
433
committer: Lorem Ipsum <test@example.com>
438
------------------------------------------------------------
440
committer: Lorem Ipsum <test@example.com>
446
self.check_log(expected, ['--long', '-n1'])
462
448
def test_force_merge_revisions_on(self):
463
self.assertLogRevnos(['-n0'], ['2', '1.1.2', '1.2.1', '1.1.1', '1'],
464
working_dir='level0')
450
2 Lorem Ipsum\t2005-11-22 [merge]
453
1.1.2 Lorem Ipsum\t2005-11-22 [merge]
456
1.2.1 Lorem Ipsum\t2005-11-22
459
1.1.1 Lorem Ipsum\t2005-11-22
462
1 Lorem Ipsum\t2005-11-22
466
self.check_log(expected, ['--short', '-n0'])
466
468
def test_include_merges(self):
467
469
# Confirm --include-merges gives the same output as -n0
468
self.assertLogRevnos(['--include-merges'],
469
['2', '1.1.2', '1.2.1', '1.1.1', '1'],
470
working_dir='level0')
471
self.assertLogRevnos(['--include-merges'],
472
['2', '1.1.2', '1.2.1', '1.1.1', '1'],
473
working_dir='level0')
474
470
out_im, err_im = self.run_bzr('log --include-merges',
475
471
working_dir='level0')
476
472
out_n0, err_n0 = self.run_bzr('log -n0', working_dir='level0')
517
563
self.build_tree(['level0/file1', 'level0/file2'])
518
564
level0.add('file1')
519
565
level0.add('file2')
520
self.wt_commit(level0, 'in branch level0')
566
level0.commit(message='in branch level0', **self.commit_options())
522
568
level1 = level0.bzrdir.sprout('level1').open_workingtree()
523
569
self.build_tree_contents([('level1/file2', 'hello\n')])
524
self.wt_commit(level1, 'in branch level1')
570
level1.commit(message='in branch level1', **self.commit_options())
525
571
level0.merge_from_branch(level1.branch)
526
self.wt_commit(level0, 'merge branch level1')
572
level0.commit(message='merge branch level1', **self.commit_options())
528
def _diff_file1_revno1(self):
529
return """=== added file 'file1'
574
def test_log_show_diff_long_with_merges(self):
575
out,err = self.run_bzr('log -p -n0')
576
self.assertEqual('', err)
577
log = test_log.normalize_log(out)
579
------------------------------------------------------------
581
committer: Lorem Ipsum <test@example.com>
587
=== modified file 'file2'
588
--- file2\t2005-11-22 00:00:01 +0000
589
+++ file2\t2005-11-22 00:00:02 +0000
591
-contents of level0/file2
593
------------------------------------------------------------
595
committer: Lorem Ipsum <test@example.com>
601
=== modified file 'file2'
602
--- file2\t2005-11-22 00:00:01 +0000
603
+++ file2\t2005-11-22 00:00:02 +0000
605
-contents of level0/file2
607
------------------------------------------------------------
609
committer: Lorem Ipsum <test@example.com>
615
=== added file 'file1'
530
616
--- file1\t1970-01-01 00:00:00 +0000
531
+++ file1\t2005-11-22 00:00:00 +0000
617
+++ file1\t2005-11-22 00:00:01 +0000
533
619
+contents of level0/file1
537
def _diff_file2_revno2(self):
538
return """=== modified file 'file2'
539
--- file2\t2005-11-22 00:00:00 +0000
540
+++ file2\t2005-11-22 00:00:01 +0000
542
-contents of level0/file2
547
def _diff_file2_revno1_1_1(self):
548
return """=== modified file 'file2'
549
--- file2\t2005-11-22 00:00:00 +0000
550
+++ file2\t2005-11-22 00:00:01 +0000
552
-contents of level0/file2
557
def _diff_file2_revno1(self):
558
return """=== added file 'file2'
621
=== added file 'file2'
559
622
--- file2\t1970-01-01 00:00:00 +0000
560
+++ file2\t2005-11-22 00:00:00 +0000
623
+++ file2\t2005-11-22 00:00:01 +0000
562
625
+contents of level0/file2
566
def assertLogRevnosAndDiff(self, args, expected,
568
self.run_bzr(['log', '-p'] + args, working_dir=working_dir)
569
expected_revnos_and_depths = [
570
(revno, depth) for revno, depth, diff in expected]
571
# Check the revnos and depths first to make debugging easier
572
self.assertEqual(expected_revnos_and_depths,
573
[(r.revno, r.merge_depth)
574
for r in self.get_captured_revisions()])
575
# Now check the diffs, adding the revno in case of failure
576
fmt = 'In revno %s\n%s'
577
for expected_rev, actual_rev in izip(expected,
578
self.get_captured_revisions()):
579
revno, depth, expected_diff = expected_rev
580
actual_diff = actual_rev.diff
581
self.assertEqualDiff(fmt % (revno, expected_diff),
582
fmt % (revno, actual_diff))
584
def test_log_diff_with_merges(self):
585
self.assertLogRevnosAndDiff(
587
[('2', 0, self._diff_file2_revno2()),
588
('1.1.1', 1, self._diff_file2_revno1_1_1()),
589
('1', 0, self._diff_file1_revno1()
590
+ self._diff_file2_revno1())],
591
working_dir='level0')
594
def test_log_diff_file1(self):
595
self.assertLogRevnosAndDiff(['-n0', 'file1'],
596
[('1', 0, self._diff_file1_revno1())],
597
working_dir='level0')
599
def test_log_diff_file2(self):
600
self.assertLogRevnosAndDiff(['-n1', 'file2'],
601
[('2', 0, self._diff_file2_revno2()),
602
('1', 0, self._diff_file2_revno1())],
603
working_dir='level0')
627
self.check_log(expected, ['-p', '-n0'])
629
def test_log_show_diff_short(self):
631
2 Lorem Ipsum\t2005-11-22 [merge]
633
=== modified file 'file2'
634
--- file2\t2005-11-22 00:00:01 +0000
635
+++ file2\t2005-11-22 00:00:02 +0000
637
-contents of level0/file2
640
1 Lorem Ipsum\t2005-11-22
642
=== added file 'file1'
643
--- file1\t1970-01-01 00:00:00 +0000
644
+++ file1\t2005-11-22 00:00:01 +0000
646
+contents of level0/file1
647
\x20\x20\x20\x20\x20\x20
648
=== added file 'file2'
649
--- file2\t1970-01-01 00:00:00 +0000
650
+++ file2\t2005-11-22 00:00:01 +0000
652
+contents of level0/file2
654
Use --include-merges or -n0 to see merged revisions.
656
self.check_log(expected, ['-p', '--short'])
658
def test_log_show_diff_line(self):
659
# Not supported by this formatter so expect plain output
661
2: Lorem Ipsum 2005-11-22 [merge] merge branch level1
662
1: Lorem Ipsum 2005-11-22 in branch level0
664
self.check_log(expected, ['-p', '--line'])
666
def test_log_show_diff_file1(self):
667
"""Only the diffs for the given file are to be shown"""
669
1 Lorem Ipsum\t2005-11-22
671
=== added file 'file1'
672
--- file1\t1970-01-01 00:00:00 +0000
673
+++ file1\t2005-11-22 00:00:01 +0000
675
+contents of level0/file1
678
self.check_log(expected, ['-p', '--short', 'file1'])
680
def test_log_show_diff_file2(self):
681
"""Only the diffs for the given file are to be shown"""
683
2 Lorem Ipsum\t2005-11-22 [merge]
685
=== modified file 'file2'
686
--- file2\t2005-11-22 00:00:01 +0000
687
+++ file2\t2005-11-22 00:00:02 +0000
689
-contents of level0/file2
692
1 Lorem Ipsum\t2005-11-22
694
=== added file 'file2'
695
--- file2\t1970-01-01 00:00:00 +0000
696
+++ file2\t2005-11-22 00:00:01 +0000
698
+contents of level0/file2
700
Use --include-merges or -n0 to see merged revisions.
702
self.check_log(expected, ['-p', '--short', 'file2'])
606
705
class TestLogUnicodeDiff(TestLog):
758
860
tree.commit('remove file1')
759
861
os.chdir('parent')
761
# FIXME: It would be good to parametrize the following tests against all
762
# formatters. But the revisions selection is not *currently* part of the
763
# LogFormatter contract, so using LogCatcher is sufficient -- vila 100118
764
def test_log_file1(self):
766
self.assertLogRevnos(['-n0', 'file1'], ['1'])
768
def test_log_file2(self):
771
self.assertLogRevnos(['-n0', 'file2'], ['4', '3.1.1', '2'])
772
# file2 in a merge revision
773
self.assertLogRevnos(['-n0', '-r3.1.1', 'file2'], ['3.1.1'])
774
# file2 in a mainline revision
775
self.assertLogRevnos(['-n0', '-r4', 'file2'], ['4', '3.1.1'])
776
# file2 since a revision
777
self.assertLogRevnos(['-n0', '-r3..', 'file2'], ['4', '3.1.1'])
778
# file2 up to a revision
779
self.assertLogRevnos(['-n0', '-r..3', 'file2'], ['2'])
781
def test_log_file3(self):
783
self.assertLogRevnos(['-n0', 'file3'], ['3'])
863
def test_log_file(self):
864
"""The log for a particular file should only list revs for that file"""
866
log = self.run_bzr('log -n0 file1')[0]
867
self.assertContainsRe(log, 'revno: 1\n')
868
self.assertNotContainsRe(log, 'revno: 2\n')
869
self.assertNotContainsRe(log, 'revno: 3\n')
870
self.assertNotContainsRe(log, 'revno: 3.1.1\n')
871
self.assertNotContainsRe(log, 'revno: 4 ')
872
log = self.run_bzr('log -n0 file2')[0]
873
self.assertNotContainsRe(log, 'revno: 1\n')
874
self.assertContainsRe(log, 'revno: 2\n')
875
self.assertNotContainsRe(log, 'revno: 3\n')
876
self.assertContainsRe(log, 'revno: 3.1.1\n')
877
self.assertContainsRe(log, 'revno: 4 ')
878
log = self.run_bzr('log -n0 file3')[0]
879
self.assertNotContainsRe(log, 'revno: 1\n')
880
self.assertNotContainsRe(log, 'revno: 2\n')
881
self.assertContainsRe(log, 'revno: 3\n')
882
self.assertNotContainsRe(log, 'revno: 3.1.1\n')
883
self.assertNotContainsRe(log, 'revno: 4 ')
884
log = self.run_bzr('log -n0 -r3.1.1 file2')[0]
885
self.assertNotContainsRe(log, 'revno: 1\n')
886
self.assertNotContainsRe(log, 'revno: 2\n')
887
self.assertNotContainsRe(log, 'revno: 3\n')
888
self.assertContainsRe(log, 'revno: 3.1.1\n')
889
self.assertNotContainsRe(log, 'revno: 4 ')
890
log = self.run_bzr('log -n0 -r4 file2')[0]
891
self.assertNotContainsRe(log, 'revno: 1\n')
892
self.assertNotContainsRe(log, 'revno: 2\n')
893
self.assertNotContainsRe(log, 'revno: 3\n')
894
self.assertContainsRe(log, 'revno: 3.1.1\n')
895
self.assertContainsRe(log, 'revno: 4 ')
896
log = self.run_bzr('log -n0 -r3.. file2')[0]
897
self.assertNotContainsRe(log, 'revno: 1\n')
898
self.assertNotContainsRe(log, 'revno: 2\n')
899
self.assertNotContainsRe(log, 'revno: 3\n')
900
self.assertContainsRe(log, 'revno: 3.1.1\n')
901
self.assertContainsRe(log, 'revno: 4 ')
902
log = self.run_bzr('log -n0 -r..3 file2')[0]
903
self.assertNotContainsRe(log, 'revno: 1\n')
904
self.assertContainsRe(log, 'revno: 2\n')
905
self.assertNotContainsRe(log, 'revno: 3\n')
906
self.assertNotContainsRe(log, 'revno: 3.1.1\n')
907
self.assertNotContainsRe(log, 'revno: 4 ')
785
909
def test_log_file_historical_missing(self):
786
910
# Check logging a deleted file gives an error if the
812
948
self.assertContainsRe(err, err_msg)
814
950
# Check we can see a renamed file if we give the right end revision
815
self.assertLogRevnos(['-r..4', 'file3'], ['3'])
818
class TestLogMultiple(TestLogWithLogCatcher):
951
log, err = self.run_bzr('log -r..4 file3')
952
self.assertEquals('', err)
953
self.assertNotContainsRe(log, 'revno: 1\n')
954
self.assertNotContainsRe(log, 'revno: 2\n')
955
self.assertContainsRe(log, 'revno: 3\n')
956
self.assertNotContainsRe(log, 'revno: 3.1.1\n')
957
self.assertNotContainsRe(log, 'revno: 4 ')
959
def test_line_log_file(self):
960
"""The line log for a file should only list relevant mainline revs"""
961
# Note: this also implicitly covers the short logging case.
962
# We test using --line in preference to --short because matching
963
# revnos in the output of --line is more reliable.
966
# full history of file1
967
log = self.run_bzr('log --line file1')[0]
968
self.assertContainsRe(log, '^1:', re.MULTILINE)
969
self.assertNotContainsRe(log, '^2:', re.MULTILINE)
970
self.assertNotContainsRe(log, '^3:', re.MULTILINE)
971
self.assertNotContainsRe(log, '^3.1.1:', re.MULTILINE)
972
self.assertNotContainsRe(log, '^4:', re.MULTILINE)
974
# full history of file2
975
log = self.run_bzr('log --line file2')[0]
976
self.assertNotContainsRe(log, '^1:', re.MULTILINE)
977
self.assertContainsRe(log, '^2:', re.MULTILINE)
978
self.assertNotContainsRe(log, '^3:', re.MULTILINE)
979
self.assertNotContainsRe(log, '^3.1.1:', re.MULTILINE)
980
self.assertContainsRe(log, '^4:', re.MULTILINE)
982
# full history of file3
983
log = self.run_bzr('log --line file3')[0]
984
self.assertNotContainsRe(log, '^1:', re.MULTILINE)
985
self.assertNotContainsRe(log, '^2:', re.MULTILINE)
986
self.assertContainsRe(log, '^3:', re.MULTILINE)
987
self.assertNotContainsRe(log, '^3.1.1:', re.MULTILINE)
988
self.assertNotContainsRe(log, '^4:', re.MULTILINE)
990
# file in a merge revision
991
log = self.run_bzr('log --line -r3.1.1 file2')[0]
992
self.assertNotContainsRe(log, '^1:', re.MULTILINE)
993
self.assertNotContainsRe(log, '^2:', re.MULTILINE)
994
self.assertNotContainsRe(log, '^3:', re.MULTILINE)
995
self.assertContainsRe(log, '^3.1.1:', re.MULTILINE)
996
self.assertNotContainsRe(log, '^4:', re.MULTILINE)
998
# file in a mainline revision
999
log = self.run_bzr('log --line -r4 file2')[0]
1000
self.assertNotContainsRe(log, '^1:', re.MULTILINE)
1001
self.assertNotContainsRe(log, '^2:', re.MULTILINE)
1002
self.assertNotContainsRe(log, '^3:', re.MULTILINE)
1003
self.assertNotContainsRe(log, '^3.1.1:', re.MULTILINE)
1004
self.assertContainsRe(log, '^4:', re.MULTILINE)
1006
# file since a revision
1007
log = self.run_bzr('log --line -r3.. file2')[0]
1008
self.assertNotContainsRe(log, '^1:', re.MULTILINE)
1009
self.assertNotContainsRe(log, '^2:', re.MULTILINE)
1010
self.assertNotContainsRe(log, '^3:', re.MULTILINE)
1011
self.assertNotContainsRe(log, '^3.1.1:', re.MULTILINE)
1012
self.assertContainsRe(log, '^4:', re.MULTILINE)
1014
# file up to a revision
1015
log = self.run_bzr('log --line -r..3 file2')[0]
1016
self.assertNotContainsRe(log, '^1:', re.MULTILINE)
1017
self.assertContainsRe(log, '^2:', re.MULTILINE)
1018
self.assertNotContainsRe(log, '^3:', re.MULTILINE)
1019
self.assertNotContainsRe(log, '^3.1.1:', re.MULTILINE)
1020
self.assertNotContainsRe(log, '^4:', re.MULTILINE)
1023
class TestLogMultiple(tests.TestCaseWithTransport):
820
1025
def prepare_tree(self):
821
1026
tree = self.make_branch_and_tree('parent')