~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

  • Committer: Vincent Ladeuil
  • Date: 2010-08-28 15:34:24 UTC
  • mto: (5398.1.1 trunk)
  • mto: This revision was merged to the branch mainline in revision 5399.
  • Revision ID: v.ladeuil+lp@free.fr-20100828153424-yybmcql9o0t43m7a
Fix bug #625686 by removing the warning filter added by selftest.

* bzrlib/symbol_versioning.py:
(suppress_deprecation_warnings, activate_deprecation_warnings):
Always return a cleanup callable even if no filter is installed.

* bzrlib/versionedfile.py:
Drive-by cleanup, the module is not needed.

* bzrlib/builtins.py:
(cmd_selftest.run): Ensure we restore the right warning filters.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
 
1
# Copyright (C) 2006-2010 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
18
18
"""Tests for the commit CLI of bzr."""
19
19
 
20
20
import os
 
21
import re
21
22
import sys
22
23
 
23
24
from bzrlib import (
 
25
    bzrdir,
24
26
    osutils,
25
27
    ignores,
26
28
    msgeditor,
27
29
    osutils,
 
30
    tests,
28
31
    )
29
32
from bzrlib.bzrdir import BzrDir
30
33
from bzrlib.tests import (
31
34
    probe_bad_non_ascii,
32
35
    TestSkipped,
33
36
    )
34
 
from bzrlib.tests.blackbox import ExternalBase
35
 
 
36
 
 
37
 
class TestCommit(ExternalBase):
 
37
from bzrlib.tests import TestCaseWithTransport
 
38
 
 
39
 
 
40
class TestCommit(TestCaseWithTransport):
38
41
 
39
42
    def test_05_empty_commit(self):
40
43
        """Commit of tree with no versioned files should fail"""
43
46
        self.build_tree(['hello.txt'])
44
47
        out,err = self.run_bzr('commit -m empty', retcode=3)
45
48
        self.assertEqual('', out)
46
 
        self.assertContainsRe(err, 'bzr: ERROR: no changes to commit\.'
47
 
                                  ' use --unchanged to commit anyhow\n')
 
49
        self.assertContainsRe(err, 'bzr: ERROR: No changes to commit\.'
 
50
                                  ' Use --unchanged to commit anyhow.\n')
48
51
 
49
52
    def test_commit_success(self):
50
53
        """Successful commit should not leave behind a bzr-commit-* file"""
106
109
                              'modified hello\.txt\n'
107
110
                              'Committed revision 2\.\n$')
108
111
 
 
112
    def test_unicode_commit_message_is_filename(self):
 
113
        """Unicode commit message same as a filename (Bug #563646).
 
114
        """
 
115
        file_name = u'\N{euro sign}'
 
116
        self.run_bzr(['init'])
 
117
        open(file_name, 'w').write('hello world')
 
118
        self.run_bzr(['add'])
 
119
        out, err = self.run_bzr(['commit', '-m', file_name])
 
120
        reflags = re.MULTILINE|re.DOTALL|re.UNICODE
 
121
        te = osutils.get_terminal_encoding()
 
122
        self.assertContainsRe(err.decode(te),
 
123
            u'The commit message is a file name:',
 
124
            flags=reflags)
 
125
 
 
126
        # Run same test with a filename that causes encode
 
127
        # error for the terminal encoding. We do this
 
128
        # by forcing terminal encoding of ascii for
 
129
        # osutils.get_terminal_encoding which is used
 
130
        # by ui.text.show_warning
 
131
        default_get_terminal_enc = osutils.get_terminal_encoding
 
132
        try:
 
133
            osutils.get_terminal_encoding = lambda trace=None: 'ascii'
 
134
            file_name = u'foo\u1234'
 
135
            open(file_name, 'w').write('hello world')
 
136
            self.run_bzr(['add'])
 
137
            out, err = self.run_bzr(['commit', '-m', file_name])
 
138
            reflags = re.MULTILINE|re.DOTALL|re.UNICODE
 
139
            te = osutils.get_terminal_encoding()
 
140
            self.assertContainsRe(err.decode(te, 'replace'),
 
141
                u'The commit message is a file name:',
 
142
                flags=reflags)
 
143
        finally:
 
144
            osutils.get_terminal_encoding = default_get_terminal_enc
 
145
 
 
146
    def test_warn_about_forgotten_commit_message(self):
 
147
        """Test that the lack of -m parameter is caught"""
 
148
        wt = self.make_branch_and_tree('.')
 
149
        self.build_tree(['one', 'two'])
 
150
        wt.add(['two'])
 
