]> git.ipfire.org Git - thirdparty/git.git/blob - t/t7500-commit-template-squash-signoff.sh
The third batch
[thirdparty/git.git] / t / t7500-commit-template-squash-signoff.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2007 Steven Grimm
4 #
5
6 test_description='git commit
7
8 Tests for template, signoff, squash and -F functions.'
9
10 . ./test-lib.sh
11
12 . "$TEST_DIRECTORY"/lib-rebase.sh
13
14 commit_msg_is () {
15 expect=commit_msg_is.expect
16 actual=commit_msg_is.actual
17
18 printf "%s" "$(git log --pretty=format:%s%b -1)" >"$actual" &&
19 printf "%s" "$1" >"$expect" &&
20 test_cmp "$expect" "$actual"
21 }
22
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' '
25 echo content > foo &&
26 git add foo &&
27 git commit -m "initial commit"
28 '
29
30 test_expect_success 'nonexistent template file should return error' '
31 echo changes >> foo &&
32 git add foo &&
33 (
34 GIT_EDITOR="echo hello >\"\$1\"" &&
35 export GIT_EDITOR &&
36 test_must_fail git commit --template "$PWD"/notexist
37 )
38 '
39
40 test_expect_success 'nonexistent template file in config should return error' '
41 test_config commit.template "$PWD"/notexist &&
42 (
43 GIT_EDITOR="echo hello >\"\$1\"" &&
44 export GIT_EDITOR &&
45 test_must_fail git commit
46 )
47 '
48
49 # From now on we'll use a template file that exists.
50 TEMPLATE="$PWD"/template
51
52 test_expect_success 'unedited template should not commit' '
53 echo "template line" > "$TEMPLATE" &&
54 test_must_fail git commit --template "$TEMPLATE"
55 '
56
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"
60 '
61
62 test_expect_success 'a Signed-off-by line by itself should not commit' '
63 (
64 test_set_editor "$TEST_DIRECTORY"/t7500/add-signed-off &&
65 test_must_fail git commit --template "$TEMPLATE"
66 )
67 '
68
69 test_expect_success 'adding comments to a template should not commit' '
70 (
71 test_set_editor "$TEST_DIRECTORY"/t7500/add-comments &&
72 test_must_fail git commit --template "$TEMPLATE"
73 )
74 '
75
76 test_expect_success 'adding real content to a template should commit' '
77 (
78 test_set_editor "$TEST_DIRECTORY"/t7500/add-content &&
79 git commit --template "$TEMPLATE"
80 ) &&
81 commit_msg_is "template linecommit message"
82 '
83
84 test_expect_success '-t option should be short for --template' '
85 echo "short template" > "$TEMPLATE" &&
86 echo "new content" >> foo &&
87 git add foo &&
88 (
89 test_set_editor "$TEST_DIRECTORY"/t7500/add-content &&
90 git commit -t "$TEMPLATE"
91 ) &&
92 commit_msg_is "short templatecommit message"
93 '
94
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 &&
99 git add foo &&
100 (
101 test_set_editor "$TEST_DIRECTORY"/t7500/add-content &&
102 git commit
103 ) &&
104 commit_msg_is "new templatecommit message"
105 '
106
107 test_expect_success 'explicit commit message should override template' '
108 echo "still more content" >> foo &&
109 git add 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"
113 '
114
115 test_expect_success 'commit message from file should override template' '
116 echo "content galore" >> foo &&
117 git add foo &&
118 echo "standard input msg" |
119 (
120 test_set_editor "$TEST_DIRECTORY"/t7500/add-content &&
121 git commit --template "$TEMPLATE" --file -
122 ) &&
123 commit_msg_is "standard input msg"
124 '
125
126 cat >"$TEMPLATE" <<\EOF
127
128
129 ### template
130
131 EOF
132 test_expect_success 'commit message from template with whitespace issue' '
133 echo "content galore" >>foo &&
134 git add foo &&
135 GIT_EDITOR=\""$TEST_DIRECTORY"\"/t7500/add-whitespaced-content \
136 git commit --template "$TEMPLATE" &&
137 commit_msg_is "commit message"
138 '
139
140 test_expect_success 'using alternate GIT_INDEX_FILE (1)' '
141
142 cp .git/index saved-index &&
143 (
144 echo some new content >file &&
145 GIT_INDEX_FILE=.git/another_index &&
146 export GIT_INDEX_FILE &&
147 git add file &&
148 git commit -m "commit using another index" &&
149 git diff-index --exit-code HEAD &&
150 git diff-files --exit-code
151 ) &&
152 cmp .git/index saved-index >/dev/null
153
154 '
155
156 test_expect_success 'using alternate GIT_INDEX_FILE (2)' '
157
158 cp .git/index saved-index &&
159 (
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)"
166
167 ) &&
168 cmp .git/index saved-index >/dev/null
169 '
170
171 cat > expect << EOF
172 zort
173
174 Signed-off-by: C O Mitter <committer@example.com>
175 EOF
176
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
182 '
183
184 test_expect_success 'commit message from file (1)' '
185 mkdir subdir &&
186 echo "Log in top directory" >log &&
187 echo "Log in sub directory" >subdir/log &&
188 (
189 cd subdir &&
190 git commit --allow-empty -F log
191 ) &&
192 commit_msg_is "Log in sub directory"
193 '
194
195 test_expect_success 'commit message from file (2)' '
196 rm -f log &&
197 echo "Log in sub directory" >subdir/log &&
198 (
199 cd subdir &&
200 git commit --allow-empty -F log
201 ) &&
202 commit_msg_is "Log in sub directory"
203 '
204
205 test_expect_success 'commit message from stdin' '
206 (
207 cd subdir &&
208 echo "Log with foo word" | git commit --allow-empty -F -
209 ) &&
210 commit_msg_is "Log with foo word"
211 '
212
213 test_expect_success 'commit -F overrides -t' '
214 (
215 cd subdir &&
216 echo "-F log" > f.log &&
217 echo "-t template" > t.template &&
218 git commit --allow-empty -F f.log -t t.template
219 ) &&
220 commit_msg_is "-F log"
221 '
222
223 test_expect_success 'Commit without message is allowed with --allow-empty-message' '
224 echo "more content" >>foo &&
225 git add foo &&
226 >empty &&
227 git commit --allow-empty-message <empty &&
228 commit_msg_is "" &&
229 git tag empty-message-commit
230 '
231
232 test_expect_success 'Commit without message is no-no without --allow-empty-message' '
233 echo "more content" >>foo &&
234 git add foo &&
235 >empty &&
236 test_must_fail git commit <empty
237 '
238
239 test_expect_success 'Commit a message with --allow-empty-message' '
240 echo "even more content" >>foo &&
241 git add foo &&
242 git commit --allow-empty-message -m"hello there" &&
243 commit_msg_is "hello there"
244 '
245
246 test_expect_success 'commit -C empty respects --allow-empty-message' '
247 echo more >>foo &&
248 git add foo &&
249 test_must_fail git commit -C empty-message-commit &&
250 git commit -C empty-message-commit --allow-empty-message &&
251 commit_msg_is ""
252 '
253
254 commit_for_rebase_autosquash_setup () {
255 echo "first content line" >>foo &&
256 git add foo &&
257 cat >log <<EOF &&
258 target message subject line
259
260 target message body line 1
261 target message body line 2
262 EOF
263 git commit -F log &&
264 echo "second content line" >>foo &&
265 git add foo &&
266 git commit -m "intermediate commit" &&
267 echo "third content line" >>foo &&
268 git add foo
269 }
270
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"
275 '
276
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
281
282 extra"
283 '
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
288 extra"
289 '
290
291 get_commit_msg () {
292 rev="$1" &&
293 git log -1 --pretty=format:"%B" "$rev"
294 }
295
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~)
300
301 $(get_commit_msg HEAD~)
302
303 edited
304 EOF
305 (
306 set_fake_editor &&
307 FAKE_COMMIT_AMEND="edited" \
308 git commit --fixup=amend:HEAD~
309 ) &&
310 get_commit_msg HEAD >actual &&
311 test_cmp expected actual
312 '
313
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~)
318
319 $(get_commit_msg HEAD~)
320
321 edited
322 EOF
323 (
324 set_fake_editor &&
325 FAKE_COMMIT_AMEND="edited" \
326 git commit --fixup=amend:HEAD~ --only
327 ) &&
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 &&
334 test_cmp foo actual
335 '
336
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~)
341
342 $(get_commit_msg HEAD~)
343
344 edited
345 EOF
346 (
347 set_fake_editor &&
348 FAKE_COMMIT_AMEND="edited" \
349 git commit --fixup=reword:HEAD~
350 ) &&
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 &&
357 test_cmp foo actual
358 '
359
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
365 '
366
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
372 '
373
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~)
378
379 $(get_commit_msg HEAD~)
380
381 edited 1
382
383 edited 2
384 EOF
385 echo "reword new commit message" >actual &&
386 (
387 set_fake_editor &&
388 FAKE_COMMIT_AMEND="edited 1" \
389 git commit --fixup=reword:HEAD~ &&
390 FAKE_COMMIT_AMEND="edited 2" \
391 git commit --fixup=reword:HEAD
392 ) &&
393 get_commit_msg HEAD >actual &&
394 test_cmp expected actual
395 '
396
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 &&
400 (
401 set_fake_editor &&
402 test_must_fail env FAKE_COMMIT_MESSAGE="amend! target message subject line" \
403 git commit --fixup=amend:HEAD~ 2>actual
404 ) &&
405 test_cmp expected actual
406 '
407
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~)
412 EOF
413 (
414 set_fake_editor &&
415 FAKE_COMMIT_MESSAGE="amend! target message subject line" \
416 git commit --fixup=amend:HEAD~ --allow-empty-message &&
417 get_commit_msg HEAD >actual
418 ) &&
419 test_cmp expected actual
420 '
421
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
429 "
430 }
431
432 for opt in --all --include --only --interactive --patch
433 do
434 test_fixup_reword_opt $opt
435 done
436
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
442 '
443
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
448 '
449
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"
455 '
456
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"
461 '
462
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"
467 '
468
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"
474 '
475
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"
480 '
481
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"
487 '
488
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"
494 '
495
496 test_expect_success 'invalid message options when using --fixup' '
497 echo changes >>foo &&
498 echo "message" >log &&
499 git add foo &&
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
504 '
505
506 cat >expected-template <<EOF
507
508 # Please enter the commit message for your changes. Lines starting
509 # with '#' will be ignored.
510 #
511 # Author: A U Thor <author@example.com>
512 #
513 # On branch commit-template-check
514 # Changes to be committed:
515 # new file: commit-template-check
516 #
517 # Untracked files not listed
518 EOF
519
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
527 '
528
529 test_expect_success 'setup empty commit with unstaged rename and copy' '
530 test_create_repo unstaged_rename_and_copy &&
531 (
532 cd unstaged_rename_and_copy &&
533
534 echo content >orig &&
535 git add orig &&
536 test_commit orig &&
537
538 cp orig new_copy &&
539 mv orig new_rename &&
540 git add -N new_copy new_rename
541 )
542 '
543
544 test_expect_success 'check commit with unstaged rename and copy' '
545 (
546 cd unstaged_rename_and_copy &&
547
548 test_must_fail git -c diff.renames=copy commit
549 )
550 '
551
552 test_expect_success 'commit without staging files fails and displays hints' '
553 echo "initial" >file &&
554 git add file &&
555 git commit -m initial &&
556 echo "changes" >>file &&
557 test_must_fail git commit -m update >actual &&
558 test_grep "no changes added to commit (use \"git add\" and/or \"git commit -a\")" actual
559 '
560
561 test_done