~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2006-05-18 08:53:27 UTC
  • mfrom: (1713.1.4 integration)
  • Revision ID: pqm@pqm.ubuntu.com-20060518085327-89822346d9321aba
Merge benchmark selftests(Robert Collins, Martin Pool), bzr add chattiness(Robert Collins), and bzr push revision count reporting improvements(Robert Collins).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
 
1
# Copyright (C) 2005 by Canonical Ltd
2
2
# -*- coding: utf-8 -*-
3
 
#
 
3
 
4
4
# This program is free software; you can redistribute it and/or modify
5
5
# it under the terms of the GNU General Public License as published by
6
6
# the Free Software Foundation; either version 2 of the License, or
7
7
# (at your option) any later version.
8
 
#
 
8
 
9
9
# This program is distributed in the hope that it will be useful,
10
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
12
# GNU General Public License for more details.
13
 
#
 
13
 
14
14
# You should have received a copy of the GNU General Public License
15
15
# along with this program; if not, write to the Free Software
16
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
20
 
21
21
import os
22
22
 
23
 
import bzrlib
24
23
from bzrlib.tests.blackbox import ExternalBase
25
 
from bzrlib.tests import TestCaseInTempDir, TestCaseWithTransport
26
24
 
27
25
 
28
26
class TestLog(ExternalBase):
29
27
 
30
 
    def _prepare(self, format=None):
31
 
        if format:
32
 
            self.run_bzr(["init", "--format="+format])
33
 
        else:
34
 
            self.run_bzr("init")
 
28
    def _prepare(self):
 
29
        self.runbzr("init")
35
30
        self.build_tree(['hello.txt', 'goodbye.txt', 'meep.txt'])
36
 
        self.run_bzr("add hello.txt")
37
 
        self.run_bzr("commit -m message1 hello.txt")
38
 
        self.run_bzr("add goodbye.txt")
39
 
        self.run_bzr("commit -m message2 goodbye.txt")
40
 
        self.run_bzr("add meep.txt")
41
 
        self.run_bzr("commit -m message3 meep.txt")
42
 
        self.full_log = self.run_bzr("log")[0]
 
31
        self.runbzr("add hello.txt")
 
32
        self.runbzr("commit -m message1 hello.txt")
 
33
        self.runbzr("add goodbye.txt")
 
34
        self.runbzr("commit -m message2 goodbye.txt")
 
35
        self.runbzr("add meep.txt")
 
36
        self.runbzr("commit -m message3 meep.txt")
 
37
        self.full_log = self.runbzr("log")[0]
43
38
 
44
39
    def test_log_null_end_revspec(self):
45
40
        self._prepare()
50
45
        self.assertTrue('message:\n  message2\n' in self.full_log)
51
46
        self.assertTrue('message:\n  message3\n' in self.full_log)
52
47
 
53
 
        log = self.run_bzr("log -r 1..")[0]
54
 
        self.assertEqualDiff(log, self.full_log)
 
48
        log = self.runbzr("log -r 1..")[0]
 
49
        self.assertEquals(log, self.full_log)
55
50
 
56
51
    def test_log_null_begin_revspec(self):
57
52
        self._prepare()
58
 
        log = self.run_bzr("log -r ..3")[0]
59
 
        self.assertEqualDiff(self.full_log, log)
 
53
        log = self.runbzr("log -r ..3")[0]
 
54
        self.assertEquals(self.full_log, log)
60
55
 
61
56
    def test_log_null_both_revspecs(self):
62
57
        self._prepare()
63
 
        log = self.run_bzr("log -r ..")[0]
 
58
        log = self.runbzr("log -r ..")[0]
64
59
        self.assertEquals(self.full_log, log)
65
 
        self.assertEqualDiff(self.full_log, log)
66
60
 
67
61
    def test_log_negative_begin_revspec_full_log(self):
68
62
        self._prepare()
69
 
        log = self.run_bzr("log -r -3..")[0]
70
 
        self.assertEqualDiff(self.full_log, log)
 
63
        log = self.runbzr("log -r -3..")[0]
 
64
        self.assertEquals(self.full_log, log)
71
65
 
72
66
    def test_log_negative_both_revspec_full_log(self):
73
67
        self._prepare()
74
 
        log = self.run_bzr("log -r -3..-1")[0]
75
 
        self.assertEqualDiff(self.full_log, log)
 
68
        log = self.runbzr("log -r -3..-1")[0]
 
