~bzr-pqm/bzr/bzr.dev

4988.10.3 by John Arbash Meinel
Merge bzr.dev 5007, resolve conflict, update NEWS
1
# Copyright (C) 2006-2010 Canonical Ltd
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
2
#
1540.2.6 by Robey Pointer
make 'log' and 'status' treat '-r N..' as implicitly '-r N..-1'
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
7
#
1540.2.6 by Robey Pointer
make 'log' and 'status' treat '-r N..' as implicitly '-r N..-1'
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
12
#
1540.2.6 by Robey Pointer
make 'log' and 'status' treat '-r N..' as implicitly '-r N..-1'
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1540.2.6 by Robey Pointer
make 'log' and 'status' treat '-r N..' as implicitly '-r N..-1'
16
17
1624.1.3 by Robert Collins
Convert log to use the new tsort.merge_sort routine.
18
"""Black-box tests for bzr log."""
1540.2.6 by Robey Pointer
make 'log' and 'status' treat '-r N..' as implicitly '-r N..-1'
19
4955.4.11 by Vincent Ladeuil
Give some tests a better focus and simplify them accordingly.
20
from itertools import izip
4325.4.3 by Vincent Ladeuil
More cleanups.
21
import os
22
import re
1540.2.6 by Robey Pointer
make 'log' and 'status' treat '-r N..' as implicitly '-r N..-1'
23
4325.4.3 by Vincent Ladeuil
More cleanups.
24
from bzrlib import (
4955.4.6 by Vincent Ladeuil
Switch to branchbuilder to avoid the cost of test.script.
25
    branchbuilder,
4955.7.3 by Vincent Ladeuil
Check ancestry so we don't output random revisions.
26
    errors,
4955.5.2 by Vincent Ladeuil
Simplify tests.
27
    log,
4325.4.3 by Vincent Ladeuil
More cleanups.
28
    osutils,
29
    tests,
2978.6.1 by Kent Gibson
Use normalize_log to more accurately test blackbox log output.
30
    )
4955.4.5 by Vincent Ladeuil
Start reproducing the problems reported in the bug.
31
from bzrlib.tests import (
32
    script,
33
    test_log,
34
    )
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
35
36
4955.4.17 by Vincent Ladeuil
Use a data factory for commit properties and reduce code duplication.
37
class TestLog(tests.TestCaseWithTransport, test_log.TestLogMixin):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
38
39
    def make_minimal_branch(self, path='.', format=None):
40
        tree = self.make_branch_and_tree(path, format=format)
41
        self.build_tree([path + '/hello.txt'])
42
        tree.add('hello.txt')
43
        tree.commit(message='message1')
44
        return tree
45
46
    def make_linear_branch(self, path='.', format=None):
2809.1.2 by Daniel Watkins
Removed unnecessary check as per abentley's on-list comments.
47
        tree = self.make_branch_and_tree(path, format=format)
2664.14.1 by Daniel Watkins
Fixed tests.blackbox.test_log to use internals where appropriate.
48
        self.build_tree(
49
            [path + '/hello.txt', path + '/goodbye.txt', path + '/meep.txt'])
50
        tree.add('hello.txt')
51
        tree.commit(message='message1')
52
        tree.add('goodbye.txt')
53
        tree.commit(message='message2')
54
        tree.add('meep.txt')
55
        tree.commit(message='message3')
56
        return tree
1553.4.2 by Michael Ellerman
Make bzr log -r .. work, fixes bug #4609. Add a bunch of tests to make sure
57
4369.2.1 by Marius Kruger
add some leftover log tests
58
    def make_merged_branch(self, path='.', format=None):
4369.2.2 by Marius Kruger
use make_linear_branch in make_merged_branch
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()
4369.2.1 by Marius Kruger
add some leftover log tests
62
        tree2.commit(message='tree2 message2')
63
        tree2.commit(message='tree2 message3')
64
        tree.merge_from_branch(tree2.branch)
65
        tree.commit(message='merge')
66
        return tree
67
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
68
4955.5.2 by Vincent Ladeuil
Simplify tests.
69
class TestLogWithLogCatcher(TestLog):
70
71
    def setUp(self):
72
        super(TestLogWithLogCatcher, self).setUp()
4955.4.5 by Vincent Ladeuil
Start reproducing the problems reported in the bug.
73
        # Capture log formatter creations
4955.5.2 by Vincent Ladeuil
Simplify tests.
74
        class MyLogFormatter(test_log.LogCatcher):
75
76
            def __new__(klass, *args, **kwargs):
4955.4.5 by Vincent Ladeuil
Start reproducing the problems reported in the bug.
77
                self.log_catcher = test_log.LogCatcher(*args, **kwargs)
78
                # Always return our own log formatter
4955.5.2 by Vincent Ladeuil
Simplify tests.
79
                return self.log_catcher
80
81
        def getme(branch):
82
                # Always return our own log formatter class hijacking the
83
                # default behavior (which requires setting up a config
84
                # variable)
85
            return MyLogFormatter
4985.1.5 by Vincent Ladeuil
Deploying the new overrideAttr facility further reduces the complexity
86
        self.overrideAttr(log.log_formatter_registry, 'get_default', getme)
4955.5.2 by Vincent Ladeuil
Simplify tests.
87
4955.4.8 by Vincent Ladeuil
Simplify more tests.
88
    def get_captured_revisions(self):
89
        return self.log_catcher.revisions
90
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()])
95
96
    def assertLogRevnosAndDepths(self, args, expected_revnos_and_depths,
97
                                working_dir='.'):
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()])
4955.5.2 by Vincent Ladeuil
Simplify tests.
102
103
104
class TestLogRevSpecs(TestLogWithLogCatcher):
105
106
    def test_log_no_revspec(self):
107
        self.make_linear_branch()
108
        self.assertLogRevnos([], ['3', '2', '1'])
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
109
1553.4.2 by Michael Ellerman
Make bzr log -r .. work, fixes bug #4609. Add a bunch of tests to make sure
110
    def test_log_null_end_revspec(self):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
111
        self.make_linear_branch()
4955.5.2 by Vincent Ladeuil
Simplify tests.
112
        self.assertLogRevnos(['-r1..'], ['3', '2', '1'])
1553.4.2 by Michael Ellerman
Make bzr log -r .. work, fixes bug #4609. Add a bunch of tests to make sure
113
114
    def test_log_null_begin_revspec(self):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
115
        self.make_linear_branch()
4955.5.2 by Vincent Ladeuil
Simplify tests.
116
        self.assertLogRevnos(['-r..3'], ['3', '2', '1'])
1553.4.2 by Michael Ellerman
Make bzr log -r .. work, fixes bug #4609. Add a bunch of tests to make sure
117
118
    def test_log_null_both_revspecs(self):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
119
        self.make_linear_branch()
