/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
2359.1.6 by John Arbash Meinel
Create a helper tree which has a semi-interesting history.
1
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
1685.1.80 by Wouter van Heyst
more code cleanup
2
#
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
1685.1.80 by Wouter van Heyst
more code cleanup
7
#
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
1685.1.80 by Wouter van Heyst
more code cleanup
12
#
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
import os
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
18
from cStringIO import StringIO
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
19
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
20
from bzrlib import (
21
    errors,
22
    log,
23
    registry,
24
    revision,
25
    revisionspec,
26
    tests,
27
    )
28
29
30
class TestCaseWithoutPropsHandler(tests.TestCaseWithTransport):
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
31
32
    def setUp(self):
33
        super(TestCaseWithoutPropsHandler, self).setUp()
34
        # keep a reference to the "current" custom prop. handler registry
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
35
        self.properties_handler_registry = log.properties_handler_registry
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
36
        # clean up the registry in log
37
        log.properties_handler_registry = registry.Registry()
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
38
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
39
    def _cleanup(self):
3144.7.13 by Guillermo Gonzalez
* fixed typo LogFormatter.show_properties in docstring
40
        super(TestCaseWithoutPropsHandler, self)._cleanup()
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
41
        # restore the custom properties handler registry
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
42
        log.properties_handler_registry = self.properties_handler_registry
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
43
44
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
45
class LogCatcher(log.LogFormatter):
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
46
    """Pull log messages into list rather than displaying them.
47
48
    For ease of testing we save log messages here rather than actually
49
    formatting them, so that we can precisely check the result without
50
    being too dependent on the exact formatting.
51
52
    We should also test the LogFormatter.
53
    """
2466.8.1 by Kent Gibson
Reworked LogFormatter API to simplify extending the attributes of the revision being logged. Added support for begin_log() and end_log() hooks in LogFormatters.
54
2490.1.2 by John Arbash Meinel
Cleanup according to PEP8 and some other small whitespace fixes
55
    supports_delta = True
2466.8.1 by Kent Gibson
Reworked LogFormatter API to simplify extending the attributes of the revision being logged. Added support for begin_log() and end_log() hooks in LogFormatters.
56
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
57
    def __init__(self):
58
        super(LogCatcher, self).__init__(to_file=None)
59
        self.logs = []
1704.2.20 by Martin Pool
log --line shows revision numbers (Alexander)
60
2466.8.1 by Kent Gibson
Reworked LogFormatter API to simplify extending the attributes of the revision being logged. Added support for begin_log() and end_log() hooks in LogFormatters.
61
    def log_revision(self, revision):
62
        self.logs.append(revision)
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
63
64
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
65
class TestShowLog(tests.TestCaseWithTransport):
1102 by Martin Pool
- merge test refactoring from robertc
66
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
67
    def checkDelta(self, delta, **kw):
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
68
        """Check the filenames touched by a delta are as expected.
69
70
        Caller only have to pass in the list of files for each part, all
71
        unspecified parts are considered empty (and checked as such).
72
        """
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
73
        for n in 'added', 'removed', 'renamed', 'modified', 'unchanged':
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
74
            # By default we expect an empty list
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
75
            expected = kw.get(n, [])
76
            # strip out only the path components
77
            got = [x[0] for x in getattr(delta, n)]
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
78
            self.assertEqual(expected, got)
79
80
    def assertInvalidRevisonNumber(self, br, start, end):
81
        lf = LogCatcher()
82
        self.assertRaises(errors.InvalidRevisionNumber,
83
                          log.show_log, br, lf,
84
                          start_revision=start, end_revision=end)
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
85
974.1.54 by aaron.bentley at utoronto
Fixed the revno bug in log
86
    def test_cur_revno(self):
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
87
        wt = self.make_branch_and_tree('.')
88
        b = wt.branch
1092.3.4 by Robert Collins
update symlink branch to integration
89
90
        lf = LogCatcher()
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
91
        wt.commit('empty commit')
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
92
        log.show_log(b, lf, verbose=True, start_revision=1, end_revision=1)
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
93
94
        # Since there is a single revision in the branch all the combinations
95
        # below should fail.
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
96
        self.assertInvalidRevisonNumber(b, 2, 1)
97
        self.assertInvalidRevisonNumber(b, 1, 2)
98
        self.assertInvalidRevisonNumber(b, 0, 2)
99
        self.assertInvalidRevisonNumber(b, 1, 0)
100
        self.assertInvalidRevisonNumber(b, -1, 1)
101
        self.assertInvalidRevisonNumber(b, 1, -1)
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
102
103
    def test_empty_branch(self):
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
104
        wt = self.make_branch_and_tree('.')
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
105
106
        lf = LogCatcher()
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
107
        log.show_log(wt.branch, lf)
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
108
        # no entries yet
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
109
        self.assertEqual([], lf.logs)
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
110
111
    def test_empty_commit(self):
112
        wt = self.make_branch_and_tree('.')
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
113
1534.4.36 by Robert Collins
Finish deprecating Branch.working_tree()
114
        wt.commit('empty commit')
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
115
        lf = LogCatcher()
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
116
        log.show_log(wt.branch, lf, verbose=True)
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
117
        self.assertEqual(1, len(lf.logs))
118
        self.assertEqual('1', lf.logs[0].revno)
119
        self.assertEqual('empty commit', lf.logs[0].rev.message)
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
120
        self.checkDelta(lf.logs[0].delta)
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
121
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
122
    def test_simple_commit(self):
123
        wt = self.make_branch_and_tree('.')
124
        wt.commit('empty commit')
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
125
        self.build_tree(['hello'])
1534.4.36 by Robert Collins
Finish deprecating Branch.working_tree()
126
        wt.add('hello')
2717.1.1 by Lukáš Lalinsky
Use UTF-8 encoded StringIO for log tests to avoid failures on non-ASCII committer names.
127
        wt.commit('add one file',
128
                  committer=u'\u013d\xf3r\xe9m \xcdp\u0161\xfam '
129
                            u'<test@example.com>')
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
130
        lf = LogCatcher()
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
131
        log.show_log(wt.branch, lf, verbose=True)
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
132
        self.assertEqual(2, len(lf.logs))
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
133
        # first one is most recent
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
134
        log_entry = lf.logs[0]
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
135
        self.assertEqual('2', log_entry.revno)
136
        self.assertEqual('add one file', log_entry.rev.message)
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
137
        self.checkDelta(log_entry.delta, added=['hello'])
3831.1.6 by John Arbash Meinel
For the simple-log tests, avoid using '\r' in the test.
138
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
139
    def test_commit_message_with_control_chars(self):
140
        wt = self.make_branch_and_tree('.')
3831.1.6 by John Arbash Meinel
For the simple-log tests, avoid using '\r' in the test.
141
        msg = u"All 8-bit chars: " +  ''.join([unichr(x) for x in range(256)])
142
        msg = msg.replace(u'\r', u'\n')
1534.4.36 by Robert Collins
Finish deprecating Branch.working_tree()
143
        wt.commit(msg)
1185.11.5 by John Arbash Meinel
Merged up-to-date against mainline, still broken.
144
        lf = LogCatcher()
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
145
        log.show_log(wt.branch, lf, verbose=True)
1185.11.5 by John Arbash Meinel
Merged up-to-date against mainline, still broken.
146
        committed_msg = lf.logs[0].rev.message
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
147
        self.assertNotEqual(msg, committed_msg)
148
        self.assertTrue(len(committed_msg) > len(msg))
1393.4.2 by Harald Meland
Cleanup + better test of commit-msg control character escape code.
149
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
150
    def test_commit_message_without_control_chars(self):
151
        wt = self.make_branch_and_tree('.')
1393.4.2 by Harald Meland
Cleanup + better test of commit-msg control character escape code.
152
        # escaped.  As ElementTree apparently does some kind of
153
        # newline conversion, neither LF (\x0A) nor CR (\x0D) are
154
        # included in the test commit message, even though they are
155
        # valid XML 1.0 characters.
156
        msg = "\x09" + ''.join([unichr(x) for x in range(0x20, 256)])
1534.4.36 by Robert Collins
Finish deprecating Branch.working_tree()
157
        wt.commit(msg)
1393.4.2 by Harald Meland
Cleanup + better test of commit-msg control character escape code.
158
        lf = LogCatcher()
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
159
        log.show_log(wt.branch, lf, verbose=True)
1393.4.2 by Harald Meland
Cleanup + better test of commit-msg control character escape code.
160
        committed_msg = lf.logs[0].rev.message
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
161
        self.assertEqual(msg, committed_msg)
1185.31.22 by John Arbash Meinel
[merge] bzr.dev
162
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
163
    def test_deltas_in_merge_revisions(self):
164
        """Check deltas created for both mainline and merge revisions"""
165
        wt = self.make_branch_and_tree('parent')
166
        self.build_tree(['parent/file1', 'parent/file2', 'parent/file3'])
167
        wt.add('file1')
168
        wt.add('file2')
169
        wt.commit(message='add file1 and file2')
2581.1.6 by Martin Pool
fix up more run_bzr callers
170
        self.run_bzr('branch parent child')
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
171
        os.unlink('child/file1')
2911.6.1 by Blake Winton
Change 'print >> f,'s to 'f.write('s.
172
        file('child/file2', 'wb').write('hello\n')
2581.1.6 by Martin Pool
fix up more run_bzr callers
173
        self.run_bzr(['commit', '-m', 'remove file1 and modify file2',
174
            'child'])
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
175
        os.chdir('parent')
2581.1.6 by Martin Pool
fix up more run_bzr callers
176
        self.run_bzr('merge ../child')
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
177
        wt.commit('merge child branch')
178
        os.chdir('..')
179
        b = wt.branch
180
        lf = LogCatcher()
181
        lf.supports_merge_revisions = True
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
182
        log.show_log(b, lf, verbose=True)
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
183
184
        self.assertEqual(3, len(lf.logs))
185
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
186
        logentry = lf.logs[0]
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
187
        self.assertEqual('2', logentry.revno)
188
        self.assertEqual('merge child branch', logentry.rev.message)
189
        self.checkDelta(logentry.delta, removed=['file1'], modified=['file2'])
190
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
191
        logentry = lf.logs[1]
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
192
        self.assertEqual('1.1.1', logentry.revno)
