Merge branch 'ab/config-based-hooks-base' into seen
[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 '"'"'git hook run sendemail-validate -- <patch>'"'"' 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 '"'"'git hook run sendemail-validate -- <patch>'"'"' 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 'sendemail.identity: bool variable without a value' '
1372         git -c sendemail.xmailer \
1373                 send-email \
1374                 --dry-run \
1375                 --from="nobody@example.com" \
1376                 $patches >stdout &&
1377         grep "To: default@example.com" stdout &&
1378         grep "X-Mailer" stdout
1379 '
1380
1381 test_expect_success $PREREQ '--no-to overrides sendemail.to' '
1382         git send-email \
1383                 --dry-run \
1384                 --from="Example <nobody@example.com>" \
1385                 --no-to \
1386                 --to=nobody@example.com \
1387                 $patches >stdout &&
1388         grep "To: nobody@example.com" stdout &&
1389         ! grep "To: Somebody <somebody@ex.com>" stdout
1390 '
1391
1392 test_expect_success $PREREQ 'sendemail.cc works' '
1393         git config --replace-all sendemail.cc "Somebody <somebody@ex.com>" &&
1394         git send-email \
1395                 --dry-run \
1396                 --from="Example <nobody@example.com>" \
1397                 --to=nobody@example.com \
1398                 $patches >stdout &&
1399         grep "Cc: Somebody <somebody@ex.com>" stdout
1400 '
1401
1402 test_expect_success $PREREQ '--no-cc overrides sendemail.cc' '
1403         git send-email \
1404                 --dry-run \
1405                 --from="Example <nobody@example.com>" \
1406                 --no-cc \
1407                 --cc=bodies@example.com \
1408                 --to=nobody@example.com \
1409                 $patches >stdout &&
1410         grep "Cc: bodies@example.com" stdout &&
1411         ! grep "Cc: Somebody <somebody@ex.com>" stdout
1412 '
1413
1414 test_expect_success $PREREQ 'sendemail.bcc works' '
1415         git config --replace-all sendemail.bcc "Other <other@ex.com>" &&
1416         git send-email \
1417                 --dry-run \
1418                 --from="Example <nobody@example.com>" \
1419                 --to=nobody@example.com \
1420                 --smtp-server relay.example.com \
1421                 $patches >stdout &&
1422         grep "RCPT TO:<other@ex.com>" stdout
1423 '
1424
1425 test_expect_success $PREREQ '--no-bcc overrides sendemail.bcc' '
1426         git send-email \
1427                 --dry-run \
1428                 --from="Example <nobody@example.com>" \
1429                 --no-bcc \
1430                 --bcc=bodies@example.com \
1431                 --to=nobody@example.com \
1432                 --smtp-server relay.example.com \
1433                 $patches >stdout &&
1434         grep "RCPT TO:<bodies@example.com>" stdout &&
1435         ! grep "RCPT TO:<other@ex.com>" stdout
1436 '
1437
1438 test_expect_success $PREREQ 'patches To headers are used by default' '
1439         patch=$(git format-patch -1 --to="bodies@example.com") &&
1440         test_when_finished "rm $patch" &&
1441         git send-email \
1442                 --dry-run \
1443                 --from="Example <nobody@example.com>" \
1444                 --smtp-server relay.example.com \
1445                 $patch >stdout &&
1446         grep "RCPT TO:<bodies@example.com>" stdout
1447 '
1448
1449 test_expect_success $PREREQ 'patches To headers are appended to' '
1450         patch=$(git format-patch -1 --to="bodies@example.com") &&
1451         test_when_finished "rm $patch" &&
1452         git send-email \
1453                 --dry-run \
1454                 --from="Example <nobody@example.com>" \
1455                 --to=nobody@example.com \
1456                 --smtp-server relay.example.com \
1457                 $patch >stdout &&
1458         grep "RCPT TO:<bodies@example.com>" stdout &&
1459         grep "RCPT TO:<nobody@example.com>" stdout
1460 '
1461
1462 test_expect_success $PREREQ 'To headers from files reset each patch' '
1463         patch1=$(git format-patch -1 --to="bodies@example.com") &&
1464         patch2=$(git format-patch -1 --to="other@example.com" HEAD~) &&
1465         test_when_finished "rm $patch1 && rm $patch2" &&
1466         git send-email \
1467                 --dry-run \
1468                 --from="Example <nobody@example.com>" \
1469                 --to="nobody@example.com" \
1470                 --smtp-server relay.example.com \
1471                 $patch1 $patch2 >stdout &&
1472         test $(grep -c "RCPT TO:<bodies@example.com>" stdout) = 1 &&
1473         test $(grep -c "RCPT TO:<nobody@example.com>" stdout) = 2 &&
1474         test $(grep -c "RCPT TO:<other@example.com>" stdout) = 1
1475 '
1476
1477 test_expect_success $PREREQ 'setup expect' '
1478 cat >email-using-8bit <<\EOF
1479 From fe6ecc66ece37198fe5db91fa2fc41d9f4fe5cc4 Mon Sep 17 00:00:00 2001
1480 Message-Id: <bogus-message-id@example.com>
1481 From: author@example.com
1482 Date: Sat, 12 Jun 2010 15:53:58 +0200
1483 Subject: subject goes here
1484
1485 Dieser deutsche Text enthält einen Umlaut!
1486 EOF
1487 '
1488
1489 test_expect_success $PREREQ 'setup expect' '
1490         echo "Subject: subject goes here" >expected
1491 '
1492
1493 test_expect_success $PREREQ 'ASCII subject is not RFC2047 quoted' '
1494         clean_fake_sendmail &&
1495         echo bogus |
1496         git send-email --from=author@example.com --to=nobody@example.com \
1497                         --smtp-server="$(pwd)/fake.sendmail" \
1498                         --8bit-encoding=UTF-8 \
1499                         email-using-8bit >stdout &&
1500         grep "Subject" msgtxt1 >actual &&
1501         test_cmp expected actual
1502 '
1503
1504 test_expect_success $PREREQ 'setup expect' '
1505         cat >content-type-decl <<-\EOF
1506         MIME-Version: 1.0
1507         Content-Type: text/plain; charset=UTF-8
1508         Content-Transfer-Encoding: 8bit
1509         EOF
1510 '
1511
1512 test_expect_success $PREREQ 'asks about and fixes 8bit encodings' '
1513         clean_fake_sendmail &&
1514         echo |
1515         git send-email --from=author@example.com --to=nobody@example.com \
1516                         --smtp-server="$(pwd)/fake.sendmail" \
1517                         email-using-8bit >stdout &&
1518         grep "do not declare a Content-Transfer-Encoding" stdout &&
1519         grep email-using-8bit stdout &&
1520         grep "Which 8bit encoding" stdout &&
1521         egrep "Content|MIME" msgtxt1 >actual &&
1522         test_cmp content-type-decl actual
1523 '
1524
1525 test_expect_success $PREREQ 'sendemail.8bitEncoding works' '
1526         clean_fake_sendmail &&
1527         git config sendemail.assume8bitEncoding UTF-8 &&
1528         echo bogus |
1529         git send-email --from=author@example.com --to=nobody@example.com \
1530                         --smtp-server="$(pwd)/fake.sendmail" \
1531                         email-using-8bit >stdout &&
1532         egrep "Content|MIME" msgtxt1 >actual &&
1533         test_cmp content-type-decl actual
1534 '
1535
1536 test_expect_success $PREREQ '--8bit-encoding overrides sendemail.8bitEncoding' '
1537         clean_fake_sendmail &&
1538         git config sendemail.assume8bitEncoding "bogus too" &&
1539         echo bogus |
1540         git send-email --from=author@example.com --to=nobody@example.com \
1541                         --smtp-server="$(pwd)/fake.sendmail" \
1542                         --8bit-encoding=UTF-8 \
1543                         email-using-8bit >stdout &&
1544         egrep "Content|MIME" msgtxt1 >actual &&
1545         test_cmp content-type-decl actual
1546 '
1547
1548 test_expect_success $PREREQ 'setup expect' '
1549         cat >email-using-8bit <<-\EOF
1550         From fe6ecc66ece37198fe5db91fa2fc41d9f4fe5cc4 Mon Sep 17 00:00:00 2001
1551         Message-Id: <bogus-message-id@example.com>
1552         From: author@example.com
1553         Date: Sat, 12 Jun 2010 15:53:58 +0200
1554         Subject: Dieser Betreff enthält auch einen Umlaut!
1555
1556         Nothing to see here.
1557         EOF
1558 '
1559
1560 test_expect_success $PREREQ 'setup expect' '
1561         cat >expected <<-\EOF
1562         Subject: =?UTF-8?q?Dieser=20Betreff=20enth=C3=A4lt=20auch=20einen=20Umlaut!?=
1563         EOF
1564 '
1565
1566 test_expect_success $PREREQ '--8bit-encoding also treats subject' '
1567         clean_fake_sendmail &&
1568         echo bogus |
1569         git send-email --from=author@example.com --to=nobody@example.com \
1570                         --smtp-server="$(pwd)/fake.sendmail" \
1571                         --8bit-encoding=UTF-8 \
1572                         email-using-8bit >stdout &&
1573         grep "Subject" msgtxt1 >actual &&
1574         test_cmp expected actual
1575 '
1576
1577 test_expect_success $PREREQ 'setup expect' '
1578         cat >email-using-8bit <<-\EOF
1579         From fe6ecc66ece37198fe5db91fa2fc41d9f4fe5cc4 Mon Sep 17 00:00:00 2001
1580         Message-Id: <bogus-message-id@example.com>
1581         From: A U Thor <author@example.com>
1582         Date: Sat, 12 Jun 2010 15:53:58 +0200
1583         Content-Type: text/plain; charset=UTF-8
1584         Subject: Nothing to see here.
1585
1586         Dieser Betreff enthält auch einen Umlaut!
1587         EOF
1588 '
1589
1590 test_expect_success $PREREQ '--transfer-encoding overrides sendemail.transferEncoding' '
1591         clean_fake_sendmail &&
1592         test_must_fail git -c sendemail.transferEncoding=8bit \
1593                 send-email \
1594                 --transfer-encoding=7bit \
1595                 --smtp-server="$(pwd)/fake.sendmail" \
1596                 email-using-8bit \
1597                 2>errors >out &&
1598         grep "cannot send message as 7bit" errors &&
1599         test -z "$(ls msgtxt*)"
1600 '
1601
1602 test_expect_success $PREREQ 'sendemail.transferEncoding via config' '
1603         clean_fake_sendmail &&
1604         test_must_fail git -c sendemail.transferEncoding=7bit \
1605                 send-email \
1606                 --smtp-server="$(pwd)/fake.sendmail" \
1607                 email-using-8bit \
1608                 2>errors >out &&
1609         grep "cannot send message as 7bit" errors &&
1610         test -z "$(ls msgtxt*)"
1611 '
1612
1613 test_expect_success $PREREQ 'sendemail.transferEncoding via cli' '
1614         clean_fake_sendmail &&
1615         test_must_fail git send-email \
1616                 --transfer-encoding=7bit \
1617                 --smtp-server="$(pwd)/fake.sendmail" \
1618                 email-using-8bit \
1619                 2>errors >out &&
1620         grep "cannot send message as 7bit" errors &&
1621         test -z "$(ls msgtxt*)"
1622 '
1623
1624 test_expect_success $PREREQ 'setup expect' '
1625         cat >expected <<-\EOF
1626         Dieser Betreff enth=C3=A4lt auch einen Umlaut!
1627         EOF
1628 '
1629
1630 test_expect_success $PREREQ '8-bit and sendemail.transferencoding=quoted-printable' '
1631         clean_fake_sendmail &&
1632         git send-email \
1633                 --transfer-encoding=quoted-printable \
1634                 --smtp-server="$(pwd)/fake.sendmail" \
1635                 email-using-8bit \
1636                 2>errors >out &&
1637         sed "1,/^$/d" msgtxt1 >actual &&
1638         test_cmp expected actual
1639 '
1640
1641 test_expect_success $PREREQ 'setup expect' '
1642         cat >expected <<-\EOF
1643         RGllc2VyIEJldHJlZmYgZW50aMOkbHQgYXVjaCBlaW5lbiBVbWxhdXQhCg==
1644         EOF
1645 '
1646
1647 test_expect_success $PREREQ '8-bit and sendemail.transferencoding=base64' '
1648         clean_fake_sendmail &&
1649         git send-email \
1650                 --transfer-encoding=base64 \
1651                 --smtp-server="$(pwd)/fake.sendmail" \
1652                 email-using-8bit \
1653                 2>errors >out &&
1654         sed "1,/^$/d" msgtxt1 >actual &&
1655         test_cmp expected actual
1656 '
1657
1658 test_expect_success $PREREQ 'setup expect' '
1659         cat >email-using-qp <<-\EOF
1660         From fe6ecc66ece37198fe5db91fa2fc41d9f4fe5cc4 Mon Sep 17 00:00:00 2001
1661         Message-Id: <bogus-message-id@example.com>
1662         From: A U Thor <author@example.com>
1663         Date: Sat, 12 Jun 2010 15:53:58 +0200
1664         MIME-Version: 1.0
1665         Content-Transfer-Encoding: quoted-printable
1666         Content-Type: text/plain; charset=UTF-8
1667         Subject: Nothing to see here.
1668
1669         Dieser Betreff enth=C3=A4lt auch einen Umlaut!
1670         EOF
1671 '
1672
1673 test_expect_success $PREREQ 'convert from quoted-printable to base64' '
1674         clean_fake_sendmail &&
1675         git send-email \
1676                 --transfer-encoding=base64 \
1677                 --smtp-server="$(pwd)/fake.sendmail" \
1678                 email-using-qp \
1679                 2>errors >out &&
1680         sed "1,/^$/d" msgtxt1 >actual &&
1681         test_cmp expected actual
1682 '
1683
1684 test_expect_success $PREREQ 'setup expect' "
1685 tr -d '\\015' | tr '%' '\\015' >email-using-crlf <<EOF
1686 From fe6ecc66ece37198fe5db91fa2fc41d9f4fe5cc4 Mon Sep 17 00:00:00 2001
1687 Message-Id: <bogus-message-id@example.com>
1688 From: A U Thor <author@example.com>
1689 Date: Sat, 12 Jun 2010 15:53:58 +0200
1690 Content-Type: text/plain; charset=UTF-8
1691 Subject: Nothing to see here.
1692
1693 Look, I have a CRLF and an = sign!%
1694 EOF
1695 "
1696
1697 test_expect_success $PREREQ 'setup expect' '
1698         cat >expected <<-\EOF
1699         Look, I have a CRLF and an =3D sign!=0D
1700         EOF
1701 '
1702
1703 test_expect_success $PREREQ 'CRLF and sendemail.transferencoding=quoted-printable' '
1704         clean_fake_sendmail &&
1705         git send-email \
1706                 --transfer-encoding=quoted-printable \
1707                 --smtp-server="$(pwd)/fake.sendmail" \
1708                 email-using-crlf \
1709                 2>errors >out &&
1710         sed "1,/^$/d" msgtxt1 >actual &&
1711         test_cmp expected actual
1712 '
1713
1714 test_expect_success $PREREQ 'setup expect' '
1715         cat >expected <<-\EOF
1716         TG9vaywgSSBoYXZlIGEgQ1JMRiBhbmQgYW4gPSBzaWduIQ0K
1717         EOF
1718 '
1719
1720 test_expect_success $PREREQ 'CRLF and sendemail.transferencoding=base64' '
1721         clean_fake_sendmail &&
1722         git send-email \
1723                 --transfer-encoding=base64 \
1724                 --smtp-server="$(pwd)/fake.sendmail" \
1725                 email-using-crlf \
1726                 2>errors >out &&
1727         sed "1,/^$/d" msgtxt1 >actual &&
1728         test_cmp expected actual
1729 '
1730
1731
1732 # Note that the patches in this test are deliberately out of order; we
1733 # want to make sure it works even if the cover-letter is not in the
1734 # first mail.
1735 test_expect_success $PREREQ 'refusing to send cover letter template' '
1736         clean_fake_sendmail &&
1737         rm -fr outdir &&
1738         git format-patch --cover-letter -2 -o outdir &&
1739         test_must_fail git send-email \
1740                 --from="Example <nobody@example.com>" \
1741                 --to=nobody@example.com \
1742                 --smtp-server="$(pwd)/fake.sendmail" \
1743                 outdir/0002-*.patch \
1744                 outdir/0000-*.patch \
1745                 outdir/0001-*.patch \
1746                 2>errors >out &&
1747         grep "SUBJECT HERE" errors &&
1748         test -z "$(ls msgtxt*)"
1749 '
1750
1751 test_expect_success $PREREQ '--force sends cover letter template anyway' '
1752         clean_fake_sendmail &&
1753         rm -fr outdir &&
1754         git format-patch --cover-letter -2 -o outdir &&
1755         git send-email \
1756                 --force \
1757                 --from="Example <nobody@example.com>" \
1758                 --to=nobody@example.com \
1759                 --smtp-server="$(pwd)/fake.sendmail" \
1760                 outdir/0002-*.patch \
1761                 outdir/0000-*.patch \
1762                 outdir/0001-*.patch \
1763                 2>errors >out &&
1764         ! grep "SUBJECT HERE" errors &&
1765         test -n "$(ls msgtxt*)"
1766 '
1767
1768 test_cover_addresses () {
1769         header="$1"
1770         shift
1771         clean_fake_sendmail &&
1772         rm -fr outdir &&
1773         git format-patch --cover-letter -2 -o outdir &&
1774         cover=$(echo outdir/0000-*.patch) &&
1775         mv $cover cover-to-edit.patch &&
1776         perl -pe "s/^From:/$header: extra\@address.com\nFrom:/" cover-to-edit.patch >"$cover" &&
1777         git send-email \
1778                 --force \
1779                 --from="Example <nobody@example.com>" \
1780                 --no-to --no-cc \
1781                 "$@" \
1782                 --smtp-server="$(pwd)/fake.sendmail" \
1783                 outdir/0000-*.patch \
1784                 outdir/0001-*.patch \
1785                 outdir/0002-*.patch \
1786                 2>errors >out &&
1787         grep "^$header: extra@address.com" msgtxt1 >to1 &&
1788         grep "^$header: extra@address.com" msgtxt2 >to2 &&
1789         grep "^$header: extra@address.com" msgtxt3 >to3 &&
1790         test_line_count = 1 to1 &&
1791         test_line_count = 1 to2 &&
1792         test_line_count = 1 to3
1793 }
1794
1795 test_expect_success $PREREQ 'to-cover adds To to all mail' '
1796         test_cover_addresses "To" --to-cover
1797 '
1798
1799 test_expect_success $PREREQ 'cc-cover adds Cc to all mail' '
1800         test_cover_addresses "Cc" --cc-cover
1801 '
1802
1803 test_expect_success $PREREQ 'tocover adds To to all mail' '
1804         test_config sendemail.tocover true &&
1805         test_cover_addresses "To"
1806 '
1807
1808 test_expect_success $PREREQ 'cccover adds Cc to all mail' '
1809         test_config sendemail.cccover true &&
1810         test_cover_addresses "Cc"
1811 '
1812
1813 test_expect_success $PREREQ 'escaped quotes in sendemail.aliasfiletype=mutt' '
1814         clean_fake_sendmail &&
1815         echo "alias sbd \\\"Dot U. Sir\\\" <somebody@example.org>" >.mutt &&
1816         git config --replace-all sendemail.aliasesfile "$(pwd)/.mutt" &&
1817         git config sendemail.aliasfiletype mutt &&
1818         git send-email \
1819                 --from="Example <nobody@example.com>" \
1820                 --to=sbd \
1821                 --smtp-server="$(pwd)/fake.sendmail" \
1822                 outdir/0001-*.patch \
1823                 2>errors >out &&
1824         grep "^!somebody@example\.org!$" commandline1 &&
1825         grep -F "To: \"Dot U. Sir\" <somebody@example.org>" out
1826 '
1827
1828 test_expect_success $PREREQ 'sendemail.aliasfiletype=mailrc' '
1829         clean_fake_sendmail &&
1830         echo "alias sbd  somebody@example.org" >.mailrc &&
1831         git config --replace-all sendemail.aliasesfile "$(pwd)/.mailrc" &&
1832         git config sendemail.aliasfiletype mailrc &&
1833         git send-email \
1834                 --from="Example <nobody@example.com>" \
1835                 --to=sbd \
1836                 --smtp-server="$(pwd)/fake.sendmail" \
1837                 outdir/0001-*.patch \
1838                 2>errors >out &&
1839         grep "^!somebody@example\.org!$" commandline1
1840 '
1841
1842 test_expect_success $PREREQ 'sendemail.aliasfile=~/.mailrc' '
1843         clean_fake_sendmail &&
1844         echo "alias sbd  someone@example.org" >"$HOME/.mailrc" &&
1845         git config --replace-all sendemail.aliasesfile "~/.mailrc" &&
1846         git config sendemail.aliasfiletype mailrc &&
1847         git send-email \
1848                 --from="Example <nobody@example.com>" \
1849                 --to=sbd \
1850                 --smtp-server="$(pwd)/fake.sendmail" \
1851                 outdir/0001-*.patch \
1852                 2>errors >out &&
1853         grep "^!someone@example\.org!$" commandline1
1854 '
1855
1856 test_dump_aliases () {
1857         msg="$1" && shift &&
1858         filetype="$1" && shift &&
1859         printf '%s\n' "$@" >expect &&
1860         cat >.tmp-email-aliases &&
1861
1862         test_expect_success $PREREQ "$msg" '
1863                 clean_fake_sendmail && rm -fr outdir &&
1864                 git config --replace-all sendemail.aliasesfile \
1865                         "$(pwd)/.tmp-email-aliases" &&
1866                 git config sendemail.aliasfiletype "$filetype" &&
1867                 git send-email --dump-aliases 2>errors >actual &&
1868                 test_cmp expect actual
1869         '
1870 }
1871
1872 test_dump_aliases '--dump-aliases sendmail format' \
1873         'sendmail' \
1874         'abgroup' \
1875         'alice' \
1876         'bcgrp' \
1877         'bob' \
1878         'chloe' <<-\EOF
1879         alice: Alice W Land <awol@example.com>
1880         bob: Robert Bobbyton <bob@example.com>
1881         chloe: chloe@example.com
1882         abgroup: alice, bob
1883         bcgrp: bob, chloe, Other <o@example.com>
1884         EOF
1885
1886 test_dump_aliases '--dump-aliases mutt format' \
1887         'mutt' \
1888         'alice' \
1889         'bob' \
1890         'chloe' \
1891         'donald' <<-\EOF
1892         alias alice Alice W Land <awol@example.com>
1893         alias donald Donald C Carlton <donc@example.com>
1894         alias bob Robert Bobbyton <bob@example.com>
1895         alias chloe chloe@example.com
1896         EOF
1897
1898 test_dump_aliases '--dump-aliases mailrc format' \
1899         'mailrc' \
1900         'alice' \
1901         'bob' \
1902         'chloe' \
1903         'eve' <<-\EOF
1904         alias alice   Alice W Land <awol@example.com>
1905         alias eve     Eve <eve@example.com>
1906         alias bob     Robert Bobbyton <bob@example.com>
1907         alias chloe   chloe@example.com
1908         EOF
1909
1910 test_dump_aliases '--dump-aliases pine format' \
1911         'pine' \
1912         'alice' \
1913         'bob' \
1914         'chloe' \
1915         'eve' <<-\EOF
1916         alice   Alice W Land    <awol@example.com>
1917         eve     Eve     <eve@example.com>
1918         bob     Robert  Bobbyton <bob@example.com>
1919         chloe           chloe@example.com
1920         EOF
1921
1922 test_dump_aliases '--dump-aliases gnus format' \
1923         'gnus' \
1924         'alice' \
1925         'bob' \
1926         'chloe' \
1927         'eve' <<-\EOF
1928         (define-mail-alias "alice" "awol@example.com")
1929         (define-mail-alias "eve" "eve@example.com")
1930         (define-mail-alias "bob" "bob@example.com")
1931         (define-mail-alias "chloe" "chloe@example.com")
1932         EOF
1933
1934 test_expect_success '--dump-aliases must be used alone' '
1935         test_must_fail git send-email --dump-aliases --to=janice@example.com -1 refs/heads/accounting
1936 '
1937
1938 test_expect_success $PREREQ 'aliases and sendemail.identity' '
1939         test_must_fail git \
1940                 -c sendemail.identity=cloud \
1941                 -c sendemail.aliasesfile=default-aliases \
1942                 -c sendemail.cloud.aliasesfile=cloud-aliases \
1943                 send-email -1 2>stderr &&
1944         test_i18ngrep "cloud-aliases" stderr
1945 '
1946
1947 test_sendmail_aliases () {
1948         msg="$1" && shift &&
1949         expect="$@" &&
1950         cat >.tmp-email-aliases &&
1951
1952         test_expect_success $PREREQ "$msg" '
1953                 clean_fake_sendmail && rm -fr outdir &&
1954                 git format-patch -1 -o outdir &&
1955                 git config --replace-all sendemail.aliasesfile \
1956                         "$(pwd)/.tmp-email-aliases" &&
1957                 git config sendemail.aliasfiletype sendmail &&
1958                 git send-email \
1959                         --from="Example <nobody@example.com>" \
1960                         --to=alice --to=bcgrp \
1961                         --smtp-server="$(pwd)/fake.sendmail" \
1962                         outdir/0001-*.patch \
1963                         2>errors >out &&
1964                 for i in $expect
1965                 do
1966                         grep "^!$i!$" commandline1 || return 1
1967                 done
1968         '
1969 }
1970
1971 test_sendmail_aliases 'sendemail.aliasfiletype=sendmail' \
1972         'awol@example\.com' \
1973         'bob@example\.com' \
1974         'chloe@example\.com' \
1975         'o@example\.com' <<-\EOF
1976         alice: Alice W Land <awol@example.com>
1977         bob: Robert Bobbyton <bob@example.com>
1978         # this is a comment
1979            # this is also a comment
1980         chloe: chloe@example.com
1981         abgroup: alice, bob
1982         bcgrp: bob, chloe, Other <o@example.com>
1983         EOF
1984
1985 test_sendmail_aliases 'sendmail aliases line folding' \
1986         alice1 \
1987         bob1 bob2 \
1988         chuck1 chuck2 \
1989         darla1 darla2 darla3 \
1990         elton1 elton2 elton3 \
1991         fred1 fred2 \
1992         greg1 <<-\EOF
1993         alice: alice1
1994         bob: bob1,\
1995         bob2
1996         chuck: chuck1,
1997             chuck2
1998         darla: darla1,\
1999         darla2,
2000             darla3
2001         elton: elton1,
2002             elton2,\
2003         elton3
2004         fred: fred1,\
2005             fred2
2006         greg: greg1
2007         bcgrp: bob, chuck, darla, elton, fred, greg
2008         EOF
2009
2010 test_sendmail_aliases 'sendmail aliases tolerate bogus line folding' \
2011         alice1 bob1 <<-\EOF
2012             alice: alice1
2013         bcgrp: bob1\
2014         EOF
2015
2016 test_sendmail_aliases 'sendmail aliases empty' alice bcgrp <<-\EOF
2017         EOF
2018
2019 test_expect_success $PREREQ 'alias support in To header' '
2020         clean_fake_sendmail &&
2021         echo "alias sbd  someone@example.org" >.mailrc &&
2022         test_config sendemail.aliasesfile ".mailrc" &&
2023         test_config sendemail.aliasfiletype mailrc &&
2024         git format-patch --stdout -1 --to=sbd >aliased.patch &&
2025         git send-email \
2026                 --from="Example <nobody@example.com>" \
2027                 --smtp-server="$(pwd)/fake.sendmail" \
2028                 aliased.patch \
2029                 2>errors >out &&
2030         grep "^!someone@example\.org!$" commandline1
2031 '
2032
2033 test_expect_success $PREREQ 'alias support in Cc header' '
2034         clean_fake_sendmail &&
2035         echo "alias sbd  someone@example.org" >.mailrc &&
2036         test_config sendemail.aliasesfile ".mailrc" &&
2037         test_config sendemail.aliasfiletype mailrc &&
2038         git format-patch --stdout -1 --cc=sbd >aliased.patch &&
2039         git send-email \
2040                 --from="Example <nobody@example.com>" \
2041                 --smtp-server="$(pwd)/fake.sendmail" \
2042                 aliased.patch \
2043                 2>errors >out &&
2044         grep "^!someone@example\.org!$" commandline1
2045 '
2046
2047 test_expect_success $PREREQ 'tocmd works with aliases' '
2048         clean_fake_sendmail &&
2049         echo "alias sbd  someone@example.org" >.mailrc &&
2050         test_config sendemail.aliasesfile ".mailrc" &&
2051         test_config sendemail.aliasfiletype mailrc &&
2052         git format-patch --stdout -1 >tocmd.patch &&
2053         echo tocmd--sbd >>tocmd.patch &&
2054         git send-email \
2055                 --from="Example <nobody@example.com>" \
2056                 --to-cmd=./tocmd-sed \
2057                 --smtp-server="$(pwd)/fake.sendmail" \
2058                 tocmd.patch \
2059                 2>errors >out &&
2060         grep "^!someone@example\.org!$" commandline1
2061 '
2062
2063 test_expect_success $PREREQ 'cccmd works with aliases' '
2064         clean_fake_sendmail &&
2065         echo "alias sbd  someone@example.org" >.mailrc &&
2066         test_config sendemail.aliasesfile ".mailrc" &&
2067         test_config sendemail.aliasfiletype mailrc &&
2068         git format-patch --stdout -1 >cccmd.patch &&
2069         echo cccmd--sbd >>cccmd.patch &&
2070         git send-email \
2071                 --from="Example <nobody@example.com>" \
2072                 --cc-cmd=./cccmd-sed \
2073                 --smtp-server="$(pwd)/fake.sendmail" \
2074                 cccmd.patch \
2075                 2>errors >out &&
2076         grep "^!someone@example\.org!$" commandline1
2077 '
2078
2079 do_xmailer_test () {
2080         expected=$1 params=$2 &&
2081         git format-patch -1 &&
2082         git send-email \
2083                 --from="Example <nobody@example.com>" \
2084                 --to=someone@example.com \
2085                 --smtp-server="$(pwd)/fake.sendmail" \
2086                 $params \
2087                 0001-*.patch \
2088                 2>errors >out &&
2089         { grep '^X-Mailer:' out || :; } >mailer &&
2090         test_line_count = $expected mailer
2091 }
2092
2093 test_expect_success $PREREQ '--[no-]xmailer without any configuration' '
2094         do_xmailer_test 1 "--xmailer" &&
2095         do_xmailer_test 0 "--no-xmailer"
2096 '
2097
2098 test_expect_success $PREREQ '--[no-]xmailer with sendemail.xmailer=true' '
2099         test_config sendemail.xmailer true &&
2100         do_xmailer_test 1 "" &&
2101         do_xmailer_test 0 "--no-xmailer" &&
2102         do_xmailer_test 1 "--xmailer"
2103 '
2104
2105 test_expect_success $PREREQ '--[no-]xmailer with sendemail.xmailer' '
2106         test_when_finished "test_unconfig sendemail.xmailer" &&
2107         cat >>.git/config <<-\EOF &&
2108         [sendemail]
2109                 xmailer
2110         EOF
2111         test_config sendemail.xmailer true &&
2112         do_xmailer_test 1 "" &&
2113         do_xmailer_test 0 "--no-xmailer" &&
2114         do_xmailer_test 1 "--xmailer"
2115 '
2116
2117 test_expect_success $PREREQ '--[no-]xmailer with sendemail.xmailer=false' '
2118         test_config sendemail.xmailer false &&
2119         do_xmailer_test 0 "" &&
2120         do_xmailer_test 0 "--no-xmailer" &&
2121         do_xmailer_test 1 "--xmailer"
2122 '
2123
2124 test_expect_success $PREREQ '--[no-]xmailer with sendemail.xmailer=' '
2125         test_config sendemail.xmailer "" &&
2126         do_xmailer_test 0 "" &&
2127         do_xmailer_test 0 "--no-xmailer" &&
2128         do_xmailer_test 1 "--xmailer"
2129 '
2130
2131 test_expect_success $PREREQ 'setup expected-list' '
2132         git send-email \
2133         --dry-run \
2134         --from="Example <from@example.com>" \
2135         --to="To 1 <to1@example.com>" \
2136         --to="to2@example.com" \
2137         --to="to3@example.com" \
2138         --cc="Cc 1 <cc1@example.com>" \
2139         --cc="Cc2 <cc2@example.com>" \
2140         --bcc="bcc1@example.com" \
2141         --bcc="bcc2@example.com" \
2142         0001-add-main.patch | replace_variable_fields \
2143         >expected-list
2144 '
2145
2146 test_expect_success $PREREQ 'use email list in --cc --to and --bcc' '
2147         git send-email \
2148         --dry-run \
2149         --from="Example <from@example.com>" \
2150         --to="To 1 <to1@example.com>, to2@example.com" \
2151         --to="to3@example.com" \
2152         --cc="Cc 1 <cc1@example.com>, Cc2 <cc2@example.com>" \
2153         --bcc="bcc1@example.com, bcc2@example.com" \
2154         0001-add-main.patch | replace_variable_fields \
2155         >actual-list &&
2156         test_cmp expected-list actual-list
2157 '
2158
2159 test_expect_success $PREREQ 'aliases work with email list' '
2160         echo "alias to2 to2@example.com" >.mutt &&
2161         echo "alias cc1 Cc 1 <cc1@example.com>" >>.mutt &&
2162         test_config sendemail.aliasesfile ".mutt" &&
2163         test_config sendemail.aliasfiletype mutt &&
2164         git send-email \
2165         --dry-run \
2166         --from="Example <from@example.com>" \
2167         --to="To 1 <to1@example.com>, to2, to3@example.com" \
2168         --cc="cc1, Cc2 <cc2@example.com>" \
2169         --bcc="bcc1@example.com, bcc2@example.com" \
2170         0001-add-main.patch | replace_variable_fields \
2171         >actual-list &&
2172         test_cmp expected-list actual-list
2173 '
2174
2175 test_expect_success $PREREQ 'leading and trailing whitespaces are removed' '
2176         echo "alias to2 to2@example.com" >.mutt &&
2177         echo "alias cc1 Cc 1 <cc1@example.com>" >>.mutt &&
2178         test_config sendemail.aliasesfile ".mutt" &&
2179         test_config sendemail.aliasfiletype mutt &&
2180         TO1=$(echo "QTo 1 <to1@example.com>" | q_to_tab) &&
2181         TO2=$(echo "QZto2" | qz_to_tab_space) &&
2182         CC1=$(echo "cc1" | append_cr) &&
2183         BCC1=$(echo " bcc1@example.com Q" | q_to_nul) &&
2184         git send-email \
2185         --dry-run \
2186         --from="        Example <from@example.com>" \
2187         --to="$TO1" \
2188         --to="$TO2" \
2189         --to="  to3@example.com   " \
2190         --cc="$CC1" \
2191         --cc="Cc2 <cc2@example.com>" \
2192         --bcc="$BCC1" \
2193         --bcc="bcc2@example.com" \
2194         0001-add-main.patch | replace_variable_fields \
2195         >actual-list &&
2196         test_cmp expected-list actual-list
2197 '
2198
2199 test_expect_success $PREREQ 'test using command name with --sendmail-cmd' '
2200         clean_fake_sendmail &&
2201         PATH="$(pwd):$PATH" \
2202         git send-email \
2203                 --from="Example <nobody@example.com>" \
2204                 --to=nobody@example.com \
2205                 --sendmail-cmd="fake.sendmail" \
2206                 HEAD^ &&
2207         test_path_is_file commandline1
2208 '
2209
2210 test_expect_success $PREREQ 'test using arguments with --sendmail-cmd' '
2211         clean_fake_sendmail &&
2212         git send-email \
2213                 --from="Example <nobody@example.com>" \
2214                 --to=nobody@example.com \
2215                 --sendmail-cmd='\''"$(pwd)/fake.sendmail" -f nobody@example.com'\'' \
2216                 HEAD^ &&
2217         test_path_is_file commandline1
2218 '
2219
2220 test_expect_success $PREREQ 'test shell expression with --sendmail-cmd' '
2221         clean_fake_sendmail &&
2222         git send-email \
2223                 --from="Example <nobody@example.com>" \
2224                 --to=nobody@example.com \
2225                 --sendmail-cmd='\''f() { "$(pwd)/fake.sendmail" "$@"; };f'\'' \
2226                 HEAD^ &&
2227         test_path_is_file commandline1
2228 '
2229
2230 test_expect_success $PREREQ 'invoke hook' '
2231         mkdir -p .git/hooks &&
2232
2233         write_script .git/hooks/sendemail-validate <<-\EOF &&
2234         # test that we have the correct environment variable, pwd, and
2235         # argument
2236         case "$GIT_DIR" in
2237         *.git)
2238                 true
2239                 ;;
2240         *)
2241                 false
2242                 ;;
2243         esac &&
2244         test -f 0001-add-main.patch &&
2245         grep "add main" "$1"
2246         EOF
2247
2248         mkdir subdir &&
2249         (
2250                 # Test that it works even if we are not at the root of the
2251                 # working tree
2252                 cd subdir &&
2253                 git send-email \
2254                         --from="Example <nobody@example.com>" \
2255                         --to=nobody@example.com \
2256                         --smtp-server="$(pwd)/../fake.sendmail" \
2257                         ../0001-add-main.patch &&
2258
2259                 # Verify error message when a patch is rejected by the hook
2260                 sed -e "s/add main/x/" ../0001-add-main.patch >../another.patch &&
2261                 test_must_fail git send-email \
2262                         --from="Example <nobody@example.com>" \
2263                         --to=nobody@example.com \
2264                         --smtp-server="$(pwd)/../fake.sendmail" \
2265                         ../another.patch 2>err &&
2266                 test_i18ngrep "rejected by sendemail-validate hook" err
2267         )
2268 '
2269
2270 test_expect_success $PREREQ 'test that send-email works outside a repo' '
2271         nongit git send-email \
2272                 --from="Example <nobody@example.com>" \
2273                 --to=nobody@example.com \
2274                 --smtp-server="$(pwd)/fake.sendmail" \
2275                 "$(pwd)/0001-add-main.patch"
2276 '
2277
2278 test_expect_success $PREREQ 'test that sendmail config is rejected' '
2279         test_config sendmail.program sendmail &&
2280         test_must_fail git send-email \
2281                 --from="Example <nobody@example.com>" \
2282                 --to=nobody@example.com \
2283                 --smtp-server="$(pwd)/fake.sendmail" \
2284                 HEAD^ 2>err &&
2285         test_i18ngrep "found configuration options for '"'"sendmail"'"'" err
2286 '
2287
2288 test_expect_success $PREREQ 'test that sendmail config rejection is specific' '
2289         test_config resendmail.program sendmail &&
2290         git send-email \
2291                 --from="Example <nobody@example.com>" \
2292                 --to=nobody@example.com \
2293                 --smtp-server="$(pwd)/fake.sendmail" \
2294                 HEAD^
2295 '
2296
2297 test_expect_success $PREREQ 'test forbidSendmailVariables behavior override' '
2298         test_config sendmail.program sendmail &&
2299         test_config sendemail.forbidSendmailVariables false &&
2300         git send-email \
2301                 --from="Example <nobody@example.com>" \
2302                 --to=nobody@example.com \
2303                 --smtp-server="$(pwd)/fake.sendmail" \
2304                 HEAD^
2305 '
2306
2307 test_done