3 test_description
='git send-email'
6 if ! test_have_prereq PERL
; then
7 say
'skipping git send-email tests, perl not available'
13 'prepare reference tree' \
14 'echo "1A quick brown fox jumps over the" >file &&
15 echo "lazy dog" >>file &&
17 GIT_AUTHOR_NAME="A" git commit -a -m "Initial."'
21 '(echo "#!$SHELL_PATH"
24 echo "while test -f commandline\$output; do output=\$((\$output+1)); done"
27 echo " echo \"!\$a!\""
28 echo "done >commandline\$output"
29 echo "cat > msgtxt\$output"
31 chmod +x ./fake.sendmail &&
32 git add fake.sendmail &&
33 GIT_AUTHOR_NAME="A" git commit -a -m "Second."'
35 clean_fake_sendmail
() {
36 rm -f commandline
* msgtxt
*
39 test_expect_success
'Extract patches' '
40 patches=`git format-patch -s --cc="One <one@example.com>" --cc=two@example.com -n HEAD^1`
43 # Test no confirm early to ensure remaining tests will not hang
47 GIT_SEND_EMAIL_NOTTY
=1 \
49 --from="Example <from@example.com>" \
50 --to=nobody@example.com \
51 --smtp-server="$(pwd)/fake.sendmail" \
54 test_must_fail
grep "Send this email" stdout
&&
58 # Exit immediately to prevent hang if a no-confirm test fails
60 test -f no_confirm_okay ||
{
61 say
'No confirm test failed; skipping remaining tests to prevent hanging'
66 test_expect_success
'No confirm with --suppress-cc' '
67 test_no_confirm --suppress-cc=sob
71 test_expect_success
'No confirm with --confirm=never' '
72 test_no_confirm --confirm=never
76 # leave sendemail.confirm set to never after this so that none of the
77 # remaining tests prompt unintentionally.
78 test_expect_success
'No confirm with sendemail.confirm=never' '
79 git config sendemail.confirm never &&
80 test_no_confirm --compose --subject=foo
84 test_expect_success
'Send patches' '
85 git send-email --suppress-cc=sob --from="Example <nobody@example.com>" --to=nobody@example.com --smtp-server="$(pwd)/fake.sendmail" $patches 2>errors
95 'Verify commandline' \
96 'test_cmp expected commandline1'
98 cat >expected-show-all-headers
<<\EOF
100 (mbox
) Adding cc
: A
<author@example.com
> from line
'From: A <author@example.com>'
101 (mbox
) Adding cc
: One
<one@example.com
> from line
'Cc: One <one@example.com>, two@example.com'
102 (mbox
) Adding cc
: two@example.com from line
'Cc: One <one@example.com>, two@example.com'
104 Server
: relay.example.com
105 MAIL FROM
:<from@example.com
>
106 RCPT TO
:<to@example.com
>,<cc@example.com
>,<author@example.com
>,<one@example.com
>,<two@example.com
>,<bcc@example.com
>
107 From
: Example
<from@example.com
>
109 Cc
: cc@example.com
, A
<author@example.com
>, One
<one@example.com
>, two@example.com
110 Subject
: [PATCH
1/1] Second.
112 Message-Id
: MESSAGE-ID-STRING
113 X-Mailer
: X-MAILER-STRING
114 In-Reply-To
: <unique-message-id@example.com
>
115 References
: <unique-message-id@example.com
>
120 test_expect_success
'Show all headers' '
124 --from="Example <from@example.com>" \
125 --to=to@example.com \
126 --cc=cc@example.com \
127 --bcc=bcc@example.com \
128 --in-reply-to="<unique-message-id@example.com>" \
129 --smtp-server relay.example.com \
131 sed -e "s/^\(Date:\).*/\1 DATE-STRING/" \
132 -e "s/^\(Message-Id:\).*/\1 MESSAGE-ID-STRING/" \
133 -e "s/^\(X-Mailer:\).*/\1 X-MAILER-STRING/" \
134 >actual-show-all-headers &&
135 test_cmp expected-show-all-headers actual-show-all-headers
138 test_expect_success
'Prompting works' '
139 clean_fake_sendmail &&
140 (echo "Example <from@example.com>"
141 echo "to@example.com"
143 ) | GIT_SEND_EMAIL_NOTTY=1 git send-email \
144 --smtp-server="$(pwd)/fake.sendmail" \
147 grep "^From: Example <from@example.com>$" msgtxt1 &&
148 grep "^To: to@example.com$" msgtxt1
152 z64
=$z8$z8$z8$z8$z8$z8$z8$z8
153 z512
=$z64$z64$z64$z64$z64$z64$z64$z64
154 test_expect_success
'reject long lines' '
155 clean_fake_sendmail &&
156 cp $patches longline.patch &&
157 echo $z512$z512 >>longline.patch &&
158 test_must_fail git send-email \
159 --from="Example <nobody@example.com>" \
160 --to=nobody@example.com \
161 --smtp-server="$(pwd)/fake.sendmail" \
162 $patches longline.patch \
164 grep longline.patch errors
167 test_expect_success
'no patch was sent' '
168 ! test -e commandline1
171 test_expect_success
'Author From: in message body' '
172 clean_fake_sendmail &&
174 --from="Example <nobody@example.com>" \
175 --to=nobody@example.com \
176 --smtp-server="$(pwd)/fake.sendmail" \
178 sed "1,/^$/d" < msgtxt1 > msgbody1
179 grep "From: A <author@example.com>" msgbody1
182 test_expect_success
'Author From: not in message body' '
183 clean_fake_sendmail &&
185 --from="A <author@example.com>" \
186 --to=nobody@example.com \
187 --smtp-server="$(pwd)/fake.sendmail" \
189 sed "1,/^$/d" < msgtxt1 > msgbody1
190 ! grep "From: A <author@example.com>" msgbody1
193 test_expect_success
'allow long lines with --no-validate' '
195 --from="Example <nobody@example.com>" \
196 --to=nobody@example.com \
197 --smtp-server="$(pwd)/fake.sendmail" \
199 $patches longline.patch \
203 test_expect_success
'Invalid In-Reply-To' '
204 clean_fake_sendmail &&
206 --from="Example <nobody@example.com>" \
207 --to=nobody@example.com \
209 --smtp-server="$(pwd)/fake.sendmail" \
212 ! grep "^In-Reply-To: < *>" msgtxt1
215 test_expect_success
'Valid In-Reply-To when prompting' '
216 clean_fake_sendmail &&
217 (echo "From Example <from@example.com>"
218 echo "To Example <to@example.com>"
220 ) | env GIT_SEND_EMAIL_NOTTY=1 git send-email \
221 --smtp-server="$(pwd)/fake.sendmail" \
223 ! grep "^In-Reply-To: < *>" msgtxt1
226 test_expect_success
'setup fake editor' '
227 (echo "#!$SHELL_PATH" &&
228 echo "echo fake edit >>\"\$1\""
233 test_set_editor
"$(pwd)/fake-editor"
235 test_expect_success
'--compose works' '
236 clean_fake_sendmail &&
238 --compose --subject foo \
239 --from="Example <nobody@example.com>" \
240 --to=nobody@example.com \
241 --smtp-server="$(pwd)/fake.sendmail" \
246 test_expect_success
'first message is compose text' '
247 grep "^fake edit" msgtxt1
250 test_expect_success
'second message is patch' '
251 grep "Subject:.*Second" msgtxt2
254 cat >expected-suppress-sob
<<\EOF
256 (mbox
) Adding cc
: A
<author@example.com
> from line
'From: A <author@example.com>'
257 (mbox
) Adding cc
: One
<one@example.com
> from line
'Cc: One <one@example.com>, two@example.com'
258 (mbox
) Adding cc
: two@example.com from line
'Cc: One <one@example.com>, two@example.com'
260 Server
: relay.example.com
261 MAIL FROM
:<from@example.com
>
262 RCPT TO
:<to@example.com
>,<cc@example.com
>,<author@example.com
>,<one@example.com
>,<two@example.com
>
263 From
: Example
<from@example.com
>
265 Cc
: cc@example.com
, A
<author@example.com
>, One
<one@example.com
>, two@example.com
266 Subject
: [PATCH
1/1] Second.
268 Message-Id
: MESSAGE-ID-STRING
269 X-Mailer
: X-MAILER-STRING
274 test_suppression
() {
278 --from="Example <from@example.com>" \
279 --to=to@example.com \
280 --smtp-server relay.example.com \
282 sed -e "s/^\(Date:\).*/\1 DATE-STRING/" \
283 -e "s/^\(Message-Id:\).*/\1 MESSAGE-ID-STRING/" \
284 -e "s/^\(X-Mailer:\).*/\1 X-MAILER-STRING/" \
285 >actual-suppress-
$1 &&
286 test_cmp expected-suppress-
$1 actual-suppress-
$1
289 test_expect_success
'sendemail.cc set' '
290 git config sendemail.cc cc@example.com &&
294 cat >expected-suppress-sob
<<\EOF
296 (mbox
) Adding cc
: A
<author@example.com
> from line
'From: A <author@example.com>'
297 (mbox
) Adding cc
: One
<one@example.com
> from line
'Cc: One <one@example.com>, two@example.com'
298 (mbox
) Adding cc
: two@example.com from line
'Cc: One <one@example.com>, two@example.com'
300 Server
: relay.example.com
301 MAIL FROM
:<from@example.com
>
302 RCPT TO
:<to@example.com
>,<author@example.com
>,<one@example.com
>,<two@example.com
>
303 From
: Example
<from@example.com
>
305 Cc
: A
<author@example.com
>, One
<one@example.com
>, two@example.com
306 Subject
: [PATCH
1/1] Second.
308 Message-Id
: MESSAGE-ID-STRING
309 X-Mailer
: X-MAILER-STRING
314 test_expect_success
'sendemail.cc unset' '
315 git config --unset sendemail.cc &&
319 cat >expected-suppress-all
<<\EOF
322 Server
: relay.example.com
323 MAIL FROM
:<from@example.com
>
324 RCPT TO
:<to@example.com
>
325 From
: Example
<from@example.com
>
327 Subject
: [PATCH
1/1] Second.
329 Message-Id
: MESSAGE-ID-STRING
330 X-Mailer
: X-MAILER-STRING
335 test_expect_success
'--suppress-cc=all' '
339 cat >expected-suppress-body
<<\EOF
341 (mbox
) Adding cc
: A
<author@example.com
> from line
'From: A <author@example.com>'
342 (mbox
) Adding cc
: One
<one@example.com
> from line
'Cc: One <one@example.com>, two@example.com'
343 (mbox
) Adding cc
: two@example.com from line
'Cc: One <one@example.com>, two@example.com'
345 Server
: relay.example.com
346 MAIL FROM
:<from@example.com
>
347 RCPT TO
:<to@example.com
>,<author@example.com
>,<one@example.com
>,<two@example.com
>
348 From
: Example
<from@example.com
>
350 Cc
: A
<author@example.com
>, One
<one@example.com
>, two@example.com
351 Subject
: [PATCH
1/1] Second.
353 Message-Id
: MESSAGE-ID-STRING
354 X-Mailer
: X-MAILER-STRING
359 test_expect_success
'--suppress-cc=body' '
360 test_suppression body
363 cat >expected-suppress-sob
<<\EOF
365 (mbox
) Adding cc
: A
<author@example.com
> from line
'From: A <author@example.com>'
366 (mbox
) Adding cc
: One
<one@example.com
> from line
'Cc: One <one@example.com>, two@example.com'
367 (mbox
) Adding cc
: two@example.com from line
'Cc: One <one@example.com>, two@example.com'
369 Server
: relay.example.com
370 MAIL FROM
:<from@example.com
>
371 RCPT TO
:<to@example.com
>,<author@example.com
>,<one@example.com
>,<two@example.com
>
372 From
: Example
<from@example.com
>
374 Cc
: A
<author@example.com
>, One
<one@example.com
>, two@example.com
375 Subject
: [PATCH
1/1] Second.
377 Message-Id
: MESSAGE-ID-STRING
378 X-Mailer
: X-MAILER-STRING
383 test_expect_success
'--suppress-cc=sob' '
387 cat >expected-suppress-bodycc
<<\EOF
389 (mbox
) Adding cc
: A
<author@example.com
> from line
'From: A <author@example.com>'
390 (mbox
) Adding cc
: One
<one@example.com
> from line
'Cc: One <one@example.com>, two@example.com'
391 (mbox
) Adding cc
: two@example.com from line
'Cc: One <one@example.com>, two@example.com'
392 (body
) Adding cc
: C O Mitter
<committer@example.com
> from line
'Signed-off-by: C O Mitter <committer@example.com>'
394 Server
: relay.example.com
395 MAIL FROM
:<from@example.com
>
396 RCPT TO
:<to@example.com
>,<author@example.com
>,<one@example.com
>,<two@example.com
>,<committer@example.com
>
397 From
: Example
<from@example.com
>
399 Cc
: A
<author@example.com
>, One
<one@example.com
>, two@example.com
, C O Mitter
<committer@example.com
>
400 Subject
: [PATCH
1/1] Second.
402 Message-Id
: MESSAGE-ID-STRING
403 X-Mailer
: X-MAILER-STRING
408 test_expect_success
'--suppress-cc=bodycc' '
409 test_suppression bodycc
412 cat >expected-suppress-cc
<<\EOF
414 (mbox
) Adding cc
: A
<author@example.com
> from line
'From: A <author@example.com>'
415 (body
) Adding cc
: C O Mitter
<committer@example.com
> from line
'Signed-off-by: C O Mitter <committer@example.com>'
417 Server
: relay.example.com
418 MAIL FROM
:<from@example.com
>
419 RCPT TO
:<to@example.com
>,<author@example.com
>,<committer@example.com
>
420 From
: Example
<from@example.com
>
422 Cc
: A
<author@example.com
>, C O Mitter
<committer@example.com
>
423 Subject
: [PATCH
1/1] Second.
425 Message-Id
: MESSAGE-ID-STRING
426 X-Mailer
: X-MAILER-STRING
431 test_expect_success
'--suppress-cc=cc' '
437 GIT_SEND_EMAIL_NOTTY
=1 \
439 --from="Example <nobody@example.com>" \
440 --to=nobody@example.com \
441 --smtp-server="$(pwd)/fake.sendmail" \
442 $@
$patches > stdout
&&
443 grep "Send this email" stdout
446 test_expect_success
'--confirm=always' '
447 test_confirm --confirm=always --suppress-cc=all
450 test_expect_success
'--confirm=auto' '
451 test_confirm --confirm=auto
454 test_expect_success
'--confirm=cc' '
455 test_confirm --confirm=cc
458 test_expect_success
'--confirm=compose' '
459 test_confirm --confirm=compose --compose
462 test_expect_success
'confirm by default (due to cc)' '
463 CONFIRM=$(git config --get sendemail.confirm) &&
464 git config --unset sendemail.confirm &&
467 git config sendemail.confirm ${CONFIRM:-never}
471 test_expect_success
'confirm by default (due to --compose)' '
472 CONFIRM=$(git config --get sendemail.confirm) &&
473 git config --unset sendemail.confirm &&
474 test_confirm --suppress-cc=all --compose
476 git config sendemail.confirm ${CONFIRM:-never}
480 test_expect_success
'confirm detects EOF (inform assumes y)' '
481 CONFIRM=$(git config --get sendemail.confirm) &&
482 git config --unset sendemail.confirm &&
484 git format-patch -2 -o outdir &&
485 GIT_SEND_EMAIL_NOTTY=1 \
487 --from="Example <nobody@example.com>" \
488 --to=nobody@example.com \
489 --smtp-server="$(pwd)/fake.sendmail" \
490 outdir/*.patch < /dev/null
492 git config sendemail.confirm ${CONFIRM:-never}
496 test_expect_success
'confirm detects EOF (auto causes failure)' '
497 CONFIRM=$(git config --get sendemail.confirm) &&
498 git config sendemail.confirm auto &&
499 GIT_SEND_EMAIL_NOTTY=1 &&
500 export GIT_SEND_EMAIL_NOTTY &&
501 test_must_fail git send-email \
502 --from="Example <nobody@example.com>" \
503 --to=nobody@example.com \
504 --smtp-server="$(pwd)/fake.sendmail" \
507 git config sendemail.confirm ${CONFIRM:-never}
511 test_expect_success
'confirm doesnt loop forever' '
512 CONFIRM=$(git config --get sendemail.confirm) &&
513 git config sendemail.confirm auto &&
514 GIT_SEND_EMAIL_NOTTY=1 &&
515 export GIT_SEND_EMAIL_NOTTY &&
516 yes "bogus" | test_must_fail git send-email \
517 --from="Example <nobody@example.com>" \
518 --to=nobody@example.com \
519 --smtp-server="$(pwd)/fake.sendmail" \
522 git config sendemail.confirm ${CONFIRM:-never}
526 test_expect_success
'utf8 Cc is rfc2047 encoded' '
527 clean_fake_sendmail &&
529 git format-patch -1 -o outdir --cc="àéìöú <utf8@example.com>" &&
531 --from="Example <nobody@example.com>" \
532 --to=nobody@example.com \
533 --smtp-server="$(pwd)/fake.sendmail" \
535 grep "^Cc:" msgtxt1 |
536 grep "=?UTF-8?q?=C3=A0=C3=A9=C3=AC=C3=B6=C3=BA?= <utf8@example.com>"
539 test_expect_success
'--compose adds MIME for utf8 body' '
540 clean_fake_sendmail &&
541 (echo "#!$SHELL_PATH" &&
542 echo "echo utf8 body: àéìöú >>\"\$1\""
543 ) >fake-editor-utf8 &&
544 chmod +x fake-editor-utf8 &&
545 GIT_EDITOR="\"$(pwd)/fake-editor-utf8\"" \
547 --compose --subject foo \
548 --from="Example <nobody@example.com>" \
549 --to=nobody@example.com \
550 --smtp-server="$(pwd)/fake.sendmail" \
552 grep "^utf8 body" msgtxt1 &&
553 grep "^Content-Type: text/plain; charset=UTF-8" msgtxt1
556 test_expect_success
'--compose respects user mime type' '
557 clean_fake_sendmail &&
558 (echo "#!$SHELL_PATH" &&
559 echo "(echo MIME-Version: 1.0"
560 echo " echo Content-Type: text/plain\\; charset=iso-8859-1"
561 echo " echo Content-Transfer-Encoding: 8bit"
562 echo " echo Subject: foo"
564 echo " echo utf8 body: àéìöú) >\"\$1\""
565 ) >fake-editor-utf8-mime &&
566 chmod +x fake-editor-utf8-mime &&
567 GIT_EDITOR="\"$(pwd)/fake-editor-utf8-mime\"" \
569 --compose --subject foo \
570 --from="Example <nobody@example.com>" \
571 --to=nobody@example.com \
572 --smtp-server="$(pwd)/fake.sendmail" \
574 grep "^utf8 body" msgtxt1 &&
575 grep "^Content-Type: text/plain; charset=iso-8859-1" msgtxt1 &&
576 ! grep "^Content-Type: text/plain; charset=UTF-8" msgtxt1
579 test_expect_success
'--compose adds MIME for utf8 subject' '
580 clean_fake_sendmail &&
581 GIT_EDITOR="\"$(pwd)/fake-editor\"" \
583 --compose --subject utf8-sübjëct \
584 --from="Example <nobody@example.com>" \
585 --to=nobody@example.com \
586 --smtp-server="$(pwd)/fake.sendmail" \
588 grep "^fake edit" msgtxt1 &&
589 grep "^Subject: =?UTF-8?q?utf8-s=C3=BCbj=C3=ABct?=" msgtxt1
592 test_expect_success
'detects ambiguous reference/file conflict' '
593 echo master > master &&
595 git commit -m"add master" &&
596 test_must_fail git send-email --dry-run master 2>errors &&
597 grep disambiguate errors
600 test_expect_success
'feed two files' '
602 git format-patch -2 -o outdir &&
605 --from="Example <nobody@example.com>" \
606 --to=nobody@example.com \
607 outdir/000?-*.patch 2>errors >out &&
608 grep "^Subject: " out >subjects &&
609 test "z$(sed -n -e 1p subjects)" = "zSubject: [PATCH 1/2] Second." &&
610 test "z$(sed -n -e 2p subjects)" = "zSubject: [PATCH 2/2] add master"
613 test_expect_success
'in-reply-to but no threading' '
616 --from="Example <nobody@example.com>" \
617 --to=nobody@example.com \
618 --in-reply-to="<in-reply-id@example.com>" \
621 grep "In-Reply-To: <in-reply-id@example.com>"