193
        self.assertEqual('remove file1 and modify file2', logentry.rev.message)
194
        self.checkDelta(logentry.delta, removed=['file1'], modified=['file2'])
195
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
196
        logentry = lf.logs[2]
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
197
        self.assertEqual('1', logentry.revno)
198
        self.assertEqual('add file1 and file2', logentry.rev.message)
199
        self.checkDelta(logentry.delta, added=['file1', 'file2'])
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
200
2997.1.1 by Kent Gibson
Support logging single merge revisions with short and line log formatters.
201
    def test_merges_nonsupporting_formatter(self):
202
        """Tests that show_log will raise if the formatter doesn't
203
        support merge revisions."""
204
        wt = self.make_branch_and_memory_tree('.')
205
        wt.lock_write()
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
206
        self.addCleanup(wt.unlock)
207
        wt.add('')
208
        wt.commit('rev-1', rev_id='rev-1',
209
                  timestamp=1132586655, timezone=36000,
210
                  committer='Joe Foo <joe@foo.com>')
211
        wt.commit('rev-merged', rev_id='rev-2a',
212
                  timestamp=1132586700, timezone=36000,
213
                  committer='Joe Foo <joe@foo.com>')
214
        wt.set_parent_ids(['rev-1', 'rev-2a'])
215
        wt.branch.set_last_revision_info(1, 'rev-1')
216
        wt.commit('rev-2', rev_id='rev-2b',
217
                  timestamp=1132586800, timezone=36000,
218
                  committer='Joe Foo <joe@foo.com>')
219
        logfile = self.make_utf8_encoded_stringio()
220
        formatter = log.ShortLogFormatter(to_file=logfile)
221
        wtb = wt.branch
222
        lf = LogCatcher()
223
        revspec = revisionspec.RevisionSpec.from_string('1.1.1')
224
        rev = revspec.in_history(wtb)
225
        self.assertRaises(errors.BzrCommandError, log.show_log, wtb, lf,
226
                          start_revision=rev, end_revision=rev)
2997.1.1 by Kent Gibson
Support logging single merge revisions with short and line log formatters.
227
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
228
229
def make_commits_with_trailing_newlines(wt):
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
230
    """Helper method for LogFormatter tests"""
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
231
    b = wt.branch
232
    b.nick='test'
233
    open('a', 'wb').write('hello moto\n')
234
    wt.add('a')
2671.5.4 by Lukáš Lalinsky
Replace the committer with the author in log, the committer is displayed only in the long format and only if it's different from the author.
235
    wt.commit('simple log message', rev_id='a1',
236
              timestamp=1132586655.459960938, timezone=-6*3600,
237
              committer='Joe Foo <joe@foo.com>')
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
238
    open('b', 'wb').write('goodbye\n')
239
    wt.add('b')
2671.5.4 by Lukáš Lalinsky
Replace the committer with the author in log, the committer is displayed only in the long format and only if it's different from the author.
240
    wt.commit('multiline\nlog\nmessage\n', rev_id='a2',
241
              timestamp=1132586842.411175966, timezone=-6*3600,
242
              committer='Joe Foo <joe@foo.com>',
243
              author='Joe Bar <joe@bar.com>')
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
244
245
    open('c', 'wb').write('just another manic monday\n')
246
    wt.add('c')
2671.5.4 by Lukáš Lalinsky
Replace the committer with the author in log, the committer is displayed only in the long format and only if it's different from the author.
247
    wt.commit('single line with trailing newline\n', rev_id='a3',
248
              timestamp=1132587176.835228920, timezone=-6*3600,
249
              committer = 'Joe Foo <joe@foo.com>')
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
250
    return b
251
252
2978.6.1 by Kent Gibson
Use normalize_log to more accurately test blackbox log output.
253
def normalize_log(log):
254
    """Replaces the variable lines of logs with fixed lines"""
255
    author = 'author: Dolor Sit <test@example.com>'
256
    committer = 'committer: Lorem Ipsum <test@example.com>'
257
    lines = log.splitlines(True)
258
    for idx,line in enumerate(lines):
259
        stripped_line = line.lstrip()
260
        indent = ' ' * (len(line) - len(stripped_line))
261
        if stripped_line.startswith('author:'):
262
            lines[idx] = indent + author + '\n'
263
        elif stripped_line.startswith('committer:'):
264
            lines[idx] = indent + committer + '\n'
265
        elif stripped_line.startswith('timestamp:'):
266
            lines[idx] = indent + 'timestamp: Just now\n'
267
    return ''.join(lines)
268
269
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
270
class TestShortLogFormatter(tests.TestCaseWithTransport):
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
271
1185.31.21 by John Arbash Meinel
Added test for log formatting, found bug when redirecting short logs to a file instead of stdout.
272
    def test_trailing_newlines(self):
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
273
        wt = self.make_branch_and_tree('.')
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
274
        b = make_commits_with_trailing_newlines(wt)
2717.1.1 by Lukáš Lalinsky
Use UTF-8 encoded StringIO for log tests to avoid failures on non-ASCII committer names.
275
        sio = self.make_utf8_encoded_stringio()
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
276
        lf = log.ShortLogFormatter(to_file=sio)
277
        log.show_log(b, lf)
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
278
        self.assertEqualDiff("""\
1185.31.21 by John Arbash Meinel
Added test for log formatting, found bug when redirecting short logs to a file instead of stdout.
279
    3 Joe Foo\t2005-11-21
280
      single line with trailing newline
281
2671.5.4 by Lukáš Lalinsky
Replace the committer with the author in log, the committer is displayed only in the long format and only if it's different from the author.
282
    2 Joe Bar\t2005-11-21
1185.31.21 by John Arbash Meinel
Added test for log formatting, found bug when redirecting short logs to a file instead of stdout.
283
      multiline
284
      log
285
      message
286
287
    1 Joe Foo\t2005-11-21
288
      simple log message
289
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
290
""",
291
                             sio.getvalue())
1185.31.21 by John Arbash Meinel
Added test for log formatting, found bug when redirecting short logs to a file instead of stdout.
292
3946.3.2 by Ian Clatworthy
add tests & NEWS item
293
    def _prepare_tree_with_merges(self, with_tags=False):
294
        wt = self.make_branch_and_memory_tree('.')
295
        wt.lock_write()
296
        self.addCleanup(wt.unlock)
297
        wt.add('')
298
        wt.commit('rev-1', rev_id='rev-1',
299
                  timestamp=1132586655, timezone=36000,
300
                  committer='Joe Foo <joe@foo.com>')
301
        wt.commit('rev-merged', rev_id='rev-2a',
302
                  timestamp=1132586700, timezone=36000,
303
                  committer='Joe Foo <joe@foo.com>')
304
        wt.set_parent_ids(['rev-1', 'rev-2a'])
305
        wt.branch.set_last_revision_info(1, 'rev-1')
306
        wt.commit('rev-2', rev_id='rev-2b',
307
                  timestamp=1132586800, timezone=36000,
308
                  committer='Joe Foo <joe@foo.com>')
309
        if with_tags:
310
            branch = wt.branch
311
            branch.tags.set_tag('v0.2', 'rev-2b')
312
            wt.commit('rev-3', rev_id='rev-3',
313
                      timestamp=1132586900, timezone=36000,
314
                      committer='Jane Foo <jane@foo.com>')
315
            branch.tags.set_tag('v1.0rc1', 'rev-3')
316
            branch.tags.set_tag('v1.0', 'rev-3')
317
        return wt
318
2997.1.1 by Kent Gibson
Support logging single merge revisions with short and line log formatters.
319
    def test_short_log_with_merges(self):
3946.3.2 by Ian Clatworthy
add tests & NEWS item
320
        wt = self._prepare_tree_with_merges()
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
321
        logfile = self.make_utf8_encoded_stringio()
322
        formatter = log.ShortLogFormatter(to_file=logfile)
323
        log.show_log(wt.branch, formatter)
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
324
        self.assertEqualDiff("""\
2997.1.1 by Kent Gibson
Support logging single merge revisions with short and line log formatters.
325
    2 Joe Foo\t2005-11-22 [merge]
326
      rev-2
327
328
    1 Joe Foo\t2005-11-22
329
      rev-1
330
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
331
""",
332
                             logfile.getvalue())
2997.1.1 by Kent Gibson
Support logging single merge revisions with short and line log formatters.
333
3943.4.2 by John Arbash Meinel
Add a test case which exercises this code path.
334
    def test_short_log_with_merges_and_range(self):
335
        wt = self.make_branch_and_memory_tree('.')
336
        wt.lock_write()
337
        self.addCleanup(wt.unlock)
338
        wt.add('')
339
        wt.commit('rev-1', rev_id='rev-1',
340
                  timestamp=1132586655, timezone=36000,
341
                  committer='Joe Foo <joe@foo.com>')
342
        wt.commit('rev-merged', rev_id='rev-2a',
343
                  timestamp=1132586700, timezone=36000,
344
                  committer='Joe Foo <joe@foo.com>')
345
        wt.branch.set_last_revision_info(1, 'rev-1')
346
        wt.set_parent_ids(['rev-1', 'rev-2a'])
347
        wt.commit('rev-2b', rev_id='rev-2b',
348
                  timestamp=1132586800, timezone=36000,
349
                  committer='Joe Foo <joe@foo.com>')
350
        wt.commit('rev-3a', rev_id='rev-3a',
351
                  timestamp=1132586800, timezone=36000,
352
                  committer='Joe Foo <joe@foo.com>')
353
        wt.branch.set_last_revision_info(2, 'rev-2b')
354
        wt.set_parent_ids(['rev-2b', 'rev-3a'])
355
        wt.commit('rev-3b', rev_id='rev-3b',
356
                  timestamp=1132586800, timezone=36000,
357
                  committer='Joe Foo <joe@foo.com>')
358
        logfile = self.make_utf8_encoded_stringio()
359
        formatter = log.ShortLogFormatter(to_file=logfile)
360
        log.show_log(wt.branch, formatter,
361
            start_revision=2, end_revision=3)
362
        self.assertEqualDiff("""\
363
    3 Joe Foo\t2005-11-22 [merge]
364
      rev-3b
365
366
    2 Joe Foo\t2005-11-22 [merge]
367
      rev-2b
368
369
""",
370
                             logfile.getvalue())
371
3946.3.2 by Ian Clatworthy
add tests & NEWS item
372
    def test_short_log_with_tags(self):
