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