Merge branch 'zh/commit-trailer'
[git] / t / t9001-send-email.sh
1 #!/bin/sh
2
3 test_description='git send-email'
4 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
5 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
6
7 . ./test-lib.sh
8
9 # May be altered later in the test
10 PREREQ="PERL"
11
12 replace_variable_fields () {
13         sed     -e "s/^\(Date:\).*/\1 DATE-STRING/" \
14                 -e "s/^\(Message-Id:\).*/\1 MESSAGE-ID-STRING/" \
15                 -e "s/^\(X-Mailer:\).*/\1 X-MAILER-STRING/"
16 }
17
18 test_expect_success $PREREQ 'prepare reference tree' '
19         echo "1A quick brown fox jumps over the" >file &&
20         echo "lazy dog" >>file &&
21         git add file &&
22         GIT_AUTHOR_NAME="A" git commit -a -m "Initial."
23 '
24
25 test_expect_success $PREREQ 'Setup helper tool' '
26         write_script fake.sendmail <<-\EOF &&
27         shift
28         output=1
29         while test -f commandline$output
30         do
31                 output=$(($output+1))
32         done
33         for a
34         do
35                 echo "!$a!"
36         done >commandline$output
37         cat >"msgtxt$output"
38         EOF
39         git add fake.sendmail &&
40         GIT_AUTHOR_NAME="A" git commit -a -m "Second."
41 '
42
43 clean_fake_sendmail () {
44         rm -f commandline* msgtxt*
45 }
46
47 test_expect_success $PREREQ 'Extract patches' '
48         patches=$(git format-patch -s --cc="One <one@example.com>" --cc=two@example.com -n HEAD^1) &&
49         threaded_patches=$(git format-patch -o threaded -s --in-reply-to="format" HEAD^1)
50 '
51
52 # Test no confirm early to ensure remaining tests will not hang
53 test_no_confirm () {
54         rm -f no_confirm_okay
55         echo n | \
56                 GIT_SEND_EMAIL_NOTTY=1 \
57                 git send-email \
58                 --from="Example <from@example.com>" \
59                 --to=nobody@example.com \
60                 --smtp-server="$(pwd)/fake.sendmail" \
61                 $@ \
62                 $patches >stdout &&
63                 ! grep "Send this email" stdout &&
64                 >no_confirm_okay
65 }
66
67 # Exit immediately to prevent hang if a no-confirm test fails
68 check_no_confirm () {
69         if ! test -f no_confirm_okay
70         then
71                 say 'confirm test failed; skipping remaining tests to prevent hanging'
72                 PREREQ="$PREREQ,CHECK_NO_CONFIRM"
73         fi
74         return 0
75 }
76
77 test_expect_success $PREREQ 'No confirm with --suppress-cc' '
78         test_no_confirm --suppress-cc=sob &&
79         check_no_confirm
80 '
81
82
83 test_expect_success $PREREQ 'No confirm with --confirm=never' '
84         test_no_confirm --confirm=never &&
85         check_no_confirm
86 '
87
88 # leave sendemail.confirm set to never after this so that none of the
89 # remaining tests prompt unintentionally.
90 test_expect_success $PREREQ 'No confirm with sendemail.confirm=never' '
91         git config sendemail.confirm never &&
92         test_no_confirm --compose --subject=foo &&
93         check_no_confirm
94 '
95
96 test_expect_success $PREREQ 'Send patches' '
97         git send-email --suppress-cc=sob --from="Example <nobody@example.com>" --to=nobody@example.com --smtp-server="$(pwd)/fake.sendmail" $patches 2>errors
98 '
99
100 test_expect_success $PREREQ 'setup expect' '
101         cat >expected <<-\EOF
102         !nobody@example.com!
103         !author@example.com!
104         !one@example.com!
105         !two@example.com!
106         EOF
107 '
108
109 test_expect_success $PREREQ 'Verify commandline' '
110         test_cmp expected commandline1
111 '
112
113 test_expect_success $PREREQ 'Send patches with --envelope-sender' '
114         clean_fake_sendmail &&
115         git send-email --envelope-sender="Patch Contributor <patch@example.com>" --suppress-cc=sob --from="Example <nobody@example.com>" --to=nobody@example.com --smtp-server="$(pwd)/fake.sendmail" $patches 2>errors
116 '
117
118 test_expect_success $PREREQ 'setup expect' '
119         cat >expected <<-\EOF
120         !patch@example.com!
121         !-i!
122         !nobody@example.com!
123         !author@example.com!
124         !one@example.com!
125         !two@example.com!
126         EOF
127 '
128
129 test_expect_success $PREREQ 'Verify commandline' '
130         test_cmp expected commandline1
131 '
132
133 test_expect_success $PREREQ 'Send patches with --envelope-sender=auto' '
134         clean_fake_sendmail &&
135         git send-email --envelope-sender=auto --suppress-cc=sob --from="Example <nobody@example.com>" --to=nobody@example.com --smtp-server="$(pwd)/fake.sendmail" $patches 2>errors
136 '
137
138 test_expect_success $PREREQ 'setup expect' '
139         cat >expected <<-\EOF
140         !nobody@example.com!
141         !-i!
142         !nobody@example.com!
143         !author@example.com!
144         !one@example.com!
145         !two@example.com!
146         EOF
147 '
148
149 test_expect_success $PREREQ 'Verify commandline' '
150         test_cmp expected commandline1
151 '
152
153 test_expect_success $PREREQ 'setup expect for cc trailer' "
154 cat >expected-cc <<\EOF
155 !recipient@example.com!
156 !author@example.com!
157 !one@example.com!
158 !two@example.com!
159 !three@example.com!
160 !four@example.com!
161 !five@example.com!
162 !six@example.com!
163 EOF
164 "
165
166 test_expect_success $PREREQ 'cc trailer with various syntax' '
167         test_commit cc-trailer &&
168         test_when_finished "git reset --hard HEAD^" &&
169         git commit --amend -F - <<-EOF &&
170         Test Cc: trailers.
171
172         Cc: one@example.com
173         Cc: <two@example.com> # trailing comments are ignored
174         Cc: <three@example.com>, <not.four@example.com> one address per line
175         Cc: "Some # Body" <four@example.com> [ <also.a.comment> ]
176         Cc: five@example.com # not.six@example.com
177         Cc: six@example.com, not.seven@example.com
178         EOF
179         clean_fake_sendmail &&
180         git send-email -1 --to=recipient@example.com \
181                 --smtp-server="$(pwd)/fake.sendmail" &&
182         test_cmp expected-cc commandline1
183 '
184
185 test_expect_success $PREREQ 'setup fake get_maintainer.pl script for cc trailer' "
186         write_script expected-cc-script.sh <<-EOF
187         echo 'One Person <one@example.com> (supporter:THIS (FOO/bar))'
188         echo 'Two Person <two@example.com> (maintainer:THIS THING)'
189         echo 'Third List <three@example.com> (moderated list:THIS THING (FOO/bar))'
190         echo '<four@example.com> (moderated list:FOR THING)'
191         echo 'five@example.com (open list:FOR THING (FOO/bar))'
192         echo 'six@example.com (open list)'
193         EOF
194 "
195
196 test_expect_success $PREREQ 'cc trailer with get_maintainer.pl output' '
197         clean_fake_sendmail &&
198         git send-email -1 --to=recipient@example.com \
199                 --cc-cmd=./expected-cc-script.sh \
200                 --smtp-server="$(pwd)/fake.sendmail" &&
201         test_cmp expected-cc commandline1
202 '
203
204 test_expect_success $PREREQ 'setup expect' "
205 cat >expected-show-all-headers <<\EOF
206 0001-Second.patch
207 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
208 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
209 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
210 Dry-OK. Log says:
211 Server: relay.example.com
212 MAIL FROM:<from@example.com>
213 RCPT TO:<to@example.com>
214 RCPT TO:<cc@example.com>
215 RCPT TO:<author@example.com>
216 RCPT TO:<one@example.com>
217 RCPT TO:<two@example.com>
218 RCPT TO:<bcc@example.com>
219 From: Example <from@example.com>
220 To: to@example.com
221 Cc: cc@example.com,
222         A <author@example.com>,
223         One <one@example.com>,
224         two@example.com
225 Subject: [PATCH 1/1] Second.
226 Date: DATE-STRING
227 Message-Id: MESSAGE-ID-STRING
228 X-Mailer: X-MAILER-STRING
229 In-Reply-To: <unique-message-id@example.com>
230 References: <unique-message-id@example.com>
231 Reply-To: Reply <reply@example.com>
232 MIME-Version: 1.0
233 Content-Transfer-Encoding: 8bit
234
235 Result: OK
236 EOF
237 "
238
239 test_suppress_self () {
240         test_commit $3 &&
241         test_when_finished "git reset --hard HEAD^" &&
242
243         write_script cccmd-sed <<-EOF &&
244                 sed -n -e s/^cccmd--//p "\$1"
245         EOF
246
247         git commit --amend --author="$1 <$2>" -F - &&
248         clean_fake_sendmail &&
249         git format-patch --stdout -1 >"suppress-self-$3.patch" &&
250
251         git send-email --from="$1 <$2>" \
252                 --to=nobody@example.com \
253                 --cc-cmd=./cccmd-sed \
254                 --suppress-cc=self \
255                 --smtp-server="$(pwd)/fake.sendmail" \
256                 suppress-self-$3.patch &&
257
258         mv msgtxt1 msgtxt1-$3 &&
259         sed -e '/^$/q' msgtxt1-$3 >"msghdr1-$3" &&
260
261         (grep '^Cc:' msghdr1-$3 >"actual-no-cc-$3";
262          test_must_be_empty actual-no-cc-$3)
263 }
264
265 test_suppress_self_unquoted () {
266         test_suppress_self "$1" "$2" "unquoted-$3" <<-EOF
267                 test suppress-cc.self unquoted-$3 with name $1 email $2
268
269                 unquoted-$3
270
271                 cccmd--$1 <$2>
272
273                 Cc: $1 <$2>
274                 Signed-off-by: $1 <$2>
275         EOF
276 }
277
278 test_suppress_self_quoted () {
279         test_suppress_self "$1" "$2" "quoted-$3" <<-EOF
280                 test suppress-cc.self quoted-$3 with name $1 email $2
281
282                 quoted-$3
283
284                 cccmd--"$1" <$2>
285
286                 Cc: $1 <$2>
287                 Cc: "$1" <$2>
288                 Signed-off-by: $1 <$2>
289                 Signed-off-by: "$1" <$2>
290         EOF
291 }
292
293 test_expect_success $PREREQ 'self name is suppressed' "
294         test_suppress_self_unquoted 'A U Thor' 'author@example.com' \
295                 'self_name_suppressed'
296 "
297
298 test_expect_success $PREREQ 'self name with dot is suppressed' "
299         test_suppress_self_quoted 'A U. Thor' 'author@example.com' \
300                 'self_name_dot_suppressed'
301 "
302
303 test_expect_success $PREREQ 'non-ascii self name is suppressed' "
304         test_suppress_self_quoted 'Füñný Nâmé' 'odd_?=mail@example.com' \
305                 'non_ascii_self_suppressed'
306 "
307
308 # This name is long enough to force format-patch to split it into multiple
309 # encoded-words, assuming it uses UTF-8 with the "Q" encoding.
310 test_expect_success $PREREQ 'long non-ascii self name is suppressed' "
311         test_suppress_self_quoted 'Ƒüñníęř €. Nâṁé' 'odd_?=mail@example.com' \
312                 'long_non_ascii_self_suppressed'
313 "
314
315 test_expect_success $PREREQ 'sanitized self name is suppressed' "
316         test_suppress_self_unquoted '\"A U. Thor\"' 'author@example.com' \
317                 'self_name_sanitized_suppressed'
318 "
319
320 test_expect_success $PREREQ 'Show all headers' '
321         git send-email \
322                 --dry-run \
323                 --suppress-cc=sob \
324                 --from="Example <from@example.com>" \
325                 --reply-to="Reply <reply@example.com>" \
326                 --to=to@example.com \
327                 --cc=cc@example.com \
328                 --bcc=bcc@example.com \
329                 --in-reply-to="<unique-message-id@example.com>" \
330                 --smtp-server relay.example.com \
331                 $patches | replace_variable_fields \
332                 >actual-show-all-headers &&
333         test_cmp expected-show-all-headers actual-show-all-headers
334 '
335
336 test_expect_success $PREREQ 'Prompting works' '
337         clean_fake_sendmail &&
338         (echo "to@example.com" &&
339          echo ""
340         ) | GIT_SEND_EMAIL_NOTTY=1 git send-email \
341                 --smtp-server="$(pwd)/fake.sendmail" \
342                 $patches \
343                 2>errors &&
344                 grep "^From: A U Thor <author@example.com>\$" msgtxt1 &&
345                 grep "^To: to@example.com\$" msgtxt1
346 '
347
348 test_expect_success $PREREQ,AUTOIDENT 'implicit ident is allowed' '
349         clean_fake_sendmail &&
350         (sane_unset GIT_AUTHOR_NAME &&
351         sane_unset GIT_AUTHOR_EMAIL &&
352         sane_unset GIT_COMMITTER_NAME &&
353         sane_unset GIT_COMMITTER_EMAIL &&
354         GIT_SEND_EMAIL_NOTTY=1 git send-email \
355                 --smtp-server="$(pwd)/fake.sendmail" \
356                 --to=to@example.com \
357                 $patches </dev/null 2>errors
358         )
359 '
360
361 test_expect_success $PREREQ,!AUTOIDENT 'broken implicit ident aborts send-email' '
362         clean_fake_sendmail &&
363         (sane_unset GIT_AUTHOR_NAME &&
364         sane_unset GIT_AUTHOR_EMAIL &&
365         sane_unset GIT_COMMITTER_NAME &&
366         sane_unset GIT_COMMITTER_EMAIL &&
367         GIT_SEND_EMAIL_NOTTY=1 && export GIT_SEND_EMAIL_NOTTY &&
368         test_must_fail git send-email \
369                 --smtp-server="$(pwd)/fake.sendmail" \
370                 --to=to@example.com \
371                 $patches </dev/null 2>errors &&
372         test_i18ngrep "tell me who you are" errors
373         )
374 '
375
376 test_expect_success $PREREQ 'setup tocmd and cccmd scripts' '
377         write_script tocmd-sed <<-\EOF &&
378         sed -n -e "s/^tocmd--//p" "$1"
379         EOF
380         write_script cccmd-sed <<-\EOF
381         sed -n -e "s/^cccmd--//p" "$1"
382         EOF
383 '
384
385 test_expect_success $PREREQ 'tocmd works' '
386         clean_fake_sendmail &&
387         cp $patches tocmd.patch &&
388         echo tocmd--tocmd@example.com >>tocmd.patch &&
389         git send-email \
390                 --from="Example <nobody@example.com>" \
391                 --to-cmd=./tocmd-sed \
392                 --smtp-server="$(pwd)/fake.sendmail" \
393                 tocmd.patch \
394                 &&
395         grep "^To: tocmd@example.com" msgtxt1
396 '
397
398 test_expect_success $PREREQ 'cccmd works' '
399         clean_fake_sendmail &&
400         cp $patches cccmd.patch &&
401         echo "cccmd--  cccmd@example.com" >>cccmd.patch &&
402         git send-email \
403                 --from="Example <nobody@example.com>" \
404                 --to=nobody@example.com \
405                 --cc-cmd=./cccmd-sed \
406                 --smtp-server="$(pwd)/fake.sendmail" \
407                 cccmd.patch \
408                 &&
409         grep "^ cccmd@example.com" msgtxt1
410 '
411
412 test_expect_success $PREREQ 'reject long lines' '
413         z8=zzzzzzzz &&
414         z64=$z8$z8$z8$z8$z8$z8$z8$z8 &&
415         z512=$z64$z64$z64$z64$z64$z64$z64$z64 &&
416         clean_fake_sendmail &&
417         cp $patches longline.patch &&
418         echo $z512$z512 >>longline.patch &&
419         test_must_fail git send-email \
420                 --from="Example <nobody@example.com>" \
421                 --to=nobody@example.com \
422                 --smtp-server="$(pwd)/fake.sendmail" \
423                 --transfer-encoding=8bit \
424                 $patches longline.patch \
425                 2>errors &&
426         grep longline.patch errors
427 '
428
429 test_expect_success $PREREQ 'no patch was sent' '
430         ! test -e commandline1
431 '
432
433 test_expect_success $PREREQ 'Author From: in message body' '
434         clean_fake_sendmail &&
435         git send-email \
436                 --from="Example <nobody@example.com>" \
437                 --to=nobody@example.com \
438                 --smtp-server="$(pwd)/fake.sendmail" \
439                 $patches &&
440         sed "1,/^\$/d" <msgtxt1 >msgbody1 &&
441         grep "From: A <author@example.com>" msgbody1
442 '
443
444 test_expect_success $PREREQ 'Author From: not in message body' '
445         clean_fake_sendmail &&
446         git send-email \
447                 --from="A <author@example.com>" \
448                 --to=nobody@example.com \
449                 --smtp-server="$(pwd)/fake.sendmail" \
450                 $patches &&
451         sed "1,/^\$/d" <msgtxt1 >msgbody1 &&
452         ! grep "From: A <author@example.com>" msgbody1
453 '
454
455 test_expect_success $PREREQ 'allow long lines with --no-validate' '
456         git send-email \
457                 --from="Example <nobody@example.com>" \
458                 --to=nobody@example.com \
459                 --smtp-server="$(pwd)/fake.sendmail" \
460                 --no-validate \
461                 $patches longline.patch \
462                 2>errors
463 '
464
465 test_expect_success $PREREQ 'short lines with auto encoding are 8bit' '
466         clean_fake_sendmail &&
467         git send-email \
468                 --from="A <author@example.com>" \
469                 --to=nobody@example.com \
470                 --smtp-server="$(pwd)/fake.sendmail" \
471                 --transfer-encoding=auto \
472                 $patches &&
473         grep "Content-Transfer-Encoding: 8bit" msgtxt1
474 '
475
476 test_expect_success $PREREQ 'long lines with auto encoding are quoted-printable' '
477         clean_fake_sendmail &&
478         git send-email \
479                 --from="Example <nobody@example.com>" \
480                 --to=nobody@example.com \
481                 --smtp-server="$(pwd)/fake.sendmail" \
482                 --transfer-encoding=auto \
483                 --no-validate \
484                 longline.patch &&
485         grep "Content-Transfer-Encoding: quoted-printable" msgtxt1
486 '
487
488 test_expect_success $PREREQ 'carriage returns with auto encoding are quoted-printable' '
489         clean_fake_sendmail &&
490         cp $patches cr.patch &&
491         printf "this is a line\r\n" >>cr.patch &&
492         git send-email \
493                 --from="Example <nobody@example.com>" \
494                 --to=nobody@example.com \
495                 --smtp-server="$(pwd)/fake.sendmail" \
496                 --transfer-encoding=auto \
497                 --no-validate \
498                 cr.patch &&
499         grep "Content-Transfer-Encoding: quoted-printable" msgtxt1
500 '
501
502 for enc in auto quoted-printable base64
503 do
504         test_expect_success $PREREQ "--validate passes with encoding $enc" '
505                 git send-email \
506                         --from="Example <nobody@example.com>" \
507                         --to=nobody@example.com \
508                         --smtp-server="$(pwd)/fake.sendmail" \
509                         --transfer-encoding=$enc \
510                         --validate \
511                         $patches longline.patch
512         '
513
514 done
515
516 test_expect_success $PREREQ "--validate respects relative core.hooksPath path" '
517         clean_fake_sendmail &&
518         mkdir my-hooks &&
519         test_when_finished "rm my-hooks.ran" &&
520         write_script my-hooks/sendemail-validate <<-\EOF &&
521         >my-hooks.ran
522         exit 1
523         EOF
524         test_config core.hooksPath "my-hooks" &&
525         test_must_fail git send-email \
526                 --from="Example <nobody@example.com>" \
527                 --to=nobody@example.com \
528                 --smtp-server="$(pwd)/fake.sendmail" \
529                 --validate \
530                 longline.patch 2>err &&
531         test_path_is_file my-hooks.ran &&
532         grep "rejected by sendemail-validate" err
533 '
534
535 test_expect_success $PREREQ "--validate respects absolute core.hooksPath path" '
536         test_config core.hooksPath "$(pwd)/my-hooks" &&
537         test_when_finished "rm my-hooks.ran" &&
538         test_must_fail git send-email \
539                 --from="Example <nobody@example.com>" \
540                 --to=nobody@example.com \
541                 --smtp-server="$(pwd)/fake.sendmail" \
542                 --validate \
543                 longline.patch 2>err &&
544         test_path_is_file my-hooks.ran &&
545         grep "rejected by sendemail-validate" err
546 '
547
548 for enc in 7bit 8bit quoted-printable base64
549 do
550         test_expect_success $PREREQ "--transfer-encoding=$enc produces correct header" '
551                 clean_fake_sendmail &&
552                 git send-email \
553                         --from="Example <nobody@example.com>" \
554                         --to=nobody@example.com \
555                         --smtp-server="$(pwd)/fake.sendmail" \
556                         --transfer-encoding=$enc \
557                         $patches &&
558                 grep "Content-Transfer-Encoding: $enc" msgtxt1
559         '
560 done
561
562 test_expect_success $PREREQ 'Invalid In-Reply-To' '
563         clean_fake_sendmail &&
564         git send-email \
565                 --from="Example <nobody@example.com>" \
566                 --to=nobody@example.com \
567                 --in-reply-to=" " \
568                 --smtp-server="$(pwd)/fake.sendmail" \
569                 $patches \
570                 2>errors &&
571         ! grep "^In-Reply-To: < *>" msgtxt1
572 '
573
574 test_expect_success $PREREQ 'Valid In-Reply-To when prompting' '
575         clean_fake_sendmail &&
576         (echo "From Example <from@example.com>" &&
577          echo "To Example <to@example.com>" &&
578          echo ""
579         ) | GIT_SEND_EMAIL_NOTTY=1 git send-email \
580                 --smtp-server="$(pwd)/fake.sendmail" \
581                 $patches 2>errors &&
582         ! grep "^In-Reply-To: < *>" msgtxt1
583 '
584
585 test_expect_success $PREREQ 'In-Reply-To without --chain-reply-to' '
586         clean_fake_sendmail &&
587         echo "<unique-message-id@example.com>" >expect &&
588         git send-email \
589                 --from="Example <nobody@example.com>" \
590                 --to=nobody@example.com \
591                 --no-chain-reply-to \
592                 --in-reply-to="$(cat expect)" \
593                 --smtp-server="$(pwd)/fake.sendmail" \
594                 $patches $patches $patches \
595                 2>errors &&
596         # The first message is a reply to --in-reply-to
597         sed -n -e "s/^In-Reply-To: *\(.*\)/\1/p" msgtxt1 >actual &&
598         test_cmp expect actual &&
599         # Second and subsequent messages are replies to the first one
600         sed -n -e "s/^Message-Id: *\(.*\)/\1/p" msgtxt1 >expect &&
601         sed -n -e "s/^In-Reply-To: *\(.*\)/\1/p" msgtxt2 >actual &&
602         test_cmp expect actual &&
603         sed -n -e "s/^In-Reply-To: *\(.*\)/\1/p" msgtxt3 >actual &&
604         test_cmp expect actual
605 '
606
607 test_expect_success $PREREQ 'In-Reply-To with --chain-reply-to' '
608         clean_fake_sendmail &&
609         echo "<unique-message-id@example.com>" >expect &&
610         git send-email \
611                 --from="Example <nobody@example.com>" \
612                 --to=nobody@example.com \
613                 --chain-reply-to \
614                 --in-reply-to="$(cat expect)" \
615                 --smtp-server="$(pwd)/fake.sendmail" \
616                 $patches $patches $patches \
617                 2>errors &&
618         sed -n -e "s/^In-Reply-To: *\(.*\)/\1/p" msgtxt1 >actual &&
619         test_cmp expect actual &&
620         sed -n -e "s/^Message-Id: *\(.*\)/\1/p" msgtxt1 >expect &&
621         sed -n -e "s/^In-Reply-To: *\(.*\)/\1/p" msgtxt2 >actual &&
622         test_cmp expect actual &&
623         sed -n -e "s/^Message-Id: *\(.*\)/\1/p" msgtxt2 >expect &&
624         sed -n -e "s/^In-Reply-To: *\(.*\)/\1/p" msgtxt3 >actual &&
625         test_cmp expect actual
626 '
627
628 test_expect_success $PREREQ 'setup fake editor' '
629         write_script fake-editor <<-\EOF
630         echo fake edit >>"$1"
631         EOF
632 '
633
634 test_set_editor "$(pwd)/fake-editor"
635
636 test_expect_success $PREREQ '--compose works' '
637         clean_fake_sendmail &&
638         git send-email \
639         --compose --subject foo \
640         --from="Example <nobody@example.com>" \
641         --to=nobody@example.com \
642         --smtp-server="$(pwd)/fake.sendmail" \
643         $patches \
644         2>errors
645 '
646
647 test_expect_success $PREREQ 'first message is compose text' '
648         grep "^fake edit" msgtxt1
649 '
650
651 test_expect_success $PREREQ 'second message is patch' '
652         grep "Subject:.*Second" msgtxt2
653 '
654
655 test_expect_success $PREREQ 'setup expect' "
656 cat >expected-suppress-sob <<\EOF
657 0001-Second.patch
658 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
659 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
660 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
661 Dry-OK. Log says:
662 Server: relay.example.com
663 MAIL FROM:<from@example.com>
664 RCPT TO:<to@example.com>
665 RCPT TO:<cc@example.com>
666 RCPT TO:<author@example.com>
667 RCPT TO:<one@example.com>
668 RCPT TO:<two@example.com>
669 From: Example <from@example.com>
670 To: to@example.com
671 Cc: cc@example.com,
672         A <author@example.com>,
673         One <one@example.com>,
674         two@example.com
675 Subject: [PATCH 1/1] Second.
676 Date: DATE-STRING
677 Message-Id: MESSAGE-ID-STRING
678 X-Mailer: X-MAILER-STRING
679 MIME-Version: 1.0
680 Content-Transfer-Encoding: 8bit
681
682 Result: OK
683 EOF
684 "
685
686 test_suppression () {
687         git send-email \
688                 --dry-run \
689                 --suppress-cc=$1 ${2+"--suppress-cc=$2"} \
690                 --from="Example <from@example.com>" \
691                 --to=to@example.com \
692                 --smtp-server relay.example.com \
693                 $patches | replace_variable_fields \
694                 >actual-suppress-$1${2+"-$2"} &&
695         test_cmp expected-suppress-$1${2+"-$2"} actual-suppress-$1${2+"-$2"}
696 }
697
698 test_expect_success $PREREQ 'sendemail.cc set' '
699         git config sendemail.cc cc@example.com &&
700         test_suppression sob
701 '
702
703 test_expect_success $PREREQ 'setup expect' "
704 cat >expected-suppress-sob <<\EOF
705 0001-Second.patch
706 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
707 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
708 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
709 Dry-OK. Log says:
710 Server: relay.example.com
711 MAIL FROM:<from@example.com>
712 RCPT TO:<to@example.com>
713 RCPT TO:<author@example.com>
714 RCPT TO:<one@example.com>
715 RCPT TO:<two@example.com>
716 From: Example <from@example.com>
717 To: to@example.com
718 Cc: A <author@example.com>,
719         One <one@example.com>,
720         two@example.com
721 Subject: [PATCH 1/1] Second.
722 Date: DATE-STRING
723 Message-Id: MESSAGE-ID-STRING
724 X-Mailer: X-MAILER-STRING
725 MIME-Version: 1.0
726 Content-Transfer-Encoding: 8bit
727
728 Result: OK
729 EOF
730 "
731
732 test_expect_success $PREREQ 'sendemail.cc unset' '
733         git config --unset sendemail.cc &&
734         test_suppression sob
735 '
736
737 test_expect_success $PREREQ 'setup expect' "
738 cat >expected-suppress-cccmd <<\EOF
739 0001-Second.patch
740 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
741 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
742 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
743 (body) Adding cc: C O Mitter <committer@example.com> from line 'Signed-off-by: C O Mitter <committer@example.com>'
744 Dry-OK. Log says:
745 Server: relay.example.com
746 MAIL FROM:<from@example.com>
747 RCPT TO:<to@example.com>
748 RCPT TO:<author@example.com>
749 RCPT TO:<one@example.com>
750 RCPT TO:<two@example.com>
751 RCPT TO:<committer@example.com>
752 From: Example <from@example.com>
753 To: to@example.com
754 Cc: A <author@example.com>,
755         One <one@example.com>,
756         two@example.com,
757         C O Mitter <committer@example.com>
758 Subject: [PATCH 1/1] Second.
759 Date: DATE-STRING
760 Message-Id: MESSAGE-ID-STRING
761 X-Mailer: X-MAILER-STRING
762 MIME-Version: 1.0
763 Content-Transfer-Encoding: 8bit
764
765 Result: OK
766 EOF
767 "
768
769 test_expect_success $PREREQ 'sendemail.cccmd' '
770         write_script cccmd <<-\EOF &&
771         echo cc-cmd@example.com
772         EOF
773         git config sendemail.cccmd ./cccmd &&
774         test_suppression cccmd
775 '
776
777 test_expect_success $PREREQ 'setup expect' '
778 cat >expected-suppress-all <<\EOF
779 0001-Second.patch
780 Dry-OK. Log says:
781 Server: relay.example.com
782 MAIL FROM:<from@example.com>
783 RCPT TO:<to@example.com>
784 From: Example <from@example.com>
785 To: to@example.com
786 Subject: [PATCH 1/1] Second.
787 Date: DATE-STRING
788 Message-Id: MESSAGE-ID-STRING
789 X-Mailer: X-MAILER-STRING
790 MIME-Version: 1.0
791 Content-Transfer-Encoding: 8bit
792
793 Result: OK
794 EOF
795 '
796
797 test_expect_success $PREREQ '--suppress-cc=all' '
798         test_suppression all
799 '
800
801 test_expect_success $PREREQ 'setup expect' "
802 cat >expected-suppress-body <<\EOF
803 0001-Second.patch
804 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
805 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
806 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
807 (cc-cmd) Adding cc: cc-cmd@example.com from: './cccmd'
808 Dry-OK. Log says:
809 Server: relay.example.com
810 MAIL FROM:<from@example.com>
811 RCPT TO:<to@example.com>
812 RCPT TO:<author@example.com>
813 RCPT TO:<one@example.com>
814 RCPT TO:<two@example.com>
815 RCPT TO:<cc-cmd@example.com>
816 From: Example <from@example.com>
817 To: to@example.com
818 Cc: A <author@example.com>,
819         One <one@example.com>,
820         two@example.com,
821         cc-cmd@example.com
822 Subject: [PATCH 1/1] Second.
823 Date: DATE-STRING
824 Message-Id: MESSAGE-ID-STRING
825 X-Mailer: X-MAILER-STRING
826 MIME-Version: 1.0
827 Content-Transfer-Encoding: 8bit
828
829 Result: OK
830 EOF
831 "
832
833 test_expect_success $PREREQ '--suppress-cc=body' '
834         test_suppression body
835 '
836
837 test_expect_success $PREREQ 'setup expect' "
838 cat >expected-suppress-body-cccmd <<\EOF
839 0001-Second.patch
840 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
841 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
842 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
843 Dry-OK. Log says:
844 Server: relay.example.com
845 MAIL FROM:<from@example.com>
846 RCPT TO:<to@example.com>
847 RCPT TO:<author@example.com>
848 RCPT TO:<one@example.com>
849 RCPT TO:<two@example.com>
850 From: Example <from@example.com>
851 To: to@example.com
852 Cc: A <author@example.com>,
853         One <one@example.com>,
854         two@example.com
855 Subject: [PATCH 1/1] Second.
856 Date: DATE-STRING
857 Message-Id: MESSAGE-ID-STRING
858 X-Mailer: X-MAILER-STRING
859 MIME-Version: 1.0
860 Content-Transfer-Encoding: 8bit
861
862 Result: OK
863 EOF
864 "
865
866 test_expect_success $PREREQ '--suppress-cc=body --suppress-cc=cccmd' '
867         test_suppression body cccmd
868 '
869
870 test_expect_success $PREREQ 'setup expect' "
871 cat >expected-suppress-sob <<\EOF
872 0001-Second.patch
873 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
874 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
875 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
876 Dry-OK. Log says:
877 Server: relay.example.com
878 MAIL FROM:<from@example.com>
879 RCPT TO:<to@example.com>
880 RCPT TO:<author@example.com>
881 RCPT TO:<one@example.com>
882 RCPT TO:<two@example.com>
883 From: Example <from@example.com>
884 To: to@example.com
885 Cc: A <author@example.com>,
886         One <one@example.com>,
887         two@example.com
888 Subject: [PATCH 1/1] Second.
889 Date: DATE-STRING
890 Message-Id: MESSAGE-ID-STRING
891 X-Mailer: X-MAILER-STRING
892 MIME-Version: 1.0
893 Content-Transfer-Encoding: 8bit
894
895 Result: OK
896 EOF
897 "
898
899 test_expect_success $PREREQ '--suppress-cc=sob' '
900         test_might_fail git config --unset sendemail.cccmd &&
901         test_suppression sob
902 '
903
904 test_expect_success $PREREQ 'setup expect' "
905 cat >expected-suppress-bodycc <<\EOF
906 0001-Second.patch
907 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
908 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
909 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
910 (body) Adding cc: C O Mitter <committer@example.com> from line 'Signed-off-by: C O Mitter <committer@example.com>'
911 Dry-OK. Log says:
912 Server: relay.example.com
913 MAIL FROM:<from@example.com>
914 RCPT TO:<to@example.com>
915 RCPT TO:<author@example.com>
916 RCPT TO:<one@example.com>
917 RCPT TO:<two@example.com>
918 RCPT TO:<committer@example.com>
919 From: Example <from@example.com>
920 To: to@example.com
921 Cc: A <author@example.com>,
922         One <one@example.com>,
923         two@example.com,
924         C O Mitter <committer@example.com>
925 Subject: [PATCH 1/1] Second.
926 Date: DATE-STRING
927 Message-Id: MESSAGE-ID-STRING
928 X-Mailer: X-MAILER-STRING
929 MIME-Version: 1.0
930 Content-Transfer-Encoding: 8bit
931
932 Result: OK
933 EOF
934 "
935
936 test_expect_success $PREREQ '--suppress-cc=bodycc' '
937         test_suppression bodycc
938 '
939
940 test_expect_success $PREREQ 'setup expect' "
941 cat >expected-suppress-cc <<\EOF
942 0001-Second.patch
943 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
944 (body) Adding cc: C O Mitter <committer@example.com> from line 'Signed-off-by: C O Mitter <committer@example.com>'
945 Dry-OK. Log says:
946 Server: relay.example.com
947 MAIL FROM:<from@example.com>
948 RCPT TO:<to@example.com>
949 RCPT TO:<author@example.com>
950 RCPT TO:<committer@example.com>
951 From: Example <from@example.com>
952 To: to@example.com
953 Cc: A <author@example.com>,
954         C O Mitter <committer@example.com>
955 Subject: [PATCH 1/1] Second.
956 Date: DATE-STRING
957 Message-Id: MESSAGE-ID-STRING
958 X-Mailer: X-MAILER-STRING
959 MIME-Version: 1.0
960 Content-Transfer-Encoding: 8bit
961
962 Result: OK
963 EOF
964 "
965
966 test_expect_success $PREREQ '--suppress-cc=cc' '
967         test_suppression cc
968 '
969
970 test_confirm () {
971         echo y | \
972                 GIT_SEND_EMAIL_NOTTY=1 \
973                 git send-email \
974                 --from="Example <nobody@example.com>" \
975                 --to=nobody@example.com \
976                 --smtp-server="$(pwd)/fake.sendmail" \
977                 $@ $patches >stdout &&
978         grep "Send this email" stdout
979 }
980
981 test_expect_success $PREREQ '--confirm=always' '
982         test_confirm --confirm=always --suppress-cc=all
983 '
984
985 test_expect_success $PREREQ '--confirm=auto' '
986         test_confirm --confirm=auto
987 '
988
989 test_expect_success $PREREQ '--confirm=cc' '
990         test_confirm --confirm=cc
991 '
992
993 test_expect_success $PREREQ '--confirm=compose' '
994         test_confirm --confirm=compose --compose
995 '
996
997 test_expect_success $PREREQ 'confirm by default (due to cc)' '
998         test_when_finished git config sendemail.confirm never &&
999         git config --unset sendemail.confirm &&
1000         test_confirm
1001 '
1002
1003 test_expect_success $PREREQ 'confirm by default (due to --compose)' '
1004         test_when_finished git config sendemail.confirm never &&
1005         git config --unset sendemail.confirm &&
1006         test_confirm --suppress-cc=all --compose
1007 '
1008
1009 test_expect_success $PREREQ 'confirm detects EOF (inform assumes y)' '
1010         test_when_finished git config sendemail.confirm never &&
1011         git config --unset sendemail.confirm &&
1012         rm -fr outdir &&
1013         git format-patch -2 -o outdir &&
1014         GIT_SEND_EMAIL_NOTTY=1 \
1015                 git send-email \
1016                         --from="Example <nobody@example.com>" \
1017                         --to=nobody@example.com \
1018                         --smtp-server="$(pwd)/fake.sendmail" \
1019                         outdir/*.patch </dev/null
1020 '
1021
1022 test_expect_success $PREREQ 'confirm detects EOF (auto causes failure)' '
1023         test_when_finished git config sendemail.confirm never &&
1024         git config sendemail.confirm auto &&
1025         GIT_SEND_EMAIL_NOTTY=1 &&
1026         export GIT_SEND_EMAIL_NOTTY &&
1027                 test_must_fail git send-email \
1028                         --from="Example <nobody@example.com>" \
1029                         --to=nobody@example.com \
1030                         --smtp-server="$(pwd)/fake.sendmail" \
1031                         $patches </dev/null
1032 '
1033
1034 test_expect_success $PREREQ 'confirm does not loop forever' '
1035         test_when_finished git config sendemail.confirm never &&
1036         git config sendemail.confirm auto &&
1037         GIT_SEND_EMAIL_NOTTY=1 &&
1038         export GIT_SEND_EMAIL_NOTTY &&
1039                 yes "bogus" | test_must_fail git send-email \
1040                         --from="Example <nobody@example.com>" \
1041                         --to=nobody@example.com \
1042                         --smtp-server="$(pwd)/fake.sendmail" \
1043                         $patches
1044 '
1045
1046 test_expect_success $PREREQ 'utf8 Cc is rfc2047 encoded' '
1047         clean_fake_sendmail &&
1048         rm -fr outdir &&
1049         git format-patch -1 -o outdir --cc="àéìöú <utf8@example.com>" &&
1050         git send-email \
1051         --from="Example <nobody@example.com>" \
1052         --to=nobody@example.com \
1053         --smtp-server="$(pwd)/fake.sendmail" \
1054         outdir/*.patch &&
1055         grep "^ " msgtxt1 |
1056         grep "=?UTF-8?q?=C3=A0=C3=A9=C3=AC=C3=B6=C3=BA?= <utf8@example.com>"
1057 '
1058
1059 test_expect_success $PREREQ '--compose adds MIME for utf8 body' '
1060         clean_fake_sendmail &&
1061         write_script fake-editor-utf8 <<-\EOF &&
1062         echo "utf8 body: àéìöú" >>"$1"
1063         EOF
1064         GIT_EDITOR="\"$(pwd)/fake-editor-utf8\"" \
1065         git send-email \
1066                 --compose --subject foo \
1067                 --from="Example <nobody@example.com>" \
1068                 --to=nobody@example.com \
1069                 --smtp-server="$(pwd)/fake.sendmail" \
1070                 $patches &&
1071         grep "^utf8 body" msgtxt1 &&
1072         grep "^Content-Type: text/plain; charset=UTF-8" msgtxt1
1073 '
1074
1075 test_expect_success $PREREQ '--compose respects user mime type' '
1076         clean_fake_sendmail &&
1077         write_script fake-editor-utf8-mime <<-\EOF &&
1078         cat >"$1" <<-\EOM
1079         MIME-Version: 1.0
1080         Content-Type: text/plain; charset=iso-8859-1
1081         Content-Transfer-Encoding: 8bit
1082         Subject: foo
1083
1084         utf8 body: àéìöú
1085         EOM
1086         EOF
1087         GIT_EDITOR="\"$(pwd)/fake-editor-utf8-mime\"" \
1088         git send-email \
1089                 --compose --subject foo \
1090                 --from="Example <nobody@example.com>" \
1091                 --to=nobody@example.com \
1092                 --smtp-server="$(pwd)/fake.sendmail" \
1093                 $patches &&
1094         grep "^utf8 body" msgtxt1 &&
1095         grep "^Content-Type: text/plain; charset=iso-8859-1" msgtxt1 &&
1096         ! grep "^Content-Type: text/plain; charset=UTF-8" msgtxt1
1097 '
1098
1099 test_expect_success $PREREQ '--compose adds MIME for utf8 subject' '
1100         clean_fake_sendmail &&
1101         GIT_EDITOR="\"$(pwd)/fake-editor\"" \
1102         git send-email \
1103                 --compose --subject utf8-sübjëct \
1104                 --from="Example <nobody@example.com>" \
1105                 --to=nobody@example.com \
1106                 --smtp-server="$(pwd)/fake.sendmail" \
1107                 $patches &&
1108         grep "^fake edit" msgtxt1 &&
1109         grep "^Subject: =?UTF-8?q?utf8-s=C3=BCbj=C3=ABct?=" msgtxt1
1110 '
1111
1112 test_expect_success $PREREQ 'utf8 author is correctly passed on' '
1113         clean_fake_sendmail &&
1114         test_commit weird_author &&
1115         test_when_finished "git reset --hard HEAD^" &&
1116         git commit --amend --author "Füñný Nâmé <odd_?=mail@example.com>" &&
1117         git format-patch --stdout -1 >funny_name.patch &&
1118         git send-email --from="Example <nobody@example.com>" \
1119                 --to=nobody@example.com \
1120                 --smtp-server="$(pwd)/fake.sendmail" \
1121                 funny_name.patch &&
1122         grep "^From: Füñný Nâmé <odd_?=mail@example.com>" msgtxt1
1123 '
1124
1125 test_expect_success $PREREQ 'utf8 sender is not duplicated' '
1126         clean_fake_sendmail &&
1127         test_commit weird_sender &&
1128         test_when_finished "git reset --hard HEAD^" &&
1129         git commit --amend --author "Füñný Nâmé <odd_?=mail@example.com>" &&
1130         git format-patch --stdout -1 >funny_name.patch &&
1131         git send-email --from="Füñný Nâmé <odd_?=mail@example.com>" \
1132                 --to=nobody@example.com \
1133                 --smtp-server="$(pwd)/fake.sendmail" \
1134                 funny_name.patch &&
1135         grep "^From: " msgtxt1 >msgfrom &&
1136         test_line_count = 1 msgfrom
1137 '
1138
1139 test_expect_success $PREREQ 'sendemail.composeencoding works' '
1140         clean_fake_sendmail &&
1141         git config sendemail.composeencoding iso-8859-1 &&
1142         write_script fake-editor-utf8 <<-\EOF &&
1143         echo "utf8 body: àéìöú" >>"$1"
1144         EOF
1145         GIT_EDITOR="\"$(pwd)/fake-editor-utf8\"" \
1146         git send-email \
1147                 --compose --subject foo \
1148                 --from="Example <nobody@example.com>" \
1149                 --to=nobody@example.com \
1150                 --smtp-server="$(pwd)/fake.sendmail" \
1151                 $patches &&
1152         grep "^utf8 body" msgtxt1 &&
1153         grep "^Content-Type: text/plain; charset=iso-8859-1" msgtxt1
1154 '
1155
1156 test_expect_success $PREREQ '--compose-encoding works' '
1157         clean_fake_sendmail &&
1158         write_script fake-editor-utf8 <<-\EOF &&
1159         echo "utf8 body: àéìöú" >>"$1"
1160         EOF
1161         GIT_EDITOR="\"$(pwd)/fake-editor-utf8\"" \
1162         git send-email \
1163                 --compose-encoding iso-8859-1 \
1164                 --compose --subject foo \
1165                 --from="Example <nobody@example.com>" \
1166                 --to=nobody@example.com \
1167                 --smtp-server="$(pwd)/fake.sendmail" \
1168                 $patches &&
1169         grep "^utf8 body" msgtxt1 &&
1170         grep "^Content-Type: text/plain; charset=iso-8859-1" msgtxt1
1171 '
1172
1173 test_expect_success $PREREQ '--compose-encoding overrides sendemail.composeencoding' '
1174         clean_fake_sendmail &&
1175         git config sendemail.composeencoding iso-8859-1 &&
1176         write_script fake-editor-utf8 <<-\EOF &&
1177         echo "utf8 body: àéìöú" >>"$1"
1178         EOF
1179         GIT_EDITOR="\"$(pwd)/fake-editor-utf8\"" \
1180         git send-email \
1181                 --compose-encoding iso-8859-2 \
1182                 --compose --subject foo \
1183                 --from="Example <nobody@example.com>" \
1184                 --to=nobody@example.com \
1185                 --smtp-server="$(pwd)/fake.sendmail" \
1186                 $patches &&
1187         grep "^utf8 body" msgtxt1 &&
1188         grep "^Content-Type: text/plain; charset=iso-8859-2" msgtxt1
1189 '
1190
1191 test_expect_success $PREREQ '--compose-encoding adds correct MIME for subject' '
1192         clean_fake_sendmail &&
1193         GIT_EDITOR="\"$(pwd)/fake-editor\"" \
1194         git send-email \
1195                 --compose-encoding iso-8859-2 \
1196                 --compose --subject utf8-sübjëct \
1197                 --from="Example <nobody@example.com>" \
1198                 --to=nobody@example.com \
1199                 --smtp-server="$(pwd)/fake.sendmail" \
1200                 $patches &&
1201         grep "^fake edit" msgtxt1 &&
1202         grep "^Subject: =?iso-8859-2?q?utf8-s=C3=BCbj=C3=ABct?=" msgtxt1
1203 '
1204
1205 test_expect_success $PREREQ 'detects ambiguous reference/file conflict' '
1206         echo main >main &&
1207         git add main &&
1208         git commit -m"add main" &&
1209         test_must_fail git send-email --dry-run main 2>errors &&
1210         grep disambiguate errors
1211 '
1212
1213 test_expect_success $PREREQ 'feed two files' '
1214         rm -fr outdir &&
1215         git format-patch -2 -o outdir &&
1216         git send-email \
1217                 --dry-run \
1218                 --from="Example <nobody@example.com>" \
1219                 --to=nobody@example.com \
1220                 outdir/000?-*.patch 2>errors >out &&
1221         grep "^Subject: " out >subjects &&
1222         test "z$(sed -n -e 1p subjects)" = "zSubject: [PATCH 1/2] Second." &&
1223         test "z$(sed -n -e 2p subjects)" = "zSubject: [PATCH 2/2] add main"
1224 '
1225
1226 test_expect_success $PREREQ 'in-reply-to but no threading' '
1227         git send-email \
1228                 --dry-run \
1229                 --from="Example <nobody@example.com>" \
1230                 --to=nobody@example.com \
1231                 --in-reply-to="<in-reply-id@example.com>" \
1232                 --no-thread \
1233                 $patches >out &&
1234         grep "In-Reply-To: <in-reply-id@example.com>" out
1235 '
1236
1237 test_expect_success $PREREQ 'no in-reply-to and no threading' '
1238         git send-email \
1239                 --dry-run \
1240                 --from="Example <nobody@example.com>" \
1241                 --to=nobody@example.com \
1242                 --no-thread \
1243                 $patches >stdout &&
1244         ! grep "In-Reply-To: " stdout
1245 '
1246
1247 test_expect_success $PREREQ 'threading but no chain-reply-to' '
1248         git send-email \
1249                 --dry-run \
1250                 --from="Example <nobody@example.com>" \
1251                 --to=nobody@example.com \
1252                 --thread \
1253                 --no-chain-reply-to \
1254                 $patches $patches >stdout &&
1255         grep "In-Reply-To: " stdout
1256 '
1257
1258 test_expect_success $PREREQ 'override in-reply-to if no threading' '
1259         git send-email \
1260                 --dry-run \
1261                 --from="Example <nobody@example.com>" \
1262                 --to=nobody@example.com \
1263                 --no-thread \
1264                 --in-reply-to="override" \
1265                 $threaded_patches >stdout &&
1266         grep "In-Reply-To: <override>" stdout
1267 '
1268
1269 test_expect_success $PREREQ 'sendemail.to works' '
1270         git config --replace-all sendemail.to "Somebody <somebody@ex.com>" &&
1271         git send-email \
1272                 --dry-run \
1273                 --from="Example <nobody@example.com>" \
1274                 $patches >stdout &&
1275         grep "To: Somebody <somebody@ex.com>" stdout
1276 '
1277
1278 test_expect_success $PREREQ 'setup sendemail.identity' '
1279         git config --replace-all sendemail.to "default@example.com" &&
1280         git config --replace-all sendemail.isp.to "isp@example.com" &&
1281         git config --replace-all sendemail.cloud.to "cloud@example.com"
1282 '
1283
1284 test_expect_success $PREREQ 'sendemail.identity: reads the correct identity config' '
1285         git -c sendemail.identity=cloud send-email \
1286                 --dry-run \
1287                 --from="nobody@example.com" \
1288                 $patches >stdout &&
1289         grep "To: cloud@example.com" stdout
1290 '
1291
1292 test_expect_success $PREREQ 'sendemail.identity: identity overrides sendemail.identity' '
1293         git -c sendemail.identity=cloud send-email \
1294                 --identity=isp \
1295                 --dry-run \
1296                 --from="nobody@example.com" \
1297                 $patches >stdout &&
1298         grep "To: isp@example.com" stdout
1299 '
1300
1301 test_expect_success $PREREQ 'sendemail.identity: --no-identity clears previous identity' '
1302         git -c sendemail.identity=cloud send-email \
1303                 --no-identity \
1304                 --dry-run \
1305                 --from="nobody@example.com" \
1306                 $patches >stdout &&
1307         grep "To: default@example.com" stdout
1308 '
1309
1310 test_expect_success $PREREQ 'sendemail.identity: bool identity variable existence overrides' '
1311         git -c sendemail.identity=cloud \
1312                 -c sendemail.xmailer=true \
1313                 -c sendemail.cloud.xmailer=false \
1314                 send-email \
1315                 --dry-run \
1316                 --from="nobody@example.com" \
1317                 $patches >stdout &&
1318         grep "To: cloud@example.com" stdout &&
1319         ! grep "X-Mailer" stdout
1320 '
1321
1322 test_expect_success $PREREQ 'sendemail.identity: bool variable fallback' '
1323         git -c sendemail.identity=cloud \
1324                 -c sendemail.xmailer=false \
1325                 send-email \
1326                 --dry-run \
1327                 --from="nobody@example.com" \
1328                 $patches >stdout &&
1329         grep "To: cloud@example.com" stdout &&
1330         ! grep "X-Mailer" stdout
1331 '
1332
1333 test_expect_success $PREREQ '--no-to overrides sendemail.to' '
1334         git send-email \
1335                 --dry-run \
1336                 --from="Example <nobody@example.com>" \
1337                 --no-to \
1338                 --to=nobody@example.com \
1339                 $patches >stdout &&
1340         grep "To: nobody@example.com" stdout &&
1341         ! grep "To: Somebody <somebody@ex.com>" stdout
1342 '
1343
1344 test_expect_success $PREREQ 'sendemail.cc works' '
1345         git config --replace-all sendemail.cc "Somebody <somebody@ex.com>" &&
1346         git send-email \
1347                 --dry-run \
1348                 --from="Example <nobody@example.com>" \
1349                 --to=nobody@example.com \
1350                 $patches >stdout &&
1351         grep "Cc: Somebody <somebody@ex.com>" stdout
1352 '
1353
1354 test_expect_success $PREREQ '--no-cc overrides sendemail.cc' '
1355         git send-email \
1356                 --dry-run \
1357                 --from="Example <nobody@example.com>" \
1358                 --no-cc \
1359                 --cc=bodies@example.com \
1360                 --to=nobody@example.com \
1361                 $patches >stdout &&
1362         grep "Cc: bodies@example.com" stdout &&
1363         ! grep "Cc: Somebody <somebody@ex.com>" stdout
1364 '
1365
1366 test_expect_success $PREREQ 'sendemail.bcc works' '
1367         git config --replace-all sendemail.bcc "Other <other@ex.com>" &&
1368         git send-email \
1369                 --dry-run \
1370                 --from="Example <nobody@example.com>" \
1371                 --to=nobody@example.com \
1372                 --smtp-server relay.example.com \
1373                 $patches >stdout &&
1374         grep "RCPT TO:<other@ex.com>" stdout
1375 '
1376
1377 test_expect_success $PREREQ '--no-bcc overrides sendemail.bcc' '
1378         git send-email \
1379                 --dry-run \
1380                 --from="Example <nobody@example.com>" \
1381                 --no-bcc \
1382                 --bcc=bodies@example.com \
1383                 --to=nobody@example.com \
1384                 --smtp-server relay.example.com \
1385                 $patches >stdout &&
1386         grep "RCPT TO:<bodies@example.com>" stdout &&
1387         ! grep "RCPT TO:<other@ex.com>" stdout
1388 '
1389
1390 test_expect_success $PREREQ 'patches To headers are used by default' '
1391         patch=$(git format-patch -1 --to="bodies@example.com") &&
1392         test_when_finished "rm $patch" &&
1393         git send-email \
1394                 --dry-run \
1395                 --from="Example <nobody@example.com>" \
1396                 --smtp-server relay.example.com \
1397                 $patch >stdout &&
1398         grep "RCPT TO:<bodies@example.com>" stdout
1399 '
1400
1401 test_expect_success $PREREQ 'patches To headers are appended to' '
1402         patch=$(git format-patch -1 --to="bodies@example.com") &&
1403         test_when_finished "rm $patch" &&
1404         git send-email \
1405                 --dry-run \
1406                 --from="Example <nobody@example.com>" \
1407                 --to=nobody@example.com \
1408                 --smtp-server relay.example.com \
1409                 $patch >stdout &&
1410         grep "RCPT TO:<bodies@example.com>" stdout &&
1411         grep "RCPT TO:<nobody@example.com>" stdout
1412 '
1413
1414 test_expect_success $PREREQ 'To headers from files reset each patch' '
1415         patch1=$(git format-patch -1 --to="bodies@example.com") &&
1416         patch2=$(git format-patch -1 --to="other@example.com" HEAD~) &&
1417         test_when_finished "rm $patch1 && rm $patch2" &&
1418         git send-email \
1419                 --dry-run \
1420                 --from="Example <nobody@example.com>" \
1421                 --to="nobody@example.com" \
1422                 --smtp-server relay.example.com \
1423                 $patch1 $patch2 >stdout &&
1424         test $(grep -c "RCPT TO:<bodies@example.com>" stdout) = 1 &&
1425         test $(grep -c "RCPT TO:<nobody@example.com>" stdout) = 2 &&
1426         test $(grep -c "RCPT TO:<other@example.com>" stdout) = 1
1427 '
1428
1429 test_expect_success $PREREQ 'setup expect' '
1430 cat >email-using-8bit <<\EOF
1431 From fe6ecc66ece37198fe5db91fa2fc41d9f4fe5cc4 Mon Sep 17 00:00:00 2001
1432 Message-Id: <bogus-message-id@example.com>
1433 From: author@example.com
1434 Date: Sat, 12 Jun 2010 15:53:58 +0200
1435 Subject: subject goes here
1436
1437 Dieser deutsche Text enthält einen Umlaut!
1438 EOF
1439 '
1440
1441 test_expect_success $PREREQ 'setup expect' '
1442         echo "Subject: subject goes here" >expected
1443 '
1444
1445 test_expect_success $PREREQ 'ASCII subject is not RFC2047 quoted' '
1446         clean_fake_sendmail &&
1447         echo bogus |
1448         git send-email --from=author@example.com --to=nobody@example.com \
1449                         --smtp-server="$(pwd)/fake.sendmail" \
1450                         --8bit-encoding=UTF-8 \
1451                         email-using-8bit >stdout &&
1452         grep "Subject" msgtxt1 >actual &&
1453         test_cmp expected actual
1454 '
1455
1456 test_expect_success $PREREQ 'setup expect' '
1457         cat >content-type-decl <<-\EOF
1458         MIME-Version: 1.0
1459         Content-Type: text/plain; charset=UTF-8
1460         Content-Transfer-Encoding: 8bit
1461         EOF
1462 '
1463
1464 test_expect_success $PREREQ 'asks about and fixes 8bit encodings' '
1465         clean_fake_sendmail &&
1466         echo |
1467         git send-email --from=author@example.com --to=nobody@example.com \
1468                         --smtp-server="$(pwd)/fake.sendmail" \
1469                         email-using-8bit >stdout &&
1470         grep "do not declare a Content-Transfer-Encoding" stdout &&
1471         grep email-using-8bit stdout &&
1472         grep "Which 8bit encoding" stdout &&
1473         egrep "Content|MIME" msgtxt1 >actual &&
1474         test_cmp content-type-decl actual
1475 '
1476
1477 test_expect_success $PREREQ 'sendemail.8bitEncoding works' '
1478         clean_fake_sendmail &&
1479         git config sendemail.assume8bitEncoding UTF-8 &&
1480         echo bogus |
1481         git send-email --from=author@example.com --to=nobody@example.com \
1482                         --smtp-server="$(pwd)/fake.sendmail" \
1483                         email-using-8bit >stdout &&
1484         egrep "Content|MIME" msgtxt1 >actual &&
1485         test_cmp content-type-decl actual
1486 '
1487
1488 test_expect_success $PREREQ '--8bit-encoding overrides sendemail.8bitEncoding' '
1489         clean_fake_sendmail &&
1490         git config sendemail.assume8bitEncoding "bogus too" &&
1491         echo bogus |
1492         git send-email --from=author@example.com --to=nobody@example.com \
1493                         --smtp-server="$(pwd)/fake.sendmail" \
1494                         --8bit-encoding=UTF-8 \
1495                         email-using-8bit >stdout &&
1496         egrep "Content|MIME" msgtxt1 >actual &&
1497         test_cmp content-type-decl actual
1498 '
1499
1500 test_expect_success $PREREQ 'setup expect' '
1501         cat >email-using-8bit <<-\EOF
1502         From fe6ecc66ece37198fe5db91fa2fc41d9f4fe5cc4 Mon Sep 17 00:00:00 2001
1503         Message-Id: <bogus-message-id@example.com>
1504         From: author@example.com
1505         Date: Sat, 12 Jun 2010 15:53:58 +0200
1506         Subject: Dieser Betreff enthält auch einen Umlaut!
1507
1508         Nothing to see here.
1509         EOF
1510 '
1511
1512 test_expect_success $PREREQ 'setup expect' '
1513         cat >expected <<-\EOF
1514         Subject: =?UTF-8?q?Dieser=20Betreff=20enth=C3=A4lt=20auch=20einen=20Umlaut!?=
1515         EOF
1516 '
1517
1518 test_expect_success $PREREQ '--8bit-encoding also treats subject' '
1519         clean_fake_sendmail &&
1520         echo bogus |
1521         git send-email --from=author@example.com --to=nobody@example.com \
1522                         --smtp-server="$(pwd)/fake.sendmail" \
1523                         --8bit-encoding=UTF-8 \
1524                         email-using-8bit >stdout &&
1525         grep "Subject" msgtxt1 >actual &&
1526         test_cmp expected actual
1527 '
1528
1529 test_expect_success $PREREQ 'setup expect' '
1530         cat >email-using-8bit <<-\EOF
1531         From fe6ecc66ece37198fe5db91fa2fc41d9f4fe5cc4 Mon Sep 17 00:00:00 2001
1532         Message-Id: <bogus-message-id@example.com>
1533         From: A U Thor <author@example.com>
1534         Date: Sat, 12 Jun 2010 15:53:58 +0200
1535         Content-Type: text/plain; charset=UTF-8
1536         Subject: Nothing to see here.
1537
1538         Dieser Betreff enthält auch einen Umlaut!
1539         EOF
1540 '
1541
1542 test_expect_success $PREREQ '--transfer-encoding overrides sendemail.transferEncoding' '
1543         clean_fake_sendmail &&
1544         test_must_fail git -c sendemail.transferEncoding=8bit \
1545                 send-email \
1546                 --transfer-encoding=7bit \
1547                 --smtp-server="$(pwd)/fake.sendmail" \
1548                 email-using-8bit \
1549                 2>errors >out &&
1550         grep "cannot send message as 7bit" errors &&
1551         test -z "$(ls msgtxt*)"
1552 '
1553
1554 test_expect_success $PREREQ 'sendemail.transferEncoding via config' '
1555         clean_fake_sendmail &&
1556         test_must_fail git -c sendemail.transferEncoding=7bit \
1557                 send-email \
1558                 --smtp-server="$(pwd)/fake.sendmail" \
1559                 email-using-8bit \
1560                 2>errors >out &&
1561         grep "cannot send message as 7bit" errors &&
1562         test -z "$(ls msgtxt*)"
1563 '
1564
1565 test_expect_success $PREREQ 'sendemail.transferEncoding via cli' '
1566         clean_fake_sendmail &&
1567         test_must_fail git send-email \
1568                 --transfer-encoding=7bit \
1569                 --smtp-server="$(pwd)/fake.sendmail" \
1570                 email-using-8bit \
1571                 2>errors >out &&
1572         grep "cannot send message as 7bit" errors &&
1573         test -z "$(ls msgtxt*)"
1574 '
1575
1576 test_expect_success $PREREQ 'setup expect' '
1577         cat >expected <<-\EOF
1578         Dieser Betreff enth=C3=A4lt auch einen Umlaut!
1579         EOF
1580 '
1581
1582 test_expect_success $PREREQ '8-bit and sendemail.transferencoding=quoted-printable' '
1583         clean_fake_sendmail &&
1584         git send-email \
1585                 --transfer-encoding=quoted-printable \
1586                 --smtp-server="$(pwd)/fake.sendmail" \
1587                 email-using-8bit \
1588                 2>errors >out &&
1589         sed "1,/^$/d" msgtxt1 >actual &&
1590         test_cmp expected actual
1591 '
1592
1593 test_expect_success $PREREQ 'setup expect' '
1594         cat >expected <<-\EOF
1595         RGllc2VyIEJldHJlZmYgZW50aMOkbHQgYXVjaCBlaW5lbiBVbWxhdXQhCg==
1596         EOF
1597 '
1598
1599 test_expect_success $PREREQ '8-bit and sendemail.transferencoding=base64' '
1600         clean_fake_sendmail &&
1601         git send-email \
1602                 --transfer-encoding=base64 \
1603                 --smtp-server="$(pwd)/fake.sendmail" \
1604                 email-using-8bit \
1605                 2>errors >out &&
1606         sed "1,/^$/d" msgtxt1 >actual &&
1607         test_cmp expected actual
1608 '
1609
1610 test_expect_success $PREREQ 'setup expect' '
1611         cat >email-using-qp <<-\EOF
1612         From fe6ecc66ece37198fe5db91fa2fc41d9f4fe5cc4 Mon Sep 17 00:00:00 2001
1613         Message-Id: <bogus-message-id@example.com>
1614         From: A U Thor <author@example.com>
1615         Date: Sat, 12 Jun 2010 15:53:58 +0200
1616         MIME-Version: 1.0
1617         Content-Transfer-Encoding: quoted-printable
1618         Content-Type: text/plain; charset=UTF-8
1619         Subject: Nothing to see here.
1620
1621         Dieser Betreff enth=C3=A4lt auch einen Umlaut!
1622         EOF
1623 '
1624
1625 test_expect_success $PREREQ 'convert from quoted-printable to base64' '
1626         clean_fake_sendmail &&
1627         git send-email \
1628                 --transfer-encoding=base64 \
1629                 --smtp-server="$(pwd)/fake.sendmail" \
1630                 email-using-qp \
1631                 2>errors >out &&
1632         sed "1,/^$/d" msgtxt1 >actual &&
1633         test_cmp expected actual
1634 '
1635
1636 test_expect_success $PREREQ 'setup expect' "
1637 tr -d '\\015' | tr '%' '\\015' >email-using-crlf <<EOF
1638 From fe6ecc66ece37198fe5db91fa2fc41d9f4fe5cc4 Mon Sep 17 00:00:00 2001
1639 Message-Id: <bogus-message-id@example.com>
1640 From: A U Thor <author@example.com>
1641 Date: Sat, 12 Jun 2010 15:53:58 +0200
1642 Content-Type: text/plain; charset=UTF-8
1643 Subject: Nothing to see here.
1644
1645 Look, I have a CRLF and an = sign!%
1646 EOF
1647 "
1648
1649 test_expect_success $PREREQ 'setup expect' '
1650         cat >expected <<-\EOF
1651         Look, I have a CRLF and an =3D sign!=0D
1652         EOF
1653 '
1654
1655 test_expect_success $PREREQ 'CRLF and sendemail.transferencoding=quoted-printable' '
1656         clean_fake_sendmail &&
1657         git send-email \
1658                 --transfer-encoding=quoted-printable \
1659                 --smtp-server="$(pwd)/fake.sendmail" \
1660                 email-using-crlf \
1661                 2>errors >out &&
1662         sed "1,/^$/d" msgtxt1 >actual &&
1663         test_cmp expected actual
1664 '
1665
1666 test_expect_success $PREREQ 'setup expect' '
1667         cat >expected <<-\EOF
1668         TG9vaywgSSBoYXZlIGEgQ1JMRiBhbmQgYW4gPSBzaWduIQ0K
1669         EOF
1670 '
1671
1672 test_expect_success $PREREQ 'CRLF and sendemail.transferencoding=base64' '
1673         clean_fake_sendmail &&
1674         git send-email \
1675                 --transfer-encoding=base64 \
1676                 --smtp-server="$(pwd)/fake.sendmail" \
1677                 email-using-crlf \
1678                 2>errors >out &&
1679         sed "1,/^$/d" msgtxt1 >actual &&
1680         test_cmp expected actual
1681 '
1682
1683
1684 # Note that the patches in this test are deliberately out of order; we
1685 # want to make sure it works even if the cover-letter is not in the
1686 # first mail.
1687 test_expect_success $PREREQ 'refusing to send cover letter template' '
1688         clean_fake_sendmail &&
1689         rm -fr outdir &&
1690         git format-patch --cover-letter -2 -o outdir &&
1691         test_must_fail git send-email \
1692                 --from="Example <nobody@example.com>" \
1693                 --to=nobody@example.com \
1694                 --smtp-server="$(pwd)/fake.sendmail" \
1695                 outdir/0002-*.patch \
1696                 outdir/0000-*.patch \
1697                 outdir/0001-*.patch \
1698                 2>errors >out &&
1699         grep "SUBJECT HERE" errors &&
1700         test -z "$(ls msgtxt*)"
1701 '
1702
1703 test_expect_success $PREREQ '--force sends cover letter template anyway' '
1704         clean_fake_sendmail &&
1705         rm -fr outdir &&
1706         git format-patch --cover-letter -2 -o outdir &&
1707         git send-email \
1708                 --force \
1709                 --from="Example <nobody@example.com>" \
1710                 --to=nobody@example.com \
1711                 --smtp-server="$(pwd)/fake.sendmail" \
1712                 outdir/0002-*.patch \
1713                 outdir/0000-*.patch \
1714                 outdir/0001-*.patch \
1715                 2>errors >out &&
1716         ! grep "SUBJECT HERE" errors &&
1717         test -n "$(ls msgtxt*)"
1718 '
1719
1720 test_cover_addresses () {
1721         header="$1"
1722         shift
1723         clean_fake_sendmail &&
1724         rm -fr outdir &&
1725         git format-patch --cover-letter -2 -o outdir &&
1726         cover=$(echo outdir/0000-*.patch) &&
1727         mv $cover cover-to-edit.patch &&
1728         perl -pe "s/^From:/$header: extra\@address.com\nFrom:/" cover-to-edit.patch >"$cover" &&
1729         git send-email \
1730                 --force \
1731                 --from="Example <nobody@example.com>" \
1732                 --no-to --no-cc \
1733                 "$@" \
1734                 --smtp-server="$(pwd)/fake.sendmail" \
1735                 outdir/0000-*.patch \
1736                 outdir/0001-*.patch \
1737                 outdir/0002-*.patch \
1738                 2>errors >out &&
1739         grep "^$header: extra@address.com" msgtxt1 >to1 &&
1740         grep "^$header: extra@address.com" msgtxt2 >to2 &&
1741         grep "^$header: extra@address.com" msgtxt3 >to3 &&
1742         test_line_count = 1 to1 &&
1743         test_line_count = 1 to2 &&
1744         test_line_count = 1 to3
1745 }
1746
1747 test_expect_success $PREREQ 'to-cover adds To to all mail' '
1748         test_cover_addresses "To" --to-cover
1749 '
1750
1751 test_expect_success $PREREQ 'cc-cover adds Cc to all mail' '
1752         test_cover_addresses "Cc" --cc-cover
1753 '
1754
1755 test_expect_success $PREREQ 'tocover adds To to all mail' '
1756         test_config sendemail.tocover true &&
1757         test_cover_addresses "To"
1758 '
1759
1760 test_expect_success $PREREQ 'cccover adds Cc to all mail' '
1761         test_config sendemail.cccover true &&
1762         test_cover_addresses "Cc"
1763 '
1764
1765 test_expect_success $PREREQ 'escaped quotes in sendemail.aliasfiletype=mutt' '
1766         clean_fake_sendmail &&
1767         echo "alias sbd \\\"Dot U. Sir\\\" <somebody@example.org>" >.mutt &&
1768         git config --replace-all sendemail.aliasesfile "$(pwd)/.mutt" &&
1769         git config sendemail.aliasfiletype mutt &&
1770         git send-email \
1771                 --from="Example <nobody@example.com>" \
1772                 --to=sbd \
1773                 --smtp-server="$(pwd)/fake.sendmail" \
1774                 outdir/0001-*.patch \
1775                 2>errors >out &&
1776         grep "^!somebody@example\.org!$" commandline1 &&
1777         grep -F "To: \"Dot U. Sir\" <somebody@example.org>" out
1778 '
1779
1780 test_expect_success $PREREQ 'sendemail.aliasfiletype=mailrc' '
1781         clean_fake_sendmail &&
1782         echo "alias sbd  somebody@example.org" >.mailrc &&
1783         git config --replace-all sendemail.aliasesfile "$(pwd)/.mailrc" &&
1784         git config sendemail.aliasfiletype mailrc &&
1785         git send-email \
1786                 --from="Example <nobody@example.com>" \
1787                 --to=sbd \
1788                 --smtp-server="$(pwd)/fake.sendmail" \
1789                 outdir/0001-*.patch \
1790                 2>errors >out &&
1791         grep "^!somebody@example\.org!$" commandline1
1792 '
1793
1794 test_expect_success $PREREQ 'sendemail.aliasfile=~/.mailrc' '
1795         clean_fake_sendmail &&
1796         echo "alias sbd  someone@example.org" >"$HOME/.mailrc" &&
1797         git config --replace-all sendemail.aliasesfile "~/.mailrc" &&
1798         git config sendemail.aliasfiletype mailrc &&
1799         git send-email \
1800                 --from="Example <nobody@example.com>" \
1801                 --to=sbd \
1802                 --smtp-server="$(pwd)/fake.sendmail" \
1803                 outdir/0001-*.patch \
1804                 2>errors >out &&
1805         grep "^!someone@example\.org!$" commandline1
1806 '
1807
1808 test_dump_aliases () {
1809         msg="$1" && shift &&
1810         filetype="$1" && shift &&
1811         printf '%s\n' "$@" >expect &&
1812         cat >.tmp-email-aliases &&
1813
1814         test_expect_success $PREREQ "$msg" '
1815                 clean_fake_sendmail && rm -fr outdir &&
1816                 git config --replace-all sendemail.aliasesfile \
1817                         "$(pwd)/.tmp-email-aliases" &&
1818                 git config sendemail.aliasfiletype "$filetype" &&
1819                 git send-email --dump-aliases 2>errors >actual &&
1820                 test_cmp expect actual
1821         '
1822 }
1823
1824 test_dump_aliases '--dump-aliases sendmail format' \
1825         'sendmail' \
1826         'abgroup' \
1827         'alice' \
1828         'bcgrp' \
1829         'bob' \
1830         'chloe' <<-\EOF
1831         alice: Alice W Land <awol@example.com>
1832         bob: Robert Bobbyton <bob@example.com>
1833         chloe: chloe@example.com
1834         abgroup: alice, bob
1835         bcgrp: bob, chloe, Other <o@example.com>
1836         EOF
1837
1838 test_dump_aliases '--dump-aliases mutt format' \
1839         'mutt' \
1840         'alice' \
1841         'bob' \
1842         'chloe' \
1843         'donald' <<-\EOF
1844         alias alice Alice W Land <awol@example.com>
1845         alias donald Donald C Carlton <donc@example.com>
1846         alias bob Robert Bobbyton <bob@example.com>
1847         alias chloe chloe@example.com
1848         EOF
1849
1850 test_dump_aliases '--dump-aliases mailrc format' \
1851         'mailrc' \
1852         'alice' \
1853         'bob' \
1854         'chloe' \
1855         'eve' <<-\EOF
1856         alias alice   Alice W Land <awol@example.com>
1857         alias eve     Eve <eve@example.com>
1858         alias bob     Robert Bobbyton <bob@example.com>
1859         alias chloe   chloe@example.com
1860         EOF
1861
1862 test_dump_aliases '--dump-aliases pine format' \
1863         'pine' \
1864         'alice' \
1865         'bob' \
1866         'chloe' \
1867         'eve' <<-\EOF
1868         alice   Alice W Land    <awol@example.com>
1869         eve     Eve     <eve@example.com>
1870         bob     Robert  Bobbyton <bob@example.com>
1871         chloe           chloe@example.com
1872         EOF
1873
1874 test_dump_aliases '--dump-aliases gnus format' \
1875         'gnus' \
1876         'alice' \
1877         'bob' \
1878         'chloe' \
1879         'eve' <<-\EOF
1880         (define-mail-alias "alice" "awol@example.com")
1881         (define-mail-alias "eve" "eve@example.com")
1882         (define-mail-alias "bob" "bob@example.com")
1883         (define-mail-alias "chloe" "chloe@example.com")
1884         EOF
1885
1886 test_expect_success '--dump-aliases must be used alone' '
1887         test_must_fail git send-email --dump-aliases --to=janice@example.com -1 refs/heads/accounting
1888 '
1889
1890 test_expect_success $PREREQ 'aliases and sendemail.identity' '
1891         test_must_fail git \
1892                 -c sendemail.identity=cloud \
1893                 -c sendemail.aliasesfile=default-aliases \
1894                 -c sendemail.cloud.aliasesfile=cloud-aliases \
1895                 send-email -1 2>stderr &&
1896         test_i18ngrep "cloud-aliases" stderr
1897 '
1898
1899 test_sendmail_aliases () {
1900         msg="$1" && shift &&
1901         expect="$@" &&
1902         cat >.tmp-email-aliases &&
1903
1904         test_expect_success $PREREQ "$msg" '
1905                 clean_fake_sendmail && rm -fr outdir &&
1906                 git format-patch -1 -o outdir &&
1907                 git config --replace-all sendemail.aliasesfile \
1908                         "$(pwd)/.tmp-email-aliases" &&
1909                 git config sendemail.aliasfiletype sendmail &&
1910                 git send-email \
1911                         --from="Example <nobody@example.com>" \
1912                         --to=alice --to=bcgrp \
1913                         --smtp-server="$(pwd)/fake.sendmail" \
1914                         outdir/0001-*.patch \
1915                         2>errors >out &&
1916                 for i in $expect
1917                 do
1918                         grep "^!$i!$" commandline1 || return 1
1919                 done
1920         '
1921 }
1922
1923 test_sendmail_aliases 'sendemail.aliasfiletype=sendmail' \
1924         'awol@example\.com' \
1925         'bob@example\.com' \
1926         'chloe@example\.com' \
1927         'o@example\.com' <<-\EOF
1928         alice: Alice W Land <awol@example.com>
1929         bob: Robert Bobbyton <bob@example.com>
1930         # this is a comment
1931            # this is also a comment
1932         chloe: chloe@example.com
1933         abgroup: alice, bob
1934         bcgrp: bob, chloe, Other <o@example.com>
1935         EOF
1936
1937 test_sendmail_aliases 'sendmail aliases line folding' \
1938         alice1 \
1939         bob1 bob2 \
1940         chuck1 chuck2 \
1941         darla1 darla2 darla3 \
1942         elton1 elton2 elton3 \
1943         fred1 fred2 \
1944         greg1 <<-\EOF
1945         alice: alice1
1946         bob: bob1,\
1947         bob2
1948         chuck: chuck1,
1949             chuck2
1950         darla: darla1,\
1951         darla2,
1952             darla3
1953         elton: elton1,
1954             elton2,\
1955         elton3
1956         fred: fred1,\
1957             fred2
1958         greg: greg1
1959         bcgrp: bob, chuck, darla, elton, fred, greg
1960         EOF
1961
1962 test_sendmail_aliases 'sendmail aliases tolerate bogus line folding' \
1963         alice1 bob1 <<-\EOF
1964             alice: alice1
1965         bcgrp: bob1\
1966         EOF
1967
1968 test_sendmail_aliases 'sendmail aliases empty' alice bcgrp <<-\EOF
1969         EOF
1970
1971 test_expect_success $PREREQ 'alias support in To header' '
1972         clean_fake_sendmail &&
1973         echo "alias sbd  someone@example.org" >.mailrc &&
1974         test_config sendemail.aliasesfile ".mailrc" &&
1975         test_config sendemail.aliasfiletype mailrc &&
1976         git format-patch --stdout -1 --to=sbd >aliased.patch &&
1977         git send-email \
1978                 --from="Example <nobody@example.com>" \
1979                 --smtp-server="$(pwd)/fake.sendmail" \
1980                 aliased.patch \
1981                 2>errors >out &&
1982         grep "^!someone@example\.org!$" commandline1
1983 '
1984
1985 test_expect_success $PREREQ 'alias support in Cc header' '
1986         clean_fake_sendmail &&
1987         echo "alias sbd  someone@example.org" >.mailrc &&
1988         test_config sendemail.aliasesfile ".mailrc" &&
1989         test_config sendemail.aliasfiletype mailrc &&
1990         git format-patch --stdout -1 --cc=sbd >aliased.patch &&
1991         git send-email \
1992                 --from="Example <nobody@example.com>" \
1993                 --smtp-server="$(pwd)/fake.sendmail" \
1994                 aliased.patch \
1995                 2>errors >out &&
1996         grep "^!someone@example\.org!$" commandline1
1997 '
1998
1999 test_expect_success $PREREQ 'tocmd works with aliases' '
2000         clean_fake_sendmail &&
2001         echo "alias sbd  someone@example.org" >.mailrc &&
2002         test_config sendemail.aliasesfile ".mailrc" &&
2003         test_config sendemail.aliasfiletype mailrc &&
2004         git format-patch --stdout -1 >tocmd.patch &&
2005         echo tocmd--sbd >>tocmd.patch &&
2006         git send-email \
2007                 --from="Example <nobody@example.com>" \
2008                 --to-cmd=./tocmd-sed \
2009                 --smtp-server="$(pwd)/fake.sendmail" \
2010                 tocmd.patch \
2011                 2>errors >out &&
2012         grep "^!someone@example\.org!$" commandline1
2013 '
2014
2015 test_expect_success $PREREQ 'cccmd works with aliases' '
2016         clean_fake_sendmail &&
2017         echo "alias sbd  someone@example.org" >.mailrc &&
2018         test_config sendemail.aliasesfile ".mailrc" &&
2019         test_config sendemail.aliasfiletype mailrc &&
2020         git format-patch --stdout -1 >cccmd.patch &&
2021         echo cccmd--sbd >>cccmd.patch &&
2022         git send-email \
2023                 --from="Example <nobody@example.com>" \
2024                 --cc-cmd=./cccmd-sed \
2025                 --smtp-server="$(pwd)/fake.sendmail" \
2026                 cccmd.patch \
2027                 2>errors >out &&
2028         grep "^!someone@example\.org!$" commandline1
2029 '
2030
2031 do_xmailer_test () {
2032         expected=$1 params=$2 &&
2033         git format-patch -1 &&
2034         git send-email \
2035                 --from="Example <nobody@example.com>" \
2036                 --to=someone@example.com \
2037                 --smtp-server="$(pwd)/fake.sendmail" \
2038                 $params \
2039                 0001-*.patch \
2040                 2>errors >out &&
2041         { grep '^X-Mailer:' out || :; } >mailer &&
2042         test_line_count = $expected mailer
2043 }
2044
2045 test_expect_success $PREREQ '--[no-]xmailer without any configuration' '
2046         do_xmailer_test 1 "--xmailer" &&
2047         do_xmailer_test 0 "--no-xmailer"
2048 '
2049
2050 test_expect_success $PREREQ '--[no-]xmailer with sendemail.xmailer=true' '
2051         test_config sendemail.xmailer true &&
2052         do_xmailer_test 1 "" &&
2053         do_xmailer_test 0 "--no-xmailer" &&
2054         do_xmailer_test 1 "--xmailer"
2055 '
2056
2057 test_expect_success $PREREQ '--[no-]xmailer with sendemail.xmailer=false' '
2058         test_config sendemail.xmailer false &&
2059         do_xmailer_test 0 "" &&
2060         do_xmailer_test 0 "--no-xmailer" &&
2061         do_xmailer_test 1 "--xmailer"
2062 '
2063
2064 test_expect_success $PREREQ 'setup expected-list' '
2065         git send-email \
2066         --dry-run \
2067         --from="Example <from@example.com>" \
2068         --to="To 1 <to1@example.com>" \
2069         --to="to2@example.com" \
2070         --to="to3@example.com" \
2071         --cc="Cc 1 <cc1@example.com>" \
2072         --cc="Cc2 <cc2@example.com>" \
2073         --bcc="bcc1@example.com" \
2074         --bcc="bcc2@example.com" \
2075         0001-add-main.patch | replace_variable_fields \
2076         >expected-list
2077 '
2078
2079 test_expect_success $PREREQ 'use email list in --cc --to and --bcc' '
2080         git send-email \
2081         --dry-run \
2082         --from="Example <from@example.com>" \
2083         --to="To 1 <to1@example.com>, to2@example.com" \
2084         --to="to3@example.com" \
2085         --cc="Cc 1 <cc1@example.com>, Cc2 <cc2@example.com>" \
2086         --bcc="bcc1@example.com, bcc2@example.com" \
2087         0001-add-main.patch | replace_variable_fields \
2088         >actual-list &&
2089         test_cmp expected-list actual-list
2090 '
2091
2092 test_expect_success $PREREQ 'aliases work with email list' '
2093         echo "alias to2 to2@example.com" >.mutt &&
2094         echo "alias cc1 Cc 1 <cc1@example.com>" >>.mutt &&
2095         test_config sendemail.aliasesfile ".mutt" &&
2096         test_config sendemail.aliasfiletype mutt &&
2097         git send-email \
2098         --dry-run \
2099         --from="Example <from@example.com>" \
2100         --to="To 1 <to1@example.com>, to2, to3@example.com" \
2101         --cc="cc1, Cc2 <cc2@example.com>" \
2102         --bcc="bcc1@example.com, bcc2@example.com" \
2103         0001-add-main.patch | replace_variable_fields \
2104         >actual-list &&
2105         test_cmp expected-list actual-list
2106 '
2107
2108 test_expect_success $PREREQ 'leading and trailing whitespaces are removed' '
2109         echo "alias to2 to2@example.com" >.mutt &&
2110         echo "alias cc1 Cc 1 <cc1@example.com>" >>.mutt &&
2111         test_config sendemail.aliasesfile ".mutt" &&
2112         test_config sendemail.aliasfiletype mutt &&
2113         TO1=$(echo "QTo 1 <to1@example.com>" | q_to_tab) &&
2114         TO2=$(echo "QZto2" | qz_to_tab_space) &&
2115         CC1=$(echo "cc1" | append_cr) &&
2116         BCC1=$(echo " bcc1@example.com Q" | q_to_nul) &&
2117         git send-email \
2118         --dry-run \
2119         --from="        Example <from@example.com>" \
2120         --to="$TO1" \
2121         --to="$TO2" \
2122         --to="  to3@example.com   " \
2123         --cc="$CC1" \
2124         --cc="Cc2 <cc2@example.com>" \
2125         --bcc="$BCC1" \
2126         --bcc="bcc2@example.com" \
2127         0001-add-main.patch | replace_variable_fields \
2128         >actual-list &&
2129         test_cmp expected-list actual-list
2130 '
2131
2132 test_expect_success $PREREQ 'invoke hook' '
2133         mkdir -p .git/hooks &&
2134
2135         write_script .git/hooks/sendemail-validate <<-\EOF &&
2136         # test that we have the correct environment variable, pwd, and
2137         # argument
2138         case "$GIT_DIR" in
2139         *.git)
2140                 true
2141                 ;;
2142         *)
2143                 false
2144                 ;;
2145         esac &&
2146         test -f 0001-add-main.patch &&
2147         grep "add main" "$1"
2148         EOF
2149
2150         mkdir subdir &&
2151         (
2152                 # Test that it works even if we are not at the root of the
2153                 # working tree
2154                 cd subdir &&
2155                 git send-email \
2156                         --from="Example <nobody@example.com>" \
2157                         --to=nobody@example.com \
2158                         --smtp-server="$(pwd)/../fake.sendmail" \
2159                         ../0001-add-main.patch &&
2160
2161                 # Verify error message when a patch is rejected by the hook
2162                 sed -e "s/add main/x/" ../0001-add-main.patch >../another.patch &&
2163                 test_must_fail git send-email \
2164                         --from="Example <nobody@example.com>" \
2165                         --to=nobody@example.com \
2166                         --smtp-server="$(pwd)/../fake.sendmail" \
2167                         ../another.patch 2>err &&
2168                 test_i18ngrep "rejected by sendemail-validate hook" err
2169         )
2170 '
2171
2172 test_expect_success $PREREQ 'test that send-email works outside a repo' '
2173         nongit git send-email \
2174                 --from="Example <nobody@example.com>" \
2175                 --to=nobody@example.com \
2176                 --smtp-server="$(pwd)/fake.sendmail" \
2177                 "$(pwd)/0001-add-main.patch"
2178 '
2179
2180 test_expect_success $PREREQ 'test that sendmail config is rejected' '
2181         test_config sendmail.program sendmail &&
2182         test_must_fail git send-email \
2183                 --from="Example <nobody@example.com>" \
2184                 --to=nobody@example.com \
2185                 --smtp-server="$(pwd)/fake.sendmail" \
2186                 HEAD^ 2>err &&
2187         test_i18ngrep "found configuration options for '"'"sendmail"'"'" err
2188 '
2189
2190 test_expect_success $PREREQ 'test that sendmail config rejection is specific' '
2191         test_config resendmail.program sendmail &&
2192         git send-email \
2193                 --from="Example <nobody@example.com>" \
2194                 --to=nobody@example.com \
2195                 --smtp-server="$(pwd)/fake.sendmail" \
2196                 HEAD^
2197 '
2198
2199 test_expect_success $PREREQ 'test forbidSendmailVariables behavior override' '
2200         test_config sendmail.program sendmail &&
2201         test_config sendemail.forbidSendmailVariables false &&
2202         git send-email \
2203                 --from="Example <nobody@example.com>" \
2204                 --to=nobody@example.com \
2205                 --smtp-server="$(pwd)/fake.sendmail" \
2206                 HEAD^
2207 '
2208
2209 test_done