~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

  • Committer: Alexander Belchenko
  • Date: 2006-07-30 16:43:12 UTC
  • mto: (1711.2.111 jam-integration)
  • mto: This revision was merged to the branch mainline in revision 1906.
  • Revision ID: bialix@ukr.net-20060730164312-b025fd3ff0cee59e
rename  gpl.txt => COPYING.txt

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2010 Canonical Ltd
 
1
# Copyright (C) 2005 by Canonical Ltd
 
2
# -*- coding: utf-8 -*-
2
3
#
3
4
# This program is free software; you can redistribute it and/or modify
4
5
# it under the terms of the GNU General Public License as published by
12
13
#
13
14
# You should have received a copy of the GNU General Public License
14
15
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
 
17
18
 
18
19
"""Black-box tests for bzr log."""
19
20
 
20
 
from itertools import izip
21
21
import os
22
 
import re
23
 
 
24
 
from bzrlib import (
25
 
    branchbuilder,
26
 
    errors,
27
 
    log,
28
 
    osutils,
29
 
    tests,
30
 
    )
31
 
from bzrlib.tests import (
32
 
    script,
33
 
    test_log,
34
 
    )
35
 
 
36
 
 
37
 
class TestLog(tests.TestCaseWithTransport, test_log.TestLogMixin):
38
 
 
39
 
    def make_minimal_branch(self, path='.', format=None):
40
 
        tree = self.make_branch_and_tree(path, format=format)
41
 
        self.build_tree([path + '/hello.txt'])
42
 
        tree.add('hello.txt')
43
 
        tree.commit(message='message1')
44
 
        return tree
45
 
 
46
 
    def make_linear_branch(self, path='.', format=None):
47
 
        tree = self.make_branch_and_tree(path, format=format)
48
 
        self.build_tree(
49
 
            [path + '/hello.txt', path + '/goodbye.txt', path + '/meep.txt'])
50
 
        tree.add('hello.txt')
51
 
        tree.commit(message='message1')
52
 
        tree.add('goodbye.txt')
53
 
        tree.commit(message='message2')
54
 
        tree.add('meep.txt')
55
 
        tree.commit(message='message3')
56
 
        return tree
57
 
 
58
 
    def make_merged_branch(self, path='.', format=None):
59
 
        tree = self.make_linear_branch(path, format)
60
 
        tree2 = tree.bzrdir.sprout('tree2',
61
 
            revision_id=tree.branch.get_rev_id(1)).open_workingtree()
62
 
        tree2.commit(message='tree2 message2')
63
 
        tree2.commit(message='tree2 message3')
64
 
        tree.merge_from_branch(tree2.branch)
65
 
        tree.commit(message='merge')
66
 
        return tree
67
 
 
68
 
 
69
 
class TestLogWithLogCatcher(TestLog):
70
 
 
71
 
    def setUp(self):
72
 
        super(TestLogWithLogCatcher, self).setUp()
73
 
        # Capture log formatter creations
74
 
        class MyLogFormatter(test_log.LogCatcher):
75
 
 
76
 
            def __new__(klass, *args, **kwargs):
77
 
                self.log_catcher = test_log.LogCatcher(*args, **kwargs)
78
 
                # Always return our own log formatter
79
 
                return self.log_catcher
80
 
 
81
 
        def getme(branch):
82
 
                # Always return our own log formatter class hijacking the
83
 
                # default behavior (which requires setting up a config
84
 
                # variable)
85
 
            return MyLogFormatter
86
 
        self.overrideAttr(log.log_formatter_registry, 'get_default', getme)
87
 
 
88
 
    def get_captured_revisions(self):
89
 
        return self.log_catcher.revisions
90
 
 
91
 
    def assertLogRevnos(self, args, expected_revnos, working_dir='.'):
92
 
        self.run_bzr(['log'] + args, working_dir=working_dir)
93
 
        self.assertEqual(expected_revnos,
94
 
                         [r.revno for r in self.get_captured_revisions()])
95
 
 
96
 
    def assertLogRevnosAndDepths(self, args, expected_revnos_and_depths,
97
 
                                working_dir='.'):
98
 
        self.run_bzr(['log'] + args, working_dir=working_dir)
99
 
        self.assertEqual(expected_revnos_and_depths,
100
 
                         [(r.revno, r.merge_depth)
101
 
                           for r in self.get_captured_revisions()])
102
 
 
103
 
 
104
 
class TestLogRevSpecs(TestLogWithLogCatcher):
105
 
 
106
 
    def test_log_no_revspec(self):
107
 
        self.make_linear_branch()
108
 
        self.assertLogRevnos([], ['3', '2', '1'])
 
22
 
 
23
import bzrlib
 
24
from bzrlib.tests.blackbox import ExternalBase
 
25
from bzrlib.tests import TestCaseInTempDir
 
26
 
 
27
 
 
28
class TestLog(ExternalBase):
 
29
 
 
30
    def _prepare(self):
 
31
        self.runbzr("init")
 
32
        self.build_tree(['hello.txt', 'goodbye.txt', 'meep.txt'])
 
33
        self.runbzr("add hello.txt")
 
34
        self.runbzr("commit -m message1 hello.txt")
 
35
        self.runbzr("add goodbye.txt")
 
36
        self.runbzr("commit -m message2 goodbye.txt")
 
37
        self.runbzr("add meep.txt")
 
38
        self.runbzr("commit -m message3 meep.txt")
 
39
        self.full_log = self.runbzr("log")[0]
109
40
 
110
41
    def test_log_null_end_revspec(self):
111
 
        self.make_linear_branch()
112
 
        self.assertLogRevnos(['-r1..'], ['3', '2', '1'])
 
42
        self._prepare()
 
43
        self.assertTrue('revno: 1\n' in self.full_log)
 
44
        self.assertTrue('revno: 2\n' in self.full_log)
 
45
        self.assertTrue('revno: 3\n' in self.full_log)
 
46
        self.assertTrue('message:\n  message1\n' in self.full_log)
 
47
        self.assertTrue('message:\n  message2\n' in self.full_log)
 
48
        self.assertTrue('message:\n  message3\n' in self.full_log)
 
49
 
 
50
        log = self.runbzr("log -r 1..")[0]
 
51
        self.assertEquals(log, self.full_log)
113
52
 
114
53
    def test_log_null_begin_revspec(self):