69
        self.assertEquals(self.full_log, log)
76
70
 
77
71
    def test_log_negative_both_revspec_partial(self):
78
72
        self._prepare()
79
 
        log = self.run_bzr("log -r -3..-2")[0]
 
73
        log = self.runbzr("log -r -3..-2")[0]
80
74
        self.assertTrue('revno: 1\n' in log)
81
75
        self.assertTrue('revno: 2\n' in log)
82
76
        self.assertTrue('revno: 3\n' not in log)
83
77
 
84
78
    def test_log_negative_begin_revspec(self):
85
79
        self._prepare()
86
 
        log = self.run_bzr("log -r -2..")[0]
 
80
        log = self.runbzr("log -r -2..")[0]
87
81
        self.assertTrue('revno: 1\n' not in log)
88
82
        self.assertTrue('revno: 2\n' in log)
89
83
        self.assertTrue('revno: 3\n' in log)
90
84
 
91
85
    def test_log_postive_revspecs(self):
92
86
        self._prepare()
93
 
        log = self.run_bzr("log -r 1..3")[0]
94
 
        self.assertEqualDiff(self.full_log, log)
95
 
 
96
 
    def test_log_reversed_revspecs(self):
97
 
        self._prepare()
98
 
        self.run_bzr_error(('bzr: ERROR: Start revision must be older than '
99
 
                            'the end revision.\n',),
100
 
                           ['log', '-r3..1'])
101
 
 
102
 
    def test_log_revno_n_path(self):
103
 
        os.mkdir('branch1')
104
 
        os.chdir('branch1')
105
 
        self._prepare()
106
 
        os.chdir('..')
107
 
        os.mkdir('branch2')
108
 
        os.chdir('branch2')
109
 
        self._prepare()
110
 
        os.chdir('..')
111
 
        log = self.run_bzr("log -r revno:2:branch1..revno:3:branch2",
112
 
                          retcode=3)[0]
113
 
        log = self.run_bzr("log -r revno:1:branch2..revno:3:branch2")[0]
114
 
        self.assertEqualDiff(self.full_log, log)
115
 
        log = self.run_bzr("log -r revno:1:branch2")[0]
116
 
        self.assertTrue('revno: 1\n' in log)
117
 
        self.assertTrue('revno: 2\n' not in log)
118
 
        self.assertTrue('branch nick: branch2\n' in log)
119
 
        self.assertTrue('branch nick: branch1\n' not in log)
120
 
        
121
 
    def test_log_nonexistent_file(self):
122
 
        # files that don't exist in either the basis tree or working tree
123
 
        # should give an error
124
 
        wt = self.make_branch_and_tree('.')
125
 
        out, err = self.run_bzr('log does-not-exist', retcode=3)
126
 
        self.assertContainsRe(
127
 
            err, 'Path does not have any revision history: does-not-exist')
128
 
 
129
 
    def test_log_with_tags(self):
130
 
        self._prepare(format='dirstate-tags')
131
 
        self.run_bzr('tag -r1 tag1')
132
 
        self.run_bzr('tag -r1 tag1.1')
133
 
        self.run_bzr('tag tag3')
134
 
        
135
 
        log = self.run_bzr("log -r-1")[0]
136
 
        self.assertTrue('tags: tag3' in log)
137
 
 
138
 
        log = self.run_bzr("log -r1")[0]
139
 
        # I guess that we can't know the order of tags in the output
140
 
        # since dicts are unordered, need to check both possibilities
141
 
        self.assertContainsRe(log, r'tags: (tag1, tag1\.1|tag1\.1, tag1)')
142
 
 
143
 
    def test_merged_log_with_tags(self):
144
 
        os.mkdir('branch1')
145
 
        os.chdir('branch1')
146
 
        self._prepare(format='dirstate-tags')
147
 
        os.chdir('..')
148
 
        self.run_bzr('branch branch1 branch2')
149
 
        os.chdir('branch1')
150
 
        self.run_bzr('commit -m foobar --unchanged')
151
 
        self.run_bzr('tag tag1')
152
 
        os.chdir('../branch2')
153
 
        self.run_bzr('merge ../branch1')
154
 
        self.run_bzr(['commit', '-m', 'merge branch 1'])
155
 
        log = self.run_bzr("log -r-1")[0]
156
 
        self.assertContainsRe(log, r'    tags: tag1')
157
 
        log = self.run_bzr("log -r3.1.1")[0]
