55
53
tree.commit(message='message3')
58
def make_merged_branch(self, path='.', format=None):
59
tree = self.make_linear_branch(path, format)
60
tree2 = tree.bzrdir.sprout('tree2',
61
revision_id=tree.branch.get_rev_id(1)).open_workingtree()
62
tree2.commit(message='tree2 message2')
63
tree2.commit(message='tree2 message3')
64
tree.merge_from_branch(tree2.branch)
65
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'])
56
def commit_options(self):
57
"""Use some mostly fixed values for commits to simplify tests.
59
Tests can use this function to get some commit attributes. The time
60
stamp is incremented at each commit.
62
self.timestamp += 1 # 1 second between each commit
63
return dict(committer='Lorem Ipsum <joe@foo.com>',
64
timezone=self.timezone,
65
timestamp=self.timestamp,
68
def check_log(self, expected, args, working_dir='level0'):
69
out, err = self.run_bzr(['log', '--timezone', 'utc'] + args,
70
working_dir=working_dir)
71
self.assertEqual('', err)
72
self.assertEqualDiff(expected, test_log.normalize_log(out))
75
class TestLogRevSpecs(TestLog):
110
77
def test_log_null_end_revspec(self):
111
78
self.make_linear_branch()
112
self.assertLogRevnos(['-r1..'], ['3', '2', '1'])
79
log = self.run_bzr(['log'])[0]
80
self.assertTrue('revno: 1\n' in log)
81
self.assertTrue('revno: 2\n' in log)
82
self.assertTrue('revno: 3\n' in log)
83
self.assertTrue('message:\n message1\n' in log)
84
self.assertTrue('message:\n message2\n' in log)
85
self.assertTrue('message:\n message3\n' in log)
87
full_log = self.run_bzr(['log'])[0]
88
log = self.run_bzr("log -r 1..")[0]
89
self.assertEqualDiff(log, full_log)
114
91
def test_log_null_begin_revspec(self):
115
92
self.make_linear_branch()
116
self.assertLogRevnos(['-r..3'], ['3', '2', '1'])
93
full_log = self.run_bzr(['log'])[0]
94
log = self.run_bzr("log -r ..3")[0]
95
self.assertEqualDiff(full_log, log)
118
97
def test_log_null_both_revspecs(self):
119
98
self.make_linear_branch()
120
self.assertLogRevnos(['-r..'], ['3', '2', '1'])
99
full_log = self.run_bzr(['log'])[0]
100
log = self.run_bzr("log -r ..")[0]
101
self.assertEqualDiff(full_log, log)
103
def test_log_zero_revspec(self):
104
self.make_minimal_branch()
105
self.run_bzr_error(['bzr: ERROR: Logging revision 0 is invalid.'],
108
def test_log_zero_begin_revspec(self):
109
self.make_linear_branch()
110
self.run_bzr_error(['bzr: ERROR: Logging revision 0 is invalid.'],
113
def test_log_zero_end_revspec(self):
114
self.make_linear_branch()
115
self.run_bzr_error(['bzr: ERROR: Logging revision 0 is invalid.'],
122
118
def test_log_negative_begin_revspec_full_log(self):
123
119
self.make_linear_branch()
124
self.assertLogRevnos(['-r-3..'], ['3', '2', '1'])
120
full_log = self.run_bzr(['log'])[0]
121
log = self.run_bzr("log -r -3..")[0]
122
self.assertEqualDiff(full_log, log)
126
124
def test_log_negative_both_revspec_full_log(self):
127
125
self.make_linear_branch()
128
self.assertLogRevnos(['-r-3..-1'], ['3', '2', '1'])
126
full_log = self.run_bzr(['log'])[0]
127
log = self.run_bzr("log -r -3..-1")[0]
128
self.assertEqualDiff(full_log, log)
130
130
def test_log_negative_both_revspec_partial(self):
131
131
self.make_linear_branch()
132
self.assertLogRevnos(['-r-3..-2'], ['2', '1'])
132
log = self.run_bzr("log -r -3..-2")[0]
133
self.assertTrue('revno: 1\n' in log)
134
self.assertTrue('revno: 2\n' in log)
135
self.assertTrue('revno: 3\n' not in log)
134
137
def test_log_negative_begin_revspec(self):
135
138
self.make_linear_branch()
136
self.assertLogRevnos(['-r-2..'], ['3', '2'])
139
log = self.run_bzr("log -r -2..")[0]
140
self.assertTrue('revno: 1\n' not in log)
141
self.assertTrue('revno: 2\n' in log)
142
self.assertTrue('revno: 3\n' in log)
138
144
def test_log_positive_revspecs(self):
139
145
self.make_linear_branch()
140
self.assertLogRevnos(['-r1..3'], ['3', '2', '1'])
142
def test_log_dotted_revspecs(self):
143
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):
209
super(Test_GenerateAllRevisions, self).setUp()
210
builder = self.make_branch_with_many_merges()
211
b = builder.get_branch()
213
self.addCleanup(b.unlock)
216
def make_branch_with_many_merges(self, path='.', format=None):
217
builder = branchbuilder.BranchBuilder(self.get_transport())
218
builder.start_series()
219
# The graph below may look a bit complicated (and it may be but I've
220
# banged my head enough on it) but the bug requires at least dotted
221
# revnos *and* merged revisions below that.
222
builder.build_snapshot('1', None, [
223
('add', ('', 'root-id', 'directory', ''))])
224
builder.build_snapshot('2', ['1'], [])
225
builder.build_snapshot('1.1.1', ['1'], [])
226
builder.build_snapshot('2.1.1', ['2'], [])
227
builder.build_snapshot('3', ['2', '1.1.1'], [])
228
builder.build_snapshot('2.1.2', ['2.1.1'], [])
229
builder.build_snapshot('2.2.1', ['2.1.1'], [])
230
builder.build_snapshot('2.1.3', ['2.1.2', '2.2.1'], [])
231
builder.build_snapshot('4', ['3', '2.1.3'], [])
232
builder.build_snapshot('5', ['4', '2.1.2'], [])
233
builder.finish_series()
236
def test_not_an_ancestor(self):
237
self.assertRaises(errors.BzrCommandError,
238
log._generate_all_revisions,
239
self.branch, '1.1.1', '2.1.3', 'reverse',
240
delayed_graph_generation=True)
242
def test_wrong_order(self):
243
self.assertRaises(errors.BzrCommandError,
244
log._generate_all_revisions,
245
self.branch, '5', '2.1.3', 'reverse',
246
delayed_graph_generation=True)
248
def test_no_start_rev_id_with_end_rev_id_being_a_merge(self):
249
revs = log._generate_all_revisions(
250
self.branch, None, '2.1.3',
251
'reverse', delayed_graph_generation=True)
254
class TestLogRevSpecsWithPaths(TestLogWithLogCatcher):
256
def test_log_revno_n_path_wrong_namespace(self):
146
full_log = self.run_bzr(['log'])[0]
147
log = self.run_bzr("log -r 1..3")[0]
148
self.assertEqualDiff(full_log, log)
150
def test_log_reversed_revspecs(self):
151
self.make_linear_branch()
152
self.run_bzr_error(('bzr: ERROR: Start revision must be older than '
153
'the end revision.\n',),
156
def test_log_revno_n_path(self):
257
157
self.make_linear_branch('branch1')
258
158
self.make_linear_branch('branch2')
259
# There is no guarantee that a path exist between two arbitrary
261
self.run_bzr("log -r revno:2:branch1..revno:3:branch2", retcode=3)
263
def test_log_revno_n_path_correct_order(self):
264
self.make_linear_branch('branch2')
265
self.assertLogRevnos(['-rrevno:1:branch2..revno:3:branch2'],
268
def test_log_revno_n_path(self):
269
self.make_linear_branch('branch2')
270
self.assertLogRevnos(['-rrevno:1:branch2'],
272
rev_props = self.log_catcher.revisions[0].rev.properties
273
self.assertEqual('branch2', rev_props['branch-nick'])
276
class TestLogErrors(TestLog):
278
def test_log_zero_revspec(self):
279
self.make_minimal_branch()
280
self.run_bzr_error(['bzr: ERROR: Logging revision 0 is invalid.'],
283
def test_log_zero_begin_revspec(self):
284
self.make_linear_branch()
285
self.run_bzr_error(['bzr: ERROR: Logging revision 0 is invalid.'],
288
def test_log_zero_end_revspec(self):
289
self.make_linear_branch()
290
self.run_bzr_error(['bzr: ERROR: Logging revision 0 is invalid.'],
160
self.run_bzr("log -r revno:2:branch1..revno:3:branch2", retcode=3)[0]
162
log = self.run_bzr("log -r revno:1:branch2..revno:3:branch2")[0]
163
full_log = self.run_bzr(['log'], working_dir='branch2')[0]
164
self.assertEqualDiff(full_log, log)
165
log = self.run_bzr("log -r revno:1:branch2")[0]
166
self.assertTrue('revno: 1\n' in log)
167
self.assertTrue('revno: 2\n' not in log)
168
self.assertTrue('branch nick: branch2\n' in log)
169
self.assertTrue('branch nick: branch1\n' not in log)
293
171
def test_log_nonexistent_revno(self):
294
172
self.make_minimal_branch()
295
self.run_bzr_error(["bzr: ERROR: Requested revision: '1234' "
296
"does not exist in branch:"],
173
(out, err) = self.run_bzr_error(
174
["bzr: ERROR: Requested revision: '1234' "
175
"does not exist in branch:"],
299
178
def test_log_nonexistent_dotted_revno(self):
300
179
self.make_minimal_branch()
301
self.run_bzr_error(["bzr: ERROR: Requested revision: '123.123' "
302
"does not exist in branch:"],
303
['log', '-r123.123'])
180
(out, err) = self.run_bzr_error(
181
["bzr: ERROR: Requested revision: '123.123' "
182
"does not exist in branch:"],
183
['log', '-r123.123'])
185
def test_log_change_revno(self):
186
self.make_linear_branch()
187
expected_log = self.run_bzr("log -r 1")[0]
188
log = self.run_bzr("log -c 1")[0]
189
self.assertEqualDiff(expected_log, log)
305
191
def test_log_change_nonexistent_revno(self):
306
192
self.make_minimal_branch()
307
self.run_bzr_error(["bzr: ERROR: Requested revision: '1234' "
308
"does not exist in branch:"],
193
(out, err) = self.run_bzr_error(
194
["bzr: ERROR: Requested revision: '1234' "
195
"does not exist in branch:"],
311
198
def test_log_change_nonexistent_dotted_revno(self):
312
199
self.make_minimal_branch()
313
self.run_bzr_error(["bzr: ERROR: Requested revision: '123.123' "
314
"does not exist in branch:"],
315
['log', '-c123.123'])
200
(out, err) = self.run_bzr_error(
201
["bzr: ERROR: Requested revision: '123.123' "
202
"does not exist in branch:"],
203
['log', '-c123.123'])
317
205
def test_log_change_single_revno_only(self):
318
206
self.make_minimal_branch()
455
343
def make_branches_with_merges(self):
456
344
level0 = self.make_branch_and_tree('level0')
457
self.wt_commit(level0, 'in branch level0')
345
level0.commit(message='in branch level0', **self.commit_options())
458
347
level1 = level0.bzrdir.sprout('level1').open_workingtree()
459
self.wt_commit(level1, 'in branch level1')
348
level1.commit(message='in branch level1', **self.commit_options())
460
350
level2 = level1.bzrdir.sprout('level2').open_workingtree()
461
self.wt_commit(level2, 'in branch level2')
351
level2.commit(message='in branch level2', **self.commit_options())
462
353
level1.merge_from_branch(level2.branch)
463
self.wt_commit(level1, 'merge branch level2')
354
level1.commit(message='merge branch level2', **self.commit_options())
464
356
level0.merge_from_branch(level1.branch)
465
self.wt_commit(level0, 'merge branch level1')
357
level0.commit(message='merge branch level1', **self.commit_options())
467
359
def test_merges_are_indented_by_level(self):
468
self.run_bzr(['log', '-n0'], working_dir='level0')
469
revnos_and_depth = [(r.revno, r.merge_depth)
470
for r in self.get_captured_revisions()]
471
self.assertEqual([('2', 0), ('1.1.2', 1), ('1.2.1', 2), ('1.1.1', 1),
473
[(r.revno, r.merge_depth)
474
for r in self.get_captured_revisions()])
361
------------------------------------------------------------
363
committer: Lorem Ipsum <test@example.com>
368
------------------------------------------------------------
370
committer: Lorem Ipsum <test@example.com>
375
------------------------------------------------------------
377
committer: Lorem Ipsum <test@example.com>
382
------------------------------------------------------------
384
committer: Lorem Ipsum <test@example.com>
389
------------------------------------------------------------
391
committer: Lorem Ipsum <test@example.com>
397
self.check_log(expected, ['-n0'])
476
399
def test_force_merge_revisions_off(self):
477
self.assertLogRevnos(['-n1'], ['2', '1'], working_dir='level0')
401
------------------------------------------------------------
403
committer: Lorem Ipsum <test@example.com>
408
------------------------------------------------------------
410
committer: Lorem Ipsum <test@example.com>
416
self.check_log(expected, ['--long', '-n1'])
479
418
def test_force_merge_revisions_on(self):
480
self.assertLogRevnos(['-n0'], ['2', '1.1.2', '1.2.1', '1.1.1', '1'],
481
working_dir='level0')
420
2 Lorem Ipsum\t2005-11-22 [merge]
423
1.1.2 Lorem Ipsum\t2005-11-22 [merge]
426
1.2.1 Lorem Ipsum\t2005-11-22
429
1.1.1 Lorem Ipsum\t2005-11-22
432
1 Lorem Ipsum\t2005-11-22
436
self.check_log(expected, ['--short', '-n0'])
483
438
def test_include_merges(self):
484
439
# Confirm --include-merges gives the same output as -n0
485
self.assertLogRevnos(['--include-merges'],
486
['2', '1.1.2', '1.2.1', '1.1.1', '1'],
487
working_dir='level0')
488
self.assertLogRevnos(['--include-merges'],
489
['2', '1.1.2', '1.2.1', '1.1.1', '1'],
490
working_dir='level0')
491
440
out_im, err_im = self.run_bzr('log --include-merges',
492
441
working_dir='level0')
493
442
out_n0, err_n0 = self.run_bzr('log -n0', working_dir='level0')
534
518
self.build_tree(['level0/file1', 'level0/file2'])
535
519
level0.add('file1')
536
520
level0.add('file2')
537
self.wt_commit(level0, 'in branch level0')
521
level0.commit(message='in branch level0', **self.commit_options())
539
523
level1 = level0.bzrdir.sprout('level1').open_workingtree()
540
524
self.build_tree_contents([('level1/file2', 'hello\n')])
541
self.wt_commit(level1, 'in branch level1')
525
level1.commit(message='in branch level1', **self.commit_options())
542
526
level0.merge_from_branch(level1.branch)
543
self.wt_commit(level0, 'merge branch level1')
527
level0.commit(message='merge branch level1', **self.commit_options())
545
def _diff_file1_revno1(self):
546
return """=== added file 'file1'
529
def test_log_show_diff_long_with_merges(self):
530
out,err = self.run_bzr('log -p -n0')
531
self.assertEqual('', err)
532
log = test_log.normalize_log(out)
534
------------------------------------------------------------
536
committer: Lorem Ipsum <test@example.com>
542
=== modified file 'file2'
543
--- file2\t2005-11-22 00:00:01 +0000
544
+++ file2\t2005-11-22 00:00:02 +0000
546
-contents of level0/file2
548
------------------------------------------------------------
550
committer: Lorem Ipsum <test@example.com>
556
=== modified file 'file2'
557
--- file2\t2005-11-22 00:00:01 +0000
558
+++ file2\t2005-11-22 00:00:02 +0000
560
-contents of level0/file2
562
------------------------------------------------------------
564
committer: Lorem Ipsum <test@example.com>
570
=== added file 'file1'
547
571
--- file1\t1970-01-01 00:00:00 +0000
548
+++ file1\t2005-11-22 00:00:00 +0000
572
+++ file1\t2005-11-22 00:00:01 +0000
550
574
+contents of level0/file1
554
def _diff_file2_revno2(self):
555
return """=== modified file 'file2'
556
--- file2\t2005-11-22 00:00:00 +0000
557
+++ file2\t2005-11-22 00:00:01 +0000
559
-contents of level0/file2
564
def _diff_file2_revno1_1_1(self):
565
return """=== modified file 'file2'
566
--- file2\t2005-11-22 00:00:00 +0000
567
+++ file2\t2005-11-22 00:00:01 +0000
569
-contents of level0/file2
574
def _diff_file2_revno1(self):
575
return """=== added file 'file2'
576
=== added file 'file2'
576
577
--- file2\t1970-01-01 00:00:00 +0000
577
+++ file2\t2005-11-22 00:00:00 +0000
578
+++ file2\t2005-11-22 00:00:01 +0000
579
580
+contents of level0/file2
583
def assertLogRevnosAndDiff(self, args, expected,
585
self.run_bzr(['log', '-p'] + args, working_dir=working_dir)
586
expected_revnos_and_depths = [
587
(revno, depth) for revno, depth, diff in expected]
588
# Check the revnos and depths first to make debugging easier
589
self.assertEqual(expected_revnos_and_depths,
590
[(r.revno, r.merge_depth)
591
for r in self.get_captured_revisions()])
592
# Now check the diffs, adding the revno in case of failure
593
fmt = 'In revno %s\n%s'
594
for expected_rev, actual_rev in izip(expected,
595
self.get_captured_revisions()):
596
revno, depth, expected_diff = expected_rev
597
actual_diff = actual_rev.diff
598
self.assertEqualDiff(fmt % (revno, expected_diff),
599
fmt % (revno, actual_diff))
601
def test_log_diff_with_merges(self):
602
self.assertLogRevnosAndDiff(
604
[('2', 0, self._diff_file2_revno2()),
605
('1.1.1', 1, self._diff_file2_revno1_1_1()),
606
('1', 0, self._diff_file1_revno1()
607
+ self._diff_file2_revno1())],
608
working_dir='level0')
611
def test_log_diff_file1(self):
612
self.assertLogRevnosAndDiff(['-n0', 'file1'],
613
[('1', 0, self._diff_file1_revno1())],
614
working_dir='level0')
616
def test_log_diff_file2(self):
617
self.assertLogRevnosAndDiff(['-n1', 'file2'],
618
[('2', 0, self._diff_file2_revno2()),
619
('1', 0, self._diff_file2_revno1())],
620
working_dir='level0')
582
self.check_log(expected, ['-p', '-n0'])
584
def test_log_show_diff_short(self):
586
2 Lorem Ipsum\t2005-11-22 [merge]
588
=== modified file 'file2'
589
--- file2\t2005-11-22 00:00:01 +0000
590
+++ file2\t2005-11-22 00:00:02 +0000
592
-contents of level0/file2
595
1 Lorem Ipsum\t2005-11-22
597
=== added file 'file1'
598
--- file1\t1970-01-01 00:00:00 +0000
599
+++ file1\t2005-11-22 00:00:01 +0000
601
+contents of level0/file1
602
\x20\x20\x20\x20\x20\x20
603
=== added file 'file2'
604
--- file2\t1970-01-01 00:00:00 +0000
605
+++ file2\t2005-11-22 00:00:01 +0000
607
+contents of level0/file2
609
Use --include-merges or -n0 to see merged revisions.
611
self.check_log(expected, ['-p', '--short'])
613
def test_log_show_diff_line(self):
614
# Not supported by this formatter so expect plain output
616
2: Lorem Ipsum 2005-11-22 [merge] merge branch level1
617
1: Lorem Ipsum 2005-11-22 in branch level0
619
self.check_log(expected, ['-p', '--line'])
621
def test_log_show_diff_file1(self):
622
"""Only the diffs for the given file are to be shown"""
624
1 Lorem Ipsum\t2005-11-22
626
=== added file 'file1'
627
--- file1\t1970-01-01 00:00:00 +0000
628
+++ file1\t2005-11-22 00:00:01 +0000
630
+contents of level0/file1
633
self.check_log(expected, ['-p', '--short', 'file1'])
635
def test_log_show_diff_file2(self):
636
"""Only the diffs for the given file are to be shown"""
638
2 Lorem Ipsum\t2005-11-22 [merge]
640
=== modified file 'file2'
641
--- file2\t2005-11-22 00:00:01 +0000
642
+++ file2\t2005-11-22 00:00:02 +0000
644
-contents of level0/file2
647
1 Lorem Ipsum\t2005-11-22
649
=== added file 'file2'
650
--- file2\t1970-01-01 00:00:00 +0000
651
+++ file2\t2005-11-22 00:00:01 +0000
653
+contents of level0/file2
655
Use --include-merges or -n0 to see merged revisions.
657
self.check_log(expected, ['-p', '--short', 'file2'])
623
660
class TestLogUnicodeDiff(TestLog):
775
815
tree.commit('remove file1')
776
816
os.chdir('parent')
778
# FIXME: It would be good to parametrize the following tests against all
779
# formatters. But the revisions selection is not *currently* part of the
780
# LogFormatter contract, so using LogCatcher is sufficient -- vila 100118
781
def test_log_file1(self):
783
self.assertLogRevnos(['-n0', 'file1'], ['1'])
785
def test_log_file2(self):
788
self.assertLogRevnos(['-n0', 'file2'], ['4', '3.1.1', '2'])
789
# file2 in a merge revision
790
self.assertLogRevnos(['-n0', '-r3.1.1', 'file2'], ['3.1.1'])
791
# file2 in a mainline revision
792
self.assertLogRevnos(['-n0', '-r4', 'file2'], ['4', '3.1.1'])
793
# file2 since a revision
794
self.assertLogRevnos(['-n0', '-r3..', 'file2'], ['4', '3.1.1'])
795
# file2 up to a revision
796
self.assertLogRevnos(['-n0', '-r..3', 'file2'], ['2'])
798
def test_log_file3(self):
800
self.assertLogRevnos(['-n0', 'file3'], ['3'])
818
def test_log_file(self):
819
"""The log for a particular file should only list revs for that file"""
821
log = self.run_bzr('log -n0 file1')[0]
822
self.assertContainsRe(log, 'revno: 1\n')
823
self.assertNotContainsRe(log, 'revno: 2\n')
824
self.assertNotContainsRe(log, 'revno: 3\n')
825
self.assertNotContainsRe(log, 'revno: 3.1.1\n')
826
self.assertNotContainsRe(log, 'revno: 4 ')
827
log = self.run_bzr('log -n0 file2')[0]
828
self.assertNotContainsRe(log, 'revno: 1\n')
829
self.assertContainsRe(log, 'revno: 2\n')
830
self.assertNotContainsRe(log, 'revno: 3\n')
831
self.assertContainsRe(log, 'revno: 3.1.1\n')
832
self.assertContainsRe(log, 'revno: 4 ')
833
log = self.run_bzr('log -n0 file3')[0]
834
self.assertNotContainsRe(log, 'revno: 1\n')
835
self.assertNotContainsRe(log, 'revno: 2\n')
836
self.assertContainsRe(log, 'revno: 3\n')
837
self.assertNotContainsRe(log, 'revno: 3.1.1\n')
838
self.assertNotContainsRe(log, 'revno: 4 ')
839
log = self.run_bzr('log -n0 -r3.1.1 file2')[0]
840
self.assertNotContainsRe(log, 'revno: 1\n')
841
self.assertNotContainsRe(log, 'revno: 2\n')
842
self.assertNotContainsRe(log, 'revno: 3\n')
843
self.assertContainsRe(log, 'revno: 3.1.1\n')
844
self.assertNotContainsRe(log, 'revno: 4 ')
845
log = self.run_bzr('log -n0 -r4 file2')[0]
846
self.assertNotContainsRe(log, 'revno: 1\n')
847
self.assertNotContainsRe(log, 'revno: 2\n')
848
self.assertNotContainsRe(log, 'revno: 3\n')
849
self.assertContainsRe(log, 'revno: 3.1.1\n')
850
self.assertContainsRe(log, 'revno: 4 ')
851
log = self.run_bzr('log -n0 -r3.. file2')[0]
852
self.assertNotContainsRe(log, 'revno: 1\n')
853
self.assertNotContainsRe(log, 'revno: 2\n')
854
self.assertNotContainsRe(log, 'revno: 3\n')
855
self.assertContainsRe(log, 'revno: 3.1.1\n')
856
self.assertContainsRe(log, 'revno: 4 ')
857
log = self.run_bzr('log -n0 -r..3 file2')[0]
858
self.assertNotContainsRe(log, 'revno: 1\n')
859
self.assertContainsRe(log, 'revno: 2\n')
860
self.assertNotContainsRe(log, 'revno: 3\n')
861
self.assertNotContainsRe(log, 'revno: 3.1.1\n')
862
self.assertNotContainsRe(log, 'revno: 4 ')
802
864
def test_log_file_historical_missing(self):
803
865
# Check logging a deleted file gives an error if the
829
903
self.assertContainsRe(err, err_msg)
831
905
# Check we can see a renamed file if we give the right end revision
832
self.assertLogRevnos(['-r..4', 'file3'], ['3'])
835
class TestLogMultiple(TestLogWithLogCatcher):
906
log, err = self.run_bzr('log -r..4 file3')
907
self.assertEquals('', err)
908
self.assertNotContainsRe(log, 'revno: 1\n')
909
self.assertNotContainsRe(log, 'revno: 2\n')
910
self.assertContainsRe(log, 'revno: 3\n')
911
self.assertNotContainsRe(log, 'revno: 3.1.1\n')
912
self.assertNotContainsRe(log, 'revno: 4 ')
914
def test_line_log_file(self):
915
"""The line log for a file should only list relevant mainline revs"""
916
# Note: this also implicitly covers the short logging case.
917
# We test using --line in preference to --short because matching
918
# revnos in the output of --line is more reliable.
921
# full history of file1
922
log = self.run_bzr('log --line file1')[0]
923
self.assertContainsRe(log, '^1:', re.MULTILINE)
924
self.assertNotContainsRe(log, '^2:', re.MULTILINE)
925
self.assertNotContainsRe(log, '^3:', re.MULTILINE)
926
self.assertNotContainsRe(log, '^3.1.1:', re.MULTILINE)
927
self.assertNotContainsRe(log, '^4:', re.MULTILINE)
929
# full history of file2
930
log = self.run_bzr('log --line file2')[0]
931
self.assertNotContainsRe(log, '^1:', re.MULTILINE)
932
self.assertContainsRe(log, '^2:', re.MULTILINE)
933
self.assertNotContainsRe(log, '^3:', re.MULTILINE)
934
self.assertNotContainsRe(log, '^3.1.1:', re.MULTILINE)
935
self.assertContainsRe(log, '^4:', re.MULTILINE)
937
# full history of file3
938
log = self.run_bzr('log --line file3')[0]
939
self.assertNotContainsRe(log, '^1:', re.MULTILINE)
940
self.assertNotContainsRe(log, '^2:', re.MULTILINE)
941
self.assertContainsRe(log, '^3:', re.MULTILINE)
942
self.assertNotContainsRe(log, '^3.1.1:', re.MULTILINE)
943
self.assertNotContainsRe(log, '^4:', re.MULTILINE)
945
# file in a merge revision
946
log = self.run_bzr('log --line -r3.1.1 file2')[0]
947
self.assertNotContainsRe(log, '^1:', re.MULTILINE)
948
self.assertNotContainsRe(log, '^2:', re.MULTILINE)
949
self.assertNotContainsRe(log, '^3:', re.MULTILINE)
950
self.assertContainsRe(log, '^3.1.1:', re.MULTILINE)
951
self.assertNotContainsRe(log, '^4:', re.MULTILINE)
953
# file in a mainline revision
954
log = self.run_bzr('log --line -r4 file2')[0]
955
self.assertNotContainsRe(log, '^1:', re.MULTILINE)
956
self.assertNotContainsRe(log, '^2:', re.MULTILINE)
957
self.assertNotContainsRe(log, '^3:', re.MULTILINE)
958
self.assertNotContainsRe(log, '^3.1.1:', re.MULTILINE)
959
self.assertContainsRe(log, '^4:', re.MULTILINE)
961
# file since a revision
962
log = self.run_bzr('log --line -r3.. file2')[0]
963
self.assertNotContainsRe(log, '^1:', re.MULTILINE)
964
self.assertNotContainsRe(log, '^2:', re.MULTILINE)
965
self.assertNotContainsRe(log, '^3:', re.MULTILINE)
966
self.assertNotContainsRe(log, '^3.1.1:', re.MULTILINE)
967
self.assertContainsRe(log, '^4:', re.MULTILINE)
969
# file up to a revision
970
log = self.run_bzr('log --line -r..3 file2')[0]
971
self.assertNotContainsRe(log, '^1:', re.MULTILINE)
972
self.assertContainsRe(log, '^2:', re.MULTILINE)
973
self.assertNotContainsRe(log, '^3:', re.MULTILINE)
974
self.assertNotContainsRe(log, '^3.1.1:', re.MULTILINE)
975
self.assertNotContainsRe(log, '^4:', re.MULTILINE)
978
class TestLogMultiple(tests.TestCaseWithTransport):
837
980
def prepare_tree(self):
838
981
tree = self.make_branch_and_tree('parent')