~bzr-pqm/bzr/bzr.dev

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
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
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
4857.4.3 by John Arbash Meinel
Handle LineLogFormatter
30
class TestCaseForLogFormatter(tests.TestCaseWithTransport):
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
31
32
    def setUp(self):
4857.4.3 by John Arbash Meinel
Handle LineLogFormatter
33
        super(TestCaseForLogFormatter, self).setUp()
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
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
4325.4.3 by Vincent Ladeuil
More cleanups.
36
        # Use a clean registry for log
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
37
        log.properties_handler_registry = registry.Registry()
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
38
4325.4.3 by Vincent Ladeuil
More cleanups.
39
        def restore():
40
            log.properties_handler_registry = self.properties_handler_registry
41
        self.addCleanup(restore)
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
42
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
43
    def assertFormatterResult(self, result, branch, formatter_class,
44
                              formatter_kwargs=None, show_log_kwargs=None,
4857.4.5 by John Arbash Meinel
We don't need the utf8 option, no test actually wanted to run without it,
45
                              normalize=False):
46
        logfile = self.make_utf8_encoded_stringio()
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
47
        if formatter_kwargs is None:
48
            formatter_kwargs = {}
49
        formatter = formatter_class(to_file=logfile, **formatter_kwargs)
50
        if show_log_kwargs is None:
51
            show_log_kwargs = {}
52
        log.show_log(branch, formatter, **show_log_kwargs)
53
        log_content = logfile.getvalue()
54
        if normalize:
55
            log_content = normalize_log(log_content)
56
        self.assertEqualDiff(result, log_content)
57
4857.4.2 by John Arbash Meinel
Add a 'make_standard_commit' helper, to remove more code duplication.
58
    def make_standard_commit(self, branch_nick, **kwargs):
59
        wt = self.make_branch_and_tree('.')
60
        wt.lock_write()
61
        self.addCleanup(wt.unlock)
62
        self.build_tree(['a'])
63
        wt.add(['a'])
64
        wt.branch.nick = branch_nick
65
        kwargs = dict(kwargs)
66
        kwargs.setdefault('message', 'add a')
67
        kwargs.setdefault('timestamp', 1132711707)
68
        kwargs.setdefault('timezone', 36000)
69
        kwargs.setdefault('committer', 'Lorem Ipsum <test@example.com>')
70
        kwargs.setdefault('authors', ['John Doe <jdoe@example.com>'])
71
        wt.commit(**kwargs)
72
        return wt
4857.4.3 by John Arbash Meinel
Handle LineLogFormatter
73
74
    def _prepare_tree_with_merges(self, with_tags=False):
75
        wt = self.make_branch_and_memory_tree('.')
76
        wt.lock_write()
77
        self.addCleanup(wt.unlock)
78
        wt.add('')
79
        wt.commit('rev-1', rev_id='rev-1',
80
                  timestamp=1132586655, timezone=36000,
81
                  committer='Joe Foo <joe@foo.com>')
82
        wt.commit('rev-merged', rev_id='rev-2a',
83
                  timestamp=1132586700, timezone=36000,
84
                  committer='Joe Foo <joe@foo.com>')
85
        wt.set_parent_ids(['rev-1', 'rev-2a'])
86
        wt.branch.set_last_revision_info(1, 'rev-1')
87
        wt.commit('rev-2', rev_id='rev-2b',
88
                  timestamp=1132586800, timezone=36000,
89
                  committer='Joe Foo <joe@foo.com>')
90
        if with_tags:
91
            branch = wt.branch
92
            branch.tags.set_tag('v0.2', 'rev-2b')
93
            wt.commit('rev-3', rev_id='rev-3',
94
                      timestamp=1132586900, timezone=36000,
95
                      committer='Jane Foo <jane@foo.com>')
96
            branch.tags.set_tag('v1.0rc1', 'rev-3')
97
            branch.tags.set_tag('v1.0', 'rev-3')
98
        return wt
99
4857.4.2 by John Arbash Meinel
Add a 'make_standard_commit' helper, to remove more code duplication.
100
        
101
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
102
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
103
class LogCatcher(log.LogFormatter):
4325.4.3 by Vincent Ladeuil
More cleanups.
104
    """Pull log messages into a list rather than displaying them.
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
105
4325.4.3 by Vincent Ladeuil
More cleanups.
106
    To simplify testing we save logged revisions here rather than actually
4325.4.1 by Vincent Ladeuil
Some cleanups.
107
    formatting anything, so that we can precisely check the result without
4325.4.3 by Vincent Ladeuil
More cleanups.
108
    being dependent on the formatting.
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
109
    """
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.
110
2490.1.2 by John Arbash Meinel
Cleanup according to PEP8 and some other small whitespace fixes
111
    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.
112
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
113
    def __init__(self):
114
        super(LogCatcher, self).__init__(to_file=None)
4325.4.4 by Vincent Ladeuil
Clarify LogCatcher purpose.
115
        self.revisions = []
1704.2.20 by Martin Pool
log --line shows revision numbers (Alexander)
116
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.
117
    def log_revision(self, revision):
4325.4.4 by Vincent Ladeuil
Clarify LogCatcher purpose.
118
        self.revisions.append(revision)
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
119
120
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
121
class TestShowLog(tests.TestCaseWithTransport):
1102 by Martin Pool
- merge test refactoring from robertc
122
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
123
    def checkDelta(self, delta, **kw):
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
124
        """Check the filenames touched by a delta are as expected.
125
126
        Caller only have to pass in the list of files for each part, all
127
        unspecified parts are considered empty (and checked as such).
128
        """
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
129
        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.
130
            # By default we expect an empty list
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
131
            expected = kw.get(n, [])
132
            # strip out only the path components
133
            got = [x[0] for x in getattr(delta, n)]
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
134
            self.assertEqual(expected, got)
135
136
    def assertInvalidRevisonNumber(self, br, start, end):
137
        lf = LogCatcher()
138
        self.assertRaises(errors.InvalidRevisionNumber,
139
                          log.show_log, br, lf,
140
                          start_revision=start, end_revision=end)
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
141
974.1.54 by aaron.bentley at utoronto
Fixed the revno bug in log
142
    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.
143
        wt = self.make_branch_and_tree('.')
144
        b = wt.branch
1092.3.4 by Robert Collins
update symlink branch to integration
145
146
        lf = LogCatcher()
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
147
        wt.commit('empty commit')
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
148
        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.
149
150
        # Since there is a single revision in the branch all the combinations
151
        # below should fail.
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
152
        self.assertInvalidRevisonNumber(b, 2, 1)
153
        self.assertInvalidRevisonNumber(b, 1, 2)
154
        self.assertInvalidRevisonNumber(b, 0, 2)
155
        self.assertInvalidRevisonNumber(b, 1, 0)
156
        self.assertInvalidRevisonNumber(b, -1, 1)
157
        self.assertInvalidRevisonNumber(b, 1, -1)
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
158
159
    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.
160
        wt = self.make_branch_and_tree('.')
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
161
162
        lf = LogCatcher()
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
163
        log.show_log(wt.branch, lf)
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
164
        # no entries yet
4325.4.4 by Vincent Ladeuil
Clarify LogCatcher purpose.
165
        self.assertEqual([], lf.revisions)
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
166
167
    def test_empty_commit(self):
168
        wt = self.make_branch_and_tree('.')
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
169
1534.4.36 by Robert Collins
Finish deprecating Branch.working_tree()
170
        wt.commit('empty commit')
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
171
        lf = LogCatcher()
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
172
        log.show_log(wt.branch, lf, verbose=True)
4325.4.4 by Vincent Ladeuil
Clarify LogCatcher purpose.
173
        revs = lf.revisions
174
        self.assertEqual(1, len(revs))
175
        self.assertEqual('1', revs[0].revno)
176
        self.assertEqual('empty commit', revs[0].rev.message)
177
        self.checkDelta(revs[0].delta)
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
178
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
179
    def test_simple_commit(self):
180
        wt = self.make_branch_and_tree('.')
181
        wt.commit('empty commit')
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
182
        self.build_tree(['hello'])
1534.4.36 by Robert Collins
Finish deprecating Branch.working_tree()
183
        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.
184
        wt.commit('add one file',
185
                  committer=u'\u013d\xf3r\xe9m \xcdp\u0161\xfam '
186
                            u'<test@example.com>')
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
187
        lf = LogCatcher()
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
188
        log.show_log(wt.branch, lf, verbose=True)
4325.4.4 by Vincent Ladeuil
Clarify LogCatcher purpose.
189
        self.assertEqual(2, len(lf.revisions))
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
190
        # first one is most recent
4325.4.4 by Vincent Ladeuil
Clarify LogCatcher purpose.
191
        log_entry = lf.revisions[0]
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
192
        self.assertEqual('2', log_entry.revno)
193
        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.
194
        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.
195
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
196
    def test_commit_message_with_control_chars(self):
197
        wt = self.make_branch_and_tree('.')
3831.1.6 by John Arbash Meinel
For the simple-log tests, avoid using '\r' in the test.
198
        msg = u"All 8-bit chars: " +  ''.join([unichr(x) for x in range(256)])
199
        msg = msg.replace(u'\r', u'\n')
1534.4.36 by Robert Collins
Finish deprecating Branch.working_tree()
200
        wt.commit(msg)
1185.11.5 by John Arbash Meinel
Merged up-to-date against mainline, still broken.
201
        lf = LogCatcher()
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
202
        log.show_log(wt.branch, lf, verbose=True)
4325.4.4 by Vincent Ladeuil
Clarify LogCatcher purpose.
203
        committed_msg = lf.revisions[0].rev.message
4627.1.1 by Robert Collins
Review feedback per IanC.
204
        if wt.branch.repository._serializer.squashes_xml_invalid_characters:
205
            self.assertNotEqual(msg, committed_msg)
206
            self.assertTrue(len(committed_msg) > len(msg))
207
        else:
208
            self.assertEqual(msg, committed_msg)
1393.4.2 by Harald Meland
Cleanup + better test of commit-msg control character escape code.
209
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
210
    def test_commit_message_without_control_chars(self):
211
        wt = self.make_branch_and_tree('.')
1393.4.2 by Harald Meland
Cleanup + better test of commit-msg control character escape code.
212
        # escaped.  As ElementTree apparently does some kind of
213
        # newline conversion, neither LF (\x0A) nor CR (\x0D) are
214
        # included in the test commit message, even though they are
215
        # valid XML 1.0 characters.
216
        msg = "\x09" + ''.join([unichr(x) for x in range(0x20, 256)])
1534.4.36 by Robert Collins
Finish deprecating Branch.working_tree()
217
        wt.commit(msg)
1393.4.2 by Harald Meland
Cleanup + better test of commit-msg control character escape code.
218
        lf = LogCatcher()
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
219
        log.show_log(wt.branch, lf, verbose=True)
4325.4.4 by Vincent Ladeuil
Clarify LogCatcher purpose.
220
        committed_msg = lf.revisions[0].rev.message
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
221
        self.assertEqual(msg, committed_msg)
1185.31.22 by John Arbash Meinel
[merge] bzr.dev
222
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
223
    def test_deltas_in_merge_revisions(self):
224
        """Check deltas created for both mainline and merge revisions"""
225
        wt = self.make_branch_and_tree('parent')
226
        self.build_tree(['parent/file1', 'parent/file2', 'parent/file3'])
227
        wt.add('file1')
228
        wt.add('file2')
229
        wt.commit(message='add file1 and file2')
2581.1.6 by Martin Pool
fix up more run_bzr callers
230
        self.run_bzr('branch parent child')
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
231
        os.unlink('child/file1')
2911.6.1 by Blake Winton
Change 'print >> f,'s to 'f.write('s.
232
        file('child/file2', 'wb').write('hello\n')