115
 
        self.make_linear_branch()
116
 
        self.assertLogRevnos(['-r..3'], ['3', '2', '1'])
 
54
        self._prepare()
 
55
        log = self.runbzr("log -r ..3")[0]
 
56
        self.assertEquals(self.full_log, log)
117
57
 
118
58
    def test_log_null_both_revspecs(self):
119
 
        self.make_linear_branch()
120
 
        self.assertLogRevnos(['-r..'], ['3', '2', '1'])
 
59
        self._prepare()
 
60
        log = self.runbzr("log -r ..")[0]
 
61
        self.assertEquals(self.full_log, log)
121
62
 
122
63
    def test_log_negative_begin_revspec_full_log(self):
123
 
        self.make_linear_branch()
124
 
        self.assertLogRevnos(['-r-3..'], ['3', '2', '1'])
 
64
        self._prepare()
 
65
        log = self.runbzr("log -r -3..")[0]
 
66
        self.assertEquals(self.full_log, log)
125
67
 
126
68
    def test_log_negative_both_revspec_full_log(self):
127
 
        self.make_linear_branch()
128
 
        self.assertLogRevnos(['-r-3..-1'], ['3', '2', '1'])
 
69
        self._prepare()
 
70
        log = self.runbzr("log -r -3..-1")[0]
 
71
        self.assertEquals(self.full_log, log)
129
72
 
130
73
    def test_log_negative_both_revspec_partial(self):
131
 
        self.make_linear_branch()
132
 
        self.assertLogRevnos(['-r-3..-2'], ['2', '1'])
 
74
        self._prepare()
 
75
        log = self.runbzr("log -r -3..-2")[0]
 
76
        self.assertTrue('revno: 1\n' in log)
 
77
        self.assertTrue('revno: 2\n' in log)
 
78
        self.assertTrue('revno: 3\n' not in log)
133
79
 
134
80
    def test_log_negative_begin_revspec(self):
135
 
        self.make_linear_branch()
136
 
        self.assertLogRevnos(['-r-2..'], ['3', '2'])
137
 
 
138
 
    def test_log_positive_revspecs(self):
139
 
        self.make_linear_branch()
140
 
        self.assertLogRevnos(['-r1..3'], ['3', '2', '1'])
141
 
 
142
 
    def test_log_dotted_revspecs(self):
143
 
        self.make_merged_branch()
144
 
        self.assertLogRevnos(['-n0', '-r1..1.1.1'], ['1.1.1', '1'])
145
 
 
146
 
    def test_log_limit(self):
147
 
        tree = self.make_branch_and_tree('.')
148
 
        # We want more commits than our batch size starts at
149
 
        for pos in range(10):
150
 
            tree.commit("%s" % pos)
151
 
        self.assertLogRevnos(['--limit', '2'], ['10', '9'])
152
 
 
153
 
    def test_log_limit_short(self):
154
 
        self.make_linear_branch()
155
 
        self.assertLogRevnos(['-l', '2'], ['3', '2'])
156
 
 
157
 
    def test_log_change_revno(self):
158
 
        self.make_linear_branch()
159
 
        self.assertLogRevnos(['-c1'], ['1'])
160
 
 
161
 
    def test_branch_revspec(self):
162
 
        foo = self.make_branch_and_tree('foo')
163
 
        bar = self.make_branch_and_tree('bar')
164
 
        self.build_tree(['foo/foo.txt', 'bar/bar.txt'])
165
 
        foo.add('foo.txt')
166
 
        bar.add('bar.txt')
167
 
        foo.commit(message='foo')
168
 
        bar.commit(message='bar')
169
 
        self.run_bzr('log -r branch:../bar', working_dir='foo')
170
 
        self.assertEqual([bar.branch.get_rev_id(1)],
171
 
                         [r.rev.revision_id
172
 
                          for r in self.get_captured_revisions()])
173
 
 
174
 
 
175
 
class TestLogExcludeCommonAncestry(TestLogWithLogCatcher):
176
 
 
177
 
    def test_exclude_common_ancestry_simple_revnos(self):
178
 
        self.make_linear_branch()
179
 
        self.assertLogRevnos(['-r1..3', '--exclude-common-ancestry'],
180
 
                             ['3', '2'])
181
 
 
182
 
 
183
 
class TestLogMergedLinearAncestry(TestLogWithLogCatcher):
184
 
 
185
 
    def setUp(self):
186
 
        super(TestLogMergedLinearAncestry, self).setUp()
187
 
        # FIXME: Using a MemoryTree would be even better here (but until we
188
 
        # stop calling run_bzr, there is no point) --vila 100118.
189
 
        builder = branchbuilder.BranchBuilder(self.get_transport())
190
 
        builder.start_series()
191
 
        # 1
192
 
        # | \
193
 
        # 2  1.1.1
194
 
        # | / |
195
 
        # 3  1.1.2
196
 
        # |   |
197
 
        # |  1.1.3
198
 
        # | / |
199
 
        # 4  1.1.4
200
 
        # | /
201
 
        # 5
202
 
 
203
 
        # mainline
204
 
        builder.build_snapshot('1', None, [
205
 
            ('add', ('', 'root-id', 'directory', ''))])
206
 
        builder.build_snapshot('2', ['1'], [])
207
 
        # branch
208
 
        builder.build_snapshot('1.1.1', ['1'], [])
209
 
        # merge branch into mainline
210
 
        builder.build_snapshot('3', ['2', '1.1.1'], [])
211
 
        # new commits in branch
212
 
        builder.build_snapshot('1.1.2', ['1.1.1'], [])
213
 
        builder.build_snapshot('1.1.3', ['1.1.2'], [])
214
 
        # merge branch into mainline
215
 
        builder.build_snapshot('4', ['3', '1.1.3'], [])
216
 
        # merge mainline into branch
217
 
        builder.build_snapshot('1.1.4', ['1.1.3', '4'], [])
218
 
        # merge branch into mainline
219
 
        builder.build_snapshot('5', ['4', '1.1.4'], [])
220
 
        builder.finish_series()
221
 
 
222
 
    def test_n0(self):
223
 
        self.assertLogRevnos(['-n0', '-r1.1.1..1.1.4'],
224
 
                             ['1.1.4', '4', '1.1.3', '1.1.2', '3', '1.1.1'])
225
 
    def test_n0_forward(self):
