/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
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
5268.4.1 by Vincent Ladeuil
Failing test for bug #575631.
162
class TestLogExcludeCommonAncestry(TestLogWithLogCatcher):
163
164
    def test_exclude_common_ancestry_simple_revnos(self):
165
        self.make_linear_branch()
166
        self.assertLogRevnos(['-r1..3', '--exclude-common-ancestry'],
167
                             ['3', '2'])
168
169
4955.7.5 by Vincent Ladeuil
Fixed as per Ian's review.
170
class TestLogMergedLinearAncestry(TestLogWithLogCatcher):
4955.4.5 by Vincent Ladeuil
Start reproducing the problems reported in the bug.
171
172
    def setUp(self):
4955.7.5 by Vincent Ladeuil
Fixed as per Ian's review.
173
        super(TestLogMergedLinearAncestry, self).setUp()
4955.4.6 by Vincent Ladeuil
Switch to branchbuilder to avoid the cost of test.script.
174
        # FIXME: Using a MemoryTree would be even better here (but until we
175
        # stop calling run_bzr, there is no point) --vila 100118.
176
        builder = branchbuilder.BranchBuilder(self.get_transport())
177
        builder.start_series()
5268.4.1 by Vincent Ladeuil
Failing test for bug #575631.
178
        # 1
179
        # | \
180
        # 2  1.1.1
181
        # | / |
182
        # 3  1.1.2
183
        # |   |
184
        # |  1.1.3
185
        # | / |
186
        # 4  1.1.4
187
        # | /
188
        # 5
189
4955.4.6 by Vincent Ladeuil
Switch to branchbuilder to avoid the cost of test.script.
190
        # mainline
191
        builder.build_snapshot('1', None, [
192
            ('add', ('', 'root-id', 'directory', ''))])
193
        builder.build_snapshot('2', ['1'], [])
194
        # branch
195
        builder.build_snapshot('1.1.1', ['1'], [])
196
        # merge branch into mainline
197
        builder.build_snapshot('3', ['2', '1.1.1'], [])
198
        # new commits in branch
199
        builder.build_snapshot('1.1.2', ['1.1.1'], [])
200
        builder.build_snapshot('1.1.3', ['1.1.2'], [])
201
        # merge branch into mainline
202
        builder.build_snapshot('4', ['3', '1.1.3'], [])
203
        # merge mainline into branch
204
        builder.build_snapshot('1.1.4', ['1.1.3', '4'], [])
205
        # merge branch into mainline
206
        builder.build_snapshot('5', ['4', '1.1.4'], [])
207
        builder.finish_series()
4955.4.5 by Vincent Ladeuil
Start reproducing the problems reported in the bug.
208
209
    def test_n0(self):
210
        self.assertLogRevnos(['-n0', '-r1.1.1..1.1.4'],
211
                             ['1.1.4', '4', '1.1.3', '1.1.2', '3', '1.1.1'])
212
    def test_n0_forward(self):
213
        self.assertLogRevnos(['-n0', '-r1.1.1..1.1.4', '--forward'],
214
                             ['3', '1.1.1', '4', '1.1.2', '1.1.3', '1.1.4'])
215
216
    def test_n1(self):
4955.4.6 by Vincent Ladeuil
Switch to branchbuilder to avoid the cost of test.script.
217
        # 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.
218
        self.assertLogRevnos(['-n1', '-r1.1.1..1.1.4'],
219
                             ['1.1.4', '1.1.3', '1.1.2', '1.1.1'])
220
221
    def test_n1_forward(self):
222
        self.assertLogRevnos(['-n1', '-r1.1.1..1.1.4', '--forward'],
223
                             ['1.1.1', '1.1.2', '1.1.3', '1.1.4'])
224
4955.5.2 by Vincent Ladeuil
Simplify tests.
225
4955.7.5 by Vincent Ladeuil
Fixed as per Ian's review.
226
class Test_GenerateAllRevisions(TestLogWithLogCatcher):
4955.7.3 by Vincent Ladeuil
Check ancestry so we don't output random revisions.
227
5092.1.1 by Vincent Ladeuil
Reproduce bug #519862.
228
    def setUp(self):
229
        super(Test_GenerateAllRevisions, self).setUp()
230
        builder = self.make_branch_with_many_merges()
231
        b = builder.get_branch()
232
        b.lock_read()
233
        self.addCleanup(b.unlock)
234
        self.branch = b
235
4955.7.5 by Vincent Ladeuil
Fixed as per Ian's review.
236
    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.
237
        builder = branchbuilder.BranchBuilder(self.get_transport())
238
        builder.start_series()
239
        # The graph below may look a bit complicated (and it may be but I've
240
        # banged my head enough on it) but the bug requires at least dotted
241
        # revnos *and* merged revisions below that.
242
        builder.build_snapshot('1', None, [
243
            ('add', ('', 'root-id', 'directory', ''))])
244
        builder.build_snapshot('2', ['1'], [])
245
        builder.build_snapshot('1.1.1', ['1'], [])
246
        builder.build_snapshot('2.1.1', ['2'], [])
247
        builder.build_snapshot('3', ['2', '1.1.1'], [])
248
        builder.build_snapshot('2.1.2', ['2.1.1'], [])
249
        builder.build_snapshot('2.2.1', ['2.1.1'], [])
250
        builder.build_snapshot('2.1.3', ['2.1.2', '2.2.1'], [])
251
        builder.build_snapshot('4', ['3', '2.1.3'], [])
252
        builder.build_snapshot('5', ['4', '2.1.2'], [])
253
        builder.finish_series()
254
        return builder
255
256
    def test_not_an_ancestor(self):
257
        self.assertRaises(errors.BzrCommandError,
258
                          log._generate_all_revisions,
5092.1.1 by Vincent Ladeuil
Reproduce bug #519862.
259
                          self.branch, '1.1.1', '2.1.3', 'reverse',
4955.7.3 by Vincent Ladeuil
Check ancestry so we don't output random revisions.
260
                          delayed_graph_generation=True)
261
262
    def test_wrong_order(self):