4955.5.2 by Vincent Ladeuil
Simplify tests.
120
        self.assertLogRevnos(['-r..'], ['3', '2', '1'])
2978.4.1 by Kent Gibson
Logging revision 0 returns error.
121
1553.4.2 by Michael Ellerman
Make bzr log -r .. work, fixes bug #4609. Add a bunch of tests to make sure
122
    def test_log_negative_begin_revspec_full_log(self):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
123
        self.make_linear_branch()
4955.5.2 by Vincent Ladeuil
Simplify tests.
124
        self.assertLogRevnos(['-r-3..'], ['3', '2', '1'])
1553.4.2 by Michael Ellerman
Make bzr log -r .. work, fixes bug #4609. Add a bunch of tests to make sure
125
126
    def test_log_negative_both_revspec_full_log(self):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
127
        self.make_linear_branch()
4955.5.2 by Vincent Ladeuil
Simplify tests.
128
        self.assertLogRevnos(['-r-3..-1'], ['3', '2', '1'])
1553.4.2 by Michael Ellerman
Make bzr log -r .. work, fixes bug #4609. Add a bunch of tests to make sure
129
130
    def test_log_negative_both_revspec_partial(self):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
131
        self.make_linear_branch()
4955.5.2 by Vincent Ladeuil
Simplify tests.
132
        self.assertLogRevnos(['-r-3..-2'], ['2', '1'])
1553.4.2 by Michael Ellerman
Make bzr log -r .. work, fixes bug #4609. Add a bunch of tests to make sure
133
134
    def test_log_negative_begin_revspec(self):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
135
        self.make_linear_branch()
4955.5.2 by Vincent Ladeuil
Simplify tests.
136
        self.assertLogRevnos(['-r-2..'], ['3', '2'])
1553.4.2 by Michael Ellerman
Make bzr log -r .. work, fixes bug #4609. Add a bunch of tests to make sure
137
2978.4.1 by Kent Gibson
Logging revision 0 returns error.
138
    def test_log_positive_revspecs(self):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
139
        self.make_linear_branch()
4955.5.2 by Vincent Ladeuil
Simplify tests.
140
        self.assertLogRevnos(['-r1..3'], ['3', '2', '1'])
1624.1.3 by Robert Collins
Convert log to use the new tsort.merge_sort routine.
141
4369.2.1 by Marius Kruger
add some leftover log tests
142
    def test_log_dotted_revspecs(self):
143
        self.make_merged_branch()
4955.5.2 by Vincent Ladeuil
Simplify tests.
144
        self.assertLogRevnos(['-n0', '-r1..1.1.1'], ['1.1.1', '1'])
3734.1.1 by Vincent Ladeuil
Fix bug #248427 by adding a --change option to log.
145
4955.5.1 by Vincent Ladeuil
Split some tests to better characterize the classes
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)
4955.5.2 by Vincent Ladeuil
Simplify tests.
151
        self.assertLogRevnos(['--limit', '2'], ['10', '9'])
4955.5.1 by Vincent Ladeuil
Split some tests to better characterize the classes
152
153
    def test_log_limit_short(self):
154
        self.make_linear_branch()
4955.5.2 by Vincent Ladeuil
Simplify tests.
155
        self.assertLogRevnos(['-l', '2'], ['3', '2'])
156
4955.4.7 by Vincent Ladeuil
Some more cleanup.
157
    def test_log_change_revno(self):
158
        self.make_linear_branch()
159
        self.assertLogRevnos(['-c1'], ['1'])
160
4955.4.6 by Vincent Ladeuil
Switch to branchbuilder to avoid the cost of test.script.
161
4955.7.5 by Vincent Ladeuil
Fixed as per Ian's review.
162
class TestLogMergedLinearAncestry(TestLogWithLogCatcher):
4955.4.5 by Vincent Ladeuil
Start reproducing the problems reported in the bug.
163
164
    def setUp(self):
4955.7.5 by Vincent Ladeuil
Fixed as per Ian's review.
165
        super(TestLogMergedLinearAncestry, self).setUp()
4955.4.6 by Vincent Ladeuil
Switch to branchbuilder to avoid the cost of test.script.
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()
170
        # mainline
171
        builder.build_snapshot('1', None, [
172
            ('add', ('', 'root-id', 'directory', ''))])
173
        builder.build_snapshot('2', ['1'], [])
174
        # branch
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()
4955.4.5 by Vincent Ladeuil
Start reproducing the problems reported in the bug.
188
189
    def test_n0(self):
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'])
195
196
    def test_n1(self):
4955.4.6 by Vincent Ladeuil
Switch to branchbuilder to avoid the cost of test.script.
197
        # starting from 1.1.4 we follow the left-hand ancestry
4955.4.5 by Vincent Ladeuil
Start reproducing the problems reported in the bug.
198
        self.assertLogRevnos(['-n1', '-r1.1.1..1.1.4'],
199
                             ['1.1.4', '1.1.3', '1.1.2', '1.1.1'])
200
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'])
204
4955.5.2 by Vincent Ladeuil
Simplify tests.
205
4955.7.5 by Vincent Ladeuil
Fixed as per Ian's review.
206
class Test_GenerateAllRevisions(TestLogWithLogCatcher):
4955.7.3 by Vincent Ladeuil
Check ancestry so we don't output random revisions.
207
5092.1.1 by Vincent Ladeuil
Reproduce bug #519862.
208
    def setUp(self):
209
        super(Test_GenerateAllRevisions, self).setUp()
210
        builder = self.make_branch_with_many_merges()
211
        b = builder.get_branch()
212
        b.lock_read()
213
        self.addCleanup(b.unlock)
214
        self.branch = b
215
4955.7.5 by Vincent Ladeuil
Fixed as per Ian's review.
216
    def make_branch_with_many_merges(self, path='.', format=None):
4955.7.3 by Vincent Ladeuil
Check ancestry so we don't output random revisions.
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()
234
        return builder
235
236
    def test_not_an_ancestor(self):
237
        self.assertRaises(errors.BzrCommandError,
238
                          log._generate_all_revisions,
5092.1.1 by Vincent Ladeuil
Reproduce bug #519862.
239
                          self.branch, '1.1.1', '2.1.3', 'reverse',
4955.7.3 by Vincent Ladeuil
Check ancestry so we don't output random revisions.
240
                          delayed_graph_generation=True)
241
242
    def test_wrong_order(self):
243
        self.assertRaises(errors.BzrCommandError,
244
                          log._generate_all_revisions,
5092.1.1 by Vincent Ladeuil
Reproduce bug #519862.
245
                          self.branch, '5', '2.1.3', 'reverse',
4955.7.3 by Vincent Ladeuil
Check ancestry so we don't output random revisions.
246
                          delayed_graph_generation=True)
