Merge commit 'v1.6.3.2' into devel
[4msysgit-hv.git] / t / t9001-send-email.sh
blob5476559ba13872757a915372f344bd88b09d71db
1 #!/bin/sh
3 test_description='git send-email'
4 . ./test-lib.sh
6 say "cannot invoke fake.sendmail; skipping test"
7 test_done
8 exit 0
10 if ! test_have_prereq PERL; then
11 say 'skipping git send-email tests, perl not available'
12 test_done
15 PROG='git send-email'
16 test_expect_success \
17 'prepare reference tree' \
18 'echo "1A quick brown fox jumps over the" >file &&
19 echo "lazy dog" >>file &&
20 git add file &&
21 GIT_AUTHOR_NAME="A" git commit -a -m "Initial."'
23 test_expect_success \
24 'Setup helper tool' \
25 '(echo "#!$SHELL_PATH"
26 echo shift
27 echo output=1
28 echo "while test -f commandline\$output; do output=\$((\$output+1)); done"
29 echo for a
30 echo do
31 echo " echo \"!\$a!\""
32 echo "done >commandline\$output"
33 echo "cat > msgtxt\$output"
34 ) >fake.sendmail &&
35 chmod +x ./fake.sendmail &&
36 git add fake.sendmail &&
37 GIT_AUTHOR_NAME="A" git commit -a -m "Second."'
39 clean_fake_sendmail() {
40 rm -f commandline* msgtxt*
43 test_expect_success 'Extract patches' '
44 patches=`git format-patch -s --cc="One <one@example.com>" --cc=two@example.com -n HEAD^1`
47 # Test no confirm early to ensure remaining tests will not hang
48 test_no_confirm () {
49 rm -f no_confirm_okay
50 echo n | \
51 GIT_SEND_EMAIL_NOTTY=1 \
52 git send-email \
53 --from="Example <from@example.com>" \
54 --to=nobody@example.com \
55 --smtp-server="$(pwd)/fake.sendmail" \
56 $@ \
57 $patches > stdout &&
58 test_must_fail grep "Send this email" stdout &&
59 > no_confirm_okay
62 # Exit immediately to prevent hang if a no-confirm test fails
63 check_no_confirm () {
64 test -f no_confirm_okay || {
65 say 'No confirm test failed; skipping remaining tests to prevent hanging'
66 test_done
70 test_expect_success 'No confirm with --suppress-cc' '
71 test_no_confirm --suppress-cc=sob
73 check_no_confirm
75 test_expect_success 'No confirm with --confirm=never' '
76 test_no_confirm --confirm=never
78 check_no_confirm
80 # leave sendemail.confirm set to never after this so that none of the
81 # remaining tests prompt unintentionally.
82 test_expect_success 'No confirm with sendemail.confirm=never' '
83 git config sendemail.confirm never &&
84 test_no_confirm --compose --subject=foo
86 check_no_confirm
88 test_expect_success 'Send patches' '
89 git send-email --suppress-cc=sob --from="Example <nobody@example.com>" --to=nobody@example.com --smtp-server="$(pwd)/fake.sendmail" $patches 2>errors
92 cat >expected <<\EOF
93 !nobody@example.com!
94 !author@example.com!
95 !one@example.com!
96 !two@example.com!
97 EOF
98 test_expect_success \
99 'Verify commandline' \
100 'test_cmp expected commandline1'
102 cat >expected-show-all-headers <<\EOF
103 0001-Second.patch
104 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
105 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
106 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
107 Dry-OK. Log says:
108 Server: relay.example.com
109 MAIL FROM:<from@example.com>
110 RCPT TO:<to@example.com>,<cc@example.com>,<author@example.com>,<one@example.com>,<two@example.com>,<bcc@example.com>
111 From: Example <from@example.com>
112 To: to@example.com
113 Cc: cc@example.com, A <author@example.com>, One <one@example.com>, two@example.com
114 Subject: [PATCH 1/1] Second.
115 Date: DATE-STRING
116 Message-Id: MESSAGE-ID-STRING
117 X-Mailer: X-MAILER-STRING
118 In-Reply-To: <unique-message-id@example.com>
119 References: <unique-message-id@example.com>
121 Result: OK
124 test_expect_success 'Show all headers' '
125 git send-email \
126 --dry-run \
127 --suppress-cc=sob \
128 --from="Example <from@example.com>" \
129 --to=to@example.com \
130 --cc=cc@example.com \
131 --bcc=bcc@example.com \
132 --in-reply-to="<unique-message-id@example.com>" \
133 --smtp-server relay.example.com \
134 $patches |
135 sed -e "s/^\(Date:\).*/\1 DATE-STRING/" \
136 -e "s/^\(Message-Id:\).*/\1 MESSAGE-ID-STRING/" \
137 -e "s/^\(X-Mailer:\).*/\1 X-MAILER-STRING/" \
138 >actual-show-all-headers &&
139 test_cmp expected-show-all-headers actual-show-all-headers
142 test_expect_success 'Prompting works' '
143 clean_fake_sendmail &&
144 (echo "Example <from@example.com>"
145 echo "to@example.com"
146 echo ""
147 ) | GIT_SEND_EMAIL_NOTTY=1 git send-email \
148 --smtp-server="$(pwd)/fake.sendmail" \
149 $patches \
150 2>errors &&
151 grep "^From: Example <from@example.com>$" msgtxt1 &&
152 grep "^To: to@example.com$" msgtxt1
155 z8=zzzzzzzz
156 z64=$z8$z8$z8$z8$z8$z8$z8$z8
157 z512=$z64$z64$z64$z64$z64$z64$z64$z64
158 test_expect_success 'reject long lines' '
159 clean_fake_sendmail &&
160 cp $patches longline.patch &&
161 echo $z512$z512 >>longline.patch &&
162 test_must_fail git send-email \
163 --from="Example <nobody@example.com>" \
164 --to=nobody@example.com \
165 --smtp-server="$(pwd)/fake.sendmail" \
166 $patches longline.patch \
167 2>errors &&
168 grep longline.patch errors
171 test_expect_success 'no patch was sent' '
172 ! test -e commandline1
175 test_expect_success 'Author From: in message body' '
176 clean_fake_sendmail &&
177 git send-email \
178 --from="Example <nobody@example.com>" \
179 --to=nobody@example.com \
180 --smtp-server="$(pwd)/fake.sendmail" \
181 $patches &&
182 sed "1,/^$/d" < msgtxt1 > msgbody1
183 grep "From: A <author@example.com>" msgbody1
186 test_expect_success 'Author From: not in message body' '
187 clean_fake_sendmail &&
188 git send-email \
189 --from="A <author@example.com>" \
190 --to=nobody@example.com \
191 --smtp-server="$(pwd)/fake.sendmail" \
192 $patches &&
193 sed "1,/^$/d" < msgtxt1 > msgbody1
194 ! grep "From: A <author@example.com>" msgbody1
197 test_expect_success 'allow long lines with --no-validate' '
198 git send-email \
199 --from="Example <nobody@example.com>" \
200 --to=nobody@example.com \
201 --smtp-server="$(pwd)/fake.sendmail" \
202 --novalidate \
203 $patches longline.patch \
204 2>errors
207 test_expect_success 'Invalid In-Reply-To' '
208 clean_fake_sendmail &&
209 git send-email \
210 --from="Example <nobody@example.com>" \
211 --to=nobody@example.com \
212 --in-reply-to=" " \
213 --smtp-server="$(pwd)/fake.sendmail" \
214 $patches
215 2>errors
216 ! grep "^In-Reply-To: < *>" msgtxt1
219 test_expect_success 'Valid In-Reply-To when prompting' '
220 clean_fake_sendmail &&
221 (echo "From Example <from@example.com>"
222 echo "To Example <to@example.com>"
223 echo ""
224 ) | env GIT_SEND_EMAIL_NOTTY=1 git send-email \
225 --smtp-server="$(pwd)/fake.sendmail" \
226 $patches 2>errors &&
227 ! grep "^In-Reply-To: < *>" msgtxt1
230 test_expect_success 'setup fake editor' '
231 (echo "#!$SHELL_PATH" &&
232 echo "echo fake edit >>\"\$1\""
233 ) >fake-editor &&
234 chmod +x fake-editor
237 test_set_editor "$(pwd)/fake-editor"
239 test_expect_success '--compose works' '
240 clean_fake_sendmail &&
241 git send-email \
242 --compose --subject foo \
243 --from="Example <nobody@example.com>" \
244 --to=nobody@example.com \
245 --smtp-server="$(pwd)/fake.sendmail" \
246 $patches \
247 2>errors
250 test_expect_success 'first message is compose text' '
251 grep "^fake edit" msgtxt1
254 test_expect_success 'second message is patch' '
255 grep "Subject:.*Second" msgtxt2
258 cat >expected-suppress-sob <<\EOF
259 0001-Second.patch
260 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
261 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
262 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
263 Dry-OK. Log says:
264 Server: relay.example.com
265 MAIL FROM:<from@example.com>
266 RCPT TO:<to@example.com>,<cc@example.com>,<author@example.com>,<one@example.com>,<two@example.com>
267 From: Example <from@example.com>
268 To: to@example.com
269 Cc: cc@example.com, A <author@example.com>, One <one@example.com>, two@example.com
270 Subject: [PATCH 1/1] Second.
271 Date: DATE-STRING
272 Message-Id: MESSAGE-ID-STRING
273 X-Mailer: X-MAILER-STRING
275 Result: OK
278 test_suppression () {
279 git send-email \
280 --dry-run \
281 --suppress-cc=$1 \
282 --from="Example <from@example.com>" \
283 --to=to@example.com \
284 --smtp-server relay.example.com \
285 $patches |
286 sed -e "s/^\(Date:\).*/\1 DATE-STRING/" \
287 -e "s/^\(Message-Id:\).*/\1 MESSAGE-ID-STRING/" \
288 -e "s/^\(X-Mailer:\).*/\1 X-MAILER-STRING/" \
289 >actual-suppress-$1 &&
290 test_cmp expected-suppress-$1 actual-suppress-$1
293 test_expect_success 'sendemail.cc set' '
294 git config sendemail.cc cc@example.com &&
295 test_suppression sob
298 cat >expected-suppress-sob <<\EOF
299 0001-Second.patch
300 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
301 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
302 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
303 Dry-OK. Log says:
304 Server: relay.example.com
305 MAIL FROM:<from@example.com>
306 RCPT TO:<to@example.com>,<author@example.com>,<one@example.com>,<two@example.com>
307 From: Example <from@example.com>
308 To: to@example.com
309 Cc: A <author@example.com>, One <one@example.com>, two@example.com
310 Subject: [PATCH 1/1] Second.
311 Date: DATE-STRING
312 Message-Id: MESSAGE-ID-STRING
313 X-Mailer: X-MAILER-STRING
315 Result: OK
318 test_expect_success 'sendemail.cc unset' '
319 git config --unset sendemail.cc &&
320 test_suppression sob
323 cat >expected-suppress-all <<\EOF
324 0001-Second.patch
325 Dry-OK. Log says:
326 Server: relay.example.com
327 MAIL FROM:<from@example.com>
328 RCPT TO:<to@example.com>
329 From: Example <from@example.com>
330 To: to@example.com
331 Subject: [PATCH 1/1] Second.
332 Date: DATE-STRING
333 Message-Id: MESSAGE-ID-STRING
334 X-Mailer: X-MAILER-STRING
336 Result: OK
339 test_expect_success '--suppress-cc=all' '
340 test_suppression all
343 cat >expected-suppress-body <<\EOF
344 0001-Second.patch
345 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
346 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
347 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
348 Dry-OK. Log says:
349 Server: relay.example.com
350 MAIL FROM:<from@example.com>
351 RCPT TO:<to@example.com>,<author@example.com>,<one@example.com>,<two@example.com>
352 From: Example <from@example.com>
353 To: to@example.com
354 Cc: A <author@example.com>, One <one@example.com>, two@example.com
355 Subject: [PATCH 1/1] Second.
356 Date: DATE-STRING
357 Message-Id: MESSAGE-ID-STRING
358 X-Mailer: X-MAILER-STRING
360 Result: OK
363 test_expect_success '--suppress-cc=body' '
364 test_suppression body
367 cat >expected-suppress-sob <<\EOF
368 0001-Second.patch
369 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
370 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
371 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
372 Dry-OK. Log says:
373 Server: relay.example.com
374 MAIL FROM:<from@example.com>
375 RCPT TO:<to@example.com>,<author@example.com>,<one@example.com>,<two@example.com>
376 From: Example <from@example.com>
377 To: to@example.com
378 Cc: A <author@example.com>, One <one@example.com>, two@example.com
379 Subject: [PATCH 1/1] Second.
380 Date: DATE-STRING
381 Message-Id: MESSAGE-ID-STRING
382 X-Mailer: X-MAILER-STRING
384 Result: OK
387 test_expect_success '--suppress-cc=sob' '
388 test_suppression sob
391 cat >expected-suppress-bodycc <<\EOF
392 0001-Second.patch
393 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
394 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
395 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
396 (body) Adding cc: C O Mitter <committer@example.com> from line 'Signed-off-by: C O Mitter <committer@example.com>'
397 Dry-OK. Log says:
398 Server: relay.example.com
399 MAIL FROM:<from@example.com>
400 RCPT TO:<to@example.com>,<author@example.com>,<one@example.com>,<two@example.com>,<committer@example.com>
401 From: Example <from@example.com>
402 To: to@example.com
403 Cc: A <author@example.com>, One <one@example.com>, two@example.com, C O Mitter <committer@example.com>
404 Subject: [PATCH 1/1] Second.
405 Date: DATE-STRING
406 Message-Id: MESSAGE-ID-STRING
407 X-Mailer: X-MAILER-STRING
409 Result: OK
412 test_expect_success '--suppress-cc=bodycc' '
413 test_suppression bodycc
416 cat >expected-suppress-cc <<\EOF
417 0001-Second.patch
418 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
419 (body) Adding cc: C O Mitter <committer@example.com> from line 'Signed-off-by: C O Mitter <committer@example.com>'
420 Dry-OK. Log says:
421 Server: relay.example.com
422 MAIL FROM:<from@example.com>
423 RCPT TO:<to@example.com>,<author@example.com>,<committer@example.com>
424 From: Example <from@example.com>
425 To: to@example.com
426 Cc: A <author@example.com>, C O Mitter <committer@example.com>
427 Subject: [PATCH 1/1] Second.
428 Date: DATE-STRING
429 Message-Id: MESSAGE-ID-STRING
430 X-Mailer: X-MAILER-STRING
432 Result: OK
435 test_expect_success '--suppress-cc=cc' '
436 test_suppression cc
439 test_confirm () {
440 echo y | \
441 GIT_SEND_EMAIL_NOTTY=1 \
442 git send-email \
443 --from="Example <nobody@example.com>" \
444 --to=nobody@example.com \
445 --smtp-server="$(pwd)/fake.sendmail" \
446 $@ $patches > stdout &&
447 grep "Send this email" stdout
450 test_expect_success '--confirm=always' '
451 test_confirm --confirm=always --suppress-cc=all
454 test_expect_success '--confirm=auto' '
455 test_confirm --confirm=auto
458 test_expect_success '--confirm=cc' '
459 test_confirm --confirm=cc
462 test_expect_success '--confirm=compose' '
463 test_confirm --confirm=compose --compose
466 test_expect_success 'confirm by default (due to cc)' '
467 CONFIRM=$(git config --get sendemail.confirm) &&
468 git config --unset sendemail.confirm &&
469 test_confirm
470 ret="$?"
471 git config sendemail.confirm ${CONFIRM:-never}
472 test $ret = "0"
475 test_expect_success 'confirm by default (due to --compose)' '
476 CONFIRM=$(git config --get sendemail.confirm) &&
477 git config --unset sendemail.confirm &&
478 test_confirm --suppress-cc=all --compose
479 ret="$?"
480 git config sendemail.confirm ${CONFIRM:-never}
481 test $ret = "0"
484 test_expect_success 'confirm detects EOF (inform assumes y)' '
485 CONFIRM=$(git config --get sendemail.confirm) &&
486 git config --unset sendemail.confirm &&
487 rm -fr outdir &&
488 git format-patch -2 -o outdir &&
489 GIT_SEND_EMAIL_NOTTY=1 \
490 git send-email \
491 --from="Example <nobody@example.com>" \
492 --to=nobody@example.com \
493 --smtp-server="$(pwd)/fake.sendmail" \
494 outdir/*.patch < /dev/null
495 ret="$?"
496 git config sendemail.confirm ${CONFIRM:-never}
497 test $ret = "0"
500 test_expect_success 'confirm detects EOF (auto causes failure)' '
501 CONFIRM=$(git config --get sendemail.confirm) &&
502 git config sendemail.confirm auto &&
503 GIT_SEND_EMAIL_NOTTY=1 &&
504 export GIT_SEND_EMAIL_NOTTY &&
505 test_must_fail git send-email \
506 --from="Example <nobody@example.com>" \
507 --to=nobody@example.com \
508 --smtp-server="$(pwd)/fake.sendmail" \
509 $patches < /dev/null
510 ret="$?"
511 git config sendemail.confirm ${CONFIRM:-never}
512 test $ret = "0"
515 test_expect_success 'confirm doesnt loop forever' '
516 CONFIRM=$(git config --get sendemail.confirm) &&
517 git config sendemail.confirm auto &&
518 GIT_SEND_EMAIL_NOTTY=1 &&
519 export GIT_SEND_EMAIL_NOTTY &&
520 yes "bogus" | test_must_fail git send-email \
521 --from="Example <nobody@example.com>" \
522 --to=nobody@example.com \
523 --smtp-server="$(pwd)/fake.sendmail" \
524 $patches
525 ret="$?"
526 git config sendemail.confirm ${CONFIRM:-never}
527 test $ret = "0"
530 test_expect_success 'utf8 Cc is rfc2047 encoded' '
531 clean_fake_sendmail &&
532 rm -fr outdir &&
533 git format-patch -1 -o outdir --cc="àéìöú <utf8@example.com>" &&
534 git send-email \
535 --from="Example <nobody@example.com>" \
536 --to=nobody@example.com \
537 --smtp-server="$(pwd)/fake.sendmail" \
538 outdir/*.patch &&
539 grep "^Cc:" msgtxt1 |
540 grep "=?utf-8?q?=C3=A0=C3=A9=C3=AC=C3=B6=C3=BA?= <utf8@example.com>"
543 test_expect_success '--compose adds MIME for utf8 body' '
544 clean_fake_sendmail &&
545 (echo "#!$SHELL_PATH" &&
546 echo "echo utf8 body: àéìöú >>\"\$1\""
547 ) >fake-editor-utf8 &&
548 chmod +x fake-editor-utf8 &&
549 GIT_EDITOR="\"$(pwd)/fake-editor-utf8\"" \
550 git send-email \
551 --compose --subject foo \
552 --from="Example <nobody@example.com>" \
553 --to=nobody@example.com \
554 --smtp-server="$(pwd)/fake.sendmail" \
555 $patches &&
556 grep "^utf8 body" msgtxt1 &&
557 grep "^Content-Type: text/plain; charset=utf-8" msgtxt1
560 test_expect_success '--compose respects user mime type' '
561 clean_fake_sendmail &&
562 (echo "#!$SHELL_PATH" &&
563 echo "(echo MIME-Version: 1.0"
564 echo " echo Content-Type: text/plain\\; charset=iso-8859-1"
565 echo " echo Content-Transfer-Encoding: 8bit"
566 echo " echo Subject: foo"
567 echo " echo "
568 echo " echo utf8 body: àéìöú) >\"\$1\""
569 ) >fake-editor-utf8-mime &&
570 chmod +x fake-editor-utf8-mime &&
571 GIT_EDITOR="\"$(pwd)/fake-editor-utf8-mime\"" \
572 git send-email \
573 --compose --subject foo \
574 --from="Example <nobody@example.com>" \
575 --to=nobody@example.com \
576 --smtp-server="$(pwd)/fake.sendmail" \
577 $patches &&
578 grep "^utf8 body" msgtxt1 &&
579 grep "^Content-Type: text/plain; charset=iso-8859-1" msgtxt1 &&
580 ! grep "^Content-Type: text/plain; charset=utf-8" msgtxt1
583 test_expect_success '--compose adds MIME for utf8 subject' '
584 clean_fake_sendmail &&
585 GIT_EDITOR="\"$(pwd)/fake-editor\"" \
586 git send-email \
587 --compose --subject utf8-sübjëct \
588 --from="Example <nobody@example.com>" \
589 --to=nobody@example.com \
590 --smtp-server="$(pwd)/fake.sendmail" \
591 $patches &&
592 grep "^fake edit" msgtxt1 &&
593 grep "^Subject: =?utf-8?q?utf8-s=C3=BCbj=C3=ABct?=" msgtxt1
596 test_expect_success 'detects ambiguous reference/file conflict' '
597 echo master > master &&
598 git add master &&
599 git commit -m"add master" &&
600 test_must_fail git send-email --dry-run master 2>errors &&
601 grep disambiguate errors
604 test_expect_success 'feed two files' '
605 rm -fr outdir &&
606 git format-patch -2 -o outdir &&
607 git send-email \
608 --dry-run \
609 --from="Example <nobody@example.com>" \
610 --to=nobody@example.com \
611 outdir/000?-*.patch 2>errors >out &&
612 grep "^Subject: " out >subjects &&
613 test "z$(sed -n -e 1p subjects)" = "zSubject: [PATCH 1/2] Second." &&
614 test "z$(sed -n -e 2p subjects)" = "zSubject: [PATCH 2/2] add master"
617 test_expect_success 'in-reply-to but no threading' '
618 git send-email \
619 --dry-run \
620 --from="Example <nobody@example.com>" \
621 --to=nobody@example.com \
622 --in-reply-to="<in-reply-id@example.com>" \
623 --nothread \
624 $patches |
625 grep "In-Reply-To: <in-reply-id@example.com>"
628 test_done