263
        self.assertRaises(errors.BzrCommandError,
264
                          log._generate_all_revisions,
5092.1.1 by Vincent Ladeuil
Reproduce bug #519862.
265
                          self.branch, '5', '2.1.3', 'reverse',
4955.7.3 by Vincent Ladeuil
Check ancestry so we don't output random revisions.
266
                          delayed_graph_generation=True)
267
5092.1.1 by Vincent Ladeuil
Reproduce bug #519862.
268
    def test_no_start_rev_id_with_end_rev_id_being_a_merge(self):
269
        revs = log._generate_all_revisions(
270
            self.branch, None, '2.1.3',
271
            'reverse', delayed_graph_generation=True)
272
4955.7.3 by Vincent Ladeuil
Check ancestry so we don't output random revisions.
273
4955.5.2 by Vincent Ladeuil
Simplify tests.
274
class TestLogRevSpecsWithPaths(TestLogWithLogCatcher):
275
276
    def test_log_revno_n_path_wrong_namespace(self):
277
        self.make_linear_branch('branch1')
278
        self.make_linear_branch('branch2')
279
        # There is no guarantee that a path exist between two arbitrary
280
        # revisions.
281
        self.run_bzr("log -r revno:2:branch1..revno:3:branch2", retcode=3)
282
283
    def test_log_revno_n_path_correct_order(self):
284
        self.make_linear_branch('branch2')
285
        self.assertLogRevnos(['-rrevno:1:branch2..revno:3:branch2'],
286
                             ['3', '2','1'])
287
288
    def test_log_revno_n_path(self):
289
        self.make_linear_branch('branch2')
290
        self.assertLogRevnos(['-rrevno:1:branch2'],
291
                             ['1'])
292
        rev_props = self.log_catcher.revisions[0].rev.properties
293
        self.assertEqual('branch2', rev_props['branch-nick'])
4955.5.1 by Vincent Ladeuil
Split some tests to better characterize the classes
294
295
296
class TestLogErrors(TestLog):
297
4955.5.2 by Vincent Ladeuil
Simplify tests.
298
    def test_log_zero_revspec(self):
299
        self.make_minimal_branch()
300
        self.run_bzr_error(['bzr: ERROR: Logging revision 0 is invalid.'],
301
                           ['log', '-r0'])
302
303
    def test_log_zero_begin_revspec(self):
304
        self.make_linear_branch()
305
        self.run_bzr_error(['bzr: ERROR: Logging revision 0 is invalid.'],
306
                           ['log', '-r0..2'])
307
308
    def test_log_zero_end_revspec(self):
309
        self.make_linear_branch()
310
        self.run_bzr_error(['bzr: ERROR: Logging revision 0 is invalid.'],
311
                           ['log', '-r-2..0'])
312
3878.3.3 by Marius Kruger
Add tests for log -r with non-exising revno's
313
    def test_log_nonexistent_revno(self):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
314
        self.make_minimal_branch()
5105.1.4 by Vincent Ladeuil
Use single quotes so that no test need to be updated.
315
        self.run_bzr_error(["bzr: ERROR: Requested revision: '1234' "
4955.4.7 by Vincent Ladeuil
Some more cleanup.
316
                            "does not exist in branch:"],
317
                           ['log', '-r1234'])
3878.3.3 by Marius Kruger
Add tests for log -r with non-exising revno's
318
319
    def test_log_nonexistent_dotted_revno(self):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
320
        self.make_minimal_branch()
5105.1.4 by Vincent Ladeuil
Use single quotes so that no test need to be updated.
321
        self.run_bzr_error(["bzr: ERROR: Requested revision: '123.123' "
4955.4.7 by Vincent Ladeuil
Some more cleanup.
322
                            "does not exist in branch:"],
323
                           ['log',  '-r123.123'])
3734.1.1 by Vincent Ladeuil
Fix bug #248427 by adding a --change option to log.
324
3878.3.2 by Marius Kruger
Add tests for log -c with non-exising revno's
325
    def test_log_change_nonexistent_revno(self):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
326
        self.make_minimal_branch()
5105.1.4 by Vincent Ladeuil
Use single quotes so that no test need to be updated.
327
        self.run_bzr_error(["bzr: ERROR: Requested revision: '1234' "
4955.4.7 by Vincent Ladeuil
Some more cleanup.
328
                            "does not exist in branch:"],
329
                           ['log',  '-c1234'])
3878.3.2 by Marius Kruger
Add tests for log -c with non-exising revno's
330
331
    def test_log_change_nonexistent_dotted_revno(self):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
332
        self.make_minimal_branch()
5105.1.4 by Vincent Ladeuil
Use single quotes so that no test need to be updated.
333
        self.run_bzr_error(["bzr: ERROR: Requested revision: '123.123' "
4955.4.7 by Vincent Ladeuil
Some more cleanup.
334
                            "does not exist in branch:"],
335
                           ['log', '-c123.123'])
3878.3.2 by Marius Kruger
Add tests for log -c with non-exising revno's
336
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
337
    def test_log_change_single_revno_only(self):
338
        self.make_minimal_branch()
4325.4.6 by Vincent Ladeuil
Fixed as per John's and Markus reviews.
339
        self.run_bzr_error(['bzr: ERROR: Option --change does not'
340
                           ' accept revision ranges'],
3734.1.1 by Vincent Ladeuil
Fix bug #248427 by adding a --change option to log.
341
                           ['log', '--change', '2..3'])
342
343
    def test_log_change_incompatible_with_revision(self):
4325.4.6 by Vincent Ladeuil
Fixed as per John's and Markus reviews.
344
        self.run_bzr_error(['bzr: ERROR: --revision and --change'
345
                           ' are mutually exclusive'],
3734.1.1 by Vincent Ladeuil
Fix bug #248427 by adding a --change option to log.
346
                           ['log', '--change', '2', '--revision', '3'])
347
2100.1.1 by wang
Running ``bzr log`` on nonexistent file gives an error instead of the
348
    def test_log_nonexistent_file(self):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
