Code

Merge branch 'js/maint-diff-temp-smudge'
[git.git] / t / t9001-send-email.sh
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*
32 }
34 test_expect_success 'Extract patches' '
35     patches=`git format-patch -s --cc="One <one@example.com>" --cc=two@example.com -n HEAD^1`
36 '
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
51 }
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
58         }
59 }
61 test_expect_success 'No confirm with --suppress-cc' '
62         test_no_confirm --suppress-cc=sob
63 '
64 check_no_confirm
66 test_expect_success 'No confirm with --confirm=never' '
67         test_no_confirm --confirm=never
68 '
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
76 '
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
81 '
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
113 EOF
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
254 EOF
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
294 EOF
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
315 EOF
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
339 EOF
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
363 EOF
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
388 EOF
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
411 EOF
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