226
 
        self.assertLogRevnos(['-n0', '-r1.1.1..1.1.4', '--forward'],
227
 
                             ['3', '1.1.1', '4', '1.1.2', '1.1.3', '1.1.4'])
228
 
 
229
 
    def test_n1(self):
230
 
        # starting from 1.1.4 we follow the left-hand ancestry
231
 
        self.assertLogRevnos(['-n1', '-r1.1.1..1.1.4'],
232
 
                             ['1.1.4', '1.1.3', '1.1.2', '1.1.1'])
233
 
 
234
 
    def test_n1_forward(self):
235
 
        self.assertLogRevnos(['-n1', '-r1.1.1..1.1.4', '--forward'],
236
 
                             ['1.1.1', '1.1.2', '1.1.3', '1.1.4'])
237
 
 
238
 
 
239
 
class Test_GenerateAllRevisions(TestLogWithLogCatcher):
240
 
 
241
 
    def setUp(self):
242
 
        super(Test_GenerateAllRevisions, self).setUp()
243
 
        builder = self.make_branch_with_many_merges()
244
 
        b = builder.get_branch()
245
 
        b.lock_read()
246
 
        self.addCleanup(b.unlock)
247
 
        self.branch = b
248
 
 
249
 
    def make_branch_with_many_merges(self, path='.', format=None):
250
 
        builder = branchbuilder.BranchBuilder(self.get_transport())
251
 
        builder.start_series()
252
 
        # The graph below may look a bit complicated (and it may be but I've
253
 
        # banged my head enough on it) but the bug requires at least dotted
254
 
        # revnos *and* merged revisions below that.
255
 
        builder.build_snapshot('1', None, [
256
 
            ('add', ('', 'root-id', 'directory', ''))])
257
 
        builder.build_snapshot('2', ['1'], [])
258
 
        builder.build_snapshot('1.1.1', ['1'], [])
259
 
        builder.build_snapshot('2.1.1', ['2'], [])
260
 
        builder.build_snapshot('3', ['2', '1.1.1'], [])
261
 
        builder.build_snapshot('2.1.2', ['2.1.1'], [])
262
 
        builder.build_snapshot('2.2.1', ['2.1.1'], [])
263
 
        builder.build_snapshot('2.1.3', ['2.1.2', '2.2.1'], [])
264
 
        builder.build_snapshot('4', ['3', '2.1.3'], [])
265
 
        builder.build_snapshot('5', ['4', '2.1.2'], [])
266
 
        builder.finish_series()
267
 
        return builder
268
 
 
269
 
    def test_not_an_ancestor(self):
270
 
        self.assertRaises(errors.BzrCommandError,
271
 
                          log._generate_all_revisions,
272
 
                          self.branch, '1.1.1', '2.1.3', 'reverse',
273
 
                          delayed_graph_generation=True)
274
 
 
275
 
    def test_wrong_order(self):
276
 
        self.assertRaises(errors.BzrCommandError,
277
 
                          log._generate_all_revisions,
278
 
                          self.branch, '5', '2.1.3', 'reverse',
279
 
                          delayed_graph_generation=True)
280
 
 
281
 
    def test_no_start_rev_id_with_end_rev_id_being_a_merge(self):
282
 
        revs = log._generate_all_revisions(
283
 
            self.branch, None, '2.1.3',
284
 
            'reverse', delayed_graph_generation=True)
285
 
 
286
 
 
287
 
class TestLogRevSpecsWithPaths(TestLogWithLogCatcher):
288
 
 
289
 
    def test_log_revno_n_path_wrong_namespace(self):
290
 
        self.make_linear_branch('branch1')
291
 
        self.make_linear_branch('branch2')
292
 
        # There is no guarantee that a path exist between two arbitrary
293
 
        # revisions.
294
 
        self.run_bzr("log -r revno:2:branch1..revno:3:branch2", retcode=3)
295
 
 
296
 
    def test_log_revno_n_path_correct_order(self):
297
 
        self.make_linear_branch('branch2')
298
 
        self.assertLogRevnos(['-rrevno:1:branch2..revno:3:branch2'],
299
 
                             ['3', '2','1'])
300
 
 
301
 
    def test_log_revno_n_path(self):
302
 
        self.make_linear_branch('branch2')
303
 
        self.assertLogRevnos(['-rrevno:1:branch2'],
304
 
                             ['1'])
305
 
        rev_props = self.log_catcher.revisions[0].rev.properties
306
 
        self.assertEqual('branch2', rev_props['branch-nick'])
307
 
 
308
 
 
309
 
class TestLogErrors(TestLog):
310
 
 
311
 
    def test_log_zero_revspec(self):
312
 
        self.make_minimal_branch()
313
 
        self.run_bzr_error(['bzr: ERROR: Logging revision 0 is invalid.'],
314
 
                           ['log', '-r0'])
315
 
 
316
 
    def test_log_zero_begin_revspec(self):
317
 
        self.make_linear_branch()
318
 
        self.run_bzr_error(['bzr: ERROR: Logging revision 0 is invalid.'],
319
 
                           ['log', '-r0..2'])
320
 
 
321
 
    def test_log_zero_end_revspec(self):
322
 
        self.make_linear_branch()
323
 
        self.run_bzr_error(['bzr: ERROR: Logging revision 0 is invalid.'],
324
 
                           ['log', '-r-2..0'])
325
 
 
326
 
    def test_log_nonexistent_revno(self):
327
 
        self.make_minimal_branch()
328
 
        self.run_bzr_error(["bzr: ERROR: Requested revision: '1234' "
329
 
                            "does not exist in branch:"],
330
 
                           ['log', '-r1234'])
331
 
 
332
 
    def test_log_nonexistent_dotted_revno(self):
333
 
        self.make_minimal_branch()
334
 
        self.run_bzr_error(["bzr: ERROR: Requested revision: '123.123' "
335
 
                            "does not exist in branch:"],
336
 
                           ['log',  '-r123.123'])
337
 
 
338
 
    def test_log_change_nonexistent_revno(self):
339
 
        self.make_minimal_branch()
340
 
        self.run_bzr_error(["bzr: ERROR: Requested revision: '1234' "
341
 
                            "does not exist in branch:"],
342
 
                           ['log',  '-c1234'])
343
 
 
344
 
    def test_log_change_nonexistent_dotted_revno(self):
345
 
        self.make_minimal_branch()