2581.1.6 by Martin Pool
fix up more run_bzr callers
233
        self.run_bzr(['commit', '-m', 'remove file1 and modify file2',
234
            'child'])
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
235
        os.chdir('parent')
2581.1.6 by Martin Pool
fix up more run_bzr callers
236
        self.run_bzr('merge ../child')
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
237
        wt.commit('merge child branch')
238
        os.chdir('..')
239
        b = wt.branch
240
        lf = LogCatcher()
241
        lf.supports_merge_revisions = True
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
242
        log.show_log(b, lf, verbose=True)
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
243
4325.4.4 by Vincent Ladeuil
Clarify LogCatcher purpose.
244
        revs = lf.revisions
245
        self.assertEqual(3, len(revs))
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
246
4325.4.4 by Vincent Ladeuil
Clarify LogCatcher purpose.
247
        logentry = revs[0]
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
248
        self.assertEqual('2', logentry.revno)
249
        self.assertEqual('merge child branch', logentry.rev.message)
250
        self.checkDelta(logentry.delta, removed=['file1'], modified=['file2'])
251
4325.4.4 by Vincent Ladeuil
Clarify LogCatcher purpose.
252
        logentry = revs[1]
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
253
        self.assertEqual('1.1.1', logentry.revno)
254
        self.assertEqual('remove file1 and modify file2', logentry.rev.message)
255
        self.checkDelta(logentry.delta, removed=['file1'], modified=['file2'])
256
4325.4.4 by Vincent Ladeuil
Clarify LogCatcher purpose.
257
        logentry = revs[2]
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
258
        self.assertEqual('1', logentry.revno)
259
        self.assertEqual('add file1 and file2', logentry.rev.message)
260
        self.checkDelta(logentry.delta, added=['file1', 'file2'])
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
261
262
263
def make_commits_with_trailing_newlines(wt):
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
264
    """Helper method for LogFormatter tests"""
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
265
    b = wt.branch
266
    b.nick='test'
267
    open('a', 'wb').write('hello moto\n')
268
    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.
269
    wt.commit('simple log message', rev_id='a1',
270
              timestamp=1132586655.459960938, timezone=-6*3600,
271
              committer='Joe Foo <joe@foo.com>')
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
272
    open('b', 'wb').write('goodbye\n')
273
    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.
274
    wt.commit('multiline\nlog\nmessage\n', rev_id='a2',
275
              timestamp=1132586842.411175966, timezone=-6*3600,
276
              committer='Joe Foo <joe@foo.com>',
4056.2.3 by James Westby
Use a new "authors" revision property to allow multiple authors
277
              authors=['Joe Bar <joe@bar.com>'])
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
278
279
    open('c', 'wb').write('just another manic monday\n')
280
    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.
281
    wt.commit('single line with trailing newline\n', rev_id='a3',
282
              timestamp=1132587176.835228920, timezone=-6*3600,
283
              committer = 'Joe Foo <joe@foo.com>')
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
284
    return b
285
286
2978.6.1 by Kent Gibson
Use normalize_log to more accurately test blackbox log output.
287
def normalize_log(log):
288
    """Replaces the variable lines of logs with fixed lines"""
289
    author = 'author: Dolor Sit <test@example.com>'
290
    committer = 'committer: Lorem Ipsum <test@example.com>'
291
    lines = log.splitlines(True)
292
    for idx,line in enumerate(lines):
293
        stripped_line = line.lstrip()
294
        indent = ' ' * (len(line) - len(stripped_line))
295
        if stripped_line.startswith('author:'):
296
            lines[idx] = indent + author + '\n'
297
        elif stripped_line.startswith('committer:'):
298
            lines[idx] = indent + committer + '\n'
299
        elif stripped_line.startswith('timestamp:'):
300
            lines[idx] = indent + 'timestamp: Just now\n'
301
    return ''.join(lines)
302
303
4857.4.3 by John Arbash Meinel
Handle LineLogFormatter
304
class TestShortLogFormatter(TestCaseForLogFormatter):
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
305
1185.31.21 by John Arbash Meinel
Added test for log formatting, found bug when redirecting short logs to a file instead of stdout.
306
    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.
307
        wt = self.make_branch_and_tree('.')
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
308
        b = make_commits_with_trailing_newlines(wt)
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
309
        self.assertFormatterResult("""\
1185.31.21 by John Arbash Meinel
Added test for log formatting, found bug when redirecting short logs to a file instead of stdout.
310
    3 Joe Foo\t2005-11-21
311
      single line with trailing newline
312
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.
313
    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.
314
      multiline
315
      log
316
      message
317
318
    1 Joe Foo\t2005-11-21
319
      simple log message
320
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
321
""",
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
322
            b, log.ShortLogFormatter)
1185.31.21 by John Arbash Meinel
Added test for log formatting, found bug when redirecting short logs to a file instead of stdout.
323
2997.1.1 by Kent Gibson
Support logging single merge revisions with short and line log formatters.
324
    def test_short_log_with_merges(self):
3946.3.2 by Ian Clatworthy
add tests & NEWS item
325
        wt = self._prepare_tree_with_merges()
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
326
        self.assertFormatterResult("""\
2997.1.1 by Kent Gibson
Support logging single merge revisions with short and line log formatters.
327
    2 Joe Foo\t2005-11-22 [merge]
328
      rev-2
329
330
    1 Joe Foo\t2005-11-22
331
      rev-1
332
4221.2.3 by Ian Clatworthy
jam feedback: don't show advice if --levels explicitly given
333
""",
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
334
            wt.branch, log.ShortLogFormatter)
4221.2.3 by Ian Clatworthy
jam feedback: don't show advice if --levels explicitly given
335
336
    def test_short_log_with_merges_and_advice(self):
337
        wt = self._prepare_tree_with_merges()
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
338
        self.assertFormatterResult("""\
4221.2.3 by Ian Clatworthy
jam feedback: don't show advice if --levels explicitly given
339
    2 Joe Foo\t2005-11-22 [merge]
340
      rev-2
341
342
    1 Joe Foo\t2005-11-22
343
      rev-1
344
4221.2.1 by Ian Clatworthy
--include-merges as an alias for --levels 0 in log
345
Use --include-merges or -n0 to see merged revisions.
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
346
""",
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
347
            wt.branch, log.ShortLogFormatter,
348
            formatter_kwargs=dict(show_advice=True))
2997.1.1 by Kent Gibson
Support logging single merge revisions with short and line log formatters.
349
3943.4.2 by John Arbash Meinel
Add a test case which exercises this code path.
350
    def test_short_log_with_merges_and_range(self):
351
        wt = self.make_branch_and_memory_tree('.')
352
        wt.lock_write()
353
        self.addCleanup(wt.unlock)
354
        wt.add('')
355
        wt.commit('rev-1', rev_id='rev-1',
356
                  timestamp=1132586655, timezone=36000,
357
                  committer='Joe Foo <joe@foo.com>')
358
        wt.commit('rev-merged', rev_id='rev-2a',
359
                  timestamp=1132586700, timezone=36000,
360
                  committer='Joe Foo <joe@foo.com>')
361
        wt.branch.set_last_revision_info(1, 'rev-1')
362
        wt.set_parent_ids(['rev-1', 'rev-2a'])
363
        wt.commit('rev-2b', rev_id='rev-2b',
364
                  timestamp=1132586800, timezone=36000,
365
                  committer='Joe Foo <joe@foo.com>')
366
        wt.commit('rev-3a', rev_id='rev-3a',
367
                  timestamp=1132586800, timezone=36000,
368
                  committer='Joe Foo <joe@foo.com>')
369
        wt.branch.set_last_revision_info(2, 'rev-2b')
370
        wt.set_parent_ids(['rev-2b', 'rev-3a'])
371
        wt.commit('rev-3b', rev_id='rev-3b',
372
                  timestamp=1132586800, timezone=36000,
373
                  committer='Joe Foo <joe@foo.com>')
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
374
        self.assertFormatterResult("""\
3943.4.2 by John Arbash Meinel
Add a test case which exercises this code path.
375
    3 Joe Foo\t2005-11-22 [merge]
376
      rev-3b
377
378
    2 Joe Foo\t2005-11-22 [merge]
379
      rev-2b
380
381
""",
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
382
            wt.branch, log.ShortLogFormatter,
383
            show_log_kwargs=dict(start_revision=2, end_revision=3))
3943.4.2 by John Arbash Meinel
Add a test case which exercises this code path.
384
3946.3.2 by Ian Clatworthy
add tests & NEWS item
385
    def test_short_log_with_tags(self):
386
        wt = self._prepare_tree_with_merges(with_tags=True)
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
387
        self.assertFormatterResult("""\
3946.3.2 by Ian Clatworthy
add tests & NEWS item
388
    3 Jane Foo\t2005-11-22 {v1.0, v1.0rc1}
389
      rev-3
390
391
    2 Joe Foo\t2005-11-22 {v0.2} [merge]
392
      rev-2
393
394
    1 Joe Foo\t2005-11-22
395
      rev-1
396
397
""",
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
398
            wt.branch, log.ShortLogFormatter)
3946.3.2 by Ian Clatworthy
add tests & NEWS item
399
2997.1.1 by Kent Gibson
Support logging single merge revisions with short and line log formatters.
400
    def test_short_log_single_merge_revision(self):
401
        wt = self.make_branch_and_memory_tree('.')
402
        wt.lock_write()
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
403
        self.addCleanup(wt.unlock)
404
        wt.add('')
405
        wt.commit('rev-1', rev_id='rev-1',
406
                  timestamp=1132586655, timezone=36000,
407
                  committer='Joe Foo <joe@foo.com>')
408
        wt.commit('rev-merged', rev_id='rev-2a',
409
                  timestamp=1132586700, timezone=36000,
410
                  committer='Joe Foo <joe@foo.com>')
411
        wt.set_parent_ids(['rev-1', 'rev-2a'])
412
        wt.branch.set_last_revision_info(1, 'rev-1')
413
        wt.commit('rev-2', rev_id='rev-2b',
414
                  timestamp=1132586800, timezone=36000,
415
                  committer='Joe Foo <joe@foo.com>')
416
        revspec = revisionspec.RevisionSpec.from_string('1.1.1')
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
417
        rev = revspec.in_history(wt.branch)
418
        self.assertFormatterResult("""\
3947.1.10 by Ian Clatworthy
review feedback from vila
419
      1.1.1 Joe Foo\t2005-11-22
420
            rev-merged
2997.1.1 by Kent Gibson
Support logging single merge revisions with short and line log formatters.
421
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
422
""",
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
423
            wt.branch, log.ShortLogFormatter,
424
            show_log_kwargs=dict(start_revision=rev, end_revision=rev))
425
426
4857.4.3 by John Arbash Meinel
Handle LineLogFormatter
427
class TestShortLogFormatterWithMergeRevisions(TestCaseForLogFormatter):
3947.1.2 by Ian Clatworthy
formatter tests
428
429
    def test_short_merge_revs_log_with_merges(self):
430
        wt = self.make_branch_and_memory_tree('.')
431
        wt.lock_write()
432
        self.addCleanup(wt.unlock)
433
        wt.add('')
434
        wt.commit('rev-1', rev_id='rev-1',
435
                  timestamp=1132586655, timezone=36000,
436
                  committer='Joe Foo <joe@foo.com>')
437
        wt.commit('rev-merged', rev_id='rev-2a',
438
                  timestamp=1132586700, timezone=36000,
439
                  committer='Joe Foo <joe@foo.com>')
440
        wt.set_parent_ids(['rev-1', 'rev-2a'])
441
        wt.branch.set_last_revision_info(1, 'rev-1')
442
        wt.commit('rev-2', rev_id='rev-2b',
443
                  timestamp=1132586800, timezone=36000,
444
                  committer='Joe Foo <joe@foo.com>')
