Merge branch 'cn/maint-branch-with-bad' into maint
[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 '-m --edit' '
128         echo amended >expect &&
129         git commit --allow-empty -m buffer &&
130         echo bongo bongo >file &&
131         git add file &&
132         EDITOR=./editor git commit -m unamended --edit &&
133         git diff-tree -s  --format=%s HEAD >msg &&
134         test_cmp expect msg
135 '
136
137 test_expect_success '-m and -F do not mix' '
138         echo enough with the bongos >file &&
139         test_must_fail git commit -F msg -m amending .
140 '
141
142 test_expect_success 'using message from other commit' '
143         git commit -C HEAD^ .
144 '
145
146 test_expect_success 'editing message from other commit' '
147         cat >editor <<-\EOF &&
148         #!/bin/sh
149         sed -e "s/amend/older/g"  < "$1" > "$1-"
150         mv "$1-" "$1"
151         EOF
152         chmod 755 editor &&
153         echo hula hula >file &&
154         EDITOR=./editor git commit -c HEAD^ -a
155 '
156
157 test_expect_success 'message from stdin' '
158         echo silly new contents >file &&
159         echo commit message from stdin |
160         git commit -F - -a
161 '
162
163 test_expect_success 'overriding author from command line' '
164         echo gak >file &&
165         git commit -m author \
166                 --author "Rubber Duck <rduck@convoy.org>" -a >output 2>&1 &&
167         grep Rubber.Duck output
168 '
169
170 test_expect_success PERL 'interactive add' '
171         echo 7 |
172         git commit --interactive |
173         grep "What now"
174 '
175
176 test_expect_success PERL "commit --interactive doesn't change index if editor aborts" '
177         echo zoo >file &&
178         test_must_fail git diff --exit-code >diff1 &&
179         (echo u ; echo "*" ; echo q) |
180         (
181                 EDITOR=: &&
182                 export EDITOR &&
183                 test_must_fail git commit --interactive
184         ) &&
185         git diff >diff2 &&
186         compare_diff_patch diff1 diff2
187 '
188
189 test_expect_success 'editor not invoked if -F is given' '
190         cat >editor <<-\EOF &&
191         #!/bin/sh
192         sed -e s/good/bad/g <"$1" >"$1-"
193         mv "$1-" "$1"
194         EOF
195         chmod 755 editor &&
196
197         echo A good commit message. >msg &&
198         echo moo >file &&
199
200         EDITOR=./editor git commit -a -F msg &&
201         git show -s --pretty=format:%s >subject &&
202         grep -q good subject &&
203
204         echo quack >file &&
205         echo Another good message. |
206         EDITOR=./editor git commit -a -F - &&
207         git show -s --pretty=format:%s >subject &&
208         grep -q good subject
209 '
210
211 test_expect_success 'partial commit that involves removal (1)' '
212
213         git rm --cached file &&
214         mv file elif &&
215         git add elif &&
216         git commit -m "Partial: add elif" elif &&
217         git diff-tree --name-status HEAD^ HEAD >current &&
218         echo "A elif" >expected &&
219         test_cmp expected current
220
221 '
222
223 test_expect_success 'partial commit that involves removal (2)' '
224
225         git commit -m "Partial: remove file" file &&
226         git diff-tree --name-status HEAD^ HEAD >current &&
227         echo "D file" >expected &&
228         test_cmp expected current
229
230 '
231
232 test_expect_success 'partial commit that involves removal (3)' '
233
234         git rm --cached elif &&
235         echo elif >elif &&
236         git commit -m "Partial: modify elif" elif &&
237         git diff-tree --name-status HEAD^ HEAD >current &&
238         echo "M elif" >expected &&
239         test_cmp expected current
240
241 '
242
243 test_expect_success 'amend commit to fix author' '
244
245         oldtick=$GIT_AUTHOR_DATE &&
246         test_tick &&
247         git reset --hard &&
248         git cat-file -p HEAD |
249         sed -e "s/author.*/author $author $oldtick/" \
250                 -e "s/^\(committer.*> \).*$/\1$GIT_COMMITTER_DATE/" > \
251                 expected &&
252         git commit --amend --author="$author" &&
253         git cat-file -p HEAD > current &&
254         test_cmp expected current
255
256 '
257
258 test_expect_success 'amend commit to fix date' '
259
260         test_tick &&
261         newtick=$GIT_AUTHOR_DATE &&
262         git reset --hard &&
263         git cat-file -p HEAD |
264         sed -e "s/author.*/author $author $newtick/" \
265                 -e "s/^\(committer.*> \).*$/\1$GIT_COMMITTER_DATE/" > \
266                 expected &&
267         git commit --amend --date="$newtick" &&
268         git cat-file -p HEAD > current &&
269         test_cmp expected current
270
271 '
272
273 test_expect_success 'commit complains about bogus date' '
274         test_must_fail git commit --amend --date=10.11.2010
275 '
276
277 test_expect_success 'sign off (1)' '
278
279         echo 1 >positive &&
280         git add positive &&
281         git commit -s -m "thank you" &&
282         git cat-file commit HEAD | sed -e "1,/^\$/d" >actual &&
283         (
284                 echo thank you
285                 echo
286                 git var GIT_COMMITTER_IDENT |
287                 sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /"
288         ) >expected &&
289         test_cmp expected actual
290
291 '
292
293 test_expect_success 'sign off (2)' '
294
295         echo 2 >positive &&
296         git add positive &&
297         existing="Signed-off-by: Watch This <watchthis@example.com>" &&
298         git commit -s -m "thank you
299
300 $existing" &&
301         git cat-file commit HEAD | sed -e "1,/^\$/d" >actual &&
302         (
303                 echo thank you
304                 echo
305                 echo $existing
306                 git var GIT_COMMITTER_IDENT |
307                 sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /"
308         ) >expected &&
309         test_cmp expected actual
310
311 '
312
313 test_expect_success 'signoff gap' '
314
315         echo 3 >positive &&
316         git add positive &&
317         alt="Alt-RFC-822-Header: Value" &&
318         git commit -s -m "welcome
319
320 $alt" &&
321         git cat-file commit HEAD | sed -e "1,/^\$/d" > actual &&
322         (
323                 echo welcome
324                 echo
325                 echo $alt
326                 git var GIT_COMMITTER_IDENT |
327                 sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /"
328         ) >expected &&
329         test_cmp expected actual
330 '
331
332 test_expect_success 'signoff gap 2' '
333
334         echo 4 >positive &&
335         git add positive &&
336         alt="fixed: 34" &&
337         git commit -s -m "welcome
338
339 We have now
340 $alt" &&
341         git cat-file commit HEAD | sed -e "1,/^\$/d" > actual &&
342         (
343                 echo welcome
344                 echo
345                 echo We have now
346                 echo $alt
347                 echo
348                 git var GIT_COMMITTER_IDENT |
349                 sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /"
350         ) >expected &&
351         test_cmp expected actual
352 '
353
354 test_expect_success 'multiple -m' '
355
356         >negative &&
357         git add negative &&
358         git commit -m "one" -m "two" -m "three" &&
359         git cat-file commit HEAD | sed -e "1,/^\$/d" >actual &&
360         (
361                 echo one
362                 echo
363                 echo two
364                 echo
365                 echo three
366         ) >expected &&
367         test_cmp expected actual
368
369 '
370
371 test_expect_success 'amend commit to fix author' '
372
373         oldtick=$GIT_AUTHOR_DATE &&
374         test_tick &&
375         git reset --hard &&
376         git cat-file -p HEAD |
377         sed -e "s/author.*/author $author $oldtick/" \
378                 -e "s/^\(committer.*> \).*$/\1$GIT_COMMITTER_DATE/" > \
379                 expected &&
380         git commit --amend --author="$author" &&
381         git cat-file -p HEAD > current &&
382         test_cmp expected current
383
384 '
385
386 test_expect_success 'git commit <file> with dirty index' '
387         echo tacocat > elif &&
388         echo tehlulz > chz &&
389         git add chz &&
390         git commit elif -m "tacocat is a palindrome" &&
391         git show --stat | grep elif &&
392         git diff --cached | grep chz
393 '
394
395 test_expect_success 'same tree (single parent)' '
396
397         git reset --hard &&
398         test_must_fail git commit -m empty
399
400 '
401
402 test_expect_success 'same tree (single parent) --allow-empty' '
403
404         git commit --allow-empty -m "forced empty" &&
405         git cat-file commit HEAD | grep forced
406
407 '
408
409 test_expect_success 'same tree (merge and amend merge)' '
410
411         git checkout -b side HEAD^ &&
412         echo zero >zero &&
413         git add zero &&
414         git commit -m "add zero" &&
415         git checkout master &&
416
417         git merge -s ours side -m "empty ok" &&
418         git diff HEAD^ HEAD >actual &&
419         : >expected &&
420         test_cmp expected actual &&
421
422         git commit --amend -m "empty really ok" &&
423         git diff HEAD^ HEAD >actual &&
424         : >expected &&
425         test_cmp expected actual
426
427 '
428
429 test_expect_success 'amend using the message from another commit' '
430
431         git reset --hard &&
432         test_tick &&
433         git commit --allow-empty -m "old commit" &&
434         old=$(git rev-parse --verify HEAD) &&
435         test_tick &&
436         git commit --allow-empty -m "new commit" &&
437         new=$(git rev-parse --verify HEAD) &&
438         test_tick &&
439         git commit --allow-empty --amend -C "$old" &&
440         git show --pretty="format:%ad %s" "$old" >expected &&
441         git show --pretty="format:%ad %s" HEAD >actual &&
442         test_cmp expected actual
443
444 '
445
446 test_expect_success 'amend using the message from a commit named with tag' '
447
448         git reset --hard &&
449         test_tick &&
450         git commit --allow-empty -m "old commit" &&
451         old=$(git rev-parse --verify HEAD) &&
452         git tag -a -m "tag on old" tagged-old HEAD &&
453         test_tick &&
454         git commit --allow-empty -m "new commit" &&
455         new=$(git rev-parse --verify HEAD) &&
456         test_tick &&
457         git commit --allow-empty --amend -C tagged-old &&
458         git show --pretty="format:%ad %s" "$old" >expected &&
459         git show --pretty="format:%ad %s" HEAD >actual &&
460         test_cmp expected actual
461
462 '
463
464 test_expect_success 'amend can copy notes' '
465
466         git config notes.rewrite.amend true &&
467         git config notes.rewriteRef "refs/notes/*" &&
468         test_commit foo &&
469         git notes add -m"a note" &&
470         test_tick &&
471         git commit --amend -m"new foo" &&
472         test "$(git notes show)" = "a note"
473
474 '
475
476 test_done