346
 
        self.run_bzr_error(["bzr: ERROR: Requested revision: '123.123' "
347
 
                            "does not exist in branch:"],
348
 
                           ['log', '-c123.123'])
349
 
 
350
 
    def test_log_change_single_revno_only(self):
351
 
        self.make_minimal_branch()
352
 
        self.run_bzr_error(['bzr: ERROR: Option --change does not'
353
 
                           ' accept revision ranges'],
354
 
                           ['log', '--change', '2..3'])
355
 
 
356
 
    def test_log_change_incompatible_with_revision(self):
357
 
        self.run_bzr_error(['bzr: ERROR: --revision and --change'
358
 
                           ' are mutually exclusive'],
359
 
                           ['log', '--change', '2', '--revision', '3'])
360
 
 
361
 
    def test_log_nonexistent_file(self):
362
 
        self.make_minimal_branch()
363
 
        # files that don't exist in either the basis tree or working tree
364
 
        # should give an error
365
 
        out, err = self.run_bzr('log does-not-exist', retcode=3)
366
 
        self.assertContainsRe(err,
367
 
                              'Path unknown at end or start of revision range: '
368
 
                              'does-not-exist')
369
 
 
370
 
    def test_log_reversed_revspecs(self):
371
 
        self.make_linear_branch()
372
 
        self.run_bzr_error(('bzr: ERROR: Start revision must be older than '
373
 
                            'the end revision.\n',),
374
 
                           ['log', '-r3..1'])
375
 
 
376
 
    def test_log_reversed_dotted_revspecs(self):
377
 
        self.make_merged_branch()
378
 
        self.run_bzr_error(('bzr: ERROR: Start revision not found in '
379
 
                            'left-hand history of end revision.\n',),
380
 
                           "log -r 1.1.1..1")
381
 
 
382
 
    def test_log_bad_message_re(self):
383
 
        """Bad --message argument gives a sensible message
384
 
 
385
 
        See https://bugs.launchpad.net/bzr/+bug/251352
386
 
        """
387
 
        self.make_minimal_branch()
388
 
        out, err = self.run_bzr(['log', '-m', '*'], retcode=3)
389
 
        self.assertContainsRe(err, "ERROR.*Invalid pattern.*nothing to repeat")
390
 
        self.assertNotContainsRe(err, "Unprintable exception")
391
 
        self.assertEqual(out, '')
392
 
 
393
 
    def test_log_unsupported_timezone(self):
394
 
        self.make_linear_branch()
395
 
        self.run_bzr_error(['bzr: ERROR: Unsupported timezone format "foo", '
396
 
                            'options are "utc", "original", "local".'],
397
 
                           ['log', '--timezone', 'foo'])
398
 
 
399
 
    def test_log_exclude_ancestry_no_range(self):
400
 
        self.make_linear_branch()
401
 
        self.run_bzr_error(['bzr: ERROR: --exclude-common-ancestry'
402
 
                            ' requires -r with two revisions'],
403
 
                           ['log', '--exclude-common-ancestry'])
404
 
 
405
 
    def test_log_exclude_ancestry_single_revision(self):
406
 
        self.make_merged_branch()
407
 
        self.run_bzr_error(['bzr: ERROR: --exclude-common-ancestry'
408
 
                            ' requires two different revisions'],
409
 
                           ['log', '--exclude-common-ancestry',
410
 
                            '-r1.1.1..1.1.1'])
411
 
 
412
 
class TestLogTags(TestLog):
413
 
 
414
 
    def test_log_with_tags(self):
415
 
        tree = self.make_linear_branch(format='dirstate-tags')
416
 
        branch = tree.branch
417
 
        branch.tags.set_tag('tag1', branch.get_rev_id(1))
418
 
        branch.tags.set_tag('tag1.1', branch.get_rev_id(1))
419
 
        branch.tags.set_tag('tag3', branch.last_revision())
420
 
 
421
 
        log = self.run_bzr("log -r-1")[0]
422
 
        self.assertTrue('tags: tag3' in log)
423
 
 
424
 
        log = self.run_bzr("log -r1")[0]
425
 
        # I guess that we can't know the order of tags in the output
426
 
        # since dicts are unordered, need to check both possibilities
427
 
        self.assertContainsRe(log, r'tags: (tag1, tag1\.1|tag1\.1, tag1)')
428
 
 
429
 
    def test_merged_log_with_tags(self):
430
 
        branch1_tree = self.make_linear_branch('branch1',
431
 
                                               format='dirstate-tags')
432
 
        branch1 = branch1_tree.branch
433
 
        branch2_tree = branch1_tree.bzrdir.sprout('branch2').open_workingtree()
434
 
        branch1_tree.commit(message='foobar', allow_pointless=True)
435
 
        branch1.tags.set_tag('tag1', branch1.last_revision())
436
 
        # tags don't propagate if we don't merge
437
 
        self.run_bzr('merge ../branch1', working_dir='branch2')
438
 
        branch2_tree.commit(message='merge branch 1')
439
 
        log = self.run_bzr("log -n0 -r-1", working_dir='branch2')[0]
440
 
        self.assertContainsRe(log, r'    tags: tag1')
441
 
        log = self.run_bzr("log -n0 -r3.1.1", working_dir='branch2')[0]
442
 
        self.assertContainsRe(log, r'tags: tag1')
443
 
 
444
 
 
445
 
class TestLogVerbose(TestLog):
446
 
 
447
 
    def setUp(self):
448
 
        super(TestLogVerbose, self).setUp()
449
 
        self.make_minimal_branch()
450
 
 
451
 
    def assertUseShortDeltaFormat(self, cmd):
452
 
        log = self.run_bzr(cmd)[0]
453
 
        # Check that we use the short status format
454
 
        self.assertContainsRe(log, '(?m)^\s*A  hello.txt$')
455
 
        self.assertNotContainsRe(log, '(?m)^\s*added:$')
456
 
 
457
 
    def assertUseLongDeltaFormat(self, cmd):
458
 
        log = self.run_bzr(cmd)[0]
459
 
        # Check that we use the long status format
460
 
        self.assertNotContainsRe(log, '(?m)^\s*A  hello.txt$')
461
 
        self.assertContainsRe(log, '(?m)^\s*added:$')
462
 
 
463
 
    def test_log_short_verbose(self):
464
 
        self.assertUseShortDeltaFormat(['log', '--short', '-v'])