3947.1.7 by Ian Clatworthy
tweak indenting/offsetting for --short given dotted revno lengths
445
        # Note that the 1.1.1 indenting is in fact correct given that
446
        # the revision numbers are right justified within 5 characters
447
        # for mainline revnos and 9 characters for dotted revnos.
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
448
        self.assertFormatterResult("""\
3947.1.2 by Ian Clatworthy
formatter tests
449
    2 Joe Foo\t2005-11-22 [merge]
450
      rev-2
451
3947.1.10 by Ian Clatworthy
review feedback from vila
452
          1.1.1 Joe Foo\t2005-11-22
453
                rev-merged
3947.1.2 by Ian Clatworthy
formatter tests
454
455
    1 Joe Foo\t2005-11-22
456
      rev-1
457
458
""",
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
459
            wt.branch, log.ShortLogFormatter,
460
            formatter_kwargs=dict(levels=0))
3947.1.2 by Ian Clatworthy
formatter tests
461
462
    def test_short_merge_revs_log_single_merge_revision(self):
463
        wt = self.make_branch_and_memory_tree('.')
464
        wt.lock_write()
465
        self.addCleanup(wt.unlock)
466
        wt.add('')
467
        wt.commit('rev-1', rev_id='rev-1',
468
                  timestamp=1132586655, timezone=36000,
469
                  committer='Joe Foo <joe@foo.com>')
470
        wt.commit('rev-merged', rev_id='rev-2a',
471
                  timestamp=1132586700, timezone=36000,
472
                  committer='Joe Foo <joe@foo.com>')
473
        wt.set_parent_ids(['rev-1', 'rev-2a'])
474
        wt.branch.set_last_revision_info(1, 'rev-1')
475
        wt.commit('rev-2', rev_id='rev-2b',
476
                  timestamp=1132586800, timezone=36000,
477
                  committer='Joe Foo <joe@foo.com>')
478
        revspec = revisionspec.RevisionSpec.from_string('1.1.1')
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
479
        rev = revspec.in_history(wt.branch)
480
        self.assertFormatterResult("""\
3947.1.10 by Ian Clatworthy
review feedback from vila
481
      1.1.1 Joe Foo\t2005-11-22
482
            rev-merged
3947.1.2 by Ian Clatworthy
formatter tests
483
484
""",
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
485
            wt.branch, log.ShortLogFormatter,
486
            formatter_kwargs=dict(levels=0),
487
            show_log_kwargs=dict(start_revision=rev, end_revision=rev))
3947.1.2 by Ian Clatworthy
formatter tests
488
489
4857.4.3 by John Arbash Meinel
Handle LineLogFormatter
490
class TestLongLogFormatter(TestCaseForLogFormatter):
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
491
1185.33.41 by Martin Pool
Fix regression of 'bzr log -v' - it wasn't showing changed files at all. (#4676)
492
    def test_verbose_log(self):
493
        """Verbose log includes changed files
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
494
1185.33.41 by Martin Pool
Fix regression of 'bzr log -v' - it wasn't showing changed files at all. (#4676)
495
        bug #4676
496
        """
4857.4.4 by John Arbash Meinel
One more standard-commit
497
        wt = self.make_standard_commit('test_verbose_log', authors=[])
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
498
        self.assertFormatterResult('''\
1185.33.41 by Martin Pool
Fix regression of 'bzr log -v' - it wasn't showing changed files at all. (#4676)
499
------------------------------------------------------------
500
revno: 1
2671.5.7 by Lukáš Lalinsky
Rename get_author to get_apparent_author, revert the long log back to displaying the committer.
501
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)
502
branch nick: test_verbose_log
503
timestamp: Wed 2005-11-23 12:08:27 +1000
504
message:
505
  add a
506
added:
507
  a
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
508
''',
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
509
            wt.branch, log.LongLogFormatter,
4857.4.5 by John Arbash Meinel
We don't need the utf8 option, no test actually wanted to run without it,
510
            show_log_kwargs=dict(verbose=True))
1185.85.4 by John Arbash Meinel
currently broken, trying to fix things up.
511
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
512
    def test_merges_are_indented_by_level(self):
513
        wt = self.make_branch_and_tree('parent')
514
        wt.commit('first post')
2581.1.6 by Martin Pool
fix up more run_bzr callers
515
        self.run_bzr('branch parent child')
516
        self.run_bzr(['commit', '-m', 'branch 1', '--unchanged', 'child'])
517
        self.run_bzr('branch child smallerchild')
518
        self.run_bzr(['commit', '-m', 'branch 2', '--unchanged',
519
            'smallerchild'])
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
520
        os.chdir('child')
2581.1.6 by Martin Pool
fix up more run_bzr callers
521
        self.run_bzr('merge ../smallerchild')
522
        self.run_bzr(['commit', '-m', 'merge branch 2'])
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
523
        os.chdir('../parent')
2581.1.6 by Martin Pool
fix up more run_bzr callers
524
        self.run_bzr('merge ../child')
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
525
        wt.commit('merge branch 1')
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
526
        self.assertFormatterResult("""\
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
527
------------------------------------------------------------
4208.2.1 by Ian Clatworthy
merge indicators in log --long
528
revno: 2 [merge]
2671.5.7 by Lukáš Lalinsky
Rename get_author to get_apparent_author, revert the long log back to displaying the committer.
529
committer: Lorem Ipsum <test@example.com>
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
530
branch nick: parent
531
timestamp: Just now
532
message:
533
  merge branch 1
534
    ------------------------------------------------------------
4208.2.1 by Ian Clatworthy
merge indicators in log --long
535
    revno: 1.1.2 [merge]
2671.5.7 by Lukáš Lalinsky
Rename get_author to get_apparent_author, revert the long log back to displaying the committer.
536
    committer: Lorem Ipsum <test@example.com>
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
537
    branch nick: child
538
    timestamp: Just now
539
    message:
540
      merge branch 2
541
        ------------------------------------------------------------
3170.3.4 by John Arbash Meinel
Update the tests for the new revision numbering.
542
        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.
543
        committer: Lorem Ipsum <test@example.com>
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
544
        branch nick: smallerchild
545
        timestamp: Just now
546
        message:
547
          branch 2
548
    ------------------------------------------------------------
549
    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.
550
    committer: Lorem Ipsum <test@example.com>
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
551
    branch nick: child
552
    timestamp: Just now
553
    message:
554
      branch 1
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
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
562
""",
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
563
            wt.branch, log.LongLogFormatter,
564
            formatter_kwargs=dict(levels=0),
565
            show_log_kwargs=dict(verbose=True),
566
            normalize=True)
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
567
568
    def test_verbose_merge_revisions_contain_deltas(self):
569
        wt = self.make_branch_and_tree('parent')
570
        self.build_tree(['parent/f1', 'parent/f2'])
571
        wt.add(['f1','f2'])
572
        wt.commit('first post')
2581.1.6 by Martin Pool
fix up more run_bzr callers
573
        self.run_bzr('branch parent child')
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
574
        os.unlink('child/f1')
2911.6.1 by Blake Winton
Change 'print >> f,'s to 'f.write('s.
575
        file('child/f2', 'wb').write('hello\n')
2581.1.6 by Martin Pool
fix up more run_bzr callers
576
        self.run_bzr(['commit', '-m', 'removed f1 and modified f2',
577
            'child'])
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
578
        os.chdir('parent')
2581.1.6 by Martin Pool
fix up more run_bzr callers
579
        self.run_bzr('merge ../child')
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
580
        wt.commit('merge branch 1')
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
581
        self.assertFormatterResult("""\
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
582
------------------------------------------------------------
4208.2.1 by Ian Clatworthy
merge indicators in log --long
583
revno: 2 [merge]
2671.5.7 by Lukáš Lalinsky
Rename get_author to get_apparent_author, revert the long log back to displaying the committer.
584
committer: Lorem Ipsum <test@example.com>
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
585
branch nick: parent
586
timestamp: Just now
587
message:
588
  merge branch 1
589
removed:
590
  f1
591
modified:
592
  f2
593
    ------------------------------------------------------------
594
    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.
595
    committer: Lorem Ipsum <test@example.com>
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
596
    branch nick: child
597
    timestamp: Just now
598
    message:
599
      removed f1 and modified f2
600
    removed:
601
      f1
602
    modified:
603
      f2
604
------------------------------------------------------------
605
revno: 1
2671.5.7 by Lukáš Lalinsky
Rename get_author to get_apparent_author, revert the long log back to displaying the committer.
606
committer: Lorem Ipsum <test@example.com>
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
607
branch nick: parent
608
timestamp: Just now
609
message:
610
  first post
611
added:
612
  f1
613
  f2
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
614
""",
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
615
            wt.branch, log.LongLogFormatter,
616
            formatter_kwargs=dict(levels=0),
617
            show_log_kwargs=dict(verbose=True),
618
            normalize=True)
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
619
620
    def test_trailing_newlines(self):
621
        wt = self.make_branch_and_tree('.')
622
        b = make_commits_with_trailing_newlines(wt)
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
623
        self.assertFormatterResult("""\
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
624
------------------------------------------------------------
625
revno: 3
2671.5.7 by Lukáš Lalinsky
Rename get_author to get_apparent_author, revert the long log back to displaying the committer.
626
committer: Joe Foo <joe@foo.com>
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
627
branch nick: test
628
timestamp: Mon 2005-11-21 09:32:56 -0600
629
message:
630
  single line with trailing newline
631
------------------------------------------------------------
632
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.
633
author: Joe Bar <joe@bar.com>
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
634
committer: Joe Foo <joe@foo.com>
635
branch nick: test
636
timestamp: Mon 2005-11-21 09:27:22 -0600
637
message:
638
  multiline
639
  log
640
  message
641
------------------------------------------------------------
642
revno: 1
2671.5.7 by Lukáš Lalinsky
Rename get_author to get_apparent_author, revert the long log back to displaying the committer.
643
committer: Joe Foo <joe@foo.com>
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
644
branch nick: test
645
timestamp: Mon 2005-11-21 09:24:15 -0600
646
message:
647
  simple log message
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
648
""",
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
649
        b, log.LongLogFormatter)
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
650
2671.5.7 by Lukáš Lalinsky
Rename get_author to get_apparent_author, revert the long log back to displaying the committer.
651
    def test_author_in_log(self):
652
        """Log includes the author name if it's set in
653
        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.
654
        """
4857.4.2 by John Arbash Meinel
Add a 'make_standard_commit' helper, to remove more code duplication.
655
        wt = self.make_standard_commit('test_author_log',
656
            authors=['John Doe <jdoe@example.com>',
657
                     'Jane Rey <jrey@example.com>'])
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
658
        self.assertFormatterResult("""\
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.
659
------------------------------------------------------------
660
revno: 1
4056.2.3 by James Westby
Use a new "authors" revision property to allow multiple authors
661
author: John Doe <jdoe@example.com>, Jane Rey <jrey@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.
662
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.
663
branch nick: test_author_log
664
timestamp: Wed 2005-11-23 12:08:27 +1000
665
message:
4857.4.2 by John Arbash Meinel
Add a 'make_standard_commit' helper, to remove more code duplication.
666
  add a
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
667
""",
4857.4.5 by John Arbash Meinel
We don't need the utf8 option, no test actually wanted to run without it,
668
        wt.branch, log.LongLogFormatter)
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.
669
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
670
    def test_properties_in_log(self):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
671
        """Log includes the custom properties returned by the registered
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
672
        handlers.
673
        """
4857.4.2 by John Arbash Meinel
Add a 'make_standard_commit' helper, to remove more code duplication.
674
        wt = self.make_standard_commit('test_properties_in_log')
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
675
        def trivial_custom_prop_handler(revision):
