Git 2.32
[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         cat >>longline.patch <<-EOF &&
419         $z512$z512
420         not a long line
421         $z512$z512
422         EOF
423         test_must_fail git send-email \
424                 --from="Example <nobody@example.com>" \
425                 --to=nobody@example.com \
426                 --smtp-server="$(pwd)/fake.sendmail" \
427                 --transfer-encoding=8bit \
428                 $patches longline.patch \
429                 2>actual &&
430         cat >expect <<-\EOF &&
431         fatal: longline.patch:35 is longer than 998 characters
432         warning: no patches were sent
433         EOF
434         test_cmp expect actual
435 '
436
437 test_expect_success $PREREQ 'no patch was sent' '
438         ! test -e commandline1
439 '
440
441 test_expect_success $PREREQ 'Author From: in message body' '
442         clean_fake_sendmail &&
443         git send-email \
444                 --from="Example <nobody@example.com>" \
445                 --to=nobody@example.com \
446                 --smtp-server="$(pwd)/fake.sendmail" \
447                 $patches &&
448         sed "1,/^\$/d" <msgtxt1 >msgbody1 &&
449         grep "From: A <author@example.com>" msgbody1
450 '
451
452 test_expect_success $PREREQ 'Author From: not in message body' '
453         clean_fake_sendmail &&
454         git send-email \
455                 --from="A <author@example.com>" \
456                 --to=nobody@example.com \
457                 --smtp-server="$(pwd)/fake.sendmail" \
458                 $patches &&
459         sed "1,/^\$/d" <msgtxt1 >msgbody1 &&
460         ! grep "From: A <author@example.com>" msgbody1
461 '
462
463 test_expect_success $PREREQ 'allow long lines with --no-validate' '
464         git send-email \
465                 --from="Example <nobody@example.com>" \
466                 --to=nobody@example.com \
467                 --smtp-server="$(pwd)/fake.sendmail" \
468                 --no-validate \
469                 $patches longline.patch \
470                 2>errors
471 '
472
473 test_expect_success $PREREQ 'short lines with auto encoding are 8bit' '
474         clean_fake_sendmail &&
475         git send-email \
476                 --from="A <author@example.com>" \
477                 --to=nobody@example.com \
478                 --smtp-server="$(pwd)/fake.sendmail" \
479                 --transfer-encoding=auto \
480                 $patches &&
481         grep "Content-Transfer-Encoding: 8bit" msgtxt1
482 '
483
484 test_expect_success $PREREQ 'long lines with auto encoding are quoted-printable' '
485         clean_fake_sendmail &&
486         git send-email \
487                 --from="Example <nobody@example.com>" \
488                 --to=nobody@example.com \
489                 --smtp-server="$(pwd)/fake.sendmail" \
490                 --transfer-encoding=auto \
491                 --no-validate \
492                 longline.patch &&
493         grep "Content-Transfer-Encoding: quoted-printable" msgtxt1
494 '
495
496 test_expect_success $PREREQ 'carriage returns with auto encoding are quoted-printable' '
497         clean_fake_sendmail &&
498         cp $patches cr.patch &&
499         printf "this is a line\r\n" >>cr.patch &&
500         git send-email \
501                 --from="Example <nobody@example.com>" \
502                 --to=nobody@example.com \
503                 --smtp-server="$(pwd)/fake.sendmail" \
504                 --transfer-encoding=auto \
505                 --no-validate \
506                 cr.patch &&
507         grep "Content-Transfer-Encoding: quoted-printable" msgtxt1
508 '
509
510 for enc in auto quoted-printable base64
511 do
512         test_expect_success $PREREQ "--validate passes with encoding $enc" '
513                 git send-email \
514                         --from="Example <nobody@example.com>" \
515                         --to=nobody@example.com \
516                         --smtp-server="$(pwd)/fake.sendmail" \
517                         --transfer-encoding=$enc \
518                         --validate \
519                         $patches longline.patch
520         '
521
522 done
523
524 test_expect_success $PREREQ "--validate respects relative core.hooksPath path" '
525         clean_fake_sendmail &&
526         mkdir my-hooks &&
527         test_when_finished "rm my-hooks.ran" &&
528         write_script my-hooks/sendemail-validate <<-\EOF &&
529         >my-hooks.ran
530         exit 1
531         EOF
532         test_config core.hooksPath "my-hooks" &&
533         test_must_fail git send-email \
534                 --from="Example <nobody@example.com>" \
535                 --to=nobody@example.com \
536                 --smtp-server="$(pwd)/fake.sendmail" \
537                 --validate \
538                 longline.patch 2>actual &&
539         test_path_is_file my-hooks.ran &&
540         cat >expect <<-EOF &&
541         fatal: longline.patch: rejected by sendemail-validate hook
542         fatal: command '"'"'my-hooks/sendemail-validate'"'"' died with exit code 1
543         warning: no patches were sent
544         EOF
545         test_cmp expect actual
546 '
547
548 test_expect_success $PREREQ "--validate respects absolute core.hooksPath path" '
549         hooks_path="$(pwd)/my-hooks" &&
550         test_config core.hooksPath "$hooks_path" &&
551         test_when_finished "rm my-hooks.ran" &&
552         test_must_fail git send-email \
553                 --from="Example <nobody@example.com>" \
554                 --to=nobody@example.com \
555                 --smtp-server="$(pwd)/fake.sendmail" \
556                 --validate \
557                 longline.patch 2>actual &&
558         test_path_is_file my-hooks.ran &&
559         cat >expect <<-EOF &&
560         fatal: longline.patch: rejected by sendemail-validate hook
561         fatal: command '"'"'$hooks_path/sendemail-validate'"'"' died with exit code 1
562         warning: no patches were sent
563         EOF
564         test_cmp expect actual
565 '
566
567 for enc in 7bit 8bit quoted-printable base64
568 do
569         test_expect_success $PREREQ "--transfer-encoding=$enc produces correct header" '
570                 clean_fake_sendmail &&
571                 git send-email \
572                         --from="Example <nobody@example.com>" \
573                         --to=nobody@example.com \
574                         --smtp-server="$(pwd)/fake.sendmail" \
575                         --transfer-encoding=$enc \
576                         $patches &&
577                 grep "Content-Transfer-Encoding: $enc" msgtxt1
578         '
579 done
580
581 test_expect_success $PREREQ 'Invalid In-Reply-To' '
582         clean_fake_sendmail &&
583         git send-email \
584                 --from="Example <nobody@example.com>" \
585                 --to=nobody@example.com \
586                 --in-reply-to=" " \
587                 --smtp-server="$(pwd)/fake.sendmail" \
588                 $patches \
589                 2>errors &&
590         ! grep "^In-Reply-To: < *>" msgtxt1
591 '
592
593 test_expect_success $PREREQ 'Valid In-Reply-To when prompting' '
594         clean_fake_sendmail &&
595         (echo "From Example <from@example.com>" &&
596          echo "To Example <to@example.com>" &&
597          echo ""
598         ) | GIT_SEND_EMAIL_NOTTY=1 git send-email \
599                 --smtp-server="$(pwd)/fake.sendmail" \
600                 $patches 2>errors &&
601         ! grep "^In-Reply-To: < *>" msgtxt1
602 '
603
604 test_expect_success $PREREQ 'In-Reply-To without --chain-reply-to' '
605         clean_fake_sendmail &&
606         echo "<unique-message-id@example.com>" >expect &&
607         git send-email \
608                 --from="Example <nobody@example.com>" \
609                 --to=nobody@example.com \
610                 --no-chain-reply-to \
611                 --in-reply-to="$(cat expect)" \
612                 --smtp-server="$(pwd)/fake.sendmail" \
613                 $patches $patches $patches \
614                 2>errors &&
615         # The first message is a reply to --in-reply-to
616         sed -n -e "s/^In-Reply-To: *\(.*\)/\1/p" msgtxt1 >actual &&
617         test_cmp expect actual &&
618         # Second and subsequent messages are replies to the first one
619         sed -n -e "s/^Message-Id: *\(.*\)/\1/p" msgtxt1 >expect &&
620         sed -n -e "s/^In-Reply-To: *\(.*\)/\1/p" msgtxt2 >actual &&
621         test_cmp expect actual &&
622         sed -n -e "s/^In-Reply-To: *\(.*\)/\1/p" msgtxt3 >actual &&
623         test_cmp expect actual
624 '
625
626 test_expect_success $PREREQ 'In-Reply-To with --chain-reply-to' '
627         clean_fake_sendmail &&
628         echo "<unique-message-id@example.com>" >expect &&
629         git send-email \
630                 --from="Example <nobody@example.com>" \
631                 --to=nobody@example.com \
632                 --chain-reply-to \
633                 --in-reply-to="$(cat expect)" \
634                 --smtp-server="$(pwd)/fake.sendmail" \
635                 $patches $patches $patches \
636                 2>errors &&
637         sed -n -e "s/^In-Reply-To: *\(.*\)/\1/p" msgtxt1 >actual &&
638         test_cmp expect actual &&
639         sed -n -e "s/^Message-Id: *\(.*\)/\1/p" msgtxt1 >expect &&
640         sed -n -e "s/^In-Reply-To: *\(.*\)/\1/p" msgtxt2 >actual &&
641         test_cmp expect actual &&
642         sed -n -e "s/^Message-Id: *\(.*\)/\1/p" msgtxt2 >expect &&
643         sed -n -e "s/^In-Reply-To: *\(.*\)/\1/p" msgtxt3 >actual &&
644         test_cmp expect actual
645 '
646
647 test_set_editor "$(pwd)/fake-editor"
648
649 test_expect_success $PREREQ 'setup erroring fake editor' '
650         write_script fake-editor <<-\EOF
651         echo >&2 "I am about to error"
652         exit 1
653         EOF
654 '
655
656 test_expect_success $PREREQ 'fake editor dies with error' '
657         clean_fake_sendmail &&
658         test_must_fail git send-email \
659                 --compose --subject foo \
660                 --from="Example <nobody@example.com>" \
661                 --to=nobody@example.com \
662                 --smtp-server="$(pwd)/fake.sendmail" \
663                 $patches 2>err &&
664         grep "I am about to error" err &&
665         grep "the editor exited uncleanly, aborting everything" err
666 '
667
668 test_expect_success $PREREQ 'setup fake editor' '
669         write_script fake-editor <<-\EOF
670         echo fake edit >>"$1"
671         EOF
672 '
673
674 test_expect_success $PREREQ '--compose works' '
675         clean_fake_sendmail &&
676         git send-email \
677         --compose --subject foo \
678         --from="Example <nobody@example.com>" \
679         --to=nobody@example.com \
680         --smtp-server="$(pwd)/fake.sendmail" \
681         $patches \
682         2>errors
683 '
684
685 test_expect_success $PREREQ 'first message is compose text' '
686         grep "^fake edit" msgtxt1
687 '
688
689 test_expect_success $PREREQ 'second message is patch' '
690         grep "Subject:.*Second" msgtxt2
691 '
692
693 test_expect_success $PREREQ 'setup expect' "
694 cat >expected-suppress-sob <<\EOF
695 0001-Second.patch
696 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
697 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
698 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
699 Dry-OK. Log says:
700 Server: relay.example.com
701 MAIL FROM:<from@example.com>
702 RCPT TO:<to@example.com>
703 RCPT TO:<cc@example.com>
704 RCPT TO:<author@example.com>
705 RCPT TO:<one@example.com>
706 RCPT TO:<two@example.com>
707 From: Example <from@example.com>
708 To: to@example.com
709 Cc: cc@example.com,
710         A <author@example.com>,
711         One <one@example.com>,
712         two@example.com
713 Subject: [PATCH 1/1] Second.
714 Date: DATE-STRING
715 Message-Id: MESSAGE-ID-STRING
716 X-Mailer: X-MAILER-STRING
717 MIME-Version: 1.0
718 Content-Transfer-Encoding: 8bit
719
720 Result: OK
721 EOF
722 "
723
724 test_suppression () {
725         git send-email \
726                 --dry-run \
727                 --suppress-cc=$1 ${2+"--suppress-cc=$2"} \
728                 --from="Example <from@example.com>" \
729                 --to=to@example.com \
730                 --smtp-server relay.example.com \
731                 $patches | replace_variable_fields \
732                 >actual-suppress-$1${2+"-$2"} &&
733         test_cmp expected-suppress-$1${2+"-$2"} actual-suppress-$1${2+"-$2"}
734 }
735
736 test_expect_success $PREREQ 'sendemail.cc set' '
737         git config sendemail.cc cc@example.com &&
738         test_suppression sob
739 '
740
741 test_expect_success $PREREQ 'setup expect' "
742 cat >expected-suppress-sob <<\EOF
743 0001-Second.patch
744 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
745 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
746 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
747 Dry-OK. Log says:
748 Server: relay.example.com
749 MAIL FROM:<from@example.com>
750 RCPT TO:<to@example.com>
751 RCPT TO:<author@example.com>
752 RCPT TO:<one@example.com>
753 RCPT TO:<two@example.com>
754 From: Example <from@example.com>
755 To: to@example.com
756 Cc: A <author@example.com>,
757         One <one@example.com>,
758         two@example.com
759 Subject: [PATCH 1/1] Second.
760 Date: DATE-STRING
761 Message-Id: MESSAGE-ID-STRING
762 X-Mailer: X-MAILER-STRING
763 MIME-Version: 1.0
764 Content-Transfer-Encoding: 8bit
765
766 Result: OK
767 EOF
768 "
769
770 test_expect_success $PREREQ 'sendemail.cc unset' '
771         git config --unset sendemail.cc &&
772         test_suppression sob
773 '
774
775 test_expect_success $PREREQ 'setup expect' "
776 cat >expected-suppress-cccmd <<\EOF
777 0001-Second.patch
778 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
779 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
780 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
781 (body) Adding cc: C O Mitter <committer@example.com> from line 'Signed-off-by: C O Mitter <committer@example.com>'
782 Dry-OK. Log says:
783 Server: relay.example.com
784 MAIL FROM:<from@example.com>
785 RCPT TO:<to@example.com>
786 RCPT TO:<author@example.com>
787 RCPT TO:<one@example.com>
788 RCPT TO:<two@example.com>
789 RCPT TO:<committer@example.com>
790 From: Example <from@example.com>
791 To: to@example.com
792 Cc: A <author@example.com>,
793         One <one@example.com>,
794         two@example.com,
795         C O Mitter <committer@example.com>
796 Subject: [PATCH 1/1] Second.
797 Date: DATE-STRING
798 Message-Id: MESSAGE-ID-STRING
799 X-Mailer: X-MAILER-STRING
800 MIME-Version: 1.0
801 Content-Transfer-Encoding: 8bit
802
803 Result: OK
804 EOF
805 "
806
807 test_expect_success $PREREQ 'sendemail.cccmd' '
808         write_script cccmd <<-\EOF &&
809         echo cc-cmd@example.com
810         EOF
811         git config sendemail.cccmd ./cccmd &&
812         test_suppression cccmd
813 '
814
815 test_expect_success $PREREQ 'setup expect' '
816 cat >expected-suppress-all <<\EOF
817 0001-Second.patch
818 Dry-OK. Log says:
819 Server: relay.example.com
820 MAIL FROM:<from@example.com>
821 RCPT TO:<to@example.com>
822 From: Example <from@example.com>
823 To: to@example.com
824 Subject: [PATCH 1/1] Second.
825 Date: DATE-STRING
826 Message-Id: MESSAGE-ID-STRING
827 X-Mailer: X-MAILER-STRING
828 MIME-Version: 1.0
829 Content-Transfer-Encoding: 8bit
830
831 Result: OK
832 EOF
833 '
834
835 test_expect_success $PREREQ '--suppress-cc=all' '
836         test_suppression all
837 '
838
839 test_expect_success $PREREQ 'setup expect' "
840 cat >expected-suppress-body <<\EOF
841 0001-Second.patch
842 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
843 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
844 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
845 (cc-cmd) Adding cc: cc-cmd@example.com from: './cccmd'
846 Dry-OK. Log says:
847 Server: relay.example.com
848 MAIL FROM:<from@example.com>
849 RCPT TO:<to@example.com>
850 RCPT TO:<author@example.com>
851 RCPT TO:<one@example.com>
852 RCPT TO:<two@example.com>
853 RCPT TO:<cc-cmd@example.com>
854 From: Example <from@example.com>
855 To: to@example.com
856 Cc: A <author@example.com>,
857         One <one@example.com>,
858         two@example.com,
859         cc-cmd@example.com
860 Subject: [PATCH 1/1] Second.
861 Date: DATE-STRING
862 Message-Id: MESSAGE-ID-STRING
863 X-Mailer: X-MAILER-STRING
864 MIME-Version: 1.0
865 Content-Transfer-Encoding: 8bit
866
867 Result: OK
868 EOF
869 "
870
871 test_expect_success $PREREQ '--suppress-cc=body' '
872         test_suppression body
873 '
874
875 test_expect_success $PREREQ 'setup expect' "
876 cat >expected-suppress-body-cccmd <<\EOF
877 0001-Second.patch
878 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
879 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
880 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
881 Dry-OK. Log says:
882 Server: relay.example.com
883 MAIL FROM:<from@example.com>
884 RCPT TO:<to@example.com>
885 RCPT TO:<author@example.com>
886 RCPT TO:<one@example.com>
887 RCPT TO:<two@example.com>
888 From: Example <from@example.com>
889 To: to@example.com
890 Cc: A <author@example.com>,
891         One <one@example.com>,
892         two@example.com
893 Subject: [PATCH 1/1] Second.
894 Date: DATE-STRING
895 Message-Id: MESSAGE-ID-STRING
896 X-Mailer: X-MAILER-STRING
897 MIME-Version: 1.0
898 Content-Transfer-Encoding: 8bit
899
900 Result: OK
901 EOF
902 "
903
904 test_expect_success $PREREQ '--suppress-cc=body --suppress-cc=cccmd' '
905         test_suppression body cccmd
906 '
907
908 test_expect_success $PREREQ 'setup expect' "
909 cat >expected-suppress-sob <<\EOF
910 0001-Second.patch
911 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
912 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
913 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
914 Dry-OK. Log says:
915 Server: relay.example.com
916 MAIL FROM:<from@example.com>
917 RCPT TO:<to@example.com>
918 RCPT TO:<author@example.com>
919 RCPT TO:<one@example.com>
920 RCPT TO:<two@example.com>
921 From: Example <from@example.com>
922 To: to@example.com
923 Cc: A <author@example.com>,
924         One <one@example.com>,
925         two@example.com
926 Subject: [PATCH 1/1] Second.
927 Date: DATE-STRING
928 Message-Id: MESSAGE-ID-STRING
929 X-Mailer: X-MAILER-STRING
930 MIME-Version: 1.0
931 Content-Transfer-Encoding: 8bit
932
933 Result: OK
934 EOF
935 "
936
937 test_expect_success $PREREQ '--suppress-cc=sob' '
938         test_might_fail git config --unset sendemail.cccmd &&
939         test_suppression sob
940 '
941
942 test_expect_success $PREREQ 'setup expect' "
943 cat >expected-suppress-bodycc <<\EOF
944 0001-Second.patch
945 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
946 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
947 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
948 (body) Adding cc: C O Mitter <committer@example.com> from line 'Signed-off-by: C O Mitter <committer@example.com>'
949 Dry-OK. Log says:
950 Server: relay.example.com
951 MAIL FROM:<from@example.com>
952 RCPT TO:<to@example.com>
953 RCPT TO:<author@example.com>
954 RCPT TO:<one@example.com>
955 RCPT TO:<two@example.com>
956 RCPT TO:<committer@example.com>
957 From: Example <from@example.com>
958 To: to@example.com
959 Cc: A <author@example.com>,
960         One <one@example.com>,
961         two@example.com,
962         C O Mitter <committer@example.com>
963 Subject: [PATCH 1/1] Second.
964 Date: DATE-STRING
965 Message-Id: MESSAGE-ID-STRING
966 X-Mailer: X-MAILER-STRING
967 MIME-Version: 1.0
968 Content-Transfer-Encoding: 8bit
969
970 Result: OK
971 EOF
972 "
973
974 test_expect_success $PREREQ '--suppress-cc=bodycc' '
975         test_suppression bodycc
976 '
977
978 test_expect_success $PREREQ 'setup expect' "
979 cat >expected-suppress-cc <<\EOF
980 0001-Second.patch
981 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
982 (body) Adding cc: C O Mitter <committer@example.com> from line 'Signed-off-by: C O Mitter <committer@example.com>'
983 Dry-OK. Log says:
984 Server: relay.example.com
985 MAIL FROM:<from@example.com>
986 RCPT TO:<to@example.com>
987 RCPT TO:<author@example.com>
988 RCPT TO:<committer@example.com>
989 From: Example <from@example.com>
990 To: to@example.com
991 Cc: A <author@example.com>,
992         C O Mitter <committer@example.com>
993 Subject: [PATCH 1/1] Second.
994 Date: DATE-STRING
995 Message-Id: MESSAGE-ID-STRING
996 X-Mailer: X-MAILER-STRING
997 MIME-Version: 1.0
998 Content-Transfer-Encoding: 8bit
999
1000 Result: OK
1001 EOF
1002 "
1003
1004 test_expect_success $PREREQ '--suppress-cc=cc' '
1005         test_suppression cc
1006 '
1007
1008 test_confirm () {
1009         echo y | \
1010                 GIT_SEND_EMAIL_NOTTY=1 \
1011                 git send-email \
1012                 --from="Example <nobody@example.com>" \
1013                 --to=nobody@example.com \
1014                 --smtp-server="$(pwd)/fake.sendmail" \
1015                 $@ $patches >stdout &&
1016         grep "Send this email" stdout
1017 }
1018
1019 test_expect_success $PREREQ '--confirm=always' '
1020         test_confirm --confirm=always --suppress-cc=all
1021 '
1022
1023 test_expect_success $PREREQ '--confirm=auto' '
1024         test_confirm --confirm=auto
1025 '
1026
1027 test_expect_success $PREREQ '--confirm=cc' '
1028         test_confirm --confirm=cc
1029 '
1030
1031 test_expect_success $PREREQ '--confirm=compose' '
1032         test_confirm --confirm=compose --compose
1033 '
1034
1035 test_expect_success $PREREQ 'confirm by default (due to cc)' '
1036         test_when_finished git config sendemail.confirm never &&
1037         git config --unset sendemail.confirm &&
1038         test_confirm
1039 '
1040
1041 test_expect_success $PREREQ 'confirm by default (due to --compose)' '
1042         test_when_finished git config sendemail.confirm never &&
1043         git config --unset sendemail.confirm &&
1044         test_confirm --suppress-cc=all --compose
1045 '
1046
1047 test_expect_success $PREREQ 'confirm detects EOF (inform assumes y)' '
1048         test_when_finished git config sendemail.confirm never &&
1049         git config --unset sendemail.confirm &&
1050         rm -fr outdir &&
1051         git format-patch -2 -o outdir &&
1052         GIT_SEND_EMAIL_NOTTY=1 \
1053                 git send-email \
1054                         --from="Example <nobody@example.com>" \
1055                         --to=nobody@example.com \
1056                         --smtp-server="$(pwd)/fake.sendmail" \
1057                         outdir/*.patch </dev/null
1058 '
1059
1060 test_expect_success $PREREQ 'confirm detects EOF (auto causes failure)' '
1061         test_when_finished git config sendemail.confirm never &&
1062         git config sendemail.confirm auto &&
1063         GIT_SEND_EMAIL_NOTTY=1 &&
1064         export GIT_SEND_EMAIL_NOTTY &&
1065                 test_must_fail git send-email \
1066                         --from="Example <nobody@example.com>" \
1067                         --to=nobody@example.com \
1068                         --smtp-server="$(pwd)/fake.sendmail" \
1069                         $patches </dev/null
1070 '
1071
1072 test_expect_success $PREREQ 'confirm does not loop forever' '
1073         test_when_finished git config sendemail.confirm never &&
1074         git config sendemail.confirm auto &&
1075         GIT_SEND_EMAIL_NOTTY=1 &&
1076         export GIT_SEND_EMAIL_NOTTY &&
1077                 yes "bogus" | test_must_fail git send-email \
1078                         --from="Example <nobody@example.com>" \
1079                         --to=nobody@example.com \
1080                         --smtp-server="$(pwd)/fake.sendmail" \
1081                         $patches
1082 '
1083
1084 test_expect_success $PREREQ 'utf8 Cc is rfc2047 encoded' '
1085         clean_fake_sendmail &&
1086         rm -fr outdir &&
1087         git format-patch -1 -o outdir --cc="àéìöú <utf8@example.com>" &&
1088         git send-email \
1089         --from="Example <nobody@example.com>" \
1090         --to=nobody@example.com \
1091         --smtp-server="$(pwd)/fake.sendmail" \
1092         outdir/*.patch &&
1093         grep "^ " msgtxt1 |
1094         grep "=?UTF-8?q?=C3=A0=C3=A9=C3=AC=C3=B6=C3=BA?= <utf8@example.com>"
1095 '
1096
1097 test_expect_success $PREREQ '--compose adds MIME for utf8 body' '
1098         clean_fake_sendmail &&
1099         write_script fake-editor-utf8 <<-\EOF &&
1100         echo "utf8 body: àéìöú" >>"$1"
1101         EOF
1102         GIT_EDITOR="\"$(pwd)/fake-editor-utf8\"" \
1103         git send-email \
1104                 --compose --subject foo \
1105                 --from="Example <nobody@example.com>" \
1106                 --to=nobody@example.com \
1107                 --smtp-server="$(pwd)/fake.sendmail" \
1108                 $patches &&
1109         grep "^utf8 body" msgtxt1 &&
1110         grep "^Content-Type: text/plain; charset=UTF-8" msgtxt1
1111 '
1112
1113 test_expect_success $PREREQ '--compose respects user mime type' '
1114         clean_fake_sendmail &&
1115         write_script fake-editor-utf8-mime <<-\EOF &&
1116         cat >"$1" <<-\EOM
1117         MIME-Version: 1.0
1118         Content-Type: text/plain; charset=iso-8859-1
1119         Content-Transfer-Encoding: 8bit
1120         Subject: foo
1121
1122         utf8 body: àéìöú
1123         EOM
1124         EOF
1125         GIT_EDITOR="\"$(pwd)/fake-editor-utf8-mime\"" \
1126         git send-email \
1127                 --compose --subject foo \
1128                 --from="Example <nobody@example.com>" \
1129                 --to=nobody@example.com \
1130                 --smtp-server="$(pwd)/fake.sendmail" \
1131                 $patches &&
1132         grep "^utf8 body" msgtxt1 &&
1133         grep "^Content-Type: text/plain; charset=iso-8859-1" msgtxt1 &&
1134         ! grep "^Content-Type: text/plain; charset=UTF-8" msgtxt1
1135 '
1136
1137 test_expect_success $PREREQ '--compose adds MIME for utf8 subject' '
1138         clean_fake_sendmail &&
1139         GIT_EDITOR="\"$(pwd)/fake-editor\"" \
1140         git send-email \
1141                 --compose --subject utf8-sübjëct \
1142                 --from="Example <nobody@example.com>" \
1143                 --to=nobody@example.com \
1144                 --smtp-server="$(pwd)/fake.sendmail" \
1145                 $patches &&
1146         grep "^fake edit" msgtxt1 &&
1147         grep "^Subject: =?UTF-8?q?utf8-s=C3=BCbj=C3=ABct?=" msgtxt1
1148 '
1149
1150 test_expect_success $PREREQ 'utf8 author is correctly passed on' '
1151         clean_fake_sendmail &&
1152         test_commit weird_author &&
1153         test_when_finished "git reset --hard HEAD^" &&
1154         git commit --amend --author "Füñný Nâmé <odd_?=mail@example.com>" &&
1155         git format-patch --stdout -1 >funny_name.patch &&
1156         git send-email --from="Example <nobody@example.com>" \
1157                 --to=nobody@example.com \
1158                 --smtp-server="$(pwd)/fake.sendmail" \
1159                 funny_name.patch &&
1160         grep "^From: Füñný Nâmé <odd_?=mail@example.com>" msgtxt1
1161 '
1162
1163 test_expect_success $PREREQ 'utf8 sender is not duplicated' '
1164         clean_fake_sendmail &&
1165         test_commit weird_sender &&
1166         test_when_finished "git reset --hard HEAD^" &&
1167         git commit --amend --author "Füñný Nâmé <odd_?=mail@example.com>" &&
1168         git format-patch --stdout -1 >funny_name.patch &&
1169         git send-email --from="Füñný Nâmé <odd_?=mail@example.com>" \
1170                 --to=nobody@example.com \
1171                 --smtp-server="$(pwd)/fake.sendmail" \
1172                 funny_name.patch &&
1173         grep "^From: " msgtxt1 >msgfrom &&
1174         test_line_count = 1 msgfrom
1175 '
1176
1177 test_expect_success $PREREQ 'sendemail.composeencoding works' '
1178         clean_fake_sendmail &&
1179         git config sendemail.composeencoding iso-8859-1 &&
1180         write_script fake-editor-utf8 <<-\EOF &&
1181         echo "utf8 body: àéìöú" >>"$1"
1182         EOF
1183         GIT_EDITOR="\"$(pwd)/fake-editor-utf8\"" \
1184         git send-email \
1185                 --compose --subject foo \
1186                 --from="Example <nobody@example.com>" \
1187                 --to=nobody@example.com \
1188                 --smtp-server="$(pwd)/fake.sendmail" \
1189                 $patches &&
1190         grep "^utf8 body" msgtxt1 &&
1191         grep "^Content-Type: text/plain; charset=iso-8859-1" msgtxt1
1192 '
1193
1194 test_expect_success $PREREQ '--compose-encoding works' '
1195         clean_fake_sendmail &&
1196         write_script fake-editor-utf8 <<-\EOF &&
1197         echo "utf8 body: àéìöú" >>"$1"
1198         EOF
1199         GIT_EDITOR="\"$(pwd)/fake-editor-utf8\"" \
1200         git send-email \
1201                 --compose-encoding iso-8859-1 \
1202                 --compose --subject foo \
1203                 --from="Example <nobody@example.com>" \
1204                 --to=nobody@example.com \
1205                 --smtp-server="$(pwd)/fake.sendmail" \
1206                 $patches &&
1207         grep "^utf8 body" msgtxt1 &&
1208         grep "^Content-Type: text/plain; charset=iso-8859-1" msgtxt1
1209 '
1210
1211 test_expect_success $PREREQ '--compose-encoding overrides sendemail.composeencoding' '
1212         clean_fake_sendmail &&
1213         git config sendemail.composeencoding iso-8859-1 &&
1214         write_script fake-editor-utf8 <<-\EOF &&
1215         echo "utf8 body: àéìöú" >>"$1"
1216         EOF
1217         GIT_EDITOR="\"$(pwd)/fake-editor-utf8\"" \
1218         git send-email \
1219                 --compose-encoding iso-8859-2 \
1220                 --compose --subject foo \
1221                 --from="Example <nobody@example.com>" \
1222                 --to=nobody@example.com \
1223                 --smtp-server="$(pwd)/fake.sendmail" \
1224                 $patches &&
1225         grep "^utf8 body" msgtxt1 &&
1226         grep "^Content-Type: text/plain; charset=iso-8859-2" msgtxt1
1227 '
1228
1229 test_expect_success $PREREQ '--compose-encoding adds correct MIME for subject' '
1230         clean_fake_sendmail &&
1231         GIT_EDITOR="\"$(pwd)/fake-editor\"" \
1232         git send-email \
1233                 --compose-encoding iso-8859-2 \
1234                 --compose --subject utf8-sübjëct \
1235                 --from="Example <nobody@example.com>" \
1236                 --to=nobody@example.com \
1237                 --smtp-server="$(pwd)/fake.sendmail" \
1238                 $patches &&
1239         grep "^fake edit" msgtxt1 &&
1240         grep "^Subject: =?iso-8859-2?q?utf8-s=C3=BCbj=C3=ABct?=" msgtxt1
1241 '
1242
1243 test_expect_success $PREREQ 'detects ambiguous reference/file conflict' '
1244         echo main >main &&
1245         git add main &&
1246         git commit -m"add main" &&
1247         test_must_fail git send-email --dry-run main 2>errors &&
1248         grep disambiguate errors
1249 '
1250
1251 test_expect_success $PREREQ 'feed two files' '
1252         rm -fr outdir &&
1253         git format-patch -2 -o outdir &&
1254         git send-email \
1255                 --dry-run \
1256                 --from="Example <nobody@example.com>" \
1257                 --to=nobody@example.com \
1258                 outdir/000?-*.patch 2>errors >out &&
1259         grep "^Subject: " out >subjects &&
1260         test "z$(sed -n -e 1p subjects)" = "zSubject: [PATCH 1/2] Second." &&
1261         test "z$(sed -n -e 2p subjects)" = "zSubject: [PATCH 2/2] add main"
1262 '
1263
1264 test_expect_success $PREREQ 'in-reply-to but no threading' '
1265         git send-email \
1266                 --dry-run \
1267                 --from="Example <nobody@example.com>" \
1268                 --to=nobody@example.com \
1269                 --in-reply-to="<in-reply-id@example.com>" \
1270                 --no-thread \
1271                 $patches >out &&
1272         grep "In-Reply-To: <in-reply-id@example.com>" out
1273 '
1274
1275 test_expect_success $PREREQ 'no in-reply-to and no threading' '
1276         git send-email \
1277                 --dry-run \
1278                 --from="Example <nobody@example.com>" \
1279                 --to=nobody@example.com \
1280                 --no-thread \
1281                 $patches >stdout &&
1282         ! grep "In-Reply-To: " stdout
1283 '
1284
1285 test_expect_success $PREREQ 'threading but no chain-reply-to' '
1286         git send-email \
1287                 --dry-run \
1288                 --from="Example <nobody@example.com>" \
1289                 --to=nobody@example.com \
1290                 --thread \
1291                 --no-chain-reply-to \
1292                 $patches $patches >stdout &&
1293         grep "In-Reply-To: " stdout
1294 '
1295
1296 test_expect_success $PREREQ 'override in-reply-to if no threading' '
1297         git send-email \
1298                 --dry-run \
1299                 --from="Example <nobody@example.com>" \
1300                 --to=nobody@example.com \
1301                 --no-thread \
1302                 --in-reply-to="override" \
1303                 $threaded_patches >stdout &&
1304         grep "In-Reply-To: <override>" stdout
1305 '
1306
1307 test_expect_success $PREREQ 'sendemail.to works' '
1308         git config --replace-all sendemail.to "Somebody <somebody@ex.com>" &&
1309         git send-email \
1310                 --dry-run \
1311                 --from="Example <nobody@example.com>" \
1312                 $patches >stdout &&
1313         grep "To: Somebody <somebody@ex.com>" stdout
1314 '
1315
1316 test_expect_success $PREREQ 'setup sendemail.identity' '
1317         git config --replace-all sendemail.to "default@example.com" &&
1318         git config --replace-all sendemail.isp.to "isp@example.com" &&
1319         git config --replace-all sendemail.cloud.to "cloud@example.com"
1320 '
1321
1322 test_expect_success $PREREQ 'sendemail.identity: reads the correct identity config' '
1323         git -c sendemail.identity=cloud send-email \
1324                 --dry-run \
1325                 --from="nobody@example.com" \
1326                 $patches >stdout &&
1327         grep "To: cloud@example.com" stdout
1328 '
1329
1330 test_expect_success $PREREQ 'sendemail.identity: identity overrides sendemail.identity' '
1331         git -c sendemail.identity=cloud send-email \
1332                 --identity=isp \
1333                 --dry-run \
1334                 --from="nobody@example.com" \
1335                 $patches >stdout &&
1336         grep "To: isp@example.com" stdout
1337 '
1338
1339 test_expect_success $PREREQ 'sendemail.identity: --no-identity clears previous identity' '
1340         git -c sendemail.identity=cloud send-email \
1341                 --no-identity \
1342                 --dry-run \
1343                 --from="nobody@example.com" \
1344                 $patches >stdout &&
1345         grep "To: default@example.com" stdout
1346 '
1347
1348 test_expect_success $PREREQ 'sendemail.identity: bool identity variable existence overrides' '
1349         git -c sendemail.identity=cloud \
1350                 -c sendemail.xmailer=true \
1351                 -c sendemail.cloud.xmailer=false \
1352                 send-email \
1353                 --dry-run \
1354                 --from="nobody@example.com" \
1355                 $patches >stdout &&
1356         grep "To: cloud@example.com" stdout &&
1357         ! grep "X-Mailer" stdout
1358 '
1359
1360 test_expect_success $PREREQ 'sendemail.identity: bool variable fallback' '
1361         git -c sendemail.identity=cloud \
1362                 -c sendemail.xmailer=false \
1363                 send-email \
1364                 --dry-run \
1365                 --from="nobody@example.com" \
1366                 $patches >stdout &&
1367         grep "To: cloud@example.com" stdout &&
1368         ! grep "X-Mailer" stdout
1369 '
1370
1371 test_expect_success $PREREQ '--no-to overrides sendemail.to' '
1372         git send-email \
1373                 --dry-run \
1374                 --from="Example <nobody@example.com>" \
1375                 --no-to \
1376                 --to=nobody@example.com \
1377                 $patches >stdout &&
1378         grep "To: nobody@example.com" stdout &&
1379         ! grep "To: Somebody <somebody@ex.com>" stdout
1380 '
1381
1382 test_expect_success $PREREQ 'sendemail.cc works' '
1383         git config --replace-all sendemail.cc "Somebody <somebody@ex.com>" &&
1384         git send-email \
1385                 --dry-run \
1386                 --from="Example <nobody@example.com>" \
1387                 --to=nobody@example.com \
1388                 $patches >stdout &&
1389         grep "Cc: Somebody <somebody@ex.com>" stdout
1390 '
1391
1392 test_expect_success $PREREQ '--no-cc overrides sendemail.cc' '
1393         git send-email \
1394                 --dry-run \
1395                 --from="Example <nobody@example.com>" \
1396                 --no-cc \
1397                 --cc=bodies@example.com \
1398                 --to=nobody@example.com \
1399                 $patches >stdout &&
1400         grep "Cc: bodies@example.com" stdout &&
1401         ! grep "Cc: Somebody <somebody@ex.com>" stdout
1402 '
1403
1404 test_expect_success $PREREQ 'sendemail.bcc works' '
1405         git config --replace-all sendemail.bcc "Other <other@ex.com>" &&
1406         git send-email \
1407                 --dry-run \
1408                 --from="Example <nobody@example.com>" \
1409                 --to=nobody@example.com \
1410                 --smtp-server relay.example.com \
1411                 $patches >stdout &&
1412         grep "RCPT TO:<other@ex.com>" stdout
1413 '
1414
1415 test_expect_success $PREREQ '--no-bcc overrides sendemail.bcc' '
1416         git send-email \
1417                 --dry-run \
1418                 --from="Example <nobody@example.com>" \
1419                 --no-bcc \
1420                 --bcc=bodies@example.com \
1421                 --to=nobody@example.com \
1422                 --smtp-server relay.example.com \
1423                 $patches >stdout &&
1424         grep "RCPT TO:<bodies@example.com>" stdout &&
1425         ! grep "RCPT TO:<other@ex.com>" stdout
1426 '
1427
1428 test_expect_success $PREREQ 'patches To headers are used by default' '
1429         patch=$(git format-patch -1 --to="bodies@example.com") &&
1430         test_when_finished "rm $patch" &&
1431         git send-email \
1432                 --dry-run \
1433                 --from="Example <nobody@example.com>" \
1434                 --smtp-server relay.example.com \
1435                 $patch >stdout &&
1436         grep "RCPT TO:<bodies@example.com>" stdout
1437 '
1438
1439 test_expect_success $PREREQ 'patches To headers are appended to' '
1440         patch=$(git format-patch -1 --to="bodies@example.com") &&
1441         test_when_finished "rm $patch" &&
1442         git send-email \
1443                 --dry-run \
1444                 --from="Example <nobody@example.com>" \
1445                 --to=nobody@example.com \
1446                 --smtp-server relay.example.com \
1447                 $patch >stdout &&
1448         grep "RCPT TO:<bodies@example.com>" stdout &&
1449         grep "RCPT TO:<nobody@example.com>" stdout
1450 '
1451
1452 test_expect_success $PREREQ 'To headers from files reset each patch' '
1453         patch1=$(git format-patch -1 --to="bodies@example.com") &&
1454         patch2=$(git format-patch -1 --to="other@example.com" HEAD~) &&
1455         test_when_finished "rm $patch1 && rm $patch2" &&
1456         git send-email \
1457                 --dry-run \
1458                 --from="Example <nobody@example.com>" \
1459                 --to="nobody@example.com" \
1460                 --smtp-server relay.example.com \
1461                 $patch1 $patch2 >stdout &&
1462         test $(grep -c "RCPT TO:<bodies@example.com>" stdout) = 1 &&
1463         test $(grep -c "RCPT TO:<nobody@example.com>" stdout) = 2 &&
1464         test $(grep -c "RCPT TO:<other@example.com>" stdout) = 1
1465 '
1466
1467 test_expect_success $PREREQ 'setup expect' '
1468 cat >email-using-8bit <<\EOF
1469 From fe6ecc66ece37198fe5db91fa2fc41d9f4fe5cc4 Mon Sep 17 00:00:00 2001
1470 Message-Id: <bogus-message-id@example.com>
1471 From: author@example.com
1472 Date: Sat, 12 Jun 2010 15:53:58 +0200
1473 Subject: subject goes here
1474
1475 Dieser deutsche Text enthält einen Umlaut!
1476 EOF
1477 '
1478
1479 test_expect_success $PREREQ 'setup expect' '
1480         echo "Subject: subject goes here" >expected
1481 '
1482
1483 test_expect_success $PREREQ 'ASCII subject is not RFC2047 quoted' '
1484         clean_fake_sendmail &&
1485         echo bogus |
1486         git send-email --from=author@example.com --to=nobody@example.com \
1487                         --smtp-server="$(pwd)/fake.sendmail" \
1488                         --8bit-encoding=UTF-8 \
1489                         email-using-8bit >stdout &&
1490         grep "Subject" msgtxt1 >actual &&
1491         test_cmp expected actual
1492 '
1493
1494 test_expect_success $PREREQ 'setup expect' '
1495         cat >content-type-decl <<-\EOF
1496         MIME-Version: 1.0
1497         Content-Type: text/plain; charset=UTF-8
1498         Content-Transfer-Encoding: 8bit
1499         EOF
1500 '
1501
1502 test_expect_success $PREREQ 'asks about and fixes 8bit encodings' '
1503         clean_fake_sendmail &&
1504         echo |
1505         git send-email --from=author@example.com --to=nobody@example.com \
1506                         --smtp-server="$(pwd)/fake.sendmail" \
1507                         email-using-8bit >stdout &&
1508         grep "do not declare a Content-Transfer-Encoding" stdout &&
1509         grep email-using-8bit stdout &&
1510         grep "Which 8bit encoding" stdout &&
1511         egrep "Content|MIME" msgtxt1 >actual &&
1512         test_cmp content-type-decl actual
1513 '
1514
1515 test_expect_success $PREREQ 'sendemail.8bitEncoding works' '
1516         clean_fake_sendmail &&
1517         git config sendemail.assume8bitEncoding UTF-8 &&
1518         echo bogus |
1519         git send-email --from=author@example.com --to=nobody@example.com \
1520                         --smtp-server="$(pwd)/fake.sendmail" \
1521                         email-using-8bit >stdout &&
1522         egrep "Content|MIME" msgtxt1 >actual &&
1523         test_cmp content-type-decl actual
1524 '
1525
1526 test_expect_success $PREREQ '--8bit-encoding overrides sendemail.8bitEncoding' '
1527         clean_fake_sendmail &&
1528         git config sendemail.assume8bitEncoding "bogus too" &&
1529         echo bogus |
1530         git send-email --from=author@example.com --to=nobody@example.com \
1531                         --smtp-server="$(pwd)/fake.sendmail" \
1532                         --8bit-encoding=UTF-8 \
1533                         email-using-8bit >stdout &&
1534         egrep "Content|MIME" msgtxt1 >actual &&
1535         test_cmp content-type-decl actual
1536 '
1537
1538 test_expect_success $PREREQ 'setup expect' '
1539         cat >email-using-8bit <<-\EOF
1540         From fe6ecc66ece37198fe5db91fa2fc41d9f4fe5cc4 Mon Sep 17 00:00:00 2001
1541         Message-Id: <bogus-message-id@example.com>
1542         From: author@example.com
1543         Date: Sat, 12 Jun 2010 15:53:58 +0200
1544         Subject: Dieser Betreff enthält auch einen Umlaut!
1545
1546         Nothing to see here.
1547         EOF
1548 '
1549
1550 test_expect_success $PREREQ 'setup expect' '
1551         cat >expected <<-\EOF
1552         Subject: =?UTF-8?q?Dieser=20Betreff=20enth=C3=A4lt=20auch=20einen=20Umlaut!?=
1553         EOF
1554 '
1555
1556 test_expect_success $PREREQ '--8bit-encoding also treats subject' '
1557         clean_fake_sendmail &&
1558         echo bogus |
1559         git send-email --from=author@example.com --to=nobody@example.com \
1560                         --smtp-server="$(pwd)/fake.sendmail" \
1561                         --8bit-encoding=UTF-8 \
1562                         email-using-8bit >stdout &&
1563         grep "Subject" msgtxt1 >actual &&
1564         test_cmp expected actual
1565 '
1566
1567 test_expect_success $PREREQ 'setup expect' '
1568         cat >email-using-8bit <<-\EOF
1569         From fe6ecc66ece37198fe5db91fa2fc41d9f4fe5cc4 Mon Sep 17 00:00:00 2001
1570         Message-Id: <bogus-message-id@example.com>
1571         From: A U Thor <author@example.com>
1572         Date: Sat, 12 Jun 2010 15:53:58 +0200
1573         Content-Type: text/plain; charset=UTF-8
1574         Subject: Nothing to see here.
1575
1576         Dieser Betreff enthält auch einen Umlaut!
1577         EOF
1578 '
1579
1580 test_expect_success $PREREQ '--transfer-encoding overrides sendemail.transferEncoding' '
1581         clean_fake_sendmail &&
1582         test_must_fail git -c sendemail.transferEncoding=8bit \
1583                 send-email \
1584                 --transfer-encoding=7bit \
1585                 --smtp-server="$(pwd)/fake.sendmail" \
1586                 email-using-8bit \
1587                 2>errors >out &&
1588         grep "cannot send message as 7bit" errors &&
1589         test -z "$(ls msgtxt*)"
1590 '
1591
1592 test_expect_success $PREREQ 'sendemail.transferEncoding via config' '
1593         clean_fake_sendmail &&
1594         test_must_fail git -c sendemail.transferEncoding=7bit \
1595                 send-email \
1596                 --smtp-server="$(pwd)/fake.sendmail" \
1597                 email-using-8bit \
1598                 2>errors >out &&
1599         grep "cannot send message as 7bit" errors &&
1600         test -z "$(ls msgtxt*)"
1601 '
1602
1603 test_expect_success $PREREQ 'sendemail.transferEncoding via cli' '
1604         clean_fake_sendmail &&
1605         test_must_fail git send-email \
1606                 --transfer-encoding=7bit \
1607                 --smtp-server="$(pwd)/fake.sendmail" \
1608                 email-using-8bit \
1609                 2>errors >out &&
1610         grep "cannot send message as 7bit" errors &&
1611         test -z "$(ls msgtxt*)"
1612 '
1613
1614 test_expect_success $PREREQ 'setup expect' '
1615         cat >expected <<-\EOF
1616         Dieser Betreff enth=C3=A4lt auch einen Umlaut!
1617         EOF
1618 '
1619
1620 test_expect_success $PREREQ '8-bit and sendemail.transferencoding=quoted-printable' '
1621         clean_fake_sendmail &&
1622         git send-email \
1623                 --transfer-encoding=quoted-printable \
1624                 --smtp-server="$(pwd)/fake.sendmail" \
1625                 email-using-8bit \
1626                 2>errors >out &&
1627         sed "1,/^$/d" msgtxt1 >actual &&
1628         test_cmp expected actual
1629 '
1630
1631 test_expect_success $PREREQ 'setup expect' '
1632         cat >expected <<-\EOF
1633         RGllc2VyIEJldHJlZmYgZW50aMOkbHQgYXVjaCBlaW5lbiBVbWxhdXQhCg==
1634         EOF
1635 '
1636
1637 test_expect_success $PREREQ '8-bit and sendemail.transferencoding=base64' '
1638         clean_fake_sendmail &&
1639         git send-email \
1640                 --transfer-encoding=base64 \
1641                 --smtp-server="$(pwd)/fake.sendmail" \
1642                 email-using-8bit \
1643                 2>errors >out &&
1644         sed "1,/^$/d" msgtxt1 >actual &&
1645         test_cmp expected actual
1646 '
1647
1648 test_expect_success $PREREQ 'setup expect' '
1649         cat >email-using-qp <<-\EOF
1650         From fe6ecc66ece37198fe5db91fa2fc41d9f4fe5cc4 Mon Sep 17 00:00:00 2001
1651         Message-Id: <bogus-message-id@example.com>
1652         From: A U Thor <author@example.com>
1653         Date: Sat, 12 Jun 2010 15:53:58 +0200
1654         MIME-Version: 1.0
1655         Content-Transfer-Encoding: quoted-printable
1656         Content-Type: text/plain; charset=UTF-8
1657         Subject: Nothing to see here.
1658
1659         Dieser Betreff enth=C3=A4lt auch einen Umlaut!
1660         EOF
1661 '
1662
1663 test_expect_success $PREREQ 'convert from quoted-printable to base64' '
1664         clean_fake_sendmail &&
1665         git send-email \
1666                 --transfer-encoding=base64 \
1667                 --smtp-server="$(pwd)/fake.sendmail" \
1668                 email-using-qp \
1669                 2>errors >out &&
1670         sed "1,/^$/d" msgtxt1 >actual &&
1671         test_cmp expected actual
1672 '
1673
1674 test_expect_success $PREREQ 'setup expect' "
1675 tr -d '\\015' | tr '%' '\\015' >email-using-crlf <<EOF
1676 From fe6ecc66ece37198fe5db91fa2fc41d9f4fe5cc4 Mon Sep 17 00:00:00 2001
1677 Message-Id: <bogus-message-id@example.com>
1678 From: A U Thor <author@example.com>
1679 Date: Sat, 12 Jun 2010 15:53:58 +0200
1680 Content-Type: text/plain; charset=UTF-8
1681 Subject: Nothing to see here.
1682
1683 Look, I have a CRLF and an = sign!%
1684 EOF
1685 "
1686
1687 test_expect_success $PREREQ 'setup expect' '
1688         cat >expected <<-\EOF
1689         Look, I have a CRLF and an =3D sign!=0D
1690         EOF
1691 '
1692
1693 test_expect_success $PREREQ 'CRLF and sendemail.transferencoding=quoted-printable' '
1694         clean_fake_sendmail &&
1695         git send-email \
1696                 --transfer-encoding=quoted-printable \
1697                 --smtp-server="$(pwd)/fake.sendmail" \
1698                 email-using-crlf \
1699                 2>errors >out &&
1700         sed "1,/^$/d" msgtxt1 >actual &&
1701         test_cmp expected actual
1702 '
1703
1704 test_expect_success $PREREQ 'setup expect' '
1705         cat >expected <<-\EOF
1706         TG9vaywgSSBoYXZlIGEgQ1JMRiBhbmQgYW4gPSBzaWduIQ0K
1707         EOF
1708 '
1709
1710 test_expect_success $PREREQ 'CRLF and sendemail.transferencoding=base64' '
1711         clean_fake_sendmail &&
1712         git send-email \
1713                 --transfer-encoding=base64 \
1714                 --smtp-server="$(pwd)/fake.sendmail" \
1715                 email-using-crlf \
1716                 2>errors >out &&
1717         sed "1,/^$/d" msgtxt1 >actual &&
1718         test_cmp expected actual
1719 '
1720
1721
1722 # Note that the patches in this test are deliberately out of order; we
1723 # want to make sure it works even if the cover-letter is not in the
1724 # first mail.
1725 test_expect_success $PREREQ 'refusing to send cover letter template' '
1726         clean_fake_sendmail &&
1727         rm -fr outdir &&
1728         git format-patch --cover-letter -2 -o outdir &&
1729         test_must_fail git send-email \
1730                 --from="Example <nobody@example.com>" \
1731                 --to=nobody@example.com \
1732                 --smtp-server="$(pwd)/fake.sendmail" \
1733                 outdir/0002-*.patch \
1734                 outdir/0000-*.patch \
1735                 outdir/0001-*.patch \
1736                 2>errors >out &&
1737         grep "SUBJECT HERE" errors &&
1738         test -z "$(ls msgtxt*)"
1739 '
1740
1741 test_expect_success $PREREQ '--force sends cover letter template anyway' '
1742         clean_fake_sendmail &&
1743         rm -fr outdir &&
1744         git format-patch --cover-letter -2 -o outdir &&
1745         git send-email \
1746                 --force \
1747                 --from="Example <nobody@example.com>" \
1748                 --to=nobody@example.com \
1749                 --smtp-server="$(pwd)/fake.sendmail" \
1750                 outdir/0002-*.patch \
1751                 outdir/0000-*.patch \
1752                 outdir/0001-*.patch \
1753                 2>errors >out &&
1754         ! grep "SUBJECT HERE" errors &&
1755         test -n "$(ls msgtxt*)"
1756 '
1757
1758 test_cover_addresses () {
1759         header="$1"
1760         shift
1761         clean_fake_sendmail &&
1762         rm -fr outdir &&
1763         git format-patch --cover-letter -2 -o outdir &&
1764         cover=$(echo outdir/0000-*.patch) &&
1765         mv $cover cover-to-edit.patch &&
1766         perl -pe "s/^From:/$header: extra\@address.com\nFrom:/" cover-to-edit.patch >"$cover" &&
1767         git send-email \
1768                 --force \
1769                 --from="Example <nobody@example.com>" \
1770                 --no-to --no-cc \
1771                 "$@" \
1772                 --smtp-server="$(pwd)/fake.sendmail" \
1773                 outdir/0000-*.patch \
1774                 outdir/0001-*.patch \
1775                 outdir/0002-*.patch \
1776                 2>errors >out &&
1777         grep "^$header: extra@address.com" msgtxt1 >to1 &&
1778         grep "^$header: extra@address.com" msgtxt2 >to2 &&
1779         grep "^$header: extra@address.com" msgtxt3 >to3 &&
1780         test_line_count = 1 to1 &&
1781         test_line_count = 1 to2 &&
1782         test_line_count = 1 to3
1783 }
1784
1785 test_expect_success $PREREQ 'to-cover adds To to all mail' '
1786         test_cover_addresses "To" --to-cover
1787 '
1788
1789 test_expect_success $PREREQ 'cc-cover adds Cc to all mail' '
1790         test_cover_addresses "Cc" --cc-cover
1791 '
1792
1793 test_expect_success $PREREQ 'tocover adds To to all mail' '
1794         test_config sendemail.tocover true &&
1795         test_cover_addresses "To"
1796 '
1797
1798 test_expect_success $PREREQ 'cccover adds Cc to all mail' '
1799         test_config sendemail.cccover true &&
1800         test_cover_addresses "Cc"
1801 '
1802
1803 test_expect_success $PREREQ 'escaped quotes in sendemail.aliasfiletype=mutt' '
1804         clean_fake_sendmail &&
1805         echo "alias sbd \\\"Dot U. Sir\\\" <somebody@example.org>" >.mutt &&
1806         git config --replace-all sendemail.aliasesfile "$(pwd)/.mutt" &&
1807         git config sendemail.aliasfiletype mutt &&
1808         git send-email \
1809                 --from="Example <nobody@example.com>" \
1810                 --to=sbd \
1811                 --smtp-server="$(pwd)/fake.sendmail" \
1812                 outdir/0001-*.patch \
1813                 2>errors >out &&
1814         grep "^!somebody@example\.org!$" commandline1 &&
1815         grep -F "To: \"Dot U. Sir\" <somebody@example.org>" out
1816 '
1817
1818 test_expect_success $PREREQ 'sendemail.aliasfiletype=mailrc' '
1819         clean_fake_sendmail &&
1820         echo "alias sbd  somebody@example.org" >.mailrc &&
1821         git config --replace-all sendemail.aliasesfile "$(pwd)/.mailrc" &&
1822         git config sendemail.aliasfiletype mailrc &&
1823         git send-email \
1824                 --from="Example <nobody@example.com>" \
1825                 --to=sbd \
1826                 --smtp-server="$(pwd)/fake.sendmail" \
1827                 outdir/0001-*.patch \
1828                 2>errors >out &&
1829         grep "^!somebody@example\.org!$" commandline1
1830 '
1831
1832 test_expect_success $PREREQ 'sendemail.aliasfile=~/.mailrc' '
1833         clean_fake_sendmail &&
1834         echo "alias sbd  someone@example.org" >"$HOME/.mailrc" &&
1835         git config --replace-all sendemail.aliasesfile "~/.mailrc" &&
1836         git config sendemail.aliasfiletype mailrc &&
1837         git send-email \
1838                 --from="Example <nobody@example.com>" \
1839                 --to=sbd \
1840                 --smtp-server="$(pwd)/fake.sendmail" \
1841                 outdir/0001-*.patch \
1842                 2>errors >out &&
1843         grep "^!someone@example\.org!$" commandline1
1844 '
1845
1846 test_dump_aliases () {
1847         msg="$1" && shift &&
1848         filetype="$1" && shift &&
1849         printf '%s\n' "$@" >expect &&
1850         cat >.tmp-email-aliases &&
1851
1852         test_expect_success $PREREQ "$msg" '
1853                 clean_fake_sendmail && rm -fr outdir &&
1854                 git config --replace-all sendemail.aliasesfile \
1855                         "$(pwd)/.tmp-email-aliases" &&
1856                 git config sendemail.aliasfiletype "$filetype" &&
1857                 git send-email --dump-aliases 2>errors >actual &&
1858                 test_cmp expect actual
1859         '
1860 }
1861
1862 test_dump_aliases '--dump-aliases sendmail format' \
1863         'sendmail' \
1864         'abgroup' \
1865         'alice' \
1866         'bcgrp' \
1867         'bob' \
1868         'chloe' <<-\EOF
1869         alice: Alice W Land <awol@example.com>
1870         bob: Robert Bobbyton <bob@example.com>
1871         chloe: chloe@example.com
1872         abgroup: alice, bob
1873         bcgrp: bob, chloe, Other <o@example.com>
1874         EOF
1875
1876 test_dump_aliases '--dump-aliases mutt format' \
1877         'mutt' \
1878         'alice' \
1879         'bob' \
1880         'chloe' \
1881         'donald' <<-\EOF
1882         alias alice Alice W Land <awol@example.com>
1883         alias donald Donald C Carlton <donc@example.com>
1884         alias bob Robert Bobbyton <bob@example.com>
1885         alias chloe chloe@example.com
1886         EOF
1887
1888 test_dump_aliases '--dump-aliases mailrc format' \
1889         'mailrc' \
1890         'alice' \
1891         'bob' \
1892         'chloe' \
1893         'eve' <<-\EOF
1894         alias alice   Alice W Land <awol@example.com>
1895         alias eve     Eve <eve@example.com>
1896         alias bob     Robert Bobbyton <bob@example.com>
1897         alias chloe   chloe@example.com
1898         EOF
1899
1900 test_dump_aliases '--dump-aliases pine format' \
1901         'pine' \
1902         'alice' \
1903         'bob' \
1904         'chloe' \
1905         'eve' <<-\EOF
1906         alice   Alice W Land    <awol@example.com>
1907         eve     Eve     <eve@example.com>
1908         bob     Robert  Bobbyton <bob@example.com>
1909         chloe           chloe@example.com
1910         EOF
1911
1912 test_dump_aliases '--dump-aliases gnus format' \
1913         'gnus' \
1914         'alice' \
1915         'bob' \
1916         'chloe' \
1917         'eve' <<-\EOF
1918         (define-mail-alias "alice" "awol@example.com")
1919         (define-mail-alias "eve" "eve@example.com")
1920         (define-mail-alias "bob" "bob@example.com")
1921         (define-mail-alias "chloe" "chloe@example.com")
1922         EOF
1923
1924 test_expect_success '--dump-aliases must be used alone' '
1925         test_must_fail git send-email --dump-aliases --to=janice@example.com -1 refs/heads/accounting
1926 '
1927
1928 test_expect_success $PREREQ 'aliases and sendemail.identity' '
1929         test_must_fail git \
1930                 -c sendemail.identity=cloud \
1931                 -c sendemail.aliasesfile=default-aliases \
1932                 -c sendemail.cloud.aliasesfile=cloud-aliases \
1933                 send-email -1 2>stderr &&
1934         test_i18ngrep "cloud-aliases" stderr
1935 '
1936
1937 test_sendmail_aliases () {
1938         msg="$1" && shift &&
1939         expect="$@" &&
1940         cat >.tmp-email-aliases &&
1941
1942         test_expect_success $PREREQ "$msg" '
1943                 clean_fake_sendmail && rm -fr outdir &&
1944                 git format-patch -1 -o outdir &&
1945                 git config --replace-all sendemail.aliasesfile \
1946                         "$(pwd)/.tmp-email-aliases" &&
1947                 git config sendemail.aliasfiletype sendmail &&
1948                 git send-email \
1949                         --from="Example <nobody@example.com>" \
1950                         --to=alice --to=bcgrp \
1951                         --smtp-server="$(pwd)/fake.sendmail" \
1952                         outdir/0001-*.patch \
1953                         2>errors >out &&
1954                 for i in $expect
1955                 do
1956                         grep "^!$i!$" commandline1 || return 1
1957                 done
1958         '
1959 }
1960
1961 test_sendmail_aliases 'sendemail.aliasfiletype=sendmail' \
1962         'awol@example\.com' \
1963         'bob@example\.com' \
1964         'chloe@example\.com' \
1965         'o@example\.com' <<-\EOF
1966         alice: Alice W Land <awol@example.com>
1967         bob: Robert Bobbyton <bob@example.com>
1968         # this is a comment
1969            # this is also a comment
1970         chloe: chloe@example.com
1971         abgroup: alice, bob
1972         bcgrp: bob, chloe, Other <o@example.com>
1973         EOF
1974
1975 test_sendmail_aliases 'sendmail aliases line folding' \
1976         alice1 \
1977         bob1 bob2 \
1978         chuck1 chuck2 \
1979         darla1 darla2 darla3 \
1980         elton1 elton2 elton3 \
1981         fred1 fred2 \
1982         greg1 <<-\EOF
1983         alice: alice1
1984         bob: bob1,\
1985         bob2
1986         chuck: chuck1,
1987             chuck2
1988         darla: darla1,\
1989         darla2,
1990             darla3
1991         elton: elton1,
1992             elton2,\
1993         elton3
1994         fred: fred1,\
1995             fred2
1996         greg: greg1
1997         bcgrp: bob, chuck, darla, elton, fred, greg
1998         EOF
1999
2000 test_sendmail_aliases 'sendmail aliases tolerate bogus line folding' \
2001         alice1 bob1 <<-\EOF
2002             alice: alice1
2003         bcgrp: bob1\
2004         EOF
2005
2006 test_sendmail_aliases 'sendmail aliases empty' alice bcgrp <<-\EOF
2007         EOF
2008
2009 test_expect_success $PREREQ 'alias support in To header' '
2010         clean_fake_sendmail &&
2011         echo "alias sbd  someone@example.org" >.mailrc &&
2012         test_config sendemail.aliasesfile ".mailrc" &&
2013         test_config sendemail.aliasfiletype mailrc &&
2014         git format-patch --stdout -1 --to=sbd >aliased.patch &&
2015         git send-email \
2016                 --from="Example <nobody@example.com>" \
2017                 --smtp-server="$(pwd)/fake.sendmail" \
2018                 aliased.patch \
2019                 2>errors >out &&
2020         grep "^!someone@example\.org!$" commandline1
2021 '
2022
2023 test_expect_success $PREREQ 'alias support in Cc header' '
2024         clean_fake_sendmail &&
2025         echo "alias sbd  someone@example.org" >.mailrc &&
2026         test_config sendemail.aliasesfile ".mailrc" &&
2027         test_config sendemail.aliasfiletype mailrc &&
2028         git format-patch --stdout -1 --cc=sbd >aliased.patch &&
2029         git send-email \
2030                 --from="Example <nobody@example.com>" \
2031                 --smtp-server="$(pwd)/fake.sendmail" \
2032                 aliased.patch \
2033                 2>errors >out &&
2034         grep "^!someone@example\.org!$" commandline1
2035 '
2036
2037 test_expect_success $PREREQ 'tocmd works with aliases' '
2038         clean_fake_sendmail &&
2039         echo "alias sbd  someone@example.org" >.mailrc &&
2040         test_config sendemail.aliasesfile ".mailrc" &&
2041         test_config sendemail.aliasfiletype mailrc &&
2042         git format-patch --stdout -1 >tocmd.patch &&
2043         echo tocmd--sbd >>tocmd.patch &&
2044         git send-email \
2045                 --from="Example <nobody@example.com>" \
2046                 --to-cmd=./tocmd-sed \
2047                 --smtp-server="$(pwd)/fake.sendmail" \
2048                 tocmd.patch \
2049                 2>errors >out &&
2050         grep "^!someone@example\.org!$" commandline1
2051 '
2052
2053 test_expect_success $PREREQ 'cccmd works with aliases' '
2054         clean_fake_sendmail &&
2055         echo "alias sbd  someone@example.org" >.mailrc &&
2056         test_config sendemail.aliasesfile ".mailrc" &&
2057         test_config sendemail.aliasfiletype mailrc &&
2058         git format-patch --stdout -1 >cccmd.patch &&
2059         echo cccmd--sbd >>cccmd.patch &&
2060         git send-email \
2061                 --from="Example <nobody@example.com>" \
2062                 --cc-cmd=./cccmd-sed \
2063                 --smtp-server="$(pwd)/fake.sendmail" \
2064                 cccmd.patch \
2065                 2>errors >out &&
2066         grep "^!someone@example\.org!$" commandline1
2067 '
2068
2069 do_xmailer_test () {
2070         expected=$1 params=$2 &&
2071         git format-patch -1 &&
2072         git send-email \
2073                 --from="Example <nobody@example.com>" \
2074                 --to=someone@example.com \
2075                 --smtp-server="$(pwd)/fake.sendmail" \
2076                 $params \
2077                 0001-*.patch \
2078                 2>errors >out &&
2079         { grep '^X-Mailer:' out || :; } >mailer &&
2080         test_line_count = $expected mailer
2081 }
2082
2083 test_expect_success $PREREQ '--[no-]xmailer without any configuration' '
2084         do_xmailer_test 1 "--xmailer" &&
2085         do_xmailer_test 0 "--no-xmailer"
2086 '
2087
2088 test_expect_success $PREREQ '--[no-]xmailer with sendemail.xmailer=true' '
2089         test_config sendemail.xmailer true &&
2090         do_xmailer_test 1 "" &&
2091         do_xmailer_test 0 "--no-xmailer" &&
2092         do_xmailer_test 1 "--xmailer"
2093 '
2094
2095 test_expect_success $PREREQ '--[no-]xmailer with sendemail.xmailer=false' '
2096         test_config sendemail.xmailer false &&
2097         do_xmailer_test 0 "" &&
2098         do_xmailer_test 0 "--no-xmailer" &&
2099         do_xmailer_test 1 "--xmailer"
2100 '
2101
2102 test_expect_success $PREREQ 'setup expected-list' '
2103         git send-email \
2104         --dry-run \
2105         --from="Example <from@example.com>" \
2106         --to="To 1 <to1@example.com>" \
2107         --to="to2@example.com" \
2108         --to="to3@example.com" \
2109         --cc="Cc 1 <cc1@example.com>" \
2110         --cc="Cc2 <cc2@example.com>" \
2111         --bcc="bcc1@example.com" \
2112         --bcc="bcc2@example.com" \
2113         0001-add-main.patch | replace_variable_fields \
2114         >expected-list
2115 '
2116
2117 test_expect_success $PREREQ 'use email list in --cc --to and --bcc' '
2118         git send-email \
2119         --dry-run \
2120         --from="Example <from@example.com>" \
2121         --to="To 1 <to1@example.com>, to2@example.com" \
2122         --to="to3@example.com" \
2123         --cc="Cc 1 <cc1@example.com>, Cc2 <cc2@example.com>" \
2124         --bcc="bcc1@example.com, bcc2@example.com" \
2125         0001-add-main.patch | replace_variable_fields \
2126         >actual-list &&
2127         test_cmp expected-list actual-list
2128 '
2129
2130 test_expect_success $PREREQ 'aliases work with email list' '
2131         echo "alias to2 to2@example.com" >.mutt &&
2132         echo "alias cc1 Cc 1 <cc1@example.com>" >>.mutt &&
2133         test_config sendemail.aliasesfile ".mutt" &&
2134         test_config sendemail.aliasfiletype mutt &&
2135         git send-email \
2136         --dry-run \
2137         --from="Example <from@example.com>" \
2138         --to="To 1 <to1@example.com>, to2, to3@example.com" \
2139         --cc="cc1, Cc2 <cc2@example.com>" \
2140         --bcc="bcc1@example.com, bcc2@example.com" \
2141         0001-add-main.patch | replace_variable_fields \
2142         >actual-list &&
2143         test_cmp expected-list actual-list
2144 '
2145
2146 test_expect_success $PREREQ 'leading and trailing whitespaces are removed' '
2147         echo "alias to2 to2@example.com" >.mutt &&
2148         echo "alias cc1 Cc 1 <cc1@example.com>" >>.mutt &&
2149         test_config sendemail.aliasesfile ".mutt" &&
2150         test_config sendemail.aliasfiletype mutt &&
2151         TO1=$(echo "QTo 1 <to1@example.com>" | q_to_tab) &&
2152         TO2=$(echo "QZto2" | qz_to_tab_space) &&
2153         CC1=$(echo "cc1" | append_cr) &&
2154         BCC1=$(echo " bcc1@example.com Q" | q_to_nul) &&
2155         git send-email \
2156         --dry-run \
2157         --from="        Example <from@example.com>" \
2158         --to="$TO1" \
2159         --to="$TO2" \
2160         --to="  to3@example.com   " \
2161         --cc="$CC1" \
2162         --cc="Cc2 <cc2@example.com>" \
2163         --bcc="$BCC1" \
2164         --bcc="bcc2@example.com" \
2165         0001-add-main.patch | replace_variable_fields \
2166         >actual-list &&
2167         test_cmp expected-list actual-list
2168 '
2169
2170 test_expect_success $PREREQ 'invoke hook' '
2171         mkdir -p .git/hooks &&
2172
2173         write_script .git/hooks/sendemail-validate <<-\EOF &&
2174         # test that we have the correct environment variable, pwd, and
2175         # argument
2176         case "$GIT_DIR" in
2177         *.git)
2178                 true
2179                 ;;
2180         *)
2181                 false
2182                 ;;
2183         esac &&
2184         test -f 0001-add-main.patch &&
2185         grep "add main" "$1"
2186         EOF
2187
2188         mkdir subdir &&
2189         (
2190                 # Test that it works even if we are not at the root of the
2191                 # working tree
2192                 cd subdir &&
2193                 git send-email \
2194                         --from="Example <nobody@example.com>" \
2195                         --to=nobody@example.com \
2196                         --smtp-server="$(pwd)/../fake.sendmail" \
2197                         ../0001-add-main.patch &&
2198
2199                 # Verify error message when a patch is rejected by the hook
2200                 sed -e "s/add main/x/" ../0001-add-main.patch >../another.patch &&
2201                 test_must_fail git send-email \
2202                         --from="Example <nobody@example.com>" \
2203                         --to=nobody@example.com \
2204                         --smtp-server="$(pwd)/../fake.sendmail" \
2205                         ../another.patch 2>err &&
2206                 test_i18ngrep "rejected by sendemail-validate hook" err
2207         )
2208 '
2209
2210 test_expect_success $PREREQ 'test that send-email works outside a repo' '
2211         nongit git send-email \
2212                 --from="Example <nobody@example.com>" \
2213                 --to=nobody@example.com \
2214                 --smtp-server="$(pwd)/fake.sendmail" \
2215                 "$(pwd)/0001-add-main.patch"
2216 '
2217
2218 test_expect_success $PREREQ 'test that sendmail config is rejected' '
2219         test_config sendmail.program sendmail &&
2220         test_must_fail git send-email \
2221                 --from="Example <nobody@example.com>" \
2222                 --to=nobody@example.com \
2223                 --smtp-server="$(pwd)/fake.sendmail" \
2224                 HEAD^ 2>err &&
2225         test_i18ngrep "found configuration options for '"'"sendmail"'"'" err
2226 '
2227
2228 test_expect_success $PREREQ 'test that sendmail config rejection is specific' '
2229         test_config resendmail.program sendmail &&
2230         git send-email \
2231                 --from="Example <nobody@example.com>" \
2232                 --to=nobody@example.com \
2233                 --smtp-server="$(pwd)/fake.sendmail" \
2234                 HEAD^
2235 '
2236
2237 test_expect_success $PREREQ 'test forbidSendmailVariables behavior override' '
2238         test_config sendmail.program sendmail &&
2239         test_config sendemail.forbidSendmailVariables false &&
2240         git send-email \
2241                 --from="Example <nobody@example.com>" \
2242                 --to=nobody@example.com \
2243                 --smtp-server="$(pwd)/fake.sendmail" \
2244                 HEAD^
2245 '
2246
2247 test_done