465
 
 
466
 
    def test_log_short_verbose_verbose(self):
467
 
        self.assertUseLongDeltaFormat(['log', '--short', '-vv'])
468
 
 
469
 
    def test_log_long_verbose(self):
470
 
        # Check that we use the long status format, ignoring the verbosity
471
 
        # level
472
 
        self.assertUseLongDeltaFormat(['log', '--long', '-v'])
473
 
 
474
 
    def test_log_long_verbose_verbose(self):
475
 
        # Check that we use the long status format, ignoring the verbosity
476
 
        # level
477
 
        self.assertUseLongDeltaFormat(['log', '--long', '-vv'])
478
 
 
479
 
 
480
 
class TestLogMerges(TestLogWithLogCatcher):
481
 
 
482
 
    def setUp(self):
483
 
        super(TestLogMerges, self).setUp()
484
 
        self.make_branches_with_merges()
485
 
 
486
 
    def make_branches_with_merges(self):
487
 
        level0 = self.make_branch_and_tree('level0')
488
 
        self.wt_commit(level0, 'in branch level0')
489
 
        level1 = level0.bzrdir.sprout('level1').open_workingtree()
490
 
        self.wt_commit(level1, 'in branch level1')
491
 
        level2 = level1.bzrdir.sprout('level2').open_workingtree()
492
 
        self.wt_commit(level2, 'in branch level2')
493
 
        level1.merge_from_branch(level2.branch)
494
 
        self.wt_commit(level1, 'merge branch level2')
495
 
        level0.merge_from_branch(level1.branch)
496
 
        self.wt_commit(level0, 'merge branch level1')
 
81
        self._prepare()
 
82
        log = self.runbzr("log -r -2..")[0]
 
83
        self.assertTrue('revno: 1\n' not in log)
 
84
        self.assertTrue('revno: 2\n' in log)
 
85
        self.assertTrue('revno: 3\n' in log)
 
86
 
 
87
    def test_log_postive_revspecs(self):
 
88
        self._prepare()
 
89
        log = self.runbzr("log -r 1..3")[0]
 
90
        self.assertEquals(self.full_log, log)
 
91
 
 
92
 
 
93
class TestLogMerges(ExternalBase):
497
94
 
498
95
    def test_merges_are_indented_by_level(self):
499
 
        self.run_bzr(['log', '-n0'], working_dir='level0')
500
 
        revnos_and_depth = [(r.revno, r.merge_depth)
501
 
                            for r in self.get_captured_revisions()]
502
 
        self.assertEqual([('2', 0), ('1.1.2', 1), ('1.2.1', 2), ('1.1.1', 1),
503
 
                          ('1', 0)],
504
 
                         [(r.revno, r.merge_depth)
505
 
                            for r in self.get_captured_revisions()])
506
 
 
507
 
    def test_force_merge_revisions_off(self):
508
 
        self.assertLogRevnos(['-n1'], ['2', '1'], working_dir='level0')
509
 
 
510
 
    def test_force_merge_revisions_on(self):
511
 
        self.assertLogRevnos(['-n0'], ['2', '1.1.2', '1.2.1', '1.1.1', '1'],
512
 
                             working_dir='level0')
513
 
 
514
 
    def test_include_merges(self):
515
 
        # Confirm --include-merges gives the same output as -n0
516
 
        self.assertLogRevnos(['--include-merges'],
517
 
                             ['2', '1.1.2', '1.2.1', '1.1.1', '1'],
518
 
                             working_dir='level0')
519
 
        self.assertLogRevnos(['--include-merges'],
520
 
                             ['2', '1.1.2', '1.2.1', '1.1.1', '1'],
521
 
                             working_dir='level0')
522
 
        out_im, err_im = self.run_bzr('log --include-merges',
523
 
                                      working_dir='level0')
524
 
        out_n0, err_n0 = self.run_bzr('log -n0', working_dir='level0')
525
 
        self.assertEqual('', err_im)
526
 
        self.assertEqual('', err_n0)
527
 
        self.assertEqual(out_im, out_n0)
528
 
 
529
 
    def test_force_merge_revisions_N(self):
530
 
        self.assertLogRevnos(['-n2'],
531
 
                             ['2', '1.1.2', '1.1.1', '1'],
532
 
                             working_dir='level0')
533
 
 
534
 
    def test_merges_single_merge_rev(self):
535
 
        self.assertLogRevnosAndDepths(['-n0', '-r1.1.2'],
536
 
                                      [('1.1.2', 0), ('1.2.1', 1)],
537
 
                                      working_dir='level0')
538
 
 
539
 
    def test_merges_partial_range(self):
540
 
        self.assertLogRevnosAndDepths(
541
 
                ['-n0', '-r1.1.1..1.1.2'],
542
 
                [('1.1.2', 0), ('1.2.1', 1), ('1.1.1', 0)],
543
 
                working_dir='level0')
544
 
 
545
 
    def test_merges_partial_range_ignore_before_lower_bound(self):
546
 
        """Dont show revisions before the lower bound's merged revs"""
547
 
        self.assertLogRevnosAndDepths(
548
 
                ['-n0', '-r1.1.2..2'],
549
 
                [('2', 0), ('1.1.2', 1), ('1.2.1', 2)],
550
 
                working_dir='level0')
551
 
 
552
 
 
553
 
class TestLogDiff(TestLogWithLogCatcher):
554
 
 
555
 
    # FIXME: We need specific tests for each LogFormatter about how the diffs
556
 
    # are displayed: --long indent them by depth, --short use a fixed
557
 
    # indent and --line does't display them. -- vila 10019
558
 
 
559
 
    def setUp(self):
560
 
        super(TestLogDiff, self).setUp()
561
 
        self.make_branch_with_diffs()
562
 
 
563
 
    def make_branch_with_diffs(self):
564
 
        level0 = self.make_branch_and_tree('level0')
565
 
        self.build_tree(['level0/file1', 'level0/file2'])
566
 
        level0.add('file1')
567
 
        level0.add('file2')
568
 
        self.wt_commit(level0, 'in branch level0')
569
 
 
570
 
        level1 = level0.bzrdir.sprout('level1').open_workingtree()
571
 
        self.build_tree_contents([('level1/file2', 'hello\n')])
572
 
        self.wt_commit(level1, 'in branch level1')
573
 
        level0.merge_from_branch(level1.branch)