151
        out, err = self.run_bzr('commit -m one two')
 
152
        self.assertContainsRe(err, "The commit message is a file name")
 
153
 
109
154
    def test_verbose_commit_renamed(self):
110
155
        # Verbose commit of renamed file should say so
111
156
        wt = self.prepare_simple_history()
124
169
        wt.rename_one('hello.txt', 'subdir/hello.txt')
125
170
        out, err = self.run_bzr('commit -m renamed')
126
171
        self.assertEqual('', out)
127
 
        self.assertContainsRe(err, '^Committing to: .*\n'
128
 
                              'added subdir\n'
129
 
                              'renamed hello\.txt => subdir/hello\.txt\n'
130
 
                              'Committed revision 2\.\n$')
 
172
        self.assertEqual(set([
 
173
            'Committing to: %s/' % osutils.getcwd(),
 
174
            'added subdir',
 
175
            'renamed hello.txt => subdir/hello.txt',
 
176
            'Committed revision 2.',
 
177
            '',
 
178
            ]), set(err.split('\n')))
131
179
 
132
180
    def test_verbose_commit_with_unknown(self):
133
181
        """Unknown files should not be listed by default in verbose output"""
167
215
        self.assertEqual(err, 'Committing to: %s\n'
168
216
                         'Committed revision 2.\n' % expected)
169
217
 
 
218
    def test_commit_sanitizes_CR_in_message(self):
 
219
        # See bug #433779, basically Emacs likes to pass '\r\n' style line
 
220
        # endings to 'bzr commit -m ""' which breaks because we don't allow
 
221
        # '\r' in commit messages. (Mostly because of issues where XML style
 
222
        # formats arbitrarily strip it out of the data while parsing.)
 
223
        # To make life easier for users, we just always translate '\r\n' =>
 
224
        # '\n'. And '\r' => '\n'.
 
225
        a_tree = self.make_branch_and_tree('a')
 
226
        self.build_tree(['a/b'])
 
227
        a_tree.add('b')
 
228
        self.run_bzr(['commit',
 
229
                      '-m', 'a string\r\n\r\nwith mixed\r\rendings\n'],
 
230
                     working_dir='a')
 
231
        rev_id = a_tree.branch.last_revision()
 
232
        rev = a_tree.branch.repository.get_revision(rev_id)
 
233
        self.assertEqualDiff('a string\n\nwith mixed\n\nendings\n',
 
234
                             rev.message)
 
235
 
170
236
    def test_commit_merge_reports_all_modified_files(self):
171
237
        # the commit command should show all the files that are shown by
172
238
        # bzr diff or bzr status when committing, even when they were not
220
286
        os.chdir('this')
221
287
        out,err = self.run_bzr('commit -m added')
222
288
        self.assertEqual('', out)
223
 
        expected = '%s/' % (osutils.getcwd(), )
224
 
        self.assertEqualDiff(
225
 
            'Committing to: %s\n'
226
 
            'modified filetomodify\n'
227
 
            'added newdir\n'
228
 
            'added newfile\n'
229
 
            'renamed dirtorename => renameddir\n'
230
 
            'renamed filetorename => renamedfile\n'
231
 
            'renamed dirtoreparent => renameddir/reparenteddir\n'
232
 
            'renamed filetoreparent => renameddir/reparentedfile\n'
233
 
            'deleted dirtoremove\n'
234
 
            'deleted filetoremove\n'
235
 
            'Committed revision 2.\n' % (expected, ),
236
 
            err)
 
289
        self.assertEqual(set([
 
290
            'Committing to: %s/' % osutils.getcwd(),
 
291
            'modified filetomodify',
 
292
            'added newdir',
 
293
            'added newfile',
 
294
            'renamed dirtorename => renameddir',
 
295
            'renamed filetorename => renamedfile',
 
296
            'renamed dirtoreparent => renameddir/reparenteddir',
 
297
            'renamed filetoreparent => renameddir/reparentedfile',
 
298
            'deleted dirtoremove',
 
299
            'deleted filetoremove',
 
300
            'Committed revision 2.',
 
301
            ''
 
302
            ]), set(err.split('\n')))
237
303
 
238
304
    def test_empty_commit_message(self):
239
305
        tree = self.make_branch_and_tree('.')
242
308
        self.run_bzr('commit -m ""', retcode=3)
243
309
 
244
310
    def test_unsupported_encoding_commit_message(self):
 
311
        if sys.platform == 'win32':
 
312
            raise tests.TestNotApplicable('Win32 parses arguments directly'
 
313
                ' as Unicode, so we can\'t pass invalid non-ascii')