349
        self.make_minimal_branch()
2100.1.1 by wang
Running ``bzr log`` on nonexistent file gives an error instead of the
350
        # files that don't exist in either the basis tree or working tree
351
        # should give an error
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
352
        out, err = self.run_bzr('log does-not-exist', retcode=3)
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
353
        self.assertContainsRe(err,
354
                              'Path unknown at end or start of revision range: '
355
                              'does-not-exist')
2388.1.11 by Alexander Belchenko
changes after John's review
356
4955.5.2 by Vincent Ladeuil
Simplify tests.
357
    def test_log_reversed_revspecs(self):
358
        self.make_linear_branch()
359
        self.run_bzr_error(('bzr: ERROR: Start revision must be older than '
360
                            'the end revision.\n',),
361
                           ['log', '-r3..1'])
362
363
    def test_log_reversed_dotted_revspecs(self):
364
        self.make_merged_branch()
365
        self.run_bzr_error(('bzr: ERROR: Start revision not found in '
366
                            'left-hand history of end revision.\n',),
367
                           "log -r 1.1.1..1")
368
4955.5.1 by Vincent Ladeuil
Split some tests to better characterize the classes
369
    def test_log_bad_message_re(self):
370
        """Bad --message argument gives a sensible message
371
        
372
        See https://bugs.launchpad.net/bzr/+bug/251352
373
        """
374
        self.make_minimal_branch()
375
        out, err = self.run_bzr(['log', '-m', '*'], retcode=3)
376
        self.assertEqual("bzr: ERROR: Invalid regular expression"
377
            " in log message filter"
378
            ": '*'"
379
            ": nothing to repeat\n", err)
380
        self.assertEqual('', out)
381
4955.4.7 by Vincent Ladeuil
Some more cleanup.
382
    def test_log_unsupported_timezone(self):
383
        self.make_linear_branch()
384
        self.run_bzr_error(['bzr: ERROR: Unsupported timezone format "foo", '
385
                            'options are "utc", "original", "local".'],
386
                           ['log', '--timezone', 'foo'])
4955.5.1 by Vincent Ladeuil
Split some tests to better characterize the classes
387
5097.1.13 by Vincent Ladeuil
Add more tests.
388
    def test_log_exclude_ancestry_no_range(self):
389
        self.make_linear_branch()
390
        self.run_bzr_error(['bzr: ERROR: --exclude-common-ancestry'
391
                            ' requires -r with two revisions'],
392
                           ['log', '--exclude-common-ancestry'])
393
394
    def test_log_exclude_ancestry_single_revision(self):
395
        self.make_merged_branch()
396
        self.run_bzr_error(['bzr: ERROR: --exclude-common-ancestry'
397
                            ' requires two different revisions'],
398
                           ['log', '--exclude-common-ancestry',
399
                            '-r1.1.1..1.1.1'])
4955.5.1 by Vincent Ladeuil
Split some tests to better characterize the classes
400
401
class TestLogTags(TestLog):
402
2388.1.3 by Erik Bagfors
tests for tags in log output
403
    def test_log_with_tags(self):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
404
        tree = self.make_linear_branch(format='dirstate-tags')
2664.14.1 by Daniel Watkins
Fixed tests.blackbox.test_log to use internals where appropriate.
405
        branch = tree.branch
406
        branch.tags.set_tag('tag1', branch.get_rev_id(1))
407
        branch.tags.set_tag('tag1.1', branch.get_rev_id(1))
3842.2.5 by Vincent Ladeuil
Better fix for bug #300055.
408
        branch.tags.set_tag('tag3', branch.last_revision())
409
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
410
        log = self.run_bzr("log -r-1")[0]
2388.1.3 by Erik Bagfors
tests for tags in log output
411
        self.assertTrue('tags: tag3' in log)
412
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
413
        log = self.run_bzr("log -r1")[0]
2388.1.3 by Erik Bagfors
tests for tags in log output
414
        # I guess that we can't know the order of tags in the output
415
        # since dicts are unordered, need to check both possibilities
2388.1.11 by Alexander Belchenko
changes after John's review
416
        self.assertContainsRe(log, r'tags: (tag1, tag1\.1|tag1\.1, tag1)')
417
2388.1.9 by Erik Bagfors
test for merges with tags in log
418
    def test_merged_log_with_tags(self):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
419
        branch1_tree = self.make_linear_branch('branch1',
420
                                               format='dirstate-tags')
2664.14.1 by Daniel Watkins
Fixed tests.blackbox.test_log to use internals where appropriate.
421
        branch1 = branch1_tree.branch
422
        branch2_tree = branch1_tree.bzrdir.sprout('branch2').open_workingtree()
423
        branch1_tree.commit(message='foobar', allow_pointless=True)
424
        branch1.tags.set_tag('tag1', branch1.last_revision())
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
425
        # tags don't propagate if we don't merge
426
        self.run_bzr('merge ../branch1', working_dir='branch2')
2664.14.1 by Daniel Watkins
Fixed tests.blackbox.test_log to use internals where appropriate.
427
        branch2_tree.commit(message='merge branch 1')
4511.3.11 by Marius Kruger
* fix tests again
428
        log = self.run_bzr("log -n0 -r-1", working_dir='branch2')[0]
2388.1.11 by Alexander Belchenko
changes after John's review
429
        self.assertContainsRe(log, r'    tags: tag1')
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
430
        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
431
        self.assertContainsRe(log, r'tags: tag1')
2388.1.3 by Erik Bagfors
tests for tags in log output
432
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
433
434
class TestLogVerbose(TestLog):
3874.1.8 by Vincent Ladeuil
Fixed as ber Robert's review.
435
436
    def setUp(self):
437
        super(TestLogVerbose, self).setUp()
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
438
        self.make_minimal_branch()
3874.1.8 by Vincent Ladeuil
Fixed as ber Robert's review.
439
440
    def assertUseShortDeltaFormat(self, cmd):
441
        log = self.run_bzr(cmd)[0]
442
        # Check that we use the short status format