574
 
        self.wt_commit(level0, 'merge branch level1')
575
 
 
576
 
    def _diff_file1_revno1(self):
577
 
        return """=== added file 'file1'
578
 
--- file1\t1970-01-01 00:00:00 +0000
579
 
+++ file1\t2005-11-22 00:00:00 +0000
580
 
@@ -0,0 +1,1 @@
581
 
+contents of level0/file1
582
 
 
583
 
"""
584
 
 
585
 
    def _diff_file2_revno2(self):
586
 
        return """=== modified file 'file2'
587
 
--- file2\t2005-11-22 00:00:00 +0000
588
 
+++ file2\t2005-11-22 00:00:01 +0000
589
 
@@ -1,1 +1,1 @@
590
 
-contents of level0/file2
591
 
+hello
592
 
 
593
 
"""
594
 
 
595
 
    def _diff_file2_revno1_1_1(self):
596
 
        return """=== modified file 'file2'
597
 
--- file2\t2005-11-22 00:00:00 +0000
598
 
+++ file2\t2005-11-22 00:00:01 +0000
599
 
@@ -1,1 +1,1 @@
600
 
-contents of level0/file2
601
 
+hello
602
 
 
603
 
"""
604
 
 
605
 
    def _diff_file2_revno1(self):
606
 
        return """=== added file 'file2'
607
 
--- file2\t1970-01-01 00:00:00 +0000
608
 
+++ file2\t2005-11-22 00:00:00 +0000
609
 
@@ -0,0 +1,1 @@
610
 
+contents of level0/file2
611
 
 
612
 
"""
613
 
 
614
 
    def assertLogRevnosAndDiff(self, args, expected,
615
 
                            working_dir='.'):
616
 
        self.run_bzr(['log', '-p'] + args, working_dir=working_dir)
617
 
        expected_revnos_and_depths = [
618
 
            (revno, depth) for revno, depth, diff in expected]
619
 
        # Check the revnos and depths first to make debugging easier
620
 
        self.assertEqual(expected_revnos_and_depths,
621
 
                         [(r.revno, r.merge_depth)
622
 
                           for r in self.get_captured_revisions()])
623
 
        # Now check the diffs, adding the revno  in case of failure
624
 
        fmt = 'In revno %s\n%s'
625
 
        for expected_rev, actual_rev in izip(expected,
626
 
                                             self.get_captured_revisions()):
627
 
            revno, depth, expected_diff = expected_rev
628
 
            actual_diff = actual_rev.diff
629
 
            self.assertEqualDiff(fmt % (revno, expected_diff),
630
 
                                 fmt % (revno, actual_diff))
631
 
 
632
 
    def test_log_diff_with_merges(self):
633
 
        self.assertLogRevnosAndDiff(
634
 
            ['-n0'],
635
 
            [('2', 0, self._diff_file2_revno2()),
636
 
             ('1.1.1', 1, self._diff_file2_revno1_1_1()),
637
 
             ('1', 0, self._diff_file1_revno1()
638
 
              + self._diff_file2_revno1())],
639
 
            working_dir='level0')
640
 
 
641
 
 
642
 
    def test_log_diff_file1(self):
643
 
        self.assertLogRevnosAndDiff(['-n0', 'file1'],
644
 
                                    [('1', 0, self._diff_file1_revno1())],
645
 
                                    working_dir='level0')
646
 
 
647
 
    def test_log_diff_file2(self):
648
 
        self.assertLogRevnosAndDiff(['-n1', 'file2'],
649
 
                                    [('2', 0, self._diff_file2_revno2()),
650
 
                                     ('1', 0, self._diff_file2_revno1())],
651
 
                                    working_dir='level0')
652
 
 
653
 
 
654
 
class TestLogUnicodeDiff(TestLog):
655
 
 
656
 
    def test_log_show_diff_non_ascii(self):
657
 
        # Smoke test for bug #328007 UnicodeDecodeError on 'log -p'
658
 
        message = u'Message with \xb5'
659
 
        body = 'Body with \xb5\n'
660
 
        wt = self.make_branch_and_tree('.')
661
 
        self.build_tree_contents([('foo', body)])
662
 
        wt.add('foo')
663
 
        wt.commit(message=message)
664
 
        # check that command won't fail with unicode error
665
 
        # don't care about exact output because we have other tests for this
666
 
        out,err = self.run_bzr('log -p --long')
667
 
        self.assertNotEqual('', out)
668
 
        self.assertEqual('', err)
669
 
        out,err = self.run_bzr('log -p --short')
670
 
        self.assertNotEqual('', out)
671
 
        self.assertEqual('', err)
672
 
        out,err = self.run_bzr('log -p --line')
673
 
        self.assertNotEqual('', out)
674
 
        self.assertEqual('', err)
675
 
 
676
 
 
677
 
class TestLogEncodings(tests.TestCaseInTempDir):
 
96
        self.build_tree(['parent/'])
 
97
        self.run_bzr('init', 'parent')
 
98
        self.run_bzr('commit', '-m', 'first post', '--unchanged', 'parent')
 
99
        self.run_bzr('branch', 'parent', 'child')
 
100
        self.run_bzr('commit', '-m', 'branch 1', '--unchanged', 'child')
 
101
        self.run_bzr('branch', 'child', 'smallerchild')
 
102
        self.run_bzr('commit', '-m', 'branch 2', '--unchanged', 'smallerchild')
 
103
        os.chdir('child')
 
104
        self.run_bzr('merge', '../smallerchild')
 
105
        self.run_bzr('commit', '-m', 'merge branch 2')
 
106
        os.chdir('../parent')
 
107
        self.run_bzr('merge', '../child')
 
108
        self.run_bzr('commit', '-m', 'merge branch 1')
 
109
        out,err = self.run_bzr('log')
 
110
        # the log will look something like:
 
111
#        self.assertEqual("""\
 
112
#------------------------------------------------------------
 
113
#revno: 2
 
114
#committer: Robert Collins <foo@example.com>
 
115
#branch nick: parent
 
116
#timestamp: Tue 2006-03-28 22:31:40 +1100
 
117
#message:
 
118
#  merge branch 1
 
119
#    ------------------------------------------------------------
 
120
#    merged: foo@example.com-20060328113140-91f43cfb46dc2863
 
121
#    committer: Robert Collins <foo@example.com>
 