373
        wt = self._prepare_tree_with_merges(with_tags=True)
374
        logfile = self.make_utf8_encoded_stringio()
375
        formatter = log.ShortLogFormatter(to_file=logfile)
376
        log.show_log(wt.branch, formatter)
377
        self.assertEqualDiff("""\
378
    3 Jane Foo\t2005-11-22 {v1.0, v1.0rc1}
379
      rev-3
380
381
    2 Joe Foo\t2005-11-22 {v0.2} [merge]
382
      rev-2
383
384
    1 Joe Foo\t2005-11-22
385
      rev-1
386
387
""",
388
                             logfile.getvalue())
389
2997.1.1 by Kent Gibson
Support logging single merge revisions with short and line log formatters.
390
    def test_short_log_single_merge_revision(self):
391
        wt = self.make_branch_and_memory_tree('.')
392
        wt.lock_write()
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
393
        self.addCleanup(wt.unlock)
394
        wt.add('')
395
        wt.commit('rev-1', rev_id='rev-1',
396
                  timestamp=1132586655, timezone=36000,
397
                  committer='Joe Foo <joe@foo.com>')
398
        wt.commit('rev-merged', rev_id='rev-2a',
399
                  timestamp=1132586700, timezone=36000,
400
                  committer='Joe Foo <joe@foo.com>')
401
        wt.set_parent_ids(['rev-1', 'rev-2a'])
402
        wt.branch.set_last_revision_info(1, 'rev-1')
403
        wt.commit('rev-2', rev_id='rev-2b',
404
                  timestamp=1132586800, timezone=36000,
405
                  committer='Joe Foo <joe@foo.com>')
406
        logfile = self.make_utf8_encoded_stringio()
407
        formatter = log.ShortLogFormatter(to_file=logfile)
408
        revspec = revisionspec.RevisionSpec.from_string('1.1.1')
409
        wtb = wt.branch
410
        rev = revspec.in_history(wtb)
411
        log.show_log(wtb, formatter, start_revision=rev, end_revision=rev)
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
412
        self.assertEqualDiff("""\
2997.1.1 by Kent Gibson
Support logging single merge revisions with short and line log formatters.
413
1.1.1 Joe Foo\t2005-11-22
414
      rev-merged
415
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
416
""",
417
                             logfile.getvalue())
2997.1.1 by Kent Gibson
Support logging single merge revisions with short and line log formatters.
418
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
419
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
420
class TestLongLogFormatter(TestCaseWithoutPropsHandler):
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
421
1185.33.41 by Martin Pool
Fix regression of 'bzr log -v' - it wasn't showing changed files at all. (#4676)
422
    def test_verbose_log(self):
423
        """Verbose log includes changed files
424
        
425
        bug #4676
426
        """
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
427
        wt = self.make_branch_and_tree('.')
428
        b = wt.branch
1185.33.41 by Martin Pool
Fix regression of 'bzr log -v' - it wasn't showing changed files at all. (#4676)
429
        self.build_tree(['a'])
1185.33.45 by Martin Pool
[merge] refactoring of branch vs working tree, etc (robertc)
430
        wt.add('a')
1185.33.41 by Martin Pool
Fix regression of 'bzr log -v' - it wasn't showing changed files at all. (#4676)
431
        # XXX: why does a longer nick show up?
432
        b.nick = 'test_verbose_log'
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
433
        wt.commit(message='add a',
434
                  timestamp=1132711707,
1185.33.41 by Martin Pool
Fix regression of 'bzr log -v' - it wasn't showing changed files at all. (#4676)
435
                  timezone=36000,
436
                  committer='Lorem Ipsum <test@example.com>')
437
        logfile = file('out.tmp', 'w+')
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
438
        formatter = log.LongLogFormatter(to_file=logfile)
439
        log.show_log(b, formatter, verbose=True)
1185.33.41 by Martin Pool
Fix regression of 'bzr log -v' - it wasn't showing changed files at all. (#4676)
440
        logfile.flush()
441
        logfile.seek(0)
442
        log_contents = logfile.read()
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
443
        self.assertEqualDiff('''\
1185.33.41 by Martin Pool
Fix regression of 'bzr log -v' - it wasn't showing changed files at all. (#4676)
444
------------------------------------------------------------
445
revno: 1
2671.5.7 by Lukáš Lalinsky
Rename get_author to get_apparent_author, revert the long log back to displaying the committer.
446
committer: Lorem Ipsum <test@example.com>
1185.33.41 by Martin Pool
Fix regression of 'bzr log -v' - it wasn't showing changed files at all. (#4676)
447
branch nick: test_verbose_log
448
timestamp: Wed 2005-11-23 12:08:27 +1000
449
message:
450
  add a
451
added:
452
  a
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
453
''',
454
                             log_contents)
1185.85.4 by John Arbash Meinel
currently broken, trying to fix things up.
455
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
456
    def test_merges_are_indented_by_level(self):
457
        wt = self.make_branch_and_tree('parent')
458
        wt.commit('first post')
2581.1.6 by Martin Pool
fix up more run_bzr callers
459
        self.run_bzr('branch parent child')
460
        self.run_bzr(['commit', '-m', 'branch 1', '--unchanged', 'child'])
461
        self.run_bzr('branch child smallerchild')
462
        self.run_bzr(['commit', '-m', 'branch 2', '--unchanged',
463
            'smallerchild'])
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
464
        os.chdir('child')
2581.1.6 by Martin Pool
fix up more run_bzr callers
465
        self.run_bzr('merge ../smallerchild')
466
        self.run_bzr(['commit', '-m', 'merge branch 2'])
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
467
        os.chdir('../parent')
2581.1.6 by Martin Pool
fix up more run_bzr callers
468
        self.run_bzr('merge ../child')
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
469
        wt.commit('merge branch 1')
470
        b = wt.branch
2717.1.1 by Lukáš Lalinsky
Use UTF-8 encoded StringIO for log tests to avoid failures on non-ASCII committer names.
471
        sio = self.make_utf8_encoded_stringio()
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
472
        lf = log.LongLogFormatter(to_file=sio)
473
        log.show_log(b, lf, verbose=True)
474
        the_log = normalize_log(sio.getvalue())
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
475
        self.assertEqualDiff("""\
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
476
------------------------------------------------------------
477
revno: 2
2671.5.7 by Lukáš Lalinsky
Rename get_author to get_apparent_author, revert the long log back to displaying the committer.
478
committer: Lorem Ipsum <test@example.com>
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
479
branch nick: parent
480
timestamp: Just now
481
message:
482
  merge branch 1
483
    ------------------------------------------------------------
484
    revno: 1.1.2
2671.5.7 by Lukáš Lalinsky
Rename get_author to get_apparent_author, revert the long log back to displaying the committer.
485
    committer: Lorem Ipsum <test@example.com>
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
486
    branch nick: child
487
    timestamp: Just now
488
    message:
489
      merge branch 2
490
        ------------------------------------------------------------
3170.3.4 by John Arbash Meinel
Update the tests for the new revision numbering.
491
        revno: 1.2.1
2671.5.7 by Lukáš Lalinsky
Rename get_author to get_apparent_author, revert the long log back to displaying the committer.
492
        committer: Lorem Ipsum <test@example.com>
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
493
        branch nick: smallerchild
494
        timestamp: Just now
495
        message:
496
          branch 2
497
    ------------------------------------------------------------
498
    revno: 1.1.1
2671.5.7 by Lukáš Lalinsky
Rename get_author to get_apparent_author, revert the long log back to displaying the committer.
499
    committer: Lorem Ipsum <test@example.com>
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
500
    branch nick: child
501
    timestamp: Just now
502
    message:
503
      branch 1
504
------------------------------------------------------------
505
revno: 1
2671.5.7 by Lukáš Lalinsky
Rename get_author to get_apparent_author, revert the long log back to displaying the committer.
506
committer: Lorem Ipsum <test@example.com>
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
507
branch nick: parent
508
timestamp: Just now
509
message:
510
  first post
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
511
""",
512
                             the_log)
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
513
514
    def test_verbose_merge_revisions_contain_deltas(self):
515
        wt = self.make_branch_and_tree('parent')
516
        self.build_tree(['parent/f1', 'parent/f2'])
517
        wt.add(['f1','f2'])
518
        wt.commit('first post')
2581.1.6 by Martin Pool
fix up more run_bzr callers
519
        self.run_bzr('branch parent child')
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
520
        os.unlink('child/f1')
2911.6.1 by Blake Winton
Change 'print >> f,'s to 'f.write('s.
521
        file('child/f2', 'wb').write('hello\n')
2581.1.6 by Martin Pool
fix up more run_bzr callers
522
        self.run_bzr(['commit', '-m', 'removed f1 and modified f2',
523
            'child'])
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
524
        os.chdir('parent')
2581.1.6 by Martin Pool
fix up more run_bzr callers
525
        self.run_bzr('merge ../child')
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
526
        wt.commit('merge branch 1')
527
        b = wt.branch
2717.1.1 by Lukáš Lalinsky
Use UTF-8 encoded StringIO for log tests to avoid failures on non-ASCII committer names.
528
        sio = self.make_utf8_encoded_stringio()
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
529
        lf = log.LongLogFormatter(to_file=sio)
530
        log.show_log(b, lf, verbose=True)
531
        the_log = normalize_log(sio.getvalue())
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
532
        self.assertEqualDiff("""\
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
533
------------------------------------------------------------
534
revno: 2
2671.5.7 by Lukáš Lalinsky
Rename get_author to get_apparent_author, revert the long log back to displaying the committer.
535
committer: Lorem Ipsum <test@example.com>
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
536
branch nick: parent
537
timestamp: Just now
538
message:
539
  merge branch 1
540
removed:
541
  f1
542
modified:
543
  f2
544
    ------------------------------------------------------------
545
    revno: 1.1.1
2671.5.7 by Lukáš Lalinsky
Rename get_author to get_apparent_author, revert the long log back to displaying the committer.
546
    committer: Lorem Ipsum <test@example.com>
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
547
    branch nick: child
548
    timestamp: Just now
549
    message:
550
      removed f1 and modified f2
551
    removed:
552
      f1
553
    modified:
554
      f2
555
------------------------------------------------------------
556
revno: 1
2671.5.7 by Lukáš Lalinsky
Rename get_author to get_apparent_author, revert the long log back to displaying the committer.
557
committer: Lorem Ipsum <test@example.com>
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
558
branch nick: parent
559
timestamp: Just now
560
message:
561
  first post
562
added:
563
  f1
564
  f2
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
565
""",
566
                             the_log)
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
567
568
    def test_trailing_newlines(self):