3947.1.7 by Ian Clatworthy
tweak indenting/offsetting for --short given dotted revno lengths
443
        self.assertContainsRe(log, '(?m)^\s*A  hello.txt$')
444
        self.assertNotContainsRe(log, '(?m)^\s*added:$')
3874.1.4 by Vincent Ladeuil
Fixed as per Aarons' comment.
445
3874.1.8 by Vincent Ladeuil
Fixed as ber Robert's review.
446
    def assertUseLongDeltaFormat(self, cmd):
447
        log = self.run_bzr(cmd)[0]
448
        # Check that we use the long status format
3947.1.7 by Ian Clatworthy
tweak indenting/offsetting for --short given dotted revno lengths
449
        self.assertNotContainsRe(log, '(?m)^\s*A  hello.txt$')
450
        self.assertContainsRe(log, '(?m)^\s*added:$')
3874.1.8 by Vincent Ladeuil
Fixed as ber Robert's review.
451
452
    def test_log_short_verbose(self):
453
        self.assertUseShortDeltaFormat(['log', '--short', '-v'])
454
3874.1.4 by Vincent Ladeuil
Fixed as per Aarons' comment.
455
    def test_log_short_verbose_verbose(self):
3874.1.8 by Vincent Ladeuil
Fixed as ber Robert's review.
456
        self.assertUseLongDeltaFormat(['log', '--short', '-vv'])
3874.1.4 by Vincent Ladeuil
Fixed as per Aarons' comment.
457
458
    def test_log_long_verbose(self):
3874.1.7 by Vincent Ladeuil
Restrict '-v' change to log --short only.
459
        # Check that we use the long status format, ignoring the verbosity
460
        # level
3874.1.8 by Vincent Ladeuil
Fixed as ber Robert's review.
461
        self.assertUseLongDeltaFormat(['log', '--long', '-v'])
3874.1.4 by Vincent Ladeuil
Fixed as per Aarons' comment.
462
463
    def test_log_long_verbose_verbose(self):
3874.1.7 by Vincent Ladeuil
Restrict '-v' change to log --short only.
464
        # Check that we use the long status format, ignoring the verbosity
465
        # level
3874.1.8 by Vincent Ladeuil
Fixed as ber Robert's review.
466
        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.
467
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
468
4955.4.8 by Vincent Ladeuil
Simplify more tests.
469
class TestLogMerges(TestLogWithLogCatcher):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
470
471
    def setUp(self):
472
        super(TestLogMerges, self).setUp()
473
        self.make_branches_with_merges()
474
475
    def make_branches_with_merges(self):
476
        level0 = self.make_branch_and_tree('level0')
4955.4.17 by Vincent Ladeuil
Use a data factory for commit properties and reduce code duplication.
477
        self.wt_commit(level0, 'in branch level0')
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
478
        level1 = level0.bzrdir.sprout('level1').open_workingtree()
4955.4.17 by Vincent Ladeuil
Use a data factory for commit properties and reduce code duplication.
479
        self.wt_commit(level1, 'in branch level1')
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
480
        level2 = level1.bzrdir.sprout('level2').open_workingtree()
4955.4.17 by Vincent Ladeuil
Use a data factory for commit properties and reduce code duplication.
481
        self.wt_commit(level2, 'in branch level2')
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
482
        level1.merge_from_branch(level2.branch)
4955.4.17 by Vincent Ladeuil
Use a data factory for commit properties and reduce code duplication.
483
        self.wt_commit(level1, 'merge branch level2')
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
484
        level0.merge_from_branch(level1.branch)
4955.4.17 by Vincent Ladeuil
Use a data factory for commit properties and reduce code duplication.
485
        self.wt_commit(level0, 'merge branch level1')
3947.1.3 by Ian Clatworthy
blackbox tests
486
2466.12.1 by Kent Gibson
Fix ``bzr log -r`` to support selecting merge revisions.
487
    def test_merges_are_indented_by_level(self):
4955.4.8 by Vincent Ladeuil
Simplify more tests.
488
        self.run_bzr(['log', '-n0'], working_dir='level0')
489
        revnos_and_depth = [(r.revno, r.merge_depth)
490
                            for r in self.get_captured_revisions()]
491
        self.assertEqual([('2', 0), ('1.1.2', 1), ('1.2.1', 2), ('1.1.1', 1),
492
                          ('1', 0)],
493
                         [(r.revno, r.merge_depth)
494
                            for r in self.get_captured_revisions()])
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
495
3947.1.3 by Ian Clatworthy
blackbox tests
496
    def test_force_merge_revisions_off(self):
4955.4.8 by Vincent Ladeuil
Simplify more tests.
497
        self.assertLogRevnos(['-n1'], ['2', '1'], working_dir='level0')
3947.1.3 by Ian Clatworthy
blackbox tests
498
499
    def test_force_merge_revisions_on(self):
4955.4.8 by Vincent Ladeuil
Simplify more tests.
500
        self.assertLogRevnos(['-n0'], ['2', '1.1.2', '1.2.1', '1.1.1', '1'],
501
                             working_dir='level0')
3947.1.7 by Ian Clatworthy
tweak indenting/offsetting for --short given dotted revno lengths
502
4221.2.1 by Ian Clatworthy
--include-merges as an alias for --levels 0 in log
503
    def test_include_merges(self):
504
        # Confirm --include-merges gives the same output as -n0
4955.4.8 by Vincent Ladeuil
Simplify more tests.
505
        self.assertLogRevnos(['--include-merges'],
506
                             ['2', '1.1.2', '1.2.1', '1.1.1', '1'],
507
                             working_dir='level0')
508
        self.assertLogRevnos(['--include-merges'],
509
                             ['2', '1.1.2', '1.2.1', '1.1.1', '1'],
510
                             working_dir='level0')
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
511
        out_im, err_im = self.run_bzr('log --include-merges',
512
                                      working_dir='level0')
513
        out_n0, err_n0 = self.run_bzr('log -n0', working_dir='level0')
514
        self.assertEqual('', err_im)
515
        self.assertEqual('', err_n0)