122
#    branch nick: child
 
123
#    timestamp: Tue 2006-03-28 22:31:40 +1100
 
124
#    message:
 
125
#      merge branch 2
 
126
#        ------------------------------------------------------------
 
127
#        merged: foo@example.com-20060328113140-1ba24f850a0ef573
 
128
#        committer: Robert Collins <foo@example.com>
 
129
#        branch nick: smallerchild
 
130
#        timestamp: Tue 2006-03-28 22:31:40 +1100
 
131
#        message:
 
132
#          branch 2
 
133
#    ------------------------------------------------------------
 
134
#    merged: foo@example.com-20060328113140-5749a4757a8ac792
 
135
#    committer: Robert Collins <foo@example.com>
 
136
#    branch nick: child
 
137
#    timestamp: Tue 2006-03-28 22:31:40 +1100
 
138
#    message:
 
139
#      branch 1
 
140
#------------------------------------------------------------
 
141
#revno: 1
 
142
#committer: Robert Collins <foo@example.com>
 
143
#branch nick: parent
 
144
#timestamp: Tue 2006-03-28 22:31:39 +1100
 
145
#message:
 
146
#  first post
 
147
#""", out)
 
148
        # but we dont have a nice pattern matcher hooked up yet, so:
 
149
        # we check for the indenting of the commit message:
 
150
        self.assertTrue('  merge branch 1' in out)
 
151
        self.assertTrue('      merge branch 2' in out)
 
152
        self.assertTrue('          branch 2' in out)
 
153
        self.assertTrue('      branch 1' in out)
 
154
        self.assertTrue('  first post' in out)
 
155
        self.assertEqual('', err)
 
156
 
 
157
 
 
158
class TestLogEncodings(TestCaseInTempDir):
678
159
 
679
160
    _mu = u'\xb5'
680
161
    _message = u'Message with \xb5'
685
166
        'latin-1',
686
167
        'iso-8859-1',
687
168
        'cp437', # Common windows encoding
688
 
        'cp1251', # Russian windows encoding
 
169
        'cp1251', # Alexander Belchenko's windows encoding
689
170
        'cp1258', # Common windows encoding
690
171
    ]
691
172
    # Encodings which cannot encode mu
696
177
    ]
697
178
 
698
179
    def setUp(self):
699
 
        super(TestLogEncodings, self).setUp()
700
 
        self.overrideAttr(osutils, '_cached_user_encoding')
 
180
        TestCaseInTempDir.setUp(self)
 
181
        self.user_encoding = bzrlib.user_encoding
 
182
 
 
183
    def tearDown(self):
 
184
        bzrlib.user_encoding = self.user_encoding
 
185
        TestCaseInTempDir.tearDown(self)
701
186
 
702
187
    def create_branch(self):
703
188
        bzr = self.run_bzr
704
189
        bzr('init')
705
 
        self.build_tree_contents([('a', 'some stuff\n')])
706
 
        bzr('add a')
707
 
        bzr(['commit', '-m', self._message])
 
190
        open('a', 'wb').write('some stuff\n')
 
191
        bzr('add', 'a')
 
192
        bzr('commit', '-m', self._message)
708
193
 
709
194
    def try_encoding(self, encoding, fail=False):
710
195
        bzr = self.run_bzr
715
200
        else:
716
201
            encoded_msg = self._message.encode(encoding)
717
202
 
718
 
        old_encoding = osutils._cached_user_encoding
 
203
        old_encoding = bzrlib.user_encoding
719
204
        # This test requires that 'run_bzr' uses the current
720
205
        # bzrlib, because we override user_encoding, and expect
721
206
        # it to be used
722
207
        try:
723
 
            osutils._cached_user_encoding = 'ascii'
 
208
            bzrlib.user_encoding = 'ascii'
724
209
            # We should be able to handle any encoding
725
210
            out, err = bzr('log', encoding=encoding)
726
211
            if not fail:
731
216
            else:
732
217
                self.assertNotEqual(-1, out.find('Message with ?'))
733
218
        finally:
734
 
            osutils._cached_user_encoding = old_encoding
 
219
            bzrlib.user_encoding = old_encoding
735
220
 
736
221
    def test_log_handles_encoding(self):
737
222
        self.create_branch()
747
232
 
748
233
    def test_stdout_encoding(self):
749
234
        bzr = self.run_bzr
750
 
        osutils._cached_user_encoding = "cp1251"
 
235
        bzrlib.user_encoding = "cp1251"
751
236
 
752
237
        bzr('init')
753
238
        self.build_tree(['a'])
754
 
        bzr('add a')
755
 
        bzr(['commit', '-m', u'\u0422\u0435\u0441\u0442'])
 
239
        bzr('add', 'a')
 
240
        bzr('commit', '-m', u'\u0422\u0435\u0441\u0442')
756
241
        stdout, stderr = self.run_bzr('log', encoding='cp866')
757
242
 
758
243
        message = stdout.splitlines()[-1]
770
255
        # Make sure the cp1251 string is not found anywhere
771
256
        self.assertEquals(-1, stdout.find(test_in_cp1251))
772
257
 
773
 
 
774
 
class TestLogFile(TestLogWithLogCatcher):
775
 
 
776
 
    def test_log_local_branch_file(self):
777
 
        """We should be able to log files in local treeless branches"""
778
 
        tree = self.make_branch_and_tree('tree')
779
 
        self.build_tree(['tree/file'])
780
 
        tree.add('file')
781
 
        tree.commit('revision 1')
782
 
        tree.bzrdir.destroy_workingtree()
783
 
        self.run_bzr('log tree/file')
784
 
 
785
 
    def prepare_tree(self, complex=False):
786
 
        # The complex configuration includes deletes and renames
787
 
        tree = self.make_branch_and_tree('parent')
788
 
        self.build_tree(['parent/file1', 'parent/file2', 'parent/file3'])
789
 
        tree.add('file1')
790
 
        tree.commit('add file1')
791
 
        tree.add('file2')
792
 
        tree.commit('add file2')
793
 
        tree.add('file3')
794
 
        tree.commit('add file3')
795
 
        child_tree = tree.bzrdir.sprout('child').open_workingtree()
796
 
        self.build_tree_contents([('child/file2', 'hello')])
797
 
        child_tree.commit(message='branch 1')
798
 
        tree.merge_from_branch(child_tree.branch)
