Skip to content

Commit 5006bfc

Browse files
committed
Merge branch 'jk/send-email-fix-addresses-from-composed-messages'
The codepath to handle recipient addresses `git send-email --compose` learns from the user was completely broken, which has been corrected. * jk/send-email-fix-addresses-from-composed-messages: send-email: handle to/cc/bcc from --compose message Revert "send-email: extract email-parsing code into a subroutine" doc/send-email: mention handling of "reply-to" with --compose
2 parents 90c8096 + 3ec6167 commit 5006bfc

File tree

3 files changed

+99
-85
lines changed

3 files changed

+99
-85
lines changed

Documentation/git-send-email.txt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,12 @@ This option may be specified multiple times.
6868
Invoke a text editor (see GIT_EDITOR in linkgit:git-var[1])
6969
to edit an introductory message for the patch series.
7070
+
71-
When `--compose` is used, git send-email will use the From, Subject, and
72-
In-Reply-To headers specified in the message. If the body of the message
73-
(what you type after the headers and a blank line) only contains blank
74-
(or Git: prefixed) lines, the summary won't be sent, but From, Subject,
75-
and In-Reply-To headers will be used unless they are removed.
71+
When `--compose` is used, git send-email will use the From, To, Cc, Bcc,
72+
Subject, Reply-To, and In-Reply-To headers specified in the message. If
73+
the body of the message (what you type after the headers and a blank
74+
line) only contains blank (or Git: prefixed) lines, the summary won't be
75+
sent, but the headers mentioned above will be used unless they are
76+
removed.
7677
+
7778
Missing From or In-Reply-To headers will be prompted for.
7879
+

git-send-email.perl