158
 
        self.assertContainsRe(log, r'    tags: tag1')
159
 
 
160
 
    def test_log_limit(self):
161
 
        self._prepare()
162
 
        log = self.run_bzr("log --limit 2")[0]
163
 
        self.assertTrue('revno: 1\n' not in log)
164
 
        self.assertTrue('revno: 2\n' in log)
165
 
        self.assertTrue('revno: 3\n' in log)
 
87
        log = self.runbzr("log -r 1..3")[0]
 
88
        self.assertEquals(self.full_log, log)
 
89
 
166
90
 
167
91
class TestLogMerges(ExternalBase):
168
92
 
169
 
    def _prepare(self):
 
93
    def test_merges_are_indented_by_level(self):
170
94
        self.build_tree(['parent/'])
171
 
        self.run_bzr('init parent')
172
 
        self.run_bzr(['commit', '-m', 'first post', '--unchanged', 'parent'])
173
 
        self.run_bzr('branch parent child')
174
 
        self.run_bzr(['commit', '-m', 'branch 1', '--unchanged', 'child'])
175
 
        self.run_bzr('branch child smallerchild')
176
 
        self.run_bzr(['commit', '-m', 'branch 2', '--unchanged',
177
 
                      'smallerchild'])
 
95
        self.run_bzr('init', 'parent')
 
96
        self.run_bzr('commit', '-m', 'first post', '--unchanged', 'parent')
 
97
        self.run_bzr('branch', 'parent', 'child')
 
98
        self.run_bzr('commit', '-m', 'branch 1', '--unchanged', 'child')
 
99
        self.run_bzr('branch', 'child', 'smallerchild')
 
100
        self.run_bzr('commit', '-m', 'branch 2', '--unchanged', 'smallerchild')
178
101
        os.chdir('child')
179
 
        self.run_bzr('merge ../smallerchild')
180
 
        self.run_bzr(['commit', '-m', 'merge branch 2'])
 
102
        self.run_bzr('merge', '../smallerchild')
 
103
        self.run_bzr('commit', '-m', 'merge branch 2')
181
104
        os.chdir('../parent')
182
 
        self.run_bzr('merge ../child')
183
 
        self.run_bzr(['commit', '-m', 'merge branch 1'])
184
 
 
185
 
    def test_merges_are_indented_by_level(self):
186
 
        self._prepare()
 
105
        self.run_bzr('merge', '../child')
 
106
        self.run_bzr('commit', '-m', 'merge branch 1')
187
107
        out,err = self.run_bzr('log')
188
108
        # the log will look something like:
189
109
#        self.assertEqual("""\
195
115
#message:
196
116
#  merge branch 1
197
117
#    ------------------------------------------------------------
198
 
#    revno: 1.1.2  
 
118
#    merged: foo@example.com-20060328113140-91f43cfb46dc2863
199
119
#    committer: Robert Collins <foo@example.com>
200
120
#    branch nick: child
201
121
#    timestamp: Tue 2006-03-28 22:31:40 +1100
202
122
#    message:
203
123
#      merge branch 2
204
124
#        ------------------------------------------------------------
205
 
#        revno: 1.1.1.1
 
125
#        merged: foo@example.com-20060328113140-1ba24f850a0ef573
206
126
#        committer: Robert Collins <foo@example.com>
207
127
#        branch nick: smallerchild
208
128
#        timestamp: Tue 2006-03-28 22:31:40 +1100
209
129
#        message:
210
130
#          branch 2
211
131
#    ------------------------------------------------------------
212
 
#    revno: 1.1.1
 
132
#    merged: foo@example.com-20060328113140-5749a4757a8ac792
213
133
#    committer: Robert Collins <foo@example.com>
214
134
#    branch nick: child
215
135
#    timestamp: Tue 2006-03-28 22:31:40 +1100
224
144
#  first post
225
145
#""", out)
226
146
        # but we dont have a nice pattern matcher hooked up yet, so:
227
 
        # we check for the indenting of the commit message and the 
228
 
        # revision numbers 
229
 
        self.assertTrue('revno: 2' in out)
 
147
        # we check for the indenting of the commit message:
230
148
        self.assertTrue('  merge branch 1' in out)
231
 
        self.assertTrue('    revno: 1.1.2' in out)
232
149
        self.assertTrue('      merge branch 2' in out)
233
 
        self.assertTrue('        revno: 1.1.1.1' in out)
