~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

  • Committer: John Arbash Meinel
  • Date: 2010-05-11 10:45:26 UTC
  • mto: This revision was merged to the branch mainline in revision 5225.
  • Revision ID: john@arbash-meinel.com-20100511104526-zxnstcxta22hzw2n
Implement a compiled extension for parsing the text key out of a CHKInventory value.

Related to bug #562666. This seems to shave 5-10% out of the time spent doing a complete
branch of bzr.dev/launchpad/etc.

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