~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/blackbox/test_log.py

  • Committer: Vincent Ladeuil
  • Date: 2009-05-05 15:31:34 UTC
  • mto: (4343.1.1 integration)
  • mto: This revision was merged to the branch mainline in revision 4344.
  • Revision ID: v.ladeuil+lp@free.fr-20090505153134-q4bp4is9gywsmzrv
Clean up test for log formats.

* bzrlib/tests/blackbox/test_logformats.py:
Update tests to actual style.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 
18
18
"""Black-box tests for bzr log."""
19
19
 
20
 
import os
21
 
import re
 
20
import os, re
22
21
 
23
 
from bzrlib import (
24
 
    osutils,
25
 
    tests,
 
22
from bzrlib import osutils
 
23
from bzrlib.tests.blackbox import ExternalBase
 
24
from bzrlib.tests import KnownFailure, TestCaseInTempDir, TestCaseWithTransport
 
25
from bzrlib.tests.test_log import (
 
26
    normalize_log,
26
27
    )
27
28
from bzrlib.tests import test_log
28
29
 
29
30
 
30
 
class TestLog(tests.TestCaseWithTransport):
31
 
 
32
 
    def setUp(self):
33
 
        super(TestLog, self).setUp()
34
 
        self.timezone = 0 # UTC
35
 
        self.timestamp = 1132617600 # Mon 2005-11-22 00:00:00 +0000
36
 
 
37
 
    def make_minimal_branch(self, path='.', format=None):
38
 
        tree = self.make_branch_and_tree(path, format=format)
39
 
        self.build_tree([path + '/hello.txt'])
40
 
        tree.add('hello.txt')
41
 
        tree.commit(message='message1')
42
 
        return tree
43
 
 
44
 
    def make_linear_branch(self, path='.', format=None):
 
31
class TestCaseWithoutPropsHandler(ExternalBase,
 
32
                                  test_log.TestCaseWithoutPropsHandler):
 
33
    pass
 
34
 
 
35
 
 
36
class TestLog(ExternalBase):
 
37
 
 
38
    def _prepare(self, path='.', format=None):
45
39
        tree = self.make_branch_and_tree(path, format=format)
46
40
        self.build_tree(
47
41
            [path + '/hello.txt', path + '/goodbye.txt', path + '/meep.txt'])
51
45
        tree.commit(message='message2')
52
46
        tree.add('meep.txt')
53
47
        tree.commit(message='message3')
54
 
        return tree
55
 
 
56
 
    def make_merged_branch(self, path='.', format=None):
57
 
        tree = self.make_linear_branch(path, format)
58
 
        tree2 = tree.bzrdir.sprout('tree2',
59
 
            revision_id=tree.branch.get_rev_id(1)).open_workingtree()
60
 
        tree2.commit(message='tree2 message2')
61
 
        tree2.commit(message='tree2 message3')
62
 
        tree.merge_from_branch(tree2.branch)
63
 
        tree.commit(message='merge')
64
 
        return tree
65
 
 
66
 
    def assertRevnos(self, log, must_have=(), must_not_have=()):
67
 
        """Check if revnos are in or not in the log output"""
68
 
        for revno in must_have:
69
 
            self.assertTrue(('revno: %s\n' % revno) in log,
70
 
                'Does not contain expected revno %s' % revno)
71
 
        for revno in must_not_have:
72
 
            self.assertFalse(('revno: %s\n' % revno) in log,
73
 
                'Contains unexpected revno %s' % revno)
74
 
 
75
 
    def commit_options(self):
76
 
        """Use some mostly fixed values for commits to simplify tests.
77
 
 
78
 
        Tests can use this function to get some commit attributes. The time
79
 
        stamp is incremented at each commit.
80
 
        """
81
 
        self.timestamp += 1 # 1 second between each commit
82
 
        return dict(committer='Lorem Ipsum <joe@foo.com>',
83
 
                 timezone=self.timezone,
84
 
                 timestamp=self.timestamp,
85
 
                 )
86
 
 
87
 
    def check_log(self, expected, args, working_dir='level0'):
88
 
        out, err = self.run_bzr(['log', '--timezone', 'utc'] + args,
89
 
                                working_dir=working_dir)
90
 
        self.assertEqual('', err)
91
 
        self.assertEqualDiff(expected, test_log.normalize_log(out))
92
 
 
93
 
 
94
 
class TestLogRevSpecs(TestLog):
 
48
        self.full_log = self.run_bzr(["log", path])[0]
 
49
        return tree
95
50
 
96
51
    def test_log_null_end_revspec(self):
97
 
        self.make_linear_branch()
98
 
        log = self.run_bzr(['log'])[0]
99
 
        self.assertTrue('revno: 1\n' in log)
100
 
        self.assertTrue('revno: 2\n' in log)
101
 
        self.assertTrue('revno: 3\n' in log)
102
 
        self.assertTrue('message:\n  message1\n' in log)
103
 
        self.assertTrue('message:\n  message2\n' in log)
104
 
        self.assertTrue('message:\n  message3\n' in log)
 
52
        self._prepare()
 
53
        self.assertTrue('revno: 1\n' in self.full_log)
 
54
        self.assertTrue('revno: 2\n' in self.full_log)
 
55
        self.assertTrue('revno: 3\n' in self.full_log)
 
56
        self.assertTrue('message:\n  message1\n' in self.full_log)
 
57
        self.assertTrue('message:\n  message2\n' in self.full_log)
 
58
        self.assertTrue('message:\n  message3\n' in self.full_log)
105
59
 
106
 
        full_log = self.run_bzr(['log'])[0]
107
60
        log = self.run_bzr("log -r 1..")[0]
108
 
        self.assertEqualDiff(log, full_log)
 
61
        self.assertEqualDiff(log, self.full_log)
109
62
 
110
63
    def test_log_null_begin_revspec(self):
111
 
        self.make_linear_branch()
112
 
        full_log = self.run_bzr(['log'])[0]
 
64
        self._prepare()
113
65
        log = self.run_bzr("log -r ..3")[0]
114
 
        self.assertEqualDiff(full_log, log)
 
66
        self.assertEqualDiff(self.full_log, log)
115
67
 
116
68
    def test_log_null_both_revspecs(self):
117
 
        self.make_linear_branch()
118
 
        full_log = self.run_bzr(['log'])[0]
 
69
        self._prepare()
119
70
        log = self.run_bzr("log -r ..")[0]
120
 
        self.assertEqualDiff(full_log, log)
 
71
        self.assertEqualDiff(self.full_log, log)
121
72
 
122
73
    def test_log_zero_revspec(self):
123
 
        self.make_minimal_branch()
124
 
        self.run_bzr_error(['bzr: ERROR: Logging revision 0 is invalid.'],
 
74
        self._prepare()
 
75
        self.run_bzr_error('bzr: ERROR: Logging revision 0 is invalid.',
125
76
                           ['log', '-r0'])
126
77
 
127
78
    def test_log_zero_begin_revspec(self):
128
 
        self.make_linear_branch()
129
 
        self.run_bzr_error(['bzr: ERROR: Logging revision 0 is invalid.'],
 
79
        self._prepare()
 
80
        self.run_bzr_error('bzr: ERROR: Logging revision 0 is invalid.',
130
81
                           ['log', '-r0..2'])
131
82
 
132
83
    def test_log_zero_end_revspec(self):
133
 
        self.make_linear_branch()
134
 
        self.run_bzr_error(['bzr: ERROR: Logging revision 0 is invalid.'],
 
84
        self._prepare()
 
85
        self.run_bzr_error('bzr: ERROR: Logging revision 0 is invalid.',
135
86
                           ['log', '-r-2..0'])
136
87
 
 
88
    def test_log_unsupported_timezone(self):
 
89
        self._prepare()
 
90
        self.run_bzr_error('bzr: ERROR: Unsupported timezone format "foo", '
 
91
                           'options are "utc", "original", "local".',
 
92
                           ['log', '--timezone', 'foo'])
 
93
 
137
94
    def test_log_negative_begin_revspec_full_log(self):
138
 
        self.make_linear_branch()
139
 
        full_log = self.run_bzr(['log'])[0]
 
95
        self._prepare()
140
96
        log = self.run_bzr("log -r -3..")[0]
141
 
        self.assertEqualDiff(full_log, log)
 
97
        self.assertEqualDiff(self.full_log, log)
142
98
 
143
99
    def test_log_negative_both_revspec_full_log(self):
144
 
        self.make_linear_branch()
145
 
        full_log = self.run_bzr(['log'])[0]
 
100
        self._prepare()
146
101
        log = self.run_bzr("log -r -3..-1")[0]
147
 
        self.assertEqualDiff(full_log, log)
 
102
        self.assertEqualDiff(self.full_log, log)
148
103
 
149
104
    def test_log_negative_both_revspec_partial(self):
150
 
        self.make_linear_branch()
 
105
        self._prepare()
151
106
        log = self.run_bzr("log -r -3..-2")[0]
152
107
        self.assertTrue('revno: 1\n' in log)
153
108
        self.assertTrue('revno: 2\n' in log)
154
109
        self.assertTrue('revno: 3\n' not in log)
155
110
 
156
111
    def test_log_negative_begin_revspec(self):
157
 
        self.make_linear_branch()
 
112
        self._prepare()
158
113
        log = self.run_bzr("log -r -2..")[0]
159
114
        self.assertTrue('revno: 1\n' not in log)
160
115
        self.assertTrue('revno: 2\n' in log)
161
116
        self.assertTrue('revno: 3\n' in log)
162
117
 
163
118
    def test_log_positive_revspecs(self):
164
 
        self.make_linear_branch()
165
 
        full_log = self.run_bzr(['log'])[0]
 
119
        self._prepare()
166
120
        log = self.run_bzr("log -r 1..3")[0]
167
 
        self.assertEqualDiff(full_log, log)
168
 
 
169
 
    def test_log_dotted_revspecs(self):
170
 
        self.make_merged_branch()
171
 
        log = self.run_bzr("log -n0 -r 1..1.1.1")[0]
172
 
        self.assertRevnos(log, (1, '1.1.1'), (2, 3, '1.1.2', 4))
 
121
        self.assertEqualDiff(self.full_log, log)
173
122
 
174
123
    def test_log_reversed_revspecs(self):
175
 
        self.make_linear_branch()
 
124
        self._prepare()
176
125
        self.run_bzr_error(('bzr: ERROR: Start revision must be older than '
177
126
                            'the end revision.\n',),
178
127
                           ['log', '-r3..1'])
179
128
 
180
 
    def test_log_reversed_dotted_revspecs(self):
181
 
        self.make_merged_branch()
182
 
        self.run_bzr_error(('bzr: ERROR: Start revision not found in '
183
 
                            'left-hand history of end revision.\n',),
184
 
                           "log -r 1.1.1..1")
185
 
 
186
129
    def test_log_revno_n_path(self):
187
 
        self.make_linear_branch('branch1')
188
 
        self.make_linear_branch('branch2')
189
 
        # Swapped revisions
190
 
        self.run_bzr("log -r revno:2:branch1..revno:3:branch2", retcode=3)[0]
191
 
        # Correct order
 
130
        self._prepare(path='branch1')
 
131
        self._prepare(path='branch2')
 
132
        log = self.run_bzr("log -r revno:2:branch1..revno:3:branch2",
 
133
                          retcode=3)[0]
192
134
        log = self.run_bzr("log -r revno:1:branch2..revno:3:branch2")[0]
193
 
        full_log = self.run_bzr(['log'], working_dir='branch2')[0]
194
 
        self.assertEqualDiff(full_log, log)
 
135
        self.assertEqualDiff(self.full_log, log)
195
136
        log = self.run_bzr("log -r revno:1:branch2")[0]
196
137
        self.assertTrue('revno: 1\n' in log)
197
138
        self.assertTrue('revno: 2\n' not in log)
199
140
        self.assertTrue('branch nick: branch1\n' not in log)
200
141
 
201
142
    def test_log_nonexistent_revno(self):
202
 
        self.make_minimal_branch()
203
 
        (out, err) = self.run_bzr_error(
204
 
            ["bzr: ERROR: Requested revision: '1234' "
205
 
             "does not exist in branch:"],
206
 
            ['log', '-r1234'])
 
143
        self._prepare()
 
144
        (out, err) = self.run_bzr_error(args="log -r 1234",
 
145
            error_regexes=["bzr: ERROR: Requested revision: '1234' "
 
146
                "does not exist in branch:"])
207
147
 
208
148
    def test_log_nonexistent_dotted_revno(self):
209
 
        self.make_minimal_branch()
210
 
        (out, err) = self.run_bzr_error(
211
 
            ["bzr: ERROR: Requested revision: '123.123' "
212
 
             "does not exist in branch:"],
213
 
            ['log',  '-r123.123'])
 
149
        self._prepare()
 
150
        (out, err) = self.run_bzr_error(args="log -r 123.123",
 
151
            error_regexes=["bzr: ERROR: Requested revision: '123.123' "
 
152
                "does not exist in branch:"])
214
153
 
215
154
    def test_log_change_revno(self):
216
 
        self.make_linear_branch()
 
155
        self._prepare()
217
156
        expected_log = self.run_bzr("log -r 1")[0]
218
157
        log = self.run_bzr("log -c 1")[0]
219
158
        self.assertEqualDiff(expected_log, log)
220
159
 
221
160
    def test_log_change_nonexistent_revno(self):
222
 
        self.make_minimal_branch()
223
 
        (out, err) = self.run_bzr_error(
224
 
            ["bzr: ERROR: Requested revision: '1234' "
225
 
             "does not exist in branch:"],
226
 
            ['log',  '-c1234'])
 
161
        self._prepare()
 
162
        (out, err) = self.run_bzr_error(args="log -c 1234",
 
163
            error_regexes=["bzr: ERROR: Requested revision: '1234' "
 
164
                "does not exist in branch:"])
227
165
 
228
166
    def test_log_change_nonexistent_dotted_revno(self):
229
 
        self.make_minimal_branch()
230
 
        (out, err) = self.run_bzr_error(
231
 
            ["bzr: ERROR: Requested revision: '123.123' "
232
 
             "does not exist in branch:"],
233
 
            ['log', '-c123.123'])
 
167
        self._prepare()
 
168
        (out, err) = self.run_bzr_error(args="log -c 123.123",
 
169
            error_regexes=["bzr: ERROR: Requested revision: '123.123' "
 
170
                "does not exist in branch:"])
234
171
 
235
 
    def test_log_change_single_revno_only(self):
236
 
        self.make_minimal_branch()
237
 
        self.run_bzr_error(['bzr: ERROR: Option --change does not'
238
 
                           ' accept revision ranges'],
 
172
    def test_log_change_single_revno(self):
 
173
        self._prepare()
 
174
        self.run_bzr_error('bzr: ERROR: Option --change does not'
 
175
                           ' accept revision ranges',
239
176
                           ['log', '--change', '2..3'])
240
177
 
241
178
    def test_log_change_incompatible_with_revision(self):
242
 
        self.run_bzr_error(['bzr: ERROR: --revision and --change'
243
 
                           ' are mutually exclusive'],
 
179
        self._prepare()
 
180
        self.run_bzr_error('bzr: ERROR: --revision and --change'
 
181
                           ' are mutually exclusive',
244
182
                           ['log', '--change', '2', '--revision', '3'])
245
183
 
246
184
    def test_log_nonexistent_file(self):
247
 
        self.make_minimal_branch()
248
185
        # files that don't exist in either the basis tree or working tree
249
186
        # should give an error
 
187
        wt = self.make_branch_and_tree('.')
250
188
        out, err = self.run_bzr('log does-not-exist', retcode=3)
251
 
        self.assertContainsRe(err,
252
 
                              'Path unknown at end or start of revision range: '
253
 
                              'does-not-exist')
 
189
        self.assertContainsRe(
 
190
            err, 'Path unknown at end or start of revision range: does-not-exist')
254
191
 
255
192
    def test_log_with_tags(self):
256
 
        tree = self.make_linear_branch(format='dirstate-tags')
 
193
        tree = self._prepare(format='dirstate-tags')
257
194
        branch = tree.branch
258
195
        branch.tags.set_tag('tag1', branch.get_rev_id(1))
259
196
        branch.tags.set_tag('tag1.1', branch.get_rev_id(1))
268
205
        self.assertContainsRe(log, r'tags: (tag1, tag1\.1|tag1\.1, tag1)')
269
206
 
270
207
    def test_merged_log_with_tags(self):
271
 
        branch1_tree = self.make_linear_branch('branch1',
272
 
                                               format='dirstate-tags')
 
208
        branch1_tree = self._prepare(path='branch1', format='dirstate-tags')
273
209
        branch1 = branch1_tree.branch
274
210
        branch2_tree = branch1_tree.bzrdir.sprout('branch2').open_workingtree()
275
211
        branch1_tree.commit(message='foobar', allow_pointless=True)
276
212
        branch1.tags.set_tag('tag1', branch1.last_revision())
277
 
        # tags don't propagate if we don't merge
278
 
        self.run_bzr('merge ../branch1', working_dir='branch2')
 
213
        os.chdir('branch2')
 
214
        self.run_bzr('merge ../branch1') # tags don't propagate otherwise
279
215
        branch2_tree.commit(message='merge branch 1')
280
 
        log = self.run_bzr("log -n0 -r-1", working_dir='branch2')[0]
 
216
        log = self.run_bzr("log -n0 -r-1")[0]
281
217
        self.assertContainsRe(log, r'    tags: tag1')
282
 
        log = self.run_bzr("log -n0 -r3.1.1", working_dir='branch2')[0]
 
218
        log = self.run_bzr("log -n0 -r3.1.1")[0]
283
219
        self.assertContainsRe(log, r'tags: tag1')
284
220
 
285
221
    def test_log_limit(self):
300
236
        self.assertContainsRe(log, r'revno: 10\n')
301
237
 
302
238
    def test_log_limit_short(self):
303
 
        self.make_linear_branch()
 
239
        self._prepare()
304
240
        log = self.run_bzr("log -l 2")[0]
305
241
        self.assertNotContainsRe(log, r'revno: 1\n')
306
242
        self.assertContainsRe(log, r'revno: 2\n')
311
247
        
312
248
        See https://bugs.launchpad.net/bzr/+bug/251352
313
249
        """
314
 
        self.make_minimal_branch()
 
250
        self._prepare()
315
251
        out, err = self.run_bzr(['log', '-m', '*'], retcode=3)
316
252
        self.assertEqual("bzr: ERROR: Invalid regular expression"
317
253
            " in log message filter"
320
256
        self.assertEqual('', out)
321
257
 
322
258
 
323
 
class TestLogTimeZone(TestLog):
324
 
 
325
 
    def test_log_unsupported_timezone(self):
326
 
        self.make_linear_branch()
327
 
        self.run_bzr_error(['bzr: ERROR: Unsupported timezone format "foo", '
328
 
                            'options are "utc", "original", "local".'],
329
 
                           ['log', '--timezone', 'foo'])
330
 
 
331
 
 
332
 
class TestLogVerbose(TestLog):
 
259
class TestLogVerbose(TestCaseWithTransport):
333
260
 
334
261
    def setUp(self):
335
262
        super(TestLogVerbose, self).setUp()
336
 
        self.make_minimal_branch()
 
263
        tree = self.make_branch_and_tree('.')
 
264
        self.build_tree(['hello.txt'])
 
265
        tree.add('hello.txt')
 
266
        tree.commit(message='message1')
337
267
 
338
268
    def assertUseShortDeltaFormat(self, cmd):
339
269
        log = self.run_bzr(cmd)[0]
364
294
        self.assertUseLongDeltaFormat(['log', '--long', '-vv'])
365
295
 
366
296
 
367
 
class TestLogMerges(TestLog):
368
 
 
369
 
    def setUp(self):
370
 
        super(TestLogMerges, self).setUp()
371
 
        self.make_branches_with_merges()
372
 
 
373
 
    def make_branches_with_merges(self):
374
 
        level0 = self.make_branch_and_tree('level0')
375
 
        level0.commit(message='in branch level0', **self.commit_options())
376
 
 
377
 
        level1 = level0.bzrdir.sprout('level1').open_workingtree()
378
 
        level1.commit(message='in branch level1', **self.commit_options())
379
 
 
380
 
        level2 = level1.bzrdir.sprout('level2').open_workingtree()
381
 
        level2.commit(message='in branch level2', **self.commit_options())
382
 
 
383
 
        level1.merge_from_branch(level2.branch)
384
 
        level1.commit(message='merge branch level2', **self.commit_options())
385
 
 
386
 
        level0.merge_from_branch(level1.branch)
387
 
        level0.commit(message='merge branch level1', **self.commit_options())
 
297
class TestLogMerges(TestCaseWithoutPropsHandler):
 
298
 
 
299
    def _prepare(self):
 
300
        parent_tree = self.make_branch_and_tree('parent')
 
301
        parent_tree.commit(message='first post', allow_pointless=True)
 
302
        child_tree = parent_tree.bzrdir.sprout('child').open_workingtree()
 
303
        child_tree.commit(message='branch 1', allow_pointless=True)
 
304
        smaller_tree = \
 
305
                child_tree.bzrdir.sprout('smallerchild').open_workingtree()
 
306
        smaller_tree.commit(message='branch 2', allow_pointless=True)
 
307
        child_tree.merge_from_branch(smaller_tree.branch)
 
308
        child_tree.commit(message='merge branch 2')
 
309
        parent_tree.merge_from_branch(child_tree.branch)
 
310
        parent_tree.commit(message='merge branch 1')
 
311
        os.chdir('parent')
 
312
 
 
313
    def _prepare_short(self):
 
314
        parent_tree = self.make_branch_and_tree('parent')
 
315
        parent_tree.commit(message='first post',
 
316
            timestamp=1132586700, timezone=36000,
 
317
            committer='Joe Foo <joe@foo.com>')
 
318
        child_tree = parent_tree.bzrdir.sprout('child').open_workingtree()
 
319
        child_tree.commit(message='branch 1',
 
320
            timestamp=1132586800, timezone=36000,
 
321
            committer='Joe Foo <joe@foo.com>')
 
322
        smaller_tree = \
 
323
                child_tree.bzrdir.sprout('smallerchild').open_workingtree()
 
324
        smaller_tree.commit(message='branch 2',
 
325
            timestamp=1132586900, timezone=36000,
 
326
            committer='Joe Foo <joe@foo.com>')
 
327
        child_tree.merge_from_branch(smaller_tree.branch)
 
328
        child_tree.commit(message='merge branch 2',
 
329
            timestamp=1132587000, timezone=36000,
 
330
            committer='Joe Foo <joe@foo.com>')
 
331
        parent_tree.merge_from_branch(child_tree.branch)
 
332
        parent_tree.commit(message='merge branch 1',
 
333
            timestamp=1132587100, timezone=36000,
 
334
            committer='Joe Foo <joe@foo.com>')
 
335
        os.chdir('parent')
388
336
 
389
337
    def test_merges_are_indented_by_level(self):
390
 
        expected = """\
 
338
        self._prepare()
 
339
        out,err = self.run_bzr('log -n0')
 
340
        self.assertEqual('', err)
 
341
        log = normalize_log(out)
 
342
        self.assertEqualDiff(log, """\
391
343
------------------------------------------------------------
392
344
revno: 2 [merge]
393
345
committer: Lorem Ipsum <test@example.com>
394
 
branch nick: level0
 
346
branch nick: parent
395
347
timestamp: Just now
396
348
message:
397
 
  merge branch level1
 
349
  merge branch 1
398
350
    ------------------------------------------------------------
399
351
    revno: 1.1.2 [merge]
400
352
    committer: Lorem Ipsum <test@example.com>
401
 
    branch nick: level1
 
353
    branch nick: child
402
354
    timestamp: Just now
403
355
    message:
404
 
      merge branch level2
 
356
      merge branch 2
405
357
        ------------------------------------------------------------
406
358
        revno: 1.2.1
407
359
        committer: Lorem Ipsum <test@example.com>
408
 
        branch nick: level2
 
360
        branch nick: smallerchild
409
361
        timestamp: Just now
410
362
        message:
411
 
          in branch level2
 
363
          branch 2
412
364
    ------------------------------------------------------------
413
365
    revno: 1.1.1
414
366
    committer: Lorem Ipsum <test@example.com>
415
 
    branch nick: level1
 
367
    branch nick: child
416
368
    timestamp: Just now
417
369
    message:
418
 
      in branch level1
 
370
      branch 1
419
371
------------------------------------------------------------
420
372
revno: 1
421
373
committer: Lorem Ipsum <test@example.com>
422
 
branch nick: level0
 
374
branch nick: parent
423
375
timestamp: Just now
424
376
message:
425
 
  in branch level0
426
 
"""
427
 
        self.check_log(expected, ['-n0'])
 
377
  first post
 
378
""")
428
379
 
429
380
    def test_force_merge_revisions_off(self):
430
 
        expected = """\
 
381
        self._prepare()
 
382
        out,err = self.run_bzr('log --long -n1')
 
383
        self.assertEqual('', err)
 
384
        log = normalize_log(out)
 
385
        self.assertEqualDiff(log, """\
431
386
------------------------------------------------------------
432
387
revno: 2 [merge]
433
388
committer: Lorem Ipsum <test@example.com>
434
 
branch nick: level0
 
389
branch nick: parent
435
390
timestamp: Just now
436
391
message:
437
 
  merge branch level1
 
392
  merge branch 1
438
393
------------------------------------------------------------
439
394
revno: 1
440
395
committer: Lorem Ipsum <test@example.com>
441
 
branch nick: level0
 
396
branch nick: parent
442
397
timestamp: Just now
443
398
message:
444
 
  in branch level0
445
 
"""
446
 
        self.check_log(expected, ['--long', '-n1'])
 
399
  first post
 
400
""")
447
401
 
448
402
    def test_force_merge_revisions_on(self):
449
 
        expected = """\
450
 
    2 Lorem Ipsum\t2005-11-22 [merge]
451
 
      merge branch level1
452
 
 
453
 
          1.1.2 Lorem Ipsum\t2005-11-22 [merge]
454
 
                merge branch level2
455
 
 
456
 
              1.2.1 Lorem Ipsum\t2005-11-22
457
 
                    in branch level2
458
 
 
459
 
          1.1.1 Lorem Ipsum\t2005-11-22
460
 
                in branch level1
461
 
 
462
 
    1 Lorem Ipsum\t2005-11-22
463
 
      in branch level0
464
 
 
465
 
"""
466
 
        self.check_log(expected, ['--short', '-n0'])
 
403
        self._prepare_short()
 
404
        out,err = self.run_bzr('log --short -n0')
 
405
        self.assertEqual('', err)
 
406
        log = normalize_log(out)
 
407
        self.assertEqualDiff(log, """\
 
408
    2 Joe Foo\t2005-11-22 [merge]
 
409
      merge branch 1
 
410
 
 
411
          1.1.2 Joe Foo\t2005-11-22 [merge]
 
412
                merge branch 2
 
413
 
 
414
              1.2.1 Joe Foo\t2005-11-22
 
415
                    branch 2
 
416
 
 
417
          1.1.1 Joe Foo\t2005-11-22
 
418
                branch 1
 
419
 
 
420
    1 Joe Foo\t2005-11-22
 
421
      first post
 
422
 
 
423
""")
467
424
 
468
425
    def test_include_merges(self):
469
426
        # Confirm --include-merges gives the same output as -n0
470
 
        out_im, err_im = self.run_bzr('log --include-merges',
471
 
                                      working_dir='level0')
472
 
        out_n0, err_n0 = self.run_bzr('log -n0', working_dir='level0')
473
 
        self.assertEqual('', err_im)
474
 
        self.assertEqual('', err_n0)
 
427
        self._prepare_short()
 
428
        out_im, err_im = self.run_bzr('log --include-merges')
 
429
        out_n0, err_n0 = self.run_bzr('log -n0')
 
430
        self.assertEqual(err_im, err_n0)
475
431
        self.assertEqual(out_im, out_n0)
476
432
 
477
433
    def test_force_merge_revisions_N(self):
478
 
        expected = """\
479
 
    2 Lorem Ipsum\t2005-11-22 [merge]
480
 
      merge branch level1
481
 
 
482
 
          1.1.2 Lorem Ipsum\t2005-11-22 [merge]
483
 
                merge branch level2
484
 
 
485
 
          1.1.1 Lorem Ipsum\t2005-11-22
486
 
                in branch level1
487
 
 
488
 
    1 Lorem Ipsum\t2005-11-22
489
 
      in branch level0
490
 
 
491
 
"""
492
 
        self.check_log(expected, ['--short', '-n2'])
 
434
        self._prepare_short()
 
435
        out,err = self.run_bzr('log --short -n2')
 
436
        self.assertEqual('', err)
 
437
        log = normalize_log(out)
 
438
        self.assertEqualDiff(log, """\
 
439
    2 Joe Foo\t2005-11-22 [merge]
 
440
      merge branch 1
 
441
 
 
442
          1.1.2 Joe Foo\t2005-11-22 [merge]
 
443
                merge branch 2
 
444
 
 
445
          1.1.1 Joe Foo\t2005-11-22
 
446
                branch 1
 
447
 
 
448
    1 Joe Foo\t2005-11-22
 
449
      first post
 
450
 
 
451
""")
493
452
 
494
453
    def test_merges_single_merge_rev(self):
495
 
        expected = """\
 
454
        self._prepare()
 
455
        out,err = self.run_bzr('log -n0 -r1.1.2')
 
456
        self.assertEqual('', err)
 
457
        log = normalize_log(out)
 
458
        self.assertEqualDiff(log, """\
496
459
------------------------------------------------------------
497
460
revno: 1.1.2 [merge]
498
461
committer: Lorem Ipsum <test@example.com>
499
 
branch nick: level1
 
462
branch nick: child
500
463
timestamp: Just now
501
464
message:
502
 
  merge branch level2
 
465
  merge branch 2
503
466
    ------------------------------------------------------------
504
467
    revno: 1.2.1
505
468
    committer: Lorem Ipsum <test@example.com>
506
 
    branch nick: level2
 
469
    branch nick: smallerchild
507
470
    timestamp: Just now
508
471
    message:
509
 
      in branch level2
510
 
"""
511
 
        self.check_log(expected, ['-n0', '-r1.1.2'])
 
472
      branch 2
 
473
""")
512
474
 
513
475
    def test_merges_partial_range(self):
514
 
        expected = """\
 
476
        self._prepare()
 
477
        out, err = self.run_bzr('log -n0 -r1.1.1..1.1.2')
 
478
        self.assertEqual('', err)
 
479
        log = normalize_log(out)
 
480
        self.assertEqualDiff(log, """\
515
481
------------------------------------------------------------
516
482
revno: 1.1.2 [merge]
517
483
committer: Lorem Ipsum <test@example.com>
518
 
branch nick: level1
 
484
branch nick: child
519
485
timestamp: Just now
520
486
message:
521
 
  merge branch level2
 
487
  merge branch 2
522
488
    ------------------------------------------------------------
523
489
    revno: 1.2.1
524
490
    committer: Lorem Ipsum <test@example.com>
525
 
    branch nick: level2
 
491
    branch nick: smallerchild
526
492
    timestamp: Just now
527
493
    message:
528
 
      in branch level2
 
494
      branch 2
529
495
------------------------------------------------------------
530
496
revno: 1.1.1
531
497
committer: Lorem Ipsum <test@example.com>
532
 
branch nick: level1
 
498
branch nick: child
533
499
timestamp: Just now
534
500
message:
535
 
  in branch level1
536
 
"""
537
 
        self.check_log(expected, ['-n0', '-r1.1.1..1.1.2'])
538
 
 
539
 
 
540
 
class TestLogDiff(TestLog):
541
 
 
542
 
    def setUp(self):
543
 
        super(TestLogDiff, self).setUp()
544
 
        self.make_branch_with_diffs()
545
 
 
546
 
    def make_branch_with_diffs(self):
547
 
        level0 = self.make_branch_and_tree('level0')
548
 
        self.build_tree(['level0/file1', 'level0/file2'])
549
 
        level0.add('file1')
550
 
        level0.add('file2')
551
 
        level0.commit(message='in branch level0', **self.commit_options())
552
 
 
553
 
        level1 = level0.bzrdir.sprout('level1').open_workingtree()
554
 
        self.build_tree_contents([('level1/file2', 'hello\n')])
555
 
        level1.commit(message='in branch level1', **self.commit_options())
556
 
        level0.merge_from_branch(level1.branch)
557
 
        level0.commit(message='merge branch level1', **self.commit_options())
 
501
  branch 1
 
502
""")
 
503
 
 
504
 
 
505
def subst_dates(string):
 
506
    """Replace date strings with constant values."""
 
507
    return re.sub(r'\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} [-\+]\d{4}',
 
508
                  'YYYY-MM-DD HH:MM:SS +ZZZZ', string)
 
509
 
 
510
 
 
511
class TestLogDiff(TestCaseWithoutPropsHandler):
 
512
 
 
513
    def _prepare(self):
 
514
        parent_tree = self.make_branch_and_tree('parent')
 
515
        self.build_tree(['parent/file1', 'parent/file2'])
 
516
        parent_tree.add('file1')
 
517
        parent_tree.add('file2')
 
518
        parent_tree.commit(message='first post',
 
519
            timestamp=1132586655, timezone=36000,
 
520
            committer='Lorem Ipsum <test@example.com>')
 
521
        child_tree = parent_tree.bzrdir.sprout('child').open_workingtree()
 
522
        self.build_tree_contents([('child/file2', 'hello\n')])
 
523
        child_tree.commit(message='branch 1',
 
524
            timestamp=1132586700, timezone=36000,
 
525
            committer='Lorem Ipsum <test@example.com>')
 
526
        parent_tree.merge_from_branch(child_tree.branch)
 
527
        parent_tree.commit(message='merge branch 1',
 
528
            timestamp=1132586800, timezone=36000,
 
529
            committer='Lorem Ipsum <test@example.com>')
 
530
        os.chdir('parent')
558
531
 
559
532
    def test_log_show_diff_long_with_merges(self):
 
533
        self._prepare()
560
534
        out,err = self.run_bzr('log -p -n0')
561
535
        self.assertEqual('', err)
562
 
        log = test_log.normalize_log(out)
563
 
        expected = """\
 
536
        log = normalize_log(out)
 
537
        self.assertEqualDiff(subst_dates(log), """\
564
538
------------------------------------------------------------
565
539
revno: 2 [merge]
566
540
committer: Lorem Ipsum <test@example.com>
567
 
branch nick: level0
 
541
branch nick: parent
568
542
timestamp: Just now
569
543
message:
570
 
  merge branch level1
 
544
  merge branch 1
571
545
diff:
572
546
=== modified file 'file2'
573
 
--- file2\t2005-11-22 00:00:01 +0000
574
 
+++ file2\t2005-11-22 00:00:02 +0000
 
547
--- file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
 
548
+++ file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
575
549
@@ -1,1 +1,1 @@
576
 
-contents of level0/file2
 
550
-contents of parent/file2
577
551
+hello
578
552
    ------------------------------------------------------------
579
553
    revno: 1.1.1
580
554
    committer: Lorem Ipsum <test@example.com>
581
 
    branch nick: level1
 
555
    branch nick: child
582
556
    timestamp: Just now
583
557
    message:
584
 
      in branch level1
 
558
      branch 1
585
559
    diff:
586
560
    === modified file 'file2'
587
 
    --- file2\t2005-11-22 00:00:01 +0000
588
 
    +++ file2\t2005-11-22 00:00:02 +0000
 
561
    --- file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
 
562
    +++ file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
589
563
    @@ -1,1 +1,1 @@
590
 
    -contents of level0/file2
 
564
    -contents of parent/file2
591
565
    +hello
592
566
------------------------------------------------------------
593
567
revno: 1
594
568
committer: Lorem Ipsum <test@example.com>
595
 
branch nick: level0
 
569
branch nick: parent
596
570
timestamp: Just now
597
571
message:
598
 
  in branch level0
 
572
  first post
599
573
diff:
600
574
=== added file 'file1'
601
 
--- file1\t1970-01-01 00:00:00 +0000
602
 
+++ file1\t2005-11-22 00:00:01 +0000
 
575
--- file1\tYYYY-MM-DD HH:MM:SS +ZZZZ
 
576
+++ file1\tYYYY-MM-DD HH:MM:SS +ZZZZ
603
577
@@ -0,0 +1,1 @@
604
 
+contents of level0/file1
 
578
+contents of parent/file1
605
579
 
606
580
=== added file 'file2'
607
 
--- file2\t1970-01-01 00:00:00 +0000
608
 
+++ file2\t2005-11-22 00:00:01 +0000
 
581
--- file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
 
582
+++ file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
609
583
@@ -0,0 +1,1 @@
610
 
+contents of level0/file2
611
 
"""
612
 
        self.check_log(expected, ['-p', '-n0'])
 
584
+contents of parent/file2
 
585
""")
613
586
 
614
587
    def test_log_show_diff_short(self):
615
 
        expected = """\
 
588
        self._prepare()
 
589
        out,err = self.run_bzr('log -p --short')
 
590
        self.assertEqual('', err)
 
591
        log = normalize_log(out)
 
592
        self.assertEqualDiff(subst_dates(log), """\
616
593
    2 Lorem Ipsum\t2005-11-22 [merge]
617
 
      merge branch level1
 
594
      merge branch 1
618
595
      === modified file 'file2'
619
 
      --- file2\t2005-11-22 00:00:01 +0000
620
 
      +++ file2\t2005-11-22 00:00:02 +0000
 
596
      --- file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
 
597
      +++ file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
621
598
      @@ -1,1 +1,1 @@
622
 
      -contents of level0/file2
 
599
      -contents of parent/file2
623
600
      +hello
624
601
 
625
602
    1 Lorem Ipsum\t2005-11-22
626
 
      in branch level0
 
603
      first post
627
604
      === added file 'file1'
628
 
      --- file1\t1970-01-01 00:00:00 +0000
629
 
      +++ file1\t2005-11-22 00:00:01 +0000
 
605
      --- file1\tYYYY-MM-DD HH:MM:SS +ZZZZ
 
606
      +++ file1\tYYYY-MM-DD HH:MM:SS +ZZZZ
630
607
      @@ -0,0 +1,1 @@
631
 
      +contents of level0/file1
 
608
      +contents of parent/file1
632
609
\x20\x20\x20\x20\x20\x20
633
610
      === added file 'file2'
634
 
      --- file2\t1970-01-01 00:00:00 +0000
635
 
      +++ file2\t2005-11-22 00:00:01 +0000
 
611
      --- file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
 
612
      +++ file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
636
613
      @@ -0,0 +1,1 @@
637
 
      +contents of level0/file2
 
614
      +contents of parent/file2
638
615
 
639
616
Use --include-merges or -n0 to see merged revisions.
640
 
"""
641
 
        self.check_log(expected, ['-p', '--short'])
 
617
""")
642
618
 
643
619
    def test_log_show_diff_line(self):
 
620
        self._prepare()
 
621
        out,err = self.run_bzr('log -p --line')
 
622
        self.assertEqual('', err)
 
623
        log = normalize_log(out)
644
624
        # Not supported by this formatter so expect plain output
645
 
        expected = """\
646
 
2: Lorem Ipsum 2005-11-22 [merge] merge branch level1
647
 
1: Lorem Ipsum 2005-11-22 in branch level0
648
 
"""
649
 
        self.check_log(expected, ['-p', '--line'])
650
 
 
651
 
    def test_log_show_diff_file1(self):
652
 
        """Only the diffs for the given file are to be shown"""
653
 
        expected = """\
654
 
    1 Lorem Ipsum\t2005-11-22
655
 
      in branch level0
656
 
      === added file 'file1'
657
 
      --- file1\t1970-01-01 00:00:00 +0000
658
 
      +++ file1\t2005-11-22 00:00:01 +0000
659
 
      @@ -0,0 +1,1 @@
660
 
      +contents of level0/file1
661
 
 
662
 
"""
663
 
        self.check_log(expected, ['-p', '--short', 'file1'])
664
 
 
665
 
    def test_log_show_diff_file2(self):
666
 
        """Only the diffs for the given file are to be shown"""
667
 
        expected = """\
 
625
        self.assertEqualDiff(subst_dates(log), """\
 
626
2: Lorem Ipsum 2005-11-22 [merge] merge branch 1
 
627
1: Lorem Ipsum 2005-11-22 first post
 
628
""")
 
629
 
 
630
    def test_log_show_diff_file(self):
 
631
        """Only the diffs for the given file are to be shown"""
 
632
        self._prepare()
 
633
        out,err = self.run_bzr('log -p --short file2')
 
634
        self.assertEqual('', err)
 
635
        log = normalize_log(out)
 
636
        self.assertEqualDiff(subst_dates(log), """\
668
637
    2 Lorem Ipsum\t2005-11-22 [merge]
669
 
      merge branch level1
 
638
      merge branch 1
670
639
      === modified file 'file2'
671
 
      --- file2\t2005-11-22 00:00:01 +0000
672
 
      +++ file2\t2005-11-22 00:00:02 +0000
 
640
      --- file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
 
641
      +++ file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
673
642
      @@ -1,1 +1,1 @@
674
 
      -contents of level0/file2
 
643
      -contents of parent/file2
675
644
      +hello
676
645
 
677
646
    1 Lorem Ipsum\t2005-11-22
678
 
      in branch level0
 
647
      first post
679
648
      === added file 'file2'
680
 
      --- file2\t1970-01-01 00:00:00 +0000
681
 
      +++ file2\t2005-11-22 00:00:01 +0000
 
649
      --- file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
 
650
      +++ file2\tYYYY-MM-DD HH:MM:SS +ZZZZ
682
651
      @@ -0,0 +1,1 @@
683
 
      +contents of level0/file2
 
652
      +contents of parent/file2
684
653
 
685
654
Use --include-merges or -n0 to see merged revisions.
686
 
"""
687
 
        self.check_log(expected, ['-p', '--short', 'file2'])
688
 
 
689
 
 
690
 
class TestLogUnicodeDiff(TestLog):
 
655
""")
 
656
        out,err = self.run_bzr('log -p --short file1')
 
657
        self.assertEqual('', err)
 
658
        log = normalize_log(out)
 
659
        self.assertEqualDiff(subst_dates(log), """\
 
660
    1 Lorem Ipsum\t2005-11-22
 
661
      first post
 
662
      === added file 'file1'
 
663
      --- file1\tYYYY-MM-DD HH:MM:SS +ZZZZ
 
664
      +++ file1\tYYYY-MM-DD HH:MM:SS +ZZZZ
 
665
      @@ -0,0 +1,1 @@
 
666
      +contents of parent/file1
 
667
 
 
668
""")
691
669
 
692
670
    def test_log_show_diff_non_ascii(self):
693
671
        # Smoke test for bug #328007 UnicodeDecodeError on 'log -p'
710
688
        self.assertEqual('', err)
711
689
 
712
690
 
713
 
class TestLogEncodings(tests.TestCaseInTempDir):
 
691
class TestLogEncodings(TestCaseInTempDir):
714
692
 
715
693
    _mu = u'\xb5'
716
694
    _message = u'Message with \xb5'
732
710
    ]
733
711
 
734
712
    def setUp(self):
735
 
        super(TestLogEncodings, self).setUp()
 
713
        TestCaseInTempDir.setUp(self)
736
714
        self.user_encoding = osutils._cached_user_encoding
737
 
        def restore():
738
 
            osutils._cached_user_encoding = self.user_encoding
739
 
        self.addCleanup(restore)
 
715
 
 
716
    def tearDown(self):
 
717
        osutils._cached_user_encoding = self.user_encoding
 
718
        TestCaseInTempDir.tearDown(self)
740
719
 
741
720
    def create_branch(self):
742
721
        bzr = self.run_bzr
810
789
        self.assertEquals(-1, stdout.find(test_in_cp1251))
811
790
 
812
791
 
813
 
class TestLogFile(tests.TestCaseWithTransport):
 
792
class TestLogFile(TestCaseWithTransport):
814
793
 
815
794
    def test_log_local_branch_file(self):
816
795
        """We should be able to log files in local treeless branches"""
1005
984
        self.assertNotContainsRe(log, '^4:', re.MULTILINE)
1006
985
 
1007
986
 
1008
 
class TestLogMultiple(tests.TestCaseWithTransport):
 
987
class TestLogMultiple(TestCaseWithTransport):
1009
988
 
1010
989
    def prepare_tree(self):
1011
990
        tree = self.make_branch_and_tree('parent')