Allow edit of empty message with commit --amend
[git] / t / t7501-commit.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 . ./test-lib.sh
11 . "$TEST_DIRECTORY/diff-lib.sh"
12
13 author='The Real Author <someguy@his.email.org>'
14
15 test_tick
16
17 test_expect_success 'initial status' '
18         echo bongo bongo >file &&
19         git add file &&
20         git status >actual &&
21         test_i18ngrep "Initial commit" actual
22 '
23
24 test_expect_success 'fail initial amend' '
25         test_must_fail git commit --amend
26 '
27
28 test_expect_success 'setup: initial commit' '
29         git commit -m initial
30 '
31
32 test_expect_success '-m and -F do not mix' '
33         test_must_fail git commit -m foo -m bar -F file
34 '
35
36 test_expect_success '-m and -C do not mix' '
37         test_must_fail git commit -C HEAD -m illegal
38 '
39
40 test_expect_success 'paths and -a do not mix' '
41         echo King of the bongo >file &&
42         test_must_fail git commit -m foo -a file
43 '
44
45 test_expect_success PERL 'can use paths with --interactive' '
46         echo bong-o-bong >file &&
47         # 2: update, 1:st path, that is all, 7: quit
48         ( echo 2; echo 1; echo; echo 7 ) |
49         git commit -m foo --interactive file &&
50         git reset --hard HEAD^
51 '
52
53 test_expect_success 'using invalid commit with -C' '
54         test_must_fail git commit -C bogus
55 '
56
57 test_expect_success 'nothing to commit' '
58         test_must_fail git commit -m initial
59 '
60
61 test_expect_success 'setup: non-initial commit' '
62         echo bongo bongo bongo >file &&
63         git commit -m next -a
64 '
65
66 test_expect_success 'commit message from non-existing file' '
67         echo more bongo: bongo bongo bongo bongo >file &&
68         test_must_fail git commit -F gah -a
69 '
70
71 test_expect_success 'empty commit message' '
72         # Empty except stray tabs and spaces on a few lines.
73         sed -e "s/@//g" >msg <<-\EOF &&
74                 @               @
75                 @@
76                 @  @
77                 @Signed-off-by: hula@
78         EOF
79         test_must_fail git commit -F msg -a
80 '
81
82 test_expect_success 'setup: commit message from file' '
83         echo this is the commit message, coming from a file >msg &&
84         git commit -F msg -a
85 '
86
87 test_expect_success 'amend commit' '
88         cat >editor <<-\EOF &&
89         #!/bin/sh
90         sed -e "s/a file/an amend commit/g" < "$1" > "$1-"
91         mv "$1-" "$1"
92         EOF
93         chmod 755 editor &&
94         EDITOR=./editor git commit --amend
95 '
96
97 test_expect_success 'set up editor' '
98         cat >editor <<-\EOF &&
99         #!/bin/sh
100         sed -e "s/unamended/amended/g" <"$1" >"$1-"
101         mv "$1-" "$1"
102         EOF
103         chmod 755 editor
104 '
105
106 test_expect_success 'amend without launching editor' '
107         echo unamended >expect &&
108         git commit --allow-empty -m "unamended" &&
109         echo needs more bongo >file &&
110         git add file &&
111         EDITOR=./editor git commit --no-edit --amend &&
112         git diff --exit-code HEAD -- file &&
113         git diff-tree -s --format=%s HEAD >msg &&
114         test_cmp expect msg
115 '
116
117 test_expect_success '--amend --edit' '
118         echo amended >expect &&
119         git commit --allow-empty -m "unamended" &&
120         echo bongo again >file &&
121         git add file &&
122         EDITOR=./editor git commit --edit --amend &&
123         git diff-tree -s --format=%s HEAD >msg &&
124         test_cmp expect msg
125 '
126
127 test_expect_success '--amend --edit of empty message' '
128         cat >replace <<-\EOF &&
129         #!/bin/sh
130         echo "amended" >"$1"
131         EOF
132         chmod 755 replace &&
133         git commit --allow-empty --allow-empty-message -m "" &&
134         echo more bongo >file &&
135         git add file &&
136         EDITOR=./replace git commit --edit --amend &&
137         git diff-tree -s --format=%s HEAD >msg &&
138         ./replace expect &&
139         test_cmp expect msg
140 '
141
142 test_expect_success '-m --edit' '
143         echo amended >expect &&
144         git commit --allow-empty -m buffer &&
145         echo bongo bongo >file &&
146         git add file &&
147         EDITOR=./editor git commit -m unamended --edit &&
148         git diff-tree -s  --format=%s HEAD >msg &&
149         test_cmp expect msg
150 '
151
152 test_expect_success '-m and -F do not mix' '
153         echo enough with the bongos >file &&
154         test_must_fail git commit -F msg -m amending .
155 '
156
157 test_expect_success 'using message from other commit' '
158         git commit -C HEAD^ .
159 '
160
161 test_expect_success 'editing message from other commit' '
162         cat >editor <<-\EOF &&
163         #!/bin/sh
164         sed -e "s/amend/older/g"  < "$1" > "$1-"
165         mv "$1-" "$1"
166         EOF
167         chmod 755 editor &&
168         echo hula hula >file &&
169         EDITOR=./editor git commit -c HEAD^ -a
170 '
171
172 test_expect_success 'message from stdin' '
173         echo silly new contents >file &&
174         echo commit message from stdin |
175         git commit -F - -a
176 '
177
178 test_expect_success 'overriding author from command line' '
179         echo gak >file &&
180         git commit -m author \
181                 --author "Rubber Duck <rduck@convoy.org>" -a >output 2>&1 &&
182         grep Rubber.Duck output
183 '
184
185 test_expect_success PERL 'interactive add' '
186         echo 7 |
187         git commit --interactive |
188         grep "What now"
189 '
190
191 test_expect_success PERL "commit --interactive doesn't change index if editor aborts" '
192         echo zoo >file &&
193         test_must_fail git diff --exit-code >diff1 &&
194         (echo u ; echo "*" ; echo q) |
195         (
196                 EDITOR=: &&
197                 export EDITOR &&
198                 test_must_fail git commit --interactive
199         ) &&
200         git diff >diff2 &&
201         compare_diff_patch diff1 diff2
202 '
203
204 test_expect_success 'editor not invoked if -F is given' '
205         cat >editor <<-\EOF &&
206         #!/bin/sh
207         sed -e s/good/bad/g <"$1" >"$1-"
208         mv "$1-" "$1"
209         EOF
210         chmod 755 editor &&
211
212         echo A good commit message. >msg &&
213         echo moo >file &&
214
215         EDITOR=./editor git commit -a -F msg &&
216         git show -s --pretty=format:%s >subject &&
217         grep -q good subject &&
218
219         echo quack >file &&
220         echo Another good message. |
221         EDITOR=./editor git commit -a -F - &&
222         git show -s --pretty=format:%s >subject &&
223         grep -q good subject
224 '
225
226 test_expect_success 'partial commit that involves removal (1)' '
227
228         git rm --cached file &&
229         mv file elif &&
230         git add elif &&
231         git commit -m "Partial: add elif" elif &&
232         git diff-tree --name-status HEAD^ HEAD >current &&
233         echo "A elif" >expected &&
234         test_cmp expected current
235
236 '
237
238 test_expect_success 'partial commit that involves removal (2)' '
239
240         git commit -m "Partial: remove file" file &&
241         git diff-tree --name-status HEAD^ HEAD >current &&
242         echo "D file" >expected &&
243         test_cmp expected current
244
245 '
246
247 test_expect_success 'partial commit that involves removal (3)' '
248
249         git rm --cached elif &&
250         echo elif >elif &&
251         git commit -m "Partial: modify elif" elif &&
252         git diff-tree --name-status HEAD^ HEAD >current &&
253         echo "M elif" >expected &&
254         test_cmp expected current
255
256 '
257
258 test_expect_success 'amend commit to fix author' '
259
260         oldtick=$GIT_AUTHOR_DATE &&
261         test_tick &&
262         git reset --hard &&
263         git cat-file -p HEAD |
264         sed -e "s/author.*/author $author $oldtick/" \
265                 -e "s/^\(committer.*> \).*$/\1$GIT_COMMITTER_DATE/" > \
266                 expected &&
267         git commit --amend --author="$author" &&
268         git cat-file -p HEAD > current &&
269         test_cmp expected current
270
271 '
272
273 test_expect_success 'amend commit to fix date' '
274
275         test_tick &&
276         newtick=$GIT_AUTHOR_DATE &&
277         git reset --hard &&
278         git cat-file -p HEAD |
279         sed -e "s/author.*/author $author $newtick/" \
280                 -e "s/^\(committer.*> \).*$/\1$GIT_COMMITTER_DATE/" > \
281                 expected &&
282         git commit --amend --date="$newtick" &&
283         git cat-file -p HEAD > current &&
284         test_cmp expected current
285
286 '
287
288 test_expect_success 'commit complains about bogus date' '
289         test_must_fail git commit --amend --date=10.11.2010
290 '
291
292 test_expect_success 'sign off (1)' '
293
294         echo 1 >positive &&
295         git add positive &&
296         git commit -s -m "thank you" &&
297         git cat-file commit HEAD | sed -e "1,/^\$/d" >actual &&
298         (
299                 echo thank you
300                 echo
301                 git var GIT_COMMITTER_IDENT |
302                 sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /"
303         ) >expected &&
304         test_cmp expected actual
305
306 '
307
308 test_expect_success 'sign off (2)' '
309
310         echo 2 >positive &&
311         git add positive &&
312         existing="Signed-off-by: Watch This <watchthis@example.com>" &&
313         git commit -s -m "thank you
314
315 $existing" &&
316         git cat-file commit HEAD | sed -e "1,/^\$/d" >actual &&
317         (
318                 echo thank you
319                 echo
320                 echo $existing
321                 git var GIT_COMMITTER_IDENT |
322                 sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /"
323         ) >expected &&
324         test_cmp expected actual
325
326 '
327
328 test_expect_success 'signoff gap' '
329
330         echo 3 >positive &&
331         git add positive &&
332         alt="Alt-RFC-822-Header: Value" &&
333         git commit -s -m "welcome
334
335 $alt" &&
336         git cat-file commit HEAD | sed -e "1,/^\$/d" > actual &&
337         (
338                 echo welcome
339                 echo
340                 echo $alt
341                 git var GIT_COMMITTER_IDENT |
342                 sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /"
343         ) >expected &&
344         test_cmp expected actual
345 '
346
347 test_expect_success 'signoff gap 2' '
348
349         echo 4 >positive &&
350         git add positive &&
351         alt="fixed: 34" &&
352         git commit -s -m "welcome
353
354 We have now
355 $alt" &&
356         git cat-file commit HEAD | sed -e "1,/^\$/d" > actual &&
357         (
358                 echo welcome
359                 echo
360                 echo We have now
361                 echo $alt
362                 echo
363                 git var GIT_COMMITTER_IDENT |
364                 sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /"
365         ) >expected &&
366         test_cmp expected actual
367 '
368
369 test_expect_success 'multiple -m' '
370
371         >negative &&
372         git add negative &&
373         git commit -m "one" -m "two" -m "three" &&
374         git cat-file commit HEAD | sed -e "1,/^\$/d" >actual &&
375         (
376                 echo one
377                 echo
378                 echo two
379                 echo
380                 echo three
381         ) >expected &&
382         test_cmp expected actual
383
384 '
385
386 test_expect_success 'amend commit to fix author' '
387
388         oldtick=$GIT_AUTHOR_DATE &&
389         test_tick &&
390         git reset --hard &&
391         git cat-file -p HEAD |
392         sed -e "s/author.*/author $author $oldtick/" \
393                 -e "s/^\(committer.*> \).*$/\1$GIT_COMMITTER_DATE/" > \
394                 expected &&
395         git commit --amend --author="$author" &&
396         git cat-file -p HEAD > current &&
397         test_cmp expected current
398
399 '
400
401 test_expect_success 'git commit <file> with dirty index' '
402         echo tacocat > elif &&
403         echo tehlulz > chz &&
404         git add chz &&
405         git commit elif -m "tacocat is a palindrome" &&
406         git show --stat | grep elif &&
407         git diff --cached | grep chz
408 '
409
410 test_expect_success 'same tree (single parent)' '
411
412         git reset --hard &&
413         test_must_fail git commit -m empty
414
415 '
416
417 test_expect_success 'same tree (single parent) --allow-empty' '
418
419         git commit --allow-empty -m "forced empty" &&
420         git cat-file commit HEAD | grep forced
421
422 '
423
424 test_expect_success 'same tree (merge and amend merge)' '
425
426         git checkout -b side HEAD^ &&
427         echo zero >zero &&
428         git add zero &&
429         git commit -m "add zero" &&
430         git checkout master &&
431
432         git merge -s ours side -m "empty ok" &&
433         git diff HEAD^ HEAD >actual &&
434         : >expected &&
435         test_cmp expected actual &&
436
437         git commit --amend -m "empty really ok" &&
438         git diff HEAD^ HEAD >actual &&
439         : >expected &&
440         test_cmp expected actual
441
442 '
443
444 test_expect_success 'amend using the message from another commit' '
445
446         git reset --hard &&
447         test_tick &&
448         git commit --allow-empty -m "old commit" &&
449         old=$(git rev-parse --verify HEAD) &&
450         test_tick &&
451         git commit --allow-empty -m "new commit" &&
452         new=$(git rev-parse --verify HEAD) &&
453         test_tick &&
454         git commit --allow-empty --amend -C "$old" &&
455         git show --pretty="format:%ad %s" "$old" >expected &&
456         git show --pretty="format:%ad %s" HEAD >actual &&
457         test_cmp expected actual
458
459 '
460
461 test_expect_success 'amend using the message from a commit named with tag' '
462
463         git reset --hard &&
464         test_tick &&
465         git commit --allow-empty -m "old commit" &&
466         old=$(git rev-parse --verify HEAD) &&
467         git tag -a -m "tag on old" tagged-old HEAD &&
468         test_tick &&
469         git commit --allow-empty -m "new commit" &&
470         new=$(git rev-parse --verify HEAD) &&
471         test_tick &&
472         git commit --allow-empty --amend -C tagged-old &&
473         git show --pretty="format:%ad %s" "$old" >expected &&
474         git show --pretty="format:%ad %s" HEAD >actual &&
475         test_cmp expected actual
476
477 '
478
479 test_expect_success 'amend can copy notes' '
480
481         git config notes.rewrite.amend true &&
482         git config notes.rewriteRef "refs/notes/*" &&
483         test_commit foo &&
484         git notes add -m"a note" &&
485         test_tick &&
486         git commit --amend -m"new foo" &&
487         test "$(git notes show)" = "a note"
488
489 '
490
491 test_done