247
5092.1.1 by Vincent Ladeuil
Reproduce bug #519862.
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)
252
4955.7.3 by Vincent Ladeuil
Check ancestry so we don't output random revisions.
253
4955.5.2 by Vincent Ladeuil
Simplify tests.
254
class TestLogRevSpecsWithPaths(TestLogWithLogCatcher):
255
256
    def test_log_revno_n_path_wrong_namespace(self):
257
        self.make_linear_branch('branch1')
258
        self.make_linear_branch('branch2')
259
        # There is no guarantee that a path exist between two arbitrary
260
        # revisions.
261
        self.run_bzr("log -r revno:2:branch1..revno:3:branch2", retcode=3)
262
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'],
266
                             ['3', '2','1'])
267
268
    def test_log_revno_n_path(self):
269
        self.make_linear_branch('branch2')
270
        self.assertLogRevnos(['-rrevno:1:branch2'],
271
                             ['1'])
272
        rev_props = self.log_catcher.revisions[0].rev.properties
273
        self.assertEqual('branch2', rev_props['branch-nick'])
4955.5.1 by Vincent Ladeuil
Split some tests to better characterize the classes
274
275
276
class TestLogErrors(TestLog):
277
4955.5.2 by Vincent Ladeuil
Simplify tests.
278
    def test_log_zero_revspec(self):
279
        self.make_minimal_branch()
280
        self.run_bzr_error(['bzr: ERROR: Logging revision 0 is invalid.'],
281
                           ['log', '-r0'])
282
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.'],
286
                           ['log', '-r0..2'])
287
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.'],
291
                           ['log', '-r-2..0'])
292
3878.3.3 by Marius Kruger
Add tests for log -r with non-exising revno's
293
    def test_log_nonexistent_revno(self):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
294
        self.make_minimal_branch()
5105.1.4 by Vincent Ladeuil
Use single quotes so that no test need to be updated.
295
        self.run_bzr_error(["bzr: ERROR: Requested revision: '1234' "
4955.4.7 by Vincent Ladeuil
Some more cleanup.
296
                            "does not exist in branch:"],
297
                           ['log', '-r1234'])
3878.3.3 by Marius Kruger
Add tests for log -r with non-exising revno's
298
299
    def test_log_nonexistent_dotted_revno(self):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
300
        self.make_minimal_branch()
5105.1.4 by Vincent Ladeuil
Use single quotes so that no test need to be updated.
301
        self.run_bzr_error(["bzr: ERROR: Requested revision: '123.123' "
4955.4.7 by Vincent Ladeuil
Some more cleanup.
302
                            "does not exist in branch:"],
303
                           ['log',  '-r123.123'])
3734.1.1 by Vincent Ladeuil
Fix bug #248427 by adding a --change option to log.
304
3878.3.2 by Marius Kruger
Add tests for log -c with non-exising revno's
305
    def test_log_change_nonexistent_revno(self):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
306
        self.make_minimal_branch()
5105.1.4 by Vincent Ladeuil
Use single quotes so that no test need to be updated.
307
        self.run_bzr_error(["bzr: ERROR: Requested revision: '1234' "
4955.4.7 by Vincent Ladeuil
Some more cleanup.
308
                            "does not exist in branch:"],
309
                           ['log',  '-c1234'])
3878.3.2 by Marius Kruger
Add tests for log -c with non-exising revno's
310
311
    def test_log_change_nonexistent_dotted_revno(self):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
312
        self.make_minimal_branch()
5105.1.4 by Vincent Ladeuil
Use single quotes so that no test need to be updated.
313
        self.run_bzr_error(["bzr: ERROR: Requested revision: '123.123' "
4955.4.7 by Vincent Ladeuil
Some more cleanup.
314
                            "does not exist in branch:"],
315
                           ['log', '-c123.123'])
3878.3.2 by Marius Kruger
Add tests for log -c with non-exising revno's
316
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
317
    def test_log_change_single_revno_only(self):
318
        self.make_minimal_branch()
4325.4.6 by Vincent Ladeuil
Fixed as per John's and Markus reviews.
319
        self.run_bzr_error(['bzr: ERROR: Option --change does not'
320
                           ' accept revision ranges'],
3734.1.1 by Vincent Ladeuil
Fix bug #248427 by adding a --change option to log.
321
                           ['log', '--change', '2..3'])
322
323
    def test_log_change_incompatible_with_revision(self):
4325.4.6 by Vincent Ladeuil
Fixed as per John's and Markus reviews.
324
        self.run_bzr_error(['bzr: ERROR: --revision and --change'
325
                           ' are mutually exclusive'],
3734.1.1 by Vincent Ladeuil
Fix bug #248427 by adding a --change option to log.
326
                           ['log', '--change', '2', '--revision', '3'])
327
2100.1.1 by wang
Running ``bzr log`` on nonexistent file gives an error instead of the
328
    def test_log_nonexistent_file(self):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
329
        self.make_minimal_branch()
2100.1.1 by wang
Running ``bzr log`` on nonexistent file gives an error instead of the
330
        # files that don't exist in either the basis tree or working tree
331
        # should give an error
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
332
        out, err = self.run_bzr('log does-not-exist', retcode=3)
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
333
        self.assertContainsRe(err,
334
                              'Path unknown at end or start of revision range: '
335
                              'does-not-exist')
2388.1.11 by Alexander Belchenko
changes after John's review
336
4955.5.2 by Vincent Ladeuil
Simplify tests.
337
    def test_log_reversed_revspecs(self):
338
        self.make_linear_branch()
339
        self.run_bzr_error(('bzr: ERROR: Start revision must be older than '
340
                            'the end revision.\n',),
341
                           ['log', '-r3..1'])
342
343
    def test_log_reversed_dotted_revspecs(self):
344
        self.make_merged_branch()
345
        self.run_bzr_error(('bzr: ERROR: Start revision not found in '
346
                            'left-hand history of end revision.\n',),
347
                           "log -r 1.1.1..1")
348
4955.5.1 by Vincent Ladeuil
Split some tests to better characterize the classes
349
    def test_log_bad_message_re(self):
350
        """Bad --message argument gives a sensible message
351
        
352
        See https://bugs.launchpad.net/bzr/+bug/251352
353
        """
354
        self.make_minimal_branch()
355
        out, err = self.run_bzr(['log', '-m', '*'], retcode=3)
356
        self.assertEqual("bzr: ERROR: Invalid regular expression"
357
            " in log message filter"
358
            ": '*'"
359
            ": nothing to repeat\n", err)
360
        self.assertEqual('', out)
361
4955.4.7 by Vincent Ladeuil
Some more cleanup.
362
    def test_log_unsupported_timezone(self):
363
        self.make_linear_branch()
364
        self.run_bzr_error(['bzr: ERROR: Unsupported timezone format "foo", '
365
                            'options are "utc", "original", "local".'],
366
                           ['log', '--timezone', 'foo'])