245
314
        tree = self.make_branch_and_tree('.')
246
315
        self.build_tree_contents([('foo.c', 'int main() {}')])
247
316
        tree.add('foo.c')
266
335
        self.build_tree_contents([
267
336
            ('branch/foo.c', 'int main() {}'),
268
337
            ('branch/bar.c', 'int main() {}')])
269
 
        inner_tree.add('foo.c')
270
 
        inner_tree.add('bar.c')
 
338
        inner_tree.add(['foo.c', 'bar.c'])
271
339
        # can't commit files in different trees; sane error
272
340
        self.run_bzr('commit -m newstuff branch/foo.c .', retcode=3)
 
341
        # can commit to branch - records foo.c only
273
342
        self.run_bzr('commit -m newstuff branch/foo.c')
 
343
        # can commit to branch - records bar.c
274
344
        self.run_bzr('commit -m newstuff branch')
275
 
        self.run_bzr('commit -m newstuff branch', retcode=3)
 
345
        # No changes left
 
346
        self.run_bzr_error(["No changes to commit"], 'commit -m newstuff branch')
276
347
 
277
348
    def test_out_of_date_tree_commit(self):
278
349
        # check we get an error code and a clear message committing with an out
308
379
        trunk = self.make_branch_and_tree('trunk')
309
380
 
310
381
        u1 = trunk.branch.create_checkout('u1')
311
 
        self.build_tree_contents([('u1/hosts', 'initial contents')])
 
382
        self.build_tree_contents([('u1/hosts', 'initial contents\n')])
312
383
        u1.add('hosts')
313
384
        self.run_bzr('commit -m add-hosts u1')
314
385
 
315
386
        u2 = trunk.branch.create_checkout('u2')
316
 
        self.build_tree_contents([('u2/hosts', 'altered in u2')])
 
387
        self.build_tree_contents([('u2/hosts', 'altered in u2\n')])
317
388
        self.run_bzr('commit -m checkin-from-u2 u2')
318
389
 
319
390
        # make an offline commits
320
 
        self.build_tree_contents([('u1/hosts', 'first offline change in u1')])
 
391
        self.build_tree_contents([('u1/hosts', 'first offline change in u1\n')])
321
392
        self.run_bzr('commit -m checkin-offline --local u1')
322
393
 
323
394
        # now try to pull in online work from u2, and then commit our offline
324
395
        # work as a merge
325
396
        # retcode 1 as we expect a text conflict
326
397
        self.run_bzr('update u1', retcode=1)
 
398
        self.assertFileEqual('''\
 
399
<<<<<<< TREE
 
400
first offline change in u1
 
401
=======
 
402
altered in u2
 
403
>>>>>>> MERGE-SOURCE
 
404
''',
 
405
                             'u1/hosts')
 
406
 
327
407
        self.run_bzr('resolved u1/hosts')
328
408
        # add a text change here to represent resolving the merge conflicts in
329
409
        # favour of a new version of the file not identical to either the u1
392
472
 
393
473
        # With no changes, it should just be 'no changes'
394
474
        # Make sure that commit is failing because there is nothing to do
