t7[5-9]*: adjust the references to the default branch name "main"
[git] / t / t7501-commit-basic-functionality.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2007 Kristian Høgsberg <krh@redhat.com>
4 #
5
6 # FIXME: Test the various index usages, -i and -o, test reflog,
7 # signoff
8
9 test_description='git commit'
10 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
11 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
12
13 . ./test-lib.sh
14 . "$TEST_DIRECTORY/diff-lib.sh"
15
16 author='The Real Author <someguy@his.email.org>'
17
18 test_tick
19
20 test_expect_success 'initial status' '
21         echo bongo bongo >file &&
22         git add file &&
23         git status >actual &&
24         test_i18ngrep "No commits yet" actual
25 '
26
27 test_expect_success 'fail initial amend' '
28         test_must_fail git commit --amend
29 '
30
31 test_expect_success 'setup: initial commit' '
32         git commit -m initial
33 '
34
35 test_expect_success '-m and -F do not mix' '
36         git checkout HEAD file && echo >>file && git add file &&
37         test_must_fail git commit -m foo -m bar -F file
38 '
39
40 test_expect_success '-m and -C do not mix' '
41         git checkout HEAD file && echo >>file && git add file &&
42         test_must_fail git commit -C HEAD -m illegal
43 '
44
45 test_expect_success 'paths and -a do not mix' '
46         echo King of the bongo >file &&
47         test_must_fail git commit -m foo -a file
48 '
49
50 test_expect_success PERL 'can use paths with --interactive' '
51         echo bong-o-bong >file &&
52         # 2: update, 1:st path, that is all, 7: quit
53         test_write_lines 2 1 "" 7 |
54         git commit -m foo --interactive file &&
55         git reset --hard HEAD^
56 '
57
58 test_expect_success 'removed files and relative paths' '
59         test_when_finished "rm -rf foo" &&
60         git init foo &&
61         >foo/foo.txt &&
62         git -C foo add foo.txt &&
63         git -C foo commit -m first &&
64         git -C foo rm foo.txt &&
65
66         mkdir -p foo/bar &&
67         git -C foo/bar commit -m second ../foo.txt
68 '
69
70 test_expect_success 'using invalid commit with -C' '
71         test_must_fail git commit --allow-empty -C bogus
72 '
73
74 test_expect_success 'nothing to commit' '
75         git reset --hard &&
76         test_must_fail git commit -m initial
77 '
78
79 test_expect_success '--dry-run fails with nothing to commit' '
80         test_must_fail git commit -m initial --dry-run
81 '
82
83 test_expect_success '--short fails with nothing to commit' '
84         test_must_fail git commit -m initial --short
85 '
86
87 test_expect_success '--porcelain fails with nothing to commit' '
88         test_must_fail git commit -m initial --porcelain
89 '
90
91 test_expect_success '--long fails with nothing to commit' '
92         test_must_fail git commit -m initial --long
93 '
94
95 test_expect_success 'setup: non-initial commit' '
96         echo bongo bongo bongo >file &&
97         git commit -m next -a
98 '
99
100 test_expect_success '--dry-run with stuff to commit returns ok' '
101         echo bongo bongo bongo >>file &&
102         git commit -m next -a --dry-run
103 '
104
105 test_expect_success '--short with stuff to commit returns ok' '
106         echo bongo bongo bongo >>file &&
107         git commit -m next -a --short
108 '
109
110 test_expect_success '--porcelain with stuff to commit returns ok' '
111         echo bongo bongo bongo >>file &&
112         git commit -m next -a --porcelain
113 '
114
115 test_expect_success '--long with stuff to commit returns ok' '
116         echo bongo bongo bongo >>file &&
117         git commit -m next -a --long
118 '
119
120 test_expect_success 'commit message from non-existing file' '
121         echo more bongo: bongo bongo bongo bongo >file &&
122         test_must_fail git commit -F gah -a
123 '
124
125 test_expect_success 'empty commit message' '
126         # Empty except stray tabs and spaces on a few lines.
127         sed -e "s/@//g" >msg <<-\EOF &&
128                 @               @
129                 @@
130                 @  @
131                 @Signed-off-by: hula@
132         EOF
133         test_must_fail git commit -F msg -a
134 '
135
136 test_expect_success 'template "emptyness" check does not kick in with -F' '
137         git checkout HEAD file && echo >>file && git add file &&
138         git commit -t file -F file
139 '
140
141 test_expect_success 'template "emptyness" check' '
142         git checkout HEAD file && echo >>file && git add file &&
143         test_must_fail git commit -t file 2>err &&
144         test_i18ngrep "did not edit" err
145 '
146
147 test_expect_success 'setup: commit message from file' '
148         git checkout HEAD file && echo >>file && git add file &&
149         echo this is the commit message, coming from a file >msg &&
150         git commit -F msg -a
151 '
152
153 test_expect_success 'amend commit' '
154         cat >editor <<-\EOF &&
155         #!/bin/sh
156         sed -e "s/a file/an amend commit/g" <"$1" >"$1-"
157         mv "$1-" "$1"
158         EOF
159         chmod 755 editor &&
160         EDITOR=./editor git commit --amend
161 '
162
163 test_expect_success 'amend --only ignores staged contents' '
164         cp file file.expect &&
165         echo changed >file &&
166         git add file &&
167         git commit --no-edit --amend --only &&
168         git cat-file blob HEAD:file >file.actual &&
169         test_cmp file.expect file.actual &&
170         git diff --exit-code
171 '
172
173 test_expect_success 'allow-empty --only ignores staged contents' '
174         echo changed-again >file &&
175         git add file &&
176         git commit --allow-empty --only -m "empty" &&
177         git cat-file blob HEAD:file >file.actual &&
178         test_cmp file.expect file.actual &&
179         git diff --exit-code
180 '
181
182 test_expect_success 'set up editor' '
183         cat >editor <<-\EOF &&
184         #!/bin/sh
185         sed -e "s/unamended/amended/g" <"$1" >"$1-"
186         mv "$1-" "$1"
187         EOF
188         chmod 755 editor
189 '
190
191 test_expect_success 'amend without launching editor' '
192         echo unamended >expect &&
193         git commit --allow-empty -m "unamended" &&
194         echo needs more bongo >file &&
195         git add file &&
196         EDITOR=./editor git commit --no-edit --amend &&
197         git diff --exit-code HEAD -- file &&
198         git diff-tree -s --format=%s HEAD >msg &&
199         test_cmp expect msg
200 '
201
202 test_expect_success '--amend --edit' '
203         echo amended >expect &&
204         git commit --allow-empty -m "unamended" &&
205         echo bongo again >file &&
206         git add file &&
207         EDITOR=./editor git commit --edit --amend &&
208         git diff-tree -s --format=%s HEAD >msg &&
209         test_cmp expect msg
210 '
211
212 test_expect_success '--amend --edit of empty message' '
213         cat >replace <<-\EOF &&
214         #!/bin/sh
215         echo "amended" >"$1"
216         EOF
217         chmod 755 replace &&
218         git commit --allow-empty --allow-empty-message -m "" &&
219         echo more bongo >file &&
220         git add file &&
221         EDITOR=./replace git commit --edit --amend &&
222         git diff-tree -s --format=%s HEAD >msg &&
223         ./replace expect &&
224         test_cmp expect msg
225 '
226
227 test_expect_success '--amend to set message to empty' '
228         echo bata >file &&
229         git add file &&
230         git commit -m "unamended" &&
231         git commit --amend --allow-empty-message -m "" &&
232         git diff-tree -s --format=%s HEAD >msg &&
233         echo "" >expect &&
234         test_cmp expect msg
235 '
236
237 test_expect_success '--amend to set empty message needs --allow-empty-message' '
238         echo conga >file &&
239         git add file &&
240         git commit -m "unamended" &&
241         test_must_fail git commit --amend -m "" &&
242         git diff-tree -s --format=%s HEAD >msg &&
243         echo "unamended" >expect &&
244         test_cmp expect msg
245 '
246
247 test_expect_success '-m --edit' '
248         echo amended >expect &&
249         git commit --allow-empty -m buffer &&
250         echo bongo bongo >file &&
251         git add file &&
252         EDITOR=./editor git commit -m unamended --edit &&
253         git diff-tree -s  --format=%s HEAD >msg &&
254         test_cmp expect msg
255 '
256
257 test_expect_success '-m and -F do not mix' '
258         echo enough with the bongos >file &&
259         test_must_fail git commit -F msg -m amending .
260 '
261
262 test_expect_success 'using message from other commit' '
263         git commit -C HEAD^ .
264 '
265
266 test_expect_success 'editing message from other commit' '
267         cat >editor <<-\EOF &&
268         #!/bin/sh
269         sed -e "s/amend/older/g"  <"$1" >"$1-"
270         mv "$1-" "$1"
271         EOF
272         chmod 755 editor &&
273         echo hula hula >file &&
274         EDITOR=./editor git commit -c HEAD^ -a
275 '
276
277 test_expect_success 'message from stdin' '
278         echo silly new contents >file &&
279         echo commit message from stdin |
280         git commit -F - -a
281 '
282
283 test_expect_success 'overriding author from command line' '
284         echo gak >file &&
285         git commit -m author \
286                 --author "Rubber Duck <rduck@convoy.org>" -a >output 2>&1 &&
287         grep Rubber.Duck output
288 '
289
290 test_expect_success PERL 'interactive add' '
291         echo 7 | test_must_fail git commit --interactive >out &&
292         grep "What now" out
293 '
294
295 test_expect_success PERL "commit --interactive doesn't change index if editor aborts" '
296         echo zoo >file &&
297         test_must_fail git diff --exit-code >diff1 &&
298         test_write_lines u "*" q |
299         (
300                 EDITOR=: &&
301                 export EDITOR &&
302                 test_must_fail git commit --interactive
303         ) &&
304         git diff >diff2 &&
305         compare_diff_patch diff1 diff2
306 '
307
308 test_expect_success 'editor not invoked if -F is given' '
309         cat >editor <<-\EOF &&
310         #!/bin/sh
311         sed -e s/good/bad/g <"$1" >"$1-"
312         mv "$1-" "$1"
313         EOF
314         chmod 755 editor &&
315
316         echo A good commit message. >msg &&
317         echo moo >file &&
318
319         EDITOR=./editor git commit -a -F msg &&
320         git show -s --pretty=format:%s >subject &&
321         grep -q good subject &&
322
323         echo quack >file &&
324         echo Another good message. |
325         EDITOR=./editor git commit -a -F - &&
326         git show -s --pretty=format:%s >subject &&
327         grep -q good subject
328 '
329
330 test_expect_success 'partial commit that involves removal (1)' '
331
332         git rm --cached file &&
333         mv file elif &&
334         git add elif &&
335         git commit -m "Partial: add elif" elif &&
336         git diff-tree --name-status HEAD^ HEAD >current &&
337         echo "A elif" >expected &&
338         test_cmp expected current
339
340 '
341
342 test_expect_success 'partial commit that involves removal (2)' '
343
344         git commit -m "Partial: remove file" file &&
345         git diff-tree --name-status HEAD^ HEAD >current &&
346         echo "D file" >expected &&
347         test_cmp expected current
348
349 '
350
351 test_expect_success 'partial commit that involves removal (3)' '
352
353         git rm --cached elif &&
354         echo elif >elif &&
355         git commit -m "Partial: modify elif" elif &&
356         git diff-tree --name-status HEAD^ HEAD >current &&
357         echo "M elif" >expected &&
358         test_cmp expected current
359
360 '
361
362 test_expect_success 'amend commit to fix author' '
363
364         oldtick=$GIT_AUTHOR_DATE &&
365         test_tick &&
366         git reset --hard &&
367         git cat-file -p HEAD >commit &&
368         sed -e "s/author.*/author $author $oldtick/" \
369                 -e "s/^\(committer.*> \).*$/\1$GIT_COMMITTER_DATE/" \
370                 commit >expected &&
371         git commit --amend --author="$author" &&
372         git cat-file -p HEAD >current &&
373         test_cmp expected current
374
375 '
376
377 test_expect_success 'amend commit to fix date' '
378
379         test_tick &&
380         newtick=$GIT_AUTHOR_DATE &&
381         git reset --hard &&
382         git cat-file -p HEAD >commit &&
383         sed -e "s/author.*/author $author $newtick/" \
384                 -e "s/^\(committer.*> \).*$/\1$GIT_COMMITTER_DATE/" \
385                 commit >expected &&
386         git commit --amend --date="$newtick" &&
387         git cat-file -p HEAD >current &&
388         test_cmp expected current
389
390 '
391
392 test_expect_success 'commit mentions forced date in output' '
393         git commit --amend --date=2010-01-02T03:04:05 >output &&
394         grep "Date: *Sat Jan 2 03:04:05 2010" output
395 '
396
397 test_expect_success 'commit complains about completely bogus dates' '
398         test_must_fail git commit --amend --date=seventeen
399 '
400
401 test_expect_success 'commit --date allows approxidate' '
402         git commit --amend \
403                 --date="midnight the 12th of october, anno domini 1979" &&
404         echo "Fri Oct 12 00:00:00 1979 +0000" >expect &&
405         git log -1 --format=%ad >actual &&
406         test_cmp expect actual
407 '
408
409 test_expect_success 'sign off (1)' '
410
411         echo 1 >positive &&
412         git add positive &&
413         git commit -s -m "thank you" &&
414         git cat-file commit HEAD >commit &&
415         sed -e "1,/^\$/d" commit >actual &&
416         (
417                 echo thank you &&
418                 echo &&
419                 git var GIT_COMMITTER_IDENT >ident &&
420                 sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /" ident
421         ) >expected &&
422         test_cmp expected actual
423
424 '
425
426 test_expect_success 'sign off (2)' '
427
428         echo 2 >positive &&
429         git add positive &&
430         existing="Signed-off-by: Watch This <watchthis@example.com>" &&
431         git commit -s -m "thank you
432
433 $existing" &&
434         git cat-file commit HEAD >commit &&
435         sed -e "1,/^\$/d" commit >actual &&
436         (
437                 echo thank you &&
438                 echo &&
439                 echo $existing &&
440                 git var GIT_COMMITTER_IDENT >ident &&
441                 sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /" ident
442         ) >expected &&
443         test_cmp expected actual
444
445 '
446
447 test_expect_success 'signoff gap' '
448
449         echo 3 >positive &&
450         git add positive &&
451         alt="Alt-RFC-822-Header: Value" &&
452         git commit -s -m "welcome
453
454 $alt" &&
455         git cat-file commit HEAD >commit &&
456         sed -e "1,/^\$/d" commit >actual &&
457         (
458                 echo welcome &&
459                 echo &&
460                 echo $alt &&
461                 git var GIT_COMMITTER_IDENT >ident &&
462                 sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /" ident
463         ) >expected &&
464         test_cmp expected actual
465 '
466
467 test_expect_success 'signoff gap 2' '
468
469         echo 4 >positive &&
470         git add positive &&
471         alt="fixed: 34" &&
472         git commit -s -m "welcome
473
474 We have now
475 $alt" &&
476         git cat-file commit HEAD >commit &&
477         sed -e "1,/^\$/d" commit >actual &&
478         (
479                 echo welcome &&
480                 echo &&
481                 echo We have now &&
482                 echo $alt &&
483                 echo &&
484                 git var GIT_COMMITTER_IDENT >ident &&
485                 sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /" ident
486         ) >expected &&
487         test_cmp expected actual
488 '
489
490 test_expect_success 'signoff respects trailer config' '
491
492         echo 5 >positive &&
493         git add positive &&
494         git commit -s -m "subject
495
496 non-trailer line
497 Myfooter: x" &&
498         git cat-file commit HEAD >commit &&
499         sed -e "1,/^\$/d" commit >actual &&
500         (
501                 echo subject &&
502                 echo &&
503                 echo non-trailer line &&
504                 echo Myfooter: x &&
505                 echo &&
506                 echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
507         ) >expected &&
508         test_cmp expected actual &&
509
510         echo 6 >positive &&
511         git add positive &&
512         git -c "trailer.Myfooter.ifexists=add" commit -s -m "subject
513
514 non-trailer line
515 Myfooter: x" &&
516         git cat-file commit HEAD >commit &&
517         sed -e "1,/^\$/d" commit >actual &&
518         (
519                 echo subject &&
520                 echo &&
521                 echo non-trailer line &&
522                 echo Myfooter: x &&
523                 echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
524         ) >expected &&
525         test_cmp expected actual
526 '
527
528 test_expect_success 'signoff not confused by ---' '
529         cat >expected <<-EOF &&
530                 subject
531
532                 body
533                 ---
534                 these dashes confuse the parser!
535
536                 Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
537         EOF
538         # should be a noop, since we already signed
539         git commit --allow-empty --signoff -F expected &&
540         git log -1 --pretty=format:%B >actual &&
541         test_cmp expected actual
542 '
543
544 test_expect_success 'multiple -m' '
545
546         >negative &&
547         git add negative &&
548         git commit -m "one" -m "two" -m "three" &&
549         git cat-file commit HEAD >commit &&
550         sed -e "1,/^\$/d" commit >actual &&
551         (
552                 echo one &&
553                 echo &&
554                 echo two &&
555                 echo &&
556                 echo three
557         ) >expected &&
558         test_cmp expected actual
559
560 '
561
562 test_expect_success 'amend commit to fix author' '
563
564         oldtick=$GIT_AUTHOR_DATE &&
565         test_tick &&
566         git reset --hard &&
567         git cat-file -p HEAD >commit &&
568         sed -e "s/author.*/author $author $oldtick/" \
569                 -e "s/^\(committer.*> \).*$/\1$GIT_COMMITTER_DATE/" \
570                 commit >expected &&
571         git commit --amend --author="$author" &&
572         git cat-file -p HEAD >current &&
573         test_cmp expected current
574
575 '
576
577 test_expect_success 'git commit <file> with dirty index' '
578         echo tacocat >elif &&
579         echo tehlulz >chz &&
580         git add chz &&
581         git commit elif -m "tacocat is a palindrome" &&
582         git show --stat >stat &&
583         grep elif stat &&
584         git diff --cached >diff &&
585         grep chz diff
586 '
587
588 test_expect_success 'same tree (single parent)' '
589
590         git reset --hard &&
591         test_must_fail git commit -m empty
592
593 '
594
595 test_expect_success 'same tree (single parent) --allow-empty' '
596
597         git commit --allow-empty -m "forced empty" &&
598         git cat-file commit HEAD >commit &&
599         grep forced commit
600
601 '
602
603 test_expect_success 'same tree (merge and amend merge)' '
604
605         git checkout -b side HEAD^ &&
606         echo zero >zero &&
607         git add zero &&
608         git commit -m "add zero" &&
609         git checkout main &&
610
611         git merge -s ours side -m "empty ok" &&
612         git diff HEAD^ HEAD >actual &&
613         test_must_be_empty actual &&
614
615         git commit --amend -m "empty really ok" &&
616         git diff HEAD^ HEAD >actual &&
617         test_must_be_empty actual
618
619 '
620
621 test_expect_success 'amend using the message from another commit' '
622
623         git reset --hard &&
624         test_tick &&
625         git commit --allow-empty -m "old commit" &&
626         old=$(git rev-parse --verify HEAD) &&
627         test_tick &&
628         git commit --allow-empty -m "new commit" &&
629         new=$(git rev-parse --verify HEAD) &&
630         test_tick &&
631         git commit --allow-empty --amend -C "$old" &&
632         git show --pretty="format:%ad %s" "$old" >expected &&
633         git show --pretty="format:%ad %s" HEAD >actual &&
634         test_cmp expected actual
635
636 '
637
638 test_expect_success 'amend using the message from a commit named with tag' '
639
640         git reset --hard &&
641         test_tick &&
642         git commit --allow-empty -m "old commit" &&
643         old=$(git rev-parse --verify HEAD) &&
644         git tag -a -m "tag on old" tagged-old HEAD &&
645         test_tick &&
646         git commit --allow-empty -m "new commit" &&
647         new=$(git rev-parse --verify HEAD) &&
648         test_tick &&
649         git commit --allow-empty --amend -C tagged-old &&
650         git show --pretty="format:%ad %s" "$old" >expected &&
651         git show --pretty="format:%ad %s" HEAD >actual &&
652         test_cmp expected actual
653
654 '
655
656 test_expect_success 'amend can copy notes' '
657
658         git config notes.rewrite.amend true &&
659         git config notes.rewriteRef "refs/notes/*" &&
660         test_commit foo &&
661         git notes add -m"a note" &&
662         test_tick &&
663         git commit --amend -m"new foo" &&
664         test "$(git notes show)" = "a note"
665
666 '
667
668 test_expect_success 'commit a file whose name is a dash' '
669         git reset --hard &&
670         for i in 1 2 3 4 5
671         do
672                 echo $i
673         done >./- &&
674         git add ./- &&
675         test_tick &&
676         git commit -m "add dash" >output </dev/null &&
677         test_i18ngrep " changed, 5 insertions" output
678 '
679
680 test_expect_success '--only works on to-be-born branch' '
681         # This test relies on having something in the index, as it
682         # would not otherwise actually prove much.  So check this.
683         test -n "$(git ls-files)" &&
684         git checkout --orphan orphan &&
685         echo foo >newfile &&
686         git add newfile &&
687         git commit --only newfile -m"--only on unborn branch" &&
688         echo newfile >expected &&
689         git ls-tree -r --name-only HEAD >actual &&
690         test_cmp expected actual
691 '
692
693 test_expect_success '--dry-run with conflicts fixed from a merge' '
694         # setup two branches with conflicting information
695         # in the same file, resolve the conflict,
696         # call commit with --dry-run
697         echo "Initial contents, unimportant" >test-file &&
698         git add test-file &&
699         git commit -m "Initial commit" &&
700         echo "commit-1-state" >test-file &&
701         git commit -m "commit 1" -i test-file &&
702         git tag commit-1 &&
703         git checkout -b branch-2 HEAD^1 &&
704         echo "commit-2-state" >test-file &&
705         git commit -m "commit 2" -i test-file &&
706         test_must_fail git merge --no-commit commit-1 &&
707         echo "commit-2-state" >test-file &&
708         git add test-file &&
709         git commit --dry-run &&
710         git commit -m "conflicts fixed from merge."
711 '
712
713 test_expect_success '--dry-run --short' '
714         >test-file &&
715         git add test-file &&
716         git commit --dry-run --short
717 '
718
719 test_done