4955.5.1 by Vincent Ladeuil
Split some tests to better characterize the classes
367
5097.1.13 by Vincent Ladeuil
Add more tests.
368
    def test_log_exclude_ancestry_no_range(self):
369
        self.make_linear_branch()
370
        self.run_bzr_error(['bzr: ERROR: --exclude-common-ancestry'
371
                            ' requires -r with two revisions'],
372
                           ['log', '--exclude-common-ancestry'])
373
374
    def test_log_exclude_ancestry_single_revision(self):
375
        self.make_merged_branch()
376
        self.run_bzr_error(['bzr: ERROR: --exclude-common-ancestry'
377
                            ' requires two different revisions'],
378
                           ['log', '--exclude-common-ancestry',
379
                            '-r1.1.1..1.1.1'])
4955.5.1 by Vincent Ladeuil
Split some tests to better characterize the classes
380
381
class TestLogTags(TestLog):
382
2388.1.3 by Erik Bagfors
tests for tags in log output
383
    def test_log_with_tags(self):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
384
        tree = self.make_linear_branch(format='dirstate-tags')
2664.14.1 by Daniel Watkins
Fixed tests.blackbox.test_log to use internals where appropriate.
385
        branch = tree.branch
386
        branch.tags.set_tag('tag1', branch.get_rev_id(1))
387
        branch.tags.set_tag('tag1.1', branch.get_rev_id(1))
3842.2.5 by Vincent Ladeuil
Better fix for bug #300055.
388
        branch.tags.set_tag('tag3', branch.last_revision())
389
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
390
        log = self.run_bzr("log -r-1")[0]
2388.1.3 by Erik Bagfors
tests for tags in log output
391
        self.assertTrue('tags: tag3' in log)
392
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
393
        log = self.run_bzr("log -r1")[0]
2388.1.3 by Erik Bagfors
tests for tags in log output
394
        # I guess that we can't know the order of tags in the output
395
        # since dicts are unordered, need to check both possibilities
2388.1.11 by Alexander Belchenko
changes after John's review
396
        self.assertContainsRe(log, r'tags: (tag1, tag1\.1|tag1\.1, tag1)')
397
2388.1.9 by Erik Bagfors
test for merges with tags in log
398
    def test_merged_log_with_tags(self):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
399
        branch1_tree = self.make_linear_branch('branch1',
400
                                               format='dirstate-tags')
2664.14.1 by Daniel Watkins
Fixed tests.blackbox.test_log to use internals where appropriate.
401
        branch1 = branch1_tree.branch
402
        branch2_tree = branch1_tree.bzrdir.sprout('branch2').open_workingtree()
403
        branch1_tree.commit(message='foobar', allow_pointless=True)
404
        branch1.tags.set_tag('tag1', branch1.last_revision())
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
405
        # tags don't propagate if we don't merge
406
        self.run_bzr('merge ../branch1', working_dir='branch2')
2664.14.1 by Daniel Watkins
Fixed tests.blackbox.test_log to use internals where appropriate.
407
        branch2_tree.commit(message='merge branch 1')
4511.3.11 by Marius Kruger
* fix tests again
408
        log = self.run_bzr("log -n0 -r-1", working_dir='branch2')[0]
2388.1.11 by Alexander Belchenko
changes after John's review
409
        self.assertContainsRe(log, r'    tags: tag1')
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
410
        log = self.run_bzr("log -n0 -r3.1.1", working_dir='branch2')[0]
2466.12.2 by Kent Gibson
shift log output with only merge revisions to the left margin
411
        self.assertContainsRe(log, r'tags: tag1')
2388.1.3 by Erik Bagfors
tests for tags in log output
412
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
413
414
class TestLogVerbose(TestLog):
3874.1.8 by Vincent Ladeuil
Fixed as ber Robert's review.
415
416
    def setUp(self):
417
        super(TestLogVerbose, self).setUp()
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
418
        self.make_minimal_branch()
3874.1.8 by Vincent Ladeuil
Fixed as ber Robert's review.
419
420
    def assertUseShortDeltaFormat(self, cmd):
421
        log = self.run_bzr(cmd)[0]
422
        # Check that we use the short status format
3947.1.7 by Ian Clatworthy
tweak indenting/offsetting for --short given dotted revno lengths
423
        self.assertContainsRe(log, '(?m)^\s*A  hello.txt$')
424
        self.assertNotContainsRe(log, '(?m)^\s*added:$')
3874.1.4 by Vincent Ladeuil
Fixed as per Aarons' comment.
425
3874.1.8 by Vincent Ladeuil
Fixed as ber Robert's review.
426
    def assertUseLongDeltaFormat(self, cmd):
427
        log = self.run_bzr(cmd)[0]
428
        # Check that we use the long status format
3947.1.7 by Ian Clatworthy
tweak indenting/offsetting for --short given dotted revno lengths
429
        self.assertNotContainsRe(log, '(?m)^\s*A  hello.txt$')
430
        self.assertContainsRe(log, '(?m)^\s*added:$')
3874.1.8 by Vincent Ladeuil
Fixed as ber Robert's review.
431
432
    def test_log_short_verbose(self):
433
        self.assertUseShortDeltaFormat(['log', '--short', '-v'])
434
3874.1.4 by Vincent Ladeuil
Fixed as per Aarons' comment.
435
    def test_log_short_verbose_verbose(self):
3874.1.8 by Vincent Ladeuil
Fixed as ber Robert's review.
436
        self.assertUseLongDeltaFormat(['log', '--short', '-vv'])
3874.1.4 by Vincent Ladeuil
Fixed as per Aarons' comment.
437
438
    def test_log_long_verbose(self):
3874.1.7 by Vincent Ladeuil
Restrict '-v' change to log --short only.
439
        # Check that we use the long status format, ignoring the verbosity
440
        # level
3874.1.8 by Vincent Ladeuil
Fixed as ber Robert's review.
441
        self.assertUseLongDeltaFormat(['log', '--long', '-v'])
3874.1.4 by Vincent Ladeuil
Fixed as per Aarons' comment.
442
443
    def test_log_long_verbose_verbose(self):
3874.1.7 by Vincent Ladeuil
Restrict '-v' change to log --short only.
444
        # Check that we use the long status format, ignoring the verbosity
445
        # level
3874.1.8 by Vincent Ladeuil
Fixed as ber Robert's review.
446
        self.assertUseLongDeltaFormat(['log', '--long', '-vv'])
3874.1.1 by Vincent Ladeuil
Fix #87179 by using the short status format when the short format is used for log.
447
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
448
4955.4.8 by Vincent Ladeuil
Simplify more tests.
449
class TestLogMerges(TestLogWithLogCatcher):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
450
451
    def setUp(self):
452
        super(TestLogMerges, self).setUp()