676
            return {'test_prop':'test_value'}
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
677
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
678
        # Cleaned up in setUp()
679
        log.properties_handler_registry.register(
680
            'trivial_custom_prop_handler',
681
            trivial_custom_prop_handler)
682
        self.assertFormatterResult("""\
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
683
------------------------------------------------------------
684
revno: 1
685
test_prop: test_value
686
author: John Doe <jdoe@example.com>
687
committer: Lorem Ipsum <test@example.com>
3144.7.13 by Guillermo Gonzalez
* fixed typo LogFormatter.show_properties in docstring
688
branch nick: test_properties_in_log
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
689
timestamp: Wed 2005-11-23 12:08:27 +1000
690
message:
4857.4.2 by John Arbash Meinel
Add a 'make_standard_commit' helper, to remove more code duplication.
691
  add a
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
692
""",
4857.4.5 by John Arbash Meinel
We don't need the utf8 option, no test actually wanted to run without it,
693
            wt.branch, log.LongLogFormatter)
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
694
3976.3.1 by Neil Martinsen-Burrell
Add custom properties handling to short log format
695
    def test_properties_in_short_log(self):
4032.1.2 by John Arbash Meinel
Track down a few more files that have trailing whitespace.
696
        """Log includes the custom properties returned by the registered
3976.3.1 by Neil Martinsen-Burrell
Add custom properties handling to short log format
697
        handlers.
698
        """
4857.4.2 by John Arbash Meinel
Add a 'make_standard_commit' helper, to remove more code duplication.
699
        wt = self.make_standard_commit('test_properties_in_short_log')
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
700
        def trivial_custom_prop_handler(revision):
701
            return {'test_prop':'test_value'}
3976.3.1 by Neil Martinsen-Burrell
Add custom properties handling to short log format
702
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
703
        log.properties_handler_registry.register(
704
            'trivial_custom_prop_handler',
705
            trivial_custom_prop_handler)
706
        self.assertFormatterResult("""\
3976.3.3 by Jelmer Vernooij
remove a tab character.
707
    1 John Doe\t2005-11-23
3976.3.1 by Neil Martinsen-Burrell
Add custom properties handling to short log format
708
      test_prop: test_value
4857.4.2 by John Arbash Meinel
Add a 'make_standard_commit' helper, to remove more code duplication.
709
      add a
3976.3.1 by Neil Martinsen-Burrell
Add custom properties handling to short log format
710
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
711
""",
712
            wt.branch, log.ShortLogFormatter)
3976.3.1 by Neil Martinsen-Burrell
Add custom properties handling to short log format
713
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
714
    def test_error_in_properties_handler(self):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
715
        """Log includes the custom properties returned by the registered
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
716
        handlers.
717
        """
4857.4.2 by John Arbash Meinel
Add a 'make_standard_commit' helper, to remove more code duplication.
718
        wt = self.make_standard_commit('error_in_properties_handler',
719
            revprops={'first_prop':'first_value'})
4857.4.5 by John Arbash Meinel
We don't need the utf8 option, no test actually wanted to run without it,
720
        sio = self.make_utf8_encoded_stringio()
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
721
        formatter = log.LongLogFormatter(to_file=sio)
4857.4.2 by John Arbash Meinel
Add a 'make_standard_commit' helper, to remove more code duplication.
722
        def trivial_custom_prop_handler(revision):
723
            raise StandardError("a test error")
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
724
4857.4.2 by John Arbash Meinel
Add a 'make_standard_commit' helper, to remove more code duplication.
725
        log.properties_handler_registry.register(
726
            'trivial_custom_prop_handler',
727
            trivial_custom_prop_handler)
728
        self.assertRaises(StandardError, log.show_log, wt.branch, formatter,)
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
729
3144.7.13 by Guillermo Gonzalez
* fixed typo LogFormatter.show_properties in docstring
730
    def test_properties_handler_bad_argument(self):
4857.4.2 by John Arbash Meinel
Add a 'make_standard_commit' helper, to remove more code duplication.
731
        wt = self.make_standard_commit('bad_argument',
732
              revprops={'a_prop':'test_value'})
4857.4.5 by John Arbash Meinel
We don't need the utf8 option, no test actually wanted to run without it,
733
        sio = self.make_utf8_encoded_stringio()
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
734
        formatter = log.LongLogFormatter(to_file=sio)
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
735
        def bad_argument_prop_handler(revision):
736
            return {'custom_prop_name':revision.properties['a_prop']}
737
738
        log.properties_handler_registry.register(
739
            'bad_argument_prop_handler',
740
            bad_argument_prop_handler)
741
742
        self.assertRaises(AttributeError, formatter.show_properties,
743
                          'a revision', '')
744
745
        revision = wt.branch.repository.get_revision(wt.branch.last_revision())
746
        formatter.show_properties(revision, '')