Lines changed: 52 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -861,6 +861,9 @@ sub get_patch_subject {
861861
my $tpl_subject = $initial_subject || '';
862862
my $tpl_in_reply_to = $initial_in_reply_to || '';
863863
my $tpl_reply_to = $reply_to || '';
864+
my $tpl_to = join(',', @initial_to);
865+
my $tpl_cc = join(',', @initial_cc);
866+
my $tpl_bcc = join(', ', @initial_bcc);
864867

865868
print $c <<EOT1, Git::prefix_lines("GIT: ", __(<<EOT2)), <<EOT3;
866869
From $tpl_sender # This line is ignored.
@@ -872,6 +875,9 @@ sub get_patch_subject {
872875
Clear the body content if you don't wish to send a summary.
873876
EOT2
874877
From: $tpl_sender
878+
To: $tpl_to
879+
Cc: $tpl_cc
880+
Bcc: $tpl_bcc
875881
Reply-To: $tpl_reply_to
876882
Subject: $tpl_subject
877883
In-Reply-To: $tpl_in_reply_to
@@ -888,73 +894,65 @@ sub get_patch_subject {
888894
do_edit($compose_filename);
889895
}
890896
897+
open my $c2, ">", $compose_filename . ".final"
898+
or die sprintf(__("Failed to open %s.final: %s"), $compose_filename, $!);
899+
891900
open $c, "<", $compose_filename
892901
or die sprintf(__("Failed to open %s: %s"), $compose_filename, $!);
893902
903+
my $need_8bit_cte = file_has_nonascii($compose_filename);
904+
my $in_body = 0;
905+
my $summary_empty = 1;
894906
if (!defined $compose_encoding) {
895907
$compose_encoding = "UTF-8";
896908
}
897-
898-
my %parsed_email;
899-
while (my $line = <$c>) {
900-
next if $line =~ m/^GIT:/;
901-
parse_header_line($line, \%parsed_email);
902-
if ($line =~ /^$/) {
903-
$parsed_email{'body'} = filter_body($c);
909+
while(<$c>) {
910+
next if m/^GIT:/;
911+
if ($in_body) {
912+
$summary_empty = 0 unless (/^\n$/);
913+
} elsif (/^\n$/) {
914+
$in_body = 1;
915+
if ($need_8bit_cte) {
916+
print $c2 "MIME-Version: 1.0\n",
917+
"Content-Type: text/plain; ",
918+
"charset=$compose_encoding\n",
919+
"Content-Transfer-Encoding: 8bit\n";
920+
}
921+
} elsif (/^MIME-Version:/i) {
922+
$need_8bit_cte = 0;
923+
} elsif (/^Subject:\s*(.+)\s*$/i) {
924+
$initial_subject = $1;
925+
my $subject = $initial_subject;
926+
$_ = "Subject: " .
927+
quote_subject($subject, $compose_encoding) .
928+
"\n";
929+
} elsif (/^In-Reply-To:\s*(.+)\s*$/i) {
930+
$initial_in_reply_to = $1;
931+
next;
932+
} elsif (/^Reply-To:\s*(.+)\s*$/i) {
933+
$reply_to = $1;
934+
} elsif (/^From:\s*(.+)\s*$/i) {
935+
$sender = $1;
936+
next;
937+
} elsif (/^To:\s*(.+)\s*$/i) {
938+
@initial_to = parse_address_line($1);
939+
next;
940+
} elsif (/^Cc:\s*(.+)\s*$/i) {
941+
@initial_cc = parse_address_line($1);
942+
next;
943+
} elsif (/^Bcc:/i) {
944+
@initial_bcc = parse_address_line($1);
945+
next;
904946
}
947+
print $c2 $_;
905948
}
906949
close $c;
950+
close $c2;
907951
908-
open my $c2, ">", $compose_filename . ".final"
909-
or die sprintf(__("Failed to open %s.final: %s"), $compose_filename, $!);
910-
911-
912-
if ($parsed_email{'From'}) {
913-
$sender = delete($parsed_email{'From'});
914-
}
915-
if ($parsed_email{'In-Reply-To'}) {
916-
$initial_in_reply_to = delete($parsed_email{'In-Reply-To'});
917-
}
918-
if ($parsed_email{'Reply-To'}) {
919-
$reply_to = delete($parsed_email{'Reply-To'});
920-
}
921-
if ($parsed_email{'Subject'}) {
922-
$initial_subject = delete($parsed_email{'Subject'});
923-
print $c2 "Subject: " .
924-
quote_subject($initial_subject, $compose_encoding) .
925-
"\n";
926-
}
927-
928-
if ($parsed_email{'MIME-Version'}) {
929-
print $c2 "MIME-Version: $parsed_email{'MIME-Version'}\n",
930-
"Content-Type: $parsed_email{'Content-Type'};\n",
931-
"Content-Transfer-Encoding: $parsed_email{'Content-Transfer-Encoding'}\n";
932-
delete($parsed_email{'MIME-Version'});
933-
delete($parsed_email{'Content-Type'});
934-
delete($parsed_email{'Content-Transfer-Encoding'});
935-
} elsif (file_has_nonascii($compose_filename)) {
936-
my $content_type = (delete($parsed_email{'Content-Type'}) or
937-
"text/plain; charset=$compose_encoding");
938-
print $c2 "MIME-Version: 1.0\n",
939-
"Content-Type: $content_type\n",
940-
"Content-Transfer-Encoding: 8bit\n";
941-
}
942-
# Preserve unknown headers
943-
foreach my $key (keys %parsed_email) {
944-
next if $key eq 'body';
945-
print $c2 "$key: $parsed_email{$key}";
946-
}
947-
948-
if ($parsed_email{'body'}) {
949-
print $c2 "\n$parsed_email{'body'}\n";
950-
delete($parsed_email{'body'});
951-
} else {
952+
if ($summary_empty) {
952953
print __("Summary email is empty, skipping it\n");
953954
$compose = -1;
954955
}
955-
956-
close $c2;
957-
958956
} elsif ($annotate) {
959957
do_edit(@files);
960958
}
@@ -1009,32 +1007,6 @@ sub ask {
10091007
return;
10101008
}
10111009
1012-
sub parse_header_line {
1013-
my $lines = shift;
1014-
my $parsed_line = shift;
1015-
my $addr_pat = join "|", qw(To Cc Bcc);
1016-
1017-
foreach (split(/\n/, $lines)) {
1018-
if (/^($addr_pat):\s*(.+)$/i) {
1019-
$parsed_line->{$1} = [ parse_address_line($2) ];
1020-
} elsif (/^([^:]*):\s*(.+)\s*$/i) {
1021-
$parsed_line->{$1} = $2;
1022-
}
1023-
}
1024-
}
1025-
1026-
sub filter_body {
1027-
my $c = shift;
1028-
my $body = "";
1029-
while (my $body_line = <$c>) {
1030-
if ($body_line !~ m/^GIT:/) {
1031-
$body .= $body_line;
1032-
}
1033-
}
1034-
return $body;
1035-
}
1036-
1037-
10381010
my %broken_encoding;
10391011
10401012
sub file_declares_8bit_cte {

t/t9001-send-email.sh

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2505,4 +2505,45 @@ test_expect_success $PREREQ 'test forbidSendmailVariables behavior override' '
25052505
HEAD^
25062506
'
25072507

2508+
test_expect_success $PREREQ '--compose handles lowercase headers' '
2509+
write_script fake-editor <<-\EOF &&
2510+
sed "s/^From:.*/from: [email protected]/i" "$1" >"$1.tmp" &&
2511+
mv "$1.tmp" "$1"
2512+
EOF
2513+
clean_fake_sendmail &&
2514+
git send-email \
2515+
--compose \
2516+
--from="Example <[email protected]>" \
2517+
2518+
--smtp-server="$(pwd)/fake.sendmail" \
2519+
HEAD^ &&
2520+
grep "From: [email protected]" msgtxt1
2521+
'
2522+
2523+
test_expect_success $PREREQ '--compose handles to headers' '
2524+
write_script fake-editor <<-\EOF &&
2525+
sed "s/^To: .*/&, [email protected]/" <"$1" >"$1.tmp" &&
2526+
echo this is the body >>"$1.tmp" &&
2527+
mv "$1.tmp" "$1"
2528+
EOF
2529+
clean_fake_sendmail &&
2530+
GIT_SEND_EMAIL_NOTTY=1 \
2531+
git send-email \
2532+
--compose \
2533+
--from="Example <[email protected]>" \
2534+
2535+
--smtp-server="$(pwd)/fake.sendmail" \
2536+
HEAD^ &&
2537+
# Check both that the cover letter used our modified "to" line,
2538+
# but also that it was picked up for the patch.
2539+
q_to_tab >expect <<-\EOF &&
2540+
2541+
2542+
EOF
2543+
grep -A1 "^To:" msgtxt1 >msgtxt1.to &&
2544+
test_cmp expect msgtxt1.to &&
2545+
grep -A1 "^To:" msgtxt2 >msgtxt2.to &&
2546+
test_cmp expect msgtxt2.to
2547+
'
2548+
25082549
test_done

0 commit comments

Comments
 (0)