453
        self.make_branches_with_merges()
454
455
    def make_branches_with_merges(self):
456
        level0 = self.make_branch_and_tree('level0')
4955.4.17 by Vincent Ladeuil
Use a data factory for commit properties and reduce code duplication.
457
        self.wt_commit(level0, 'in branch level0')
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
458
        level1 = level0.bzrdir.sprout('level1').open_workingtree()
4955.4.17 by Vincent Ladeuil
Use a data factory for commit properties and reduce code duplication.
459
        self.wt_commit(level1, 'in branch level1')
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
460
        level2 = level1.bzrdir.sprout('level2').open_workingtree()
4955.4.17 by Vincent Ladeuil
Use a data factory for commit properties and reduce code duplication.
461
        self.wt_commit(level2, 'in branch level2')
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
462
        level1.merge_from_branch(level2.branch)
4955.4.17 by Vincent Ladeuil
Use a data factory for commit properties and reduce code duplication.
463
        self.wt_commit(level1, 'merge branch level2')
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
464
        level0.merge_from_branch(level1.branch)
4955.4.17 by Vincent Ladeuil
Use a data factory for commit properties and reduce code duplication.
465
        self.wt_commit(level0, 'merge branch level1')
3947.1.3 by Ian Clatworthy
blackbox tests
466
2466.12.1 by Kent Gibson
Fix ``bzr log -r`` to support selecting merge revisions.
467
    def test_merges_are_indented_by_level(self):
4955.4.8 by Vincent Ladeuil
Simplify more tests.
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),
472
                          ('1', 0)],
473
                         [(r.revno, r.merge_depth)
474
                            for r in self.get_captured_revisions()])
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
475
3947.1.3 by Ian Clatworthy
blackbox tests
476
    def test_force_merge_revisions_off(self):
4955.4.8 by Vincent Ladeuil
Simplify more tests.
477
        self.assertLogRevnos(['-n1'], ['2', '1'], working_dir='level0')
3947.1.3 by Ian Clatworthy
blackbox tests
478
479
    def test_force_merge_revisions_on(self):
4955.4.8 by Vincent Ladeuil
Simplify more tests.
480
        self.assertLogRevnos(['-n0'], ['2', '1.1.2', '1.2.1', '1.1.1', '1'],
481
                             working_dir='level0')
3947.1.7 by Ian Clatworthy
tweak indenting/offsetting for --short given dotted revno lengths
482
4221.2.1 by Ian Clatworthy
--include-merges as an alias for --levels 0 in log
483
    def test_include_merges(self):
484
        # Confirm --include-merges gives the same output as -n0
4955.4.8 by Vincent Ladeuil
Simplify more tests.
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')
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
491
        out_im, err_im = self.run_bzr('log --include-merges',
492
                                      working_dir='level0')
493
        out_n0, err_n0 = self.run_bzr('log -n0', working_dir='level0')
494
        self.assertEqual('', err_im)
495
        self.assertEqual('', err_n0)
4221.2.1 by Ian Clatworthy
--include-merges as an alias for --levels 0 in log
496
        self.assertEqual(out_im, out_n0)
497
3947.1.7 by Ian Clatworthy
tweak indenting/offsetting for --short given dotted revno lengths
498
    def test_force_merge_revisions_N(self):
4955.4.8 by Vincent Ladeuil
Simplify more tests.
499
        self.assertLogRevnos(['-n2'],
500
                             ['2', '1.1.2', '1.1.1', '1'],
501
                             working_dir='level0')
3947.1.3 by Ian Clatworthy
blackbox tests
502
2466.12.1 by Kent Gibson
Fix ``bzr log -r`` to support selecting merge revisions.
503
    def test_merges_single_merge_rev(self):
4955.4.8 by Vincent Ladeuil
Simplify more tests.
504
        self.assertLogRevnosAndDepths(['-n0', '-r1.1.2'],
505
                                      [('1.1.2', 0), ('1.2.1', 1)],
506
                                      working_dir='level0')
2466.12.1 by Kent Gibson
Fix ``bzr log -r`` to support selecting merge revisions.
507
508
    def test_merges_partial_range(self):
4955.4.8 by Vincent Ladeuil
Simplify more tests.
509
        self.assertLogRevnosAndDepths(
510
                ['-n0', '-r1.1.1..1.1.2'],
511
                [('1.1.2', 0), ('1.2.1', 1), ('1.1.1', 0)],
512
                working_dir='level0')
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
513
4511.3.1 by Marius Kruger
add test_merges_partial_range_ignore_before_lower_bound
514
    def test_merges_partial_range_ignore_before_lower_bound(self):
4511.3.11 by Marius Kruger
* fix tests again
515
        """Dont show revisions before the lower bound's merged revs"""
4955.4.8 by Vincent Ladeuil
Simplify more tests.
516
        self.assertLogRevnosAndDepths(
517
                ['-n0', '-r1.1.2..2'],
518
                [('2', 0), ('1.1.2', 1), ('1.2.1', 2)],
519
                working_dir='level0')
4511.3.1 by Marius Kruger
add test_merges_partial_range_ignore_before_lower_bound
520
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
521
4955.4.11 by Vincent Ladeuil
Give some tests a better focus and simplify them accordingly.
522
class TestLogDiff(TestLogWithLogCatcher):
523
524
    # FIXME: We need specific tests for each LogFormatter about how the diffs
525
    # are displayed: --long indent them by depth, --short use a fixed
526
    # indent and --line does't display them. -- vila 10019
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
527
528
    def setUp(self):
529
        super(TestLogDiff, self).setUp()
530
        self.make_branch_with_diffs()
531
532
    def make_branch_with_diffs(self):
533
        level0 = self.make_branch_and_tree('level0')
534
        self.build_tree(['level0/file1', 'level0/file2'])
535
        level0.add('file1')
536
        level0.add('file2')
4955.4.17 by Vincent Ladeuil
Use a data factory for commit properties and reduce code duplication.
537
        self.wt_commit(level0, 'in branch level0')
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
538
539
        level1 = level0.bzrdir.sprout('level1').open_workingtree()
540
        self.build_tree_contents([('level1/file2', 'hello\n')])
4955.4.17 by Vincent Ladeuil
Use a data factory for commit properties and reduce code duplication.
541
        self.wt_commit(level1, 'in branch level1')
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
542
        level0.merge_from_branch(level1.branch)
4955.4.17 by Vincent Ladeuil
Use a data factory for commit properties and reduce code duplication.
543
        self.wt_commit(level0, 'merge branch level1')
3943.5.3 by Ian Clatworthy
add tests
544
4955.4.11 by Vincent Ladeuil
Give some tests a better focus and simplify them accordingly.
545
    def _diff_file1_revno1(self):