569
        wt = self.make_branch_and_tree('.')
570
        b = make_commits_with_trailing_newlines(wt)
2717.1.1 by Lukáš Lalinsky
Use UTF-8 encoded StringIO for log tests to avoid failures on non-ASCII committer names.
571
        sio = self.make_utf8_encoded_stringio()
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
572
        lf = log.LongLogFormatter(to_file=sio)
573
        log.show_log(b, lf)
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
574
        self.assertEqualDiff("""\
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
575
------------------------------------------------------------
576
revno: 3
2671.5.7 by Lukáš Lalinsky
Rename get_author to get_apparent_author, revert the long log back to displaying the committer.
577
committer: Joe Foo <joe@foo.com>
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
578
branch nick: test
579
timestamp: Mon 2005-11-21 09:32:56 -0600
580
message:
581
  single line with trailing newline
582
------------------------------------------------------------
583
revno: 2
2671.5.4 by Lukáš Lalinsky
Replace the committer with the author in log, the committer is displayed only in the long format and only if it's different from the author.
584
author: Joe Bar <joe@bar.com>
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
585
committer: Joe Foo <joe@foo.com>
586
branch nick: test
587
timestamp: Mon 2005-11-21 09:27:22 -0600
588
message:
589
  multiline
590
  log
591
  message
592
------------------------------------------------------------
593
revno: 1
2671.5.7 by Lukáš Lalinsky
Rename get_author to get_apparent_author, revert the long log back to displaying the committer.
594
committer: Joe Foo <joe@foo.com>
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
595
branch nick: test
596
timestamp: Mon 2005-11-21 09:24:15 -0600
597
message:
598
  simple log message
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
599
""",
600
                             sio.getvalue())
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
601
2671.5.7 by Lukáš Lalinsky
Rename get_author to get_apparent_author, revert the long log back to displaying the committer.
602
    def test_author_in_log(self):
603
        """Log includes the author name if it's set in
604
        the revision properties
2671.2.1 by Lukáš Lalinský
Add --author option to 'bzr commit' to record the author's name, if it's different from the committer.
605
        """
606
        wt = self.make_branch_and_tree('.')
607
        b = wt.branch
608
        self.build_tree(['a'])
609
        wt.add('a')
610
        b.nick = 'test_author_log'
611
        wt.commit(message='add a',
612
                  timestamp=1132711707,
613
                  timezone=36000,
614
                  committer='Lorem Ipsum <test@example.com>',
2671.2.5 by Lukáš Lalinský
Fixes for comments from the mailing list.
615
                  author='John Doe <jdoe@example.com>')
2671.2.1 by Lukáš Lalinský
Add --author option to 'bzr commit' to record the author's name, if it's different from the committer.
616
        sio = StringIO()
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
617
        formatter = log.LongLogFormatter(to_file=sio)
618
        log.show_log(b, formatter)
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
619
        self.assertEqualDiff('''\
2671.2.1 by Lukáš Lalinský
Add --author option to 'bzr commit' to record the author's name, if it's different from the committer.
620
------------------------------------------------------------
621
revno: 1
622
author: John Doe <jdoe@example.com>
2671.5.4 by Lukáš Lalinsky
Replace the committer with the author in log, the committer is displayed only in the long format and only if it's different from the author.
623
committer: Lorem Ipsum <test@example.com>
2671.2.1 by Lukáš Lalinský
Add --author option to 'bzr commit' to record the author's name, if it's different from the committer.
624
branch nick: test_author_log
625
timestamp: Wed 2005-11-23 12:08:27 +1000
626
message:
627
  add a
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
628
''',
629
                             sio.getvalue())
2671.2.1 by Lukáš Lalinský
Add --author option to 'bzr commit' to record the author's name, if it's different from the committer.
630
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
631
    def test_properties_in_log(self):
632
        """Log includes the custom properties returned by the registered 
633
        handlers.
634
        """
635
        wt = self.make_branch_and_tree('.')
636
        b = wt.branch
637
        self.build_tree(['a'])
638
        wt.add('a')
3144.7.13 by Guillermo Gonzalez
* fixed typo LogFormatter.show_properties in docstring
639
        b.nick = 'test_properties_in_log'
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
640
        wt.commit(message='add a',
641
                  timestamp=1132711707,
642
                  timezone=36000,
643
                  committer='Lorem Ipsum <test@example.com>',
644
                  author='John Doe <jdoe@example.com>')
645
        sio = StringIO()
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
646
        formatter = log.LongLogFormatter(to_file=sio)
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
647
        try:
648
            def trivial_custom_prop_handler(revision):
649
                return {'test_prop':'test_value'}
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
650
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
651
            log.properties_handler_registry.register(
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
652
                'trivial_custom_prop_handler',
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
653
                trivial_custom_prop_handler)
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
654
            log.show_log(b, formatter)
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
655
        finally:
656
            log.properties_handler_registry.remove(
657
                'trivial_custom_prop_handler')
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
658
            self.assertEqualDiff('''\
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
659
------------------------------------------------------------
660
revno: 1
661
test_prop: test_value
662
author: John Doe <jdoe@example.com>
663
committer: Lorem Ipsum <test@example.com>
3144.7.13 by Guillermo Gonzalez
* fixed typo LogFormatter.show_properties in docstring
664
branch nick: test_properties_in_log
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
665
timestamp: Wed 2005-11-23 12:08:27 +1000
666
message:
667
  add a
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
668
''',
669
                                 sio.getvalue())
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
670
671
    def test_error_in_properties_handler(self):
672
        """Log includes the custom properties returned by the registered 
673
        handlers.
674
        """
675
        wt = self.make_branch_and_tree('.')
676
        b = wt.branch
677
        self.build_tree(['a'])
678
        wt.add('a')
679
        b.nick = 'test_author_log'
680
        wt.commit(message='add a',
681
                  timestamp=1132711707,
682
                  timezone=36000,
683
                  committer='Lorem Ipsum <test@example.com>',
684
                  author='John Doe <jdoe@example.com>',
685
                  revprops={'first_prop':'first_value'})
686
        sio = StringIO()
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
687
        formatter = log.LongLogFormatter(to_file=sio)
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
688
        try:
689
            def trivial_custom_prop_handler(revision):
690
                raise StandardError("a test error")
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
691
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
692
            log.properties_handler_registry.register(
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
693
                'trivial_custom_prop_handler',
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
694
                trivial_custom_prop_handler)
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
695
            self.assertRaises(StandardError, log.show_log, b, formatter,)
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
696
        finally:
697
            log.properties_handler_registry.remove(
698
                'trivial_custom_prop_handler')
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
699
3144.7.13 by Guillermo Gonzalez
* fixed typo LogFormatter.show_properties in docstring
700
    def test_properties_handler_bad_argument(self):
701
        wt = self.make_branch_and_tree('.')
702
        b = wt.branch
703
        self.build_tree(['a'])
704
        wt.add('a')
705
        b.nick = 'test_author_log'
706
        wt.commit(message='add a',
707
                  timestamp=1132711707,
708
                  timezone=36000,
709
                  committer='Lorem Ipsum <test@example.com>',
710
                  author='John Doe <jdoe@example.com>',
711
                  revprops={'a_prop':'test_value'})
712
        sio = StringIO()
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
713
        formatter = log.LongLogFormatter(to_file=sio)
3144.7.13 by Guillermo Gonzalez
* fixed typo LogFormatter.show_properties in docstring
714
        try:
715
            def bad_argument_prop_handler(revision):
716
                return {'custom_prop_name':revision.properties['a_prop']}
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
717
3144.7.13 by Guillermo Gonzalez
* fixed typo LogFormatter.show_properties in docstring
718
            log.properties_handler_registry.register(
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
719
                'bad_argument_prop_handler',
3144.7.13 by Guillermo Gonzalez
* fixed typo LogFormatter.show_properties in docstring
720
                bad_argument_prop_handler)
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
721
722
            self.assertRaises(AttributeError, formatter.show_properties,
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
723
                              'a revision', '')
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
724
3144.7.13 by Guillermo Gonzalez
* fixed typo LogFormatter.show_properties in docstring
725
            revision = b.repository.get_revision(b.last_revision())
726
            formatter.show_properties(revision, '')
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
727
            self.assertEqualDiff('''custom_prop_name: test_value\n''',
728
                                 sio.getvalue())
3144.7.13 by Guillermo Gonzalez
* fixed typo LogFormatter.show_properties in docstring
729
        finally:
730
            log.properties_handler_registry.remove(
731
                'bad_argument_prop_handler')
2671.2.1 by Lukáš Lalinský
Add --author option to 'bzr commit' to record the author's name, if it's different from the committer.
732
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
733
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
734
class TestLineLogFormatter(tests.TestCaseWithTransport):
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
735
1704.2.20 by Martin Pool
log --line shows revision numbers (Alexander)
736
    def test_line_log(self):
737
        """Line log should show revno
738
        
739
        bug #5162
740
        """
741
        wt = self.make_branch_and_tree('.')
742
        b = wt.branch
743
        self.build_tree(['a'])
744
        wt.add('a')
745
        b.nick = 'test-line-log'
3642.1.5 by Robert Collins
Separate out batching of revisions.
746
        wt.commit(message='add a',
747
                  timestamp=1132711707,
1704.2.20 by Martin Pool
log --line shows revision numbers (Alexander)
748
                  timezone=36000,
749
                  committer='Line-Log-Formatter Tester <test@line.log>')
750
        logfile = file('out.tmp', 'w+')
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
751
        formatter = log.LineLogFormatter(to_file=logfile)
752
        log.show_log(b, formatter)
1704.2.20 by Martin Pool
log --line shows revision numbers (Alexander)
753
        logfile.flush()
754
        logfile.seek(0)
755
        log_contents = logfile.read()
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
756
        self.assertEqualDiff('1: Line-Log-Formatte... 2005-11-23 add a\n',
757
                             log_contents)
