Raw
1 #!/bin/sh
2
3 test_description='git commit porcelain-ish'
4
5 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
6 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
7
8 . ./test-lib.sh
9
10 commit_msg_is () {
11 expect=commit_msg_is.expect
12 actual=commit_msg_is.actual
13
14 printf "%s" "$(git log --pretty=format:%s%b -1)" >$actual &&
15 printf "%s" "$1" >$expect &&
16 test_cmp $expect $actual
17 }
18
19 # Arguments: [<prefix] [<commit message>] [<commit options>]
20 check_summary_oneline() {
21 test_tick &&
22 git commit ${3+"$3"} -m "$2" >raw &&
23 head -n 1 raw >act &&
24
25 # branch name
26 SUMMARY_PREFIX="$(git name-rev --name-only HEAD)" &&
27
28 # append the "special" prefix, like "root-commit", "detached HEAD"
29 if test -n "$1"
30 then
31 SUMMARY_PREFIX="$SUMMARY_PREFIX ($1)"
32 fi
33
34 # abbrev SHA-1
35 SUMMARY_POSTFIX="$(git log -1 --pretty='format:%h')"
36 echo "[$SUMMARY_PREFIX $SUMMARY_POSTFIX] $2" >exp &&
37
38 test_cmp exp act
39 }
40
41 trailer_commit_base () {
42 echo "fun" >>file &&
43 git add file &&
44 git commit -s --trailer "Signed-off-by=C1 E1 " \
45 --trailer "Helped-by:C2 E2 " \
46 --trailer "Reported-by=C3 E3" \
47 --trailer "Mentored-by:C4 E4" \
48 -m "hello"
49 }
50
51 test_expect_success 'output summary format' '
52
53 echo new >file1 &&
54 git add file1 &&
55 check_summary_oneline "root-commit" "initial" &&
56
57 echo change >>file1 &&
58 git add file1
59 '
60
61 test_expect_success 'output summary format: root-commit' '
62 check_summary_oneline "" "a change"
63 '
64
65 test_expect_success 'output summary format for commit with an empty diff' '
66
67 check_summary_oneline "" "empty" "--allow-empty"
68 '
69
70 test_expect_success 'output summary format for merges' '
71
72 git checkout -b recursive-base &&
73 test_commit base file1 &&
74
75 git checkout -b recursive-a recursive-base &&
76 test_commit commit-a file1 &&
77
78 git checkout -b recursive-b recursive-base &&
79 test_commit commit-b file1 &&
80
81 # conflict
82 git checkout recursive-a &&
83 test_must_fail git merge recursive-b &&
84 # resolve the conflict
85 echo commit-a >file1 &&
86 git add file1 &&
87 check_summary_oneline "" "Merge"
88 '
89
90 output_tests_cleanup() {
91 # this is needed for "do not fire editor in the presence of conflicts"
92 git checkout main &&
93
94 # this is needed for the "partial removal" test to pass
95 git rm file1 &&
96 git commit -m "cleanup"
97 }
98
99 test_expect_success 'the basics' '
100
101 output_tests_cleanup &&
102
103 echo doing partial >"commit is" &&
104 mkdir not &&
105 echo very much encouraged but we should >not/forbid &&
106 git add "commit is" not &&
107 echo update added "commit is" file >"commit is" &&
108 echo also update another >not/forbid &&
109 test_tick &&
110 git commit -a -m "initial with -a" &&
111
112 git cat-file blob HEAD:"commit is" >current.1 &&
113 git cat-file blob HEAD:not/forbid >current.2 &&
114
115 cmp current.1 "commit is" &&
116 cmp current.2 not/forbid
117
118 '
119
120 test_expect_success 'partial' '
121
122 echo another >"commit is" &&
123 echo another >not/forbid &&
124 test_tick &&
125 git commit -m "partial commit to handle a file" "commit is" &&
126
127 changed=$(git diff-tree --name-only HEAD^ HEAD) &&
128 test "$changed" = "commit is"
129
130 '
131
132 test_expect_success 'partial modification in a subdirectory' '
133
134 test_tick &&
135 git commit -m "partial commit to subdirectory" not &&
136
137 changed=$(git diff-tree -r --name-only HEAD^ HEAD) &&
138 test "$changed" = "not/forbid"
139
140 '
141
142 test_expect_success 'partial removal' '
143
144 git rm not/forbid &&
145 git commit -m "partial commit to remove not/forbid" not &&
146
147 changed=$(git diff-tree -r --name-only HEAD^ HEAD) &&
148 test "$changed" = "not/forbid" &&
149 remain=$(git ls-tree -r --name-only HEAD) &&
150 test "$remain" = "commit is"
151
152 '
153
154 test_expect_success 'sign off' '
155
156 >positive &&
157 git add positive &&
158 git commit -s -m "thank you" &&
159 git cat-file commit HEAD >commit.msg &&
160 sed -ne "s/Signed-off-by: //p" commit.msg >actual &&
161 git var GIT_COMMITTER_IDENT >ident &&
162 sed -e "s/>.*/>/" ident >expected &&
163 test_cmp expected actual
164
165 '
166
167 test_expect_success 'commit --trailer with "="' '
168 trailer_commit_base &&
169 cat >expected <<-\EOF &&
170 hello
171
172 Signed-off-by: C O Mitter <committer@example.com>
173 Signed-off-by: C1 E1
174 Helped-by: C2 E2
175 Reported-by: C3 E3
176 Mentored-by: C4 E4
177 EOF
178 commit_body HEAD >actual &&
179 test_cmp expected actual
180 '
181
182 test_expect_success 'commit --trailer with -c and "replace" as ifexists' '
183 trailer_commit_base &&
184 cat >expected <<-\EOF &&
185 hello
186
187 Signed-off-by: C O Mitter <committer@example.com>
188 Signed-off-by: C1 E1
189 Reported-by: C3 E3
190 Mentored-by: C4 E4
191 Helped-by: C3 E3
192 EOF
193 git -c trailer.ifexists="replace" \
194 commit --trailer "Mentored-by: C4 E4" \
195 --trailer "Helped-by: C3 E3" \
196 --amend &&
197 commit_body HEAD >actual &&
198 test_cmp expected actual
199 '
200
201 test_expect_success 'commit --trailer with -c and "add" as ifexists' '
202 trailer_commit_base &&
203 cat >expected <<-\EOF &&
204 hello
205
206 Signed-off-by: C O Mitter <committer@example.com>
207 Signed-off-by: C1 E1
208 Helped-by: C2 E2
209 Reported-by: C3 E3
210 Mentored-by: C4 E4
211 Reported-by: C3 E3
212 Mentored-by: C4 E4
213 EOF
214 git -c trailer.ifexists="add" \
215 commit --trailer "Reported-by: C3 E3" \
216 --trailer "Mentored-by: C4 E4" \
217 --amend &&
218 commit_body HEAD >actual &&
219 test_cmp expected actual
220 '
221
222 test_expect_success 'commit --trailer with -c and "donothing" as ifexists' '
223 trailer_commit_base &&
224 cat >expected <<-\EOF &&
225 hello
226
227 Signed-off-by: C O Mitter <committer@example.com>
228 Signed-off-by: C1 E1
229 Helped-by: C2 E2
230 Reported-by: C3 E3
231 Mentored-by: C4 E4
232 Reviewed-by: C6 E6
233 EOF
234 git -c trailer.ifexists="donothing" \
235 commit --trailer "Mentored-by: C5 E5" \
236 --trailer "Reviewed-by: C6 E6" \
237 --amend &&
238 commit_body HEAD >actual &&
239 test_cmp expected actual
240 '
241
242 test_expect_success 'commit --trailer with -c and "addIfDifferent" as ifexists' '
243 trailer_commit_base &&
244 cat >expected <<-\EOF &&
245 hello
246
247 Signed-off-by: C O Mitter <committer@example.com>
248 Signed-off-by: C1 E1
249 Helped-by: C2 E2
250 Reported-by: C3 E3
251 Mentored-by: C4 E4
252 Mentored-by: C5 E5
253 EOF
254 git -c trailer.ifexists="addIfDifferent" \
255 commit --trailer "Reported-by: C3 E3" \
256 --trailer "Mentored-by: C5 E5" \
257 --amend &&
258 commit_body HEAD >actual &&
259 test_cmp expected actual
260 '
261
262 test_expect_success 'commit --trailer with -c and "addIfDifferentNeighbor" as ifexists' '
263 trailer_commit_base &&
264 cat >expected <<-\EOF &&
265 hello
266
267 Signed-off-by: C O Mitter <committer@example.com>
268 Signed-off-by: C1 E1
269 Helped-by: C2 E2
270 Reported-by: C3 E3
271 Mentored-by: C4 E4
272 Reported-by: C3 E3
273 EOF
274 git -c trailer.ifexists="addIfDifferentNeighbor" \
275 commit --trailer "Mentored-by: C4 E4" \
276 --trailer "Reported-by: C3 E3" \
277 --amend &&
278 commit_body HEAD >actual &&
279 test_cmp expected actual
280 '
281
282 test_expect_success 'commit --trailer with -c and "end" as where' '
283 trailer_commit_base &&
284 cat >expected <<-\EOF &&
285 hello
286
287 Signed-off-by: C O Mitter <committer@example.com>
288 Signed-off-by: C1 E1
289 Helped-by: C2 E2
290 Reported-by: C3 E3
291 Mentored-by: C4 E4
292 Reported-by: C3 E3
293 Mentored-by: C4 E4
294 EOF
295 git -c trailer.where="end" \
296 commit --trailer "Reported-by: C3 E3" \
297 --trailer "Mentored-by: C4 E4" \
298 --amend &&
299 commit_body HEAD >actual &&
300 test_cmp expected actual
301 '
302
303 test_expect_success 'commit --trailer with -c and "start" as where' '
304 trailer_commit_base &&
305 cat >expected <<-\EOF &&
306 hello
307
308 Signed-off-by: C1 E1
309 Signed-off-by: C O Mitter <committer@example.com>
310 Signed-off-by: C1 E1
311 Helped-by: C2 E2
312 Reported-by: C3 E3
313 Mentored-by: C4 E4
314 EOF
315 git -c trailer.where="start" \
316 commit --trailer "Signed-off-by: C O Mitter <committer@example.com>" \
317 --trailer "Signed-off-by: C1 E1" \
318 --amend &&
319 commit_body HEAD >actual &&
320 test_cmp expected actual
321 '
322
323 test_expect_success 'commit --trailer with -c and "after" as where' '
324 trailer_commit_base &&
325 cat >expected <<-\EOF &&
326 hello
327
328 Signed-off-by: C O Mitter <committer@example.com>
329 Signed-off-by: C1 E1
330 Helped-by: C2 E2
331 Reported-by: C3 E3
332 Mentored-by: C4 E4
333 Mentored-by: C5 E5
334 EOF
335 git -c trailer.where="after" \
336 commit --trailer "Mentored-by: C4 E4" \
337 --trailer "Mentored-by: C5 E5" \
338 --amend &&
339 commit_body HEAD >actual &&
340 test_cmp expected actual
341 '
342
343 test_expect_success 'commit --trailer with -c and "before" as where' '
344 trailer_commit_base &&
345 cat >expected <<-\EOF &&
346 hello
347
348 Signed-off-by: C O Mitter <committer@example.com>
349 Signed-off-by: C1 E1
350 Helped-by: C2 E2
351 Reported-by: C3 E3
352 Mentored-by: C2 E2
353 Mentored-by: C3 E3
354 Mentored-by: C4 E4
355 EOF
356 git -c trailer.where="before" \
357 commit --trailer "Mentored-by: C3 E3" \
358 --trailer "Mentored-by: C2 E2" \
359 --amend &&
360 commit_body HEAD >actual &&
361 test_cmp expected actual
362 '
363
364 test_expect_success 'commit --trailer with -c and "donothing" as ifmissing' '
365 trailer_commit_base &&
366 cat >expected <<-\EOF &&
367 hello
368
369 Signed-off-by: C O Mitter <committer@example.com>
370 Signed-off-by: C1 E1
371 Helped-by: C2 E2
372 Reported-by: C3 E3
373 Mentored-by: C4 E4
374 Helped-by: C5 E5
375 EOF
376 git -c trailer.ifmissing="donothing" \
377 commit --trailer "Helped-by: C5 E5" \
378 --trailer "Based-by: C6 E6" \
379 --amend &&
380 commit_body HEAD >actual &&
381 test_cmp expected actual
382 '
383
384 test_expect_success 'commit --trailer with -c and "add" as ifmissing' '
385 trailer_commit_base &&
386 cat >expected <<-\EOF &&
387 hello
388
389 Signed-off-by: C O Mitter <committer@example.com>
390 Signed-off-by: C1 E1
391 Helped-by: C2 E2
392 Reported-by: C3 E3
393 Mentored-by: C4 E4
394 Helped-by: C5 E5
395 Based-by: C6 E6
396 EOF
397 git -c trailer.ifmissing="add" \
398 commit --trailer "Helped-by: C5 E5" \
399 --trailer "Based-by: C6 E6" \
400 --amend &&
401 commit_body HEAD >actual &&
402 test_cmp expected actual
403 '
404
405 test_expect_success 'commit --trailer with -c ack.key ' '
406 echo "fun" >>file1 &&
407 git add file1 &&
408 cat >expected <<-\EOF &&
409 hello
410
411 Acked-by: Peff
412 EOF
413 git -c trailer.ack.key="Acked-by" \
414 commit --trailer "ack = Peff" -m "hello" &&
415 commit_body HEAD >actual &&
416 test_cmp expected actual
417 '
418
419 test_expect_success 'commit --trailer with -c and ":=#" as separators' '
420 echo "fun" >>file1 &&
421 git add file1 &&
422 cat >expected <<-\EOF &&
423 I hate bug
424
425 Bug #42
426 EOF
427 git -c trailer.separators=":=#" \
428 -c trailer.bug.key="Bug #" \
429 commit --trailer "bug = 42" -m "I hate bug" &&
430 commit_body HEAD >actual &&
431 test_cmp expected actual
432 '
433
434 test_expect_success 'commit --trailer with -c and command' '
435 trailer_commit_base &&
436 cat >expected <<-\EOF &&
437 hello
438
439 Signed-off-by: C O Mitter <committer@example.com>
440 Signed-off-by: C1 E1
441 Helped-by: C2 E2
442 Mentored-by: C4 E4
443 Reported-by: A U Thor <author@example.com>
444 EOF
445 git -c trailer.report.key="Reported-by: " \
446 -c trailer.report.ifexists="replace" \
447 -c trailer.report.command="NAME=\"\$ARG\"; test -n \"\$NAME\" && \
448 git log --author=\"\$NAME\" -1 --format=\"format:%aN <%aE>\" || true" \
449 commit --trailer "report = author" --amend &&
450 commit_body HEAD >actual &&
451 test_cmp expected actual
452 '
453
454 test_expect_success 'commit --trailer not confused by --- separator' '
455 cat >msg <<-\EOF &&
456 subject
457
458 body with dashes
459 ---
460 in it
461 EOF
462 git commit --allow-empty --trailer="my-trailer: value" -F msg &&
463 {
464 cat msg &&
465 echo &&
466 echo "my-trailer: value"
467 } >expected &&
468 commit_body HEAD >actual &&
469 test_cmp expected actual
470 '
471
472 test_expect_success 'commit --trailer with --verbose' '
473 cat >msg <<-\EOF &&
474 subject
475
476 body
477 EOF
478 GIT_EDITOR=: git commit --edit -F msg --allow-empty \
479 --trailer="my-trailer: value" --verbose &&
480 {
481 cat msg &&
482 echo &&
483 echo "my-trailer: value"
484 } >expected &&
485 commit_body HEAD >actual &&
486 test_cmp expected actual
487 '
488
489 test_expect_success 'multiple -m' '
490
491 >negative &&
492 git add negative &&
493 git commit -m "one" -m "two" -m "three" &&
494 actual=$(commit_body HEAD) &&
495 expected=$(test_write_lines "one" "" "two" "" "three") &&
496 test "z$actual" = "z$expected"
497
498 '
499
500 test_expect_success 'verbose' '
501
502 echo minus >negative &&
503 git add negative &&
504 git status -v >raw &&
505 sed -ne "/^diff --git /p" raw >actual &&
506 echo "diff --git a/negative b/negative" >expect &&
507 test_cmp expect actual
508
509 '
510
511 test_expect_success 'verbose respects diff config' '
512
513 test_config diff.noprefix true &&
514 git status -v >actual &&
515 test_grep "diff --git negative negative" actual
516 '
517
518 mesg_with_comment_and_newlines='
519 # text
520
521 '
522
523 test_expect_success 'prepare file with comment line and trailing newlines' '
524 printf "%s" "$mesg_with_comment_and_newlines" >expect
525 '
526
527 test_expect_success 'cleanup commit messages (verbatim option,-t)' '
528
529 echo >>negative &&
530 git commit --cleanup=verbatim --no-status -t expect -a &&
531 commit_body HEAD >actual &&
532 test_cmp expect actual
533
534 '
535
536 test_expect_success 'cleanup commit messages (verbatim option,-F)' '
537
538 echo >>negative &&
539 git commit --cleanup=verbatim -F expect -a &&
540 commit_body HEAD >actual &&
541 test_cmp expect actual
542
543 '
544
545 test_expect_success 'cleanup commit messages (verbatim option,-m)' '
546
547 echo >>negative &&
548 git commit --cleanup=verbatim -m "$mesg_with_comment_and_newlines" -a &&
549 commit_body HEAD >actual &&
550 test_cmp expect actual
551
552 '
553
554 test_expect_success 'cleanup commit messages (whitespace option,-F)' '
555
556 echo >>negative &&
557 test_write_lines "" "# text" "" >text &&
558 echo "# text" >expect &&
559 git commit --cleanup=whitespace -F text -a &&
560 commit_body HEAD >actual &&
561 test_cmp expect actual
562
563 '
564
565 test_expect_success 'cleanup commit messages (scissors option,-F,-e)' '
566
567 echo >>negative &&
568 cat >text <<-\EOF &&
569
570 # to be kept
571
572 # ------------------------ >8 ------------------------
573 # to be kept, too
574 # ------------------------ >8 ------------------------
575 to be removed
576 # ------------------------ >8 ------------------------
577 to be removed, too
578 EOF
579
580 cat >expect <<-\EOF &&
581 # to be kept
582
583 # ------------------------ >8 ------------------------
584 # to be kept, too
585 EOF
586 git commit --cleanup=scissors -e -F text -a &&
587 commit_body HEAD >actual &&
588 test_cmp expect actual
589 '
590
591 test_expect_success 'cleanup commit messages (scissors option,-F,-e, scissors on first line)' '
592
593 echo >>negative &&
594 cat >text <<-\EOF &&
595 # ------------------------ >8 ------------------------
596 to be removed
597 EOF
598 git commit --cleanup=scissors -e -F text -a --allow-empty-message &&
599 commit_body HEAD >actual &&
600 test_must_be_empty actual
601 '
602
603 test_expect_success 'cleanup commit messages (strip option,-F)' '
604
605 echo >>negative &&
606 test_write_lines "" "# text" "sample" "" >text &&
607 echo sample >expect &&
608 git commit --cleanup=strip -F text -a &&
609 commit_body HEAD >actual &&
610 test_cmp expect actual
611
612 '
613
614 test_expect_success 'cleanup commit messages (strip option,-F,-e)' '
615
616 echo >>negative &&
617 test_write_lines "" "sample" "" >text &&
618 git commit -e -F text -a &&
619 head -n 4 .git/COMMIT_EDITMSG >actual
620 '
621
622 echo "sample
623
624 # Please enter the commit message for your changes. Lines starting
625 # with '#' will be ignored, and an empty message aborts the commit." >expect
626
627 test_expect_success 'cleanup commit messages (strip option,-F,-e): output' '
628 test_cmp expect actual
629 '
630
631 test_expect_success 'cleanup commit message (fail on invalid cleanup mode option)' '
632 test_must_fail git commit --cleanup=non-existent
633 '
634
635 test_expect_success 'cleanup commit message (fail on invalid cleanup mode configuration)' '
636 test_must_fail git -c commit.cleanup=non-existent commit
637 '
638
639 test_expect_success 'cleanup commit message (no config and no option uses default)' '
640 echo content >>file &&
641 git add file &&
642 (
643 test_set_editor "$TEST_DIRECTORY"/t7500/add-content-and-comment &&
644 git commit --no-status
645 ) &&
646 commit_msg_is "commit message"
647 '
648
649 test_expect_success 'cleanup commit message (option overrides default)' '
650 echo content >>file &&
651 git add file &&
652 (
653 test_set_editor "$TEST_DIRECTORY"/t7500/add-content-and-comment &&
654 git commit --cleanup=whitespace --no-status
655 ) &&
656 commit_msg_is "commit message # comment"
657 '
658
659 test_expect_success 'cleanup commit message (config overrides default)' '
660 echo content >>file &&
661 git add file &&
662 (
663 test_set_editor "$TEST_DIRECTORY"/t7500/add-content-and-comment &&
664 git -c commit.cleanup=whitespace commit --no-status
665 ) &&
666 commit_msg_is "commit message # comment"
667 '
668
669 test_expect_success 'cleanup commit message (option overrides config)' '
670 echo content >>file &&
671 git add file &&
672 (
673 test_set_editor "$TEST_DIRECTORY"/t7500/add-content-and-comment &&
674 git -c commit.cleanup=whitespace commit --cleanup=default
675 ) &&
676 commit_msg_is "commit message"
677 '
678
679 test_expect_success 'cleanup commit message (default, -m)' '
680 echo content >>file &&
681 git add file &&
682 git commit -m "message #comment " &&
683 commit_msg_is "message #comment"
684 '
685
686 test_expect_success 'cleanup commit message (whitespace option, -m)' '
687 echo content >>file &&
688 git add file &&
689 git commit --cleanup=whitespace --no-status -m "message #comment " &&
690 commit_msg_is "message #comment"
691 '
692
693 test_expect_success 'cleanup commit message (whitespace config, -m)' '
694 echo content >>file &&
695 git add file &&
696 git -c commit.cleanup=whitespace commit --no-status -m "message #comment " &&
697 commit_msg_is "message #comment"
698 '
699
700 test_expect_success 'message shows author when it is not equal to committer' '
701 echo >>negative &&
702 git commit -e -m "sample" -a &&
703 test_grep \
704 "^# Author: *A U Thor <author@example.com>\$" \
705 .git/COMMIT_EDITMSG
706 '
707
708 test_expect_success 'message shows date when it is explicitly set' '
709 git commit --allow-empty -e -m foo --date="2010-01-02T03:04:05" &&
710 test_grep \
711 "^# Date: *Sat Jan 2 03:04:05 2010 +0000" \
712 .git/COMMIT_EDITMSG
713 '
714
715 test_expect_success 'message does not have multiple scissors lines' '
716 git commit --cleanup=scissors -v --allow-empty -e -m foo &&
717 test $(grep -c -e "--- >8 ---" .git/COMMIT_EDITMSG) -eq 1
718 '
719
720 test_expect_success AUTOIDENT 'message shows committer when it is automatic' '
721
722 echo >>negative &&
723 (
724 sane_unset GIT_COMMITTER_EMAIL &&
725 sane_unset GIT_COMMITTER_NAME &&
726 git commit -e -m "sample" -a
727 ) &&
728 # the ident is calculated from the system, so we cannot
729 # check the actual value, only that it is there
730 test_grep "^# Committer: " .git/COMMIT_EDITMSG
731 '
732
733 write_script .git/FAKE_EDITOR <<EOF
734 echo editor started >"$(pwd)/.git/result"
735 exit 0
736 EOF
737
738 test_expect_success !FAIL_PREREQS,!AUTOIDENT 'do not fire editor when committer is bogus' '
739 >.git/result &&
740
741 echo >>negative &&
742 (
743 sane_unset GIT_COMMITTER_EMAIL &&
744 sane_unset GIT_COMMITTER_NAME &&
745 GIT_EDITOR="\"$(pwd)/.git/FAKE_EDITOR\"" &&
746 export GIT_EDITOR &&
747 test_must_fail git commit -e -m sample -a
748 ) &&
749 test_must_be_empty .git/result
750 '
751
752 test_expect_success 'do not fire editor if -m <msg> was given' '
753 echo tick >file &&
754 git add file &&
755 echo "editor not started" >.git/result &&
756 (GIT_EDITOR="\"$(pwd)/.git/FAKE_EDITOR\"" git commit -m tick) &&
757 test "$(cat .git/result)" = "editor not started"
758 '
759
760 test_expect_success 'do not fire editor if -m "" was given' '
761 echo tock >file &&
762 git add file &&
763 echo "editor not started" >.git/result &&
764 (GIT_EDITOR="\"$(pwd)/.git/FAKE_EDITOR\"" \
765 git commit -m "" --allow-empty-message) &&
766 test "$(cat .git/result)" = "editor not started"
767 '
768
769 test_expect_success 'do not fire editor in the presence of conflicts' '
770
771 git clean -f &&
772 echo f >g &&
773 git add g &&
774 git commit -m "add g" &&
775 git branch second &&
776 echo main >g &&
777 echo g >h &&
778 git add g h &&
779 git commit -m "modify g and add h" &&
780 git checkout second &&
781 echo second >g &&
782 git add g &&
783 git commit -m second &&
784 # Must fail due to conflict
785 test_must_fail git cherry-pick -n main &&
786 echo "editor not started" >.git/result &&
787 (
788 GIT_EDITOR="\"$(pwd)/.git/FAKE_EDITOR\"" &&
789 export GIT_EDITOR &&
790 test_must_fail git commit
791 ) &&
792 test "$(cat .git/result)" = "editor not started"
793 '
794
795 write_script .git/FAKE_EDITOR <<EOF
796 # kill -TERM command added below.
797 EOF
798
799 test_expect_success EXECKEEPSPID 'a SIGTERM should break locks' '
800 echo >>negative &&
801 ! "$SHELL_PATH" -c '\''
802 echo kill -TERM $$ >>.git/FAKE_EDITOR
803 GIT_EDITOR=.git/FAKE_EDITOR
804 export GIT_EDITOR
805 exec git commit -a'\'' &&
806 test ! -f .git/index.lock
807 '
808
809 rm -f .git/MERGE_MSG .git/COMMIT_EDITMSG
810 git reset -q --hard
811
812 test_expect_success 'Hand committing of a redundant merge removes dups' '
813
814 git rev-parse second main >expect &&
815 test_must_fail git merge second main &&
816 git checkout main g &&
817 EDITOR=: git commit -a &&
818 git cat-file commit HEAD >raw &&
819 sed -n -e "s/^parent //p" -e "/^$/q" raw >actual &&
820 test_cmp expect actual
821
822 '
823
824 test_expect_success 'A single-liner subject with a token plus colon is not a footer' '
825
826 git reset --hard &&
827 git commit -s -m "hello: kitty" --allow-empty &&
828 commit_body HEAD >actual &&
829 test_line_count = 3 actual
830
831 '
832
833 test_expect_success 'commit -s places sob on third line after two empty lines' '
834 git commit -s --allow-empty --allow-empty-message &&
835 cat <<-EOF >expect &&
836
837
838 Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
839
840 EOF
841 sed -e "/^#/d" -e "s/^:.*//" .git/COMMIT_EDITMSG >actual &&
842 test_cmp expect actual
843 '
844
845 write_script .git/FAKE_EDITOR <<\EOF
846 mv "$1" "$1.orig"
847 (
848 echo message
849 cat "$1.orig"
850 ) >"$1"
851 EOF
852
853 echo '## Custom template' >template
854
855 try_commit () {
856 git reset --hard &&
857 echo >>negative &&
858 GIT_EDITOR=.git/FAKE_EDITOR git commit -a $* $use_template &&
859 case "$use_template" in
860 '')
861 test_grep ! "^## Custom template" .git/COMMIT_EDITMSG ;;
862 *)
863 test_grep "^## Custom template" .git/COMMIT_EDITMSG ;;
864 esac
865 }
866
867 try_commit_status_combo () {
868
869 test_expect_success 'commit' '
870 try_commit "" &&
871 test_grep "^# Changes to be committed:" .git/COMMIT_EDITMSG
872 '
873
874 test_expect_success 'commit --status' '
875 try_commit --status &&
876 test_grep "^# Changes to be committed:" .git/COMMIT_EDITMSG
877 '
878
879 test_expect_success 'commit --no-status' '
880 try_commit --no-status &&
881 test_grep ! "^# Changes to be committed:" .git/COMMIT_EDITMSG
882 '
883
884 test_expect_success 'commit with commit.status = yes' '
885 test_config commit.status yes &&
886 try_commit "" &&
887 test_grep "^# Changes to be committed:" .git/COMMIT_EDITMSG
888 '
889
890 test_expect_success 'commit with commit.status = no' '
891 test_config commit.status no &&
892 try_commit "" &&
893 test_grep ! "^# Changes to be committed:" .git/COMMIT_EDITMSG
894 '
895
896 test_expect_success 'commit --status with commit.status = yes' '
897 test_config commit.status yes &&
898 try_commit --status &&
899 test_grep "^# Changes to be committed:" .git/COMMIT_EDITMSG
900 '
901
902 test_expect_success 'commit --no-status with commit.status = yes' '
903 test_config commit.status yes &&
904 try_commit --no-status &&
905 test_grep ! "^# Changes to be committed:" .git/COMMIT_EDITMSG
906 '
907
908 test_expect_success 'commit --status with commit.status = no' '
909 test_config commit.status no &&
910 try_commit --status &&
911 test_grep "^# Changes to be committed:" .git/COMMIT_EDITMSG
912 '
913
914 test_expect_success 'commit --no-status with commit.status = no' '
915 test_config commit.status no &&
916 try_commit --no-status &&
917 test_grep ! "^# Changes to be committed:" .git/COMMIT_EDITMSG
918 '
919
920 }
921
922 try_commit_status_combo
923
924 use_template="-t template"
925
926 try_commit_status_combo
927
928 test_expect_success 'commit --status with custom comment character' '
929 test_config core.commentchar ";" &&
930 try_commit --status &&
931 test_grep "^; Changes to be committed:" .git/COMMIT_EDITMSG
932 '
933
934 test_expect_success !WITH_BREAKING_CHANGES 'switch core.commentchar' '
935 test_commit "#foo" foo &&
936 cat >config-include <<-\EOF &&
937 [core]
938 commentString=:
939 commentString=%
940 commentChar=auto
941 EOF
942 test_when_finished "rm config-include" &&
943 test_config include.path "$(pwd)/config-include" &&
944 test_config core.commentChar ! &&
945 GIT_EDITOR=.git/FAKE_EDITOR git commit --amend 2>err &&
946 sed -n "s/^hint: *\$//p; s/^hint: //p; s/^warning: //p" err >actual &&
947 cat >expect <<-EOF &&
948 Support for ${SQ}core.commentChar=auto${SQ} is deprecated and will be removed in Git 3.0
949
950 To use the default comment string (#) please run
951
952 git config unset core.commentChar
953 git config unset --file ~/config-include --all core.commentString
954 git config unset --file ~/config-include core.commentChar
955
956 To set a custom comment string please run
957
958 git config set --file ~/config-include core.commentChar <comment string>
959
960 where ${SQ}<comment string>${SQ} is the string you wish to use.
961 EOF
962 test_cmp expect actual &&
963 test_grep "^; Changes to be committed:" .git/COMMIT_EDITMSG
964 '
965
966 test_expect_success !WITH_BREAKING_CHANGES 'switch core.commentchar but out of options' '
967 cat >text <<\EOF &&
968 # 1
969 ; 2
970 @ 3
971 ! 4
972 $ 5
973 % 6
974 ^ 7
975 & 8
976 | 9
977 : 10
978 EOF
979 git commit --amend -F text &&
980 (
981 test_set_editor .git/FAKE_EDITOR &&
982 test_must_fail git -c core.commentChar=auto commit --amend
983 )
984 '
985
986 test_expect_success WITH_BREAKING_CHANGES 'core.commentChar=auto is rejected' '
987 test_config core.commentChar auto &&
988 test_must_fail git rev-parse --git-dir 2>err &&
989 sed -n "s/^hint: *\$//p; s/^hint: //p; s/^fatal: //p" err >actual &&
990 cat >expect <<-EOF &&
991 Support for ${SQ}core.commentChar=auto${SQ} has been removed in Git 3.0
992
993 To use the default comment string (#) please run
994
995 git config unset core.commentChar
996
997 To set a custom comment string please run
998
999 git config set core.commentChar <comment string>
1000
1001 where ${SQ}<comment string>${SQ} is the string you wish to use.
1002 EOF
1003 test_cmp expect actual
1004 '
1005
1006 test_done