/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

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

  • Committer: Jelmer Vernooij
  • Date: 2009-05-28 16:04:39 UTC
  • mfrom: (4387 +trunk)
  • mto: This revision was merged to the branch mainline in revision 4405.
  • Revision ID: jelmer@samba.org-20090528160439-4z0xlrk5nejobm7q
Merge bzr.dev.

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