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