47
44
self.build_tree(['hello.txt'])
48
45
out,err = self.run_bzr('commit -m empty', retcode=3)
49
46
self.assertEqual('', out)
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))
47
self.assertContainsRe(err, 'bzr: ERROR: No changes to commit\.'
48
' Use --unchanged to commit anyhow.\n')
62
50
def test_commit_success(self):
63
51
"""Successful commit should not leave behind a bzr-commit-* file"""
69
57
self.run_bzr(["commit", "--unchanged", "-m", u'foo\xb5'])
70
58
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-'))
86
60
def test_commit_with_path(self):
87
61
"""Commit tree with path of root specified"""
88
62
a_tree = self.make_branch_and_tree('a')
132
107
'modified hello\.txt\n'
133
108
'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
170
110
def test_warn_about_forgotten_commit_message(self):
171
111
"""Test that the lack of -m parameter is caught"""
172
112
wt = self.make_branch_and_tree('.')
329
269
tree = self.make_branch_and_tree('.')
330
270
self.build_tree_contents([('foo.c', 'int main() {}')])
331
271
tree.add('foo.c')
332
self.run_bzr('commit -m ""')
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.')
334
294
def test_other_branch_commit(self):
335
295
# this branch is to ensure consistent behaviour, whether we're run
383
343
trunk = self.make_branch_and_tree('trunk')
385
345
u1 = trunk.branch.create_checkout('u1')
386
self.build_tree_contents([('u1/hosts', 'initial contents\n')])
346
self.build_tree_contents([('u1/hosts', 'initial contents')])
388
348
self.run_bzr('commit -m add-hosts u1')
390
350
u2 = trunk.branch.create_checkout('u2')
391
self.build_tree_contents([('u2/hosts', 'altered in u2\n')])
351
self.build_tree_contents([('u2/hosts', 'altered in u2')])
392
352
self.run_bzr('commit -m checkin-from-u2 u2')
394
354
# make an offline commits
395
self.build_tree_contents([('u1/hosts', 'first offline change in u1\n')])
355
self.build_tree_contents([('u1/hosts', 'first offline change in u1')])
396
356
self.run_bzr('commit -m checkin-offline --local u1')
398
358
# now try to pull in online work from u2, and then commit our offline
399
359
# work as a merge
400
360
# retcode 1 as we expect a text conflict
401
361
self.run_bzr('update u1', retcode=1)
402
self.assertFileEqual('''\
404
first offline change in u1
411
362
self.run_bzr('resolved u1/hosts')
412
363
# add a text change here to represent resolving the merge conflicts in
413
364
# favour of a new version of the file not identical to either the u1
596
547
'commit -m add-b --fixes=xxx:123',
597
548
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'])
618
550
def test_fixes_invalid_bug_number(self):
619
551
tree = self.make_branch_and_tree('tree')
620
552
self.build_tree(['tree/hello.txt'])
734
666
self.assertContainsRe(err,
735
667
r'^bzr: ERROR: Cannot lock.*readonly transport')
737
def setup_editor(self):
669
def test_commit_hook_template(self):
738
670
# Test that commit template hooks work
671
def restoreDefaults():
672
msgeditor.hooks['commit_message_template'] = []
673
osutils.set_or_unset_env('BZR_EDITOR', default_editor)
739
674
if sys.platform == "win32":
740
675
f = file('fed.bat', 'w')
741
676
f.write('@rem dummy fed')
743
self.overrideEnv('BZR_EDITOR', "fed.bat")
678
default_editor = osutils.set_or_unset_env('BZR_EDITOR', "fed.bat")
745
680
f = file('fed.sh', 'wb')
746
681
f.write('#!/bin/sh\n')
748
683
os.chmod('fed.sh', 0755)
749
self.overrideEnv('BZR_EDITOR', "./fed.sh")
751
def setup_commit_with_template(self):
684
default_editor = osutils.set_or_unset_env('BZR_EDITOR', "./fed.sh")
685
self.addCleanup(restoreDefaults)
753
686
msgeditor.hooks.install_named_hook("commit_message_template",
754
687
lambda commit_obj, msg: "save me some typing\n", None)
755
688
tree = self.make_branch_and_tree('tree')
756
689
self.build_tree(['tree/hello.txt'])
757
690
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")
770
def test_commit_hook_template_accepted(self):
771
tree = self.setup_commit_with_template()
772
out, err = self.run_bzr("commit tree/hello.txt", stdin="y\n")
773
last_rev = tree.branch.repository.get_revision(tree.last_revision())
774
self.assertEqual('save me some typing\n', last_rev.message)
776
def test_commit_hook_template_rejected(self):
777
tree = self.setup_commit_with_template()
778
expected = tree.last_revision()
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 \"\"."],
783
"commit tree/hello.txt", stdin="n\n")
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
691
out, err = self.run_bzr("commit tree/hello.txt")
793
692
last_rev = tree.branch.repository.get_revision(tree.last_revision())
794
693
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')