/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
1551.10.18 by Aaron Bentley
Log works in local treeless branches (#84247)
1
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
1540.2.6 by Robey Pointer
make 'log' and 'status' treat '-r N..' as implicitly '-r N..-1'
2
# -*- coding: utf-8 -*-
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
3
#
1540.2.6 by Robey Pointer
make 'log' and 'status' treat '-r N..' as implicitly '-r N..-1'
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
8
#
1540.2.6 by Robey Pointer
make 'log' and 'status' treat '-r N..' as implicitly '-r N..-1'
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
13
#
1540.2.6 by Robey Pointer
make 'log' and 'status' treat '-r N..' as implicitly '-r N..-1'
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
18
1624.1.3 by Robert Collins
Convert log to use the new tsort.merge_sort routine.
19
"""Black-box tests for bzr log."""
1540.2.6 by Robey Pointer
make 'log' and 'status' treat '-r N..' as implicitly '-r N..-1'
20
3940.1.2 by Ian Clatworthy
add test
21
import os, re
1540.2.6 by Robey Pointer
make 'log' and 'status' treat '-r N..' as implicitly '-r N..-1'
22
3224.5.4 by Andrew Bennetts
Fix test suite, mainly weeding out uses of bzrlib.user_encoding.
23
from bzrlib import osutils
1540.2.6 by Robey Pointer
make 'log' and 'status' treat '-r N..' as implicitly '-r N..-1'
24
from bzrlib.tests.blackbox import ExternalBase
3936.3.12 by Ian Clatworthy
more single revision & sequence tuning
25
from bzrlib.tests import KnownFailure, TestCaseInTempDir, TestCaseWithTransport
2978.6.1 by Kent Gibson
Use normalize_log to more accurately test blackbox log output.
26
from bzrlib.tests.test_log import (
27
    normalize_log,
28
    )
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
29
from bzrlib.tests import test_log
30
31
3842.2.5 by Vincent Ladeuil
Better fix for bug #300055.
32
class TestCaseWithoutPropsHandler(ExternalBase,
33
                                  test_log.TestCaseWithoutPropsHandler):
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
34
    pass
1540.2.6 by Robey Pointer
make 'log' and 'status' treat '-r N..' as implicitly '-r N..-1'
35
36
37
class TestLog(ExternalBase):
38
2664.14.1 by Daniel Watkins
Fixed tests.blackbox.test_log to use internals where appropriate.
39
    def _prepare(self, path='.', format=None):
2809.1.2 by Daniel Watkins
Removed unnecessary check as per abentley's on-list comments.
40
        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.
41
        self.build_tree(
42
            [path + '/hello.txt', path + '/goodbye.txt', path + '/meep.txt'])
43
        tree.add('hello.txt')
44
        tree.commit(message='message1')
45
        tree.add('goodbye.txt')
46
        tree.commit(message='message2')
47
        tree.add('meep.txt')
48
        tree.commit(message='message3')
49
        self.full_log = self.run_bzr(["log", path])[0]
50
        return tree
1553.4.2 by Michael Ellerman
Make bzr log -r .. work, fixes bug #4609. Add a bunch of tests to make sure
51
52
    def test_log_null_end_revspec(self):
53
        self._prepare()
54
        self.assertTrue('revno: 1\n' in self.full_log)
55
        self.assertTrue('revno: 2\n' in self.full_log)
56
        self.assertTrue('revno: 3\n' in self.full_log)
57
        self.assertTrue('message:\n  message1\n' in self.full_log)
58
        self.assertTrue('message:\n  message2\n' in self.full_log)
59
        self.assertTrue('message:\n  message3\n' in self.full_log)
60
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
61
        log = self.run_bzr("log -r 1..")[0]
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
62
        self.assertEqualDiff(log, self.full_log)
1553.4.2 by Michael Ellerman
Make bzr log -r .. work, fixes bug #4609. Add a bunch of tests to make sure
63
64
    def test_log_null_begin_revspec(self):
65
        self._prepare()
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
66
        log = self.run_bzr("log -r ..3")[0]
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
67
        self.assertEqualDiff(self.full_log, log)
1553.4.2 by Michael Ellerman
Make bzr log -r .. work, fixes bug #4609. Add a bunch of tests to make sure
68
69
    def test_log_null_both_revspecs(self):
70
        self._prepare()
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
71
        log = self.run_bzr("log -r ..")[0]
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
72
        self.assertEqualDiff(self.full_log, log)
1553.4.2 by Michael Ellerman
Make bzr log -r .. work, fixes bug #4609. Add a bunch of tests to make sure
73
2978.4.1 by Kent Gibson
Logging revision 0 returns error.
74
    def test_log_zero_revspec(self):
75
        self._prepare()
76
        self.run_bzr_error('bzr: ERROR: Logging revision 0 is invalid.',
77
                           ['log', '-r0'])
78
79
    def test_log_zero_begin_revspec(self):
80
        self._prepare()
81
        self.run_bzr_error('bzr: ERROR: Logging revision 0 is invalid.',
82
                           ['log', '-r0..2'])
83
84
    def test_log_zero_end_revspec(self):
85
        self._prepare()
86
        self.run_bzr_error('bzr: ERROR: Logging revision 0 is invalid.',
87
                           ['log', '-r-2..0'])
88
3144.1.1 by Lukáš Lalinský
Fixed error reporting of unsupported timezone format.
89
    def test_log_unsupported_timezone(self):
90
        self._prepare()
91
        self.run_bzr_error('bzr: ERROR: Unsupported timezone format "foo", '
92
                           'options are "utc", "original", "local".',
93
                           ['log', '--timezone', 'foo'])
94
1553.4.2 by Michael Ellerman
Make bzr log -r .. work, fixes bug #4609. Add a bunch of tests to make sure
95
    def test_log_negative_begin_revspec_full_log(self):
96
        self._prepare()
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
97
        log = self.run_bzr("log -r -3..")[0]
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
98
        self.assertEqualDiff(self.full_log, log)
1553.4.2 by Michael Ellerman
Make bzr log -r .. work, fixes bug #4609. Add a bunch of tests to make sure
99
100
    def test_log_negative_both_revspec_full_log(self):
101
        self._prepare()
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
102
        log = self.run_bzr("log -r -3..-1")[0]
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
103
        self.assertEqualDiff(self.full_log, log)
1553.4.2 by Michael Ellerman
Make bzr log -r .. work, fixes bug #4609. Add a bunch of tests to make sure
104
105
    def test_log_negative_both_revspec_partial(self):
106
        self._prepare()
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
107
        log = self.run_bzr("log -r -3..-2")[0]
1553.4.2 by Michael Ellerman
Make bzr log -r .. work, fixes bug #4609. Add a bunch of tests to make sure
108
        self.assertTrue('revno: 1\n' in log)
109
        self.assertTrue('revno: 2\n' in log)
110
        self.assertTrue('revno: 3\n' not in log)
111
112
    def test_log_negative_begin_revspec(self):
113
        self._prepare()
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
114
        log = self.run_bzr("log -r -2..")[0]
1553.4.2 by Michael Ellerman
Make bzr log -r .. work, fixes bug #4609. Add a bunch of tests to make sure
115
        self.assertTrue('revno: 1\n' not in log)
116
        self.assertTrue('revno: 2\n' in log)
117
        self.assertTrue('revno: 3\n' in log)
118
2978.4.1 by Kent Gibson
Logging revision 0 returns error.
119
    def test_log_positive_revspecs(self):
1553.4.2 by Michael Ellerman
Make bzr log -r .. work, fixes bug #4609. Add a bunch of tests to make sure
120
        self._prepare()
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
121
        log = self.run_bzr("log -r 1..3")[0]
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
122
        self.assertEqualDiff(self.full_log, log)
1624.1.3 by Robert Collins
Convert log to use the new tsort.merge_sort routine.
123
2466.12.1 by Kent Gibson
Fix ``bzr log -r`` to support selecting merge revisions.
124
    def test_log_reversed_revspecs(self):
125
        self._prepare()
126
        self.run_bzr_error(('bzr: ERROR: Start revision must be older than '
127
                            'the end revision.\n',),
2581.1.6 by Martin Pool
fix up more run_bzr callers
128
                           ['log', '-r3..1'])
2466.12.1 by Kent Gibson
Fix ``bzr log -r`` to support selecting merge revisions.
129
1907.4.2 by Matthieu Moy
Make log work nicely with revno:N:path too.
130
    def test_log_revno_n_path(self):
2664.14.1 by Daniel Watkins
Fixed tests.blackbox.test_log to use internals where appropriate.
131
        self._prepare(path='branch1')
132
        self._prepare(path='branch2')
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
133
        log = self.run_bzr("log -r revno:2:branch1..revno:3:branch2",
1907.4.2 by Matthieu Moy
Make log work nicely with revno:N:path too.
134
                          retcode=3)[0]
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
135
        log = self.run_bzr("log -r revno:1:branch2..revno:3:branch2")[0]
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
136
        self.assertEqualDiff(self.full_log, log)
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
137
        log = self.run_bzr("log -r revno:1:branch2")[0]
1907.4.2 by Matthieu Moy
Make log work nicely with revno:N:path too.
138
        self.assertTrue('revno: 1\n' in log)
139
        self.assertTrue('revno: 2\n' not in log)
140
        self.assertTrue('branch nick: branch2\n' in log)
141
        self.assertTrue('branch nick: branch1\n' not in log)
3734.1.1 by Vincent Ladeuil
Fix bug #248427 by adding a --change option to log.
142
3878.3.3 by Marius Kruger
Add tests for log -r with non-exising revno's
143
    def test_log_nonexistent_revno(self):
144
        self._prepare()
145
        (out, err) = self.run_bzr_error(args="log -r 1234",
146
            error_regexes=["bzr: ERROR: Requested revision: '1234' "
147
                "does not exist in branch:"])
148
149
    def test_log_nonexistent_dotted_revno(self):
150
        self._prepare()
151
        (out, err) = self.run_bzr_error(args="log -r 123.123",
152
            error_regexes=["bzr: ERROR: Requested revision: '123.123' "
153
                "does not exist in branch:"])
154
3734.1.1 by Vincent Ladeuil
Fix bug #248427 by adding a --change option to log.
155
    def test_log_change_revno(self):
156
        self._prepare()
157
        expected_log = self.run_bzr("log -r 1")[0]
158
        log = self.run_bzr("log -c 1")[0]
159
        self.assertEqualDiff(expected_log, log)
160
3878.3.2 by Marius Kruger
Add tests for log -c with non-exising revno's
161
    def test_log_change_nonexistent_revno(self):
162
        self._prepare()
163
        (out, err) = self.run_bzr_error(args="log -c 1234",
164
            error_regexes=["bzr: ERROR: Requested revision: '1234' "
165
                "does not exist in branch:"])
166
167
    def test_log_change_nonexistent_dotted_revno(self):
168
        self._prepare()
169
        (out, err) = self.run_bzr_error(args="log -c 123.123",
170
            error_regexes=["bzr: ERROR: Requested revision: '123.123' "
171
                "does not exist in branch:"])
172
3734.1.1 by Vincent Ladeuil
Fix bug #248427 by adding a --change option to log.
173
    def test_log_change_single_revno(self):
174
        self._prepare()
175
        self.run_bzr_error('bzr: ERROR: Option --change does not'
176
                           ' accept revision ranges',
177
                           ['log', '--change', '2..3'])
178
179
    def test_log_change_incompatible_with_revision(self):
180
        self._prepare()
181
        self.run_bzr_error('bzr: ERROR: --revision and --change'
182
                           ' are mutually exclusive',
183
                           ['log', '--change', '2', '--revision', '3'])
184
2100.1.1 by wang
Running ``bzr log`` on nonexistent file gives an error instead of the
185
    def test_log_nonexistent_file(self):
186
        # files that don't exist in either the basis tree or working tree
187
        # should give an error
188
        wt = self.make_branch_and_tree('.')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
189
        out, err = self.run_bzr('log does-not-exist', retcode=3)
2100.1.1 by wang
Running ``bzr log`` on nonexistent file gives an error instead of the
190
        self.assertContainsRe(
3943.6.3 by Ian Clatworthy
search the start tree if the end tree doesn't have a file
191
            err, 'Path unknown at end or start of revision range: does-not-exist')
2388.1.11 by Alexander Belchenko
changes after John's review
192
2388.1.3 by Erik Bagfors
tests for tags in log output
193
    def test_log_with_tags(self):
2664.14.1 by Daniel Watkins
Fixed tests.blackbox.test_log to use internals where appropriate.
194
        tree = self._prepare(format='dirstate-tags')
195
        branch = tree.branch
196
        branch.tags.set_tag('tag1', branch.get_rev_id(1))
197
        branch.tags.set_tag('tag1.1', branch.get_rev_id(1))
3842.2.5 by Vincent Ladeuil
Better fix for bug #300055.
198
        branch.tags.set_tag('tag3', branch.last_revision())
199
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
200
        log = self.run_bzr("log -r-1")[0]
2388.1.3 by Erik Bagfors
tests for tags in log output
201
        self.assertTrue('tags: tag3' in log)
202
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
203
        log = self.run_bzr("log -r1")[0]
2388.1.3 by Erik Bagfors
tests for tags in log output
204
        # I guess that we can't know the order of tags in the output
205
        # since dicts are unordered, need to check both possibilities
2388.1.11 by Alexander Belchenko
changes after John's review
206
        self.assertContainsRe(log, r'tags: (tag1, tag1\.1|tag1\.1, tag1)')
207
2388.1.9 by Erik Bagfors
test for merges with tags in log
208
    def test_merged_log_with_tags(self):
2664.14.1 by Daniel Watkins
Fixed tests.blackbox.test_log to use internals where appropriate.
209
        branch1_tree = self._prepare(path='branch1', format='dirstate-tags')
210
        branch1 = branch1_tree.branch
211
        branch2_tree = branch1_tree.bzrdir.sprout('branch2').open_workingtree()
212
        branch1_tree.commit(message='foobar', allow_pointless=True)
213
        branch1.tags.set_tag('tag1', branch1.last_revision())
214
        os.chdir('branch2')
215
        self.run_bzr('merge ../branch1') # tags don't propagate otherwise
216
        branch2_tree.commit(message='merge branch 1')
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
217
        log = self.run_bzr("log -r-1")[0]
2388.1.11 by Alexander Belchenko
changes after John's review
218
        self.assertContainsRe(log, r'    tags: tag1')
2578.2.1 by Andrew Bennetts
Merge Kent Gibson's fix for bug #4663, resolving conflicts.
219
        log = self.run_bzr("log -r3.1.1")[0]
2466.12.2 by Kent Gibson
shift log output with only merge revisions to the left margin
220
        self.assertContainsRe(log, r'tags: tag1')
2388.1.3 by Erik Bagfors
tests for tags in log output
221
2466.9.1 by Kent Gibson
add bzr log --limit
222
    def test_log_limit(self):
3660.1.1 by Robert Collins
Fix log --limit (broken by log filtering patch).
223
        tree = self.make_branch_and_tree('.')
224
        # We want more commits than our batch size starts at
225
        for pos in range(10):
226
            tree.commit("%s" % pos)
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
227
        log = self.run_bzr("log --limit 2")[0]
3108.1.3 by Matt Nordhoff
Use assertContainsRe/assertNotContainsRe in tests.
228
        self.assertNotContainsRe(log, r'revno: 1\n')
3660.1.1 by Robert Collins
Fix log --limit (broken by log filtering patch).
229
        self.assertNotContainsRe(log, r'revno: 2\n')
230
        self.assertNotContainsRe(log, r'revno: 3\n')
231
        self.assertNotContainsRe(log, r'revno: 4\n')
232
        self.assertNotContainsRe(log, r'revno: 5\n')
233
        self.assertNotContainsRe(log, r'revno: 6\n')
234
        self.assertNotContainsRe(log, r'revno: 7\n')
235
        self.assertNotContainsRe(log, r'revno: 8\n')
236
        self.assertContainsRe(log, r'revno: 9\n')
237
        self.assertContainsRe(log, r'revno: 10\n')
2466.9.1 by Kent Gibson
add bzr log --limit
238
3108.1.2 by Matt Nordhoff
Simple copied unit test.
239
    def test_log_limit_short(self):
240
        self._prepare()
241
        log = self.run_bzr("log -l 2")[0]
3108.1.3 by Matt Nordhoff
Use assertContainsRe/assertNotContainsRe in tests.
242
        self.assertNotContainsRe(log, r'revno: 1\n')
243
        self.assertContainsRe(log, r'revno: 2\n')
244
        self.assertContainsRe(log, r'revno: 3\n')
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
245
3874.1.8 by Vincent Ladeuil
Fixed as ber Robert's review.
246
247
class TestLogVerbose(TestCaseWithTransport):
248
249
    def setUp(self):
250
        super(TestLogVerbose, self).setUp()
251
        tree = self.make_branch_and_tree('.')
252
        self.build_tree(['hello.txt'])
253
        tree.add('hello.txt')
254
        tree.commit(message='message1')
255
256
    def assertUseShortDeltaFormat(self, cmd):
257
        log = self.run_bzr(cmd)[0]
258
        # Check that we use the short status format
3947.1.7 by Ian Clatworthy
tweak indenting/offsetting for --short given dotted revno lengths
259
        self.assertContainsRe(log, '(?m)^\s*A  hello.txt$')
260
        self.assertNotContainsRe(log, '(?m)^\s*added:$')
3874.1.4 by Vincent Ladeuil
Fixed as per Aarons' comment.
261
3874.1.8 by Vincent Ladeuil
Fixed as ber Robert's review.
262
    def assertUseLongDeltaFormat(self, cmd):
263
        log = self.run_bzr(cmd)[0]
264
        # Check that we use the long status format
3947.1.7 by Ian Clatworthy
tweak indenting/offsetting for --short given dotted revno lengths
265
        self.assertNotContainsRe(log, '(?m)^\s*A  hello.txt$')
266
        self.assertContainsRe(log, '(?m)^\s*added:$')
3874.1.8 by Vincent Ladeuil
Fixed as ber Robert's review.
267
268
    def test_log_short_verbose(self):
269
        self.assertUseShortDeltaFormat(['log', '--short', '-v'])
270
3874.1.4 by Vincent Ladeuil
Fixed as per Aarons' comment.
271
    def test_log_short_verbose_verbose(self):
3874.1.8 by Vincent Ladeuil
Fixed as ber Robert's review.
272
        self.assertUseLongDeltaFormat(['log', '--short', '-vv'])
3874.1.4 by Vincent Ladeuil
Fixed as per Aarons' comment.
273
274
    def test_log_long_verbose(self):
3874.1.7 by Vincent Ladeuil
Restrict '-v' change to log --short only.
275
        # Check that we use the long status format, ignoring the verbosity
276
        # level
3874.1.8 by Vincent Ladeuil
Fixed as ber Robert's review.
277
        self.assertUseLongDeltaFormat(['log', '--long', '-v'])
3874.1.4 by Vincent Ladeuil
Fixed as per Aarons' comment.
278
279
    def test_log_long_verbose_verbose(self):
3874.1.7 by Vincent Ladeuil
Restrict '-v' change to log --short only.
280
        # Check that we use the long status format, ignoring the verbosity
281
        # level
3874.1.8 by Vincent Ladeuil
Fixed as ber Robert's review.
282
        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.
283
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
284
285
class TestLogMerges(TestCaseWithoutPropsHandler):
1624.1.3 by Robert Collins
Convert log to use the new tsort.merge_sort routine.
286
2466.12.1 by Kent Gibson
Fix ``bzr log -r`` to support selecting merge revisions.
287
    def _prepare(self):
2664.14.1 by Daniel Watkins
Fixed tests.blackbox.test_log to use internals where appropriate.
288
        parent_tree = self.make_branch_and_tree('parent')
289
        parent_tree.commit(message='first post', allow_pointless=True)
290
        child_tree = parent_tree.bzrdir.sprout('child').open_workingtree()
291
        child_tree.commit(message='branch 1', allow_pointless=True)
292
        smaller_tree = \
293
                child_tree.bzrdir.sprout('smallerchild').open_workingtree()
294
        smaller_tree.commit(message='branch 2', allow_pointless=True)
295
        child_tree.merge_from_branch(smaller_tree.branch)
296
        child_tree.commit(message='merge branch 2')
297
        parent_tree.merge_from_branch(child_tree.branch)
298
        parent_tree.commit(message='merge branch 1')
299
        os.chdir('parent')
2466.12.1 by Kent Gibson
Fix ``bzr log -r`` to support selecting merge revisions.
300
3947.1.3 by Ian Clatworthy
blackbox tests
301
    def _prepare_short(self):
302
        parent_tree = self.make_branch_and_tree('parent')
303
        parent_tree.commit(message='first post',
304
            timestamp=1132586700, timezone=36000,
305
            committer='Joe Foo <joe@foo.com>')
306
        child_tree = parent_tree.bzrdir.sprout('child').open_workingtree()
307
        child_tree.commit(message='branch 1',
308
            timestamp=1132586800, timezone=36000,
309
            committer='Joe Foo <joe@foo.com>')
310
        smaller_tree = \
311
                child_tree.bzrdir.sprout('smallerchild').open_workingtree()
312
        smaller_tree.commit(message='branch 2',
313
            timestamp=1132586900, timezone=36000,
314
            committer='Joe Foo <joe@foo.com>')
315
        child_tree.merge_from_branch(smaller_tree.branch)
316
        child_tree.commit(message='merge branch 2',
317
            timestamp=1132587000, timezone=36000,
318
            committer='Joe Foo <joe@foo.com>')
319
        parent_tree.merge_from_branch(child_tree.branch)
320
        parent_tree.commit(message='merge branch 1',
321
            timestamp=1132587100, timezone=36000,
322
            committer='Joe Foo <joe@foo.com>')
323
        os.chdir('parent')
324
2466.12.1 by Kent Gibson
Fix ``bzr log -r`` to support selecting merge revisions.
325
    def test_merges_are_indented_by_level(self):
326
        self._prepare()
1624.1.3 by Robert Collins
Convert log to use the new tsort.merge_sort routine.
327
        out,err = self.run_bzr('log')
328
        self.assertEqual('', err)
2978.6.1 by Kent Gibson
Use normalize_log to more accurately test blackbox log output.
329
        log = normalize_log(out)
330
        self.assertEqualDiff(log, """\
331
------------------------------------------------------------
332
revno: 2
333
committer: Lorem Ipsum <test@example.com>
334
branch nick: parent
335
timestamp: Just now
336
message:
337
  merge branch 1
338
    ------------------------------------------------------------
339
    revno: 1.1.2
340
    committer: Lorem Ipsum <test@example.com>
341
    branch nick: child
342
    timestamp: Just now
343
    message:
344
      merge branch 2
345
        ------------------------------------------------------------
3170.3.4 by John Arbash Meinel
Update the tests for the new revision numbering.
346
        revno: 1.2.1
2978.6.1 by Kent Gibson
Use normalize_log to more accurately test blackbox log output.
347
        committer: Lorem Ipsum <test@example.com>
348
        branch nick: smallerchild
349
        timestamp: Just now
350
        message:
351
          branch 2
352
    ------------------------------------------------------------
353
    revno: 1.1.1
354
    committer: Lorem Ipsum <test@example.com>
355
    branch nick: child
356
    timestamp: Just now
357
    message:
358
      branch 1
359
------------------------------------------------------------
360
revno: 1
361
committer: Lorem Ipsum <test@example.com>
362
branch nick: parent
363
timestamp: Just now
364
message:
365
  first post
366
""")
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
367
3947.1.3 by Ian Clatworthy
blackbox tests
368
    def test_force_merge_revisions_off(self):
369
        self._prepare()
3947.1.6 by Ian Clatworthy
log -n/--level-count N option
370
        out,err = self.run_bzr('log --long -n1')
3947.1.3 by Ian Clatworthy
blackbox tests
371
        self.assertEqual('', err)
372
        log = normalize_log(out)
373
        self.assertEqualDiff(log, """\
374
------------------------------------------------------------
375
revno: 2
376
committer: Lorem Ipsum <test@example.com>
377
branch nick: parent
378
timestamp: Just now
379
message:
380
  merge branch 1
381
------------------------------------------------------------
382
revno: 1
383
committer: Lorem Ipsum <test@example.com>
384
branch nick: parent
385
timestamp: Just now
386
message:
387
  first post
388
""")
389
390
    def test_force_merge_revisions_on(self):
391
        self._prepare_short()
3947.1.6 by Ian Clatworthy
log -n/--level-count N option
392
        out,err = self.run_bzr('log --short -n0')
3947.1.3 by Ian Clatworthy
blackbox tests
393
        self.assertEqual('', err)
394
        log = normalize_log(out)
395
        self.assertEqualDiff(log, """\
396
    2 Joe Foo\t2005-11-22 [merge]
397
      merge branch 1
398
3947.1.10 by Ian Clatworthy
review feedback from vila
399
          1.1.2 Joe Foo\t2005-11-22 [merge]
400
                merge branch 2
401
402
              1.2.1 Joe Foo\t2005-11-22
403
                    branch 2
404
405
          1.1.1 Joe Foo\t2005-11-22
406
                branch 1
3947.1.7 by Ian Clatworthy
tweak indenting/offsetting for --short given dotted revno lengths
407
408
    1 Joe Foo\t2005-11-22
409
      first post
410
411
""")
412
413
    def test_force_merge_revisions_N(self):
414
        self._prepare_short()
415
        out,err = self.run_bzr('log --short -n2')
416
        self.assertEqual('', err)
417
        log = normalize_log(out)
418
        self.assertEqualDiff(log, """\
419
    2 Joe Foo\t2005-11-22 [merge]
420
      merge branch 1
421
3947.1.10 by Ian Clatworthy
review feedback from vila
422
          1.1.2 Joe Foo\t2005-11-22 [merge]
423
                merge branch 2
3947.1.7 by Ian Clatworthy
tweak indenting/offsetting for --short given dotted revno lengths
424
3947.1.10 by Ian Clatworthy
review feedback from vila
425
          1.1.1 Joe Foo\t2005-11-22
426
                branch 1
3947.1.3 by Ian Clatworthy
blackbox tests
427
428
    1 Joe Foo\t2005-11-22
429
      first post
430
431
""")
432
2466.12.1 by Kent Gibson
Fix ``bzr log -r`` to support selecting merge revisions.
433
    def test_merges_single_merge_rev(self):
434
        self._prepare()
2581.1.6 by Martin Pool
fix up more run_bzr callers
435
        out,err = self.run_bzr('log -r1.1.2')
2466.12.1 by Kent Gibson
Fix ``bzr log -r`` to support selecting merge revisions.
436
        self.assertEqual('', err)
2978.6.1 by Kent Gibson
Use normalize_log to more accurately test blackbox log output.
437
        log = normalize_log(out)
438
        self.assertEqualDiff(log, """\
439
------------------------------------------------------------
440
revno: 1.1.2
441
committer: Lorem Ipsum <test@example.com>
442
branch nick: child
443
timestamp: Just now
444
message:
445
  merge branch 2
446
    ------------------------------------------------------------
3170.3.4 by John Arbash Meinel
Update the tests for the new revision numbering.
447
    revno: 1.2.1
2978.6.1 by Kent Gibson
Use normalize_log to more accurately test blackbox log output.
448
    committer: Lorem Ipsum <test@example.com>
449
    branch nick: smallerchild
450
    timestamp: Just now
451
    message:
452
      branch 2
453
""")
2466.12.1 by Kent Gibson
Fix ``bzr log -r`` to support selecting merge revisions.
454
455
    def test_merges_partial_range(self):
456
        self._prepare()
3842.2.5 by Vincent Ladeuil
Better fix for bug #300055.
457
        out, err = self.run_bzr('log -r1.1.1..1.1.2')
2466.12.1 by Kent Gibson
Fix ``bzr log -r`` to support selecting merge revisions.
458
        self.assertEqual('', err)
2978.6.1 by Kent Gibson
Use normalize_log to more accurately test blackbox log output.
459
        log = normalize_log(out)
460
        self.assertEqualDiff(log, """\
461
------------------------------------------------------------
462
revno: 1.1.2
463
committer: Lorem Ipsum <test@example.com>
464
branch nick: child
465
timestamp: Just now
466
message:
467
  merge branch 2
468
    ------------------------------------------------------------
3170.3.4 by John Arbash Meinel
Update the tests for the new revision numbering.
469
    revno: 1.2.1
2978.6.1 by Kent Gibson
Use normalize_log to more accurately test blackbox log output.
470
    committer: Lorem Ipsum <test@example.com>
471
    branch nick: smallerchild
472
    timestamp: Just now
473
    message:
474
      branch 2
475
------------------------------------------------------------
476
revno: 1.1.1
477
committer: Lorem Ipsum <test@example.com>
478
branch nick: child
479
timestamp: Just now
480
message:
481
  branch 1
482
""")
2466.12.1 by Kent Gibson
Fix ``bzr log -r`` to support selecting merge revisions.
483
2978.3.1 by Kent Gibson
Return an error if the revisionspec contains merge revisions, but the log formatter doesn't support them.
484
    def test_merges_nonsupporting_formatter(self):
3936.3.12 by Ian Clatworthy
more single revision & sequence tuning
485
        # This "feature" of log formatters is madness. If a log
486
        # formatter cannot display a dotted-revno, it ought to ignore it.
487
        # Otherwise, a linear sequence is always expected to be handled now.
488
        raise KnownFailure('log formatters must support linear sequences now')
2978.3.1 by Kent Gibson
Return an error if the revisionspec contains merge revisions, but the log formatter doesn't support them.
489
        self._prepare()
490
        err_msg = 'Selected log formatter only supports mainline revisions.'
2997.1.1 by Kent Gibson
Support logging single merge revisions with short and line log formatters.
491
        # The single revision case is tested in the core tests
492
        # since all standard formatters support single merge revisions.
3936.3.8 by Ian Clatworthy
back-out --strict
493
        out,err = self.run_bzr('log --short -r1..1.1.2', retcode=3)
2978.3.1 by Kent Gibson
Return an error if the revisionspec contains merge revisions, but the log formatter doesn't support them.
494
        self.assertContainsRe(err, err_msg)
3936.3.8 by Ian Clatworthy
back-out --strict
495
        out,err = self.run_bzr('log --short -r1.1.1..1.1.2', retcode=3)
2978.3.1 by Kent Gibson
Return an error if the revisionspec contains merge revisions, but the log formatter doesn't support them.
496
        self.assertContainsRe(err, err_msg)
497
3842.2.5 by Vincent Ladeuil
Better fix for bug #300055.
498
3943.5.3 by Ian Clatworthy
add tests
499
def subst_dates(string):
500
    """Replace date strings with constant values."""
501
    return re.sub(r'\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} [-\+]\d{4}',
502
                  'YYYY-MM-DD HH:MM:SS +ZZZZ', string)
503
504
505
class TestLogDiff(TestCaseWithoutPropsHandler):
506
507
    def _prepare(self):
508
        parent_tree = self.make_branch_and_tree('parent')
509
        self.build_tree(['parent/file1', 'parent/file2'])
510
        parent_tree.add('file1')
511
        parent_tree.add('file2')
512
        parent_tree.commit(message='first post',
513
            timestamp=1132586655, timezone=36000,
514
            committer='Lorem Ipsum <test@example.com>')
515
        child_tree = parent_tree.bzrdir.sprout('child').open_workingtree()
516
        self.build_tree_contents([('child/file2', 'hello\n')])
517
        child_tree.commit(message='branch 1',
518
            timestamp=1132586700, timezone=36000,
519
            committer='Lorem Ipsum <test@example.com>')
520
        parent_tree.merge_from_branch(child_tree.branch)
521
        parent_tree.commit(message='merge branch 1',
522
            timestamp=1132586800, timezone=36000,
523
            committer='Lorem Ipsum <test@example.com>')
524
        os.chdir('parent')
525
526
    def test_log_show_diff_long(self):
527
        self._prepare()
3943.5.5 by Ian Clatworthy
tweak option name as requested in bug report
528
        out,err = self.run_bzr('log -p')
3943.5.3 by Ian Clatworthy
add tests
529
        self.assertEqual('', err)
530
        log = normalize_log(out)
531
        self.assertEqualDiff(subst_dates(log), """\
532
------------------------------------------------------------
533
revno: 2
534
committer: Lorem Ipsum <test@example.com>
535
branch nick: parent
536
timestamp: Just now
537
message:
538
  merge branch 1
539
diff:
3943.5.6 by Ian Clatworthy
feedback from jam's review
540
=== modified file 'file2'
541
--- file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
542
+++ file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
543
@@ -1,1 +1,1 @@
544
-contents of parent/file2
545
+hello
3943.5.3 by Ian Clatworthy
add tests
546
    ------------------------------------------------------------
547
    revno: 1.1.1
548
    committer: Lorem Ipsum <test@example.com>
549
    branch nick: child
550
    timestamp: Just now
551
    message:
552
      branch 1
553
    diff:
3943.5.6 by Ian Clatworthy
feedback from jam's review
554
    === modified file 'file2'
555
    --- file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
556
    +++ file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
557
    @@ -1,1 +1,1 @@
558
    -contents of parent/file2
559
    +hello
3943.5.3 by Ian Clatworthy
add tests
560
------------------------------------------------------------
561
revno: 1
562
committer: Lorem Ipsum <test@example.com>
563
branch nick: parent
564
timestamp: Just now
565
message:
566
  first post
567
diff:
3943.5.6 by Ian Clatworthy
feedback from jam's review
568
=== added file 'file1'
569
--- file1\tYYYY-MM-DD HH:MM:SS +ZZZZ
570
+++ file1\tYYYY-MM-DD HH:MM:SS +ZZZZ
571
@@ -0,0 +1,1 @@
572
+contents of parent/file1
573
574
=== added file 'file2'
575
--- file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
576
+++ file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
577
@@ -0,0 +1,1 @@
578
+contents of parent/file2
3943.5.3 by Ian Clatworthy
add tests
579
""")
580
581
    def test_log_show_diff_short(self):
582
        self._prepare()
3943.5.5 by Ian Clatworthy
tweak option name as requested in bug report
583
        out,err = self.run_bzr('log -p --short')
3943.5.3 by Ian Clatworthy
add tests
584
        self.assertEqual('', err)
585
        log = normalize_log(out)
586
        self.assertEqualDiff(subst_dates(log), """\
587
    2 Lorem Ipsum\t2005-11-22 [merge]
588
      merge branch 1
589
      === modified file 'file2'
590
      --- file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
591
      +++ file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
592
      @@ -1,1 +1,1 @@
593
      -contents of parent/file2
594
      +hello
595
596
    1 Lorem Ipsum\t2005-11-22
597
      first post
598
      === added file 'file1'
599
      --- file1\tYYYY-MM-DD HH:MM:SS +ZZZZ
600
      +++ file1\tYYYY-MM-DD HH:MM:SS +ZZZZ
601
      @@ -0,0 +1,1 @@
602
      +contents of parent/file1
4032.1.2 by John Arbash Meinel
Track down a few more files that have trailing whitespace.
603
\x20\x20\x20\x20\x20\x20
3943.5.3 by Ian Clatworthy
add tests
604
      === added file 'file2'
605
      --- file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
606
      +++ file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
607
      @@ -0,0 +1,1 @@
608
      +contents of parent/file2
609
610
""")
611
612
    def test_log_show_diff_line(self):
613
        self._prepare()
3943.5.5 by Ian Clatworthy
tweak option name as requested in bug report
614
        out,err = self.run_bzr('log -p --line')
3943.5.3 by Ian Clatworthy
add tests
615
        self.assertEqual('', err)
616
        log = normalize_log(out)
617
        # Not supported by this formatter so expect plain output
618
        self.assertEqualDiff(subst_dates(log), """\
3983.2.1 by Neil Martinsen-Burrell
add merge indication to the line format
619
2: Lorem Ipsum 2005-11-22 [merge] merge branch 1
3943.5.3 by Ian Clatworthy
add tests
620
1: Lorem Ipsum 2005-11-22 first post
621
""")
622
3943.5.4 by Ian Clatworthy
filter diff by file
623
    def test_log_show_diff_file(self):
624
        """Only the diffs for the given file are to be shown"""
625
        self._prepare()
3943.5.5 by Ian Clatworthy
tweak option name as requested in bug report
626
        out,err = self.run_bzr('log -p --short file2')
3943.5.4 by Ian Clatworthy
filter diff by file
627
        self.assertEqual('', err)
628
        log = normalize_log(out)
629
        self.assertEqualDiff(subst_dates(log), """\
630
    2 Lorem Ipsum\t2005-11-22 [merge]
631
      merge branch 1
632
      === modified file 'file2'
633
      --- file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
634
      +++ file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
635
      @@ -1,1 +1,1 @@
636
      -contents of parent/file2
637
      +hello
638
639
    1 Lorem Ipsum\t2005-11-22
640
      first post
641
      === added file 'file2'
642
      --- file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
643
      +++ file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
644
      @@ -0,0 +1,1 @@
645
      +contents of parent/file2
646
647
""")
3943.5.5 by Ian Clatworthy
tweak option name as requested in bug report
648
        out,err = self.run_bzr('log -p --short file1')
3943.5.4 by Ian Clatworthy
filter diff by file
649
        self.assertEqual('', err)
650
        log = normalize_log(out)
651
        self.assertEqualDiff(subst_dates(log), """\
652
    1 Lorem Ipsum\t2005-11-22
653
      first post
654
      === added file 'file1'
655
      --- file1\tYYYY-MM-DD HH:MM:SS +ZZZZ
656
      +++ file1\tYYYY-MM-DD HH:MM:SS +ZZZZ
657
      @@ -0,0 +1,1 @@
658
      +contents of parent/file1
659
660
""")
661
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.
662
    def test_log_show_diff_non_ascii(self):
663
        # Smoke test for bug #328007 UnicodeDecodeError on 'log -p'
664
        message = u'Message with \xb5'
665
        body = 'Body with \xb5\n'
666
        wt = self.make_branch_and_tree('.')
667
        self.build_tree_contents([('foo', body)])
668
        wt.add('foo')
669
        wt.commit(message=message)
670
        # check that command won't fail with unicode error
671
        # don't care about exact output because we have other tests for this
672
        out,err = self.run_bzr('log -p --long')
673
        self.assertNotEqual('', out)
674
        self.assertEqual('', err)
675
        out,err = self.run_bzr('log -p --short')
676
        self.assertNotEqual('', out)
677
        self.assertEqual('', err)
678
        out,err = self.run_bzr('log -p --line')
679
        self.assertNotEqual('', out)
680
        self.assertEqual('', err)
681
3943.5.3 by Ian Clatworthy
add tests
682
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
683
class TestLogEncodings(TestCaseInTempDir):
684
685
    _mu = u'\xb5'
686
    _message = u'Message with \xb5'
687
688
    # Encodings which can encode mu
689
    good_encodings = [
690
        'utf-8',
691
        'latin-1',
692
        'iso-8859-1',
693
        '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.
694
        'cp1251', # Russian windows encoding
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
695
        'cp1258', # Common windows encoding
696
    ]
697
    # Encodings which cannot encode mu
698
    bad_encodings = [
699
        'ascii',
700
        'iso-8859-2',
701
        'koi8_r',
702
    ]
703
704
    def setUp(self):
705
        TestCaseInTempDir.setUp(self)
3224.5.4 by Andrew Bennetts
Fix test suite, mainly weeding out uses of bzrlib.user_encoding.
706
        self.user_encoding = osutils._cached_user_encoding
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
707
708
    def tearDown(self):
3224.5.4 by Andrew Bennetts
Fix test suite, mainly weeding out uses of bzrlib.user_encoding.
709
        osutils._cached_user_encoding = self.user_encoding
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
710
        TestCaseInTempDir.tearDown(self)
711
712
    def create_branch(self):
713
        bzr = self.run_bzr
714
        bzr('init')
715
        open('a', 'wb').write('some stuff\n')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
716
        bzr('add a')
717
        bzr(['commit', '-m', self._message])
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
718
719
    def try_encoding(self, encoding, fail=False):
720
        bzr = self.run_bzr
721
        if fail:
722
            self.assertRaises(UnicodeEncodeError,
723
                self._mu.encode, encoding)
724
            encoded_msg = self._message.encode(encoding, 'replace')
725
        else:
726
            encoded_msg = self._message.encode(encoding)
727
3224.5.4 by Andrew Bennetts
Fix test suite, mainly weeding out uses of bzrlib.user_encoding.
728
        old_encoding = osutils._cached_user_encoding
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
729
        # This test requires that 'run_bzr' uses the current
730
        # bzrlib, because we override user_encoding, and expect
731
        # it to be used
732
        try:
3224.5.4 by Andrew Bennetts
Fix test suite, mainly weeding out uses of bzrlib.user_encoding.
733
            osutils._cached_user_encoding = 'ascii'
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
734
            # We should be able to handle any encoding
735
            out, err = bzr('log', encoding=encoding)
736
            if not fail:
737
                # Make sure we wrote mu as we expected it to exist
738
                self.assertNotEqual(-1, out.find(encoded_msg))
739
                out_unicode = out.decode(encoding)
740
                self.assertNotEqual(-1, out_unicode.find(self._message))
741
            else:
742
                self.assertNotEqual(-1, out.find('Message with ?'))
743
        finally:
3224.5.4 by Andrew Bennetts
Fix test suite, mainly weeding out uses of bzrlib.user_encoding.
744
            osutils._cached_user_encoding = old_encoding
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
745
746
    def test_log_handles_encoding(self):
747
        self.create_branch()
748
749
        for encoding in self.good_encodings:
750
            self.try_encoding(encoding)
751
752
    def test_log_handles_bad_encoding(self):
753
        self.create_branch()
754
755
        for encoding in self.bad_encodings:
756
            self.try_encoding(encoding, fail=True)
757
758
    def test_stdout_encoding(self):
759
        bzr = self.run_bzr
3224.5.4 by Andrew Bennetts
Fix test suite, mainly weeding out uses of bzrlib.user_encoding.
760
        osutils._cached_user_encoding = "cp1251"
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
761
762
        bzr('init')
763
        self.build_tree(['a'])
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
764
        bzr('add a')
765
        bzr(['commit', '-m', u'\u0422\u0435\u0441\u0442'])
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
766
        stdout, stderr = self.run_bzr('log', encoding='cp866')
767
768
        message = stdout.splitlines()[-1]
769
770
        # explanation of the check:
771
        # u'\u0422\u0435\u0441\u0442' is word 'Test' in russian
772
        # in cp866  encoding this is string '\x92\xa5\xe1\xe2'
773
        # in cp1251 encoding this is string '\xd2\xe5\xf1\xf2'
774
        # This test should check that output of log command
775
        # encoded to sys.stdout.encoding
776
        test_in_cp866 = '\x92\xa5\xe1\xe2'
777
        test_in_cp1251 = '\xd2\xe5\xf1\xf2'
778
        # Make sure the log string is encoded in cp866
779
        self.assertEquals(test_in_cp866, message[2:])
780
        # Make sure the cp1251 string is not found anywhere
781
        self.assertEquals(-1, stdout.find(test_in_cp1251))
782
1551.10.18 by Aaron Bentley
Log works in local treeless branches (#84247)
783
784
class TestLogFile(TestCaseWithTransport):
785
786
    def test_log_local_branch_file(self):
787
        """We should be able to log files in local treeless branches"""
788
        tree = self.make_branch_and_tree('tree')
789
        self.build_tree(['tree/file'])
790
        tree.add('file')
791
        tree.commit('revision 1')
792
        tree.bzrdir.destroy_workingtree()
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
793
        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.
794
3943.6.1 by Ian Clatworthy
find file using the end revision
795
    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
796
        # 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.
797
        tree = self.make_branch_and_tree('parent')
798
        self.build_tree(['parent/file1', 'parent/file2', 'parent/file3'])
799
        tree.add('file1')
800
        tree.commit('add file1')
801
        tree.add('file2')
802
        tree.commit('add file2')
803
        tree.add('file3')
804
        tree.commit('add file3')
2664.14.1 by Daniel Watkins
Fixed tests.blackbox.test_log to use internals where appropriate.
805
        child_tree = tree.bzrdir.sprout('child').open_workingtree()
806
        self.build_tree_contents([('child/file2', 'hello')])
807
        child_tree.commit(message='branch 1')
808
        tree.merge_from_branch(child_tree.branch)
809
        tree.commit(message='merge child branch')
3943.6.1 by Ian Clatworthy
find file using the end revision
810
        if complex:
3943.6.3 by Ian Clatworthy
search the start tree if the end tree doesn't have a file
811
            tree.remove('file2')
812
            tree.commit('remove file2')
813
            tree.rename_one('file3', 'file4')
814
            tree.commit('file3 is now called file4')
3943.6.1 by Ian Clatworthy
find file using the end revision
815
            tree.remove('file1')
3943.6.3 by Ian Clatworthy
search the start tree if the end tree doesn't have a file
816
            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.
817
        os.chdir('parent')
3940.1.2 by Ian Clatworthy
add test
818
819
    def test_log_file(self):
820
        """The log for a particular file should only list revs for that file"""
821
        self.prepare_tree()
2581.1.6 by Martin Pool
fix up more run_bzr callers
822
        log = self.run_bzr('log file1')[0]
2359.1.1 by Kent Gibson
Fix ``bzr log <file>`` so it only logs the revisions that changed the file, and does it faster.
823
        self.assertContainsRe(log, 'revno: 1\n')
824
        self.assertNotContainsRe(log, 'revno: 2\n')
825
        self.assertNotContainsRe(log, 'revno: 3\n')
826
        self.assertNotContainsRe(log, 'revno: 3.1.1\n')
827
        self.assertNotContainsRe(log, 'revno: 4\n')
2581.1.6 by Martin Pool
fix up more run_bzr callers
828
        log = self.run_bzr('log file2')[0]
2359.1.1 by Kent Gibson
Fix ``bzr log <file>`` so it only logs the revisions that changed the file, and does it faster.
829
        self.assertNotContainsRe(log, 'revno: 1\n')
830
        self.assertContainsRe(log, 'revno: 2\n')
831
        self.assertNotContainsRe(log, 'revno: 3\n')
832
        self.assertContainsRe(log, 'revno: 3.1.1\n')
2359.1.2 by Kent Gibson
add logging of merge revisions
833
        self.assertContainsRe(log, 'revno: 4\n')
2581.1.6 by Martin Pool
fix up more run_bzr callers
834
        log = self.run_bzr('log file3')[0]
2359.1.1 by Kent Gibson
Fix ``bzr log <file>`` so it only logs the revisions that changed the file, and does it faster.
835
        self.assertNotContainsRe(log, 'revno: 1\n')
836
        self.assertNotContainsRe(log, 'revno: 2\n')
837
        self.assertContainsRe(log, 'revno: 3\n')
838
        self.assertNotContainsRe(log, 'revno: 3.1.1\n')
839
        self.assertNotContainsRe(log, 'revno: 4\n')
2581.1.6 by Martin Pool
fix up more run_bzr callers
840
        log = self.run_bzr('log -r3.1.1 file2')[0]
2466.12.1 by Kent Gibson
Fix ``bzr log -r`` to support selecting merge revisions.
841
        self.assertNotContainsRe(log, 'revno: 1\n')
842
        self.assertNotContainsRe(log, 'revno: 2\n')
843
        self.assertNotContainsRe(log, 'revno: 3\n')
844
        self.assertContainsRe(log, 'revno: 3.1.1\n')
845
        self.assertNotContainsRe(log, 'revno: 4\n')
2581.1.6 by Martin Pool
fix up more run_bzr callers
846
        log = self.run_bzr('log -r4 file2')[0]
847
        self.assertNotContainsRe(log, 'revno: 1\n')
848
        self.assertNotContainsRe(log, 'revno: 2\n')
849
        self.assertNotContainsRe(log, 'revno: 3\n')
850
        self.assertContainsRe(log, 'revno: 3.1.1\n')
851
        self.assertContainsRe(log, 'revno: 4\n')
852
        log = self.run_bzr('log -r3.. file2')[0]
853
        self.assertNotContainsRe(log, 'revno: 1\n')
854
        self.assertNotContainsRe(log, 'revno: 2\n')
855
        self.assertNotContainsRe(log, 'revno: 3\n')
856
        self.assertContainsRe(log, 'revno: 3.1.1\n')
857
        self.assertContainsRe(log, 'revno: 4\n')
858
        log = self.run_bzr('log -r..3 file2')[0]
2466.12.1 by Kent Gibson
Fix ``bzr log -r`` to support selecting merge revisions.
859
        self.assertNotContainsRe(log, 'revno: 1\n')
860
        self.assertContainsRe(log, 'revno: 2\n')
861
        self.assertNotContainsRe(log, 'revno: 3\n')
862
        self.assertNotContainsRe(log, 'revno: 3.1.1\n')
863
        self.assertNotContainsRe(log, 'revno: 4\n')
3940.1.2 by Ian Clatworthy
add test
864
3943.6.4 by Ian Clatworthy
review feedback from vila
865
    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
866
        # Check logging a deleted file gives an error if the
867
        # file isn't found at the end or start of the revision range
3943.6.4 by Ian Clatworthy
review feedback from vila
868
        self.prepare_tree(complex=True)
3943.6.3 by Ian Clatworthy
search the start tree if the end tree doesn't have a file
869
        err_msg = "Path unknown at end or start of revision range: file2"
870
        err = self.run_bzr('log file2', retcode=3)[1]
3943.6.1 by Ian Clatworthy
find file using the end revision
871
        self.assertContainsRe(err, err_msg)
872
3943.6.4 by Ian Clatworthy
review feedback from vila
873
    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
874
        # Check logging a deleted file is ok if the file existed
875
        # at the end the revision range
3943.6.4 by Ian Clatworthy
review feedback from vila
876
        self.prepare_tree(complex=True)
3943.6.3 by Ian Clatworthy
search the start tree if the end tree doesn't have a file
877
        log, err = self.run_bzr('log -r..4 file2')
878
        self.assertEquals('', err)
879
        self.assertNotContainsRe(log, 'revno: 1\n')
880
        self.assertContainsRe(log, 'revno: 2\n')
881
        self.assertNotContainsRe(log, 'revno: 3\n')
882
        self.assertContainsRe(log, 'revno: 3.1.1\n')
883
        self.assertContainsRe(log, 'revno: 4\n')
884
3943.6.4 by Ian Clatworthy
review feedback from vila
885
    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
886
        # Check logging a deleted file is ok if the file existed
887
        # at the start of the revision range
3943.6.4 by Ian Clatworthy
review feedback from vila
888
        self.prepare_tree(complex=True)
3943.6.3 by Ian Clatworthy
search the start tree if the end tree doesn't have a file
889
        log, err = self.run_bzr('log file1')
890
        self.assertEquals('', err)
3943.6.1 by Ian Clatworthy
find file using the end revision
891
        self.assertContainsRe(log, 'revno: 1\n')
892
        self.assertNotContainsRe(log, 'revno: 2\n')
893
        self.assertNotContainsRe(log, 'revno: 3\n')
894
        self.assertNotContainsRe(log, 'revno: 3.1.1\n')
895
        self.assertNotContainsRe(log, 'revno: 4\n')
896
897
    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
898
        """File matched against revision range, not current tree."""
3943.6.1 by Ian Clatworthy
find file using the end revision
899
        self.prepare_tree(complex=True)
3943.6.3 by Ian Clatworthy
search the start tree if the end tree doesn't have a file
900
3943.6.1 by Ian Clatworthy
find file using the end revision
901
        # 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
902
        err_msg = "Path unknown at end or start of revision range: file3"
3943.6.1 by Ian Clatworthy
find file using the end revision
903
        err = self.run_bzr('log file3', retcode=3)[1]
904
        self.assertContainsRe(err, err_msg)
905
906
        # Check we can see a renamed file if we give the right end revision
3943.6.3 by Ian Clatworthy
search the start tree if the end tree doesn't have a file
907
        log, err = self.run_bzr('log -r..4 file3')
908
        self.assertEquals('', err)
3943.6.1 by Ian Clatworthy
find file using the end revision
909
        self.assertNotContainsRe(log, 'revno: 1\n')
910
        self.assertNotContainsRe(log, 'revno: 2\n')
911
        self.assertContainsRe(log, 'revno: 3\n')
912
        self.assertNotContainsRe(log, 'revno: 3.1.1\n')
913
        self.assertNotContainsRe(log, 'revno: 4\n')
914
3940.1.2 by Ian Clatworthy
add test
915
    def test_line_log_file(self):
916
        """The line log for a file should only list relevant mainline revs"""
917
        # Note: this also implicitly  covers the short logging case.
918
        # We test using --line in preference to --short because matching
919
        # revnos in the output of --line is more reliable.
920
        self.prepare_tree()
3940.1.5 by Ian Clatworthy
feedback from vila
921
922
        # full history of file1
3940.1.2 by Ian Clatworthy
add test
923
        log = self.run_bzr('log --line file1')[0]
924
        self.assertContainsRe(log, '^1:', re.MULTILINE)
925
        self.assertNotContainsRe(log, '^2:', re.MULTILINE)
926
        self.assertNotContainsRe(log, '^3:', re.MULTILINE)
927
        self.assertNotContainsRe(log, '^3.1.1:', re.MULTILINE)
928
        self.assertNotContainsRe(log, '^4:', re.MULTILINE)
3940.1.5 by Ian Clatworthy
feedback from vila
929
930
        # full history of file2
3940.1.2 by Ian Clatworthy
add test
931
        log = self.run_bzr('log --line file2')[0]
932
        self.assertNotContainsRe(log, '^1:', re.MULTILINE)
933
        self.assertContainsRe(log, '^2:', re.MULTILINE)
934
        self.assertNotContainsRe(log, '^3:', re.MULTILINE)
935
        self.assertNotContainsRe(log, '^3.1.1:', re.MULTILINE)
936
        self.assertContainsRe(log, '^4:', re.MULTILINE)
3940.1.5 by Ian Clatworthy
feedback from vila
937
938
        # full history of file3
3940.1.2 by Ian Clatworthy
add test
939
        log = self.run_bzr('log --line file3')[0]
940
        self.assertNotContainsRe(log, '^1:', re.MULTILINE)
941
        self.assertNotContainsRe(log, '^2:', re.MULTILINE)
942
        self.assertContainsRe(log, '^3:', re.MULTILINE)
943
        self.assertNotContainsRe(log, '^3.1.1:', re.MULTILINE)
944
        self.assertNotContainsRe(log, '^4:', re.MULTILINE)
3940.1.5 by Ian Clatworthy
feedback from vila
945
946
        # file in a merge revision
3940.1.2 by Ian Clatworthy
add test
947
        log = self.run_bzr('log --line -r3.1.1 file2')[0]
948
        self.assertNotContainsRe(log, '^1:', re.MULTILINE)
949
        self.assertNotContainsRe(log, '^2:', re.MULTILINE)
950
        self.assertNotContainsRe(log, '^3:', re.MULTILINE)
951
        self.assertContainsRe(log, '^3.1.1:', re.MULTILINE)
952
        self.assertNotContainsRe(log, '^4:', re.MULTILINE)
3940.1.5 by Ian Clatworthy
feedback from vila
953
954
        # file in a mainline revision
3940.1.2 by Ian Clatworthy
add test
955
        log = self.run_bzr('log --line -r4 file2')[0]
956
        self.assertNotContainsRe(log, '^1:', re.MULTILINE)
957
        self.assertNotContainsRe(log, '^2:', re.MULTILINE)
958
        self.assertNotContainsRe(log, '^3:', re.MULTILINE)
959
        self.assertNotContainsRe(log, '^3.1.1:', re.MULTILINE)
960
        self.assertContainsRe(log, '^4:', re.MULTILINE)
3940.1.5 by Ian Clatworthy
feedback from vila
961
962
        # file since a revision
3940.1.2 by Ian Clatworthy
add test
963
        log = self.run_bzr('log --line -r3.. file2')[0]
964
        self.assertNotContainsRe(log, '^1:', re.MULTILINE)
965
        self.assertNotContainsRe(log, '^2:', re.MULTILINE)
966
        self.assertNotContainsRe(log, '^3:', re.MULTILINE)
967
        self.assertNotContainsRe(log, '^3.1.1:', re.MULTILINE)
968
        self.assertContainsRe(log, '^4:', re.MULTILINE)
3940.1.5 by Ian Clatworthy
feedback from vila
969
970
        # file up to a revision
3940.1.2 by Ian Clatworthy
add test
971
        log = self.run_bzr('log --line -r..3 file2')[0]
972
        self.assertNotContainsRe(log, '^1:', re.MULTILINE)
973
        self.assertContainsRe(log, '^2:', re.MULTILINE)
974
        self.assertNotContainsRe(log, '^3:', re.MULTILINE)
975
        self.assertNotContainsRe(log, '^3.1.1:', re.MULTILINE)
976
        self.assertNotContainsRe(log, '^4:', re.MULTILINE)