3 # Copyright (c) 2007 Steven Grimm
6 test_description
='git commit
8 Tests for template, signoff, squash and -F functions.'
12 .
"$TEST_DIRECTORY"/lib-rebase.sh
15 expect
=commit_msg_is.expect
16 actual
=commit_msg_is.actual
18 printf "%s" "$(git log --pretty=format:%s%b -1)" >"$actual" &&
19 printf "%s" "$1" >"$expect" &&
20 test_cmp
"$expect" "$actual"
23 # A sanity check to see if commit is working at all.
24 test_expect_success
'a basic commit in an empty tree should succeed' '
27 git commit -m "initial commit"
30 test_expect_success
'nonexistent template file should return error' '
31 echo changes >> foo &&
34 GIT_EDITOR="echo hello >\"\$1\"" &&
36 test_must_fail git commit --template "$PWD"/notexist
40 test_expect_success
'nonexistent template file in config should return error' '
41 test_config commit.template "$PWD"/notexist &&
43 GIT_EDITOR="echo hello >\"\$1\"" &&
45 test_must_fail git commit
49 # From now on we'll use a template file that exists.
50 TEMPLATE
="$PWD"/template
52 test_expect_success
'unedited template should not commit' '
53 echo "template line" > "$TEMPLATE" &&
54 test_must_fail git commit --template "$TEMPLATE"
57 test_expect_success
'unedited template with comments should not commit' '
58 echo "# comment in template" >> "$TEMPLATE" &&
59 test_must_fail git commit --template "$TEMPLATE"
62 test_expect_success
'a Signed-off-by line by itself should not commit' '
64 test_set_editor "$TEST_DIRECTORY"/t7500/add-signed-off &&
65 test_must_fail git commit --template "$TEMPLATE"
69 test_expect_success
'adding comments to a template should not commit' '
71 test_set_editor "$TEST_DIRECTORY"/t7500/add-comments &&
72 test_must_fail git commit --template "$TEMPLATE"
76 test_expect_success
'adding real content to a template should commit' '
78 test_set_editor "$TEST_DIRECTORY"/t7500/add-content &&
79 git commit --template "$TEMPLATE"
81 commit_msg_is "template linecommit message"
84 test_expect_success
'-t option should be short for --template' '
85 echo "short template" > "$TEMPLATE" &&
86 echo "new content" >> foo &&
89 test_set_editor "$TEST_DIRECTORY"/t7500/add-content &&
90 git commit -t "$TEMPLATE"
92 commit_msg_is "short templatecommit message"
95 test_expect_success
'config-specified template should commit' '
96 echo "new template" > "$TEMPLATE" &&
97 test_config commit.template "$TEMPLATE" &&
98 echo "more content" >> foo &&
101 test_set_editor "$TEST_DIRECTORY"/t7500/add-content &&
104 commit_msg_is "new templatecommit message"
107 test_expect_success
'explicit commit message should override template' '
108 echo "still more content" >> foo &&
110 GIT_EDITOR="$TEST_DIRECTORY"/t7500/add-content git commit --template "$TEMPLATE" \
111 -m "command line msg" &&
112 commit_msg_is "command line msg"
115 test_expect_success
'commit message from file should override template' '
116 echo "content galore" >> foo &&
118 echo "standard input msg" |
120 test_set_editor "$TEST_DIRECTORY"/t7500/add-content &&
121 git commit --template "$TEMPLATE" --file -
123 commit_msg_is "standard input msg"
126 cat >"$TEMPLATE" <<\EOF
132 test_expect_success
'commit message from template with whitespace issue' '
133 echo "content galore" >>foo &&
135 GIT_EDITOR=\""$TEST_DIRECTORY"\"/t7500/add-whitespaced-content \
136 git commit --template "$TEMPLATE" &&
137 commit_msg_is "commit message"
140 test_expect_success
'using alternate GIT_INDEX_FILE (1)' '
142 cp .git/index saved-index &&
144 echo some new content >file &&
145 GIT_INDEX_FILE=.git/another_index &&
146 export GIT_INDEX_FILE &&
148 git commit -m "commit using another index" &&
149 git diff-index --exit-code HEAD &&
150 git diff-files --exit-code
152 cmp .git/index saved-index >/dev/null
156 test_expect_success
'using alternate GIT_INDEX_FILE (2)' '
158 cp .git/index saved-index &&
160 rm -f .git/no-such-index &&
161 GIT_INDEX_FILE=.git/no-such-index &&
162 export GIT_INDEX_FILE &&
163 git commit -m "commit using nonexistent index" &&
164 test -z "$(git ls-files)" &&
165 test -z "$(git ls-tree HEAD)"
168 cmp .git/index saved-index >/dev/null
174 Signed-off-by: C O Mitter <committer@example.com>
177 test_expect_success
'--signoff' '
178 echo "yet another content *narf*" >> foo &&
179 echo "zort" | git commit -s -F - foo &&
180 git cat-file commit HEAD | sed "1,/^\$/d" > output &&
181 test_cmp expect output
184 test_expect_success
'commit message from file (1)' '
186 echo "Log in top directory" >log &&
187 echo "Log in sub directory" >subdir/log &&
190 git commit --allow-empty -F log
192 commit_msg_is "Log in sub directory"
195 test_expect_success
'commit message from file (2)' '
197 echo "Log in sub directory" >subdir/log &&
200 git commit --allow-empty -F log
202 commit_msg_is "Log in sub directory"
205 test_expect_success
'commit message from stdin' '
208 echo "Log with foo word" | git commit --allow-empty -F -
210 commit_msg_is "Log with foo word"
213 test_expect_success
'commit -F overrides -t' '
216 echo "-F log" > f.log &&
217 echo "-t template" > t.template &&
218 git commit --allow-empty -F f.log -t t.template
220 commit_msg_is "-F log"
223 test_expect_success
'Commit without message is allowed with --allow-empty-message' '
224 echo "more content" >>foo &&
227 git commit --allow-empty-message <empty &&
229 git tag empty-message-commit
232 test_expect_success
'Commit without message is no-no without --allow-empty-message' '
233 echo "more content" >>foo &&
236 test_must_fail git commit <empty
239 test_expect_success
'Commit a message with --allow-empty-message' '
240 echo "even more content" >>foo &&
242 git commit --allow-empty-message -m"hello there" &&
243 commit_msg_is "hello there"
246 test_expect_success
'commit -C empty respects --allow-empty-message' '
249 test_must_fail git commit -C empty-message-commit &&
250 git commit -C empty-message-commit --allow-empty-message &&
254 commit_for_rebase_autosquash_setup
() {
255 echo "first content line" >>foo
&&
258 target message subject line
260 target message body line 1
261 target message body line 2
264 echo "second content line" >>foo
&&
266 git commit
-m "intermediate commit" &&
267 echo "third content line" >>foo
&&
271 test_expect_success
'commit --fixup provides correct one-line commit message' '
272 commit_for_rebase_autosquash_setup &&
273 EDITOR="echo ignored >>" git commit --fixup HEAD~1 &&
274 commit_msg_is "fixup! target message subject line"
277 test_expect_success
'commit --fixup -m"something" -m"extra"' '
278 commit_for_rebase_autosquash_setup &&
279 git commit --fixup HEAD~1 -m"something" -m"extra" &&
280 commit_msg_is "fixup! target message subject linesomething
284 test_expect_success
'commit --fixup --edit' '
285 commit_for_rebase_autosquash_setup &&
286 EDITOR="printf \"something\nextra\" >>" git commit --fixup HEAD~1 --edit &&
287 commit_msg_is "fixup! target message subject linesomething
293 git log
-1 --pretty=format
:"%B" "$rev"
296 test_expect_success
'commit --fixup=amend: creates amend! commit' '
297 commit_for_rebase_autosquash_setup &&
298 cat >expected <<-EOF &&
299 amend! $(git log -1 --format=%s HEAD~)
301 $(get_commit_msg HEAD~)
307 FAKE_COMMIT_AMEND="edited" \
308 git commit --fixup=amend:HEAD~
310 get_commit_msg HEAD >actual &&
311 test_cmp expected actual
314 test_expect_success
'--fixup=amend: --only ignores staged changes' '
315 commit_for_rebase_autosquash_setup &&
316 cat >expected <<-EOF &&
317 amend! $(git log -1 --format=%s HEAD~)
319 $(get_commit_msg HEAD~)
325 FAKE_COMMIT_AMEND="edited" \
326 git commit --fixup=amend:HEAD~ --only
328 get_commit_msg HEAD >actual &&
329 test_cmp expected actual &&
330 test_cmp_rev HEAD@{1}^{tree} HEAD^{tree} &&
331 test_cmp_rev HEAD@{1} HEAD^ &&
332 test_expect_code 1 git diff --cached --exit-code &&
333 git cat-file blob :foo >actual &&
337 test_expect_success
'--fixup=reword: ignores staged changes' '
338 commit_for_rebase_autosquash_setup &&
339 cat >expected <<-EOF &&
340 amend! $(git log -1 --format=%s HEAD~)
342 $(get_commit_msg HEAD~)
348 FAKE_COMMIT_AMEND="edited" \
349 git commit --fixup=reword:HEAD~
351 get_commit_msg HEAD >actual &&
352 test_cmp expected actual &&
353 test_cmp_rev HEAD@{1}^{tree} HEAD^{tree} &&
354 test_cmp_rev HEAD@{1} HEAD^ &&
355 test_expect_code 1 git diff --cached --exit-code &&
356 git cat-file blob :foo >actual &&
360 test_expect_success
'--fixup=reword: error out with -m option' '
361 commit_for_rebase_autosquash_setup &&
362 echo "fatal: options '\''-m'\'' and '\''--fixup:reword'\'' cannot be used together" >expect &&
363 test_must_fail git commit --fixup=reword:HEAD~ -m "reword commit message" 2>actual &&
364 test_cmp expect actual
367 test_expect_success
'--fixup=amend: error out with -m option' '
368 commit_for_rebase_autosquash_setup &&
369 echo "fatal: options '\''-m'\'' and '\''--fixup:amend'\'' cannot be used together" >expect &&
370 test_must_fail git commit --fixup=amend:HEAD~ -m "amend commit message" 2>actual &&
371 test_cmp expect actual
374 test_expect_success
'consecutive amend! commits remove amend! line from commit msg body' '
375 commit_for_rebase_autosquash_setup &&
376 cat >expected <<-EOF &&
377 amend! amend! $(git log -1 --format=%s HEAD~)
379 $(get_commit_msg HEAD~)
385 echo "reword new commit message" >actual &&
388 FAKE_COMMIT_AMEND="edited 1" \
389 git commit --fixup=reword:HEAD~ &&
390 FAKE_COMMIT_AMEND="edited 2" \
391 git commit --fixup=reword:HEAD
393 get_commit_msg HEAD >actual &&
394 test_cmp expected actual
397 test_expect_success
'deny to create amend! commit if its commit msg body is empty' '
398 commit_for_rebase_autosquash_setup &&
399 echo "Aborting commit due to empty commit message body." >expected &&
402 test_must_fail env FAKE_COMMIT_MESSAGE="amend! target message subject line" \
403 git commit --fixup=amend:HEAD~ 2>actual
405 test_cmp expected actual
408 test_expect_success
'amend! commit allows empty commit msg body with --allow-empty-message' '
409 commit_for_rebase_autosquash_setup &&
410 cat >expected <<-EOF &&
411 amend! $(git log -1 --format=%s HEAD~)
415 FAKE_COMMIT_MESSAGE="amend! target message subject line" \
416 git commit --fixup=amend:HEAD~ --allow-empty-message &&
417 get_commit_msg HEAD >actual
419 test_cmp expected actual
422 test_fixup_reword_opt
() {
423 test_expect_success
"--fixup=reword: incompatible with $1" "
424 echo 'fatal: reword option of '\''--fixup'\'' and' \
425 ''\''--patch/--interactive/--all/--include/--only'\' \
426 'cannot be used together' >expect &&
427 test_must_fail git commit --fixup=reword:HEAD~ $1 2>actual &&
428 test_cmp expect actual
432 for opt
in --all --include --only --interactive --patch
434 test_fixup_reword_opt
$opt
437 test_expect_success
'--fixup=reword: give error with pathsec' '
438 commit_for_rebase_autosquash_setup &&
439 echo "fatal: reword option of '\''--fixup'\'' and path '\''foo'\'' cannot be used together" >expect &&
440 test_must_fail git commit --fixup=reword:HEAD~ -- foo 2>actual &&
441 test_cmp expect actual
444 test_expect_success
'--fixup=reword: -F give error message' '
445 echo "fatal: options '\''-F'\'' and '\''--fixup'\'' cannot be used together" >expect &&
446 test_must_fail git commit --fixup=reword:HEAD~ -F msg 2>actual &&
447 test_cmp expect actual
450 test_expect_success
'commit --squash works with -F' '
451 commit_for_rebase_autosquash_setup &&
452 echo "log message from file" >msgfile &&
453 git commit --squash HEAD~1 -F msgfile &&
454 commit_msg_is "squash! target message subject linelog message from file"
457 test_expect_success
'commit --squash works with -m' '
458 commit_for_rebase_autosquash_setup &&
459 git commit --squash HEAD~1 -m "foo bar\nbaz" &&
460 commit_msg_is "squash! target message subject linefoo bar\nbaz"
463 test_expect_success
'commit --squash works with -C' '
464 commit_for_rebase_autosquash_setup &&
465 git commit --squash HEAD~1 -C HEAD &&
466 commit_msg_is "squash! target message subject lineintermediate commit"
469 test_expect_success
'commit --squash works with -c' '
470 commit_for_rebase_autosquash_setup &&
471 test_set_editor "$TEST_DIRECTORY"/t7500/edit-content &&
472 git commit --squash HEAD~1 -c HEAD &&
473 commit_msg_is "squash! target message subject lineedited commit"
476 test_expect_success
'commit --squash works with -C for same commit' '
477 commit_for_rebase_autosquash_setup &&
478 git commit --squash HEAD -C HEAD &&
479 commit_msg_is "squash! intermediate commit"
482 test_expect_success
'commit --squash works with -c for same commit' '
483 commit_for_rebase_autosquash_setup &&
484 test_set_editor "$TEST_DIRECTORY"/t7500/edit-content &&
485 git commit --squash HEAD -c HEAD &&
486 commit_msg_is "squash! edited commit"
489 test_expect_success
'commit --squash works with editor' '
490 commit_for_rebase_autosquash_setup &&
491 test_set_editor "$TEST_DIRECTORY"/t7500/add-content &&
492 git commit --squash HEAD~1 &&
493 commit_msg_is "squash! target message subject linecommit message"
496 test_expect_success
'invalid message options when using --fixup' '
497 echo changes >>foo &&
498 echo "message" >log &&
500 test_must_fail git commit --fixup HEAD~1 --squash HEAD~2 &&
501 test_must_fail git commit --fixup HEAD~1 -C HEAD~2 &&
502 test_must_fail git commit --fixup HEAD~1 -c HEAD~2 &&
503 test_must_fail git commit --fixup HEAD~1 -F log
506 cat >expected-template
<<EOF
508 # Please enter the commit message for your changes. Lines starting
509 # with '#' will be ignored.
511 # Author: A U Thor <author@example.com>
513 # On branch commit-template-check
514 # Changes to be committed:
515 # new file: commit-template-check
517 # Untracked files not listed
520 test_expect_success
'new line found before status message in commit template' '
521 git checkout -b commit-template-check &&
522 git reset --hard HEAD &&
523 touch commit-template-check &&
524 git add commit-template-check &&
525 GIT_EDITOR="cat >editor-input" git commit --untracked-files=no --allow-empty-message &&
526 test_cmp expected-template editor-input
529 test_expect_success
'setup empty commit with unstaged rename and copy' '
530 test_create_repo unstaged_rename_and_copy &&
532 cd unstaged_rename_and_copy &&
534 echo content >orig &&
539 mv orig new_rename &&
540 git add -N new_copy new_rename
544 test_expect_success
'check commit with unstaged rename and copy' '
546 cd unstaged_rename_and_copy &&
548 test_must_fail git -c diff.renames=copy commit
552 test_expect_success
'commit without staging files fails and displays hints' '
553 echo "initial" >file &&
555 git commit -m initial &&
556 echo "changes" >>file &&
557 test_must_fail git commit -m update >actual &&
558 test_i18ngrep "no changes added to commit (use \"git add\" and/or \"git commit -a\")" actual