1756.2.20 by Aaron Bentley
Optimize log formats that don't show merges
758
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
759
    def test_trailing_newlines(self):
760
        wt = self.make_branch_and_tree('.')
761
        b = make_commits_with_trailing_newlines(wt)
2717.1.1 by Lukáš Lalinsky
Use UTF-8 encoded StringIO for log tests to avoid failures on non-ASCII committer names.
762
        sio = self.make_utf8_encoded_stringio()
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
763
        lf = log.LineLogFormatter(to_file=sio)
764
        log.show_log(b, lf)
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
765
        self.assertEqualDiff("""\
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
766
3: Joe Foo 2005-11-21 single line with trailing newline
2671.5.4 by Lukáš Lalinsky
Replace the committer with the author in log, the committer is displayed only in the long format and only if it's different from the author.
767
2: Joe Bar 2005-11-21 multiline
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
768
1: Joe Foo 2005-11-21 simple log message
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
769
""",
770
                             sio.getvalue())
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
771
3946.3.2 by Ian Clatworthy
add tests & NEWS item
772
    def _prepare_tree_with_merges(self, with_tags=False):
773
        wt = self.make_branch_and_memory_tree('.')
774
        wt.lock_write()
775
        self.addCleanup(wt.unlock)
776
        wt.add('')
777
        wt.commit('rev-1', rev_id='rev-1',
778
                  timestamp=1132586655, timezone=36000,
779
                  committer='Joe Foo <joe@foo.com>')
780
        wt.commit('rev-merged', rev_id='rev-2a',
781
                  timestamp=1132586700, timezone=36000,
782
                  committer='Joe Foo <joe@foo.com>')
783
        wt.set_parent_ids(['rev-1', 'rev-2a'])
784
        wt.branch.set_last_revision_info(1, 'rev-1')
785
        wt.commit('rev-2', rev_id='rev-2b',
786
                  timestamp=1132586800, timezone=36000,
787
                  committer='Joe Foo <joe@foo.com>')
788
        if with_tags:
789
            branch = wt.branch
790
            branch.tags.set_tag('v0.2', 'rev-2b')
791
            wt.commit('rev-3', rev_id='rev-3',
792
                      timestamp=1132586900, timezone=36000,
793
                      committer='Jane Foo <jane@foo.com>')
794
            branch.tags.set_tag('v1.0rc1', 'rev-3')
795
            branch.tags.set_tag('v1.0', 'rev-3')
796
        return wt
797
2997.1.1 by Kent Gibson
Support logging single merge revisions with short and line log formatters.
798
    def test_line_log_single_merge_revision(self):
3946.3.2 by Ian Clatworthy
add tests & NEWS item
799
        wt = self._prepare_tree_with_merges()
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
800
        logfile = self.make_utf8_encoded_stringio()
801
        formatter = log.LineLogFormatter(to_file=logfile)
802
        revspec = revisionspec.RevisionSpec.from_string('1.1.1')
803
        wtb = wt.branch
804
        rev = revspec.in_history(wtb)
805
        log.show_log(wtb, formatter, start_revision=rev, end_revision=rev)
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
806
        self.assertEqualDiff("""\
2997.1.1 by Kent Gibson
Support logging single merge revisions with short and line log formatters.
807
1.1.1: Joe Foo 2005-11-22 rev-merged
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
808
""",
809
                             logfile.getvalue())
2997.1.1 by Kent Gibson
Support logging single merge revisions with short and line log formatters.
810
3946.3.2 by Ian Clatworthy
add tests & NEWS item
811
    def test_line_log_with_tags(self):
812
        wt = self._prepare_tree_with_merges(with_tags=True)
813
        logfile = self.make_utf8_encoded_stringio()
814
        formatter = log.LineLogFormatter(to_file=logfile)
815
        log.show_log(wt.branch, formatter)
816
        self.assertEqualDiff("""\
3946.3.3 by Ian Clatworthy
feedback from jelmer re position of tags in --line
817
3: Jane Foo 2005-11-22 {v1.0, v1.0rc1} rev-3
818
2: Joe Foo 2005-11-22 {v0.2} rev-2
3946.3.2 by Ian Clatworthy
add tests & NEWS item
819
1: Joe Foo 2005-11-22 rev-1
820
""",
821
                             logfile.getvalue())
2997.1.1 by Kent Gibson
Support logging single merge revisions with short and line log formatters.
822
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
823
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
824
class TestGetViewRevisions(tests.TestCaseWithTransport):
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
825
1756.2.22 by Aaron Bentley
Apply review comments
826
    def make_tree_with_commits(self):
827
        """Create a tree with well-known revision ids"""
1756.2.20 by Aaron Bentley
Optimize log formats that don't show merges
828
        wt = self.make_branch_and_tree('tree1')
829
        wt.commit('commit one', rev_id='1')
830
        wt.commit('commit two', rev_id='2')
831
        wt.commit('commit three', rev_id='3')
832
        mainline_revs = [None, '1', '2', '3']
1756.2.22 by Aaron Bentley
Apply review comments
833
        rev_nos = {'1': 1, '2': 2, '3': 3}
834
        return mainline_revs, rev_nos, wt
835
836
    def make_tree_with_merges(self):
837
        """Create a tree with well-known revision ids and a merge"""
838
        mainline_revs, rev_nos, wt = self.make_tree_with_commits()
1756.2.20 by Aaron Bentley
Optimize log formats that don't show merges
839
        tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
840
        tree2.commit('four-a', rev_id='4a')
1979.2.1 by Robert Collins
(robertc) adds a convenience method "merge_from_branch" to WorkingTree.
841
        wt.merge_from_branch(tree2.branch)
1756.2.20 by Aaron Bentley
Optimize log formats that don't show merges
842
        wt.commit('four-b', rev_id='4b')
843
        mainline_revs.append('4b')
1756.2.22 by Aaron Bentley
Apply review comments
844
        rev_nos['4b'] = 4
1988.4.2 by Robert Collins
``bzr log`` Now shows dotted-decimal revision numbers for all revisions,
845
        # 4a: 3.1.1
1756.2.22 by Aaron Bentley
Apply review comments
846
        return mainline_revs, rev_nos, wt
847
1756.2.24 by Aaron Bentley
Forward sorting shows merges under mainline revision
848
    def make_tree_with_many_merges(self):
849
        """Create a tree with well-known revision ids"""
850
        wt = self.make_branch_and_tree('tree1')
3842.2.5 by Vincent Ladeuil
Better fix for bug #300055.
851
        self.build_tree_contents([('tree1/f', '1\n')])
852
        wt.add(['f'], ['f-id'])
1756.2.24 by Aaron Bentley
Forward sorting shows merges under mainline revision
853
        wt.commit('commit one', rev_id='1')
854
        wt.commit('commit two', rev_id='2')
3842.2.5 by Vincent Ladeuil
Better fix for bug #300055.
855
1756.2.24 by Aaron Bentley
Forward sorting shows merges under mainline revision
856
        tree3 = wt.bzrdir.sprout('tree3').open_workingtree()
3842.2.5 by Vincent Ladeuil
Better fix for bug #300055.
857
        self.build_tree_contents([('tree3/f', '1\n2\n3a\n')])
1756.2.24 by Aaron Bentley
Forward sorting shows merges under mainline revision
858
        tree3.commit('commit three a', rev_id='3a')
3842.2.5 by Vincent Ladeuil
Better fix for bug #300055.
859
1988.4.2 by Robert Collins
``bzr log`` Now shows dotted-decimal revision numbers for all revisions,
860
        tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
1979.2.1 by Robert Collins
(robertc) adds a convenience method "merge_from_branch" to WorkingTree.
861
        tree2.merge_from_branch(tree3.branch)
1756.2.24 by Aaron Bentley
Forward sorting shows merges under mainline revision
862
        tree2.commit('commit three b', rev_id='3b')
3842.2.5 by Vincent Ladeuil
Better fix for bug #300055.
863
1979.2.1 by Robert Collins
(robertc) adds a convenience method "merge_from_branch" to WorkingTree.
864
        wt.merge_from_branch(tree2.branch)
1756.2.24 by Aaron Bentley
Forward sorting shows merges under mainline revision
865
        wt.commit('commit three c', rev_id='3c')
866
        tree2.commit('four-a', rev_id='4a')
3842.2.5 by Vincent Ladeuil
Better fix for bug #300055.
867
1979.2.1 by Robert Collins
(robertc) adds a convenience method "merge_from_branch" to WorkingTree.
868
        wt.merge_from_branch(tree2.branch)
1756.2.24 by Aaron Bentley
Forward sorting shows merges under mainline revision
869
        wt.commit('four-b', rev_id='4b')
3842.2.5 by Vincent Ladeuil
Better fix for bug #300055.
870
1756.2.24 by Aaron Bentley
Forward sorting shows merges under mainline revision
871
        mainline_revs = [None, '1', '2', '3c', '4b']
1988.4.2 by Robert Collins
``bzr log`` Now shows dotted-decimal revision numbers for all revisions,
872
        rev_nos = {'1':1, '2':2, '3c': 3, '4b':4}
873
        full_rev_nos_for_reference = {
874
            '1': '1',
875
            '2': '2',
3170.3.4 by John Arbash Meinel
Update the tests for the new revision numbering.
876
            '3a': '2.1.1', #first commit tree 3
877
            '3b': '2.2.1', # first commit tree 2
1988.4.2 by Robert Collins
``bzr log`` Now shows dotted-decimal revision numbers for all revisions,
878
            '3c': '3', #merges 3b to main
3170.3.4 by John Arbash Meinel
Update the tests for the new revision numbering.
879
            '4a': '2.2.2', # second commit tree 2
1988.4.2 by Robert Collins
``bzr log`` Now shows dotted-decimal revision numbers for all revisions,
880
            '4b': '4', # merges 4a to main
881
            }
1756.2.24 by Aaron Bentley
Forward sorting shows merges under mainline revision
882
        return mainline_revs, rev_nos, wt
883
1756.2.22 by Aaron Bentley
Apply review comments
884
    def test_get_view_revisions_forward(self):
885
        """Test the get_view_revisions method"""
886
        mainline_revs, rev_nos, wt = self.make_tree_with_commits()
3287.6.1 by Robert Collins
* ``VersionedFile.get_graph`` is deprecated, with no replacement method.
887
        wt.lock_read()
