18
18
"""Tests for the commit CLI of bzr."""
25
from testtools.matchers import DocTestMatches
23
27
from bzrlib import (
30
33
from bzrlib.bzrdir import BzrDir
31
34
from bzrlib.tests import (
35
from bzrlib.tests.blackbox import ExternalBase
38
class TestCommit(ExternalBase):
38
from bzrlib.tests import TestCaseWithTransport
41
class TestCommit(TestCaseWithTransport):
40
43
def test_05_empty_commit(self):
41
44
"""Commit of tree with no versioned files should fail"""
44
47
self.build_tree(['hello.txt'])
45
48
out,err = self.run_bzr('commit -m empty', retcode=3)
46
49
self.assertEqual('', out)
47
self.assertContainsRe(err, 'bzr: ERROR: No changes to commit\.'
48
' Use --unchanged to commit anyhow.\n')
51
# 1) We really don't want 'aborting commit write group' anymore.
52
# 2) bzr: ERROR: is a really long line, so we wrap it with '\'
57
bzr: ERROR: No changes to commit.\
58
Please 'bzr add' the files you want to commit,\
59
or use --unchanged to force an empty commit.
60
""", flags=doctest.ELLIPSIS|doctest.REPORT_UDIFF))
50
62
def test_commit_success(self):
51
63
"""Successful commit should not leave behind a bzr-commit-* file"""
57
69
self.run_bzr(["commit", "--unchanged", "-m", u'foo\xb5'])
58
70
self.assertEqual('', self.run_bzr('unknowns')[0])
72
def test_commit_lossy_native(self):
73
"""A --lossy option to commit is supported."""
74
self.make_branch_and_tree('.')
75
self.run_bzr('commit --lossy --unchanged -m message')
76
self.assertEqual('', self.run_bzr('unknowns')[0])
78
def test_commit_lossy_foreign(self):
79
test_foreign.register_dummy_foreign_for_test(self)
80
self.make_branch_and_tree('.',
81
format=test_foreign.DummyForeignVcsDirFormat())
82
self.run_bzr('commit --lossy --unchanged -m message')
83
output = self.run_bzr('revision-info')[0]
84
self.assertTrue(output.startswith('1 dummy-'))
60
86
def test_commit_with_path(self):
61
87
"""Commit tree with path of root specified"""
62
88
a_tree = self.make_branch_and_tree('a')
107
132
'modified hello\.txt\n'
108
133
'Committed revision 2\.\n$')
135
def test_unicode_commit_message_is_filename(self):
136
"""Unicode commit message same as a filename (Bug #563646).
138
self.requireFeature(features.UnicodeFilenameFeature)
139
file_name = u'\N{euro sign}'
140
self.run_bzr(['init'])
141
open(file_name, 'w').write('hello world')
142
self.run_bzr(['add'])
143
out, err = self.run_bzr(['commit', '-m', file_name])
144
reflags = re.MULTILINE|re.DOTALL|re.UNICODE
145
te = osutils.get_terminal_encoding()
146
self.assertContainsRe(err.decode(te),
147
u'The commit message is a file name:',
150
# Run same test with a filename that causes encode
151
# error for the terminal encoding. We do this
152
# by forcing terminal encoding of ascii for
153
# osutils.get_terminal_encoding which is used
154
# by ui.text.show_warning
155
default_get_terminal_enc = osutils.get_terminal_encoding
157
osutils.get_terminal_encoding = lambda trace=None: 'ascii'
158
file_name = u'foo\u1234'
159
open(file_name, 'w').write('hello world')
160
self.run_bzr(['add'])
161
out, err = self.run_bzr(['commit', '-m', file_name])
162
reflags = re.MULTILINE|re.DOTALL|re.UNICODE
163
te = osutils.get_terminal_encoding()
164
self.assertContainsRe(err.decode(te, 'replace'),
165
u'The commit message is a file name:',
168
osutils.get_terminal_encoding = default_get_terminal_enc
110
170
def test_warn_about_forgotten_commit_message(self):
111
171
"""Test that the lack of -m parameter is caught"""
112
172
wt = self.make_branch_and_tree('.')
269
329
tree = self.make_branch_and_tree('.')
270
330
self.build_tree_contents([('foo.c', 'int main() {}')])
271
331
tree.add('foo.c')
272
self.run_bzr('commit -m ""', retcode=3)
274
def test_unsupported_encoding_commit_message(self):
275
if sys.platform == 'win32':
276
raise tests.TestNotApplicable('Win32 parses arguments directly'
277
' as Unicode, so we can\'t pass invalid non-ascii')
278
tree = self.make_branch_and_tree('.')
279
self.build_tree_contents([('foo.c', 'int main() {}')])
281
# LANG env variable has no effect on Windows
282
# but some characters anyway cannot be represented
283
# in default user encoding
284
char = probe_bad_non_ascii(osutils.get_user_encoding())
286
raise TestSkipped('Cannot find suitable non-ascii character'
287
'for user_encoding (%s)' % osutils.get_user_encoding())
288
out,err = self.run_bzr_subprocess('commit -m "%s"' % char,
290
env_changes={'LANG': 'C'})
291
self.assertContainsRe(err, r'bzrlib.errors.BzrError: Parameter.*is '
292
'unsupported by the current encoding.')
332
self.run_bzr('commit -m ""')
294
334
def test_other_branch_commit(self):
295
335
# this branch is to ensure consistent behaviour, whether we're run
556
596
'commit -m add-b --fixes=xxx:123',
557
597
working_dir='tree')
599
def test_fixes_bug_with_default_tracker(self):
600
"""commit --fixes=234 uses the default bug tracker."""
601
tree = self.make_branch_and_tree('tree')
602
self.build_tree(['tree/hello.txt'])
603
tree.add('hello.txt')
605
["bzr: ERROR: No tracker specified for bug 123. Use the form "
606
"'tracker:id' or specify a default bug tracker using the "
607
"`bugtracker` option.\n"
608
"See \"bzr help bugs\" for more information on this feature. "
610
'commit -m add-b --fixes=123',
612
tree.branch.get_config().set_user_option("bugtracker", "lp")
613
self.run_bzr('commit -m hello --fixes=234 tree/hello.txt')
614
last_rev = tree.branch.repository.get_revision(tree.last_revision())
615
self.assertEqual('https://launchpad.net/bugs/234 fixed',
616
last_rev.properties['bugs'])
559
618
def test_fixes_invalid_bug_number(self):
560
619
tree = self.make_branch_and_tree('tree')
561
620
self.build_tree(['tree/hello.txt'])
573
632
self.build_tree(['tree/hello.txt'])
574
633
tree.add('hello.txt')
575
634
self.run_bzr_error(
576
[r"Invalid bug orange. Must be in the form of 'tracker:id'\. "
577
r"See \"bzr help bugs\" for more information on this feature.\n"
578
r"Commit refused\."],
579
'commit -m add-b --fixes=orange',
635
[r"Invalid bug orange:apples:bananas. Must be in the form of "
636
r"'tracker:id'\. See \"bzr help bugs\" for more information on "
637
r"this feature.\nCommit refused\."],
638
'commit -m add-b --fixes=orange:apples:bananas',
580
639
working_dir='tree')
582
641
def test_no_author(self):
681
740
f = file('fed.bat', 'w')
682
741
f.write('@rem dummy fed')
684
osutils.set_or_unset_env('BZR_EDITOR', "fed.bat")
743
self.overrideEnv('BZR_EDITOR', "fed.bat")
686
745
f = file('fed.sh', 'wb')
687
746
f.write('#!/bin/sh\n')
689
748
os.chmod('fed.sh', 0755)
690
osutils.set_or_unset_env('BZR_EDITOR', "./fed.sh")
749
self.overrideEnv('BZR_EDITOR', "./fed.sh")
692
751
def setup_commit_with_template(self):
693
752
self.setup_editor()
698
757
tree.add('hello.txt')
760
def test_edit_empty_message(self):
761
tree = self.make_branch_and_tree('tree')
763
self.build_tree(['tree/hello.txt'])
764
tree.add('hello.txt')
765
out, err = self.run_bzr("commit tree/hello.txt", retcode=3,
767
self.assertContainsRe(err,
768
"bzr: ERROR: Empty commit message specified")
701
770
def test_commit_hook_template_accepted(self):
702
771
tree = self.setup_commit_with_template()
703
772
out, err = self.run_bzr("commit tree/hello.txt", stdin="y\n")
707
776
def test_commit_hook_template_rejected(self):
708
777
tree = self.setup_commit_with_template()
709
778
expected = tree.last_revision()
710
out, err = self.run_bzr_error(["empty commit message"],
779
out, err = self.run_bzr_error(["Empty commit message specified."
780
" Please specify a commit message with either"
781
" --message or --file or leave a blank message"
782
" with --message \"\"."],
711
783
"commit tree/hello.txt", stdin="n\n")
712
784
self.assertEqual(expected, tree.last_revision())
786
def test_set_commit_message(self):
787
msgeditor.hooks.install_named_hook("set_commit_message",
788
lambda commit_obj, msg: "save me some typing\n", None)
789
tree = self.make_branch_and_tree('tree')
790
self.build_tree(['tree/hello.txt'])
791
tree.add('hello.txt')
792
out, err = self.run_bzr("commit tree/hello.txt")
793
last_rev = tree.branch.repository.get_revision(tree.last_revision())
794
self.assertEqual('save me some typing\n', last_rev.message)
796
def test_commit_without_username(self):
797
"""Ensure commit error if username is not set.
799
self.run_bzr(['init', 'foo'])
801
open('foo.txt', 'w').write('hello')
802
self.run_bzr(['add'])
803
self.overrideEnv('EMAIL', None)
804
self.overrideEnv('BZR_EMAIL', None)
805
# Also, make sure that it's not inferred from mailname.
806
self.overrideAttr(config, '_auto_user_id',
807
lambda: (None, None))
808
out, err = self.run_bzr(['commit', '-m', 'initial'], 3)
809
self.assertContainsRe(err, 'Unable to determine your name')
811
def test_commit_recursive_checkout(self):
812
"""Ensure that a commit to a recursive checkout fails cleanly.
814
self.run_bzr(['init', 'test_branch'])
815
self.run_bzr(['checkout', 'test_branch', 'test_checkout'])
816
os.chdir('test_checkout')
817
self.run_bzr(['bind', '.']) # bind to self
818
open('foo.txt', 'w').write('hello')
819
self.run_bzr(['add'])
820
out, err = self.run_bzr(['commit', '-m', 'addedfoo'], 3)
821
self.assertEqual(out, '')
822
self.assertContainsRe(err,
823
'Branch.*test_checkout.*appears to be bound to itself')