/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: Robert Collins
  • Date: 2007-09-19 05:14:14 UTC
  • mto: (2835.1.1 ianc-integration)
  • mto: This revision was merged to the branch mainline in revision 2836.
  • Revision ID: robertc@robertcollins.net-20070919051414-2tgjqteg7k3ps4h0
* ``pull``, ``merge`` and ``push`` will no longer silently correct some
  repository index errors that occured as a result of the Weave disk format.
  Instead the ``reconcile`` command needs to be run to correct those
  problems if they exist (and it has been able to fix most such problems
  since bzr 0.8). Some new problems have been identified during this release
  and you should run ``bzr check`` once on every repository to see if you
  need to reconcile. If you cannot ``pull`` or ``merge`` from a remote
  repository due to mismatched parent errors - a symptom of index errors -
  you should simply take a full copy of that remote repository to a clean
  directory outside any local repositories, then run reconcile on it, and
  finally pull from it locally. (And naturally email the repositories owner
  to ask them to upgrade and run reconcile).
  (Robert Collins)

* ``VersionedFile.fix_parents`` has been removed as a harmful API.
  ``VersionedFile.join`` will no longer accept different parents on either
  side of a join - it will either ignore them, or error, depending on the
  implementation. See notes when upgrading for more information.
  (Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
 
2
# -*- coding: utf-8 -*-
 
3
#
 
4
# This program is free software; you can redistribute it and/or modify
 
5
# it under the terms of the GNU General Public License as published by
 
6
# the Free Software Foundation; either version 2 of the License, or
 
7
# (at your option) any later version.
 
8
#
 
9
# This program is distributed in the hope that it will be useful,
 
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
# GNU General Public License for more details.
 
13
#
 
14
# You should have received a copy of the GNU General Public License
 
15
# along with this program; if not, write to the Free Software
 
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
17
 
 
18
 
 
19
"""Black-box tests for bzr log."""
 
20
 
 
21
import os
 
22
 
 
23
import bzrlib
 
24
from bzrlib.tests.blackbox import ExternalBase
 
25
from bzrlib.tests import TestCaseInTempDir, TestCaseWithTransport
 
26
 
 
27
 
 
28
class TestLog(ExternalBase):
 
29
 
 
30
    def _prepare(self, format=None):
 
31
        if format:
 
32
            self.run_bzr(["init", "--format="+format])
 
33
        else:
 
34
            self.run_bzr("init")
 
35
        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]
 
43
 
 
44
    def test_log_null_end_revspec(self):
 
45
        self._prepare()
 
46
        self.assertTrue('revno: 1\n' in self.full_log)
 
47
        self.assertTrue('revno: 2\n' in self.full_log)
 
48
        self.assertTrue('revno: 3\n' in self.full_log)
 
49
        self.assertTrue('message:\n  message1\n' in self.full_log)
 
50
        self.assertTrue('message:\n  message2\n' in self.full_log)
 
51
        self.assertTrue('message:\n  message3\n' in self.full_log)
 
52
 
 
53
        log = self.run_bzr("log -r 1..")[0]
 
54
        self.assertEqualDiff(log, self.full_log)
 
55
 
 
56
    def test_log_null_begin_revspec(self):
 
57
        self._prepare()
 
58
        log = self.run_bzr("log -r ..3")[0]
 
59
        self.assertEqualDiff(self.full_log, log)
 
60
 
 
61
    def test_log_null_both_revspecs(self):
 
62
        self._prepare()
 
63
        log = self.run_bzr("log -r ..")[0]
 
64
        self.assertEquals(self.full_log, log)
 
65
        self.assertEqualDiff(self.full_log, log)
 
66
 
 
67
    def test_log_negative_begin_revspec_full_log(self):
 
68
        self._prepare()
 
69
        log = self.run_bzr("log -r -3..")[0]
 
70
        self.assertEqualDiff(self.full_log, log)
 
71
 
 
72
    def test_log_negative_both_revspec_full_log(self):
 
73
        self._prepare()
 
74
        log = self.run_bzr("log -r -3..-1")[0]
 
75
        self.assertEqualDiff(self.full_log, log)
 
76
 
 
77
    def test_log_negative_both_revspec_partial(self):
 
78
        self._prepare()
 
79
        log = self.run_bzr("log -r -3..-2")[0]
 
80
        self.assertTrue('revno: 1\n' in log)
 
81
        self.assertTrue('revno: 2\n' in log)
 
82
        self.assertTrue('revno: 3\n' not in log)
 
83
 
 
84
    def test_log_negative_begin_revspec(self):
 
85
        self._prepare()
 
86
        log = self.run_bzr("log -r -2..")[0]
 
87
        self.assertTrue('revno: 1\n' not in log)
 
88
        self.assertTrue('revno: 2\n' in log)
 
89
        self.assertTrue('revno: 3\n' in log)
 
90
 
 
91
    def test_log_postive_revspecs(self):
 
92
        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)
 
166
 
 
167
class TestLogMerges(ExternalBase):
 
168
 
 
169
    def _prepare(self):
 
170
        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'])
 
178
        os.chdir('child')
 
179
        self.run_bzr('merge ../smallerchild')
 
180
        self.run_bzr(['commit', '-m', 'merge branch 2'])
 
181
        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()
 
187
        out,err = self.run_bzr('log')
 
188
        # the log will look something like:
 
189
#        self.assertEqual("""\
 
190
#------------------------------------------------------------
 
191
#revno: 2
 
192
#committer: Robert Collins <foo@example.com>
 
193
#branch nick: parent
 
194
#timestamp: Tue 2006-03-28 22:31:40 +1100
 
195
#message:
 
196
#  merge branch 1
 
197
#    ------------------------------------------------------------
 
198
#    revno: 1.1.2  
 
199
#    committer: Robert Collins <foo@example.com>
 
200
#    branch nick: child
 
201
#    timestamp: Tue 2006-03-28 22:31:40 +1100
 
202
#    message:
 
203
#      merge branch 2
 
204
#        ------------------------------------------------------------
 
205
#        revno: 1.1.1.1
 
206
#        committer: Robert Collins <foo@example.com>
 
207
#        branch nick: smallerchild
 
208
#        timestamp: Tue 2006-03-28 22:31:40 +1100
 
209
#        message:
 
210
#          branch 2
 
211
#    ------------------------------------------------------------
 
212
#    revno: 1.1.1
 
213
#    committer: Robert Collins <foo@example.com>
 
214
#    branch nick: child
 
215
#    timestamp: Tue 2006-03-28 22:31:40 +1100
 
216
#    message:
 
217
#      branch 1
 
218
#------------------------------------------------------------
 
219
#revno: 1
 
220
#committer: Robert Collins <foo@example.com>
 
221
#branch nick: parent
 
222
#timestamp: Tue 2006-03-28 22:31:39 +1100
 
223
#message:
 
224
#  first post
 
225
#""", out)
 
226
        # 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)
 
230
        self.assertTrue('  merge branch 1' in out)
 
231
        self.assertTrue('    revno: 1.1.2' in out)
 
232
        self.assertTrue('      merge branch 2' in out)
 
233
        self.assertTrue('        revno: 1.1.1.1' in out)
 
234
        self.assertTrue('          branch 2' in out)
 
235
        self.assertTrue('    revno: 1.1.1' in out)
 
236
        self.assertTrue('      branch 1' in out)
 
237
        self.assertTrue('revno: 1\n' in out)
 
238
        self.assertTrue('  first post' in out)
 
239
        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')