4221.2.1 by Ian Clatworthy
--include-merges as an alias for --levels 0 in log
516
        self.assertEqual(out_im, out_n0)
517
3947.1.7 by Ian Clatworthy
tweak indenting/offsetting for --short given dotted revno lengths
518
    def test_force_merge_revisions_N(self):
4955.4.8 by Vincent Ladeuil
Simplify more tests.
519
        self.assertLogRevnos(['-n2'],
520
                             ['2', '1.1.2', '1.1.1', '1'],
521
                             working_dir='level0')
3947.1.3 by Ian Clatworthy
blackbox tests
522
2466.12.1 by Kent Gibson
Fix ``bzr log -r`` to support selecting merge revisions.
523
    def test_merges_single_merge_rev(self):
4955.4.8 by Vincent Ladeuil
Simplify more tests.
524
        self.assertLogRevnosAndDepths(['-n0', '-r1.1.2'],
525
                                      [('1.1.2', 0), ('1.2.1', 1)],
526
                                      working_dir='level0')
2466.12.1 by Kent Gibson
Fix ``bzr log -r`` to support selecting merge revisions.
527
528
    def test_merges_partial_range(self):
4955.4.8 by Vincent Ladeuil
Simplify more tests.
529
        self.assertLogRevnosAndDepths(
530
                ['-n0', '-r1.1.1..1.1.2'],
531
                [('1.1.2', 0), ('1.2.1', 1), ('1.1.1', 0)],
532
                working_dir='level0')
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
533
4511.3.1 by Marius Kruger
add test_merges_partial_range_ignore_before_lower_bound
534
    def test_merges_partial_range_ignore_before_lower_bound(self):
4511.3.11 by Marius Kruger
* fix tests again
535
        """Dont show revisions before the lower bound's merged revs"""
4955.4.8 by Vincent Ladeuil
Simplify more tests.
536
        self.assertLogRevnosAndDepths(
537
                ['-n0', '-r1.1.2..2'],
538
                [('2', 0), ('1.1.2', 1), ('1.2.1', 2)],
539
                working_dir='level0')
4511.3.1 by Marius Kruger
add test_merges_partial_range_ignore_before_lower_bound
540
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
541
4955.4.11 by Vincent Ladeuil
Give some tests a better focus and simplify them accordingly.
542
class TestLogDiff(TestLogWithLogCatcher):
543
544
    # FIXME: We need specific tests for each LogFormatter about how the diffs
545
    # are displayed: --long indent them by depth, --short use a fixed
546
    # indent and --line does't display them. -- vila 10019
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
547
548
    def setUp(self):
549
        super(TestLogDiff, self).setUp()
550
        self.make_branch_with_diffs()
551
552
    def make_branch_with_diffs(self):
553
        level0 = self.make_branch_and_tree('level0')
554
        self.build_tree(['level0/file1', 'level0/file2'])
555
        level0.add('file1')
556
        level0.add('file2')
4955.4.17 by Vincent Ladeuil
Use a data factory for commit properties and reduce code duplication.
557
        self.wt_commit(level0, 'in branch level0')
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
558
559
        level1 = level0.bzrdir.sprout('level1').open_workingtree()
560
        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.
561
        self.wt_commit(level1, 'in branch level1')
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
562
        level0.merge_from_branch(level1.branch)
4955.4.17 by Vincent Ladeuil
Use a data factory for commit properties and reduce code duplication.
563
        self.wt_commit(level0, 'merge branch level1')
3943.5.3 by Ian Clatworthy
add tests
564
4955.4.11 by Vincent Ladeuil
Give some tests a better focus and simplify them accordingly.
565
    def _diff_file1_revno1(self):
566
        return """=== added file 'file1'
4325.4.6 by Vincent Ladeuil
Fixed as per John's and Markus reviews.
567
--- 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.
568
+++ file1\t2005-11-22 00:00:00 +0000
3943.5.6 by Ian Clatworthy
feedback from jam's review
569
@@ -0,0 +1,1 @@
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
570
+contents of level0/file1
3943.5.6 by Ian Clatworthy
feedback from jam's review
571
4955.4.11 by Vincent Ladeuil
Give some tests a better focus and simplify them accordingly.
572
"""
573
574
    def _diff_file2_revno2(self):
575
        return """=== modified file 'file2'
4955.4.17 by Vincent Ladeuil
Use a data factory for commit properties and reduce code duplication.
576
--- file2\t2005-11-22 00:00:00 +0000
577
+++ file2\t2005-11-22 00:00:01 +0000
4955.4.11 by Vincent Ladeuil
Give some tests a better focus and simplify them accordingly.
578
@@ -1,1 +1,1 @@
579
-contents of level0/file2
580
+hello
581
582
"""
583
584
    def _diff_file2_revno1_1_1(self):
585
        return """=== modified file 'file2'
4955.4.17 by Vincent Ladeuil
Use a data factory for commit properties and reduce code duplication.
586
--- file2\t2005-11-22 00:00:00 +0000
587
+++ file2\t2005-11-22 00:00:01 +0000
4955.4.11 by Vincent Ladeuil
Give some tests a better focus and simplify them accordingly.
588
@@ -1,1 +1,1 @@
589
-contents of level0/file2
590
+hello
591
592
"""
593
594
    def _diff_file2_revno1(self):
595
        return """=== added file 'file2'
4325.4.6 by Vincent Ladeuil
Fixed as per John's and Markus reviews.
596
--- 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.
597
+++ file2\t2005-11-22 00:00:00 +0000
3943.5.6 by Ian Clatworthy
feedback from jam's review
598
@@ -0,0 +1,1 @@
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
599
+contents of level0/file2
4955.4.11 by Vincent Ladeuil
Give some tests a better focus and simplify them accordingly.
600
601
"""
602
4955.4.13 by Vincent Ladeuil
Remove dead code.
603
    def assertLogRevnosAndDiff(self, args, expected,
4955.4.11 by Vincent Ladeuil
Give some tests a better focus and simplify them accordingly.
604
                            working_dir='.'):