234
150
        self.assertTrue('          branch 2' in out)
235
 
        self.assertTrue('    revno: 1.1.1' in out)
236
151
        self.assertTrue('      branch 1' in out)
237
 
        self.assertTrue('revno: 1\n' in out)
238
152
        self.assertTrue('  first post' in out)
239
153
        self.assertEqual('', err)
240
 
 
241
 
    def test_merges_single_merge_rev(self):
242
 
        self._prepare()
243
 
        out,err = self.run_bzr('log -r1.1.2')
244
 
        # the log will look something like:
245
 
#        self.assertEqual("""\
246
 
#    ------------------------------------------------------------
247
 
#    revno: 1.1.2  
248
 
#    committer: Robert Collins <foo@example.com>
249
 
#    branch nick: child
250
 
#    timestamp: Tue 2006-03-28 22:31:40 +1100
251
 
#    message:
252
 
#      merge branch 2
253
 
#        ------------------------------------------------------------
254
 
#        revno: 1.1.1.1
255
 
#        committer: Robert Collins <foo@example.com>
256
 
#        branch nick: smallerchild
257
 
#        timestamp: Tue 2006-03-28 22:31:40 +1100
258
 
#        message:
259
 
#          branch 2
260
 
#""", out)
261
 
        # but we dont have a nice pattern matcher hooked up yet, so:
262
 
        # we check for the indenting of the commit message and the 
263
 
        # revision numbers 
264
 
        self.assertTrue('revno: 2' not in out)
265
 
        self.assertTrue('  merge branch 1' not in out)
266
 
        self.assertTrue('    revno: 1.1.2' in out)
267
 
        self.assertTrue('      merge branch 2' in out)
268
 
        self.assertTrue('        revno: 1.1.1.1' in out)
269
 
        self.assertTrue('          branch 2' in out)
270
 
        self.assertTrue('    revno: 1.1.1\n' not in out)
271
 
        self.assertTrue('      branch 1' not in out)
272
 
        self.assertTrue('revno: 1\n' not in out)
273
 
        self.assertTrue('  first post' not in out)
274
 
        self.assertEqual('', err)
275
 
 
276
 
    def test_merges_partial_range(self):
277
 
        self._prepare()
278
 
        out,err = self.run_bzr('log -r1.1.1..1.1.2')
279
 
        # the log will look something like:
280
 
#        self.assertEqual("""\
281
 
#    ------------------------------------------------------------
282
 
#    revno: 1.1.2  
283
 
#    committer: Robert Collins <foo@example.com>
284
 
#    branch nick: child
285
 
#    timestamp: Tue 2006-03-28 22:31:40 +1100
286
 
#    message:
287
 
#      merge branch 2
288
 
#        ------------------------------------------------------------
289
 
#        revno: 1.1.1.1
290
 
#        committer: Robert Collins <foo@example.com>
291
 
#        branch nick: smallerchild
292
 
#        timestamp: Tue 2006-03-28 22:31:40 +1100
293
 
#        message:
294
 
#          branch 2
295
 
#    ------------------------------------------------------------
296
 
#    revno: 1.1.1
297
 
#    committer: Robert Collins <foo@example.com>
298
 
#    branch nick: child
299
 
#    timestamp: Tue 2006-03-28 22:31:40 +1100
300
 
#    message:
301
 
#      branch 1
302
 
#""", out)
303
 
        # but we dont have a nice pattern matcher hooked up yet, so:
304
 
        # we check for the indenting of the commit message and the 
305
 
        # revision numbers 
306
 
        self.assertTrue('revno: 2' not in out)
307
 
        self.assertTrue('  merge branch 1' not in out)
308
 
        self.assertTrue('    revno: 1.1.2' in out)
309
 
        self.assertTrue('      merge branch 2' in out)
310
 
        self.assertTrue('        revno: 1.1.1.1' in out)
311
 
        self.assertTrue('          branch 2' in out)
312
 
        self.assertTrue('    revno: 1.1.1' in out)
313
 
        self.assertTrue('      branch 1' in out)
314
 
        self.assertTrue('revno: 1\n' not in out)
315
 
        self.assertTrue('  first post' not in out)
316
 
        self.assertEqual('', err)
317
 
 
318
 
 
319
 
class TestLogEncodings(TestCaseInTempDir):
320
 
 
321
 
    _mu = u'\xb5'
322
 
    _message = u'Message with \xb5'