747
        self.assertEqualDiff('''custom_prop_name: test_value\n''',
748
                             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.
749
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
750
4857.4.3 by John Arbash Meinel
Handle LineLogFormatter
751
class TestLongLogFormatterWithoutMergeRevisions(TestCaseForLogFormatter):
3947.1.2 by Ian Clatworthy
formatter tests
752
753
    def test_long_verbose_log(self):
754
        """Verbose log includes changed files
4032.1.2 by John Arbash Meinel
Track down a few more files that have trailing whitespace.
755
3947.1.2 by Ian Clatworthy
formatter tests
756
        bug #4676
757
        """
4857.4.2 by John Arbash Meinel
Add a 'make_standard_commit' helper, to remove more code duplication.
758
        wt = self.make_standard_commit('test_long_verbose_log', authors=[])
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
759
        self.assertFormatterResult("""\
3947.1.2 by Ian Clatworthy
formatter tests
760
------------------------------------------------------------
761
revno: 1
762
committer: Lorem Ipsum <test@example.com>
4857.4.2 by John Arbash Meinel
Add a 'make_standard_commit' helper, to remove more code duplication.
763
branch nick: test_long_verbose_log
3947.1.2 by Ian Clatworthy
formatter tests
764
timestamp: Wed 2005-11-23 12:08:27 +1000
765
message:
766
  add a
767
added:
768
  a
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
769
""",
770
            wt.branch, log.LongLogFormatter,
771
            formatter_kwargs=dict(levels=1),
4857.4.5 by John Arbash Meinel
We don't need the utf8 option, no test actually wanted to run without it,
772
            show_log_kwargs=dict(verbose=True))
3947.1.2 by Ian Clatworthy
formatter tests
773
774
    def test_long_verbose_contain_deltas(self):
775
        wt = self.make_branch_and_tree('parent')
776
        self.build_tree(['parent/f1', 'parent/f2'])
777
        wt.add(['f1','f2'])
778
        wt.commit('first post')
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
779
        child_wt = wt.bzrdir.sprout('child').open_workingtree()
3947.1.2 by Ian Clatworthy
formatter tests
780
        os.unlink('child/f1')
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
781
        self.build_tree_contents([('child/f2', 'hello\n')])
782
        child_wt.commit('removed f1 and modified f2')
783
        wt.merge_from_branch(child_wt.branch)
3947.1.2 by Ian Clatworthy
formatter tests
784
        wt.commit('merge branch 1')
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
785
        self.assertFormatterResult("""\
3947.1.2 by Ian Clatworthy
formatter tests
786
------------------------------------------------------------
4208.2.1 by Ian Clatworthy
merge indicators in log --long
787
revno: 2 [merge]
3947.1.2 by Ian Clatworthy
formatter tests
788
committer: Lorem Ipsum <test@example.com>
789
branch nick: parent
790
timestamp: Just now
791
message:
792
  merge branch 1
793
removed:
794
  f1
795
modified:
796
  f2
797
------------------------------------------------------------
798
revno: 1
799
committer: Lorem Ipsum <test@example.com>
800
branch nick: parent
801
timestamp: Just now
802
message:
803
  first post
804
added:
805
  f1
806
  f2
807
""",
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
808
            wt.branch, log.LongLogFormatter,
809
            formatter_kwargs=dict(levels=1),
810
            show_log_kwargs=dict(verbose=True),
811
            normalize=True)
3947.1.2 by Ian Clatworthy
formatter tests
812
813
    def test_long_trailing_newlines(self):
814
        wt = self.make_branch_and_tree('.')
815
        b = make_commits_with_trailing_newlines(wt)
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
816
        self.assertFormatterResult("""\
3947.1.2 by Ian Clatworthy
formatter tests
817
------------------------------------------------------------
818
revno: 3
819
committer: Joe Foo <joe@foo.com>
820
branch nick: test
821
timestamp: Mon 2005-11-21 09:32:56 -0600
822
message:
823
  single line with trailing newline
824
------------------------------------------------------------
825
revno: 2
826
author: Joe Bar <joe@bar.com>
827
committer: Joe Foo <joe@foo.com>
828
branch nick: test
829
timestamp: Mon 2005-11-21 09:27:22 -0600
830
message:
831
  multiline
832
  log
833
  message
834
------------------------------------------------------------
835
revno: 1
836
committer: Joe Foo <joe@foo.com>
837
branch nick: test
838
timestamp: Mon 2005-11-21 09:24:15 -0600
839
message:
840
  simple log message
841
""",
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
842
        b, log.LongLogFormatter,
843
        formatter_kwargs=dict(levels=1))
3947.1.2 by Ian Clatworthy
formatter tests
844
845
    def test_long_author_in_log(self):
846
        """Log includes the author name if it's set in
847
        the revision properties
848
        """
4857.4.2 by John Arbash Meinel
Add a 'make_standard_commit' helper, to remove more code duplication.
849
        wt = self.make_standard_commit('test_author_log')
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
850
        self.assertFormatterResult("""\
3947.1.2 by Ian Clatworthy
formatter tests
851
------------------------------------------------------------
852
revno: 1
853
author: John Doe <jdoe@example.com>
854
committer: Lorem Ipsum <test@example.com>
855
branch nick: test_author_log
856
timestamp: Wed 2005-11-23 12:08:27 +1000
857
message:
4857.4.2 by John Arbash Meinel
Add a 'make_standard_commit' helper, to remove more code duplication.
858
  add a
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
859
""",
860
            wt.branch, log.LongLogFormatter,
861
            formatter_kwargs=dict(levels=1))
3947.1.2 by Ian Clatworthy
formatter tests
862
863
    def test_long_properties_in_log(self):
4032.1.2 by John Arbash Meinel
Track down a few more files that have trailing whitespace.
864
        """Log includes the custom properties returned by the registered
3947.1.2 by Ian Clatworthy
formatter tests
865
        handlers.
866
        """
4857.4.2 by John Arbash Meinel
Add a 'make_standard_commit' helper, to remove more code duplication.
867
        wt = self.make_standard_commit('test_properties_in_log')
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
868
        def trivial_custom_prop_handler(revision):
869
            return {'test_prop':'test_value'}
3947.1.2 by Ian Clatworthy
formatter tests
870
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
871
        log.properties_handler_registry.register(
872
            'trivial_custom_prop_handler',
873
            trivial_custom_prop_handler)
874
        self.assertFormatterResult("""\
3947.1.2 by Ian Clatworthy
formatter tests
875
------------------------------------------------------------
876
revno: 1
877
test_prop: test_value
878
author: John Doe <jdoe@example.com>
879
committer: Lorem Ipsum <test@example.com>
880
branch nick: test_properties_in_log
881
timestamp: Wed 2005-11-23 12:08:27 +1000
882
message:
4857.4.2 by John Arbash Meinel
Add a 'make_standard_commit' helper, to remove more code duplication.
883
  add a
4857.4.1 by John Arbash Meinel
Start cleaning up test_log.
884
""",
885
            wt.branch, log.LongLogFormatter,
886
            formatter_kwargs=dict(levels=1))
3947.1.2 by Ian Clatworthy
formatter tests
887
888
4857.4.3 by John Arbash Meinel
Handle LineLogFormatter
889
class TestLineLogFormatter(TestCaseForLogFormatter):
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
890
1704.2.20 by Martin Pool
log --line shows revision numbers (Alexander)
891
    def test_line_log(self):
892
        """Line log should show revno
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
893
1704.2.20 by Martin Pool
log --line shows revision numbers (Alexander)
894
        bug #5162
895
        """
4857.4.3 by John Arbash Meinel
Handle LineLogFormatter
896
        wt = self.make_standard_commit('test-line-log',
897
                committer='Line-Log-Formatter Tester <test@line.log>',
898
                authors=[])
899
        self.assertFormatterResult("""\
900
1: Line-Log-Formatte... 2005-11-23 add a
901
""",
902
            wt.branch, log.LineLogFormatter)
1756.2.20 by Aaron Bentley
Optimize log formats that don't show merges
903
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
904
    def test_trailing_newlines(self):
905
        wt = self.make_branch_and_tree('.')
906
        b = make_commits_with_trailing_newlines(wt)
4857.4.3 by John Arbash Meinel
Handle LineLogFormatter
907
        self.assertFormatterResult("""\
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
908
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.
909
2: Joe Bar 2005-11-21 multiline
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
910
1: Joe Foo 2005-11-21 simple log message
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
911
""",
4857.4.3 by John Arbash Meinel
Handle LineLogFormatter
912
            b, log.LineLogFormatter)
3946.3.2 by Ian Clatworthy
add tests & NEWS item
913
2997.1.1 by Kent Gibson
Support logging single merge revisions with short and line log formatters.
914
    def test_line_log_single_merge_revision(self):
3946.3.2 by Ian Clatworthy
add tests & NEWS item
915
        wt = self._prepare_tree_with_merges()
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
916
        revspec = revisionspec.RevisionSpec.from_string('1.1.1')
4857.4.3 by John Arbash Meinel
Handle LineLogFormatter
917
        rev = revspec.in_history(wt.branch)
918
        self.assertFormatterResult("""\
2997.1.1 by Kent Gibson
Support logging single merge revisions with short and line log formatters.
919
1.1.1: Joe Foo 2005-11-22 rev-merged
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
920
""",
4857.4.3 by John Arbash Meinel
Handle LineLogFormatter
921
            wt.branch, log.LineLogFormatter,
922
            show_log_kwargs=dict(start_revision=rev, end_revision=rev))
2997.1.1 by Kent Gibson
Support logging single merge revisions with short and line log formatters.
923
3946.3.2 by Ian Clatworthy
add tests & NEWS item
924
    def test_line_log_with_tags(self):
925
        wt = self._prepare_tree_with_merges(with_tags=True)
4857.4.3 by John Arbash Meinel
Handle LineLogFormatter
926
        self.assertFormatterResult("""\
3946.3.3 by Ian Clatworthy
feedback from jelmer re position of tags in --line
927
3: Jane Foo 2005-11-22 {v1.0, v1.0rc1} rev-3
3983.2.1 by Neil Martinsen-Burrell
add merge indication to the line format
928
2: Joe Foo 2005-11-22 [merge] {v0.2} rev-2
3946.3.2 by Ian Clatworthy
add tests & NEWS item
929
1: Joe Foo 2005-11-22 rev-1
930
""",
4857.4.3 by John Arbash Meinel
Handle LineLogFormatter
931
            wt.branch, log.LineLogFormatter)
932
933
934
class TestLineLogFormatterWithMergeRevisions(TestCaseForLogFormatter):
3947.1.2 by Ian Clatworthy
formatter tests
935
936
    def test_line_merge_revs_log(self):
937
        """Line log should show revno
4032.1.2 by John Arbash Meinel
Track down a few more files that have trailing whitespace.
938
3947.1.2 by Ian Clatworthy
formatter tests
939
        bug #5162
940
        """
4857.4.3 by John Arbash Meinel
Handle LineLogFormatter
941
        wt = self.make_standard_commit('test-line-log',
942
                committer='Line-Log-Formatter Tester <test@line.log>',
943
                authors=[])
944
        self.assertFormatterResult("""\
945
1: Line-Log-Formatte... 2005-11-23 add a
946
""",
947
            wt.branch, log.LineLogFormatter)
3947.1.2 by Ian Clatworthy
formatter tests
948
949
    def test_line_merge_revs_log_single_merge_revision(self):
950
        wt = self.make_branch_and_memory_tree('.')
951
        wt.lock_write()
952
        self.addCleanup(wt.unlock)
953
        wt.add('')
954
        wt.commit('rev-1', rev_id='rev-1',
955
                  timestamp=1132586655, timezone=36000,
956
                  committer='Joe Foo <joe@foo.com>')
957
        wt.commit('rev-merged', rev_id='rev-2a',
958
                  timestamp=1132586700, timezone=36000,
959
                  committer='Joe Foo <joe@foo.com>')
960
        wt.set_parent_ids(['rev-1', 'rev-2a'])
961
        wt.branch.set_last_revision_info(1, 'rev-1')
962
        wt.commit('rev-2', rev_id='rev-2b',
963
                  timestamp=1132586800, timezone=36000,
964
                  committer='Joe Foo <joe@foo.com>')
965
        revspec = revisionspec.RevisionSpec.from_string('1.1.1')
4857.4.3 by John Arbash Meinel
Handle LineLogFormatter
966
        rev = revspec.in_history(wt.branch)
967
        self.assertFormatterResult("""\
3947.1.2 by Ian Clatworthy
formatter tests
968
1.1.1: Joe Foo 2005-11-22 rev-merged
969
""",
4857.4.3 by John Arbash Meinel
Handle LineLogFormatter
970
            wt.branch, log.LineLogFormatter,
971
            formatter_kwargs=dict(levels=0),
972
            show_log_kwargs=dict(start_revision=rev, end_revision=rev))
3947.1.2 by Ian Clatworthy
formatter tests
973
974
    def test_line_merge_revs_log_with_merges(self):
975
        wt = self.make_branch_and_memory_tree('.')
976
        wt.lock_write()
977
        self.addCleanup(wt.unlock)
978
        wt.add('')
979
        wt.commit('rev-1', rev_id='rev-1',
980
                  timestamp=1132586655, timezone=36000,
981
                  committer='Joe Foo <joe@foo.com>')
982
        wt.commit('rev-merged', rev_id='rev-2a',
983
                  timestamp=1132586700, timezone=36000,
984
                  committer='Joe Foo <joe@foo.com>')
985
        wt.set_parent_ids(['rev-1', 'rev-2a'])
986
        wt.branch.set_last_revision_info(1, 'rev-1')
987
        wt.commit('rev-2', rev_id='rev-2b',
988
                  timestamp=1132586800, timezone=36000,
989
                  committer='Joe Foo <joe@foo.com>')
4857.4.3 by John Arbash Meinel
Handle LineLogFormatter
990
        self.assertFormatterResult("""\
3983.2.1 by Neil Martinsen-Burrell
add merge indication to the line format
991
2: Joe Foo 2005-11-22 [merge] rev-2
3947.1.2 by Ian Clatworthy
formatter tests
992
  1.1.1: Joe Foo 2005-11-22 rev-merged
993
1: Joe Foo 2005-11-22 rev-1
994
""",
4857.4.3 by John Arbash Meinel
Handle LineLogFormatter
995
            wt.branch, log.LineLogFormatter,
996
            formatter_kwargs=dict(levels=0))
997
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
998
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
999
class TestGetViewRevisions(tests.TestCaseWithTransport):
2466.11.2 by Kent Gibson
Add tests for deltas in merge revisions
1000
1756.2.22 by Aaron Bentley
Apply review comments
1001
    def make_tree_with_commits(self):
1002
        """Create a tree with well-known revision ids"""
1756.2.20 by Aaron Bentley
Optimize log formats that don't show merges
1003
        wt = self.make_branch_and_tree('tree1')
1004
        wt.commit('commit one', rev_id='1')
1005
        wt.commit('commit two', rev_id='2')
1006
        wt.commit('commit three', rev_id='3')
1007
        mainline_revs = [None, '1', '2', '3']
1756.2.22 by Aaron Bentley
Apply review comments
1008
        rev_nos = {'1': 1, '2': 2, '3': 3}
1009
        return mainline_revs, rev_nos, wt
1010
1011
    def make_tree_with_merges(self):
1012
        """Create a tree with well-known revision ids and a merge"""
1013
        mainline_revs, rev_nos, wt = self.make_tree_with_commits()
1756.2.20 by Aaron Bentley
Optimize log formats that don't show merges
1014
        tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
1015
        tree2.commit('four-a', rev_id='4a')
1979.2.1 by Robert Collins
(robertc) adds a convenience method "merge_from_branch" to WorkingTree.
1016
        wt.merge_from_branch(tree2.branch)
1756.2.20 by Aaron Bentley
Optimize log formats that don't show merges
1017
        wt.commit('four-b', rev_id='4b')
1018
        mainline_revs.append('4b')
1756.2.22 by Aaron Bentley
Apply review comments
1019
        rev_nos['4b'] = 4
1988.4.2 by Robert Collins
``bzr log`` Now shows dotted-decimal revision numbers for all revisions,
1020
        # 4a: 3.1.1
1756.2.22 by Aaron Bentley
Apply review comments
1021
        return mainline_revs, rev_nos, wt
1022
4615.1.2 by John Arbash Meinel
clarify the test a bit by using BranchBuilder.
1023
    def make_branch_with_many_merges(self):
1756.2.24 by Aaron Bentley
Forward sorting shows merges under mainline revision
1024
        """Create a tree with well-known revision ids"""
4615.1.2 by John Arbash Meinel
clarify the test a bit by using BranchBuilder.
1025
        builder = self.make_branch_builder('tree1')
1026
        builder.start_series()
1027
        builder.build_snapshot('1', None, [
1028
            ('add', ('', 'TREE_ROOT', 'directory', '')),
1029
            ('add', ('f', 'f-id', 'file', '1\n'))])
1030
        builder.build_snapshot('2', ['1'], [])
1031
        builder.build_snapshot('3a', ['2'], [
1032
            ('modify', ('f-id', '1\n2\n3a\n'))])
1033
        builder.build_snapshot('3b', ['2', '3a'], [
1034
            ('modify', ('f-id', '1\n2\n3a\n'))])
1035
        builder.build_snapshot('3c', ['2', '3b'], [
1036
            ('modify', ('f-id', '1\n2\n3a\n'))])
1037
        builder.build_snapshot('4a', ['3b'], [])
1038
        builder.build_snapshot('4b', ['3c', '4a'], [])
1039
        builder.finish_series()
1040
1041
        # 1
1042
        # |
1043
        # 2-.
1044
        # |\ \
1045
        # | | 3a
1046
        # | |/
1047
        # | 3b
1048
        # |/|
1049
        # 3c4a
1050
        # |/
1051
        # 4b
3842.2.5 by Vincent Ladeuil
Better fix for bug #300055.
1052
1756.2.24 by Aaron Bentley
Forward sorting shows merges under mainline revision
1053
        mainline_revs = [None, '1', '2', '3c', '4b']
1988.4.2 by Robert Collins
``bzr log`` Now shows dotted-decimal revision numbers for all revisions,
1054
        rev_nos = {'1':1, '2':2, '3c': 3, '4b':4}
1055
        full_rev_nos_for_reference = {
1056
            '1': '1',
1057
            '2': '2',
3170.3.4 by John Arbash Meinel
Update the tests for the new revision numbering.
1058
            '3a': '2.1.1', #first commit tree 3
1059
            '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,
1060
            '3c': '3', #merges 3b to main
3170.3.4 by John Arbash Meinel
Update the tests for the new revision numbering.
1061
            '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,
1062
            '4b': '4', # merges 4a to main
1063
            }
4615.1.2 by John Arbash Meinel
clarify the test a bit by using BranchBuilder.
1064
        return mainline_revs, rev_nos, builder.get_branch()
1756.2.24 by Aaron Bentley
Forward sorting shows merges under mainline revision
1065
1756.2.22 by Aaron Bentley
Apply review comments
1066
    def test_get_view_revisions_forward(self):
1067
        """Test the get_view_revisions method"""
1068
        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.
1069
        wt.lock_read()
1070
        self.addCleanup(wt.unlock)
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
1071
        revisions = list(log.get_view_revisions(
1072
                mainline_revs, rev_nos, wt.branch, 'forward'))
1988.4.2 by Robert Collins
``bzr log`` Now shows dotted-decimal revision numbers for all revisions,
1073
        self.assertEqual([('1', '1', 0), ('2', '2', 0), ('3', '3', 0)],
3842.2.2 by Vincent Ladeuil
Reproduce bug #300055.
1074
                         revisions)
1075
        revisions2 = list(log.get_view_revisions(
1076
                mainline_revs, rev_nos, wt.branch, 'forward',
1077
                include_merges=False))
1756.2.22 by Aaron Bentley
Apply review comments
1078
        self.assertEqual(revisions, revisions2)
1079
1080
    def test_get_view_revisions_reverse(self):
1081
        """Test the get_view_revisions with reverse"""
1082
        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.
1083
        wt.lock_read()
1084
        self.addCleanup(wt.unlock)
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
1085
        revisions = list(log.get_view_revisions(
1086
                mainline_revs, rev_nos, wt.branch, 'reverse'))
1988.4.2 by Robert Collins
``bzr log`` Now shows dotted-decimal revision numbers for all revisions,
1087
        self.assertEqual([('3', '3', 0), ('2', '2', 0), ('1', '1', 0), ],
3842.2.2 by Vincent Ladeuil
Reproduce bug #300055.
1088
                         revisions)
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
1089
        revisions2 = list(log.get_view_revisions(
1090
                mainline_revs, rev_nos, wt.branch, 'reverse',
1091
                include_merges=False))
1756.2.22 by Aaron Bentley
Apply review comments
1092
        self.assertEqual(revisions, revisions2)
1093
1094
    def test_get_view_revisions_merge(self):
1095
        """Test get_view_revisions when there are merges"""
1096
        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.
1097
        wt.lock_read()
1098
        self.addCleanup(wt.unlock)
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
1099
        revisions = list(log.get_view_revisions(
1100
                mainline_revs, rev_nos, wt.branch, 'forward'))
1988.4.2 by Robert Collins
``bzr log`` Now shows dotted-decimal revision numbers for all revisions,
1101
        self.assertEqual([('1', '1', 0), ('2', '2', 0), ('3', '3', 0),
3842.2.2 by Vincent Ladeuil
Reproduce bug #300055.
1102
                          ('4b', '4', 0), ('4a', '3.1.1', 1)],
1103
                         revisions)
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
1104
        revisions = list(log.get_view_revisions(
1105
                mainline_revs, rev_nos, wt.branch, 'forward',
1106
                include_merges=False))
1988.4.2 by Robert Collins
``bzr log`` Now shows dotted-decimal revision numbers for all revisions,
1107
        self.assertEqual([('1', '1', 0), ('2', '2', 0), ('3', '3', 0),
3842.2.2 by Vincent Ladeuil
Reproduce bug #300055.
1108
                          ('4b', '4', 0)],
1109
                         revisions)
1756.2.24 by Aaron Bentley
Forward sorting shows merges under mainline revision
1110
1111
    def test_get_view_revisions_merge_reverse(self):
1112
        """Test get_view_revisions in reverse when there are merges"""
1113
        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.
1114
        wt.lock_read()
1115
        self.addCleanup(wt.unlock)
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
1116
        revisions = list(log.get_view_revisions(
1117
                mainline_revs, rev_nos, wt.branch, 'reverse'))
1988.4.2 by Robert Collins
``bzr log`` Now shows dotted-decimal revision numbers for all revisions,
1118
        self.assertEqual([('4b', '4', 0), ('4a', '3.1.1', 1),
3842.2.2 by Vincent Ladeuil
Reproduce bug #300055.
1119
                          ('3', '3', 0), ('2', '2', 0), ('1', '1', 0)],
1120
                         revisions)
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
1121
        revisions = list(log.get_view_revisions(
1122
                mainline_revs, rev_nos, wt.branch, 'reverse',
1123
                include_merges=False))
1988.4.2 by Robert Collins
``bzr log`` Now shows dotted-decimal revision numbers for all revisions,
1124
        self.assertEqual([('4b', '4', 0), ('3', '3', 0), ('2', '2', 0),
3842.2.2 by Vincent Ladeuil
Reproduce bug #300055.
1125
                          ('1', '1', 0)],
1126
                         revisions)
1756.2.24 by Aaron Bentley
Forward sorting shows merges under mainline revision
1127
1128
    def test_get_view_revisions_merge2(self):
1129
        """Test get_view_revisions when there are merges"""
4615.1.2 by John Arbash Meinel
clarify the test a bit by using BranchBuilder.
1130
        mainline_revs, rev_nos, b = self.make_branch_with_many_merges()
1131
        b.lock_read()
1132
        self.addCleanup(b.unlock)
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
1133
        revisions = list(log.get_view_revisions(
4615.1.2 by John Arbash Meinel
clarify the test a bit by using BranchBuilder.
1134
                mainline_revs, rev_nos, b, 'forward'))
1988.4.2 by Robert Collins
``bzr log`` Now shows dotted-decimal revision numbers for all revisions,
1135
        expected = [('1', '1', 0), ('2', '2', 0), ('3c', '3', 0),
4615.1.3 by John Arbash Meinel
Since the merge depth changed, it causes log to change slightly as well.
1136
                    ('3b', '2.2.1', 1), ('3a', '2.1.1', 2), ('4b', '4', 0),
3842.2.2 by Vincent Ladeuil
Reproduce bug #300055.
1137
                    ('4a', '2.2.2', 1)]
1988.4.2 by Robert Collins
``bzr log`` Now shows dotted-decimal revision numbers for all revisions,
1138
        self.assertEqual(expected, revisions)
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
1139
        revisions = list(log.get_view_revisions(
4615.1.2 by John Arbash Meinel
clarify the test a bit by using BranchBuilder.
1140
                mainline_revs, rev_nos, b, 'forward',
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
1141
                include_merges=False))
1988.4.2 by Robert Collins
``bzr log`` Now shows dotted-decimal revision numbers for all revisions,
1142
        self.assertEqual([('1', '1', 0), ('2', '2', 0), ('3c', '3', 0),
3842.2.2 by Vincent Ladeuil
Reproduce bug #300055.
1143
                          ('4b', '4', 0)],
1144
                         revisions)
2359.1.6 by John Arbash Meinel
Create a helper tree which has a semi-interesting history.
1145
1146
3842.2.5 by Vincent Ladeuil
Better fix for bug #300055.
1147
    def test_file_id_for_range(self):
4615.1.2 by John Arbash Meinel
clarify the test a bit by using BranchBuilder.
1148
        mainline_revs, rev_nos, b = self.make_branch_with_many_merges()
1149
        b.lock_read()
1150
        self.addCleanup(b.unlock)
3842.2.5 by Vincent Ladeuil
Better fix for bug #300055.
1151
1152
        def rev_from_rev_id(revid, branch):
1153
            revspec = revisionspec.RevisionSpec.from_string('revid:%s' % revid)
1154
            return revspec.in_history(branch)
1155
1156
        def view_revs(start_rev, end_rev, file_id, direction):
1157
            revs = log.calculate_view_revisions(
4615.1.2 by John Arbash Meinel
clarify the test a bit by using BranchBuilder.
1158
                b,
3842.2.5 by Vincent Ladeuil
Better fix for bug #300055.
1159
                start_rev, # start_revision
1160
                end_rev, # end_revision
1161
                direction, # direction
1162
                file_id, # specific_fileid
1163
                True, # generate_merge_revisions
1164
                )
1165
            return revs
1166
4615.1.2 by John Arbash Meinel
clarify the test a bit by using BranchBuilder.
1167
        rev_3a = rev_from_rev_id('3a', b)
1168
        rev_4b = rev_from_rev_id('4b', b)
4615.1.3 by John Arbash Meinel
Since the merge depth changed, it causes log to change slightly as well.
1169
        self.assertEqual([('3c', '3', 0), ('3b', '2.2.1', 1), ('3a', '2.1.1', 2)],
3842.2.5 by Vincent Ladeuil
Better fix for bug #300055.
1170
                          view_revs(rev_3a, rev_4b, 'f-id', 'reverse'))
3936.3.30 by Ian Clatworthy
use iter_merge_sorted_revisions() with stop_range feature
1171
        # Note: 3c still appears before 3a here because of depth-based sorting
4615.1.3 by John Arbash Meinel
Since the merge depth changed, it causes log to change slightly as well.
1172
        self.assertEqual([('3c', '3', 0), ('3b', '2.2.1', 1), ('3a', '2.1.1', 2)],
3842.2.5 by Vincent Ladeuil
Better fix for bug #300055.
1173
                          view_revs(rev_3a, rev_4b, 'f-id', 'forward'))
1174
1175
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
1176
class TestGetRevisionsTouchingFileID(tests.TestCaseWithTransport):
2359.1.6 by John Arbash Meinel
Create a helper tree which has a semi-interesting history.
1177
1178
    def create_tree_with_single_merge(self):
1179
        """Create a branch with a moderate layout.
1180
1181
        The revision graph looks like:
1182
1183
           A
1184
           |\
1185
           B C
1186
           |/
1187
           D
1188
1189
        In this graph, A introduced files f1 and f2 and f3.
1190
        B modifies f1 and f3, and C modifies f2 and f3.
1191
        D merges the changes from B and C and resolves the conflict for f3.
1192
        """
1193
        # TODO: jam 20070218 This seems like it could really be done
1194
        #       with make_branch_and_memory_tree() if we could just
1195
        #       create the content of those files.
1196
        # TODO: jam 20070218 Another alternative is that we would really
1197
        #       like to only create this tree 1 time for all tests that
1198
        #       use it. Since 'log' only uses the tree in a readonly
1199
        #       fashion, it seems a shame to regenerate an identical
1200
        #       tree for each test.
1201
        tree = self.make_branch_and_tree('tree')
1202
        tree.lock_write()
1203
        self.addCleanup(tree.unlock)
1204
1205
        self.build_tree_contents([('tree/f1', 'A\n'),
1206
                                  ('tree/f2', 'A\n'),
1207
                                  ('tree/f3', 'A\n'),
1208
                                 ])
1209
        tree.add(['f1', 'f2', 'f3'], ['f1-id', 'f2-id', 'f3-id'])
1210
        tree.commit('A', rev_id='A')
1211
1212
        self.build_tree_contents([('tree/f2', 'A\nC\n'),
1213
                                  ('tree/f3', 'A\nC\n'),
1214
                                 ])
1215
        tree.commit('C', rev_id='C')
1216
        # Revert back to A to build the other history.
1217
        tree.set_last_revision('A')
1218
        tree.branch.set_last_revision_info(1, 'A')
1219
        self.build_tree_contents([('tree/f1', 'A\nB\n'),
1220
                                  ('tree/f2', 'A\n'),
1221
                                  ('tree/f3', 'A\nB\n'),
1222
                                 ])
1223
        tree.commit('B', rev_id='B')
1224
        tree.set_parent_ids(['B', 'C'])
1225
        self.build_tree_contents([('tree/f1', 'A\nB\n'),
1226
                                  ('tree/f2', 'A\nC\n'),
1227
                                  ('tree/f3', 'A\nB\nC\n'),
1228
                                 ])
1229
        tree.commit('D', rev_id='D')
1230
1231
        # Switch to a read lock for this tree.
3842.2.5 by Vincent Ladeuil
Better fix for bug #300055.
1232
        # 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.
1233
        tree.unlock()
1234
        tree.lock_read()
1235
        return tree
1236
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
1237
    def check_delta(self, delta, **kw):
1238
        """Check the filenames touched by a delta are as expected.
1239
1240
        Caller only have to pass in the list of files for each part, all
1241
        unspecified parts are considered empty (and checked as such).
1242
        """
1243
        for n in 'added', 'removed', 'renamed', 'modified', 'unchanged':
1244
            # By default we expect an empty list
1245
            expected = kw.get(n, [])
1246
            # strip out only the path components
1247
            got = [x[0] for x in getattr(delta, n)]
3842.2.7 by Vincent Ladeuil
Fixed as per Jonh's review.
1248
            self.assertEqual(expected, got)
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
1249
2359.1.6 by John Arbash Meinel
Create a helper tree which has a semi-interesting history.
1250
    def test_tree_with_single_merge(self):
1251
        """Make sure the tree layout is correct."""
1252
        tree = self.create_tree_with_single_merge()
1253
        rev_A_tree = tree.branch.repository.revision_tree('A')
1254
        rev_B_tree = tree.branch.repository.revision_tree('B')
1255
        rev_C_tree = tree.branch.repository.revision_tree('C')
1256
        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.
1257
1258
        self.check_delta(rev_B_tree.changes_from(rev_A_tree),
1259
                         modified=['f1', 'f3'])
1260
1261
        self.check_delta(rev_C_tree.changes_from(rev_A_tree),
1262
                         modified=['f2', 'f3'])
1263
1264
        self.check_delta(rev_D_tree.changes_from(rev_B_tree),
1265
                         modified=['f2', 'f3'])
1266
1267
        self.check_delta(rev_D_tree.changes_from(rev_C_tree),
1268
                         modified=['f1', 'f3'])
2359.1.6 by John Arbash Meinel
Create a helper tree which has a semi-interesting history.
1269
2359.1.7 by John Arbash Meinel
Create a direct test for _get_revisions_touching_file_id
1270
    def assertAllRevisionsForFileID(self, tree, file_id, revisions):
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
1271
        """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
1272
2466.12.1 by Kent Gibson
Fix ``bzr log -r`` to support selecting merge revisions.
1273
        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
1274
        sure they are correct.
1275
        """
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
1276
        # 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
1277
        # So we do the setup here.
1278
        mainline = tree.branch.revision_history()
1279
        mainline.insert(0, None)
1280
        revnos = dict((rev, idx+1) for idx, rev in enumerate(mainline))
1281
        view_revs_iter = log.get_view_revisions(mainline, revnos, tree.branch,
1282
                                                'reverse', True)
2466.12.1 by Kent Gibson
Fix ``bzr log -r`` to support selecting merge revisions.
1283
        actual_revs = log._filter_revisions_touching_file_id(
3711.3.23 by John Arbash Meinel
Documentation and cleanup.
1284
                            tree.branch,
2466.12.1 by Kent Gibson
Fix ``bzr log -r`` to support selecting merge revisions.
1285
                            file_id,
3842.2.5 by Vincent Ladeuil
Better fix for bug #300055.
1286
                            list(view_revs_iter))
2359.1.7 by John Arbash Meinel
Create a direct test for _get_revisions_touching_file_id
1287
        self.assertEqual(revisions, [r for r, revno, depth in actual_revs])
1288
1289
    def test_file_id_f1(self):
1290
        tree = self.create_tree_with_single_merge()
1291
        # f1 should be marked as modified by revisions A and B
1292
        self.assertAllRevisionsForFileID(tree, 'f1-id', ['B', 'A'])
1293
1294
    def test_file_id_f2(self):
1295
        tree = self.create_tree_with_single_merge()
1296
        # f2 should be marked as modified by revisions A, C, and D
1297
        # because D merged the changes from C.
1298
        self.assertAllRevisionsForFileID(tree, 'f2-id', ['D', 'C', 'A'])
1299
1300
    def test_file_id_f3(self):
1301
        tree = self.create_tree_with_single_merge()
1302
        # 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.
1303
        self.assertAllRevisionsForFileID(tree, 'f3-id', ['D', 'C', 'B', 'A'])
1551.17.2 by Aaron Bentley
Stop showing deltas in pull -v output
1304
3373.2.1 by John Arbash Meinel
Fix bug #209948, properly skip over ghosts when displaying the changes for a single file.
1305
    def test_file_id_with_ghosts(self):
1306
        # This is testing bug #209948, where having a ghost would cause
1307
        # _filter_revisions_touching_file_id() to fail.
1308
        tree = self.create_tree_with_single_merge()
1309
        # 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.
1310
        # (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.
1311
        tree.unlock()
1312
        tree.lock_write()
1313
        first_parent = tree.last_revision()
1314
        tree.set_parent_ids([first_parent, 'ghost-revision-id'])
1315
        self.build_tree_contents([('tree/f1', 'A\nB\nXX\n')])
1316
        tree.commit('commit with a ghost', rev_id='XX')
1317
        self.assertAllRevisionsForFileID(tree, 'f1-id', ['XX', 'B', 'A'])
1318
        self.assertAllRevisionsForFileID(tree, 'f2-id', ['D', 'C', 'A'])
1319
4183.3.1 by Vincent Ladeuil
Fix bug #346431 by allowing log._filter_revisions_touching_file_id to be
1320
    def test_unknown_file_id(self):
1321
        tree = self.create_tree_with_single_merge()
1322
        self.assertAllRevisionsForFileID(tree, 'unknown', [])
1323
1324
    def test_empty_branch_unknown_file_id(self):
1325
        tree = self.make_branch_and_tree('tree')
1326
        self.assertAllRevisionsForFileID(tree, 'unknown', [])
1327
1551.17.2 by Aaron Bentley
Stop showing deltas in pull -v output
1328
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
1329
class TestShowChangedRevisions(tests.TestCaseWithTransport):
1551.17.2 by Aaron Bentley
Stop showing deltas in pull -v output
1330
1331
    def test_show_changed_revisions_verbose(self):
1332
        tree = self.make_branch_and_tree('tree_a')
1333
        self.build_tree(['tree_a/foo'])
1334
        tree.add('foo')
1335
        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.
1336
        s = self.make_utf8_encoded_stringio()
1551.17.2 by Aaron Bentley
Stop showing deltas in pull -v output
1337
        log.show_changed_revisions(tree.branch, [], ['bar-id'], s)
1338
        self.assertContainsRe(s.getvalue(), 'bar')
1339
        self.assertNotContainsRe(s.getvalue(), 'foo')
2671.5.8 by Lukáš Lalinsky
Add tests for LogFormatter.short_committer and LogFormatter.short_author.
1340
1341
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
1342
class TestLogFormatter(tests.TestCase):
2671.5.8 by Lukáš Lalinsky
Add tests for LogFormatter.short_committer and LogFormatter.short_author.
1343
1344
    def test_short_committer(self):
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
1345
        rev = revision.Revision('a-id')
2671.5.8 by Lukáš Lalinsky
Add tests for LogFormatter.short_committer and LogFormatter.short_author.
1346
        rev.committer = 'John Doe <jdoe@example.com>'
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
1347
        lf = log.LogFormatter(None)
2671.5.8 by Lukáš Lalinsky
Add tests for LogFormatter.short_committer and LogFormatter.short_author.
1348
        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.
1349
        rev.committer = 'John Smith <jsmith@example.com>'
3063.3.3 by Lukáš Lalinský
Add one more test for config.parse_username().
1350
        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.
1351
        rev.committer = 'John Smith'
3063.3.3 by Lukáš Lalinský
Add one more test for config.parse_username().
1352
        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.
1353
        rev.committer = 'jsmith@example.com'
3063.3.3 by Lukáš Lalinský
Add one more test for config.parse_username().
1354
        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.
1355
        rev.committer = '<jsmith@example.com>'
3063.3.3 by Lukáš Lalinský
Add one more test for config.parse_username().
1356
        self.assertEqual('jsmith@example.com', lf.short_committer(rev))
1357
        rev.committer = 'John Smith jsmith@example.com'
1358
        self.assertEqual('John Smith', lf.short_committer(rev))
2671.5.8 by Lukáš Lalinsky
Add tests for LogFormatter.short_committer and LogFormatter.short_author.
1359
1360
    def test_short_author(self):
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
1361
        rev = revision.Revision('a-id')
2671.5.8 by Lukáš Lalinsky
Add tests for LogFormatter.short_committer and LogFormatter.short_author.
1362
        rev.committer = 'John Doe <jdoe@example.com>'
3842.2.1 by Vincent Ladeuil
Cosmetic changes.
1363
        lf = log.LogFormatter(None)
2671.5.8 by Lukáš Lalinsky
Add tests for LogFormatter.short_committer and LogFormatter.short_author.
1364
        self.assertEqual('John Doe', lf.short_author(rev))
1365
        rev.properties['author'] = 'John Smith <jsmith@example.com>'
1366
        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.
1367
        rev.properties['author'] = 'John Smith'
1368
        self.assertEqual('John Smith', lf.short_author(rev))
1369
        rev.properties['author'] = 'jsmith@example.com'
1370
        self.assertEqual('jsmith@example.com', lf.short_author(rev))
1371
        rev.properties['author'] = '<jsmith@example.com>'
1372
        self.assertEqual('jsmith@example.com', lf.short_author(rev))
3063.3.3 by Lukáš Lalinský
Add one more test for config.parse_username().
1373
        rev.properties['author'] = 'John Smith jsmith@example.com'
1374
        self.assertEqual('John Smith', lf.short_author(rev))
4056.2.3 by James Westby
Use a new "authors" revision property to allow multiple authors
1375
        del rev.properties['author']
1376
        rev.properties['authors'] = ('John Smith <jsmith@example.com>\n'
1377
                'Jane Rey <jrey@example.com>')
1378
        self.assertEqual('John Smith', lf.short_author(rev))
3842.2.2 by Vincent Ladeuil
Reproduce bug #300055.
1379
1380
1381
class TestReverseByDepth(tests.TestCase):
1382
    """Test reverse_by_depth behavior.
1383
1384
    This is used to present revisions in forward (oldest first) order in a nice
1385
    layout.
1386
1387
    The tests use lighter revision description to ease reading.
1388
    """
1389
1390
    def assertReversed(self, forward, backward):
1391
        # Transform the descriptions to suit the API: tests use (revno, depth),
1392
        # while the API expects (revid, revno, depth)
1393
        def complete_revisions(l):
1394
            """Transform the description to suit the API.
1395
1396
            Tests use (revno, depth) whil the API expects (revid, revno, depth).
1397
            Since the revid is arbitrary, we just duplicate revno
1398
            """
1399
            return [ (r, r, d) for r, d in l]
1400
        forward = complete_revisions(forward)
1401
        backward= complete_revisions(backward)
1402
        self.assertEqual(forward, log.reverse_by_depth(backward))
1403
1404
1405
    def test_mainline_revisions(self):
1406
        self.assertReversed([( '1', 0), ('2', 0)],
1407
                            [('2', 0), ('1', 0)])
1408
1409
    def test_merged_revisions(self):
3842.2.3 by Vincent Ladeuil
Yet more cleanup and fix test_file_id_f3 bogus test.
1410
        self.assertReversed([('1', 0), ('2', 0), ('2.2', 1), ('2.1', 1),],
1411
                            [('2', 0), ('2.1', 1), ('2.2', 1), ('1', 0),])
3842.2.2 by Vincent Ladeuil
Reproduce bug #300055.
1412
    def test_shifted_merged_revisions(self):
1413
        """Test irregular layout.
1414
1415
        Requesting revisions touching a file can produce "holes" in the depths.
1416
        """
1417
        self.assertReversed([('1', 0), ('2', 0), ('1.1', 2), ('1.2', 2),],
1418
                            [('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.
1419
1420
    def test_merged_without_child_revisions(self):
1421
        """Test irregular layout.
1422
1423
        Revision ranges can produce "holes" in the depths.
1424
        """
1425
        # When a revision of higher depth doesn't follow one of lower depth, we
1426
        # assume a lower depth one is virtually there
1427
        self.assertReversed([('1', 2), ('2', 2), ('3', 3), ('4', 4)],
1428
                            [('4', 4), ('3', 3), ('2', 2), ('1', 2),])
1429
        # So we get the same order after reversing below even if the original
1430
        # revisions are not in the same order.
1431
        self.assertReversed([('1', 2), ('2', 2), ('3', 3), ('4', 4)],
1432
                            [('3', 3), ('4', 4), ('2', 2), ('1', 2),])
3848.1.6 by Aaron Bentley
Implement get_history_change
1433
1434
3848.1.8 by Aaron Bentley
Implement basic show_branch_change
1435
class TestHistoryChange(tests.TestCaseWithTransport):
3848.1.6 by Aaron Bentley
Implement get_history_change
1436
1437
    def setup_a_tree(self):
1438
        tree = self.make_branch_and_tree('tree')
1439
        tree.lock_write()
1440
        self.addCleanup(tree.unlock)
1441
        tree.commit('1a', rev_id='1a')
1442
        tree.commit('2a', rev_id='2a')
1443
        tree.commit('3a', rev_id='3a')
1444
        return tree
1445
1446
    def setup_ab_tree(self):
1447
        tree = self.setup_a_tree()
1448
        tree.set_last_revision('1a')
1449
        tree.branch.set_last_revision_info(1, '1a')
1450
        tree.commit('2b', rev_id='2b')
1451
        tree.commit('3b', rev_id='3b')
1452
        return tree
1453
1454
    def setup_ac_tree(self):
1455
        tree = self.setup_a_tree()
1456
        tree.set_last_revision(revision.NULL_REVISION)
1457
        tree.branch.set_last_revision_info(0, revision.NULL_REVISION)
1458
        tree.commit('1c', rev_id='1c')
1459
        tree.commit('2c', rev_id='2c')
1460
        tree.commit('3c', rev_id='3c')
1461
        return tree
1462
1463
    def test_all_new(self):
1464
        tree = self.setup_ab_tree()
3848.1.7 by Aaron Bentley
Use repository in get_history_change
1465
        old, new = log.get_history_change('1a', '3a', tree.branch.repository)
3848.1.6 by Aaron Bentley
Implement get_history_change
1466
        self.assertEqual([], old)
1467
        self.assertEqual(['2a', '3a'], new)
1468
1469
    def test_all_old(self):
1470
        tree = self.setup_ab_tree()
3848.1.7 by Aaron Bentley
Use repository in get_history_change
1471
        old, new = log.get_history_change('3a', '1a', tree.branch.repository)
3848.1.6 by Aaron Bentley
Implement get_history_change
1472
        self.assertEqual([], new)
1473
        self.assertEqual(['2a', '3a'], old)
1474
1475
    def test_null_old(self):
1476
        tree = self.setup_ab_tree()
1477
        old, new = log.get_history_change(revision.NULL_REVISION,
3848.1.7 by Aaron Bentley
Use repository in get_history_change
1478
                                          '3a', tree.branch.repository)
3848.1.6 by Aaron Bentley
Implement get_history_change
1479
        self.assertEqual([], old)
1480
        self.assertEqual(['1a', '2a', '3a'], new)
1481
1482
    def test_null_new(self):
1483
        tree = self.setup_ab_tree()
3848.1.7 by Aaron Bentley
Use repository in get_history_change
1484
        old, new = log.get_history_change('3a', revision.NULL_REVISION,
1485
                                          tree.branch.repository)
3848.1.6 by Aaron Bentley
Implement get_history_change
1486
        self.assertEqual([], new)
1487
        self.assertEqual(['1a', '2a', '3a'], old)
1488
1489
    def test_diverged(self):
1490
        tree = self.setup_ab_tree()
3848.1.7 by Aaron Bentley
Use repository in get_history_change
1491
        old, new = log.get_history_change('3a', '3b', tree.branch.repository)
3848.1.6 by Aaron Bentley
Implement get_history_change
1492
        self.assertEqual(old, ['2a', '3a'])
1493
        self.assertEqual(new, ['2b', '3b'])
1494
1495
    def test_unrelated(self):
1496
        tree = self.setup_ac_tree()
3848.1.7 by Aaron Bentley
Use repository in get_history_change
1497
        old, new = log.get_history_change('3a', '3c', tree.branch.repository)
3848.1.6 by Aaron Bentley
Implement get_history_change
1498
        self.assertEqual(old, ['1a', '2a', '3a'])
1499
        self.assertEqual(new, ['1c', '2c', '3c'])
3848.1.8 by Aaron Bentley
Implement basic show_branch_change
1500
1501
    def test_show_branch_change(self):
1502
        tree = self.setup_ab_tree()
1503
        s = StringIO()
3848.1.12 by Aaron Bentley
Fix test parameter order
1504
        log.show_branch_change(tree.branch, s, 3, '3a')
3848.1.8 by Aaron Bentley
Implement basic show_branch_change
1505
        self.assertContainsRe(s.getvalue(),
1506
            '[*]{60}\nRemoved Revisions:\n(.|\n)*2a(.|\n)*3a(.|\n)*'
1507
            '[*]{60}\n\nAdded Revisions:\n(.|\n)*2b(.|\n)*3b')
1508
1509
    def test_show_branch_change_no_change(self):
1510
        tree = self.setup_ab_tree()
1511
        s = StringIO()
3848.1.12 by Aaron Bentley
Fix test parameter order
1512
        log.show_branch_change(tree.branch, s, 3, '3b')
3848.1.8 by Aaron Bentley
Implement basic show_branch_change
1513
        self.assertEqual(s.getvalue(),
1514
            'Nothing seems to have changed\n')
1515
3848.1.9 by Aaron Bentley
new/old sections are omitted as appropriate.
1516
    def test_show_branch_change_no_old(self):
1517
        tree = self.setup_ab_tree()
1518
        s = StringIO()
3848.1.12 by Aaron Bentley
Fix test parameter order
1519
        log.show_branch_change(tree.branch, s, 2, '2b')
3848.1.9 by Aaron Bentley
new/old sections are omitted as appropriate.
1520
        self.assertContainsRe(s.getvalue(), 'Added Revisions:')
1521
        self.assertNotContainsRe(s.getvalue(), 'Removed Revisions:')
1522
1523
    def test_show_branch_change_no_new(self):
1524
        tree = self.setup_ab_tree()
1525
        tree.branch.set_last_revision_info(2, '2b')
1526
        s = StringIO()
3848.1.12 by Aaron Bentley
Fix test parameter order
1527
        log.show_branch_change(tree.branch, s, 3, '3b')
3848.1.9 by Aaron Bentley
new/old sections are omitted as appropriate.
1528
        self.assertContainsRe(s.getvalue(), 'Removed Revisions:')
1529
        self.assertNotContainsRe(s.getvalue(), 'Added Revisions:')
4921.2.1 by Neil Martinsen-Burrell
include bug fixes in log output
1530
1531
1532
1533
class TestLogWithBugs(TestCaseForLogFormatter):
1534
1535
    def setUp(self):
1536
        TestCaseForLogFormatter.setUp(self)
1537
        log.properties_handler_registry.register(
1538
            'bugs_properties_handler',
1539
            log._bugs_properties_handler)
1540
4921.2.2 by Neil Martinsen-Burrell
from review comments: improve splitting, add test that handler is present, use build_tree in tests
1541
    def make_commits_with_bugs(self):
1542
        """Helper method for LogFormatter tests"""
1543
        tree = self.make_branch_and_tree(u'.')
1544
        self.build_tree(['a', 'b'])
1545
        tree.add('a')
1546
        tree.commit('simple log message', rev_id='a1',
1547
                    timestamp=1132586655.459960938, timezone=-6*3600,
1548
                    committer='Joe Foo <joe@foo.com>',
1549
                    revprops={'bugs': 'test://bug/id fixed'})
1550
        tree.add('b')
1551
        tree.commit('multiline\nlog\nmessage\n', rev_id='a2',
1552
                    timestamp=1132586842.411175966, timezone=-6*3600,
1553
                    committer='Joe Foo <joe@foo.com>',
1554
                    authors=['Joe Bar <joe@bar.com>'],
1555
                    revprops={'bugs': 'test://bug/id fixed\n'
1556
                                      'test://bug/2 fixed'})
1557
        return tree
1558
1559
4921.2.1 by Neil Martinsen-Burrell
include bug fixes in log output
1560
    def test_long_bugs(self):
4921.2.2 by Neil Martinsen-Burrell
from review comments: improve splitting, add test that handler is present, use build_tree in tests
1561
        tree = self.make_commits_with_bugs()
4921.2.1 by Neil Martinsen-Burrell
include bug fixes in log output
1562
        self.assertFormatterResult("""\
1563
------------------------------------------------------------
1564
revno: 2
1565
fixes bug(s): test://bug/id test://bug/2
1566
author: Joe Bar <joe@bar.com>
1567
committer: Joe Foo <joe@foo.com>
1568
branch nick: work
1569
timestamp: Mon 2005-11-21 09:27:22 -0600
1570
message:
1571
  multiline
1572
  log
1573
  message
1574
------------------------------------------------------------
1575
revno: 1
1576
fixes bug(s): test://bug/id
1577
committer: Joe Foo <joe@foo.com>
1578
branch nick: work
1579
timestamp: Mon 2005-11-21 09:24:15 -0600
1580
message:
1581
  simple log message
1582
""",
1583
            tree.branch, log.LongLogFormatter)
1584
1585
    def test_short_bugs(self):
4921.2.2 by Neil Martinsen-Burrell
from review comments: improve splitting, add test that handler is present, use build_tree in tests
1586
        tree = self.make_commits_with_bugs()
4921.2.1 by Neil Martinsen-Burrell
include bug fixes in log output
1587
        self.assertFormatterResult("""\
1588
    2 Joe Bar\t2005-11-21
1589
      fixes bug(s): test://bug/id test://bug/2
1590
      multiline
1591
      log
1592
      message
1593
1594
    1 Joe Foo\t2005-11-21
1595
      fixes bug(s): test://bug/id
1596
      simple log message
1597
1598
""",
1599
            tree.branch, log.ShortLogFormatter)
1600
1601
    def test_wrong_bugs_property(self):
1602
        tree = self.make_branch_and_tree(u'.')
1603
        self.build_tree(['foo'])
1604
        tree.commit('simple log message', rev_id='a1',
1605
              timestamp=1132586655.459960938, timezone=-6*3600,
1606
              committer='Joe Foo <joe@foo.com>',
1607
              revprops={'bugs': 'test://bug/id invalid_value'})
1608
        self.assertFormatterResult("""\
1609
    1 Joe Foo\t2005-11-21
1610
      simple log message
1611
1612
""",
1613
            tree.branch, log.ShortLogFormatter)
4921.2.2 by Neil Martinsen-Burrell
from review comments: improve splitting, add test that handler is present, use build_tree in tests
1614
1615
    def test_bugs_handler_present(self):
1616
        self.properties_handler_registry.get('bugs_properties_handler')