605
        self.run_bzr(['log', '-p'] + args, working_dir=working_dir)
606
        expected_revnos_and_depths = [
607
            (revno, depth) for revno, depth, diff in expected]
608
        # Check the revnos and depths first to make debugging easier
609
        self.assertEqual(expected_revnos_and_depths,
610
                         [(r.revno, r.merge_depth)
611
                           for r in self.get_captured_revisions()])
612
        # Now check the diffs, adding the revno  in case of failure
613
        fmt = 'In revno %s\n%s'
614
        for expected_rev, actual_rev in izip(expected,
615
                                             self.get_captured_revisions()):
616
            revno, depth, expected_diff = expected_rev
617
            actual_diff = actual_rev.diff
618
            self.assertEqualDiff(fmt % (revno, expected_diff),
619
                                 fmt % (revno, actual_diff))
620
621
    def test_log_diff_with_merges(self):
4955.4.13 by Vincent Ladeuil
Remove dead code.
622
        self.assertLogRevnosAndDiff(
623
            ['-n0'],
624
            [('2', 0, self._diff_file2_revno2()),
625
             ('1.1.1', 1, self._diff_file2_revno1_1_1()),
626
             ('1', 0, self._diff_file1_revno1()
627
              + self._diff_file2_revno1())],
628
            working_dir='level0')
4955.4.11 by Vincent Ladeuil
Give some tests a better focus and simplify them accordingly.
629
630
631
    def test_log_diff_file1(self):
4955.4.13 by Vincent Ladeuil
Remove dead code.
632
        self.assertLogRevnosAndDiff(['-n0', 'file1'],
633
                                    [('1', 0, self._diff_file1_revno1())],
634
                                    working_dir='level0')
4955.4.11 by Vincent Ladeuil
Give some tests a better focus and simplify them accordingly.
635
636
    def test_log_diff_file2(self):
4955.4.13 by Vincent Ladeuil
Remove dead code.
637
        self.assertLogRevnosAndDiff(['-n1', 'file2'],
638
                                    [('2', 0, self._diff_file2_revno2()),
639
                                     ('1', 0, self._diff_file2_revno1())],
640
                                    working_dir='level0')
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
641
642
643
class TestLogUnicodeDiff(TestLog):
3943.5.4 by Ian Clatworthy
filter diff by file
644
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.
645
    def test_log_show_diff_non_ascii(self):
646
        # Smoke test for bug #328007 UnicodeDecodeError on 'log -p'
647
        message = u'Message with \xb5'
648
        body = 'Body with \xb5\n'
649
        wt = self.make_branch_and_tree('.')
650
        self.build_tree_contents([('foo', body)])
651
        wt.add('foo')
652
        wt.commit(message=message)
653
        # check that command won't fail with unicode error
654
        # don't care about exact output because we have other tests for this
655
        out,err = self.run_bzr('log -p --long')
656
        self.assertNotEqual('', out)
657
        self.assertEqual('', err)
658
        out,err = self.run_bzr('log -p --short')
659
        self.assertNotEqual('', out)
660
        self.assertEqual('', err)
661
        out,err = self.run_bzr('log -p --line')
662
        self.assertNotEqual('', out)
663
        self.assertEqual('', err)
664
3943.5.3 by Ian Clatworthy
add tests
665
4325.4.3 by Vincent Ladeuil
More cleanups.
666
class TestLogEncodings(tests.TestCaseInTempDir):
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
667
668
    _mu = u'\xb5'
669
    _message = u'Message with \xb5'
670
671
    # Encodings which can encode mu
672
    good_encodings = [
673
        'utf-8',
674
        'latin-1',
675
        'iso-8859-1',
676
        '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.
677
        'cp1251', # Russian windows encoding
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
678
        'cp1258', # Common windows encoding
679
    ]
680
    # Encodings which cannot encode mu
681
    bad_encodings = [
682
        'ascii',
683
        'iso-8859-2',
684
        'koi8_r',
685
    ]
686
687
    def setUp(self):
4325.4.3 by Vincent Ladeuil
More cleanups.
688
        super(TestLogEncodings, self).setUp()
4985.1.5 by Vincent Ladeuil
Deploying the new overrideAttr facility further reduces the complexity
689
        self.overrideAttr(osutils, '_cached_user_encoding')
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
690
691
    def create_branch(self):
692
        bzr = self.run_bzr
693
        bzr('init')
4955.4.16 by Vincent Ladeuil
Be windows-friendly and don't left opened files behind.
694
        self.build_tree_contents([('a', 'some stuff\n')])
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
695
        bzr('add a')
696
        bzr(['commit', '-m', self._message])
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
697
698
    def try_encoding(self, encoding, fail=False):
699
        bzr = self.run_bzr
700
        if fail:
701
            self.assertRaises(UnicodeEncodeError,
702
                self._mu.encode, encoding)
703
            encoded_msg = self._message.encode(encoding, 'replace')
704
        else:
705
            encoded_msg = self._message.encode(encoding)
706
3224.5.4 by Andrew Bennetts
Fix test suite, mainly weeding out uses of bzrlib.user_encoding.
707
        old_encoding = osutils._cached_user_encoding
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
708
        # This test requires that 'run_bzr' uses the current
709
        # bzrlib, because we override user_encoding, and expect
710
        # it to be used
711
        try:
3224.5.4 by Andrew Bennetts
Fix test suite, mainly weeding out uses of bzrlib.user_encoding.
712
            osutils._cached_user_encoding = 'ascii'
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
713
            # We should be able to handle any encoding
714
            out, err = bzr('log', encoding=encoding)
715
            if not fail:
716
                # Make sure we wrote mu as we expected it to exist
717
                self.assertNotEqual(-1, out.find(encoded_msg))
718
                out_unicode = out.decode(encoding)
719
                self.assertNotEqual(-1, out_unicode.find(self._message))
720
            else:
721
                self.assertNotEqual(-1, out.find('Message with ?'))
722
        finally:
3224.5.4 by Andrew Bennetts
Fix test suite, mainly weeding out uses of bzrlib.user_encoding.
723
            osutils._cached_user_encoding = old_encoding
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
724
725
    def test_log_handles_encoding(self):