323
 
 
324
 
    # Encodings which can encode mu
325
 
    good_encodings = [
326
 
        'utf-8',
327
 
        'latin-1',
328
 
        'iso-8859-1',
329
 
        'cp437', # Common windows encoding
330
 
        'cp1251', # Alexander Belchenko's windows encoding
331
 
        'cp1258', # Common windows encoding
332
 
    ]
333
 
    # Encodings which cannot encode mu
334
 
    bad_encodings = [
335
 
        'ascii',
336
 
        'iso-8859-2',
337
 
        'koi8_r',
338
 
    ]
339
 
 
340
 
    def setUp(self):
341
 
        TestCaseInTempDir.setUp(self)
342
 
        self.user_encoding = bzrlib.user_encoding
343
 
 
344
 
    def tearDown(self):
345
 
        bzrlib.user_encoding = self.user_encoding
346
 
        TestCaseInTempDir.tearDown(self)
347
 
 
348
 
    def create_branch(self):
349
 
        bzr = self.run_bzr
350
 
        bzr('init')
351
 
        open('a', 'wb').write('some stuff\n')
352
 
        bzr('add a')
353
 
        bzr(['commit', '-m', self._message])
354
 
 
355
 
    def try_encoding(self, encoding, fail=False):
356
 
        bzr = self.run_bzr
357
 
        if fail:
358
 
            self.assertRaises(UnicodeEncodeError,
359
 
                self._mu.encode, encoding)
360
 
            encoded_msg = self._message.encode(encoding, 'replace')
361
 
        else:
362
 
            encoded_msg = self._message.encode(encoding)
363
 
 
364
 
        old_encoding = bzrlib.user_encoding
365
 
        # This test requires that 'run_bzr' uses the current
366
 
        # bzrlib, because we override user_encoding, and expect
367
 
        # it to be used
368
 
        try:
369
 
            bzrlib.user_encoding = 'ascii'
370
 
            # We should be able to handle any encoding
371
 
            out, err = bzr('log', encoding=encoding)
372
 
            if not fail:
373
 
                # Make sure we wrote mu as we expected it to exist
374
 
                self.assertNotEqual(-1, out.find(encoded_msg))
375
 
                out_unicode = out.decode(encoding)
376
 
                self.assertNotEqual(-1, out_unicode.find(self._message))
377
 
            else:
378
 
                self.assertNotEqual(-1, out.find('Message with ?'))
379
 
        finally:
380
 
            bzrlib.user_encoding = old_encoding
381
 
 
382
 
    def test_log_handles_encoding(self):
383
 
        self.create_branch()
384
 
 
385
 
        for encoding in self.good_encodings:
386
 
            self.try_encoding(encoding)
387
 
 
388
 
    def test_log_handles_bad_encoding(self):
389
 
        self.create_branch()
390
 
 
391
 
        for encoding in self.bad_encodings:
392
 
            self.try_encoding(encoding, fail=True)
393
 
 
394
 
    def test_stdout_encoding(self):
395
 
        bzr = self.run_bzr
396
 
        bzrlib.user_encoding = "cp1251"
397
 
 
398
 
        bzr('init')
399
 
        self.build_tree(['a'])
400
 
        bzr('add a')
401
 
        bzr(['commit', '-m', u'\u0422\u0435\u0441\u0442'])
402
 
        stdout, stderr = self.run_bzr('log', encoding='cp866')
403
 
 
404
 
        message = stdout.splitlines()[-1]
405
 
 
406
 
        # explanation of the check:
407
 
        # u'\u0422\u0435\u0441\u0442' is word 'Test' in russian
408
 
        # in cp866  encoding this is string '\x92\xa5\xe1\xe2'
409
 
        # in cp1251 encoding this is string '\xd2\xe5\xf1\xf2'
410
 
        # This test should check that output of log command
411
 
        # encoded to sys.stdout.encoding
412
 
        test_in_cp866 = '\x92\xa5\xe1\xe2'
413
 
        test_in_cp1251 = '\xd2\xe5\xf1\xf2'
414
 
        # Make sure the log string is encoded in cp866
415
 
        self.assertEquals(test_in_cp866, message[2:])
416
 
        # Make sure the cp1251 string is not found anywhere
417
 
        self.assertEquals(-1, stdout.find(test_in_cp1251))
418
 
 
419
 
 
420
 