395
 
        self.run_bzr_error(['no changes to commit'],
 
475
        self.run_bzr_error(['No changes to commit'],
396
476
                           'commit --strict -m no-changes',
397
477
                           working_dir='tree')
398
478
 
581
661
        properties = last_rev.properties
582
662
        self.assertEqual('John Doe\nJane Rey', properties['authors'])
583
663
 
 
664
    def test_commit_time(self):
 
665
        tree = self.make_branch_and_tree('tree')
 
666
        self.build_tree(['tree/hello.txt'])
 
667
        tree.add('hello.txt')
 
668
        out, err = self.run_bzr("commit -m hello "
 
669
            "--commit-time='2009-10-10 08:00:00 +0100' tree/hello.txt")
 
670
        last_rev = tree.branch.repository.get_revision(tree.last_revision())
 
671
        self.assertEqual(
 
672
            'Sat 2009-10-10 08:00:00 +0100',
 
673
            osutils.format_date(last_rev.timestamp, last_rev.timezone))
 
674
        
 
675
    def test_commit_time_bad_time(self):
 
676
        tree = self.make_branch_and_tree('tree')
 
677
        self.build_tree(['tree/hello.txt'])
 
678
        tree.add('hello.txt')
 
679
        out, err = self.run_bzr("commit -m hello "
 
680
            "--commit-time='NOT A TIME' tree/hello.txt", retcode=3)
 
681
        self.assertStartsWith(
 
682
            err, "bzr: ERROR: Could not parse --commit-time:")
 
683
 
584
684
    def test_partial_commit_with_renames_in_tree(self):
585
685
        # this test illustrates bug #140419
586
686
        t = self.make_branch_and_tree('.')
599
699
        self.assertContainsRe(err, r'modified test\nCommitted revision 2.')
600
700
 
601
701
    def test_commit_readonly_checkout(self):
602
 
        # https://bugs.edge.launchpad.net/bzr/+bug/129701
 
702
        # https://bugs.launchpad.net/bzr/+bug/129701
603
703
        # "UnlockableTransport error trying to commit in checkout of readonly
604
704
        # branch"
605
705
        self.make_branch('master')
611
711
        self.assertContainsRe(err,
612
712
            r'^bzr: ERROR: Cannot lock.*readonly transport')
613
713
 
614
 
    def test_commit_hook_template(self):
 
714
    def setup_editor(self):
615
715
        # Test that commit template hooks work
616
 
        def restoreDefaults():
617
 
            msgeditor.hooks['commit_message_template'] = []
618
 
            osutils.set_or_unset_env('BZR_EDITOR', default_editor)
619
716
        if sys.platform == "win32":
620
717
            f = file('fed.bat', 'w')
621
718
            f.write('@rem dummy fed')
622
719
            f.close()
623
 
            default_editor = osutils.set_or_unset_env('BZR_EDITOR', "fed.bat")
 
720
            osutils.set_or_unset_env('BZR_EDITOR', "fed.bat")
624
721
        else:
625
722
            f = file('fed.sh', 'wb')
626
723
            f.write('#!/bin/sh\n')
627
724
            f.close()
628
725
            os.chmod('fed.sh', 0755)
629
 
            default_editor = osutils.set_or_unset_env('BZR_EDITOR', "./fed.sh")
630
 
        self.addCleanup(restoreDefaults)
 
726
            osutils.set_or_unset_env('BZR_EDITOR', "./fed.sh")
 
727
 
 
728
    def setup_commit_with_template(self):
 
729
        self.setup_editor()
631
730
        msgeditor.hooks.install_named_hook("commit_message_template",
632
731
                lambda commit_obj, msg: "save me some typing\n", None)
633
732
        tree = self.make_branch_and_tree('tree')
634
733
        self.build_tree(['tree/hello.txt'])
635
734
        tree.add('hello.txt')
636
 
        out, err = self.run_bzr("commit tree/hello.txt")
 
735
        return tree
 
736
 
 
737
    def test_commit_hook_template_accepted(self):
 
738
        tree = self.setup_commit_with_template()
 
739
        out, err = self.run_bzr("commit tree/hello.txt", stdin="y\n")
637
740
        last_rev = tree.branch.repository.get_revision(tree.last_revision())
638
741
        self.assertEqual('save me some typing\n', last_rev.message)
 
742
 
 
743
    def test_commit_hook_template_rejected(self):
 
744
        tree = self.setup_commit_with_template()
 
745
        expected = tree.last_revision()
 
746
        out, err = self.run_bzr_error(["empty commit message"],
 
747
            "commit tree/hello.txt", stdin="n\n")
 
748
        self.assertEqual(expected, tree.last_revision())
 
749
 
 
750
    def test_commit_without_username(self):
 
751
        """Ensure commit error if username is not set.
 
752
        """
 
753
        self.run_bzr(['init', 'foo'])
 
754
        os.chdir('foo')
 
755
        open('foo.txt', 'w').write('hello')
 
756
        self.run_bzr(['add'])
 
757
        osutils.set_or_unset_env('EMAIL', None)
 
758
        osutils.set_or_unset_env('BZR_EMAIL', None)
 
759
        out, err = self.run_bzr(['commit', '-m', 'initial'], 3)
 
760
        self.assertContainsRe(err, 'Unable to determine your name')
 
761
 
 
762
    def test_commit_recursive_checkout(self):
 
763
        """Ensure that a commit to a recursive checkout fails cleanly.
 
764
        """
 
765
        self.run_bzr(['init', 'test_branch'])
 
766
        self.run_bzr(['checkout', 'test_branch', 'test_checkout'])
 
767
        os.chdir('test_checkout')
 
768
        self.run_bzr(['bind', '.']) # bind to self
 
769
        open('foo.txt', 'w').write('hello')
 
770
        self.run_bzr(['add'])
 
771
        out, err = self.run_bzr(['commit', '-m', 'addedfoo'], 3)
 
772
        self.assertEqual(out, '')
 
773
        self.assertContainsRe(err,
 
774
            'Branch.*test_checkout.*appears to be bound to itself')
 
775