888
        self.addCleanup(wt.unlock)
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
889
        revisions = list(log.get_view_revisions(
890
                mainline_revs, rev_nos, wt.branch, 'forward'))
1988.4.2 by Robert Collins
``bzr log`` Now shows dotted-decimal revision numbers for all revisions,
891
        self.assertEqual([('1', '1', 0), ('2', '2', 0), ('3', '3', 0)],
3842.2.2 by Vincent Ladeuil
Reproduce bug #300055.
892
                         revisions)
893
        revisions2 = list(log.get_view_revisions(
894
                mainline_revs, rev_nos, wt.branch, 'forward',
895
                include_merges=False))
1756.2.22 by Aaron Bentley
Apply review comments
896
        self.assertEqual(revisions, revisions2)
897
898
    def test_get_view_revisions_reverse(self):
899
        """Test the get_view_revisions with reverse"""
900
        mainline_revs, rev_nos, wt = self.make_tree_with_commits()
3287.6.1 by Robert Collins
* ``VersionedFile.get_graph`` is deprecated, with no replacement method.
901
        wt.lock_read()
902
        self.addCleanup(wt.unlock)
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
903
        revisions = list(log.get_view_revisions(
904
                mainline_revs, rev_nos, wt.branch, 'reverse'))
1988.4.2 by Robert Collins
``bzr log`` Now shows dotted-decimal revision numbers for all revisions,
905
        self.assertEqual([('3', '3', 0), ('2', '2', 0), ('1', '1', 0), ],
3842.2.2 by Vincent Ladeuil
Reproduce bug #300055.
906
                         revisions)
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
907
        revisions2 = list(log.get_view_revisions(
908
                mainline_revs, rev_nos, wt.branch, 'reverse',
909
                include_merges=False))
1756.2.22 by Aaron Bentley
Apply review comments
910
        self.assertEqual(revisions, revisions2)
911
912
    def test_get_view_revisions_merge(self):
913
        """Test get_view_revisions when there are merges"""
914
        mainline_revs, rev_nos, wt = self.make_tree_with_merges()
3287.6.1 by Robert Collins
* ``VersionedFile.get_graph`` is deprecated, with no replacement method.
915
        wt.lock_read()
916
        self.addCleanup(wt.unlock)
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
917
        revisions = list(log.get_view_revisions(
918
                mainline_revs, rev_nos, wt.branch, 'forward'))
1988.4.2 by Robert Collins
``bzr log`` Now shows dotted-decimal revision numbers for all revisions,
919
        self.assertEqual([('1', '1', 0), ('2', '2', 0), ('3', '3', 0),
3842.2.2 by Vincent Ladeuil
Reproduce bug #300055.
920
                          ('4b', '4', 0), ('4a', '3.1.1', 1)],
921
                         revisions)
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
922
        revisions = list(log.get_view_revisions(
923
                mainline_revs, rev_nos, wt.branch, 'forward',
924
                include_merges=False))
1988.4.2 by Robert Collins
``bzr log`` Now shows dotted-decimal revision numbers for all revisions,
925
        self.assertEqual([('1', '1', 0), ('2', '2', 0), ('3', '3', 0),
3842.2.2 by Vincent Ladeuil
Reproduce bug #300055.
926
                          ('4b', '4', 0)],
927
                         revisions)
1756.2.24 by Aaron Bentley
Forward sorting shows merges under mainline revision
928
929
    def test_get_view_revisions_merge_reverse(self):
930
        """Test get_view_revisions in reverse when there are merges"""
931
        mainline_revs, rev_nos, wt = self.make_tree_with_merges()
3287.6.1 by Robert Collins
* ``VersionedFile.get_graph`` is deprecated, with no replacement method.
932
        wt.lock_read()
933
        self.addCleanup(wt.unlock)
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
934
        revisions = list(log.get_view_revisions(
935
                mainline_revs, rev_nos, wt.branch, 'reverse'))
1988.4.2 by Robert Collins
``bzr log`` Now shows dotted-decimal revision numbers for all revisions,
936
        self.assertEqual([('4b', '4', 0), ('4a', '3.1.1', 1),
3842.2.2 by Vincent Ladeuil
Reproduce bug #300055.
937
                          ('3', '3', 0), ('2', '2', 0), ('1', '1', 0)],
938
                         revisions)
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
939
        revisions = list(log.get_view_revisions(
940
                mainline_revs, rev_nos, wt.branch, 'reverse',
941
                include_merges=False))
1988.4.2 by Robert Collins
``bzr log`` Now shows dotted-decimal revision numbers for all revisions,
942
        self.assertEqual([('4b', '4', 0), ('3', '3', 0), ('2', '2', 0),
3842.2.2 by Vincent Ladeuil
Reproduce bug #300055.
943
                          ('1', '1', 0)],
944
                         revisions)
1756.2.24 by Aaron Bentley
Forward sorting shows merges under mainline revision
945
946
    def test_get_view_revisions_merge2(self):
947
        """Test get_view_revisions when there are merges"""
948
        mainline_revs, rev_nos, wt = self.make_tree_with_many_merges()
3287.6.1 by Robert Collins
* ``VersionedFile.get_graph`` is deprecated, with no replacement method.
949
        wt.lock_read()
950
        self.addCleanup(wt.unlock)
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
951
        revisions = list(log.get_view_revisions(
952
                mainline_revs, rev_nos, wt.branch, 'forward'))
1988.4.2 by Robert Collins
``bzr log`` Now shows dotted-decimal revision numbers for all revisions,
953
        expected = [('1', '1', 0), ('2', '2', 0), ('3c', '3', 0),
3842.2.2 by Vincent Ladeuil
Reproduce bug #300055.
954
                    ('3a', '2.1.1', 1), ('3b', '2.2.1', 1), ('4b', '4', 0),
955
                    ('4a', '2.2.2', 1)]
1988.4.2 by Robert Collins
``bzr log`` Now shows dotted-decimal revision numbers for all revisions,
956
        self.assertEqual(expected, revisions)
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
957
        revisions = list(log.get_view_revisions(
958
                mainline_revs, rev_nos, wt.branch, 'forward',
959
                include_merges=False))
1988.4.2 by Robert Collins
``bzr log`` Now shows dotted-decimal revision numbers for all revisions,
960
        self.assertEqual([('1', '1', 0), ('2', '2', 0), ('3c', '3', 0),
3842.2.2 by Vincent Ladeuil
Reproduce bug #300055.
961
                          ('4b', '4', 0)],
962
                         revisions)
2359.1.6 by John Arbash Meinel
Create a helper tree which has a semi-interesting history.
963
964
3842.2.5 by Vincent Ladeuil
Better fix for bug #300055.
965
    def test_file_id_for_range(self):
966
        mainline_revs, rev_nos, wt = self.make_tree_with_many_merges()
967
        wt.lock_read()
968
        self.addCleanup(wt.unlock)
969
970
        def rev_from_rev_id(revid, branch):
971
            revspec = revisionspec.RevisionSpec.from_string('revid:%s' % revid)
972
            return revspec.in_history(branch)
973
974
        def view_revs(start_rev, end_rev, file_id, direction):
975
            revs = log.calculate_view_revisions(
976
                wt.branch,
977
                start_rev, # start_revision
978
                end_rev, # end_revision
979
                direction, # direction
980
                file_id, # specific_fileid
981
                True, # generate_merge_revisions
982
                True, # allow_single_merge_revision
983
                )
984
            return revs
985
986
        rev_3a = rev_from_rev_id('3a', wt.branch)
987
        rev_4b = rev_from_rev_id('4b', wt.branch)
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
988
        self.assertEqual([('3c', '3', 0), ('3a', '2.1.1', 1)],
3842.2.5 by Vincent Ladeuil
Better fix for bug #300055.
989
                          view_revs(rev_3a, rev_4b, 'f-id', 'reverse'))
990
        # Note that the depth is 0 for 3a because depths are normalized, but
991
        # there is still a bug somewhere... most probably in
992
        # _filter_revision_range and/or get_view_revisions still around a bad
993
        # use of reverse_by_depth
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
994
        self.assertEqual([('3a', '2.1.1', 0)],
3842.2.5 by Vincent Ladeuil
Better fix for bug #300055.
995
                          view_revs(rev_3a, rev_4b, 'f-id', 'forward'))
996
997
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
998
class TestGetRevisionsTouchingFileID(tests.TestCaseWithTransport):
2359.1.6 by John Arbash Meinel
Create a helper tree which has a semi-interesting history.
999
1000
    def create_tree_with_single_merge(self):
1001
        """Create a branch with a moderate layout.
1002
1003
        The revision graph looks like:
1004
1005
           A
1006
           |\
1007
           B C
1008
           |/
1009
           D
1010
1011
        In this graph, A introduced files f1 and f2 and f3.
1012
        B modifies f1 and f3, and C modifies f2 and f3.
1013
        D merges the changes from B and C and resolves the conflict for f3.
1014
        """
1015
        # TODO: jam 20070218 This seems like it could really be done
1016
        #       with make_branch_and_memory_tree() if we could just
1017
        #       create the content of those files.
1018
        # TODO: jam 20070218 Another alternative is that we would really
1019
        #       like to only create this tree 1 time for all tests that
1020
        #       use it. Since 'log' only uses the tree in a readonly
1021
        #       fashion, it seems a shame to regenerate an identical
1022
        #       tree for each test.
1023
        tree = self.make_branch_and_tree('tree')
1024
        tree.lock_write()
1025
        self.addCleanup(tree.unlock)
1026
1027
        self.build_tree_contents([('tree/f1', 'A\n'),
1028
                                  ('tree/f2', 'A\n'),
1029
                                  ('tree/f3', 'A\n'),
1030
                                 ])
1031
        tree.add(['f1', 'f2', 'f3'], ['f1-id', 'f2-id', 'f3-id'])
1032
        tree.commit('A', rev_id='A')
1033
1034
        self.build_tree_contents([('tree/f2', 'A\nC\n'),
1035
                                  ('tree/f3', 'A\nC\n'),
1036
                                 ])
1037
        tree.commit('C', rev_id='C')
1038
        # Revert back to A to build the other history.
1039
        tree.set_last_revision('A')
1040
        tree.branch.set_last_revision_info(1, 'A')
1041
        self.build_tree_contents([('tree/f1', 'A\nB\n'),
1042
                                  ('tree/f2', 'A\n'),
1043
                                  ('tree/f3', 'A\nB\n'),
1044
                                 ])