799
 
        tree.commit(message='merge child branch')
800
 
        if complex:
801
 
            tree.remove('file2')
802
 
            tree.commit('remove file2')
803
 
            tree.rename_one('file3', 'file4')
804
 
            tree.commit('file3 is now called file4')
805
 
            tree.remove('file1')
806
 
            tree.commit('remove file1')
807
 
        os.chdir('parent')
808
 
 
809
 
    # FIXME: It would be good to parametrize the following tests against all
810
 
    # formatters. But the revisions selection is not *currently* part of the
811
 
    # LogFormatter contract, so using LogCatcher is sufficient -- vila 100118
812
 
    def test_log_file1(self):
813
 
        self.prepare_tree()
814
 
        self.assertLogRevnos(['-n0', 'file1'], ['1'])
815
 
 
816
 
    def test_log_file2(self):
817
 
        self.prepare_tree()
818
 
        # file2 full history
819
 
        self.assertLogRevnos(['-n0', 'file2'], ['4', '3.1.1', '2'])
820
 
        # file2 in a merge revision
821
 
        self.assertLogRevnos(['-n0', '-r3.1.1', 'file2'], ['3.1.1'])
822
 
        # file2 in a mainline revision
823
 
        self.assertLogRevnos(['-n0', '-r4', 'file2'], ['4', '3.1.1'])
824
 
        # file2 since a revision
825
 
        self.assertLogRevnos(['-n0', '-r3..', 'file2'], ['4', '3.1.1'])
826
 
        # file2 up to a revision
827
 
        self.assertLogRevnos(['-n0', '-r..3', 'file2'], ['2'])
828
 
 
829
 
    def test_log_file3(self):
830
 
        self.prepare_tree()
831
 
        self.assertLogRevnos(['-n0', 'file3'], ['3'])
832
 
 
833
 
    def test_log_file_historical_missing(self):
834
 
        # Check logging a deleted file gives an error if the
835
 
        # file isn't found at the end or start of the revision range
836
 
        self.prepare_tree(complex=True)
837
 
        err_msg = "Path unknown at end or start of revision range: file2"
838
 
        err = self.run_bzr('log file2', retcode=3)[1]
839
 
        self.assertContainsRe(err, err_msg)
840
 
 
841
 
    def test_log_file_historical_end(self):
842
 
        # Check logging a deleted file is ok if the file existed
843
 
        # at the end the revision range
844
 
        self.prepare_tree(complex=True)
845
 
        self.assertLogRevnos(['-n0', '-r..4', 'file2'], ['4', '3.1.1', '2'])
846
 
 
847
 
    def test_log_file_historical_start(self):
848
 
        # Check logging a deleted file is ok if the file existed
849
 
        # at the start of the revision range
850
 
        self.prepare_tree(complex=True)
851
 
        self.assertLogRevnos(['file1'], ['1'])
852
 
 
853
 
    def test_log_file_renamed(self):
854
 
        """File matched against revision range, not current tree."""
855
 
        self.prepare_tree(complex=True)
856
 
 
857
 
        # Check logging a renamed file gives an error by default
858
 
        err_msg = "Path unknown at end or start of revision range: file3"
859
 
        err = self.run_bzr('log file3', retcode=3)[1]
860
 
        self.assertContainsRe(err, err_msg)
861
 
 
862
 
        # Check we can see a renamed file if we give the right end revision
863
 
        self.assertLogRevnos(['-r..4', 'file3'], ['3'])
864
 
 
865
 
 
866
 
class TestLogMultiple(TestLogWithLogCatcher):
867
 
 
868
 
    def prepare_tree(self):
869
 
        tree = self.make_branch_and_tree('parent')
870
 
        self.build_tree([
871
 
            'parent/file1',
872
 
            'parent/file2',
873
 
            'parent/dir1/',
874
 
            'parent/dir1/file5',
875
 
            'parent/dir1/dir2/',
876
 
            'parent/dir1/dir2/file3',
877
 
            'parent/file4'])
878
 
        tree.add('file1')
879
 
        tree.commit('add file1')
880
 
        tree.add('file2')
881
 
        tree.commit('add file2')
882
 
        tree.add(['dir1', 'dir1/dir2', 'dir1/dir2/file3'])
883
 
        tree.commit('add file3')
884
 
        tree.add('file4')
885
 
        tree.commit('add file4')
886
 
        tree.add('dir1/file5')
887
 
        tree.commit('add file5')
888
 
        child_tree = tree.bzrdir.sprout('child').open_workingtree()
889
 
        self.build_tree_contents([('child/file2', 'hello')])
890
 
        child_tree.commit(message='branch 1')
891
 
        tree.merge_from_branch(child_tree.branch)
892
 
        tree.commit(message='merge child branch')
893
 
        os.chdir('parent')
894
 
 
895
 
    def test_log_files(self):
896
 
        """The log for multiple file should only list revs for those files"""
897
 
        self.prepare_tree()
898
 
        self.assertLogRevnos(['file1', 'file2', 'dir1/dir2/file3'],
899
 
                             ['6', '5.1.1', '3', '2', '1'])
900
 
 
901
 
    def test_log_directory(self):
902
 
        """The log for a directory should show all nested files."""
903
 
        self.prepare_tree()
904
 
        self.assertLogRevnos(['dir1'], ['5', '3'])
905
 
 
906
 
    def test_log_nested_directory(self):
907
 
        """The log for a directory should show all nested files."""
908
 
        self.prepare_tree()
909
 
        self.assertLogRevnos(['dir1/dir2'], ['3'])
910
 
 
911
 
    def test_log_in_nested_directory(self):
912
 
        """The log for a directory should show all nested files."""
913
 
        self.prepare_tree()
914
 
        os.chdir("dir1")
915
 
        self.assertLogRevnos(['.'], ['5', '3'])
916
 
 
917
 
    def test_log_files_and_directories(self):
918
 
        """Logging files and directories together should be fine."""
919
 
        self.prepare_tree()
920
 
        self.assertLogRevnos(['file4', 'dir1/dir2'], ['4', '3'])
921
 
 
922
 
    def test_log_files_and_dirs_in_nested_directory(self):
923
 
        """The log for a directory should show all nested files."""
924
 
        self.prepare_tree()
925
 
        os.chdir("dir1")
926
 
        self.assertLogRevnos(['dir2', 'file5'], ['5', '3'])