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
681
721
f = file('fed.bat', 'w')
682
722
f.write('@rem dummy fed')
684
osutils.set_or_unset_env('BZR_EDITOR', "fed.bat")
724
self.overrideEnv('BZR_EDITOR', "fed.bat")
686
726
f = file('fed.sh', 'wb')
687
727
f.write('#!/bin/sh\n')
689
729
os.chmod('fed.sh', 0755)
690
osutils.set_or_unset_env('BZR_EDITOR', "./fed.sh")
730
self.overrideEnv('BZR_EDITOR', "./fed.sh")
692
732
def setup_commit_with_template(self):
693
733
self.setup_editor()
698
738
tree.add('hello.txt')
741
def test_edit_empty_message(self):
742
tree = self.make_branch_and_tree('tree')
744
self.build_tree(['tree/hello.txt'])
745
tree.add('hello.txt')
746
out, err = self.run_bzr("commit tree/hello.txt", retcode=3,
748
self.assertContainsRe(err,
749
"bzr: ERROR: Empty commit message specified")
701
751
def test_commit_hook_template_accepted(self):
702
752
tree = self.setup_commit_with_template()
703
753
out, err = self.run_bzr("commit tree/hello.txt", stdin="y\n")
707
757
def test_commit_hook_template_rejected(self):
708
758
tree = self.setup_commit_with_template()
709
759
expected = tree.last_revision()
710
out, err = self.run_bzr_error(["empty commit message"],
760
out, err = self.run_bzr_error(["Empty commit message specified."
761
" Please specify a commit message with either"
762
" --message or --file or leave a blank message"
763
" with --message \"\"."],
711
764
"commit tree/hello.txt", stdin="n\n")
712
765
self.assertEqual(expected, tree.last_revision())
767
def test_set_commit_message(self):
768
msgeditor.hooks.install_named_hook("set_commit_message",
769
lambda commit_obj, msg: "save me some typing\n", None)
770
tree = self.make_branch_and_tree('tree')
771
self.build_tree(['tree/hello.txt'])
772
tree.add('hello.txt')
773
out, err = self.run_bzr("commit tree/hello.txt")
774
last_rev = tree.branch.repository.get_revision(tree.last_revision())
775
self.assertEqual('save me some typing\n', last_rev.message)
777
def test_commit_without_username(self):
778
"""Ensure commit error if username is not set.
780
self.run_bzr(['init', 'foo'])
782
open('foo.txt', 'w').write('hello')
783
self.run_bzr(['add'])
784
self.overrideEnv('EMAIL', None)
785
self.overrideEnv('BZR_EMAIL', None)
786
# Also, make sure that it's not inferred from mailname.
787
self.overrideAttr(config, '_auto_user_id',
788
lambda: (None, None))
789
out, err = self.run_bzr(['commit', '-m', 'initial'], 3)
790
self.assertContainsRe(err, 'Unable to determine your name')
792
def test_commit_recursive_checkout(self):
793
"""Ensure that a commit to a recursive checkout fails cleanly.
795
self.run_bzr(['init', 'test_branch'])
796
self.run_bzr(['checkout', 'test_branch', 'test_checkout'])
797
os.chdir('test_checkout')
798
self.run_bzr(['bind', '.']) # bind to self
799
open('foo.txt', 'w').write('hello')
800
self.run_bzr(['add'])
801
out, err = self.run_bzr(['commit', '-m', 'addedfoo'], 3)
802
self.assertEqual(out, '')
803
self.assertContainsRe(err,
804
'Branch.*test_checkout.*appears to be bound to itself')