1045
        tree.commit('B', rev_id='B')
1046
        tree.set_parent_ids(['B', 'C'])
1047
        self.build_tree_contents([('tree/f1', 'A\nB\n'),
1048
                                  ('tree/f2', 'A\nC\n'),
1049
                                  ('tree/f3', 'A\nB\nC\n'),
1050
                                 ])
1051
        tree.commit('D', rev_id='D')
1052
1053
        # Switch to a read lock for this tree.
3842.2.5 by Vincent Ladeuil
Better fix for bug #300055.
1054
        # We still have an addCleanup(tree.unlock) pending
2359.1.6 by John Arbash Meinel
Create a helper tree which has a semi-interesting history.
1055
        tree.unlock()
1056
        tree.lock_read()
1057
        return tree
1058
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
1059
    def check_delta(self, delta, **kw):
1060
        """Check the filenames touched by a delta are as expected.
1061
1062
        Caller only have to pass in the list of files for each part, all
1063
        unspecified parts are considered empty (and checked as such).
1064
        """
1065
        for n in 'added', 'removed', 'renamed', 'modified', 'unchanged':
1066
            # By default we expect an empty list
1067
            expected = kw.get(n, [])
1068
            # strip out only the path components
1069
            got = [x[0] for x in getattr(delta, n)]
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
1070
            self.assertEqual(expected, got)
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
1071
2359.1.6 by John Arbash Meinel
Create a helper tree which has a semi-interesting history.
1072
    def test_tree_with_single_merge(self):
1073
        """Make sure the tree layout is correct."""
1074
        tree = self.create_tree_with_single_merge()
1075
        rev_A_tree = tree.branch.repository.revision_tree('A')
1076
        rev_B_tree = tree.branch.repository.revision_tree('B')
1077
        rev_C_tree = tree.branch.repository.revision_tree('C')
1078
        rev_D_tree = tree.branch.repository.revision_tree('D')
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
1079
1080
        self.check_delta(rev_B_tree.changes_from(rev_A_tree),
1081
                         modified=['f1', 'f3'])
1082
1083
        self.check_delta(rev_C_tree.changes_from(rev_A_tree),
1084
                         modified=['f2', 'f3'])
1085
1086
        self.check_delta(rev_D_tree.changes_from(rev_B_tree),
1087
                         modified=['f2', 'f3'])
1088
1089
        self.check_delta(rev_D_tree.changes_from(rev_C_tree),
1090
                         modified=['f1', 'f3'])
2359.1.6 by John Arbash Meinel
Create a helper tree which has a semi-interesting history.
1091
2359.1.7 by John Arbash Meinel
Create a direct test for _get_revisions_touching_file_id
1092
    def assertAllRevisionsForFileID(self, tree, file_id, revisions):
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
1093
        """Ensure _filter_revisions_touching_file_id returns the right values.
2359.1.7 by John Arbash Meinel
Create a direct test for _get_revisions_touching_file_id
1094
2466.12.1 by Kent Gibson
Fix ``bzr log -r`` to support selecting merge revisions.
1095
        Get the return value from _filter_revisions_touching_file_id and make
2359.1.7 by John Arbash Meinel
Create a direct test for _get_revisions_touching_file_id
1096
        sure they are correct.
1097
        """
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
1098
        # The api for _filter_revisions_touching_file_id is a little crazy.
2359.1.7 by John Arbash Meinel
Create a direct test for _get_revisions_touching_file_id
1099
        # So we do the setup here.
1100
        mainline = tree.branch.revision_history()
1101
        mainline.insert(0, None)
1102
        revnos = dict((rev, idx+1) for idx, rev in enumerate(mainline))
1103
        view_revs_iter = log.get_view_revisions(mainline, revnos, tree.branch,
1104
                                                'reverse', True)
2466.12.1 by Kent Gibson
Fix ``bzr log -r`` to support selecting merge revisions.
1105
        actual_revs = log._filter_revisions_touching_file_id(
3711.3.23 by John Arbash Meinel
Documentation and cleanup.
1106
                            tree.branch,
2466.12.1 by Kent Gibson
Fix ``bzr log -r`` to support selecting merge revisions.
1107
                            file_id,
3842.2.5 by Vincent Ladeuil
Better fix for bug #300055.
1108
                            list(view_revs_iter))
2359.1.7 by John Arbash Meinel
Create a direct test for _get_revisions_touching_file_id
1109
        self.assertEqual(revisions, [r for r, revno, depth in actual_revs])
1110
1111
    def test_file_id_f1(self):
1112
        tree = self.create_tree_with_single_merge()
1113
        # f1 should be marked as modified by revisions A and B
1114
        self.assertAllRevisionsForFileID(tree, 'f1-id', ['B', 'A'])
1115
1116
    def test_file_id_f2(self):
1117
        tree = self.create_tree_with_single_merge()
1118
        # f2 should be marked as modified by revisions A, C, and D
1119
        # because D merged the changes from C.
1120
        self.assertAllRevisionsForFileID(tree, 'f2-id', ['D', 'C', 'A'])
1121
1122
    def test_file_id_f3(self):
1123
        tree = self.create_tree_with_single_merge()
1124
        # f3 should be marked as modified by revisions A, B, C, and D
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
1125
        self.assertAllRevisionsForFileID(tree, 'f3-id', ['D', 'C', 'B', 'A'])
1551.17.2 by Aaron Bentley
Stop showing deltas in pull -v output
1126
3373.2.1 by John Arbash Meinel
Fix bug #209948, properly skip over ghosts when displaying the changes for a single file.
1127
    def test_file_id_with_ghosts(self):
1128
        # This is testing bug #209948, where having a ghost would cause
1129
        # _filter_revisions_touching_file_id() to fail.
1130
        tree = self.create_tree_with_single_merge()
1131
        # We need to add a revision, so switch back to a write-locked tree
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
1132
        # (still a single addCleanup(tree.unlock) pending).
3373.2.1 by John Arbash Meinel
Fix bug #209948, properly skip over ghosts when displaying the changes for a single file.
1133
        tree.unlock()
1134
        tree.lock_write()
1135
        first_parent = tree.last_revision()
1136
        tree.set_parent_ids([first_parent, 'ghost-revision-id'])
1137
        self.build_tree_contents([('tree/f1', 'A\nB\nXX\n')])
1138
        tree.commit('commit with a ghost', rev_id='XX')
1139
        self.assertAllRevisionsForFileID(tree, 'f1-id', ['XX', 'B', 'A'])
1140
        self.assertAllRevisionsForFileID(tree, 'f2-id', ['D', 'C', 'A'])
1141
1551.17.2 by Aaron Bentley
Stop showing deltas in pull -v output
1142
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
1143
class TestShowChangedRevisions(tests.TestCaseWithTransport):
1551.17.2 by Aaron Bentley
Stop showing deltas in pull -v output
1144
1145
    def test_show_changed_revisions_verbose(self):
1146
        tree = self.make_branch_and_tree('tree_a')
1147
        self.build_tree(['tree_a/foo'])
1148
        tree.add('foo')
1149
        tree.commit('bar', rev_id='bar-id')
2717.1.1 by Lukáš Lalinsky
Use UTF-8 encoded StringIO for log tests to avoid failures on non-ASCII committer names.
1150
        s = self.make_utf8_encoded_stringio()
1551.17.2 by Aaron Bentley
Stop showing deltas in pull -v output
1151
        log.show_changed_revisions(tree.branch, [], ['bar-id'], s)
1152
        self.assertContainsRe(s.getvalue(), 'bar')
1153
        self.assertNotContainsRe(s.getvalue(), 'foo')
2671.5.8 by Lukáš Lalinsky
Add tests for LogFormatter.short_committer and LogFormatter.short_author.
1154
1155
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
1156
class TestLogFormatter(tests.TestCase):
2671.5.8 by Lukáš Lalinsky
Add tests for LogFormatter.short_committer and LogFormatter.short_author.
1157
1158
    def test_short_committer(self):
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
1159
        rev = revision.Revision('a-id')
2671.5.8 by Lukáš Lalinsky
Add tests for LogFormatter.short_committer and LogFormatter.short_author.
1160
        rev.committer = 'John Doe <jdoe@example.com>'
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
1161
        lf = log.LogFormatter(None)
2671.5.8 by Lukáš Lalinsky
Add tests for LogFormatter.short_committer and LogFormatter.short_author.
1162
        self.assertEqual('John Doe', lf.short_committer(rev))
3063.3.1 by Lukáš Lalinský
Fall back to showing e-mail in ``log --short/--line`` if the committer/author has only e-mail.
1163
        rev.committer = 'John Smith <jsmith@example.com>'
3063.3.3 by Lukáš Lalinský
Add one more test for config.parse_username().
1164
        self.assertEqual('John Smith', lf.short_committer(rev))
3063.3.1 by Lukáš Lalinský
Fall back to showing e-mail in ``log --short/--line`` if the committer/author has only e-mail.
1165
        rev.committer = 'John Smith'
3063.3.3 by Lukáš Lalinský
Add one more test for config.parse_username().
1166
        self.assertEqual('John Smith', lf.short_committer(rev))
3063.3.1 by Lukáš Lalinský
Fall back to showing e-mail in ``log --short/--line`` if the committer/author has only e-mail.
1167
        rev.committer = 'jsmith@example.com'
3063.3.3 by Lukáš Lalinský
Add one more test for config.parse_username().
1168
        self.assertEqual('jsmith@example.com', lf.short_committer(rev))
3063.3.1 by Lukáš Lalinský
Fall back to showing e-mail in ``log --short/--line`` if the committer/author has only e-mail.
1169
        rev.committer = '<jsmith@example.com>'
3063.3.3 by Lukáš Lalinský
Add one more test for config.parse_username().
1170
        self.assertEqual('jsmith@example.com', lf.short_committer(rev))
1171
        rev.committer = 'John Smith jsmith@example.com'
1172
        self.assertEqual('John Smith', lf.short_committer(rev))
2671.5.8 by Lukáš Lalinsky
Add tests for LogFormatter.short_committer and LogFormatter.short_author.
1173
1174
    def test_short_author(self):
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
1175
        rev = revision.Revision('a-id')
