/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
1551.10.18 by Aaron Bentley
Log works in local treeless branches (#84247)
1
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
1540.2.6 by Robey Pointer
make 'log' and 'status' treat '-r N..' as implicitly '-r N..-1'
2
# -*- coding: utf-8 -*-
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
3
#
1540.2.6 by Robey Pointer
make 'log' and 'status' treat '-r N..' as implicitly '-r N..-1'
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
8
#
1540.2.6 by Robey Pointer
make 'log' and 'status' treat '-r N..' as implicitly '-r N..-1'
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
13
#
1540.2.6 by Robey Pointer
make 'log' and 'status' treat '-r N..' as implicitly '-r N..-1'
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
18
1624.1.3 by Robert Collins
Convert log to use the new tsort.merge_sort routine.
19
"""Black-box tests for bzr log."""
1540.2.6 by Robey Pointer
make 'log' and 'status' treat '-r N..' as implicitly '-r N..-1'
20
1624.1.3 by Robert Collins
Convert log to use the new tsort.merge_sort routine.
21
import os
1540.2.6 by Robey Pointer
make 'log' and 'status' treat '-r N..' as implicitly '-r N..-1'
22
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
23
import bzrlib
1540.2.6 by Robey Pointer
make 'log' and 'status' treat '-r N..' as implicitly '-r N..-1'
24
from bzrlib.tests.blackbox import ExternalBase
1551.10.18 by Aaron Bentley
Log works in local treeless branches (#84247)
25
from bzrlib.tests import TestCaseInTempDir, TestCaseWithTransport
1540.2.6 by Robey Pointer
make 'log' and 'status' treat '-r N..' as implicitly '-r N..-1'
26
27
28
class TestLog(ExternalBase):
29
2388.1.3 by Erik Bagfors
tests for tags in log output
30
    def _prepare(self, format=None):
31
        if format:
32
            self.runbzr("init --format="+format)
33
        else:
34
            self.runbzr("init")
1553.4.2 by Michael Ellerman
Make bzr log -r .. work, fixes bug #4609. Add a bunch of tests to make sure
35
        self.build_tree(['hello.txt', 'goodbye.txt', 'meep.txt'])
1540.2.6 by Robey Pointer
make 'log' and 'status' treat '-r N..' as implicitly '-r N..-1'
36
        self.runbzr("add hello.txt")
1553.4.2 by Michael Ellerman
Make bzr log -r .. work, fixes bug #4609. Add a bunch of tests to make sure
37
        self.runbzr("commit -m message1 hello.txt")
38
        self.runbzr("add goodbye.txt")
39
        self.runbzr("commit -m message2 goodbye.txt")
40
        self.runbzr("add meep.txt")
41
        self.runbzr("commit -m message3 meep.txt")
42
        self.full_log = self.runbzr("log")[0]
43
44
    def test_log_null_end_revspec(self):
45
        self._prepare()
46
        self.assertTrue('revno: 1\n' in self.full_log)
47
        self.assertTrue('revno: 2\n' in self.full_log)
48
        self.assertTrue('revno: 3\n' in self.full_log)
49
        self.assertTrue('message:\n  message1\n' in self.full_log)
50
        self.assertTrue('message:\n  message2\n' in self.full_log)
51
        self.assertTrue('message:\n  message3\n' in self.full_log)
52
53
        log = self.runbzr("log -r 1..")[0]
54
        self.assertEquals(log, self.full_log)
55
56
    def test_log_null_begin_revspec(self):
57
        self._prepare()
58
        log = self.runbzr("log -r ..3")[0]
59
        self.assertEquals(self.full_log, log)
60
61
    def test_log_null_both_revspecs(self):
62
        self._prepare()
63
        log = self.runbzr("log -r ..")[0]
64
        self.assertEquals(self.full_log, log)
65
66
    def test_log_negative_begin_revspec_full_log(self):
67
        self._prepare()
68
        log = self.runbzr("log -r -3..")[0]
69
        self.assertEquals(self.full_log, log)
70
71
    def test_log_negative_both_revspec_full_log(self):
72
        self._prepare()
73
        log = self.runbzr("log -r -3..-1")[0]
74
        self.assertEquals(self.full_log, log)
75
76
    def test_log_negative_both_revspec_partial(self):
77
        self._prepare()
78
        log = self.runbzr("log -r -3..-2")[0]
79
        self.assertTrue('revno: 1\n' in log)
80
        self.assertTrue('revno: 2\n' in log)
81
        self.assertTrue('revno: 3\n' not in log)
82
83
    def test_log_negative_begin_revspec(self):
84
        self._prepare()
85
        log = self.runbzr("log -r -2..")[0]
86
        self.assertTrue('revno: 1\n' not in log)
87
        self.assertTrue('revno: 2\n' in log)
88
        self.assertTrue('revno: 3\n' in log)
89
90
    def test_log_postive_revspecs(self):
91
        self._prepare()
92
        log = self.runbzr("log -r 1..3")[0]
93
        self.assertEquals(self.full_log, log)
1624.1.3 by Robert Collins
Convert log to use the new tsort.merge_sort routine.
94
1907.4.2 by Matthieu Moy
Make log work nicely with revno:N:path too.
95
    def test_log_revno_n_path(self):
96
        os.mkdir('branch1')
97
        os.chdir('branch1')
98
        self._prepare()
99
        os.chdir('..')
100
        os.mkdir('branch2')
101
        os.chdir('branch2')
102
        self._prepare()
103
        os.chdir('..')
104
        log = self.runbzr("log -r revno:2:branch1..revno:3:branch2",
105
                          retcode=3)[0]
106
        log = self.runbzr("log -r revno:1:branch2..revno:3:branch2")[0]
107
        self.assertEquals(self.full_log, log)
108
        log = self.runbzr("log -r revno:1:branch2")[0]
109
        self.assertTrue('revno: 1\n' in log)
110
        self.assertTrue('revno: 2\n' not in log)
111
        self.assertTrue('branch nick: branch2\n' in log)
112
        self.assertTrue('branch nick: branch1\n' not in log)
113
        
2100.1.1 by wang
Running ``bzr log`` on nonexistent file gives an error instead of the
114
    def test_log_nonexistent_file(self):
115
        # files that don't exist in either the basis tree or working tree
116
        # should give an error
117
        wt = self.make_branch_and_tree('.')
118
        out, err = self.run_bzr('log', 'does-not-exist', retcode=3)
119
        self.assertContainsRe(
120
            err, 'Path does not have any revision history: does-not-exist')
2388.1.11 by Alexander Belchenko
changes after John's review
121
2388.1.3 by Erik Bagfors
tests for tags in log output
122
    def test_log_with_tags(self):
123
        self._prepare(format='dirstate-tags')
124
        self.runbzr('tag -r1 tag1')
125
        self.runbzr('tag -r1 tag1.1')
126
        self.runbzr('tag tag3')
127
        
128
        log = self.runbzr("log -r-1")[0]
129
        self.assertTrue('tags: tag3' in log)
130
131
        log = self.runbzr("log -r1")[0]
132
        # I guess that we can't know the order of tags in the output
133
        # since dicts are unordered, need to check both possibilities
2388.1.11 by Alexander Belchenko
changes after John's review
134
        self.assertContainsRe(log, r'tags: (tag1, tag1\.1|tag1\.1, tag1)')
135
2388.1.9 by Erik Bagfors
test for merges with tags in log
136
    def test_merged_log_with_tags(self):
137
        os.mkdir('branch1')
138
        os.chdir('branch1')
139
        self._prepare(format='dirstate-tags')
140
        os.chdir('..')
2388.1.11 by Alexander Belchenko
changes after John's review
141
        self.runbzr('branch branch1 branch2')
2388.1.9 by Erik Bagfors
test for merges with tags in log
142
        os.chdir('branch1')
2388.1.11 by Alexander Belchenko
changes after John's review
143
        self.runbzr('commit -m foobar --unchanged')
2388.1.9 by Erik Bagfors
test for merges with tags in log
144
        self.runbzr('tag tag1')
145
        os.chdir('../branch2')
2388.1.11 by Alexander Belchenko
changes after John's review
146
        self.runbzr('merge ../branch1')
147
        self.runbzr('commit -m merge_branch_1')
2388.1.9 by Erik Bagfors
test for merges with tags in log
148
        log = self.runbzr("log -r-1")[0]
2388.1.11 by Alexander Belchenko
changes after John's review
149
        self.assertContainsRe(log, r'    tags: tag1')
2388.1.3 by Erik Bagfors
tests for tags in log output
150
2466.9.1 by Kent Gibson
add bzr log --limit
151
    def test_log_limit(self):
152
        self._prepare()
153
        log = self.runbzr("log --limit 2")[0]
154
        self.assertTrue('revno: 1\n' not in log)
155
        self.assertTrue('revno: 2\n' in log)
156
        self.assertTrue('revno: 3\n' in log)
157
1624.1.3 by Robert Collins
Convert log to use the new tsort.merge_sort routine.
158
159
class TestLogMerges(ExternalBase):
160
161
    def test_merges_are_indented_by_level(self):
162
        self.build_tree(['parent/'])
163
        self.run_bzr('init', 'parent')
164
        self.run_bzr('commit', '-m', 'first post', '--unchanged', 'parent')
165
        self.run_bzr('branch', 'parent', 'child')
166
        self.run_bzr('commit', '-m', 'branch 1', '--unchanged', 'child')
167
        self.run_bzr('branch', 'child', 'smallerchild')
168
        self.run_bzr('commit', '-m', 'branch 2', '--unchanged', 'smallerchild')
169
        os.chdir('child')
170
        self.run_bzr('merge', '../smallerchild')
171
        self.run_bzr('commit', '-m', 'merge branch 2')
172
        os.chdir('../parent')
173
        self.run_bzr('merge', '../child')
174
        self.run_bzr('commit', '-m', 'merge branch 1')
175
        out,err = self.run_bzr('log')
176
        # the log will look something like:
177
#        self.assertEqual("""\
178
#------------------------------------------------------------
179
#revno: 2
180
#committer: Robert Collins <foo@example.com>
181
#branch nick: parent
182
#timestamp: Tue 2006-03-28 22:31:40 +1100
183
#message:
184
#  merge branch 1
185
#    ------------------------------------------------------------
1988.4.2 by Robert Collins
``bzr log`` Now shows dotted-decimal revision numbers for all revisions,
186
#    revno: 1.1.2  
1624.1.3 by Robert Collins
Convert log to use the new tsort.merge_sort routine.
187
#    merged: foo@example.com-20060328113140-91f43cfb46dc2863
188
#    committer: Robert Collins <foo@example.com>
189
#    branch nick: child
190
#    timestamp: Tue 2006-03-28 22:31:40 +1100
191
#    message:
192
#      merge branch 2
193
#        ------------------------------------------------------------
1988.4.2 by Robert Collins
``bzr log`` Now shows dotted-decimal revision numbers for all revisions,
194
#        revno: 1.1.1.1
1624.1.3 by Robert Collins
Convert log to use the new tsort.merge_sort routine.
195
#        merged: foo@example.com-20060328113140-1ba24f850a0ef573
196
#        committer: Robert Collins <foo@example.com>
197
#        branch nick: smallerchild
198
#        timestamp: Tue 2006-03-28 22:31:40 +1100
199
#        message:
200
#          branch 2
201
#    ------------------------------------------------------------
1988.4.2 by Robert Collins
``bzr log`` Now shows dotted-decimal revision numbers for all revisions,
202
#    revno: 1.1.1
1624.1.3 by Robert Collins
Convert log to use the new tsort.merge_sort routine.
203
#    merged: foo@example.com-20060328113140-5749a4757a8ac792
204
#    committer: Robert Collins <foo@example.com>
205
#    branch nick: child
206
#    timestamp: Tue 2006-03-28 22:31:40 +1100
207
#    message:
208
#      branch 1
209
#------------------------------------------------------------
210
#revno: 1
211
#committer: Robert Collins <foo@example.com>
212
#branch nick: parent
213
#timestamp: Tue 2006-03-28 22:31:39 +1100
214
#message:
215
#  first post
216
#""", out)
217
        # but we dont have a nice pattern matcher hooked up yet, so:
1988.4.2 by Robert Collins
``bzr log`` Now shows dotted-decimal revision numbers for all revisions,
218
        # we check for the indenting of the commit message and the 
219
        # revision numbers 
220
        self.assertTrue('revno: 2' in out)
1624.1.3 by Robert Collins
Convert log to use the new tsort.merge_sort routine.
221
        self.assertTrue('  merge branch 1' in out)
1988.4.2 by Robert Collins
``bzr log`` Now shows dotted-decimal revision numbers for all revisions,
222
        self.assertTrue('    revno: 1.1.2' in out)
1624.1.3 by Robert Collins
Convert log to use the new tsort.merge_sort routine.
223
        self.assertTrue('      merge branch 2' in out)
1988.4.2 by Robert Collins
``bzr log`` Now shows dotted-decimal revision numbers for all revisions,
224
        self.assertTrue('        revno: 1.1.1.1' in out)
1624.1.3 by Robert Collins
Convert log to use the new tsort.merge_sort routine.
225
        self.assertTrue('          branch 2' in out)
1988.4.2 by Robert Collins
``bzr log`` Now shows dotted-decimal revision numbers for all revisions,
226
        self.assertTrue('    revno: 1.1.1' in out)
1624.1.3 by Robert Collins
Convert log to use the new tsort.merge_sort routine.
227
        self.assertTrue('      branch 1' in out)
1988.4.2 by Robert Collins
``bzr log`` Now shows dotted-decimal revision numbers for all revisions,
228
        self.assertTrue('revno: 1' in out)
1624.1.3 by Robert Collins
Convert log to use the new tsort.merge_sort routine.
229
        self.assertTrue('  first post' in out)
230
        self.assertEqual('', err)
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
231
232
233
class TestLogEncodings(TestCaseInTempDir):
234
235
    _mu = u'\xb5'
236
    _message = u'Message with \xb5'
237
238
    # Encodings which can encode mu
239
    good_encodings = [
240
        'utf-8',
241
        'latin-1',
242
        'iso-8859-1',
243
        'cp437', # Common windows encoding
244
        'cp1251', # Alexander Belchenko's windows encoding
245
        'cp1258', # Common windows encoding
246
    ]
247
    # Encodings which cannot encode mu
248
    bad_encodings = [
249
        'ascii',
250
        'iso-8859-2',
251
        'koi8_r',
252
    ]
253
254
    def setUp(self):
255
        TestCaseInTempDir.setUp(self)
256
        self.user_encoding = bzrlib.user_encoding
257
258
    def tearDown(self):
259
        bzrlib.user_encoding = self.user_encoding
260
        TestCaseInTempDir.tearDown(self)
261
262
    def create_branch(self):
263
        bzr = self.run_bzr
264
        bzr('init')
265
        open('a', 'wb').write('some stuff\n')
266
        bzr('add', 'a')
267
        bzr('commit', '-m', self._message)
268
269
    def try_encoding(self, encoding, fail=False):
270
        bzr = self.run_bzr
271
        if fail:
272
            self.assertRaises(UnicodeEncodeError,
273
                self._mu.encode, encoding)
274
            encoded_msg = self._message.encode(encoding, 'replace')
275
        else:
276
            encoded_msg = self._message.encode(encoding)
277
278
        old_encoding = bzrlib.user_encoding
279
        # This test requires that 'run_bzr' uses the current
280
        # bzrlib, because we override user_encoding, and expect
281
        # it to be used
282
        try:
283
            bzrlib.user_encoding = 'ascii'
284
            # We should be able to handle any encoding
285
            out, err = bzr('log', encoding=encoding)
286
            if not fail:
287
                # Make sure we wrote mu as we expected it to exist
288
                self.assertNotEqual(-1, out.find(encoded_msg))
289
                out_unicode = out.decode(encoding)
290
                self.assertNotEqual(-1, out_unicode.find(self._message))
291
            else:
292
                self.assertNotEqual(-1, out.find('Message with ?'))
293
        finally:
294
            bzrlib.user_encoding = old_encoding
295
296
    def test_log_handles_encoding(self):
297
        self.create_branch()
298
299
        for encoding in self.good_encodings:
300
            self.try_encoding(encoding)
301
302
    def test_log_handles_bad_encoding(self):
303
        self.create_branch()
304
305
        for encoding in self.bad_encodings:
306
            self.try_encoding(encoding, fail=True)
307
308
    def test_stdout_encoding(self):
309
        bzr = self.run_bzr
310
        bzrlib.user_encoding = "cp1251"
311
312
        bzr('init')
313
        self.build_tree(['a'])
314
        bzr('add', 'a')
315
        bzr('commit', '-m', u'\u0422\u0435\u0441\u0442')
316
        stdout, stderr = self.run_bzr('log', encoding='cp866')
317
318
        message = stdout.splitlines()[-1]
319
320
        # explanation of the check:
321
        # u'\u0422\u0435\u0441\u0442' is word 'Test' in russian
322
        # in cp866  encoding this is string '\x92\xa5\xe1\xe2'
323
        # in cp1251 encoding this is string '\xd2\xe5\xf1\xf2'
324
        # This test should check that output of log command
325
        # encoded to sys.stdout.encoding
326
        test_in_cp866 = '\x92\xa5\xe1\xe2'
327
        test_in_cp1251 = '\xd2\xe5\xf1\xf2'
328
        # Make sure the log string is encoded in cp866
329
        self.assertEquals(test_in_cp866, message[2:])
330
        # Make sure the cp1251 string is not found anywhere
331
        self.assertEquals(-1, stdout.find(test_in_cp1251))
332
1551.10.18 by Aaron Bentley
Log works in local treeless branches (#84247)
333
334
class TestLogFile(TestCaseWithTransport):
335
336
    def test_log_local_branch_file(self):
337
        """We should be able to log files in local treeless branches"""
338
        tree = self.make_branch_and_tree('tree')
339
        self.build_tree(['tree/file'])
340
        tree.add('file')
341
        tree.commit('revision 1')
342
        tree.bzrdir.destroy_workingtree()
343
        self.run_bzr('log', 'tree/file')
2359.1.1 by Kent Gibson
Fix ``bzr log <file>`` so it only logs the revisions that changed the file, and does it faster.
344
345
    def test_log_file(self):
346
        """The log for a particular file should only list revs for that file"""
347
        tree = self.make_branch_and_tree('parent')
348
        self.build_tree(['parent/file1', 'parent/file2', 'parent/file3'])
349
        tree.add('file1')
350
        tree.commit('add file1')
351
        tree.add('file2')
352
        tree.commit('add file2')
353
        tree.add('file3')
354
        tree.commit('add file3')
355
        self.run_bzr('branch', 'parent', 'child')
356
        print >> file('child/file2', 'wb'), 'hello'
357
        self.run_bzr('commit', '-m', 'branch 1', 'child')
358
        os.chdir('parent')
359
        self.run_bzr('merge', '../child')
2359.1.2 by Kent Gibson
add logging of merge revisions
360
        self.run_bzr('commit', '-m', 'merge child branch')
2359.1.1 by Kent Gibson
Fix ``bzr log <file>`` so it only logs the revisions that changed the file, and does it faster.
361
        
362
        log = self.run_bzr('log', 'file1')[0]
363
        self.assertContainsRe(log, 'revno: 1\n')
364
        self.assertNotContainsRe(log, 'revno: 2\n')
365
        self.assertNotContainsRe(log, 'revno: 3\n')
366
        self.assertNotContainsRe(log, 'revno: 3.1.1\n')
367
        self.assertNotContainsRe(log, 'revno: 4\n')
368
        log = self.run_bzr('log', 'file2')[0]
369
        self.assertNotContainsRe(log, 'revno: 1\n')
370
        self.assertContainsRe(log, 'revno: 2\n')
371
        self.assertNotContainsRe(log, 'revno: 3\n')
372
        self.assertContainsRe(log, 'revno: 3.1.1\n')
2359.1.2 by Kent Gibson
add logging of merge revisions
373
        self.assertContainsRe(log, 'revno: 4\n')
2359.1.1 by Kent Gibson
Fix ``bzr log <file>`` so it only logs the revisions that changed the file, and does it faster.
374
        log = self.run_bzr('log', 'file3')[0]
375
        self.assertNotContainsRe(log, 'revno: 1\n')
376
        self.assertNotContainsRe(log, 'revno: 2\n')
377
        self.assertContainsRe(log, 'revno: 3\n')
378
        self.assertNotContainsRe(log, 'revno: 3.1.1\n')
379
        self.assertNotContainsRe(log, 'revno: 4\n')