726
        self.create_branch()
727
728
        for encoding in self.good_encodings:
729
            self.try_encoding(encoding)
730
731
    def test_log_handles_bad_encoding(self):
732
        self.create_branch()
733
734
        for encoding in self.bad_encodings:
735
            self.try_encoding(encoding, fail=True)
736
737
    def test_stdout_encoding(self):
738
        bzr = self.run_bzr
3224.5.4 by Andrew Bennetts
Fix test suite, mainly weeding out uses of bzrlib.user_encoding.
739
        osutils._cached_user_encoding = "cp1251"
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
740
741
        bzr('init')
742
        self.build_tree(['a'])
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
743
        bzr('add a')
744
        bzr(['commit', '-m', u'\u0422\u0435\u0441\u0442'])
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
745
        stdout, stderr = self.run_bzr('log', encoding='cp866')
746
747
        message = stdout.splitlines()[-1]
748
749
        # explanation of the check:
750
        # u'\u0422\u0435\u0441\u0442' is word 'Test' in russian
751
        # in cp866  encoding this is string '\x92\xa5\xe1\xe2'
752
        # in cp1251 encoding this is string '\xd2\xe5\xf1\xf2'
753
        # This test should check that output of log command
754
        # encoded to sys.stdout.encoding
755
        test_in_cp866 = '\x92\xa5\xe1\xe2'
756
        test_in_cp1251 = '\xd2\xe5\xf1\xf2'
757
        # Make sure the log string is encoded in cp866
758
        self.assertEquals(test_in_cp866, message[2:])
759
        # Make sure the cp1251 string is not found anywhere
760
        self.assertEquals(-1, stdout.find(test_in_cp1251))