class TestLogFile(TestCaseWithTransport):
421
 
 
422
 
    def test_log_local_branch_file(self):
423
 
        """We should be able to log files in local treeless branches"""
424
 
        tree = self.make_branch_and_tree('tree')
425
 
        self.build_tree(['tree/file'])
426
 
        tree.add('file')
427
 
        tree.commit('revision 1')
428
 
        tree.bzrdir.destroy_workingtree()
429
 
        self.run_bzr('log tree/file')
430
 
 
431
 
    def test_log_file(self):
432
 
        """The log for a particular file should only list revs for that file"""
433
 
        tree = self.make_branch_and_tree('parent')
434
 
        self.build_tree(['parent/file1', 'parent/file2', 'parent/file3'])
435
 
        tree.add('file1')
436
 
        tree.commit('add file1')
437
 
        tree.add('file2')
438
 
        tree.commit('add file2')
439
 
        tree.add('file3')
440
 
        tree.commit('add file3')
441
 
        self.run_bzr('branch parent child')
442
 
        print >> file('child/file2', 'wb'), 'hello'
443
 
        self.run_bzr(['commit', '-m', 'branch 1', 'child'])
444
 
        os.chdir('parent')
445
 
        self.run_bzr('merge ../child')
446
 
        self.run_bzr(['commit', '-m', 'merge child branch'])
447
 
        log = self.run_bzr('log file1')[0]
448
 
        self.assertContainsRe(log, 'revno: 1\n')
449
 
        self.assertNotContainsRe(log, 'revno: 2\n')
450
 
        self.assertNotContainsRe(log, 'revno: 3\n')
451
 
        self.assertNotContainsRe(log, 'revno: 3.1.1\n')
452
 
        self.assertNotContainsRe(log, 'revno: 4\n')
453
 
        log = self.run_bzr('log file2')[0]
454
 
        self.assertNotContainsRe(log, 'revno: 1\n')
455
 
        self.assertContainsRe(log, 'revno: 2\n')
456
 
        self.assertNotContainsRe(log, 'revno: 3\n')
457
 
        self.assertContainsRe(log, 'revno: 3.1.1\n')
458
 
        self.assertContainsRe(log, 'revno: 4\n')
459
 
        log = self.run_bzr('log file3')[0]
460
 
        self.assertNotContainsRe(log, 'revno: 1\n')
461
 
        self.assertNotContainsRe(log, 'revno: 2\n')
462
 
        self.assertContainsRe(log, 'revno: 3\n')
463
 
        self.assertNotContainsRe(log, 'revno: 3.1.1\n')
464
 
        self.assertNotContainsRe(log, 'revno: 4\n')
465
 
        log = self.run_bzr('log -r3.1.1 file2')[0]
466
 
        self.assertNotContainsRe(log, 'revno: 1\n')
467
 
        self.assertNotContainsRe(log, 'revno: 2\n')
468
 
        self.assertNotContainsRe(log, 'revno: 3\n')
469
 
        self.assertContainsRe(log, 'revno: 3.1.1\n')
470
 
        self.assertNotContainsRe(log, 'revno: 4\n')
471
 
        log = self.run_bzr('log -r4 file2')[0]
472
 
        self.assertNotContainsRe(log, 'revno: 1\n')
473
 
        self.assertNotContainsRe(log, 'revno: 2\n')
474
 
        self.assertNotContainsRe(log, 'revno: 3\n')
475
 
        self.assertContainsRe(log, 'revno: 3.1.1\n')
476
 
        self.assertContainsRe(log, 'revno: 4\n')
477
 
        log = self.run_bzr('log -r3.. file2')[0]
478
 
        self.assertNotContainsRe(log, 'revno: 1\n')
479
 
        self.assertNotContainsRe(log, 'revno: 2\n')
480
 
        self.assertNotContainsRe(log, 'revno: 3\n')
481
 
        self.assertContainsRe(log, 'revno: 3.1.1\n')
482
 
        self.assertContainsRe(log, 'revno: 4\n')
483
 
        log = self.run_bzr('log -r..3 file2')[0]
484
 
        self.assertNotContainsRe(log, 'revno: 1\n')
485
 
        self.assertContainsRe(log, 'revno: 2\n')
486
 
        self.assertNotContainsRe(log, 'revno: 3\n')
487
 
        self.assertNotContainsRe(log, 'revno: 3.1.1\n')
488
 
        self.assertNotContainsRe(log, 'revno: 4\n')