Skip to content

Commit 05eda51

Browse files
committed
Merge branch 'km/send-email-compose-encoding'
"git send-email --compose" can let the user create a non-ascii cover letter message, but there was not a way to mark it with appropriate content type before sending it out. Further updates fix subject quoting. * km/send-email-compose-encoding: git-send-email: add rfc2047 quoting for "=?" git-send-email: introduce quote_subject() git-send-email: skip RFC2047 quoting for ASCII subjects git-send-email: use compose-encoding for Subject git-send-email: introduce compose-encoding
2 parents 64b22a5 + ce1459f commit 05eda51

File tree

3 files changed

+116
-5
lines changed

3 files changed

+116
-5
lines changed

Documentation/git-send-email.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@ The --to option must be repeated for each user you want on the to list.
126126
+
127127
Note that no attempts whatsoever are made to validate the encoding.
128128

129+
--compose-encoding=<encoding>::
130+
Specify encoding of compose message. Default is the value of the
131+
'sendemail.composeencoding'; if that is unspecified, UTF-8 is assumed.
132+
129133

130134
Sending
131135
~~~~~~~

git-send-email.perl

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ sub usage {
5656
--in-reply-to <str> * Email "In-Reply-To:"
5757
--annotate * Review each patch that will be sent in an editor.
5858
--compose * Open an editor for introduction.
59+
--compose-encoding <str> * Encoding to assume for introduction.
5960
--8bit-encoding <str> * Encoding to assume 8bit mails if undeclared
6061
6162
Sending:
@@ -198,6 +199,7 @@ sub do_edit {
198199
my ($validate, $confirm);
199200
my (@suppress_cc);
200201
my ($auto_8bit_encoding);
202+
my ($compose_encoding);
201203

202204
my ($debug_net_smtp) = 0; # Net::SMTP, see send_message()
203205

@@ -231,6 +233,7 @@ sub do_edit {
231233
"confirm" => \$confirm,
232234
"from" => \$sender,
233235
"assume8bitencoding" => \$auto_8bit_encoding,
236+
"composeencoding" => \$compose_encoding,
234237
);
235238

236239
my %config_path_settings = (
@@ -315,6 +318,7 @@ sub signal_handler {
315318
"validate!" => \$validate,
316319
"format-patch!" => \$format_patch,
317320
"8bit-encoding=s" => \$auto_8bit_encoding,
321+
"compose-encoding=s" => \$compose_encoding,
318322
"force" => \$force,
319323
);
320324

@@ -632,6 +636,9 @@ sub get_patch_subject {
632636
my $need_8bit_cte = file_has_nonascii($compose_filename);
633637
my $in_body = 0;
634638
my $summary_empty = 1;
639+
if (!defined $compose_encoding) {
640+
$compose_encoding = "UTF-8";
641+
}
635642
while(<$c>) {
636643
next if m/^GIT:/;
637644
if ($in_body) {
@@ -641,7 +648,7 @@ sub get_patch_subject {
641648
if ($need_8bit_cte) {
642649
print $c2 "MIME-Version: 1.0\n",
643650
"Content-Type: text/plain; ",
644-
"charset=UTF-8\n",
651+
"charset=$compose_encoding\n",
645652
"Content-Transfer-Encoding: 8bit\n";
646653
}
647654
} elsif (/^MIME-Version:/i) {
@@ -650,9 +657,7 @@ sub get_patch_subject {
650657
$initial_subject = $1;
651658
my $subject = $initial_subject;
652659
$_ = "Subject: " .
653-
($subject =~ /[^[:ascii:]]/ ?
654-
quote_rfc2047($subject) :
655-
$subject) .
660+
quote_subject($subject, $compose_encoding) .
656661
"\n";
657662
} elsif (/^In-Reply-To:\s*(.+)\s*$/i) {
658663
$initial_reply_to = $1;
@@ -900,6 +905,22 @@ sub is_rfc2047_quoted {
900905
$s =~ m/^(?:"[[:ascii:]]*"|=\?$token\?$token\?$encoded_text\?=)$/o;
901906
}
902907

908+
sub subject_needs_rfc2047_quoting {
909+
my $s = shift;
910+
911+
return ($s =~ /[^[:ascii:]]/) || ($s =~ /=\?/);
912+
}
913+
914+
sub quote_subject {
915+
local $subject = shift;
916+
my $encoding = shift || 'UTF-8';
917+
918+
if (subject_needs_rfc2047_quoting($subject)) {
919+
return quote_rfc2047($subject, $encoding);
920+
}
921+
return $subject;
922+
}
923+
903924
# use the simplest quoting being able to handle the recipient
904925
sub sanitize_address {
905926
my ($recipient) = @_;
@@ -1321,7 +1342,7 @@ sub send_message {
13211342
}
13221343

13231344
if ($broken_encoding{$t} && !is_rfc2047_quoted($subject)) {
1324-
$subject = quote_rfc2047($subject, $auto_8bit_encoding);
1345+
$subject = quote_subject($subject, $auto_8bit_encoding);
13251346
}
13261347

13271348
if (defined $author and $author ne $sender) {

t/t9001-send-email.sh

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -854,6 +854,75 @@ test_expect_success $PREREQ 'utf8 author is correctly passed on' '
854854
grep "^From: Füñný Nâmé <[email protected]>" msgtxt1
855855
'
856856

857+
test_expect_success $PREREQ 'sendemail.composeencoding works' '
858+
clean_fake_sendmail &&
859+
git config sendemail.composeencoding iso-8859-1 &&
860+
(echo "#!$SHELL_PATH" &&
861+
echo "echo utf8 body: àéìöú >>\"\$1\""
862+
) >fake-editor-utf8 &&
863+
chmod +x fake-editor-utf8 &&
864+
GIT_EDITOR="\"$(pwd)/fake-editor-utf8\"" \
865+
git send-email \
866+
--compose --subject foo \
867+
--from="Example <[email protected]>" \
868+
869+
--smtp-server="$(pwd)/fake.sendmail" \
870+
$patches &&
871+
grep "^utf8 body" msgtxt1 &&
872+
grep "^Content-Type: text/plain; charset=iso-8859-1" msgtxt1
873+
'
874+
875+
test_expect_success $PREREQ '--compose-encoding works' '
876+
clean_fake_sendmail &&
877+
(echo "#!$SHELL_PATH" &&
878+
echo "echo utf8 body: àéìöú >>\"\$1\""
879+
) >fake-editor-utf8 &&
880+
chmod +x fake-editor-utf8 &&
881+
GIT_EDITOR="\"$(pwd)/fake-editor-utf8\"" \
882+
git send-email \
883+
--compose-encoding iso-8859-1 \
884+
--compose --subject foo \
885+
--from="Example <[email protected]>" \
886+
887+
--smtp-server="$(pwd)/fake.sendmail" \
888+
$patches &&
889+
grep "^utf8 body" msgtxt1 &&
890+
grep "^Content-Type: text/plain; charset=iso-8859-1" msgtxt1
891+
'
892+
893+
test_expect_success $PREREQ '--compose-encoding overrides sendemail.composeencoding' '
894+
clean_fake_sendmail &&
895+
git config sendemail.composeencoding iso-8859-1 &&
896+
(echo "#!$SHELL_PATH" &&
897+
echo "echo utf8 body: àéìöú >>\"\$1\""
898+
) >fake-editor-utf8 &&
899+
chmod +x fake-editor-utf8 &&
900+
GIT_EDITOR="\"$(pwd)/fake-editor-utf8\"" \
901+
git send-email \
902+
--compose-encoding iso-8859-2 \
903+
--compose --subject foo \
904+
--from="Example <[email protected]>" \
905+
906+
--smtp-server="$(pwd)/fake.sendmail" \
907+
$patches &&
908+
grep "^utf8 body" msgtxt1 &&
909+
grep "^Content-Type: text/plain; charset=iso-8859-2" msgtxt1
910+
'
911+
912+
test_expect_success $PREREQ '--compose-encoding adds correct MIME for subject' '
913+
clean_fake_sendmail &&
914+
GIT_EDITOR="\"$(pwd)/fake-editor\"" \
915+
git send-email \
916+
--compose-encoding iso-8859-2 \
917+
--compose --subject utf8-sübjëct \
918+
--from="Example <[email protected]>" \
919+
920+
--smtp-server="$(pwd)/fake.sendmail" \
921+
$patches &&
922+
grep "^fake edit" msgtxt1 &&
923+
grep "^Subject: =?iso-8859-2?q?utf8-s=C3=BCbj=C3=ABct?=" msgtxt1
924+
'
925+
857926
test_expect_success $PREREQ 'detects ambiguous reference/file conflict' '
858927
echo master > master &&
859928
git add master &&
@@ -1073,6 +1142,23 @@ Dieser deutsche Text enthält einen Umlaut!
10731142
EOF
10741143
'
10751144

1145+
test_expect_success $PREREQ 'setup expect' '
1146+
cat >expected <<EOF
1147+
Subject: subject goes here
1148+
EOF
1149+
'
1150+
1151+
test_expect_success $PREREQ 'ASCII subject is not RFC2047 quoted' '
1152+
clean_fake_sendmail &&
1153+
echo bogus |
1154+
1155+
--smtp-server="$(pwd)/fake.sendmail" \
1156+
--8bit-encoding=UTF-8 \
1157+
email-using-8bit >stdout &&
1158+
grep "Subject" msgtxt1 >actual &&
1159+
test_cmp expected actual
1160+
'
1161+
10761162
test_expect_success $PREREQ 'setup expect' '
10771163
cat >content-type-decl <<EOF
10781164
MIME-Version: 1.0

0 commit comments

Comments
 (0)