546
        return """=== added file 'file1'
4325.4.6 by Vincent Ladeuil
Fixed as per John's and Markus reviews.
547
--- file1\t1970-01-01 00:00:00 +0000
4955.4.17 by Vincent Ladeuil
Use a data factory for commit properties and reduce code duplication.
548
+++ file1\t2005-11-22 00:00:00 +0000
3943.5.6 by Ian Clatworthy
feedback from jam's review
549
@@ -0,0 +1,1 @@
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
550
+contents of level0/file1
3943.5.6 by Ian Clatworthy
feedback from jam's review
551
4955.4.11 by Vincent Ladeuil
Give some tests a better focus and simplify them accordingly.
552
"""
553
554
    def _diff_file2_revno2(self):
555
        return """=== modified file 'file2'
4955.4.17 by Vincent Ladeuil
Use a data factory for commit properties and reduce code duplication.
556
--- file2\t2005-11-22 00:00:00 +0000
557
+++ file2\t2005-11-22 00:00:01 +0000
4955.4.11 by Vincent Ladeuil
Give some tests a better focus and simplify them accordingly.
558
@@ -1,1 +1,1 @@
559
-contents of level0/file2
560
+hello
561
562
"""
563
564
    def _diff_file2_revno1_1_1(self):
565
        return """=== modified file 'file2'
4955.4.17 by Vincent Ladeuil
Use a data factory for commit properties and reduce code duplication.
566
--- file2\t2005-11-22 00:00:00 +0000
567
+++ file2\t2005-11-22 00:00:01 +0000
4955.4.11 by Vincent Ladeuil
Give some tests a better focus and simplify them accordingly.
568
@@ -1,1 +1,1 @@
569
-contents of level0/file2
570
+hello
571
572
"""
573
574
    def _diff_file2_revno1(self):
575
        return """=== added file 'file2'
4325.4.6 by Vincent Ladeuil
Fixed as per John's and Markus reviews.
576
--- file2\t1970-01-01 00:00:00 +0000
4955.4.17 by Vincent Ladeuil
Use a data factory for commit properties and reduce code duplication.
577
+++ file2\t2005-11-22 00:00:00 +0000
3943.5.6 by Ian Clatworthy
feedback from jam's review
578
@@ -0,0 +1,1 @@
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
579
+contents of level0/file2
4955.4.11 by Vincent Ladeuil
Give some tests a better focus and simplify them accordingly.
580
581
"""
582
4955.4.13 by Vincent Ladeuil
Remove dead code.
583
    def assertLogRevnosAndDiff(self, args, expected,
4955.4.11 by Vincent Ladeuil
Give some tests a better focus and simplify them accordingly.
584
                            working_dir='.'):
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))
600
601
    def test_log_diff_with_merges(self):
