silence gcc array-bounds warning
[git.git] / t / t9001-send-email.sh
blob3c90c4fc1c0ee798b5e37729d1a67018499f0a92
1 #!/bin/sh
3 test_description='git send-email'
4 . ./test-lib.sh
6 PROG='git send-email'
7 test_expect_success \
8 'prepare reference tree' \
9 'echo "1A quick brown fox jumps over the" >file &&
10 echo "lazy dog" >>file &&
11 git add file &&
12 GIT_AUTHOR_NAME="A" git commit -a -m "Initial."'
14 test_expect_success \
15 'Setup helper tool' \
16 '(echo "#!$SHELL_PATH"
17 echo shift
18 echo output=1
19 echo "while test -f commandline\$output; do output=\$((\$output+1)); done"
20 echo for a
21 echo do
22 echo " echo \"!\$a!\""
23 echo "done >commandline\$output"
24 echo "cat > msgtxt\$output"
25 ) >fake.sendmail &&
26 chmod +x ./fake.sendmail &&
27 git add fake.sendmail &&
28 GIT_AUTHOR_NAME="A" git commit -a -m "Second."'
30 clean_fake_sendmail() {
31 rm -f commandline* msgtxt*
34 test_expect_success 'Extract patches' '
35 patches=`git format-patch -s --cc="One <one@example.com>" --cc=two@example.com -n HEAD^1`
38 # Test no confirm early to ensure remaining tests will not hang
39 test_no_confirm () {
40 rm -f no_confirm_okay
41 echo n | \
42 GIT_SEND_EMAIL_NOTTY=1 \
43 git send-email \
44 --from="Example <from@example.com>" \
45 --to=nobody@example.com \
46 --smtp-server="$(pwd)/fake.sendmail" \
47 $@ \
48 $patches > stdout &&
49 test_must_fail grep "Send this email" stdout &&
50 > no_confirm_okay
53 # Exit immediately to prevent hang if a no-confirm test fails
54 check_no_confirm () {
55 test -f no_confirm_okay || {
56 say 'No confirm test failed; skipping remaining tests to prevent hanging'
57 test_done
61 test_expect_success 'No confirm with --suppress-cc' '
62 test_no_confirm --suppress-cc=sob
64 check_no_confirm
66 test_expect_success 'No confirm with --confirm=never' '
67 test_no_confirm --confirm=never
69 check_no_confirm
71 # leave sendemail.confirm set to never after this so that none of the
72 # remaining tests prompt unintentionally.
73 test_expect_success 'No confirm with sendemail.confirm=never' '
74 git config sendemail.confirm never &&
75 test_no_confirm --compose --subject=foo
77 check_no_confirm
79 test_expect_success 'Send patches' '
80 git send-email --suppress-cc=sob --from="Example <nobody@example.com>" --to=nobody@example.com --smtp-server="$(pwd)/fake.sendmail" $patches 2>errors
83 cat >expected <<\EOF
84 !nobody@example.com!
85 !author@example.com!
86 !one@example.com!
87 !two@example.com!
88 EOF
89 test_expect_success \
90 'Verify commandline' \
91 'test_cmp expected commandline1'
93 cat >expected-show-all-headers <<\EOF
94 0001-Second.patch
95 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
96 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
97 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
98 Dry-OK. Log says:
99 Server: relay.example.com
100 MAIL FROM:<from@example.com>
101 RCPT TO:<to@example.com>,<cc@example.com>,<author@example.com>,<one@example.com>,<two@example.com>,<bcc@example.com>
102 From: Example <from@example.com>
103 To: to@example.com
104 Cc: cc@example.com, A <author@example.com>, One <one@example.com>, two@example.com
105 Subject: [PATCH 1/1] Second.
106 Date: DATE-STRING
107 Message-Id: MESSAGE-ID-STRING
108 X-Mailer: X-MAILER-STRING
109 In-Reply-To: <unique-message-id@example.com>
110 References: <unique-message-id@example.com>
112 Result: OK
115 test_expect_success 'Show all headers' '
116 git send-email \
117 --dry-run \
118 --suppress-cc=sob \
119 --from="Example <from@example.com>" \
120 --to=to@example.com \
121 --cc=cc@example.com \
122 --bcc=bcc@example.com \
123 --in-reply-to="<unique-message-id@example.com>" \
124 --smtp-server relay.example.com \
125 $patches |
126 sed -e "s/^\(Date:\).*/\1 DATE-STRING/" \
127 -e "s/^\(Message-Id:\).*/\1 MESSAGE-ID-STRING/" \
128 -e "s/^\(X-Mailer:\).*/\1 X-MAILER-STRING/" \
129 >actual-show-all-headers &&
130 test_cmp expected-show-all-headers actual-show-all-headers
133 test_expect_success 'Prompting works' '
134 clean_fake_sendmail &&
135 (echo "Example <from@example.com>"
136 echo "to@example.com"
137 echo ""
138 ) | GIT_SEND_EMAIL_NOTTY=1 git send-email \
139 --smtp-server="$(pwd)/fake.sendmail" \
140 $patches \
141 2>errors &&
142 grep "^From: Example <from@example.com>$" msgtxt1 &&
143 grep "^To: to@example.com$" msgtxt1
146 z8=zzzzzzzz
147 z64=$z8$z8$z8$z8$z8$z8$z8$z8
148 z512=$z64$z64$z64$z64$z64$z64$z64$z64
149 test_expect_success 'reject long lines' '
150 clean_fake_sendmail &&
151 cp $patches longline.patch &&
152 echo $z512$z512 >>longline.patch &&
153 test_must_fail git send-email \
154 --from="Example <nobody@example.com>" \
155 --to=nobody@example.com \
156 --smtp-server="$(pwd)/fake.sendmail" \
157 $patches longline.patch \
158 2>errors &&
159 grep longline.patch errors
162 test_expect_success 'no patch was sent' '
163 ! test -e commandline1
166 test_expect_success 'Author From: in message body' '
167 clean_fake_sendmail &&
168 git send-email \
169 --from="Example <nobody@example.com>" \
170 --to=nobody@example.com \
171 --smtp-server="$(pwd)/fake.sendmail" \
172 $patches &&
173 sed "1,/^$/d" < msgtxt1 > msgbody1
174 grep "From: A <author@example.com>" msgbody1
177 test_expect_success 'Author From: not in message body' '
178 clean_fake_sendmail &&
179 git send-email \
180 --from="A <author@example.com>" \
181 --to=nobody@example.com \
182 --smtp-server="$(pwd)/fake.sendmail" \
183 $patches &&
184 sed "1,/^$/d" < msgtxt1 > msgbody1
185 ! grep "From: A <author@example.com>" msgbody1
188 test_expect_success 'allow long lines with --no-validate' '
189 git send-email \
190 --from="Example <nobody@example.com>" \
191 --to=nobody@example.com \
192 --smtp-server="$(pwd)/fake.sendmail" \
193 --novalidate \
194 $patches longline.patch \
195 2>errors
198 test_expect_success 'Invalid In-Reply-To' '
199 clean_fake_sendmail &&
200 git send-email \
201 --from="Example <nobody@example.com>" \
202 --to=nobody@example.com \
203 --in-reply-to=" " \
204 --smtp-server="$(pwd)/fake.sendmail" \
205 $patches
206 2>errors
207 ! grep "^In-Reply-To: < *>" msgtxt1
210 test_expect_success 'Valid In-Reply-To when prompting' '
211 clean_fake_sendmail &&
212 (echo "From Example <from@example.com>"
213 echo "To Example <to@example.com>"
214 echo ""
215 ) | env GIT_SEND_EMAIL_NOTTY=1 git send-email \
216 --smtp-server="$(pwd)/fake.sendmail" \
217 $patches 2>errors &&
218 ! grep "^In-Reply-To: < *>" msgtxt1
221 test_expect_success 'setup fake editor' '
222 (echo "#!$SHELL_PATH" &&
223 echo "echo fake edit >>\"\$1\""
224 ) >fake-editor &&
225 chmod +x fake-editor
228 test_set_editor "$(pwd)/fake-editor"
230 test_expect_success '--compose works' '
231 clean_fake_sendmail &&
232 git send-email \
233 --compose --subject foo \
234 --from="Example <nobody@example.com>" \
235 --to=nobody@example.com \
236 --smtp-server="$(pwd)/fake.sendmail" \
237 $patches \
238 2>errors
241 test_expect_success 'first message is compose text' '
242 grep "^fake edit" msgtxt1
245 test_expect_success 'second message is patch' '
246 grep "Subject:.*Second" msgtxt2
249 cat >expected-suppress-sob <<\EOF
250 0001-Second.patch
251 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
252 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
253 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
254 Dry-OK. Log says:
255 Server: relay.example.com
256 MAIL FROM:<from@example.com>
257 RCPT TO:<to@example.com>,<cc@example.com>,<author@example.com>,<one@example.com>,<two@example.com>
258 From: Example <from@example.com>
259 To: to@example.com
260 Cc: cc@example.com, A <author@example.com>, One <one@example.com>, two@example.com
261 Subject: [PATCH 1/1] Second.
262 Date: DATE-STRING
263 Message-Id: MESSAGE-ID-STRING
264 X-Mailer: X-MAILER-STRING
266 Result: OK
269 test_suppression () {
270 git send-email \
271 --dry-run \
272 --suppress-cc=$1 \
273 --from="Example <from@example.com>" \
274 --to=to@example.com \
275 --smtp-server relay.example.com \
276 $patches |
277 sed -e "s/^\(Date:\).*/\1 DATE-STRING/" \
278 -e "s/^\(Message-Id:\).*/\1 MESSAGE-ID-STRING/" \
279 -e "s/^\(X-Mailer:\).*/\1 X-MAILER-STRING/" \
280 >actual-suppress-$1 &&
281 test_cmp expected-suppress-$1 actual-suppress-$1
284 test_expect_success 'sendemail.cc set' '
285 git config sendemail.cc cc@example.com &&
286 test_suppression sob
289 cat >expected-suppress-sob <<\EOF
290 0001-Second.patch
291 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
292 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
293 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
294 Dry-OK. Log says:
295 Server: relay.example.com
296 MAIL FROM:<from@example.com>
297 RCPT TO:<to@example.com>,<author@example.com>,<one@example.com>,<two@example.com>
298 From: Example <from@example.com>
299 To: to@example.com
300 Cc: A <author@example.com>, One <one@example.com>, two@example.com
301 Subject: [PATCH 1/1] Second.
302 Date: DATE-STRING
303 Message-Id: MESSAGE-ID-STRING
304 X-Mailer: X-MAILER-STRING
306 Result: OK
309 test_expect_success 'sendemail.cc unset' '
310 git config --unset sendemail.cc &&
311 test_suppression sob
314 cat >expected-suppress-all <<\EOF
315 0001-Second.patch
316 Dry-OK. Log says:
317 Server: relay.example.com
318 MAIL FROM:<from@example.com>
319 RCPT TO:<to@example.com>
320 From: Example <from@example.com>
321 To: to@example.com
322 Subject: [PATCH 1/1] Second.
323 Date: DATE-STRING
324 Message-Id: MESSAGE-ID-STRING
325 X-Mailer: X-MAILER-STRING
327 Result: OK
330 test_expect_success '--suppress-cc=all' '
331 test_suppression all
334 cat >expected-suppress-body <<\EOF
335 0001-Second.patch
336 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
337 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
338 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
339 Dry-OK. Log says:
340 Server: relay.example.com
341 MAIL FROM:<from@example.com>
342 RCPT TO:<to@example.com>,<author@example.com>,<one@example.com>,<two@example.com>
343 From: Example <from@example.com>
344 To: to@example.com
345 Cc: A <author@example.com>, One <one@example.com>, two@example.com
346 Subject: [PATCH 1/1] Second.
347 Date: DATE-STRING
348 Message-Id: MESSAGE-ID-STRING
349 X-Mailer: X-MAILER-STRING
351 Result: OK
354 test_expect_success '--suppress-cc=body' '
355 test_suppression body
358 cat >expected-suppress-sob <<\EOF
359 0001-Second.patch
360 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
361 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
362 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
363 Dry-OK. Log says:
364 Server: relay.example.com
365 MAIL FROM:<from@example.com>
366 RCPT TO:<to@example.com>,<author@example.com>,<one@example.com>,<two@example.com>
367 From: Example <from@example.com>
368 To: to@example.com
369 Cc: A <author@example.com>, One <one@example.com>, two@example.com
370 Subject: [PATCH 1/1] Second.
371 Date: DATE-STRING
372 Message-Id: MESSAGE-ID-STRING
373 X-Mailer: X-MAILER-STRING
375 Result: OK
378 test_expect_success '--suppress-cc=sob' '
379 test_suppression sob
382 cat >expected-suppress-bodycc <<\EOF
383 0001-Second.patch
384 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
385 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
386 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
387 (body) Adding cc: C O Mitter <committer@example.com> from line 'Signed-off-by: C O Mitter <committer@example.com>'
388 Dry-OK. Log says:
389 Server: relay.example.com
390 MAIL FROM:<from@example.com>
391 RCPT TO:<to@example.com>,<author@example.com>,<one@example.com>,<two@example.com>,<committer@example.com>
392 From: Example <from@example.com>
393 To: to@example.com
394 Cc: A <author@example.com>, One <one@example.com>, two@example.com, C O Mitter <committer@example.com>
395 Subject: [PATCH 1/1] Second.
396 Date: DATE-STRING
397 Message-Id: MESSAGE-ID-STRING
398 X-Mailer: X-MAILER-STRING
400 Result: OK
403 test_expect_success '--suppress-cc=bodycc' '
404 test_suppression bodycc
407 cat >expected-suppress-cc <<\EOF
408 0001-Second.patch
409 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
410 (body) Adding cc: C O Mitter <committer@example.com> from line 'Signed-off-by: C O Mitter <committer@example.com>'
411 Dry-OK. Log says:
412 Server: relay.example.com
413 MAIL FROM:<from@example.com>
414 RCPT TO:<to@example.com>,<author@example.com>,<committer@example.com>
415 From: Example <from@example.com>
416 To: to@example.com
417 Cc: A <author@example.com>, C O Mitter <committer@example.com>
418 Subject: [PATCH 1/1] Second.
419 Date: DATE-STRING
420 Message-Id: MESSAGE-ID-STRING
421 X-Mailer: X-MAILER-STRING
423 Result: OK
426 test_expect_success '--suppress-cc=cc' '
427 test_suppression cc
430 test_confirm () {
431 echo y | \
432 GIT_SEND_EMAIL_NOTTY=1 \
433 git send-email \
434 --from="Example <nobody@example.com>" \
435 --to=nobody@example.com \
436 --smtp-server="$(pwd)/fake.sendmail" \
437 $@ $patches > stdout &&
438 grep "Send this email" stdout
441 test_expect_success '--confirm=always' '
442 test_confirm --confirm=always --suppress-cc=all
445 test_expect_success '--confirm=auto' '
446 test_confirm --confirm=auto
449 test_expect_success '--confirm=cc' '
450 test_confirm --confirm=cc
453 test_expect_success '--confirm=compose' '
454 test_confirm --confirm=compose --compose
457 test_expect_success 'confirm by default (due to cc)' '
458 CONFIRM=$(git config --get sendemail.confirm) &&
459 git config --unset sendemail.confirm &&
460 test_confirm
461 ret="$?"
462 git config sendemail.confirm ${CONFIRM:-never}
463 test $ret = "0"
466 test_expect_success 'confirm by default (due to --compose)' '
467 CONFIRM=$(git config --get sendemail.confirm) &&
468 git config --unset sendemail.confirm &&
469 test_confirm --suppress-cc=all --compose
470 ret="$?"
471 git config sendemail.confirm ${CONFIRM:-never}
472 test $ret = "0"
475 test_expect_success 'confirm detects EOF (inform assumes y)' '
476 CONFIRM=$(git config --get sendemail.confirm) &&
477 git config --unset sendemail.confirm &&
478 rm -fr outdir &&
479 git format-patch -2 -o outdir &&
480 GIT_SEND_EMAIL_NOTTY=1 \
481 git send-email \
482 --from="Example <nobody@example.com>" \
483 --to=nobody@example.com \
484 --smtp-server="$(pwd)/fake.sendmail" \
485 outdir/*.patch < /dev/null
486 ret="$?"
487 git config sendemail.confirm ${CONFIRM:-never}
488 test $ret = "0"
491 test_expect_success 'confirm detects EOF (auto causes failure)' '
492 CONFIRM=$(git config --get sendemail.confirm) &&
493 git config sendemail.confirm auto &&
494 GIT_SEND_EMAIL_NOTTY=1 &&
495 export GIT_SEND_EMAIL_NOTTY &&
496 test_must_fail git send-email \
497 --from="Example <nobody@example.com>" \
498 --to=nobody@example.com \
499 --smtp-server="$(pwd)/fake.sendmail" \
500 $patches < /dev/null
501 ret="$?"
502 git config sendemail.confirm ${CONFIRM:-never}
503 test $ret = "0"
506 test_expect_success 'confirm doesnt loop forever' '
507 CONFIRM=$(git config --get sendemail.confirm) &&
508 git config sendemail.confirm auto &&
509 GIT_SEND_EMAIL_NOTTY=1 &&
510 export GIT_SEND_EMAIL_NOTTY &&
511 yes "bogus" | test_must_fail git send-email \
512 --from="Example <nobody@example.com>" \
513 --to=nobody@example.com \
514 --smtp-server="$(pwd)/fake.sendmail" \
515 $patches
516 ret="$?"
517 git config sendemail.confirm ${CONFIRM:-never}
518 test $ret = "0"
521 test_expect_success 'utf8 Cc is rfc2047 encoded' '
522 clean_fake_sendmail &&
523 rm -fr outdir &&
524 git format-patch -1 -o outdir --cc="àéìöú <utf8@example.com>" &&
525 git send-email \
526 --from="Example <nobody@example.com>" \
527 --to=nobody@example.com \
528 --smtp-server="$(pwd)/fake.sendmail" \
529 outdir/*.patch &&
530 grep "^Cc:" msgtxt1 |
531 grep "=?utf-8?q?=C3=A0=C3=A9=C3=AC=C3=B6=C3=BA?= <utf8@example.com>"
534 test_expect_success '--compose adds MIME for utf8 body' '
535 clean_fake_sendmail &&
536 (echo "#!$SHELL_PATH" &&
537 echo "echo utf8 body: àéìöú >>\"\$1\""
538 ) >fake-editor-utf8 &&
539 chmod +x fake-editor-utf8 &&
540 GIT_EDITOR="\"$(pwd)/fake-editor-utf8\"" \
541 git send-email \
542 --compose --subject foo \
543 --from="Example <nobody@example.com>" \
544 --to=nobody@example.com \
545 --smtp-server="$(pwd)/fake.sendmail" \
546 $patches &&
547 grep "^utf8 body" msgtxt1 &&
548 grep "^Content-Type: text/plain; charset=utf-8" msgtxt1
551 test_expect_success '--compose respects user mime type' '
552 clean_fake_sendmail &&
553 (echo "#!$SHELL_PATH" &&
554 echo "(echo MIME-Version: 1.0"
555 echo " echo Content-Type: text/plain\\; charset=iso-8859-1"
556 echo " echo Content-Transfer-Encoding: 8bit"
557 echo " echo Subject: foo"
558 echo " echo "
559 echo " echo utf8 body: àéìöú) >\"\$1\""
560 ) >fake-editor-utf8-mime &&
561 chmod +x fake-editor-utf8-mime &&
562 GIT_EDITOR="\"$(pwd)/fake-editor-utf8-mime\"" \
563 git send-email \
564 --compose --subject foo \
565 --from="Example <nobody@example.com>" \
566 --to=nobody@example.com \
567 --smtp-server="$(pwd)/fake.sendmail" \
568 $patches &&
569 grep "^utf8 body" msgtxt1 &&
570 grep "^Content-Type: text/plain; charset=iso-8859-1" msgtxt1 &&
571 ! grep "^Content-Type: text/plain; charset=utf-8" msgtxt1
574 test_expect_success '--compose adds MIME for utf8 subject' '
575 clean_fake_sendmail &&
576 GIT_EDITOR="\"$(pwd)/fake-editor\"" \
577 git send-email \
578 --compose --subject utf8-sübjëct \
579 --from="Example <nobody@example.com>" \
580 --to=nobody@example.com \
581 --smtp-server="$(pwd)/fake.sendmail" \
582 $patches &&
583 grep "^fake edit" msgtxt1 &&
584 grep "^Subject: =?utf-8?q?utf8-s=C3=BCbj=C3=ABct?=" msgtxt1
587 test_expect_success 'detects ambiguous reference/file conflict' '
588 echo master > master &&
589 git add master &&
590 git commit -m"add master" &&
591 test_must_fail git send-email --dry-run master 2>errors &&
592 grep disambiguate errors
595 test_expect_success 'feed two files' '
596 rm -fr outdir &&
597 git format-patch -2 -o outdir &&
598 git send-email \
599 --dry-run \
600 --from="Example <nobody@example.com>" \
601 --to=nobody@example.com \
602 outdir/000?-*.patch 2>errors >out &&
603 grep "^Subject: " out >subjects &&
604 test "z$(sed -n -e 1p subjects)" = "zSubject: [PATCH 1/2] Second." &&
605 test "z$(sed -n -e 2p subjects)" = "zSubject: [PATCH 2/2] add master"
608 test_expect_success 'in-reply-to but no threading' '
609 git send-email \
610 --dry-run \
611 --from="Example <nobody@example.com>" \
612 --to=nobody@example.com \
613 --in-reply-to="<in-reply-id@example.com>" \
614 --no-thread \
615 $patches |
616 grep "In-Reply-To: <in-reply-id@example.com>"
619 test_done