test-lib: Introduce test_chmod and use it instead of update-index --chmod
[alt-git.git] / t / t9001-send-email.sh
blobe426c96fb7d0f72b2822d4379b7fa671a04ab733
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 z8=zzzzzzzz
134 z64=$z8$z8$z8$z8$z8$z8$z8$z8
135 z512=$z64$z64$z64$z64$z64$z64$z64$z64
136 test_expect_success 'reject long lines' '
137 clean_fake_sendmail &&
138 cp $patches longline.patch &&
139 echo $z512$z512 >>longline.patch &&
140 test_must_fail git send-email \
141 --from="Example <nobody@example.com>" \
142 --to=nobody@example.com \
143 --smtp-server="$(pwd)/fake.sendmail" \
144 $patches longline.patch \
145 2>errors &&
146 grep longline.patch errors
149 test_expect_success 'no patch was sent' '
150 ! test -e commandline1
153 test_expect_success 'Author From: in message body' '
154 clean_fake_sendmail &&
155 git send-email \
156 --from="Example <nobody@example.com>" \
157 --to=nobody@example.com \
158 --smtp-server="$(pwd)/fake.sendmail" \
159 $patches &&
160 sed "1,/^$/d" < msgtxt1 > msgbody1
161 grep "From: A <author@example.com>" msgbody1
164 test_expect_success 'Author From: not in message body' '
165 clean_fake_sendmail &&
166 git send-email \
167 --from="A <author@example.com>" \
168 --to=nobody@example.com \
169 --smtp-server="$(pwd)/fake.sendmail" \
170 $patches &&
171 sed "1,/^$/d" < msgtxt1 > msgbody1
172 ! grep "From: A <author@example.com>" msgbody1
175 test_expect_success 'allow long lines with --no-validate' '
176 git send-email \
177 --from="Example <nobody@example.com>" \
178 --to=nobody@example.com \
179 --smtp-server="$(pwd)/fake.sendmail" \
180 --novalidate \
181 $patches longline.patch \
182 2>errors
185 test_expect_success 'Invalid In-Reply-To' '
186 clean_fake_sendmail &&
187 git send-email \
188 --from="Example <nobody@example.com>" \
189 --to=nobody@example.com \
190 --in-reply-to=" " \
191 --smtp-server="$(pwd)/fake.sendmail" \
192 $patches
193 2>errors
194 ! grep "^In-Reply-To: < *>" msgtxt1
197 test_expect_success 'Valid In-Reply-To when prompting' '
198 clean_fake_sendmail &&
199 (echo "From Example <from@example.com>"
200 echo "To Example <to@example.com>"
201 echo ""
202 ) | env GIT_SEND_EMAIL_NOTTY=1 git send-email \
203 --smtp-server="$(pwd)/fake.sendmail" \
204 $patches 2>errors &&
205 ! grep "^In-Reply-To: < *>" msgtxt1
208 test_expect_success 'setup fake editor' '
209 (echo "#!$SHELL_PATH" &&
210 echo "echo fake edit >>\"\$1\""
211 ) >fake-editor &&
212 chmod +x fake-editor
215 test_set_editor "$(pwd)/fake-editor"
217 test_expect_success '--compose works' '
218 clean_fake_sendmail &&
219 git send-email \
220 --compose --subject foo \
221 --from="Example <nobody@example.com>" \
222 --to=nobody@example.com \
223 --smtp-server="$(pwd)/fake.sendmail" \
224 $patches \
225 2>errors
228 test_expect_success 'first message is compose text' '
229 grep "^fake edit" msgtxt1
232 test_expect_success 'second message is patch' '
233 grep "Subject:.*Second" msgtxt2
236 cat >expected-suppress-sob <<\EOF
237 0001-Second.patch
238 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
239 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
240 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
241 Dry-OK. Log says:
242 Server: relay.example.com
243 MAIL FROM:<from@example.com>
244 RCPT TO:<to@example.com>,<cc@example.com>,<author@example.com>,<one@example.com>,<two@example.com>
245 From: Example <from@example.com>
246 To: to@example.com
247 Cc: cc@example.com, A <author@example.com>, One <one@example.com>, two@example.com
248 Subject: [PATCH 1/1] Second.
249 Date: DATE-STRING
250 Message-Id: MESSAGE-ID-STRING
251 X-Mailer: X-MAILER-STRING
253 Result: OK
256 test_suppression () {
257 git send-email \
258 --dry-run \
259 --suppress-cc=$1 \
260 --from="Example <from@example.com>" \
261 --to=to@example.com \
262 --smtp-server relay.example.com \
263 $patches |
264 sed -e "s/^\(Date:\).*/\1 DATE-STRING/" \
265 -e "s/^\(Message-Id:\).*/\1 MESSAGE-ID-STRING/" \
266 -e "s/^\(X-Mailer:\).*/\1 X-MAILER-STRING/" \
267 >actual-suppress-$1 &&
268 test_cmp expected-suppress-$1 actual-suppress-$1
271 test_expect_success 'sendemail.cc set' '
272 git config sendemail.cc cc@example.com &&
273 test_suppression sob
276 cat >expected-suppress-sob <<\EOF
277 0001-Second.patch
278 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
279 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
280 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
281 Dry-OK. Log says:
282 Server: relay.example.com
283 MAIL FROM:<from@example.com>
284 RCPT TO:<to@example.com>,<author@example.com>,<one@example.com>,<two@example.com>
285 From: Example <from@example.com>
286 To: to@example.com
287 Cc: A <author@example.com>, One <one@example.com>, two@example.com
288 Subject: [PATCH 1/1] Second.
289 Date: DATE-STRING
290 Message-Id: MESSAGE-ID-STRING
291 X-Mailer: X-MAILER-STRING
293 Result: OK
296 test_expect_success 'sendemail.cc unset' '
297 git config --unset sendemail.cc &&
298 test_suppression sob
301 cat >expected-suppress-all <<\EOF
302 0001-Second.patch
303 Dry-OK. Log says:
304 Server: relay.example.com
305 MAIL FROM:<from@example.com>
306 RCPT TO:<to@example.com>
307 From: Example <from@example.com>
308 To: to@example.com
309 Subject: [PATCH 1/1] Second.
310 Date: DATE-STRING
311 Message-Id: MESSAGE-ID-STRING
312 X-Mailer: X-MAILER-STRING
314 Result: OK
317 test_expect_success '--suppress-cc=all' '
318 test_suppression all
321 cat >expected-suppress-body <<\EOF
322 0001-Second.patch
323 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
324 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
325 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
326 Dry-OK. Log says:
327 Server: relay.example.com
328 MAIL FROM:<from@example.com>
329 RCPT TO:<to@example.com>,<author@example.com>,<one@example.com>,<two@example.com>
330 From: Example <from@example.com>
331 To: to@example.com
332 Cc: A <author@example.com>, One <one@example.com>, two@example.com
333 Subject: [PATCH 1/1] Second.
334 Date: DATE-STRING
335 Message-Id: MESSAGE-ID-STRING
336 X-Mailer: X-MAILER-STRING
338 Result: OK
341 test_expect_success '--suppress-cc=body' '
342 test_suppression body
345 cat >expected-suppress-sob <<\EOF
346 0001-Second.patch
347 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
348 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
349 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
350 Dry-OK. Log says:
351 Server: relay.example.com
352 MAIL FROM:<from@example.com>
353 RCPT TO:<to@example.com>,<author@example.com>,<one@example.com>,<two@example.com>
354 From: Example <from@example.com>
355 To: to@example.com
356 Cc: A <author@example.com>, One <one@example.com>, two@example.com
357 Subject: [PATCH 1/1] Second.
358 Date: DATE-STRING
359 Message-Id: MESSAGE-ID-STRING
360 X-Mailer: X-MAILER-STRING
362 Result: OK
365 test_expect_success '--suppress-cc=sob' '
366 test_suppression sob
369 cat >expected-suppress-bodycc <<\EOF
370 0001-Second.patch
371 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
372 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
373 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
374 (body) Adding cc: C O Mitter <committer@example.com> from line 'Signed-off-by: C O Mitter <committer@example.com>'
375 Dry-OK. Log says:
376 Server: relay.example.com
377 MAIL FROM:<from@example.com>
378 RCPT TO:<to@example.com>,<author@example.com>,<one@example.com>,<two@example.com>,<committer@example.com>
379 From: Example <from@example.com>
380 To: to@example.com
381 Cc: A <author@example.com>, One <one@example.com>, two@example.com, C O Mitter <committer@example.com>
382 Subject: [PATCH 1/1] Second.
383 Date: DATE-STRING
384 Message-Id: MESSAGE-ID-STRING
385 X-Mailer: X-MAILER-STRING
387 Result: OK
390 test_expect_success '--suppress-cc=bodycc' '
391 test_suppression bodycc
394 cat >expected-suppress-cc <<\EOF
395 0001-Second.patch
396 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
397 (body) Adding cc: C O Mitter <committer@example.com> from line 'Signed-off-by: C O Mitter <committer@example.com>'
398 Dry-OK. Log says:
399 Server: relay.example.com
400 MAIL FROM:<from@example.com>
401 RCPT TO:<to@example.com>,<author@example.com>,<committer@example.com>
402 From: Example <from@example.com>
403 To: to@example.com
404 Cc: A <author@example.com>, C O Mitter <committer@example.com>
405 Subject: [PATCH 1/1] Second.
406 Date: DATE-STRING
407 Message-Id: MESSAGE-ID-STRING
408 X-Mailer: X-MAILER-STRING
410 Result: OK
413 test_expect_success '--suppress-cc=cc' '
414 test_suppression cc
417 test_confirm () {
418 echo y | \
419 GIT_SEND_EMAIL_NOTTY=1 \
420 git send-email \
421 --from="Example <nobody@example.com>" \
422 --to=nobody@example.com \
423 --smtp-server="$(pwd)/fake.sendmail" \
424 $@ \
425 $patches | grep "Send this email"
428 test_expect_success '--confirm=always' '
429 test_confirm --confirm=always --suppress-cc=all
432 test_expect_success '--confirm=auto' '
433 test_confirm --confirm=auto
436 test_expect_success '--confirm=cc' '
437 test_confirm --confirm=cc
440 test_expect_success '--confirm=compose' '
441 test_confirm --confirm=compose --compose
444 test_expect_success 'confirm by default (due to cc)' '
445 CONFIRM=$(git config --get sendemail.confirm) &&
446 git config --unset sendemail.confirm &&
447 test_confirm &&
448 git config sendemail.confirm $CONFIRM
451 test_expect_success 'confirm by default (due to --compose)' '
452 CONFIRM=$(git config --get sendemail.confirm) &&
453 git config --unset sendemail.confirm &&
454 test_confirm --suppress-cc=all --compose
455 ret="$?"
456 git config sendemail.confirm ${CONFIRM:-never}
457 test $ret = "0"
460 test_expect_success '--compose adds MIME for utf8 body' '
461 clean_fake_sendmail &&
462 (echo "#!$SHELL_PATH" &&
463 echo "echo utf8 body: àéìöú >>\"\$1\""
464 ) >fake-editor-utf8 &&
465 chmod +x fake-editor-utf8 &&
466 GIT_EDITOR="\"$(pwd)/fake-editor-utf8\"" \
467 git send-email \
468 --compose --subject foo \
469 --from="Example <nobody@example.com>" \
470 --to=nobody@example.com \
471 --smtp-server="$(pwd)/fake.sendmail" \
472 $patches &&
473 grep "^utf8 body" msgtxt1 &&
474 grep "^Content-Type: text/plain; charset=utf-8" msgtxt1
477 test_expect_success '--compose respects user mime type' '
478 clean_fake_sendmail &&
479 (echo "#!$SHELL_PATH" &&
480 echo "(echo MIME-Version: 1.0"
481 echo " echo Content-Type: text/plain\\; charset=iso-8859-1"
482 echo " echo Content-Transfer-Encoding: 8bit"
483 echo " echo Subject: foo"
484 echo " echo "
485 echo " echo utf8 body: àéìöú) >\"\$1\""
486 ) >fake-editor-utf8-mime &&
487 chmod +x fake-editor-utf8-mime &&
488 GIT_EDITOR="\"$(pwd)/fake-editor-utf8-mime\"" \
489 git send-email \
490 --compose --subject foo \
491 --from="Example <nobody@example.com>" \
492 --to=nobody@example.com \
493 --smtp-server="$(pwd)/fake.sendmail" \
494 $patches &&
495 grep "^utf8 body" msgtxt1 &&
496 grep "^Content-Type: text/plain; charset=iso-8859-1" msgtxt1 &&
497 ! grep "^Content-Type: text/plain; charset=utf-8" msgtxt1
500 test_expect_success '--compose adds MIME for utf8 subject' '
501 clean_fake_sendmail &&
502 GIT_EDITOR="\"$(pwd)/fake-editor\"" \
503 git send-email \
504 --compose --subject utf8-sübjëct \
505 --from="Example <nobody@example.com>" \
506 --to=nobody@example.com \
507 --smtp-server="$(pwd)/fake.sendmail" \
508 $patches &&
509 grep "^fake edit" msgtxt1 &&
510 grep "^Subject: =?utf-8?q?utf8-s=C3=BCbj=C3=ABct?=" msgtxt1
513 test_expect_success 'detects ambiguous reference/file conflict' '
514 echo master > master &&
515 git add master &&
516 git commit -m"add master" &&
517 test_must_fail git send-email --dry-run master 2>errors &&
518 grep disambiguate errors
521 test_expect_success 'feed two files' '
522 rm -fr outdir &&
523 git format-patch -2 -o outdir &&
524 git send-email \
525 --dry-run \
526 --from="Example <nobody@example.com>" \
527 --to=nobody@example.com \
528 outdir/000?-*.patch 2>errors >out &&
529 grep "^Subject: " out >subjects &&
530 test "z$(sed -n -e 1p subjects)" = "zSubject: [PATCH 1/2] Second." &&
531 test "z$(sed -n -e 2p subjects)" = "zSubject: [PATCH 2/2] add master"
534 test_expect_success 'in-reply-to but no threading' '
535 git send-email \
536 --dry-run \
537 --from="Example <nobody@example.com>" \
538 --to=nobody@example.com \
539 --in-reply-to="<in-reply-id@example.com>" \
540 --no-thread \
541 $patches |
542 grep "In-Reply-To: <in-reply-id@example.com>"
545 test_done