761
1551.10.18 by Aaron Bentley
Log works in local treeless branches (#84247)
762
4955.4.9 by Vincent Ladeuil
More simplifications.
763
class TestLogFile(TestLogWithLogCatcher):
1551.10.18 by Aaron Bentley
Log works in local treeless branches (#84247)
764
765
    def test_log_local_branch_file(self):
766
        """We should be able to log files in local treeless branches"""
767
        tree = self.make_branch_and_tree('tree')
768
        self.build_tree(['tree/file'])
769
        tree.add('file')
770
        tree.commit('revision 1')
771
        tree.bzrdir.destroy_workingtree()
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
772
        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.
773
3943.6.1 by Ian Clatworthy
find file using the end revision
774
    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
775
        # 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.
776
        tree = self.make_branch_and_tree('parent')
777
        self.build_tree(['parent/file1', 'parent/file2', 'parent/file3'])
778
        tree.add('file1')
779
        tree.commit('add file1')
780
        tree.add('file2')
781
        tree.commit('add file2')
782
        tree.add('file3')
783
        tree.commit('add file3')
2664.14.1 by Daniel Watkins
Fixed tests.blackbox.test_log to use internals where appropriate.
784
        child_tree = tree.bzrdir.sprout('child').open_workingtree()
785
        self.build_tree_contents([('child/file2', 'hello')])
786
        child_tree.commit(message='branch 1')
787
        tree.merge_from_branch(child_tree.branch)
788
        tree.commit(message='merge child branch')
3943.6.1 by Ian Clatworthy
find file using the end revision
789
        if complex:
3943.6.3 by Ian Clatworthy
search the start tree if the end tree doesn't have a file
790
            tree.remove('file2')
791
            tree.commit('remove file2')
792
            tree.rename_one('file3', 'file4')
793
            tree.commit('file3 is now called file4')
3943.6.1 by Ian Clatworthy
find file using the end revision
794
            tree.remove('file1')
3943.6.3 by Ian Clatworthy
search the start tree if the end tree doesn't have a file
795
            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.
796
        os.chdir('parent')
3940.1.2 by Ian Clatworthy
add test
797
4955.4.9 by Vincent Ladeuil
More simplifications.
798
    # FIXME: It would be good to parametrize the following tests against all
799
    # formatters. But the revisions selection is not *currently* part of the
800
    # LogFormatter contract, so using LogCatcher is sufficient -- vila 100118
801
    def test_log_file1(self):
802
        self.prepare_tree()
803
        self.assertLogRevnos(['-n0', 'file1'], ['1'])
804
805
    def test_log_file2(self):
806
        self.prepare_tree()
807
        # file2 full history
808
        self.assertLogRevnos(['-n0', 'file2'], ['4', '3.1.1', '2'])
809
        # file2 in a merge revision
810
        self.assertLogRevnos(['-n0', '-r3.1.1', 'file2'], ['3.1.1'])
811
        # file2 in a mainline revision
812
        self.assertLogRevnos(['-n0', '-r4', 'file2'], ['4', '3.1.1'])
813
        # file2 since a revision
814
        self.assertLogRevnos(['-n0', '-r3..', 'file2'], ['4', '3.1.1'])
815
        # file2 up to a revision
816
        self.assertLogRevnos(['-n0', '-r..3', 'file2'], ['2'])
817
818
    def test_log_file3(self):
819
        self.prepare_tree()
820
        self.assertLogRevnos(['-n0', 'file3'], ['3'])
3940.1.2 by Ian Clatworthy
add test
821
3943.6.4 by Ian Clatworthy
review feedback from vila
822
    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
823
        # Check logging a deleted file gives an error if the
824
        # file isn't found at the end or start of the revision range
3943.6.4 by Ian Clatworthy
review feedback from vila
825
        self.prepare_tree(complex=True)
3943.6.3 by Ian Clatworthy
search the start tree if the end tree doesn't have a file
826
        err_msg = "Path unknown at end or start of revision range: file2"
827
        err = self.run_bzr('log file2', retcode=3)[1]
3943.6.1 by Ian Clatworthy
find file using the end revision
828
        self.assertContainsRe(err, err_msg)
829
3943.6.4 by Ian Clatworthy
review feedback from vila
830
    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
831
        # Check logging a deleted file is ok if the file existed
832
        # at the end the revision range
3943.6.4 by Ian Clatworthy
review feedback from vila
833
        self.prepare_tree(complex=True)
4955.4.9 by Vincent Ladeuil
More simplifications.
834
        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
835
3943.6.4 by Ian Clatworthy
review feedback from vila
836
    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
837
        # Check logging a deleted file is ok if the file existed
838
        # at the start of the revision range
3943.6.4 by Ian Clatworthy
review feedback from vila
839
        self.prepare_tree(complex=True)
4955.4.9 by Vincent Ladeuil
More simplifications.
840
        self.assertLogRevnos(['file1'], ['1'])
3943.6.1 by Ian Clatworthy
find file using the end revision
841
842
    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
843
        """File matched against revision range, not current tree."""
3943.6.1 by Ian Clatworthy
find file using the end revision
844
        self.prepare_tree(complex=True)
3943.6.3 by Ian Clatworthy
search the start tree if the end tree doesn't have a file
845
3943.6.1 by Ian Clatworthy
find file using the end revision
846
        # 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
847
        err_msg = "Path unknown at end or start of revision range: file3"
3943.6.1 by Ian Clatworthy
find file using the end revision
848
        err = self.run_bzr('log file3', retcode=3)[1]
849
        self.assertContainsRe(err, err_msg)
850
851
        # Check we can see a renamed file if we give the right end revision
4955.4.9 by Vincent Ladeuil
More simplifications.
852
        self.assertLogRevnos(['-r..4', 'file3'], ['3'])
4202.2.1 by Ian Clatworthy
get directory logging working again
853
854
4955.4.10 by Vincent Ladeuil
More simplification.
855
class TestLogMultiple(TestLogWithLogCatcher):
4202.2.1 by Ian Clatworthy
get directory logging working again
856
857
    def prepare_tree(self):
858
        tree = self.make_branch_and_tree('parent')
859
        self.build_tree([
860
            'parent/file1',
861
            'parent/file2',
862
            'parent/dir1/',
863
            'parent/dir1/file5',
864
            'parent/dir1/dir2/',
865
            'parent/dir1/dir2/file3',
866
            'parent/file4'])
867
        tree.add('file1')
4202.2.2 by Ian Clatworthy
improve signal-to-noise ratio in tests
868
        tree.commit('add file1')
4202.2.1 by Ian Clatworthy
get directory logging working again
869
        tree.add('file2')
4202.2.2 by Ian Clatworthy
improve signal-to-noise ratio in tests
870
        tree.commit('add file2')
4202.2.1 by Ian Clatworthy
get directory logging working again
871
        tree.add(['dir1', 'dir1/dir2', 'dir1/dir2/file3'])
4202.2.2 by Ian Clatworthy
improve signal-to-noise ratio in tests
872
        tree.commit('add file3')
4202.2.1 by Ian Clatworthy
get directory logging working again
873
        tree.add('file4')
4202.2.2 by Ian Clatworthy
improve signal-to-noise ratio in tests
874
        tree.commit('add file4')
4202.2.1 by Ian Clatworthy
get directory logging working again
875
        tree.add('dir1/file5')
4202.2.2 by Ian Clatworthy
improve signal-to-noise ratio in tests
876
        tree.commit('add file5')
4202.2.1 by Ian Clatworthy
get directory logging working again
877
        child_tree = tree.bzrdir.sprout('child').open_workingtree()
878
        self.build_tree_contents([('child/file2', 'hello')])
4202.2.2 by Ian Clatworthy
improve signal-to-noise ratio in tests
879
        child_tree.commit(message='branch 1')
4202.2.1 by Ian Clatworthy
get directory logging working again
880
        tree.merge_from_branch(child_tree.branch)
4202.2.2 by Ian Clatworthy
improve signal-to-noise ratio in tests
881
        tree.commit(message='merge child branch')
4202.2.1 by Ian Clatworthy
get directory logging working again
882
        os.chdir('parent')
883
884
    def test_log_files(self):
885
        """The log for multiple file should only list revs for those files"""
886
        self.prepare_tree()
4955.4.10 by Vincent Ladeuil
More simplification.
887
        self.assertLogRevnos(['file1', 'file2', 'dir1/dir2/file3'],
888
                             ['6', '5.1.1', '3', '2', '1'])
4202.2.1 by Ian Clatworthy
get directory logging working again
889
890
    def test_log_directory(self):
891
        """The log for a directory should show all nested files."""
892
        self.prepare_tree()
4955.4.10 by Vincent Ladeuil
More simplification.
893
        self.assertLogRevnos(['dir1'], ['5', '3'])
4202.2.1 by Ian Clatworthy
get directory logging working again
894
895
    def test_log_nested_directory(self):
896
        """The log for a directory should show all nested files."""
897
        self.prepare_tree()
4955.4.10 by Vincent Ladeuil
More simplification.
898
        self.assertLogRevnos(['dir1/dir2'], ['3'])
4202.2.1 by Ian Clatworthy
get directory logging working again
899
900
    def test_log_in_nested_directory(self):
901
        """The log for a directory should show all nested files."""
902
        self.prepare_tree()
903
        os.chdir("dir1")
4955.4.10 by Vincent Ladeuil
More simplification.
904
        self.assertLogRevnos(['.'], ['5', '3'])
4202.2.1 by Ian Clatworthy
get directory logging working again
905
906
    def test_log_files_and_directories(self):
907
        """Logging files and directories together should be fine."""
908
        self.prepare_tree()
4955.4.10 by Vincent Ladeuil
More simplification.
909
        self.assertLogRevnos(['file4', 'dir1/dir2'], ['4', '3'])
4202.2.1 by Ian Clatworthy
get directory logging working again
910
911
    def test_log_files_and_dirs_in_nested_directory(self):
912
        """The log for a directory should show all nested files."""
913
        self.prepare_tree()
914
        os.chdir("dir1")
4955.4.10 by Vincent Ladeuil
More simplification.
915
        self.assertLogRevnos(['dir2', 'file5'], ['5', '3'])