4955.4.13 by Vincent Ladeuil
Remove dead code.
602
        self.assertLogRevnosAndDiff(
603
            ['-n0'],
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')
4955.4.11 by Vincent Ladeuil
Give some tests a better focus and simplify them accordingly.
609
610
611
    def test_log_diff_file1(self):
4955.4.13 by Vincent Ladeuil
Remove dead code.
612
        self.assertLogRevnosAndDiff(['-n0', 'file1'],
613
                                    [('1', 0, self._diff_file1_revno1())],
614
                                    working_dir='level0')
4955.4.11 by Vincent Ladeuil
Give some tests a better focus and simplify them accordingly.
615
616
    def test_log_diff_file2(self):
4955.4.13 by Vincent Ladeuil
Remove dead code.
617
        self.assertLogRevnosAndDiff(['-n1', 'file2'],
618
                                    [('2', 0, self._diff_file2_revno2()),
619
                                     ('1', 0, self._diff_file2_revno1())],
620
                                    working_dir='level0')
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
621
622
623
class TestLogUnicodeDiff(TestLog):
3943.5.4 by Ian Clatworthy
filter diff by file
624
4110.1.1 by Alexander Belchenko
Fixed problem with `log -p` and non-ascii content of files: show_diff should write the diff to exact [stdout] stream.
625
    def test_log_show_diff_non_ascii(self):
626
        # Smoke test for bug #328007 UnicodeDecodeError on 'log -p'
627
        message = u'Message with \xb5'
628
        body = 'Body with \xb5\n'
629
        wt = self.make_branch_and_tree('.')
630
        self.build_tree_contents([('foo', body)])
631
        wt.add('foo')
632
        wt.commit(message=message)
633
        # check that command won't fail with unicode error
634
        # don't care about exact output because we have other tests for this
635
        out,err = self.run_bzr('log -p --long')
636
        self.assertNotEqual('', out)
637
        self.assertEqual('', err)
638
        out,err = self.run_bzr('log -p --short')
639
        self.assertNotEqual('', out)
640
        self.assertEqual('', err)
641
        out,err = self.run_bzr('log -p --line')
642
        self.assertNotEqual('', out)
643
        self.assertEqual('', err)
644
3943.5.3 by Ian Clatworthy
add tests
645
4325.4.3 by Vincent Ladeuil
More cleanups.
646
class TestLogEncodings(tests.TestCaseInTempDir):
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
647
648
    _mu = u'\xb5'
649
    _message = u'Message with \xb5'
650
651
    # Encodings which can encode mu
652
    good_encodings = [
653
        'utf-8',
654
        'latin-1',
655
        'iso-8859-1',
656
        'cp437', # Common windows encoding
4110.1.1 by Alexander Belchenko
Fixed problem with `log -p` and non-ascii content of files: show_diff should write the diff to exact [stdout] stream.
657
        'cp1251', # Russian windows encoding
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
658
        'cp1258', # Common windows encoding
659
    ]
660
    # Encodings which cannot encode mu
661
    bad_encodings = [
662
        'ascii',
663
        'iso-8859-2',
664
        'koi8_r',
665
    ]
666
667
    def setUp(self):
4325.4.3 by Vincent Ladeuil
More cleanups.
668
        super(TestLogEncodings, self).setUp()
4985.1.5 by Vincent Ladeuil
Deploying the new overrideAttr facility further reduces the complexity
669
        self.overrideAttr(osutils, '_cached_user_encoding')
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
670
671
    def create_branch(self):
672
        bzr = self.run_bzr
673
        bzr('init')
4955.4.16 by Vincent Ladeuil
Be windows-friendly and don't left opened files behind.
674
        self.build_tree_contents([('a', 'some stuff\n')])
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
675
        bzr('add a')
676
        bzr(['commit', '-m', self._message])
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
677
678
    def try_encoding(self, encoding, fail=False):
679
        bzr = self.run_bzr
680
        if fail:
681
            self.assertRaises(UnicodeEncodeError,
682
                self._mu.encode, encoding)
683
            encoded_msg = self._message.encode(encoding, 'replace')
684
        else:
685
            encoded_msg = self._message.encode(encoding)
686
3224.5.4 by Andrew Bennetts
Fix test suite, mainly weeding out uses of bzrlib.user_encoding.
687
        old_encoding = osutils._cached_user_encoding
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
688
        # This test requires that 'run_bzr' uses the current
689
        # bzrlib, because we override user_encoding, and expect
690
        # it to be used
691
        try:
3224.5.4 by Andrew Bennetts
Fix test suite, mainly weeding out uses of bzrlib.user_encoding.
692
            osutils._cached_user_encoding = 'ascii'
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
693
            # We should be able to handle any encoding
694
            out, err = bzr('log', encoding=encoding)
695
            if not fail:
696
                # Make sure we wrote mu as we expected it to exist
697
                self.assertNotEqual(-1, out.find(encoded_msg))
698
                out_unicode = out.decode(encoding)
699
                self.assertNotEqual(-1, out_unicode.find(self._message))
700
            else:
701
                self.assertNotEqual(-1, out.find('Message with ?'))
702
        finally:
3224.5.4 by Andrew Bennetts
Fix test suite, mainly weeding out uses of bzrlib.user_encoding.
703
            osutils._cached_user_encoding = old_encoding
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
704
705
    def test_log_handles_encoding(self):
706
        self.create_branch()
707
708
        for encoding in self.good_encodings:
709
            self.try_encoding(encoding)
710
711
    def test_log_handles_bad_encoding(self):
712
        self.create_branch()
713
714
        for encoding in self.bad_encodings:
715
            self.try_encoding(encoding, fail=True)
716
717
    def test_stdout_encoding(self):
718
        bzr = self.run_bzr
3224.5.4 by Andrew Bennetts
Fix test suite, mainly weeding out uses of bzrlib.user_encoding.
719
        osutils._cached_user_encoding = "cp1251"
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
720
721
        bzr('init')
722
        self.build_tree(['a'])
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
723
        bzr('add a')
724
        bzr(['commit', '-m', u'\u0422\u0435\u0441\u0442'])
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
725
        stdout, stderr = self.run_bzr('log', encoding='cp866')
726
727
        message = stdout.splitlines()[-1]
728
729
        # explanation of the check:
730
        # u'\u0422\u0435\u0441\u0442' is word 'Test' in russian
731
        # in cp866  encoding this is string '\x92\xa5\xe1\xe2'
732
        # in cp1251 encoding this is string '\xd2\xe5\xf1\xf2'
733
        # This test should check that output of log command
734
        # encoded to sys.stdout.encoding
735
        test_in_cp866 = '\x92\xa5\xe1\xe2'
736
        test_in_cp1251 = '\xd2\xe5\xf1\xf2'
737
        # Make sure the log string is encoded in cp866
738
        self.assertEquals(test_in_cp866, message[2:])
739
        # Make sure the cp1251 string is not found anywhere
740
        self.assertEquals(-1, stdout.find(test_in_cp1251))
741
1551.10.18 by Aaron Bentley
Log works in local treeless branches (#84247)
742
4955.4.9 by Vincent Ladeuil
More simplifications.
743
class TestLogFile(TestLogWithLogCatcher):
1551.10.18 by Aaron Bentley
Log works in local treeless branches (#84247)
744
745
    def test_log_local_branch_file(self):
746
        """We should be able to log files in local treeless branches"""
747
        tree = self.make_branch_and_tree('tree')
748
        self.build_tree(['tree/file'])
749
        tree.add('file')
750
        tree.commit('revision 1')
751
        tree.bzrdir.destroy_workingtree()
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
752
        self.run_bzr('log tree/file')
2359.1.1 by Kent Gibson
Fix ``bzr log <file>`` so it only logs the revisions that changed the file, and does it faster.
753
3943.6.1 by Ian Clatworthy
find file using the end revision
754
    def prepare_tree(self, complex=False):
3943.6.3 by Ian Clatworthy
search the start tree if the end tree doesn't have a file
755
        # The complex configuration includes deletes and renames
2359.1.1 by Kent Gibson
Fix ``bzr log <file>`` so it only logs the revisions that changed the file, and does it faster.
756
        tree = self.make_branch_and_tree('parent')
757
        self.build_tree(['parent/file1', 'parent/file2', 'parent/file3'])
758
        tree.add('file1')
759
        tree.commit('add file1')
760
        tree.add('file2')
761
        tree.commit('add file2')
762
        tree.add('file3')
763
        tree.commit('add file3')
2664.14.1 by Daniel Watkins
Fixed tests.blackbox.test_log to use internals where appropriate.
764
        child_tree = tree.bzrdir.sprout('child').open_workingtree()
765
        self.build_tree_contents([('child/file2', 'hello')])
766
        child_tree.commit(message='branch 1')
767
        tree.merge_from_branch(child_tree.branch)
768
        tree.commit(message='merge child branch')
3943.6.1 by Ian Clatworthy
find file using the end revision
769
        if complex:
3943.6.3 by Ian Clatworthy
search the start tree if the end tree doesn't have a file
770
            tree.remove('file2')
771
            tree.commit('remove file2')
772
            tree.rename_one('file3', 'file4')
773
            tree.commit('file3 is now called file4')
3943.6.1 by Ian Clatworthy
find file using the end revision
774
            tree.remove('file1')
3943.6.3 by Ian Clatworthy
search the start tree if the end tree doesn't have a file
775
            tree.commit('remove file1')
2359.1.1 by Kent Gibson
Fix ``bzr log <file>`` so it only logs the revisions that changed the file, and does it faster.
776
        os.chdir('parent')
3940.1.2 by Ian Clatworthy
add test
777
4955.4.9 by Vincent Ladeuil
More simplifications.
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):
782
        self.prepare_tree()
783
        self.assertLogRevnos(['-n0', 'file1'], ['1'])
784
785
    def test_log_file2(self):
786
        self.prepare_tree()
787
        # file2 full history
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'])
797
798
    def test_log_file3(self):
799
        self.prepare_tree()
800
        self.assertLogRevnos(['-n0', 'file3'], ['3'])
3940.1.2 by Ian Clatworthy
add test
801
3943.6.4 by Ian Clatworthy
review feedback from vila
802
    def test_log_file_historical_missing(self):
3943.6.3 by Ian Clatworthy
search the start tree if the end tree doesn't have a file
803
        # Check logging a deleted file gives an error if the
804
        # file isn't found at the end or start of the revision range
3943.6.4 by Ian Clatworthy
review feedback from vila
805
        self.prepare_tree(complex=True)
3943.6.3 by Ian Clatworthy
search the start tree if the end tree doesn't have a file
806
        err_msg = "Path unknown at end or start of revision range: file2"
807
        err = self.run_bzr('log file2', retcode=3)[1]
3943.6.1 by Ian Clatworthy
find file using the end revision
808
        self.assertContainsRe(err, err_msg)
809
3943.6.4 by Ian Clatworthy
review feedback from vila
810
    def test_log_file_historical_end(self):
3943.6.3 by Ian Clatworthy
search the start tree if the end tree doesn't have a file
811
        # Check logging a deleted file is ok if the file existed
812
        # at the end the revision range
3943.6.4 by Ian Clatworthy
review feedback from vila
813
        self.prepare_tree(complex=True)
4955.4.9 by Vincent Ladeuil
More simplifications.
814
        self.assertLogRevnos(['-n0', '-r..4', 'file2'], ['4', '3.1.1', '2'])
3943.6.3 by Ian Clatworthy
search the start tree if the end tree doesn't have a file
815
3943.6.4 by Ian Clatworthy
review feedback from vila
816
    def test_log_file_historical_start(self):
3943.6.3 by Ian Clatworthy
search the start tree if the end tree doesn't have a file
817
        # Check logging a deleted file is ok if the file existed
818
        # at the start of the revision range
3943.6.4 by Ian Clatworthy
review feedback from vila
819
        self.prepare_tree(complex=True)
4955.4.9 by Vincent Ladeuil
More simplifications.
820
        self.assertLogRevnos(['file1'], ['1'])
3943.6.1 by Ian Clatworthy
find file using the end revision
821
822
    def test_log_file_renamed(self):
3943.6.3 by Ian Clatworthy
search the start tree if the end tree doesn't have a file
823
        """File matched against revision range, not current tree."""
3943.6.1 by Ian Clatworthy
find file using the end revision
824
        self.prepare_tree(complex=True)
3943.6.3 by Ian Clatworthy
search the start tree if the end tree doesn't have a file
825
3943.6.1 by Ian Clatworthy
find file using the end revision
826
        # Check logging a renamed file gives an error by default
3943.6.3 by Ian Clatworthy
search the start tree if the end tree doesn't have a file
827
        err_msg = "Path unknown at end or start of revision range: file3"
3943.6.1 by Ian Clatworthy
find file using the end revision
828
        err = self.run_bzr('log file3', retcode=3)[1]
829
        self.assertContainsRe(err, err_msg)
830
831
        # Check we can see a renamed file if we give the right end revision
4955.4.9 by Vincent Ladeuil
More simplifications.
832
        self.assertLogRevnos(['-r..4', 'file3'], ['3'])
4202.2.1 by Ian Clatworthy
get directory logging working again
833
834
4955.4.10 by Vincent Ladeuil
More simplification.
835
class TestLogMultiple(TestLogWithLogCatcher):
4202.2.1 by Ian Clatworthy
get directory logging working again
836
837
    def prepare_tree(self):
838
        tree = self.make_branch_and_tree('parent')
839
        self.build_tree([
840
            'parent/file1',
841
            'parent/file2',
842
            'parent/dir1/',
843
            'parent/dir1/file5',
844
            'parent/dir1/dir2/',
845
            'parent/dir1/dir2/file3',
846
            'parent/file4'])
847
        tree.add('file1')
4202.2.2 by Ian Clatworthy
improve signal-to-noise ratio in tests
848
        tree.commit('add file1')
4202.2.1 by Ian Clatworthy
get directory logging working again
849
        tree.add('file2')
4202.2.2 by Ian Clatworthy
improve signal-to-noise ratio in tests
850
        tree.commit('add file2')
4202.2.1 by Ian Clatworthy
get directory logging working again
851
        tree.add(['dir1', 'dir1/dir2', 'dir1/dir2/file3'])
4202.2.2 by Ian Clatworthy
improve signal-to-noise ratio in tests
852
        tree.commit('add file3')
4202.2.1 by Ian Clatworthy
get directory logging working again
853
        tree.add('file4')
4202.2.2 by Ian Clatworthy
improve signal-to-noise ratio in tests
854
        tree.commit('add file4')
4202.2.1 by Ian Clatworthy
get directory logging working again
855
        tree.add('dir1/file5')
4202.2.2 by Ian Clatworthy
improve signal-to-noise ratio in tests
856
        tree.commit('add file5')
4202.2.1 by Ian Clatworthy
get directory logging working again
857
        child_tree = tree.bzrdir.sprout('child').open_workingtree()
858
        self.build_tree_contents([('child/file2', 'hello')])
4202.2.2 by Ian Clatworthy
improve signal-to-noise ratio in tests
859
        child_tree.commit(message='branch 1')
4202.2.1 by Ian Clatworthy
get directory logging working again
860
        tree.merge_from_branch(child_tree.branch)
4202.2.2 by Ian Clatworthy
improve signal-to-noise ratio in tests
861
        tree.commit(message='merge child branch')
4202.2.1 by Ian Clatworthy
get directory logging working again
862
        os.chdir('parent')
863
864
    def test_log_files(self):
865
        """The log for multiple file should only list revs for those files"""
866
        self.prepare_tree()
4955.4.10 by Vincent Ladeuil
More simplification.
867
        self.assertLogRevnos(['file1', 'file2', 'dir1/dir2/file3'],
868
                             ['6', '5.1.1', '3', '2', '1'])
4202.2.1 by Ian Clatworthy
get directory logging working again
869
870
    def test_log_directory(self):
871
        """The log for a directory should show all nested files."""
872
        self.prepare_tree()
4955.4.10 by Vincent Ladeuil
More simplification.
873
        self.assertLogRevnos(['dir1'], ['5', '3'])
4202.2.1 by Ian Clatworthy
get directory logging working again
874
875
    def test_log_nested_directory(self):
876
        """The log for a directory should show all nested files."""
877
        self.prepare_tree()
4955.4.10 by Vincent Ladeuil
More simplification.
878
        self.assertLogRevnos(['dir1/dir2'], ['3'])
4202.2.1 by Ian Clatworthy
get directory logging working again
879
880
    def test_log_in_nested_directory(self):
881
        """The log for a directory should show all nested files."""
882
        self.prepare_tree()
883
        os.chdir("dir1")
4955.4.10 by Vincent Ladeuil
More simplification.
884
        self.assertLogRevnos(['.'], ['5', '3'])
4202.2.1 by Ian Clatworthy
get directory logging working again
885
886
    def test_log_files_and_directories(self):
887
        """Logging files and directories together should be fine."""
888
        self.prepare_tree()
4955.4.10 by Vincent Ladeuil
More simplification.
889
        self.assertLogRevnos(['file4', 'dir1/dir2'], ['4', '3'])
4202.2.1 by Ian Clatworthy
get directory logging working again
890
891
    def test_log_files_and_dirs_in_nested_directory(self):
892
        """The log for a directory should show all nested files."""
893
        self.prepare_tree()
894
        os.chdir("dir1")
4955.4.10 by Vincent Ladeuil
More simplification.
895
        self.assertLogRevnos(['dir2', 'file5'], ['5', '3'])