2671.5.8 by Lukáš Lalinsky
Add tests for LogFormatter.short_committer and LogFormatter.short_author.
1176
        rev.committer = 'John Doe <jdoe@example.com>'
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
1177
        lf = log.LogFormatter(None)
2671.5.8 by Lukáš Lalinsky
Add tests for LogFormatter.short_committer and LogFormatter.short_author.
1178
        self.assertEqual('John Doe', lf.short_author(rev))
1179
        rev.properties['author'] = 'John Smith <jsmith@example.com>'
1180
        self.assertEqual('John Smith', lf.short_author(rev))
3063.3.1 by Lukáš Lalinský
Fall back to showing e-mail in ``log --short/--line`` if the committer/author has only e-mail.
1181
        rev.properties['author'] = 'John Smith'
1182
        self.assertEqual('John Smith', lf.short_author(rev))
1183
        rev.properties['author'] = 'jsmith@example.com'
1184
        self.assertEqual('jsmith@example.com', lf.short_author(rev))
1185
        rev.properties['author'] = '<jsmith@example.com>'
1186
        self.assertEqual('jsmith@example.com', lf.short_author(rev))
3063.3.3 by Lukáš Lalinský
Add one more test for config.parse_username().
1187
        rev.properties['author'] = 'John Smith jsmith@example.com'
1188
        self.assertEqual('John Smith', lf.short_author(rev))
3842.2.2 by Vincent Ladeuil
Reproduce bug #300055.
1189
1190
1191
class TestReverseByDepth(tests.TestCase):
1192
    """Test reverse_by_depth behavior.
1193
1194
    This is used to present revisions in forward (oldest first) order in a nice
1195
    layout.
1196
1197
    The tests use lighter revision description to ease reading.
1198
    """
1199
1200
    def assertReversed(self, forward, backward):
1201
        # Transform the descriptions to suit the API: tests use (revno, depth),
1202
        # while the API expects (revid, revno, depth)
1203
        def complete_revisions(l):
1204
            """Transform the description to suit the API.
1205
1206
            Tests use (revno, depth) whil the API expects (revid, revno, depth).
1207
            Since the revid is arbitrary, we just duplicate revno
1208
            """
1209
            return [ (r, r, d) for r, d in l]
1210
        forward = complete_revisions(forward)
1211
        backward= complete_revisions(backward)
1212
        self.assertEqual(forward, log.reverse_by_depth(backward))
1213
1214
1215
    def test_mainline_revisions(self):
1216
        self.assertReversed([( '1', 0), ('2', 0)],
1217
                            [('2', 0), ('1', 0)])
1218
1219
    def test_merged_revisions(self):
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
1220
        self.assertReversed([('1', 0), ('2', 0), ('2.2', 1), ('2.1', 1),],
1221
                            [('2', 0), ('2.1', 1), ('2.2', 1), ('1', 0),])
3842.2.2 by Vincent Ladeuil
Reproduce bug #300055.
1222
    def test_shifted_merged_revisions(self):
1223
        """Test irregular layout.
1224
1225
        Requesting revisions touching a file can produce "holes" in the depths.
1226
        """
1227
        self.assertReversed([('1', 0), ('2', 0), ('1.1', 2), ('1.2', 2),],
1228
                            [('2', 0), ('1.2', 2), ('1.1', 2), ('1', 0),])
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
1229
1230
    def test_merged_without_child_revisions(self):
1231
        """Test irregular layout.
1232
1233
        Revision ranges can produce "holes" in the depths.
1234
        """
1235
        # When a revision of higher depth doesn't follow one of lower depth, we
1236
        # assume a lower depth one is virtually there
1237
        self.assertReversed([('1', 2), ('2', 2), ('3', 3), ('4', 4)],
1238
                            [('4', 4), ('3', 3), ('2', 2), ('1', 2),])
1239
        # So we get the same order after reversing below even if the original
1240
        # revisions are not in the same order.
1241
        self.assertReversed([('1', 2), ('2', 2), ('3', 3), ('4', 4)],
1242
                            [('3', 3), ('4', 4), ('2', 2), ('1', 2),])
3848.1.6 by Aaron Bentley
Implement get_history_change
1243
1244
3848.1.8 by Aaron Bentley
Implement basic show_branch_change
1245
class TestHistoryChange(tests.TestCaseWithTransport):
3848.1.6 by Aaron Bentley
Implement get_history_change
1246
1247
    def setup_a_tree(self):
1248
        tree = self.make_branch_and_tree('tree')
1249
        tree.lock_write()
1250
        self.addCleanup(tree.unlock)
1251
        tree.commit('1a', rev_id='1a')
1252
        tree.commit('2a', rev_id='2a')
1253
        tree.commit('3a', rev_id='3a')
1254
        return tree
1255
1256
    def setup_ab_tree(self):
1257
        tree = self.setup_a_tree()
1258
        tree.set_last_revision('1a')
1259
        tree.branch.set_last_revision_info(1, '1a')
1260
        tree.commit('2b', rev_id='2b')
1261
        tree.commit('3b', rev_id='3b')
1262
        return tree
1263
1264
    def setup_ac_tree(self):
1265
        tree = self.setup_a_tree()
1266
        tree.set_last_revision(revision.NULL_REVISION)
1267
        tree.branch.set_last_revision_info(0, revision.NULL_REVISION)
1268
        tree.commit('1c', rev_id='1c')
1269
        tree.commit('2c', rev_id='2c')
1270
        tree.commit('3c', rev_id='3c')
1271
        return tree
1272
1273
    def test_all_new(self):
1274
        tree = self.setup_ab_tree()
3848.1.7 by Aaron Bentley
Use repository in get_history_change
1275
        old, new = log.get_history_change('1a', '3a', tree.branch.repository)
3848.1.6 by Aaron Bentley
Implement get_history_change
1276
        self.assertEqual([], old)
1277
        self.assertEqual(['2a', '3a'], new)
1278
1279
    def test_all_old(self):
1280
        tree = self.setup_ab_tree()
3848.1.7 by Aaron Bentley
Use repository in get_history_change
1281
        old, new = log.get_history_change('3a', '1a', tree.branch.repository)
3848.1.6 by Aaron Bentley
Implement get_history_change
1282
        self.assertEqual([], new)
1283
        self.assertEqual(['2a', '3a'], old)
1284
1285
    def test_null_old(self):
1286
        tree = self.setup_ab_tree()
1287
        old, new = log.get_history_change(revision.NULL_REVISION,
3848.1.7 by Aaron Bentley
Use repository in get_history_change
1288
                                          '3a', tree.branch.repository)
3848.1.6 by Aaron Bentley
Implement get_history_change
1289
        self.assertEqual([], old)
1290
        self.assertEqual(['1a', '2a', '3a'], new)
1291
1292
    def test_null_new(self):
1293
        tree = self.setup_ab_tree()
3848.1.7 by Aaron Bentley
Use repository in get_history_change
1294
        old, new = log.get_history_change('3a', revision.NULL_REVISION,
1295
                                          tree.branch.repository)
3848.1.6 by Aaron Bentley
Implement get_history_change
1296
        self.assertEqual([], new)
1297
        self.assertEqual(['1a', '2a', '3a'], old)
1298
1299
    def test_diverged(self):
1300
        tree = self.setup_ab_tree()
3848.1.7 by Aaron Bentley
Use repository in get_history_change
1301
        old, new = log.get_history_change('3a', '3b', tree.branch.repository)
3848.1.6 by Aaron Bentley
Implement get_history_change
1302
        self.assertEqual(old, ['2a', '3a'])
1303
        self.assertEqual(new, ['2b', '3b'])
1304
1305
    def test_unrelated(self):
1306
        tree = self.setup_ac_tree()
3848.1.7 by Aaron Bentley
Use repository in get_history_change
1307
        old, new = log.get_history_change('3a', '3c', tree.branch.repository)
3848.1.6 by Aaron Bentley
Implement get_history_change
1308
        self.assertEqual(old, ['1a', '2a', '3a'])
1309
        self.assertEqual(new, ['1c', '2c', '3c'])
3848.1.8 by Aaron Bentley
Implement basic show_branch_change
1310
1311
    def test_show_branch_change(self):
1312
        tree = self.setup_ab_tree()
1313
        s = StringIO()
3848.1.12 by Aaron Bentley
Fix test parameter order
1314
        log.show_branch_change(tree.branch, s, 3, '3a')
3848.1.8 by Aaron Bentley
Implement basic show_branch_change
1315
        self.assertContainsRe(s.getvalue(),
1316
            '[*]{60}\nRemoved Revisions:\n(.|\n)*2a(.|\n)*3a(.|\n)*'
1317
            '[*]{60}\n\nAdded Revisions:\n(.|\n)*2b(.|\n)*3b')
1318
1319
    def test_show_branch_change_no_change(self):
1320
        tree = self.setup_ab_tree()
1321
        s = StringIO()
3848.1.12 by Aaron Bentley
Fix test parameter order
1322
        log.show_branch_change(tree.branch, s, 3, '3b')
3848.1.8 by Aaron Bentley
Implement basic show_branch_change
1323
        self.assertEqual(s.getvalue(),
1324
            'Nothing seems to have changed\n')
1325
3848.1.9 by Aaron Bentley
new/old sections are omitted as appropriate.
1326
    def test_show_branch_change_no_old(self):
1327
        tree = self.setup_ab_tree()
1328
        s = StringIO()
3848.1.12 by Aaron Bentley
Fix test parameter order
1329
        log.show_branch_change(tree.branch, s, 2, '2b')
3848.1.9 by Aaron Bentley
new/old sections are omitted as appropriate.
1330
        self.assertContainsRe(s.getvalue(), 'Added Revisions:')
1331
        self.assertNotContainsRe(s.getvalue(), 'Removed Revisions:')
1332
1333
    def test_show_branch_change_no_new(self):
1334
        tree = self.setup_ab_tree()
1335
        tree.branch.set_last_revision_info(2, '2b')
1336
        s = StringIO()
3848.1.12 by Aaron Bentley
Fix test parameter order
1337
        log.show_branch_change(tree.branch, s, 3, '3b')
3848.1.9 by Aaron Bentley
new/old sections are omitted as appropriate.
1338
        self.assertContainsRe(s.getvalue(), 'Removed Revisions:')
1339
        self.assertNotContainsRe(s.getvalue(), 'Added Revisions:')