From f06a6a493a14ae632cdd3d04af04301769f4ef71 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 16 Apr 2007 16:51:47 -0700 Subject: send-email: do not leave an empty CC: line if no cc is present. Signed-off-by: Junio C Hamano --- git-send-email.perl | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 1278fcba4..d6b15480d 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -446,9 +446,12 @@ sub send_message my ($name, $addr) = ($from =~ /^(.*?)(\s+<.*)/); $from = "\"$name\"$addr"; } + my $ccline = ""; + if ($cc ne '') { + $ccline = "\nCc: $cc"; + } my $header = "From: $from -To: $to -Cc: $cc +To: $to${ccline} Subject: $subject Date: $date Message-Id: $message_id -- cgit v1.2.1 From 238cc6352eabe3f87f13093bc4015162bf424509 Mon Sep 17 00:00:00 2001 From: "Robin H. Johnson" Date: Wed, 25 Apr 2007 19:37:15 -0700 Subject: Document --dry-run parameter to send-email. Looks like --dry-run was added to the code, but never to the --help output. Signed-off-by: Robin H. Johnson Signed-off-by: Junio C Hamano --- git-send-email.perl | 2 ++ 1 file changed, 2 insertions(+) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 1278fcba4..5e38a97cb 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -77,6 +77,8 @@ Options: --quiet Make git-send-email less verbose. One line per email should be all that is output. + --dry-run Do everything except actually send the emails. + EOT exit(1); } -- cgit v1.2.1 From 71c7da94218fbe36e64a326825ff30ef811b2a88 Mon Sep 17 00:00:00 2001 From: "Robin H. Johnson" Date: Wed, 25 Apr 2007 19:37:16 -0700 Subject: Prefix Dry- to the message status to denote dry-runs. While doing testing, it's useful to see that a dry run was actually done, instead of a real one. Signed-off-by: Robin H. Johnson Signed-off-by: Junio C Hamano --- git-send-email.perl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 5e38a97cb..50d45fe00 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -488,9 +488,9 @@ X-Mailer: git-send-email $gitversion $smtp->ok or die "Failed to send $subject\n".$smtp->message; } if ($quiet) { - printf "Sent %s\n", $subject; + printf (($dry_run ? "Dry-" : "")."Sent %s\n", $subject); } else { - print "OK. Log says:\nDate: $date\n"; + print (($dry_run ? "Dry-" : "")."OK. Log says:\nDate: $date\n"); if ($smtp) { print "Server: $smtp_server\n"; } else { -- cgit v1.2.1 From 8e3d436b0b5148bac11259bac55621e285eeb6c4 Mon Sep 17 00:00:00 2001 From: "Robin H. Johnson" Date: Wed, 25 Apr 2007 19:37:17 -0700 Subject: Debugging cleanup improvements The debug output is much more helpful if it has the parameters that were used. Pull the sendmail parameters into a seperate array for that, and also include similar data during the Net::SMTP case. Signed-off-by: Robin H. Johnson Signed-off-by: Junio C Hamano --- git-send-email.perl | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 50d45fe00..36795c8bd 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -465,15 +465,15 @@ X-Mailer: git-send-email $gitversion $header .= join("\n", @xh) . "\n"; } + my @sendmail_parameters = ('-i', map { extract_valid_address($_) } @recipients); + if ($dry_run) { # We don't want to send the email. } elsif ($smtp_server =~ m#^/#) { my $pid = open my $sm, '|-'; defined $pid or die $!; if (!$pid) { - exec($smtp_server,'-i', - map { extract_valid_address($_) } - @recipients) or die $!; + exec($smtp_server, @sendmail_parameters) or die $!; } print $sm "$header\n$message"; close $sm or die $?; @@ -493,8 +493,10 @@ X-Mailer: git-send-email $gitversion print (($dry_run ? "Dry-" : "")."OK. Log says:\nDate: $date\n"); if ($smtp) { print "Server: $smtp_server\n"; + print "MAIL FROM: $from\n"; + print "RCPT TO: ".join(',',@recipients)."\n"; } else { - print "Sendmail: $smtp_server\n"; + print "Sendmail: $smtp_server ".join(' ',@sendmail_parameters)."\n"; } print "From: $from\nSubject: $subject\nCc: $cc\nTo: $to\n\n"; if ($smtp) { -- cgit v1.2.1 From af068d274245be9aedc58e6835c2e43329639974 Mon Sep 17 00:00:00 2001 From: "Robin H. Johnson" Date: Wed, 25 Apr 2007 19:37:18 -0700 Subject: Change the scope of the $cc variable as it is not needed outside of send_message. $cc is only used inside the send_message scope, so lets clean it out of the global scope. Signed-off-by: Robin H. Johnson Signed-off-by: Junio C Hamano --- git-send-email.perl | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 36795c8bd..ad83009e2 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -379,7 +379,7 @@ if (@files) { } # Variables we set as part of the loop over files -our ($message_id, $cc, %mail, $subject, $reply_to, $references, $message); +our ($message_id, %mail, $subject, $reply_to, $references, $message); sub extract_valid_address { my $address = shift; @@ -420,7 +420,6 @@ sub make_message_id -$cc = ""; $time = time - scalar $#files; sub unquote_rfc2047 { @@ -443,7 +442,8 @@ sub send_message $gitversion = Git::version(); } - my ($author_name) = ($from =~ /^(.*?)\s+ Date: Wed, 25 Apr 2007 19:37:19 -0700 Subject: Perform correct quoting of recipient names. Always perform quoting of the recipient names if they contain periods, previously only the author's address was treated this way. This stops sendmail binaries from exploding the name into bad addresses. Signed-off-by: Robin H. Johnson Signed-off-by: Junio C Hamano --- git-send-email.perl | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index ad83009e2..e4fe8965b 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -431,9 +431,22 @@ sub unquote_rfc2047 { return "$_"; } +# If an address contains a . in the name portion, the name must be quoted. +sub sanitize_address_rfc822 +{ + my ($recipient) = @_; + my ($recipient_name) = ($recipient =~ /^(.*?)\s+ Date: Wed, 25 Apr 2007 19:37:20 -0700 Subject: Validate @recipients before using it for sendmail and Net::SMTP. Ensure that @recipients is only raw addresses when it is handed to the sendmail binary OR Net::SMTP, otherwise BCC cases might get an extra <, or wierd stuff might be passed to the exec. Signed-off-by: Robin H. Johnson Signed-off-by: Junio C Hamano --- git-send-email.perl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index e4fe8965b..b60229290 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -449,6 +449,7 @@ sub send_message @cc = (map { sanitize_address_rfc822($_) } @cc); my $to = join (",\n\t", @recipients); @recipients = unique_email_list(@recipients,@cc,@bcclist); + @recipients = (map { extract_valid_address($_) } @recipients); my $date = format_2822_time($time++); my $gitversion = '@@GIT_VERSION@@'; if ($gitversion =~ m/..GIT_VERSION../) { @@ -474,7 +475,7 @@ X-Mailer: git-send-email $gitversion $header .= join("\n", @xh) . "\n"; } - my @sendmail_parameters = ('-i', map { extract_valid_address($_) } @recipients); + my @sendmail_parameters = ('-i', @recipients); if ($dry_run) { # We don't want to send the email. -- cgit v1.2.1 From 2b69bfc23d89d2ec5507bc6906b533e8429b313d Mon Sep 17 00:00:00 2001 From: "Robin H. Johnson" Date: Wed, 25 Apr 2007 19:37:21 -0700 Subject: Ensure clean addresses are always used with Net::SMTP Always pass in clean addresses to Net::SMTP for the MAIL FROM, and use them on the SMTP non-quiet output as well. Signed-off-by: Robin H. Johnson Signed-off-by: Junio C Hamano --- git-send-email.perl | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index b60229290..35c4722a1 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -476,6 +476,7 @@ X-Mailer: git-send-email $gitversion } my @sendmail_parameters = ('-i', @recipients); + my $raw_from = extract_valid_address($from); if ($dry_run) { # We don't want to send the email. @@ -490,7 +491,7 @@ X-Mailer: git-send-email $gitversion } else { require Net::SMTP; $smtp ||= Net::SMTP->new( $smtp_server ); - $smtp->mail( $from ) or die $smtp->message; + $smtp->mail( $raw_from ) or die $smtp->message; $smtp->to( @recipients ) or die $smtp->message; $smtp->data or die $smtp->message; $smtp->datasend("$header\n$message") or die $smtp->message; @@ -501,10 +502,10 @@ X-Mailer: git-send-email $gitversion printf (($dry_run ? "Dry-" : "")."Sent %s\n", $subject); } else { print (($dry_run ? "Dry-" : "")."OK. Log says:\nDate: $date\n"); - if ($smtp) { + if ($smtp_server !~ m#^/#) { print "Server: $smtp_server\n"; - print "MAIL FROM: $from\n"; - print "RCPT TO: ".join(',',@recipients)."\n"; + print "MAIL FROM:<$raw_from>\n"; + print "RCPT TO:".join(',',(map { "<$_>" } @recipients))."\n"; } else { print "Sendmail: $smtp_server ".join(' ',@sendmail_parameters)."\n"; } -- cgit v1.2.1 From f073a592d6400b3aa653ce02943535bf917078b5 Mon Sep 17 00:00:00 2001 From: "Robin H. Johnson" Date: Wed, 25 Apr 2007 19:37:22 -0700 Subject: Allow users to optionally specify their envelope sender. If your normal user is not the same user you are subscribed to a list with, then the default envelope sender used will cause your messages to bounce or silently vanish into the ether. This patch provides an optional parameter to set the envelope sender. To use it with the sendmail binary, you must have privileges to use the -f parameter! Signed-off-by: Robin H. Johnson Signed-off-by: Junio C Hamano --- git-send-email.perl | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 35c4722a1..56c2936f2 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -79,6 +79,8 @@ Options: --dry-run Do everything except actually send the emails. + --envelope-sender Specify the envelope sender used to send the emails. + EOT exit(1); } @@ -139,6 +141,7 @@ my (@to,@cc,@initial_cc,@bcclist,@xh, my ($chain_reply_to, $quiet, $suppress_from, $no_signed_off_cc, $dry_run) = (1, 0, 0, 0, 0); my $smtp_server; +my $envelope_sender; # Example reply to: #$initial_reply_to = ''; #<20050203173208.GA23964@foobar.com>'; @@ -177,6 +180,7 @@ my $rc = GetOptions("from=s" => \$from, "suppress-from" => \$suppress_from, "no-signed-off-cc|no-signed-off-by-cc" => \$no_signed_off_cc, "dry-run" => \$dry_run, + "envelope-sender=s" => \$envelope_sender, ); unless ($rc) { @@ -476,7 +480,11 @@ X-Mailer: git-send-email $gitversion } my @sendmail_parameters = ('-i', @recipients); - my $raw_from = extract_valid_address($from); + my $raw_from = $from; + $raw_from = $envelope_sender if (defined $envelope_sender); + $raw_from = extract_valid_address($raw_from); + unshift (@sendmail_parameters, + '-f', $raw_from) if(defined $envelope_sender); if ($dry_run) { # We don't want to send the email. -- cgit v1.2.1 From bf7af1167411cbdd5ade7587a64b18d1b7b2ea69 Mon Sep 17 00:00:00 2001 From: "Robin H. Johnson" Date: Wed, 25 Apr 2007 21:53:22 -0700 Subject: Sanitize @to recipients. We need to sanitize @to as well to ensure that names are properly quoted. Signed-off-by: Robin H. Johnson Signed-off-by: Junio C Hamano --- git-send-email.perl | 1 + 1 file changed, 1 insertion(+) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 56c2936f2..12ced2888 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -274,6 +274,7 @@ sub expand_aliases { } @to = expand_aliases(@to); +@to = (map { sanitize_address_rfc822($_) } @to); @initial_cc = expand_aliases(@initial_cc); @bcclist = expand_aliases(@bcclist); -- cgit v1.2.1 From 35c49eeae7e71e8554f27958a16405397c69b552 Mon Sep 17 00:00:00 2001 From: Petr Baudis Date: Wed, 9 May 2007 12:49:41 +0200 Subject: Git.pm: config_boolean() -> config_bool() This patch renames config_boolean() to config_bool() for consistency with the commandline interface and because it is shorter but still obvious. ;-) It also changes the return value from some obscure string to real Perl boolean, allowing for clean user code. Signed-off-by: Petr Baudis --- git-send-email.perl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index a6e3e0261..404095f25 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -154,8 +154,8 @@ if ($@) { $term = new FakeTerm "$@: going non-interactive"; } -my $def_chain = $repo->config_boolean('sendemail.chainreplyto'); -if ($def_chain and $def_chain eq 'false') { +my $def_chain = $repo->config_bool('sendemail.chainreplyto'); +if (defined $def_chain and not $def_chain) { $chain_reply_to = 0; } -- cgit v1.2.1 From 504ceab6d24bc19ed5a04b5978c8899fa58dffe1 Mon Sep 17 00:00:00 2001 From: Michael Hendricks Date: Wed, 16 May 2007 23:15:16 -0600 Subject: git-send-email: allow leading white space on mutt aliases mutt version 1.5.14 (perhaps earlier versions too) permits alias files to have white space before the 'alias' keyword. Signed-off-by: Michael Hendricks Signed-off-by: Junio C Hamano --- git-send-email.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 12ced2888..e60d8777f 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -212,7 +212,7 @@ my $aliasfiletype = $repo->config('sendemail.aliasfiletype'); my %parse_alias = ( # multiline formats can be supported in the future mutt => sub { my $fh = shift; while (<$fh>) { - if (/^alias\s+(\S+)\s+(.*)$/) { + if (/^\s*alias\s+(\S+)\s+(.*)$/) { my ($alias, $addr) = ($1, $2); $addr =~ s/#.*$//; # mutt allows # comments # commas delimit multiple addresses -- cgit v1.2.1 From 2cf69cf6edbaa15ed47f9c73c0eb60ce7983ba6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Mon, 11 Jun 2007 13:04:40 -0400 Subject: Unquote From line from patch before comparing with given from address. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes --suppress-from actually work when you're unfortunate enough to have non-ASCII in your name. Also, if there's a match use the optionally RFC2047 quoted version from the email. Signed-off-by: Kristian Høgsberg Signed-off-by: Junio C Hamano --- git-send-email.perl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index eb876f88d..7c0c90bd2 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -561,7 +561,8 @@ foreach my $t (@files) { $subject = $1; } elsif (/^(Cc|From):\s+(.*)$/) { - if ($2 eq $from) { + if (unquote_rfc2047($2) eq $from) { + $from = $2; next if ($suppress_from); } elsif ($1 eq 'From') { -- cgit v1.2.1 From aeb59328453cd4f438345ea79ff04c96bccbbbb8 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 20 Jun 2007 13:47:34 -0700 Subject: git-send-email: Do not make @-less message ID When the original $from address fails to yield a valid-looking e-mail address, we created a bogus looking message ID, formatted like this: Message-Id: <11823357623688-git-send-email-> This commit fixes it by moving call to make_message_id() to where it matters, namely, before the $message_id is needed to be placed in the generated e-mail header; this has an important side effect of making it clear that $from is already available. Also throw in Sys::Hostname::hostname() just for fun, although I suspect that the code would never trigger due to the modified call sequence that makes sure $from is always available. This is based on a suggestion by Michael Hendricks. Signed-off-by: Junio C Hamano --- git-send-email.perl | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 7c0c90bd2..9f7555167 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -412,13 +412,21 @@ sub extract_valid_address { # 1 second since the last time we were called. # We'll setup a template for the message id, using the "from" address: -my $message_id_from = extract_valid_address($from); -my $message_id_template = "<%s-git-send-email-$message_id_from>"; sub make_message_id { my $date = time; my $pseudo_rand = int (rand(4200)); + my $du_part; + for ($from, $committer, $author) { + $du_part = extract_valid_address($_); + last if ($du_part ne ''); + } + if ($du_part eq '') { + use Sys::Hostname qw(); + $du_part = 'user@' . Sys::Hostname::hostname(); + } + my $message_id_template = "<%s-git-send-email-$du_part>"; $message_id = sprintf $message_id_template, "$date$pseudo_rand"; #print "new message id = $message_id\n"; # Was useful for debugging } @@ -467,6 +475,8 @@ sub send_message $ccline = "\nCc: $cc"; } $from = sanitize_address_rfc822($from); + make_message_id(); + my $header = "From: $from To: $to${ccline} Subject: $subject @@ -533,7 +543,6 @@ X-Mailer: git-send-email $gitversion $reply_to = $initial_reply_to; $references = $initial_reply_to || ''; -make_message_id(); $subject = $initial_subject; foreach my $t (@files) { @@ -627,7 +636,6 @@ foreach my $t (@files) { $references = "$message_id"; } } - make_message_id(); } if ($compose) { -- cgit v1.2.1 From e46f7a0e1c641cd80affd80516677f1e370cd72c Mon Sep 17 00:00:00 2001 From: Adam Roben Date: Tue, 26 Jun 2007 15:48:30 -0700 Subject: git-send-email: Add --threaded option The --threaded option controls whether the In-Reply-To header will be set on any emails sent. The current behavior is to always set this header, so this option is most useful in its negated form, --no-threaded. This behavior can also be controlled through the 'sendemail.threaded' config setting. Signed-off-by: Adam Roben Signed-off-by: Junio C Hamano --- git-send-email.perl | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 9f7555167..b8b8fe7ee 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -74,6 +74,9 @@ Options: --suppress-from Suppress sending emails to yourself if your address appears in a From: line. + --threaded Specify that the "In-Reply-To:" header should be set on all + emails. Defaults to on. + --quiet Make git-send-email less verbose. One line per email should be all that is output. @@ -138,8 +141,8 @@ my (@to,@cc,@initial_cc,@bcclist,@xh, $initial_reply_to,$initial_subject,@files,$from,$compose,$time); # Behavior modification variables -my ($chain_reply_to, $quiet, $suppress_from, $no_signed_off_cc, - $dry_run) = (1, 0, 0, 0, 0); +my ($threaded, $chain_reply_to, $quiet, $suppress_from, $no_signed_off_cc, + $dry_run) = (1, 1, 0, 0, 0, 0); my $smtp_server; my $envelope_sender; @@ -154,9 +157,16 @@ if ($@) { $term = new FakeTerm "$@: going non-interactive"; } -my $def_chain = $repo->config_bool('sendemail.chainreplyto'); -if (defined $def_chain and not $def_chain) { - $chain_reply_to = 0; +my %config_settings = ( + "threaded" => \$threaded, + "chainreplyto" => \$chain_reply_to, +); + +foreach my $setting (keys %config_settings) { + my $default = $repo->config_bool("sendemail.$setting"); + if (defined $default) { + $config_settings{$setting} = $default ? 1 : 0; + } } @bcclist = $repo->config('sendemail.bcc'); @@ -181,6 +191,7 @@ my $rc = GetOptions("from=s" => \$from, "no-signed-off-cc|no-signed-off-by-cc" => \$no_signed_off_cc, "dry-run" => \$dry_run, "envelope-sender=s" => \$envelope_sender, + "threaded!" => \$threaded, ); unless ($rc) { @@ -287,7 +298,7 @@ if (!defined $initial_subject && $compose) { $prompting++; } -if (!defined $initial_reply_to && $prompting) { +if ($threaded && !defined $initial_reply_to && $prompting) { do { $_= $term->readline("Message-ID to be used as In-Reply-To for the first email? ", $initial_reply_to); @@ -484,7 +495,7 @@ Date: $date Message-Id: $message_id X-Mailer: git-send-email $gitversion "; - if ($reply_to) { + if ($threaded && $reply_to) { $header .= "In-Reply-To: $reply_to\n"; $header .= "References: $references\n"; -- cgit v1.2.1 From 5483c71d7ac06b4f16c646886abbb2d0f88a2855 Mon Sep 17 00:00:00 2001 From: Adam Roben Date: Wed, 27 Jun 2007 20:59:37 -0700 Subject: git-send-email: make options easier to configure. This change makes git-send-email's behavior easier to modify by adding config equivalents for two more of git-send-email's flags. The mapping of flag to config setting is: --[no-]supress-from => sendemail.suppressfrom --[no-]signed-off-cc => sendemail.signedoffcc It renames the --threaded option to --thread/--no-thread; the config variable is also called sendemail.thread. Signed-off-by: Adam Roben Signed-off-by: Junio C Hamano --- git-send-email.perl | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index b8b8fe7ee..87f59fa31 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -64,17 +64,16 @@ Options: email sent, rather than to the first email sent. Defaults to on. - --no-signed-off-cc Suppress the automatic addition of email addresses - that appear in Signed-off-by: or Cc: lines to the cc: - list. Note: Using this option is not recommended. + --signed-off-cc Automatically add email addresses that appear in + Signed-off-by: or Cc: lines to the cc: list. Defaults to on. --smtp-server If set, specifies the outgoing SMTP server to use. Defaults to localhost. --suppress-from Suppress sending emails to yourself if your address - appears in a From: line. + appears in a From: line. Defaults to off. - --threaded Specify that the "In-Reply-To:" header should be set on all + --thread Specify that the "In-Reply-To:" header should be set on all emails. Defaults to on. --quiet Make git-send-email less verbose. One line per email @@ -140,9 +139,6 @@ my $compose_filename = ".msg.$$"; my (@to,@cc,@initial_cc,@bcclist,@xh, $initial_reply_to,$initial_subject,@files,$from,$compose,$time); -# Behavior modification variables -my ($threaded, $chain_reply_to, $quiet, $suppress_from, $no_signed_off_cc, - $dry_run) = (1, 1, 0, 0, 0, 0); my $smtp_server; my $envelope_sender; @@ -157,16 +153,22 @@ if ($@) { $term = new FakeTerm "$@: going non-interactive"; } +# Behavior modification variables +my ($quiet, $dry_run) = (0, 0); + +# Variables with corresponding config settings +my ($thread, $chain_reply_to, $suppress_from, $signed_off_cc); + my %config_settings = ( - "threaded" => \$threaded, - "chainreplyto" => \$chain_reply_to, + "thread" => [\$thread, 1], + "chainreplyto" => [\$chain_reply_to, 1], + "suppressfrom" => [\$suppress_from, 0], + "signedoffcc" => [\$signed_off_cc, 1], ); foreach my $setting (keys %config_settings) { - my $default = $repo->config_bool("sendemail.$setting"); - if (defined $default) { - $config_settings{$setting} = $default ? 1 : 0; - } + my $config = $repo->config_bool("sendemail.$setting"); + ${$config_settings{$setting}->[0]} = (defined $config) ? $config : $config_settings{$setting}->[1]; } @bcclist = $repo->config('sendemail.bcc'); @@ -187,11 +189,11 @@ my $rc = GetOptions("from=s" => \$from, "smtp-server=s" => \$smtp_server, "compose" => \$compose, "quiet" => \$quiet, - "suppress-from" => \$suppress_from, - "no-signed-off-cc|no-signed-off-by-cc" => \$no_signed_off_cc, + "suppress-from!" => \$suppress_from, + "signed-off-cc|signed-off-by-cc!" => \$signed_off_cc, "dry-run" => \$dry_run, "envelope-sender=s" => \$envelope_sender, - "threaded!" => \$threaded, + "thread!" => \$thread, ); unless ($rc) { @@ -298,7 +300,7 @@ if (!defined $initial_subject && $compose) { $prompting++; } -if ($threaded && !defined $initial_reply_to && $prompting) { +if ($thread && !defined $initial_reply_to && $prompting) { do { $_= $term->readline("Message-ID to be used as In-Reply-To for the first email? ", $initial_reply_to); @@ -495,7 +497,7 @@ Date: $date Message-Id: $message_id X-Mailer: git-send-email $gitversion "; - if ($threaded && $reply_to) { + if ($thread && $reply_to) { $header .= "In-Reply-To: $reply_to\n"; $header .= "References: $references\n"; @@ -620,7 +622,7 @@ foreach my $t (@files) { } } else { $message .= $_; - if (/^(Signed-off-by|Cc): (.*)$/i && !$no_signed_off_cc) { + if (/^(Signed-off-by|Cc): (.*)$/i && $signed_off_cc) { my $c = $2; chomp $c; push @cc, $c; -- cgit v1.2.1 From ae740a588d581b34d2794a0993ae45cdca6d5ece Mon Sep 17 00:00:00 2001 From: Michael Hendricks Date: Wed, 4 Jul 2007 19:11:36 -0600 Subject: git-send-email: allow an email alias for --from Signed-off-by: Michael Hendricks Signed-off-by: Junio C Hamano --- git-send-email.perl | 2 ++ 1 file changed, 2 insertions(+) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 87f59fa31..89f7c36ee 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -254,6 +254,8 @@ if (@alias_files and $aliasfiletype and defined $parse_alias{$aliasfiletype}) { } } +($from) = expand_aliases($from) if defined $from; + my $prompting = 0; if (!defined $from) { $from = $author || $committer; -- cgit v1.2.1 From b06c6bc831cbb9e9eb82fd3ffd5a2b674cd940d0 Mon Sep 17 00:00:00 2001 From: Greg KH Date: Thu, 12 Jul 2007 21:17:49 -0700 Subject: make git-send-email.perl handle email addresses with no names when Email::Valid is present When using git-send-email.perl on a changeset that has: Cc: in the body of the description, and the Email::Valid perl module is installed on the system, the email address will be deemed "invalid" for some reason (Email::Valid isn't smart enough to handle this?) and complain and not send the address the email. Signed-off-by: Greg Kroah-Hartman Signed-off-by: Junio C Hamano --- git-send-email.perl | 1 + 1 file changed, 1 insertion(+) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 89f7c36ee..a847d5ed5 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -410,6 +410,7 @@ sub extract_valid_address { return $address if ($address =~ /^($local_part_regexp)$/); if ($have_email_valid) { + $address =~ s/^<(.*)>$/$1/; return scalar Email::Valid->address($address); } else { # less robust/correct than the monster regexp in Email::Valid, -- cgit v1.2.1 From 689b4d552b8108d2c92c63258990ecd2bc791739 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Fri, 13 Jul 2007 08:54:06 -0700 Subject: send-email: discard blank around address in extract_valid_address as well. Signed-off-by: Junio C Hamano --- git-send-email.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index a847d5ed5..7552caca4 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -410,7 +410,7 @@ sub extract_valid_address { return $address if ($address =~ /^($local_part_regexp)$/); if ($have_email_valid) { - $address =~ s/^<(.*)>$/$1/; + $address =~ s/^\s*<(.*)>\s*$/$1/; return scalar Email::Valid->address($address); } else { # less robust/correct than the monster regexp in Email::Valid, -- cgit v1.2.1 From ef0c2abf3e5061f891b7f07953ef3b0695f52c89 Mon Sep 17 00:00:00 2001 From: Adam Roben Date: Thu, 19 Jul 2007 22:09:35 -0700 Subject: Add GIT_EDITOR environment and core.editor configuration variables These variables let you specify an editor that will be launched in preference to the EDITOR and VISUAL environment variables. The order of preference is GIT_EDITOR, core.editor, EDITOR, VISUAL. [jc: added a test and config variable documentation] Signed-off-by: Adam Roben Signed-off-by: Junio C Hamano --- git-send-email.perl | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 7552caca4..a09b1c965 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -49,8 +49,8 @@ Options: --bcc Specify a list of email addresses that should be Bcc: on all the emails. - --compose Use \$EDITOR to edit an introductory message for the - patch series. + --compose Use \$GIT_EDITOR, core.editor, \$EDITOR, or \$VISUAL to edit + an introductory message for the patch series. --subject Specify the initial "Subject:" line. Only necessary if --compose is also set. If --compose @@ -341,8 +341,7 @@ GIT: for the patch you are writing. EOT close(C); - my $editor = $ENV{EDITOR}; - $editor = 'vi' unless defined $editor; + my $editor = $ENV{GIT_EDITOR} || $repo->config("core.editor") || $ENV{VISUAL} || $ENV{EDITOR} || "vi"; system($editor, $compose_filename); open(C2,">",$compose_filename . ".final") -- cgit v1.2.1 From 2d8ae400d134c326f3ab0ec15ae522fb74cd0b1d Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Tue, 24 Jul 2007 09:50:38 -0500 Subject: send-email: Update regex parsing for pine aliases The pine address book format is tab seperated and the first field is the nickname/alias and the third field is the email address as per: http://www.washington.edu/pine/tech-notes/low-level.html Signed-off-by: Kumar Gala Signed-off-by: Junio C Hamano --- git-send-email.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index a09b1c965..f43f92f95 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -237,7 +237,7 @@ my %parse_alias = ( $aliases{$1} = [ split(/\s+/, $2) ]; }}}, pine => sub { my $fh = shift; while (<$fh>) { - if (/^(\S+)\s+(.*)$/) { + if (/^(\S+)\t.*\t(.*)$/) { $aliases{$1} = [ split(/\s*,\s*/, $2) ]; }}}, gnus => sub { my $fh = shift; while (<$fh>) { -- cgit v1.2.1 From 5b56aaa29e9d7c0371b6d47bd8a6b12a0c4292dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=1B=2CAv=1B=28Bnig?= Date: Mon, 6 Aug 2007 22:34:50 +0200 Subject: send-email: teach sanitize_address to do rfc2047 quoting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without this patch I'm not able to properly send emails as I have a non-ascii character in my name. I removed the _rfc822 suffix from the function name as it now does more than rfc822 quoting. I dug through rfc822 to do the double quoting right. Only if that is not possible rfc2047 quoting is applied. Signed-off-by: Uwe Kleine-K,Av(Bnig Cc: Jakub Narebski Signed-off-by: Junio C Hamano --- git-send-email.perl | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index f43f92f95..39e433b76 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -289,7 +289,7 @@ sub expand_aliases { } @to = expand_aliases(@to); -@to = (map { sanitize_address_rfc822($_) } @to); +@to = (map { sanitize_address($_) } @to); @initial_cc = expand_aliases(@initial_cc); @bcclist = expand_aliases(@bcclist); @@ -459,22 +459,41 @@ sub unquote_rfc2047 { return "$_"; } -# If an address contains a . in the name portion, the name must be quoted. -sub sanitize_address_rfc822 +# use the simplest quoting being able to handle the recipient +sub sanitize_address { my ($recipient) = @_; - my ($recipient_name) = ($recipient =~ /^(.*?)\s+@,;:\\".\000-\037\177]/) { + $recipient_name =~ s/(["\\\r])/\\$1/; + $recipient_name = "\"$recipient_name\""; + } + + return "$recipient_name $recipient_addr"; + } sub send_message { my @recipients = unique_email_list(@to); - @cc = (map { sanitize_address_rfc822($_) } @cc); + @cc = (map { sanitize_address($_) } @cc); my $to = join (",\n\t", @recipients); @recipients = unique_email_list(@recipients,@cc,@bcclist); @recipients = (map { extract_valid_address($_) } @recipients); @@ -489,7 +508,7 @@ sub send_message if ($cc ne '') { $ccline = "\nCc: $cc"; } - $from = sanitize_address_rfc822($from); + $from = sanitize_address($from); make_message_id(); my $header = "From: $from -- cgit v1.2.1 From 155197e6e770599a5ed7a33a33f2916032184dd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Thu, 9 Aug 2007 15:27:57 +0200 Subject: send-email: rfc822 forbids using without a non-empty "phrase" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Email::Valid does respect this considering such a mailbox specification invalid. b06c6bc831cbb9e9eb82fd3ffd5a2b674cd940d0 addressed the issue, but only if Email::Valid is available. Signed-off-by: Uwe Kleine-König Signed-off-by: Junio C Hamano --- git-send-email.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 39e433b76..a02ab9694 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -408,8 +408,8 @@ sub extract_valid_address { # check for a local address: return $address if ($address =~ /^($local_part_regexp)$/); + $address =~ s/^\s*<(.*)>\s*$/$1/; if ($have_email_valid) { - $address =~ s/^\s*<(.*)>\s*$/$1/; return scalar Email::Valid->address($address); } else { # less robust/correct than the monster regexp in Email::Valid, -- cgit v1.2.1 From 94638f89f5bcd1f92b86ebf988f7974167c3fd27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Thu, 9 Aug 2007 15:27:58 +0200 Subject: send-email: get all the quoting of realnames right MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - when sending several mails I got a slightly different behaviour for the first mail compared to the second to last one. The reason is that $from was assigned in line 608 and was not reset when beginning to handle the next mail. - Email::Valid can only handle properly quoted real names, so quote arguments to extract_valid_address. This patch cleans up variable naming to better differentiate between sender of the mail and it's author. Signed-off-by: Uwe Kleine-König Signed-off-by: Junio C Hamano --- git-send-email.perl | 50 ++++++++++++++++++++++++-------------------------- 1 file changed, 24 insertions(+), 26 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index a02ab9694..69559b289 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -137,7 +137,7 @@ my $compose_filename = ".msg.$$"; # Variables we fill in automatically, or via prompting: my (@to,@cc,@initial_cc,@bcclist,@xh, - $initial_reply_to,$initial_subject,@files,$from,$compose,$time); + $initial_reply_to,$initial_subject,@files,$author,$sender,$compose,$time); my $smtp_server; my $envelope_sender; @@ -179,7 +179,7 @@ if (!@bcclist or !$bcclist[0]) { # Begin by accumulating all the variables (defined above), that we will end up # needing, first, from the command line: -my $rc = GetOptions("from=s" => \$from, +my $rc = GetOptions("sender|from=s" => \$sender, "in-reply-to=s" => \$initial_reply_to, "subject=s" => \$initial_subject, "to=s" => \@to, @@ -216,8 +216,8 @@ foreach my $entry (@bcclist) { # Now, let's fill any that aren't set in with defaults: -my ($author) = $repo->ident_person('author'); -my ($committer) = $repo->ident_person('committer'); +my ($repoauthor) = $repo->ident_person('author'); +my ($repocommitter) = $repo->ident_person('committer'); my %aliases; my @alias_files = $repo->config('sendemail.aliasesfile'); @@ -254,17 +254,17 @@ if (@alias_files and $aliasfiletype and defined $parse_alias{$aliasfiletype}) { } } -($from) = expand_aliases($from) if defined $from; +($sender) = expand_aliases($sender) if defined $sender; my $prompting = 0; -if (!defined $from) { - $from = $author || $committer; +if (!defined $sender) { + $sender = $repoauthor || $repocommitter; do { - $_ = $term->readline("Who should the emails appear to be from? [$from] "); + $_ = $term->readline("Who should the emails appear to be from? [$sender] "); } while (!defined $_); - $from = $_ if ($_); - print "Emails will be sent from: ", $from, "\n"; + $sender = $_ if ($_); + print "Emails will be sent from: ", $sender, "\n"; $prompting++; } @@ -330,7 +330,7 @@ if ($compose) { # effort to have it be unique open(C,">",$compose_filename) or die "Failed to open for writing $compose_filename: $!"; - print C "From $from # This line is ignored.\n"; + print C "From $sender # This line is ignored.\n"; printf C "Subject: %s\n\n", $initial_subject; printf C <code, ' ', ($smtp->message =~ /\n([^\n]+\n)$/s), "\n"; @@ -582,7 +582,7 @@ $subject = $initial_subject; foreach my $t (@files) { open(F,"<",$t) or die "can't open file $t"; - my $author_not_sender = undef; + my $author = undef; @cc = @initial_cc; @xh = (); my $input_format = undef; @@ -604,12 +604,11 @@ foreach my $t (@files) { $subject = $1; } elsif (/^(Cc|From):\s+(.*)$/) { - if (unquote_rfc2047($2) eq $from) { - $from = $2; + if (unquote_rfc2047($2) eq $sender) { next if ($suppress_from); } elsif ($1 eq 'From') { - $author_not_sender = $2; + $author = unquote_rfc2047($2); } printf("(mbox) Adding cc: %s from line '%s'\n", $2, $_) unless $quiet; @@ -653,9 +652,8 @@ foreach my $t (@files) { } } close F; - if (defined $author_not_sender) { - $author_not_sender = unquote_rfc2047($author_not_sender); - $message = "From: $author_not_sender\n\n$message"; + if (defined $author) { + $message = "From: $author\n\n$message"; } -- cgit v1.2.1 From 324a8bd0cfb696458bc651d3713d7523fd0d7479 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 17 Aug 2007 18:51:12 -0700 Subject: git-send-email --cc-cmd This new option allows an arbitrary "cmd" to generate per patch file specific "Cc:"s. Signed-off-by: Joe Perches Signed-off-by: Junio C Hamano --- git-send-email.perl | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 69559b289..4767249e6 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -46,6 +46,9 @@ Options: --cc Specify an initial "Cc:" list for the entire series of emails. + --cc-cmd Specify a command to execute per file which adds + per file specific cc address entries + --bcc Specify a list of email addresses that should be Bcc: on all the emails. @@ -157,13 +160,14 @@ if ($@) { my ($quiet, $dry_run) = (0, 0); # Variables with corresponding config settings -my ($thread, $chain_reply_to, $suppress_from, $signed_off_cc); +my ($thread, $chain_reply_to, $suppress_from, $signed_off_cc, $cc_cmd); my %config_settings = ( "thread" => [\$thread, 1], "chainreplyto" => [\$chain_reply_to, 1], "suppressfrom" => [\$suppress_from, 0], "signedoffcc" => [\$signed_off_cc, 1], + "cccmd" => [\$cc_cmd, ""], ); foreach my $setting (keys %config_settings) { @@ -189,6 +193,7 @@ my $rc = GetOptions("sender|from=s" => \$sender, "smtp-server=s" => \$smtp_server, "compose" => \$compose, "quiet" => \$quiet, + "cc-cmd=s" => \$cc_cmd, "suppress-from!" => \$suppress_from, "signed-off-cc|signed-off-by-cc!" => \$signed_off_cc, "dry-run" => \$dry_run, @@ -652,11 +657,26 @@ foreach my $t (@files) { } } close F; + + if ($cc_cmd ne "") { + open(F, "$cc_cmd $t |") + or die "(cc-cmd) Could not execute '$cc_cmd'"; + while() { + my $c = $_; + $c =~ s/^\s*//g; + $c =~ s/\n$//g; + push @cc, $c; + printf("(cc-cmd) Adding cc: %s from: '%s'\n", + $c, $cc_cmd) unless $quiet; + } + close F + or die "(cc-cmd) failed to close pipe to '$cc_cmd'"; + } + if (defined $author) { $message = "From: $author\n\n$message"; } - send_message(); # set up for the next message -- cgit v1.2.1 From 412876dcbb7ca10e64ed8118bc1995788d397782 Mon Sep 17 00:00:00 2001 From: Sean Estabrooks Date: Fri, 17 Aug 2007 17:38:25 -0400 Subject: Reset terminal attributes when terminating git send-email If you break out of the prompts presented to you by git send-email your terminal can be left in an inconsistent state. Here we trap the interrupt signal and reset the terminal before exiting. Signed-off-by: Sean Estabrooks Signed-off-by: Junio C Hamano --- git-send-email.perl | 3 +++ 1 file changed, 3 insertions(+) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 69559b289..f1a885568 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -21,8 +21,11 @@ use warnings; use Term::ReadLine; use Getopt::Long; use Data::Dumper; +use Term::ANSIColor; use Git; +$SIG{INT} = sub { print color("reset"), "\n"; exit }; + package FakeTerm; sub new { my ($class, $reason) = @_; -- cgit v1.2.1 From 34cc60ce2b48f6037997543ddbab1ed9903df4a8 Mon Sep 17 00:00:00 2001 From: Douglas Stockwell Date: Mon, 3 Sep 2007 03:06:25 +0900 Subject: send-email: Add support for SSL and SMTP-AUTH Allows username and password to be given using --smtp-user and --smtp-pass. SSL use is flagged by --smtp-ssl. These are backed by corresponding defaults in the git configuration file. This implements Junio's 'mail identity' suggestion in a slightly more generalised manner. --identity=$identity, backed by sendemail.identity indicates that the configuration subsection [sendemail "$identity"] should take priority over the [sendemail] section for all configuration values. Signed-off-by: Douglas Stockwell Signed-off-by: Junio C Hamano --- git-send-email.perl | 101 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 75 insertions(+), 26 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index e0b7d1245..dd7560b18 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -73,9 +73,18 @@ Options: --signed-off-cc Automatically add email addresses that appear in Signed-off-by: or Cc: lines to the cc: list. Defaults to on. + --identity The configuration identity, a subsection to prioritise over + the default section. + --smtp-server If set, specifies the outgoing SMTP server to use. Defaults to localhost. + --smtp-user The username for SMTP-AUTH. + + --smtp-pass The password for SMTP-AUTH. + + --smtp-ssl If set, connects to the SMTP server using SSL. + --suppress-from Suppress sending emails to yourself if your address appears in a From: line. Defaults to off. @@ -145,7 +154,6 @@ my $compose_filename = ".msg.$$"; my (@to,@cc,@initial_cc,@bcclist,@xh, $initial_reply_to,$initial_subject,@files,$author,$sender,$compose,$time); -my $smtp_server; my $envelope_sender; # Example reply to: @@ -164,24 +172,26 @@ my ($quiet, $dry_run) = (0, 0); # Variables with corresponding config settings my ($thread, $chain_reply_to, $suppress_from, $signed_off_cc, $cc_cmd); +my ($smtp_server, $smtp_authuser, $smtp_authpass, $smtp_ssl); +my ($identity, $aliasfiletype, @alias_files); -my %config_settings = ( +my %config_bool_settings = ( "thread" => [\$thread, 1], "chainreplyto" => [\$chain_reply_to, 1], "suppressfrom" => [\$suppress_from, 0], "signedoffcc" => [\$signed_off_cc, 1], - "cccmd" => [\$cc_cmd, ""], + "smtpssl" => [\$smtp_ssl, 0], ); -foreach my $setting (keys %config_settings) { - my $config = $repo->config_bool("sendemail.$setting"); - ${$config_settings{$setting}->[0]} = (defined $config) ? $config : $config_settings{$setting}->[1]; -} - -@bcclist = $repo->config('sendemail.bcc'); -if (!@bcclist or !$bcclist[0]) { - @bcclist = (); -} +my %config_settings = ( + "smtpserver" => \$smtp_server, + "smtpuser" => \$smtp_authuser, + "smtppass" => \$smtp_authpass, + "cccmd" => \$cc_cmd, + "aliasfiletype" => \$aliasfiletype, + "bcc" => \@bcclist, + "aliasesfile" => \@alias_files, +); # Begin by accumulating all the variables (defined above), that we will end up # needing, first, from the command line: @@ -194,6 +204,10 @@ my $rc = GetOptions("sender|from=s" => \$sender, "bcc=s" => \@bcclist, "chain-reply-to!" => \$chain_reply_to, "smtp-server=s" => \$smtp_server, + "smtp-user=s" => \$smtp_authuser, + "smtp-pass=s" => \$smtp_authpass, + "smtp-ssl!" => \$smtp_ssl, + "identity=s" => \$identity, "compose" => \$compose, "quiet" => \$quiet, "cc-cmd=s" => \$cc_cmd, @@ -208,6 +222,43 @@ unless ($rc) { usage(); } +# Now, let's fill any that aren't set in with defaults: + +sub read_config { + my ($prefix) = @_; + + foreach my $setting (keys %config_bool_settings) { + my $target = $config_bool_settings{$setting}->[0]; + $$target = $repo->config_bool("$prefix.$setting") unless (defined $$target); + } + + foreach my $setting (keys %config_settings) { + my $target = $config_settings{$setting}; + if (ref($target) eq "ARRAY") { + unless (@$target) { + my @values = $repo->config("$prefix.$setting"); + @$target = @values if (@values && defined $values[0]); + } + } + else { + $$target = $repo->config("$prefix.$setting") unless (defined $$target); + } + } +} + +# read configuration from [sendemail "$identity"], fall back on [sendemail] +$identity = $repo->config("sendemail.identity") unless (defined $identity); +read_config("sendemail.$identity") if (defined $identity); +read_config("sendemail"); + +# fall back on builtin bool defaults +foreach my $setting (values %config_bool_settings) { + ${$setting->[0]} = $setting->[1] unless (defined (${$setting->[0]})); +} + +my ($repoauthor) = $repo->ident_person('author'); +my ($repocommitter) = $repo->ident_person('committer'); + # Verify the user input foreach my $entry (@to) { @@ -222,14 +273,7 @@ foreach my $entry (@bcclist) { die "Comma in --bcclist entry: $entry'\n" unless $entry !~ m/,/; } -# Now, let's fill any that aren't set in with defaults: - -my ($repoauthor) = $repo->ident_person('author'); -my ($repocommitter) = $repo->ident_person('committer'); - my %aliases; -my @alias_files = $repo->config('sendemail.aliasesfile'); -my $aliasfiletype = $repo->config('sendemail.aliasfiletype'); my %parse_alias = ( # multiline formats can be supported in the future mutt => sub { my $fh = shift; while (<$fh>) { @@ -320,10 +364,7 @@ if ($thread && !defined $initial_reply_to && $prompting) { $initial_reply_to =~ s/(^\s+|\s+$)//g; } -if (!$smtp_server) { - $smtp_server = $repo->config('sendemail.smtpserver'); -} -if (!$smtp_server) { +if (!defined $smtp_server) { foreach (qw( /usr/sbin/sendmail /usr/lib/sendmail )) { if (-x $_) { $smtp_server = $_; @@ -553,8 +594,16 @@ X-Mailer: git-send-email $gitversion print $sm "$header\n$message"; close $sm or die $?; } else { - require Net::SMTP; - $smtp ||= Net::SMTP->new( $smtp_server ); + if ($smtp_ssl) { + require Net::SMTP::SSL; + $smtp ||= Net::SMTP::SSL->new( $smtp_server, Port => 465 ); + } + else { + require Net::SMTP; + $smtp ||= Net::SMTP->new( $smtp_server ); + } + $smtp->auth( $smtp_authuser, $smtp_authpass ) + or die $smtp->message if (defined $smtp_authuser); $smtp->mail( $raw_from ) or die $smtp->message; $smtp->to( @recipients ) or die $smtp->message; $smtp->data or die $smtp->message; @@ -661,7 +710,7 @@ foreach my $t (@files) { } close F; - if ($cc_cmd ne "") { + if (defined $cc_cmd) { open(F, "$cc_cmd $t |") or die "(cc-cmd) Could not execute '$cc_cmd'"; while() { -- cgit v1.2.1 From 3803bceae84fe122eccb49e3096abead508cde8f Mon Sep 17 00:00:00 2001 From: David Kastrup Date: Wed, 12 Sep 2007 07:53:45 +0200 Subject: git-send-email.perl: Add angle brackets to In-Reply-To if necessary Although message-id by defintion should have surrounding angle brackets, there is no point forcing people to type them in. Signed-off-by: David Kastrup Signed-off-by: Junio C Hamano --- git-send-email.perl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index e0b7d1245..195fe6f70 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -317,7 +317,8 @@ if ($thread && !defined $initial_reply_to && $prompting) { } while (!defined $_); $initial_reply_to = $_; - $initial_reply_to =~ s/(^\s+|\s+$)//g; + $initial_reply_to =~ s/^\s+?\s+$/>/; } if (!$smtp_server) { -- cgit v1.2.1 From be510cfef3d8344007bd34128ca6eb799b714c8c Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 17 Sep 2007 21:18:20 -0700 Subject: send-email: make message-id generation a bit more robust Earlier code took Unix time and appended a few random digits. If you are firing off many messages within a second, you could issue the same id to different messages, which is a no-no. If you send out 31 messages within a single second, with random integer taken out of rand(4200), you have about 10% chance of producing the same message ID. This fixes the problem by uses a prefix string which is constant-per-invocation (time and pid), with a serial number for each message generated by the process appended at the end. Signed-off-by: Junio C Hamano --- git-send-email.perl | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 195fe6f70..9547cc37a 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -437,10 +437,17 @@ sub extract_valid_address { # We'll setup a template for the message id, using the "from" address: +my ($message_id_stamp, $message_id_serial); sub make_message_id { - my $date = time; - my $pseudo_rand = int (rand(4200)); + my $uniq; + if (!defined $message_id_stamp) { + $message_id_stamp = sprintf("%s-%s", time, $$); + $message_id_serial = 0; + } + $message_id_serial++; + $uniq = "$message_id_stamp-$message_id_serial"; + my $du_part; for ($sender, $repocommitter, $repoauthor) { $du_part = extract_valid_address(sanitize_address($_)); @@ -450,8 +457,8 @@ sub make_message_id use Sys::Hostname qw(); $du_part = 'user@' . Sys::Hostname::hostname(); } - my $message_id_template = "<%s-git-send-email-$du_part>"; - $message_id = sprintf $message_id_template, "$date$pseudo_rand"; + my $message_id_template = "<%s-git-send-email-%s>"; + $message_id = sprintf($message_id_template, $uniq, $du_part); #print "new message id = $message_id\n"; # Was useful for debugging } -- cgit v1.2.1 From 44b2476a1278c87d6985993b5e6fd45f1e5f08f2 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 25 Sep 2007 17:27:54 -0700 Subject: send-email --smtp-server-port: allow overriding the default port You can use --smtp-server-port option to specify a port different from the default (typically, SMTP servers listen to smtp port 25 and ssmtp port 465). Users should be aware that sending auth info over non-ssl connections may be unsafe or just may not work at all depending on SMTP server config. Signed-off-by: Glenn Rempe Signed-off-by: Junio C Hamano --- git-send-email.perl | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 4031e86b8..62e142973 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -77,7 +77,10 @@ Options: the default section. --smtp-server If set, specifies the outgoing SMTP server to use. - Defaults to localhost. + Defaults to localhost. Port number can be specified here with + hostname:port format or by using --smtp-server-port option. + + --smtp-server-port Specify a port on the outgoing SMTP server to connect to. --smtp-user The username for SMTP-AUTH. @@ -172,8 +175,8 @@ my ($quiet, $dry_run) = (0, 0); # Variables with corresponding config settings my ($thread, $chain_reply_to, $suppress_from, $signed_off_cc, $cc_cmd); -my ($smtp_server, $smtp_authuser, $smtp_authpass, $smtp_ssl); -my ($identity, $aliasfiletype, @alias_files); +my ($smtp_server, $smtp_server_port, $smtp_authuser, $smtp_authpass, $smtp_ssl); +my ($identity, $aliasfiletype, @alias_files, @smtp_host_parts); my %config_bool_settings = ( "thread" => [\$thread, 1], @@ -185,6 +188,7 @@ my %config_bool_settings = ( my %config_settings = ( "smtpserver" => \$smtp_server, + "smtpserverport" => \$smtp_server_port, "smtpuser" => \$smtp_authuser, "smtppass" => \$smtp_authpass, "cccmd" => \$cc_cmd, @@ -204,6 +208,7 @@ my $rc = GetOptions("sender|from=s" => \$sender, "bcc=s" => \@bcclist, "chain-reply-to!" => \$chain_reply_to, "smtp-server=s" => \$smtp_server, + "smtp-server-port=s" => \$smtp_server_port, "smtp-user=s" => \$smtp_authuser, "smtp-pass=s" => \$smtp_authpass, "smtp-ssl!" => \$smtp_ssl, @@ -602,16 +607,30 @@ X-Mailer: git-send-email $gitversion print $sm "$header\n$message"; close $sm or die $?; } else { + + if (!defined $smtp_server) { + die "The required SMTP server is not properly defined." + } + if ($smtp_ssl) { + $smtp_server_port ||= 465; # ssmtp require Net::SMTP::SSL; - $smtp ||= Net::SMTP::SSL->new( $smtp_server, Port => 465 ); + $smtp ||= Net::SMTP::SSL->new($smtp_server, Port => $smtp_server_port); } else { require Net::SMTP; - $smtp ||= Net::SMTP->new( $smtp_server ); + $smtp ||= Net::SMTP->new((defined $smtp_server_port) + ? "$smtp_server:$smtp_server_port" + : $smtp_server); + } + + if (!$smtp) { + die "Unable to initialize SMTP properly. Is there something wrong with your config?"; + } + + if ((defined $smtp_authuser) && (defined $smtp_authpass)) { + $smtp->auth( $smtp_authuser, $smtp_authpass ) or die $smtp->message; } - $smtp->auth( $smtp_authuser, $smtp_authpass ) - or die $smtp->message if (defined $smtp_authuser); $smtp->mail( $raw_from ) or die $smtp->message; $smtp->to( @recipients ) or die $smtp->message; $smtp->data or die $smtp->message; -- cgit v1.2.1 From 2db9b49c6c19d3edaa3c20147f7d9f29588433df Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Mon, 1 Oct 2007 14:42:42 +0200 Subject: git-send-email: add a new sendemail.to configuration variable Some projects prefer to receive patches via a given email address. In these cases, it's handy to configure that address once. Signed-off-by: Miklos Vajna Signed-off-by: Junio C Hamano --- git-send-email.perl | 1 + 1 file changed, 1 insertion(+) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 62e142973..96051bc01 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -191,6 +191,7 @@ my %config_settings = ( "smtpserverport" => \$smtp_server_port, "smtpuser" => \$smtp_authuser, "smtppass" => \$smtp_authpass, + "to" => \@to, "cccmd" => \$cc_cmd, "aliasfiletype" => \$aliasfiletype, "bcc" => \@bcclist, -- cgit v1.2.1 From 620bb245b945531bb6e08016d5f28caf9e797786 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Wed, 7 Nov 2007 08:34:12 +0100 Subject: send-email: apply --suppress-from to S-o-b and cc-cmd MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Uwe Kleine-König Cc: Ryan Anderson Signed-off-by: Junio C Hamano --- git-send-email.perl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 96051bc01..f4b8f9651 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -88,8 +88,7 @@ Options: --smtp-ssl If set, connects to the SMTP server using SSL. - --suppress-from Suppress sending emails to yourself if your address - appears in a From: line. Defaults to off. + --suppress-from Suppress sending emails to yourself. Defaults to off. --thread Specify that the "In-Reply-To:" header should be set on all emails. Defaults to on. @@ -730,6 +729,7 @@ foreach my $t (@files) { if (/^(Signed-off-by|Cc): (.*)$/i && $signed_off_cc) { my $c = $2; chomp $c; + next if ($c eq $sender and $suppress_from); push @cc, $c; printf("(sob) Adding cc: %s from line '%s'\n", $c, $_) unless $quiet; @@ -745,6 +745,7 @@ foreach my $t (@files) { my $c = $_; $c =~ s/^\s*//g; $c =~ s/\n$//g; + next if ($c eq $sender and $suppress_from); push @cc, $c; printf("(cc-cmd) Adding cc: %s from: '%s'\n", $c, $cc_cmd) unless $quiet; -- cgit v1.2.1 From cb6c162fba3fe3e1333b48c6062c18108c41fb82 Mon Sep 17 00:00:00 2001 From: Benoit Sigoure Date: Thu, 8 Nov 2007 19:56:28 +0100 Subject: git-send-email: Change the prompt for the subject of the initial message. I never understood what this prompt was asking for until I read the actual source code. I think this wording is much more understandable. Signed-off-by: Benoit Sigoure Signed-off-by: Junio C Hamano --- git-send-email.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 9547cc37a..8760cf88a 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -303,7 +303,7 @@ sub expand_aliases { if (!defined $initial_subject && $compose) { do { - $_ = $term->readline("What subject should the emails start with? ", + $_ = $term->readline("What subject should the initial email start with? ", $initial_subject); } while (!defined $_); $initial_subject = $_; -- cgit v1.2.1 From 8291db6f584076b60efa47d72c604b1949508ef8 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Fri, 16 Nov 2007 05:49:09 -0500 Subject: git-send-email: add charset header if we add encoded 'From' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We sometimes pick out the original rfc822 'From' header and include it in the body of the message. If the original author's name needs encoding, then we should specify that in the content-type header. If we already had a content-type header in the mail, then we may need to re-encode. The logic is there to detect this case, but it doesn't actually do the re-encoding. Signed-off-by: Jeff King Acked-by: Uwe Kleine-König Signed-off-by: Junio C Hamano --- git-send-email.perl | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 8760cf88a..2b1f1b598 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -468,11 +468,13 @@ $time = time - scalar $#files; sub unquote_rfc2047 { local ($_) = @_; - if (s/=\?utf-8\?q\?(.*)\?=/$1/g) { + my $encoding; + if (s/=\?([^?]+)\?q\?(.*)\?=/$2/g) { + $encoding = $1; s/_/ /g; s/=([0-9A-F]{2})/chr(hex($1))/eg; } - return "$_"; + return wantarray ? ($_, $encoding) : $_; } # use the simplest quoting being able to handle the recipient @@ -599,6 +601,9 @@ foreach my $t (@files) { open(F,"<",$t) or die "can't open file $t"; my $author = undef; + my $author_encoding; + my $has_content_type; + my $body_encoding; @cc = @initial_cc; @xh = (); my $input_format = undef; @@ -624,12 +629,20 @@ foreach my $t (@files) { next if ($suppress_from); } elsif ($1 eq 'From') { - $author = unquote_rfc2047($2); + ($author, $author_encoding) + = unquote_rfc2047($2); } printf("(mbox) Adding cc: %s from line '%s'\n", $2, $_) unless $quiet; push @cc, $2; } + elsif (/^Content-type:/i) { + $has_content_type = 1; + if (/charset="?[^ "]+/) { + $body_encoding = $1; + } + push @xh, $_; + } elsif (!/^Date:\s/ && /^[-A-Za-z]+:\s+\S/) { push @xh, $_; } @@ -686,6 +699,21 @@ foreach my $t (@files) { if (defined $author) { $message = "From: $author\n\n$message"; + if (defined $author_encoding) { + if ($has_content_type) { + if ($body_encoding eq $author_encoding) { + # ok, we already have the right encoding + } + else { + # uh oh, we should re-encode + } + } + else { + push @xh, + 'MIME-Version: 1.0', + "Content-Type: text/plain; charset=$author_encoding"; + } + } } send_message(); -- cgit v1.2.1 From b7f30e0a972ab90a0f7720a7d6411822eb796ea3 Mon Sep 17 00:00:00 2001 From: "David D. Kilzer" Date: Sun, 18 Nov 2007 20:14:55 -0800 Subject: git-send-email: show all headers when sending mail As a git newbie, it was confusing to set an In-Reply-To header but then not see it printed when the git-send-email command was run. This patch prints all headers that would be sent to sendmail or an SMTP server instead of only printing From, Subject, Cc, To. It also removes the now-extraneous Date header after the "Log says" line. Added test to t/t9001-send-email.sh. Signed-off-by: David D. Kilzer Signed-off-by: Junio C Hamano --- git-send-email.perl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index fd0a4ad0c..47afc5691 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -643,7 +643,7 @@ X-Mailer: git-send-email $gitversion if ($quiet) { printf (($dry_run ? "Dry-" : "")."Sent %s\n", $subject); } else { - print (($dry_run ? "Dry-" : "")."OK. Log says:\nDate: $date\n"); + print (($dry_run ? "Dry-" : "")."OK. Log says:\n"); if ($smtp_server !~ m#^/#) { print "Server: $smtp_server\n"; print "MAIL FROM:<$raw_from>\n"; @@ -651,7 +651,7 @@ X-Mailer: git-send-email $gitversion } else { print "Sendmail: $smtp_server ".join(' ',@sendmail_parameters)."\n"; } - print "From: $sanitized_sender\nSubject: $subject\nCc: $cc\nTo: $to\n\n"; + print $header, "\n"; if ($smtp) { print "Result: ", $smtp->code, ' ', ($smtp->message =~ /\n([^\n]+\n)$/s), "\n"; -- cgit v1.2.1 From 7ac17529297910c7b4502bdfa543ddec3f943413 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ask=20Bj=C3=B8rn=20Hansen?= Date: Mon, 19 Nov 2007 03:00:26 -0800 Subject: send-email: Don't add To: recipients to the Cc: header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Ask Bjørn Hansen Signed-off-by: Junio C Hamano --- git-send-email.perl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 47afc5691..990e44bf0 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -557,7 +557,11 @@ sub sanitize_address sub send_message { my @recipients = unique_email_list(@to); - @cc = (map { sanitize_address($_) } @cc); + @cc = (grep { my $cc = extract_valid_address($_); + not grep { $cc eq $_ } @recipients + } + map { sanitize_address($_) } + @cc); my $to = join (",\n\t", @recipients); @recipients = unique_email_list(@recipients,@cc,@bcclist); @recipients = (map { extract_valid_address($_) } @recipients); -- cgit v1.2.1 From 8641ee3dcbae749c42b7cf117ba3050e2cb95a93 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Tue, 20 Nov 2007 07:54:04 -0500 Subject: send-email: add transfer encoding header with content-type We add the content-type header only when we have non-7bit characters from the 'From' header, so we really need to specify the encoding (in other cases, where the commit text needed a content-type, git-format-patch will already have added the encoding header). Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- git-send-email.perl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 2b1f1b598..b03297c9d 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -711,7 +711,8 @@ foreach my $t (@files) { else { push @xh, 'MIME-Version: 1.0', - "Content-Type: text/plain; charset=$author_encoding"; + "Content-Type: text/plain; charset=$author_encoding", + 'Content-Transfer-Encoding: 8bit'; } } } -- cgit v1.2.1 From 5f5b611805ed60a303ccbc07ebd9a5bac2dabb92 Mon Sep 17 00:00:00 2001 From: Wincent Colaiuta Date: Wed, 21 Nov 2007 13:35:05 +0100 Subject: Authenticate only once in git-send-email When using git-send-email with SMTP authentication sending a patch series would redundantly authenticate multiple times, once for each patch. In the worst case, this would actually prevent the series from being sent because the server would reply with a "5.5.0 Already Authenticated" status code which would derail the process. This commit teaches git-send-email to authenticate once and only once at the beginning of the series. Signed-off-by: Wincent Colaiuta Signed-off-by: Junio C Hamano --- git-send-email.perl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 9c6fa6441..76baa8e43 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -145,6 +145,7 @@ sub format_2822_time { my $have_email_valid = eval { require Email::Valid; 1 }; my $smtp; +my $auth; sub unique_email_list(@); sub cleanup_compose_files(); @@ -635,7 +636,7 @@ X-Mailer: git-send-email $gitversion } if ((defined $smtp_authuser) && (defined $smtp_authpass)) { - $smtp->auth( $smtp_authuser, $smtp_authpass ) or die $smtp->message; + $auth ||= $smtp->auth( $smtp_authuser, $smtp_authpass ) or die $smtp->message; } $smtp->mail( $raw_from ) or die $smtp->message; $smtp->to( @recipients ) or die $smtp->message; -- cgit v1.2.1 From ace72086bbe1cd59bc15a0e5b043bdb98335af00 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Sun, 9 Dec 2007 18:17:28 +0100 Subject: git-send-email.perl: Really add angle brackets to In-Reply-To if necessary 3803bcea tried to fix this, but it only adds the branckes when the given In-Reply-To begins and ends with whitespaces. It also didn't do anything to the --in-reply-to argument. Signed-off-by: Mike Hommey Signed-off-by: Junio C Hamano --- git-send-email.perl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 76baa8e43..c0e1dd348 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -367,10 +367,11 @@ if ($thread && !defined $initial_reply_to && $prompting) { } while (!defined $_); $initial_reply_to = $_; - $initial_reply_to =~ s/^\s+?\s+$/>/; } +$initial_reply_to =~ s/^\s*?\s*$/>/; + if (!defined $smtp_server) { foreach (qw( /usr/sbin/sendmail /usr/lib/sendmail )) { if (-x $_) { -- cgit v1.2.1 From ace9c2a9dd7c9e54194998fc6b7c677dbb7d0902 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 10 Dec 2007 21:44:42 -0800 Subject: send-email: do not muck with initial-reply-to when unset. When not prompting, initial_reply_to can be left unset. Do not try to sanitize it and get useless warning. Signed-off-by: Junio C Hamano --- git-send-email.perl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index c0e1dd348..1d6f46645 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -368,9 +368,10 @@ if ($thread && !defined $initial_reply_to && $prompting) { $initial_reply_to = $_; } - -$initial_reply_to =~ s/^\s*?\s*$/>/; +if (defined $initial_reply_to && $_ ne "") { + $initial_reply_to =~ s/^\s*?\s*$/>/; +} if (!defined $smtp_server) { foreach (qw( /usr/sbin/sendmail /usr/lib/sendmail )) { -- cgit v1.2.1 From 4f3d37035a7c735a3b69f962656819f4ff7e4927 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Mon, 17 Dec 2007 15:51:34 -0500 Subject: git-send-email: avoid duplicate message-ids We used to unconditionally add a message-id to the outgoing email without bothering to check if it already had one. Instead, let's use the existing one. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- git-send-email.perl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index b03297c9d..e8354c760 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -527,7 +527,7 @@ sub send_message $ccline = "\nCc: $cc"; } my $sanitized_sender = sanitize_address($sender); - make_message_id(); + make_message_id() unless defined($message_id); my $header = "From: $sanitized_sender To: $to${ccline} @@ -643,6 +643,9 @@ foreach my $t (@files) { } push @xh, $_; } + elsif (/^Message-Id: (.*)/i) { + $message_id = $1; + } elsif (!/^Date:\s/ && /^[-A-Za-z]+:\s+\S/) { push @xh, $_; } @@ -728,6 +731,7 @@ foreach my $t (@files) { $references = "$message_id"; } } + $message_id = undef; } if ($compose) { -- cgit v1.2.1 From 0e0278baad8752da6c3b37495f005dc1dd6f799a Mon Sep 17 00:00:00 2001 From: Gustaf Hendeby Date: Sat, 22 Dec 2007 01:40:52 +0100 Subject: Make git send-email accept $EDITOR with arguments Currently git send-email does not accept $EDITOR with arguments, eg, emacs -nw, when starting an editor to produce a cover letter. This patch changes this by letting the shell handle the option parsing. Signed-off-by: Gustaf Hendeby Signed-off-by: Junio C Hamano --- git-send-email.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 248d03508..e47994afc 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -400,7 +400,7 @@ EOT close(C); my $editor = $ENV{GIT_EDITOR} || $repo->config("core.editor") || $ENV{VISUAL} || $ENV{EDITOR} || "vi"; - system($editor, $compose_filename); + system('sh', '-c', '$0 $@', $editor, $compose_filename); open(C2,">",$compose_filename . ".final") or die "Failed to open $compose_filename.final : " . $!; -- cgit v1.2.1 From aa54892f5ada8282643dc7387b33261c7135d784 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Fri, 18 Jan 2008 09:19:36 -0500 Subject: send-email: detect invocation errors earlier We never even look at the command line arguments until after we have prompted the user for some information. So running "git send-email" without arguments would prompt for "from" and "to" headers, only to then die with "No patch files specified." Instead, let's try to do as much error checking as possible before getting user input. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- git-send-email.perl | 55 ++++++++++++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 28 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index e47994afc..7a86977ef 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -314,6 +314,33 @@ if (@alias_files and $aliasfiletype and defined $parse_alias{$aliasfiletype}) { ($sender) = expand_aliases($sender) if defined $sender; +# Now that all the defaults are set, process the rest of the command line +# arguments and collect up the files that need to be processed. +for my $f (@ARGV) { + if (-d $f) { + opendir(DH,$f) + or die "Failed to opendir $f: $!"; + + push @files, grep { -f $_ } map { +$f . "/" . $_ } + sort readdir(DH); + + } elsif (-f $f) { + push @files, $f; + + } else { + print STDERR "Skipping $f - not found.\n"; + } +} + +if (@files) { + unless ($quiet) { + print $_,"\n" for (@files); + } +} else { + print STDERR "\nNo patch files specified!\n\n"; + usage(); +} + my $prompting = 0; if (!defined $sender) { $sender = $repoauthor || $repocommitter; @@ -427,34 +454,6 @@ EOT @files = ($compose_filename . ".final"); } - -# Now that all the defaults are set, process the rest of the command line -# arguments and collect up the files that need to be processed. -for my $f (@ARGV) { - if (-d $f) { - opendir(DH,$f) - or die "Failed to opendir $f: $!"; - - push @files, grep { -f $_ } map { +$f . "/" . $_ } - sort readdir(DH); - - } elsif (-f $f) { - push @files, $f; - - } else { - print STDERR "Skipping $f - not found.\n"; - } -} - -if (@files) { - unless ($quiet) { - print $_,"\n" for (@files); - } -} else { - print STDERR "\nNo patch files specified!\n\n"; - usage(); -} - # Variables we set as part of the loop over files our ($message_id, %mail, $subject, $reply_to, $references, $message); -- cgit v1.2.1 From 747bbff9b9583642cd8702b7b559757a6960df00 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Fri, 18 Jan 2008 09:19:48 -0500 Subject: send-email: validate patches before sending anything We try to catch errors early so that we don't end up sending half of a broken patch series. Right now the only validation is checking that line-lengths are under the SMTP-mandated limit of 998. The validation parsing is very crude (it just checks each line length without understanding the mailbox format) but should work fine for this simple check. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- git-send-email.perl | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 7a86977ef..4e62c3f0e 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -332,6 +332,11 @@ for my $f (@ARGV) { } } +foreach my $f (@files) { + my $error = validate_patch($f); + $error and die "fatal: $f: $error\nwarning: no patches were sent\n"; +} + if (@files) { unless ($quiet) { print $_,"\n" for (@files); @@ -837,3 +842,15 @@ sub unique_email_list(@) { } return @emails; } + +sub validate_patch { + my $fn = shift; + open(my $fh, '<', $fn) + or die "unable to open $fn: $!\n"; + while (my $line = <$fh>) { + if (length($line) > 998) { + return "$.: patch contains a line longer than 998 characters"; + } + } + return undef; +} -- cgit v1.2.1 From c764a0c2b6d8c94d90c95fa8170970c85a40665c Mon Sep 17 00:00:00 2001 From: Jeff King Date: Fri, 18 Jan 2008 09:20:10 -0500 Subject: send-email: add no-validate option Since we are now sanity-checking the contents of patches and refusing to send ones with long lines, this knob provides a way for the user to override the new behavior (if, e.g., he knows his SMTP path will handle it). Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- git-send-email.perl | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 4e62c3f0e..6c72952fc 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -100,6 +100,8 @@ Options: --envelope-sender Specify the envelope sender used to send the emails. + --no-validate Don't perform any sanity checks on patches. + EOT exit(1); } @@ -177,6 +179,7 @@ my ($quiet, $dry_run) = (0, 0); my ($thread, $chain_reply_to, $suppress_from, $signed_off_cc, $cc_cmd); my ($smtp_server, $smtp_server_port, $smtp_authuser, $smtp_authpass, $smtp_ssl); my ($identity, $aliasfiletype, @alias_files, @smtp_host_parts); +my ($no_validate); my %config_bool_settings = ( "thread" => [\$thread, 1], @@ -222,6 +225,7 @@ my $rc = GetOptions("sender|from=s" => \$sender, "dry-run" => \$dry_run, "envelope-sender=s" => \$envelope_sender, "thread!" => \$thread, + "no-validate" => \$no_validate, ); unless ($rc) { @@ -332,9 +336,11 @@ for my $f (@ARGV) { } } -foreach my $f (@files) { - my $error = validate_patch($f); - $error and die "fatal: $f: $error\nwarning: no patches were sent\n"; +if (!$no_validate) { + foreach my $f (@files) { + my $error = validate_patch($f); + $error and die "fatal: $f: $error\nwarning: no patches were sent\n"; + } } if (@files) { -- cgit v1.2.1 From 97394ee4304a8d336663df5da23a33efbe1ab46b Mon Sep 17 00:00:00 2001 From: Gustaf Hendeby Date: Mon, 21 Jan 2008 20:57:46 +0100 Subject: send-email, fix breakage in combination with --compose This fixes the subtile bug in git send-email that was introduced into git send-email with aa54892f5ada8282643dc7387b33261c7135d784 (send-email: detect invocation errors earlier), which caused no patches to be sent out if the --compose flag was used. Signed-off-by: Gustaf Hendeby Tested-by: Seth Falcon Signed-off-by: Junio C Hamano --- git-send-email.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 6c72952fc..a1a9d14b0 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -462,7 +462,7 @@ EOT exit(0); } - @files = ($compose_filename . ".final"); + @files = ($compose_filename . ".final", @files); } # Variables we set as part of the loop over files -- cgit v1.2.1 From 2363d7467dcd60467b3e694b3ba6f859bb226f5c Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Sun, 3 Feb 2008 19:53:56 -0500 Subject: git-send-email: ssh/login style password requests Whilst convenient, it is most unwise to record passwords in any place but one's brain. Moreover, it is especially foolish to store them in configuration files, even with access permissions set accordingly. git-send-email has been amended, so that if it detects an smtp username without a password, it promptly prompts for the password and masks the input for privacy. Furthermore, the argument to --smtp-pass has been rendered optional. The documentation has been updated to reflect these changes. Signed-off-by: Michael Witten Signed-off-by: Junio C Hamano --- git-send-email.perl | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index a1a9d14b0..fec55ea2d 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -157,7 +157,7 @@ my $compose_filename = ".msg.$$"; # Variables we fill in automatically, or via prompting: my (@to,@cc,@initial_cc,@bcclist,@xh, - $initial_reply_to,$initial_subject,@files,$author,$sender,$compose,$time); + $initial_reply_to,$initial_subject,@files,$author,$sender,$smtp_authpass,$compose,$time); my $envelope_sender; @@ -177,7 +177,7 @@ my ($quiet, $dry_run) = (0, 0); # Variables with corresponding config settings my ($thread, $chain_reply_to, $suppress_from, $signed_off_cc, $cc_cmd); -my ($smtp_server, $smtp_server_port, $smtp_authuser, $smtp_authpass, $smtp_ssl); +my ($smtp_server, $smtp_server_port, $smtp_authuser, $smtp_ssl); my ($identity, $aliasfiletype, @alias_files, @smtp_host_parts); my ($no_validate); @@ -214,7 +214,7 @@ my $rc = GetOptions("sender|from=s" => \$sender, "smtp-server=s" => \$smtp_server, "smtp-server-port=s" => \$smtp_server_port, "smtp-user=s" => \$smtp_authuser, - "smtp-pass=s" => \$smtp_authpass, + "smtp-pass:s" => \$smtp_authpass, "smtp-ssl!" => \$smtp_ssl, "identity=s" => \$identity, "compose" => \$compose, @@ -647,9 +647,26 @@ X-Mailer: git-send-email $gitversion die "Unable to initialize SMTP properly. Is there something wrong with your config?"; } - if ((defined $smtp_authuser) && (defined $smtp_authpass)) { + if (defined $smtp_authuser) { + + if (!defined $smtp_authpass) { + + system "stty -echo"; + + do { + print "Password: "; + $_ = ; + print "\n"; + } while (!defined $_); + + chomp($smtp_authpass = $_); + + system "stty echo"; + } + $auth ||= $smtp->auth( $smtp_authuser, $smtp_authpass ) or die $smtp->message; } + $smtp->mail( $raw_from ) or die $smtp->message; $smtp->to( @recipients ) or die $smtp->message; $smtp->data or die $smtp->message; -- cgit v1.2.1 From 874299760708e3bd4d63e9afa8da3fe8a7ddc006 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Sun, 3 Feb 2008 19:53:57 -0500 Subject: git-send-email: SIG{TERM,INT} handlers A single signal handler is used for both SIGTERM and SIGINT in order to clean up after an uncouth termination of git-send-email. In particular, the handler resets the text color (this cleanup was already present), turns on tty echoing (in case termination occurrs during a masked Password prompt), and informs the user of of any temporary files created by --compose. Signed-off-by: Michael Witten Signed-off-by: Junio C Hamano --- git-send-email.perl | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index fec55ea2d..14268fc1d 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -24,8 +24,6 @@ use Data::Dumper; use Term::ANSIColor; use Git; -$SIG{INT} = sub { print color("reset"), "\n"; exit }; - package FakeTerm; sub new { my ($class, $reason) = @_; @@ -201,6 +199,29 @@ my %config_settings = ( "aliasesfile" => \@alias_files, ); +# Handle Uncouth Termination +sub signal_handler { + + # Make text normal + print color("reset"), "\n"; + + # SMTP password masked + system "stty echo"; + + # tmp files from --compose + if (-e $compose_filename) { + print "'$compose_filename' contains an intermediate version of the email you were composing.\n"; + } + if (-e ($compose_filename . ".final")) { + print "'$compose_filename.final' contains the composed email.\n" + } + + exit; +}; + +$SIG{TERM} = \&signal_handler; +$SIG{INT} = \&signal_handler; + # Begin by accumulating all the variables (defined above), that we will end up # needing, first, from the command line: -- cgit v1.2.1 From 8a7c56e1591ad5593883bb23fb6c5683a8a1a1a8 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Sun, 3 Feb 2008 19:53:58 -0500 Subject: git-send-email: Better handling of EOF Before, when the user sent the EOF control character, the prompts would be repeated on the same line as the previous prompt. Now, repeat prompts display on separate lines. Signed-off-by: Michael Witten Signed-off-by: Junio C Hamano --- git-send-email.perl | 44 ++++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 16 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 14268fc1d..9d7c1f467 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -376,9 +376,12 @@ if (@files) { my $prompting = 0; if (!defined $sender) { $sender = $repoauthor || $repocommitter; - do { + + while (1) { $_ = $term->readline("Who should the emails appear to be from? [$sender] "); - } while (!defined $_); + last if defined $_; + print "\n"; + } $sender = $_ if ($_); print "Emails will be sent from: ", $sender, "\n"; @@ -386,10 +389,14 @@ if (!defined $sender) { } if (!@to) { - do { - $_ = $term->readline("Who should the emails be sent to? ", - ""); - } while (!defined $_); + + + while (1) { + $_ = $term->readline("Who should the emails be sent to? ", ""); + last if defined $_; + print "\n"; + } + my $to = $_; push @to, split /,/, $to; $prompting++; @@ -411,19 +418,22 @@ sub expand_aliases { @bcclist = expand_aliases(@bcclist); if (!defined $initial_subject && $compose) { - do { - $_ = $term->readline("What subject should the initial email start with? ", - $initial_subject); - } while (!defined $_); + while (1) { + $_ = $term->readline("What subject should the initial email start with? ", $initial_subject); + last if defined $_; + print "\n"; + } + $initial_subject = $_; $prompting++; } if ($thread && !defined $initial_reply_to && $prompting) { - do { - $_= $term->readline("Message-ID to be used as In-Reply-To for the first email? ", - $initial_reply_to); - } while (!defined $_); + while (1) { + $_= $term->readline("Message-ID to be used as In-Reply-To for the first email? ", $initial_reply_to); + last if defined $_; + print "\n"; + } $initial_reply_to = $_; } @@ -474,9 +484,11 @@ EOT close(C); close(C2); - do { + while (1) { $_ = $term->readline("Send this email? (y|n) "); - } while (!defined $_); + last if defined $_; + print "\n"; + } if (uc substr($_,0,1) ne 'Y') { cleanup_compose_files(); -- cgit v1.2.1 From 656482830ddc4a4e2af132fabb118a25190439c2 Mon Sep 17 00:00:00 2001 From: David Brown Date: Tue, 25 Dec 2007 19:56:29 -0800 Subject: git-send-email: Generalize auto-cc recipient mechanism. There are a few options to git-send-email to suppress the automatic generation of 'Cc' fields: --suppress-from, and --signed-off-cc. However, there are other times that git-send-email automatically includes Cc'd recipients. This is not desirable for all development environments. Add a new option --suppress-cc, which can be specified one or more times to list the categories of auto-cc fields that should be suppressed. If not specified, it defaults to values to give the same behavior as specified by --suppress-from, and --signed-off-cc. The categories are: self - patch sender. Same as --suppress-from. author - patch author. cc - cc lines mentioned in the patch. cccmd - avoid running the cccmd. sob - signed off by lines. all - all non-explicit recipients Signed-off-by: David Brown Signed-off-by: Junio C Hamano --- git-send-email.perl | 56 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 7 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index a1a9d14b0..8de5789f6 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -88,6 +88,12 @@ Options: --smtp-ssl If set, connects to the SMTP server using SSL. + --suppress-cc Suppress the specified category of auto-CC. The category + can be one of 'author' for the patch author, 'self' to + avoid copying yourself, 'sob' for Signed-off-by lines, + 'cccmd' for the output of the cccmd, or 'all' to suppress + all of these. + --suppress-from Suppress sending emails to yourself. Defaults to off. --thread Specify that the "In-Reply-To:" header should be set on all @@ -180,12 +186,13 @@ my ($thread, $chain_reply_to, $suppress_from, $signed_off_cc, $cc_cmd); my ($smtp_server, $smtp_server_port, $smtp_authuser, $smtp_authpass, $smtp_ssl); my ($identity, $aliasfiletype, @alias_files, @smtp_host_parts); my ($no_validate); +my (@suppress_cc); my %config_bool_settings = ( "thread" => [\$thread, 1], "chainreplyto" => [\$chain_reply_to, 1], - "suppressfrom" => [\$suppress_from, 0], - "signedoffcc" => [\$signed_off_cc, 1], + "suppressfrom" => [\$suppress_from, undef], + "signedoffcc" => [\$signed_off_cc, undef], "smtpssl" => [\$smtp_ssl, 0], ); @@ -199,6 +206,7 @@ my %config_settings = ( "aliasfiletype" => \$aliasfiletype, "bcc" => \@bcclist, "aliasesfile" => \@alias_files, + "suppresscc" => \@suppress_cc, ); # Begin by accumulating all the variables (defined above), that we will end up @@ -221,6 +229,7 @@ my $rc = GetOptions("sender|from=s" => \$sender, "quiet" => \$quiet, "cc-cmd=s" => \$cc_cmd, "suppress-from!" => \$suppress_from, + "suppress-cc=s" => \@suppress_cc, "signed-off-cc|signed-off-by-cc!" => \$signed_off_cc, "dry-run" => \$dry_run, "envelope-sender=s" => \$envelope_sender, @@ -266,6 +275,35 @@ foreach my $setting (values %config_bool_settings) { ${$setting->[0]} = $setting->[1] unless (defined (${$setting->[0]})); } +# Set CC suppressions +my(%suppress_cc); +if (@suppress_cc) { + foreach my $entry (@suppress_cc) { + die "Unknown --suppress-cc field: '$entry'\n" + unless $entry =~ /^(all|cccmd|cc|author|self|sob)$/; + $suppress_cc{$entry} = 1; + } +} + +if ($suppress_cc{'all'}) { + foreach my $entry (qw (ccmd cc author self sob)) { + $suppress_cc{$entry} = 1; + } + delete $suppress_cc{'all'}; +} + +# If explicit old-style ones are specified, they trump --suppress-cc. +$suppress_cc{'self'} = $suppress_from if defined $suppress_from; +$suppress_cc{'sob'} = $signed_off_cc if defined $signed_off_cc; + +# Debugging, print out the suppressions. +if (0) { + print "suppressions:\n"; + foreach my $entry (keys %suppress_cc) { + printf " %-5s -> $suppress_cc{$entry}\n", $entry; + } +} + my ($repoauthor) = $repo->ident_person('author'); my ($repocommitter) = $repo->ident_person('committer'); @@ -711,11 +749,14 @@ foreach my $t (@files) { } elsif (/^(Cc|From):\s+(.*)$/) { if (unquote_rfc2047($2) eq $sender) { - next if ($suppress_from); + next if ($suppress_cc{'self'}); } elsif ($1 eq 'From') { ($author, $author_encoding) = unquote_rfc2047($2); + next if ($suppress_cc{'author'}); + } else { + next if ($suppress_cc{'cc'}); } printf("(mbox) Adding cc: %s from line '%s'\n", $2, $_) unless $quiet; @@ -742,7 +783,7 @@ foreach my $t (@files) { # line 2 = subject # So let's support that, too. $input_format = 'lots'; - if (@cc == 0) { + if (@cc == 0 && !$suppress_cc{'cc'}) { printf("(non-mbox) Adding cc: %s from line '%s'\n", $_, $_) unless $quiet; @@ -759,10 +800,11 @@ foreach my $t (@files) { } } else { $message .= $_; - if (/^(Signed-off-by|Cc): (.*)$/i && $signed_off_cc) { + if (/^(Signed-off-by|Cc): (.*)$/i) { + next if ($suppress_cc{'sob'}); my $c = $2; chomp $c; - next if ($c eq $sender and $suppress_from); + next if ($c eq $sender and $suppress_cc{'self'}); push @cc, $c; printf("(sob) Adding cc: %s from line '%s'\n", $c, $_) unless $quiet; @@ -771,7 +813,7 @@ foreach my $t (@files) { } close F; - if (defined $cc_cmd) { + if (defined $cc_cmd && !$suppress_cc{'cccmd'}) { open(F, "$cc_cmd $t |") or die "(cc-cmd) Could not execute '$cc_cmd'"; while() { -- cgit v1.2.1 From 1ca3d6ed01774eab37e96d9c88b840ea618f97af Mon Sep 17 00:00:00 2001 From: Jay Soffian Date: Wed, 20 Feb 2008 00:55:07 -0500 Subject: send-email: squelch warning due to comparing undefined $_ to "" The check to see if initial_reply_to is defined was also comparing $_ to "" for a reason I cannot ascertain (looking at the commit which made the change didn't provide enlightenment), but if $_ is undefined, perl generates a warning. Signed-off-by: Jay Soffian Signed-off-by: Junio C Hamano --- git-send-email.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index a1a9d14b0..8e6f3b22c 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -406,7 +406,7 @@ if ($thread && !defined $initial_reply_to && $prompting) { $initial_reply_to = $_; } -if (defined $initial_reply_to && $_ ne "") { +if (defined $initial_reply_to) { $initial_reply_to =~ s/^\s*?\s*$/>/; } -- cgit v1.2.1 From 0fb7fc751d29cd1099556f71fc7c08158a6a78bc Mon Sep 17 00:00:00 2001 From: Jay Soffian Date: Thu, 21 Feb 2008 19:16:04 -0500 Subject: send-email: fix In-Reply-To regression Fix a regression introduced by 1ca3d6e (send-email: squelch warning due to comparing undefined $_ to "") where if the user was prompted for an initial In-Reply-To and didn't provide one, messages would be sent out with an invalid In-Reply-To of "<>" Also add test cases for the regression and the fix. A small modification was needed to allow send-email to take its replies from stdin if the environment variable GIT_SEND_EMAIL_NOTTY is set. Signed-off-by: Jay Soffian Signed-off-by: Junio C Hamano --- git-send-email.perl | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index ccb87a2d5..29b1105c4 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -170,7 +170,9 @@ my $envelope_sender; my $repo = Git->repository(); my $term = eval { - new Term::ReadLine 'git-send-email'; + $ENV{"GIT_SEND_EMAIL_NOTTY"} + ? new Term::ReadLine 'git-send-email', \*STDIN, \*STDOUT + : new Term::ReadLine 'git-send-email'; }; if ($@) { $term = new FakeTerm "$@: going non-interactive"; @@ -476,8 +478,9 @@ if ($thread && !defined $initial_reply_to && $prompting) { $initial_reply_to = $_; } if (defined $initial_reply_to) { - $initial_reply_to =~ s/^\s*?\s*$/>/; + $initial_reply_to =~ s/^\s*?\s*$//; + $initial_reply_to = "<$initial_reply_to>" if $initial_reply_to ne ''; } if (!defined $smtp_server) { -- cgit v1.2.1 From ba51795c5fc32a507df9f91ffeae21893e9e7633 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 7 Mar 2008 22:12:13 -0800 Subject: send-email: --no-signed-off-cc should suppress 'sob' cc The logic to countermand suppression of Cc to the signers with a more explicit --signed-off-by option done in 6564828 (git-send-email: Generalize auto-cc recipient mechanism) suffers from a double-negation error. A --signed-off-cc option, when false, should actively suppress CC: to be generated out of S-o-b lines, and it should refrain from suppressing when it is true. It also fixes "(sob) Adding cc:" status output; earlier it included the line terminator LF inside '%s', which was totally bogus. Signed-off-by: Junio C Hamano --- git-send-email.perl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 29b1105c4..be4a20d7c 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -317,7 +317,7 @@ if ($suppress_cc{'all'}) { # If explicit old-style ones are specified, they trump --suppress-cc. $suppress_cc{'self'} = $suppress_from if defined $suppress_from; -$suppress_cc{'sob'} = $signed_off_cc if defined $signed_off_cc; +$suppress_cc{'sob'} = !$signed_off_cc if defined $signed_off_cc; # Debugging, print out the suppressions. if (0) { @@ -855,6 +855,7 @@ foreach my $t (@files) { $message .= $_; if (/^(Signed-off-by|Cc): (.*)$/i) { next if ($suppress_cc{'sob'}); + chomp; my $c = $2; chomp $c; next if ($c eq $sender and $suppress_cc{'self'}); -- cgit v1.2.1 From ad79c02451295a4b1ce59e60cfc0ca4bd7e3fbdf Mon Sep 17 00:00:00 2001 From: Frank Lichtenheld Date: Fri, 14 Mar 2008 18:29:30 +0100 Subject: send-email: Don't require to be called in a repository We might not have some configuration variables available, but if the user doesn't care about that, neither should we. Still use the repository if it is available, though. Signed-off-by: Frank Lichtenheld Signed-off-by: Junio C Hamano --- git-send-email.perl | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index be4a20d7c..9e568bf9c 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -168,7 +168,8 @@ my $envelope_sender; # Example reply to: #$initial_reply_to = ''; #<20050203173208.GA23964@foobar.com>'; -my $repo = Git->repository(); +my $repo = eval { Git->repository() }; +my @repo = $repo ? ($repo) : (); my $term = eval { $ENV{"GIT_SEND_EMAIL_NOTTY"} ? new Term::ReadLine 'git-send-email', \*STDIN, \*STDOUT @@ -271,25 +272,25 @@ sub read_config { foreach my $setting (keys %config_bool_settings) { my $target = $config_bool_settings{$setting}->[0]; - $$target = $repo->config_bool("$prefix.$setting") unless (defined $$target); + $$target = Git::config_bool(@repo, "$prefix.$setting") unless (defined $$target); } foreach my $setting (keys %config_settings) { my $target = $config_settings{$setting}; if (ref($target) eq "ARRAY") { unless (@$target) { - my @values = $repo->config("$prefix.$setting"); + my @values = Git::config(@repo, "$prefix.$setting"); @$target = @values if (@values && defined $values[0]); } } else { - $$target = $repo->config("$prefix.$setting") unless (defined $$target); + $$target = Git::config(@repo, "$prefix.$setting") unless (defined $$target); } } } # read configuration from [sendemail "$identity"], fall back on [sendemail] -$identity = $repo->config("sendemail.identity") unless (defined $identity); +$identity = Git::config(@repo, "sendemail.identity") unless (defined $identity); read_config("sendemail.$identity") if (defined $identity); read_config("sendemail"); @@ -327,8 +328,9 @@ if (0) { } } -my ($repoauthor) = $repo->ident_person('author'); -my ($repocommitter) = $repo->ident_person('committer'); +my ($repoauthor, $repocommitter); +($repoauthor) = Git::ident_person(@repo, 'author'); +($repocommitter) = Git::ident_person(@repo, 'committer'); # Verify the user input @@ -415,7 +417,7 @@ if (@files) { my $prompting = 0; if (!defined $sender) { - $sender = $repoauthor || $repocommitter; + $sender = $repoauthor || $repocommitter || ''; while (1) { $_ = $term->readline("Who should the emails appear to be from? [$sender] "); @@ -509,7 +511,7 @@ GIT: for the patch you are writing. EOT close(C); - my $editor = $ENV{GIT_EDITOR} || $repo->config("core.editor") || $ENV{VISUAL} || $ENV{EDITOR} || "vi"; + my $editor = $ENV{GIT_EDITOR} || Git::config(@repo, "core.editor") || $ENV{VISUAL} || $ENV{EDITOR} || "vi"; system('sh', '-c', '$0 $@', $editor, $compose_filename); open(C2,">",$compose_filename . ".final") -- cgit v1.2.1 From 5f8b9fcd03af09fd7c55407af1f26833728278c2 Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Sun, 27 Apr 2008 14:14:58 +0200 Subject: git-send-email: add a new sendemail.cc configuration variable Some projects prefer to always CC patches to a given mailing list. In these cases, it's handy to configure that address once. Signed-off-by: Miklos Vajna Signed-off-by: Junio C Hamano --- git-send-email.perl | 1 + 1 file changed, 1 insertion(+) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 9e568bf9c..cb05cf5b9 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -203,6 +203,7 @@ my %config_settings = ( "smtpuser" => \$smtp_authuser, "smtppass" => \$smtp_authpass, "to" => \@to, + "cc" => \@initial_cc, "cccmd" => \$cc_cmd, "aliasfiletype" => \$aliasfiletype, "bcc" => \@bcclist, -- cgit v1.2.1 From 065096c2b558af80e670299621ff3ddc6839954c Mon Sep 17 00:00:00 2001 From: Bryan Donlan Date: Sun, 4 May 2008 01:37:53 -0400 Subject: git-send-email.perl: Handle shell metacharacters in $EDITOR properly This fixes the git-send-perl semantics for launching an editor when $GIT_EDITOR (or friends) contains shell metacharacters to match launch_editor() in builtin-tag.c. If we use the current approach (sh -c '$0 $@' "$EDITOR" files ...), we see it fails when $EDITOR has shell metacharacters: $ sh -x -c '$0 $@' "$VISUAL" "foo" + "$FAKE_EDITOR" foo "$FAKE_EDITOR": 1: "$FAKE_EDITOR": not found Whereas builtin-tag.c will invoke sh -c "$EDITOR \"$@\"". Thus, this patch changes git-send-email.perl to use the same method as the C utilities, and additionally updates t/t9001-send-email.sh to test for this bug. Signed-off-by: Bryan Donlan Signed-off-by: Junio C Hamano --- git-send-email.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 9e568bf9c..b50239636 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -512,7 +512,7 @@ EOT close(C); my $editor = $ENV{GIT_EDITOR} || Git::config(@repo, "core.editor") || $ENV{VISUAL} || $ENV{EDITOR} || "vi"; - system('sh', '-c', '$0 $@', $editor, $compose_filename); + system('sh', '-c', $editor.' "$@"', $editor, $compose_filename); open(C2,">",$compose_filename . ".final") or die "Failed to open $compose_filename.final : " . $!; -- cgit v1.2.1 From 0706bd19ef9b41e7519df2c73796ef93484272fd Mon Sep 17 00:00:00 2001 From: Jeff King Date: Fri, 28 Mar 2008 17:28:33 -0400 Subject: send-email: specify content-type of --compose body If the compose message contains non-ascii characters, then we assume it is in utf-8 and include the appropriate MIME headers. If the user has already included a MIME-Version header, then we assume they know what they are doing and don't add any headers. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- git-send-email.perl | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index be4a20d7c..71ba44d69 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -518,8 +518,22 @@ EOT open(C,"<",$compose_filename) or die "Failed to open $compose_filename : " . $!; + my $need_8bit_cte = file_has_nonascii($compose_filename); + my $in_body = 0; while() { next if m/^GIT: /; + if (!$in_body && /^\n$/) { + $in_body = 1; + if ($need_8bit_cte) { + print C2 "MIME-Version: 1.0\n", + "Content-Type: text/plain; ", + "charset=utf-8\n", + "Content-Transfer-Encoding: 8bit\n"; + } + } + if (!$in_body && /^MIME-Version:/i) { + $need_8bit_cte = 0; + } print C2 $_; } close(C); @@ -956,3 +970,13 @@ sub validate_patch { } return undef; } + +sub file_has_nonascii { + my $fn = shift; + open(my $fh, '<', $fn) + or die "unable to open $fn: $!\n"; + while (my $line = <$fh>) { + return 1 if $line =~ /[^[:ascii:]]/; + } + return 0; +} -- cgit v1.2.1 From d54eaaa268eb79a51ac11bfa8bbfb456c0b1a1fa Mon Sep 17 00:00:00 2001 From: Jeff King Date: Fri, 28 Mar 2008 17:29:01 -0400 Subject: send-email: rfc2047-quote subject lines with non-ascii characters We always use 'utf-8' as the encoding, since we currently have no way of getting the information from the user. This also refactors the quoting of recipient names, since both processes can share the rfc2047 quoting code. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- git-send-email.perl | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 71ba44d69..455a57059 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -534,6 +534,14 @@ EOT if (!$in_body && /^MIME-Version:/i) { $need_8bit_cte = 0; } + if (!$in_body && /^Subject: ?(.*)/i) { + my $subject = $1; + $_ = "Subject: " . + ($subject =~ /[^[:ascii:]]/ ? + quote_rfc2047($subject) : + $subject) . + "\n"; + } print C2 $_; } close(C); @@ -624,6 +632,14 @@ sub unquote_rfc2047 { return wantarray ? ($_, $encoding) : $_; } +sub quote_rfc2047 { + local $_ = shift; + my $encoding = shift || 'utf-8'; + s/([^-a-zA-Z0-9!*+\/])/sprintf("=%02X", ord($1))/eg; + s/(.*)/=\?$encoding\?q\?$1\?=/; + return $_; +} + # use the simplest quoting being able to handle the recipient sub sanitize_address { @@ -641,8 +657,7 @@ sub sanitize_address # rfc2047 is needed if a non-ascii char is included if ($recipient_name =~ /[^[:ascii:]]/) { - $recipient_name =~ s/([^-a-zA-Z0-9!*+\/])/sprintf("=%02X", ord($1))/eg; - $recipient_name =~ s/(.*)/=\?utf-8\?q\?$1\?=/; + $recipient_name = quote_rfc2047($recipient_name); } # double quotes are needed if specials or CTLs are included -- cgit v1.2.1 From 18023c20656265364d4d1805f435e8420ab70687 Mon Sep 17 00:00:00 2001 From: "Horst H. von Brand" Date: Fri, 28 Mar 2008 11:09:04 -0300 Subject: Fix recipient santitization Need to quote all special characters, not just the first one Signed-off-by: Horst H. von Brand Signed-off-by: Junio C Hamano --- git-send-email.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index be4a20d7c..5630276f7 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -633,7 +633,7 @@ sub sanitize_address # double quotes are needed if specials or CTLs are included elsif ($recipient_name =~ /[][()<>@,;:\\".\000-\037\177]/) { - $recipient_name =~ s/(["\\\r])/\\$1/; + $recipient_name =~ s/(["\\\r])/\\$1/g; $recipient_name = "\"$recipient_name\""; } -- cgit v1.2.1 From 9f7820ae574815e6a5c2a8c361a3c7e788d0930c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ask=20Bj=C3=B8rn=20Hansen?= Date: Sat, 7 Jun 2008 00:33:42 -0700 Subject: send-email: Allow the envelope sender to be set via configuration Signed-off-by: Junio C Hamano --- git-send-email.perl | 1 + 1 file changed, 1 insertion(+) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index a598fdc89..ec69c237f 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -209,6 +209,7 @@ my %config_settings = ( "bcc" => \@bcclist, "aliasesfile" => \@alias_files, "suppresscc" => \@suppress_cc, + "envelopesender" => \$envelope_sender, ); # Handle Uncouth Termination -- cgit v1.2.1 From d1eb35b653ddc1bb3fffde1729a7f10342525049 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Sat, 7 Jun 2008 15:34:36 +0200 Subject: git-send-email: allow whitespace in addressee list When interactively supplying addresses to send an email to with send-email, whitespace after the separation comma (as in 'list, jc') wasn't ignored. This meant that resolving of the alias ' jc' would fail, sending an email only to list. With this patch, the optional trailing whitespace is ignored. Signed-off-by: Pieter de Bie Signed-off-by: Junio C Hamano --- git-send-email.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index ec69c237f..0b04ba32f 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -442,7 +442,7 @@ if (!@to) { } my $to = $_; - push @to, split /,/, $to; + push @to, split /,\s*/, $to; $prompting++; } -- cgit v1.2.1 From 300913bd448def6fe2f943f534a172259725e7c6 Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Wed, 25 Jun 2008 15:44:40 -0700 Subject: git-send-email: Accept fifos as well as files When a fifo is given, validation must be skipped because we can't read the fifo twice. Ideally git-send-email would cache the read data instead of attempting to read twice, but for now just skip validation. Signed-off-by: Kevin Ballard Signed-off-by: Junio C Hamano --- git-send-email.perl | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 0b04ba32f..16d437526 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -393,7 +393,7 @@ for my $f (@ARGV) { push @files, grep { -f $_ } map { +$f . "/" . $_ } sort readdir(DH); - } elsif (-f $f) { + } elsif (-f $f or -p $f) { push @files, $f; } else { @@ -403,8 +403,10 @@ for my $f (@ARGV) { if (!$no_validate) { foreach my $f (@files) { - my $error = validate_patch($f); - $error and die "fatal: $f: $error\nwarning: no patches were sent\n"; + unless (-p $f) { + my $error = validate_patch($f); + $error and die "fatal: $f: $error\nwarning: no patches were sent\n"; + } } } -- cgit v1.2.1 From f6bebd121ac531871c4cee576b0baf6814099425 Mon Sep 17 00:00:00 2001 From: Thomas Rast Date: Wed, 25 Jun 2008 21:42:43 +0200 Subject: git-send-email: add support for TLS via Net::SMTP::SSL We do this by handing over the Net::SMTP instance to Net::SMTP::SSL, which avoids Net::SMTP::TLS and its weird error checking. This trick is due to Brian Evins. Signed-off-by: Thomas Rast Signed-off-by: Junio C Hamano --- git-send-email.perl | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 0b04ba32f..763072042 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -84,7 +84,10 @@ Options: --smtp-pass The password for SMTP-AUTH. - --smtp-ssl If set, connects to the SMTP server using SSL. + --smtp-encryption Specify 'tls' for STARTTLS encryption, or 'ssl' for SSL. + Any other value disables the feature. + + --smtp-ssl Synonym for '--smtp-encryption=ssl'. Deprecated. --suppress-cc Suppress the specified category of auto-CC. The category can be one of 'author' for the patch author, 'self' to @@ -184,7 +187,7 @@ my ($quiet, $dry_run) = (0, 0); # Variables with corresponding config settings my ($thread, $chain_reply_to, $suppress_from, $signed_off_cc, $cc_cmd); -my ($smtp_server, $smtp_server_port, $smtp_authuser, $smtp_ssl); +my ($smtp_server, $smtp_server_port, $smtp_authuser, $smtp_encryption); my ($identity, $aliasfiletype, @alias_files, @smtp_host_parts); my ($no_validate); my (@suppress_cc); @@ -194,7 +197,6 @@ my %config_bool_settings = ( "chainreplyto" => [\$chain_reply_to, 1], "suppressfrom" => [\$suppress_from, undef], "signedoffcc" => [\$signed_off_cc, undef], - "smtpssl" => [\$smtp_ssl, 0], ); my %config_settings = ( @@ -249,7 +251,8 @@ my $rc = GetOptions("sender|from=s" => \$sender, "smtp-server-port=s" => \$smtp_server_port, "smtp-user=s" => \$smtp_authuser, "smtp-pass:s" => \$smtp_authpass, - "smtp-ssl!" => \$smtp_ssl, + "smtp-ssl" => sub { $smtp_encryption = 'ssl' }, + "smtp-encryption=s" => \$smtp_encryption, "identity=s" => \$identity, "compose" => \$compose, "quiet" => \$quiet, @@ -289,6 +292,15 @@ sub read_config { $$target = Git::config(@repo, "$prefix.$setting") unless (defined $$target); } } + + if (!defined $smtp_encryption) { + my $enc = Git::config(@repo, "$prefix.smtpencryption"); + if (defined $enc) { + $smtp_encryption = $enc; + } elsif (Git::config_bool(@repo, "$prefix.smtpssl")) { + $smtp_encryption = 'ssl'; + } + } } # read configuration from [sendemail "$identity"], fall back on [sendemail] @@ -738,7 +750,7 @@ X-Mailer: git-send-email $gitversion die "The required SMTP server is not properly defined." } - if ($smtp_ssl) { + if ($smtp_encryption eq 'ssl') { $smtp_server_port ||= 465; # ssmtp require Net::SMTP::SSL; $smtp ||= Net::SMTP::SSL->new($smtp_server, Port => $smtp_server_port); @@ -748,6 +760,17 @@ X-Mailer: git-send-email $gitversion $smtp ||= Net::SMTP->new((defined $smtp_server_port) ? "$smtp_server:$smtp_server_port" : $smtp_server); + if ($smtp_encryption eq 'tls') { + require Net::SMTP::SSL; + $smtp->command('STARTTLS'); + $smtp->response(); + if ($smtp->code == 220) { + $smtp = Net::SMTP::SSL->start_SSL($smtp) + or die "STARTTLS failed! ".$smtp->message; + } else { + die "Server does not support STARTTLS! ".$smtp->message; + } + } } if (!$smtp) { -- cgit v1.2.1 From fa835cd5728411bfd8f851e7327e11ad809a59d1 Mon Sep 17 00:00:00 2001 From: Thomas Rast Date: Thu, 26 Jun 2008 23:03:21 +0200 Subject: git-send-email: prevent undefined variable warnings if no encryption is set With the previous patch, not configuring any encryption (either on or off) would leave $smtp_encryption undefined. We simply set it to the empty string in that case. Signed-off-by: Thomas Rast Signed-off-by: Junio C Hamano --- git-send-email.perl | 3 +++ 1 file changed, 3 insertions(+) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 763072042..edb12c2aa 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -313,6 +313,9 @@ foreach my $setting (values %config_bool_settings) { ${$setting->[0]} = $setting->[1] unless (defined (${$setting->[0]})); } +# 'default' encryption is none -- this only prevents a warning +$smtp_encryption = '' unless (defined $smtp_encryption); + # Set CC suppressions my(%suppress_cc); if (@suppress_cc) { -- cgit v1.2.1 From 6cbf8b00fb27f5f55f1a5645ba60c451cb090fc1 Mon Sep 17 00:00:00 2001 From: Thomas Rast Date: Thu, 3 Jul 2008 00:11:31 +0200 Subject: git-send-email: Do not attempt to STARTTLS more than once With the previous TLS patch, send-email would attempt to STARTTLS at the beginning of every mail, despite reusing the last connection. We simply skip further encryption checks after successful TLS initiation. Signed-off-by: Thomas Rast Signed-off-by: Junio C Hamano --- git-send-email.perl | 1 + 1 file changed, 1 insertion(+) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index a047b016e..3564419e8 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -772,6 +772,7 @@ X-Mailer: git-send-email $gitversion if ($smtp->code == 220) { $smtp = Net::SMTP::SSL->start_SSL($smtp) or die "STARTTLS failed! ".$smtp->message; + $smtp_encryption = ''; } else { die "Server does not support STARTTLS! ".$smtp->message; } -- cgit v1.2.1 From 9d1ccf5e640bdaeddd01a86b40b4c0980c1ef642 Mon Sep 17 00:00:00 2001 From: Robert Shearman Date: Wed, 9 Jul 2008 22:39:40 +0100 Subject: git-send-email: Fix authenticating on some servers when using TLS. Send HELO again after a successful STARTTLS command to refresh the list of extensions. These may be different to what is returned over a clear connection (for example the AUTH command may be accepted over a secure connection, but not over a clear connection). Furthermore, this behaviour is recommended by RFC 2487 (http://www.ietf.org/rfc/rfc2487.txt). Signed-off-by: Robert Shearman Signed-off-by: Junio C Hamano --- git-send-email.perl | 3 +++ 1 file changed, 3 insertions(+) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 3564419e8..6adb66947 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -773,6 +773,9 @@ X-Mailer: git-send-email $gitversion $smtp = Net::SMTP::SSL->start_SSL($smtp) or die "STARTTLS failed! ".$smtp->message; $smtp_encryption = ''; + # Send EHLO again to receive fresh + # supported commands + $smtp->hello(); } else { die "Server does not support STARTTLS! ".$smtp->message; } -- cgit v1.2.1 From 1b1dd23f2d6a707b7077cdf6bc6d4055bd0bfb7d Mon Sep 17 00:00:00 2001 From: Stephan Beyer Date: Sun, 13 Jul 2008 15:36:15 +0200 Subject: Make usage strings dash-less When you misuse a git command, you are shown the usage string. But this is currently shown in the dashed form. So if you just copy what you see, it will not work, when the dashed form is no longer supported. This patch makes git commands show the dash-less version. For shell scripts that do not specify OPTIONS_SPEC, git-sh-setup.sh generates a dash-less usage string now. Signed-off-by: Stephan Beyer Signed-off-by: Junio C Hamano --- git-send-email.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 6adb66947..2e4a44ad2 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -38,7 +38,7 @@ package main; sub usage { print <... +git send-email [options] ... Options: --from Specify the "From:" line of the email to be sent. -- cgit v1.2.1 From 8892048d516fffab2000c2b47e006d8d8ebaa8c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Valdemar=20M=C3=B8rch?= Date: Fri, 25 Jul 2008 15:06:48 +0200 Subject: send-email: find body-encoding correctly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In 8291db6 (git-send-email: add charset header if we add encoded 'From', 2007-11-16), "$1" is used from a regexp without using () to capture anything in $1. Later, when that value was used, it causes a warning about a variable being undefined, instead of using the correct value for comparison (not that it makes difference in the current code that does not do actual re-encoding). Signed-off-by: Peter Valdemar Mørch Signed-off-by: Junio C Hamano --- git-send-email.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 0b04ba32f..385ff7c21 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -850,7 +850,7 @@ foreach my $t (@files) { } elsif (/^Content-type:/i) { $has_content_type = 1; - if (/charset="?[^ "]+/) { + if (/charset="?([^ "]+)/) { $body_encoding = $1; } push @xh, $_; -- cgit v1.2.1 From 7ecbad91e94c0552da9c8903e4ed004c4d6744e4 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Tue, 30 Sep 2008 07:58:24 -0500 Subject: Docs: send-email's usage text and man page mention same options Specifically, boolean options are now listed in the form --[no-]option and both forms of documentation now consistently use --[no-]signed-off-by-cc Signed-off-by: Michael Witten Acked-by: Jeff King Signed-off-by: Shawn O. Pearce --- git-send-email.perl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index d2fd89907..9f56162b1 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -64,11 +64,11 @@ Options: Only used if --compose is also set. If --compose is not set, this will be prompted for. - --chain-reply-to If set, the replies will all be to the previous + --[no-]chain-reply-to If set, the replies will all be to the previous email sent, rather than to the first email sent. Defaults to on. - --signed-off-cc Automatically add email addresses that appear in + --[no-]signed-off-by-cc Automatically add email addresses that appear in Signed-off-by: or Cc: lines to the cc: list. Defaults to on. --identity The configuration identity, a subsection to prioritise over @@ -95,9 +95,9 @@ Options: 'cccmd' for the output of the cccmd, or 'all' to suppress all of these. - --suppress-from Suppress sending emails to yourself. Defaults to off. + --[no-]suppress-from Suppress sending emails to yourself. Defaults to off. - --thread Specify that the "In-Reply-To:" header should be set on all + --[no-]thread Specify that the "In-Reply-To:" header should be set on all emails. Defaults to on. --quiet Make git-send-email less verbose. One line per email -- cgit v1.2.1 From 180c9f5c299b6ec9fcd77e3346fbdd6874e028a4 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Tue, 30 Sep 2008 07:58:25 -0500 Subject: Docs: send-email usage text much sexier All of the descriptions are aligned, shorter, better arranged, and no line is greater than 78 columns. Signed-off-by: Michael Witten Acked-by: Jeff King Signed-off-by: Shawn O. Pearce --- git-send-email.perl | 94 +++++++++++++++-------------------------------------- 1 file changed, 26 insertions(+), 68 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 9f56162b1..2c31a257e 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -40,74 +40,32 @@ sub usage { print <... Options: - --from Specify the "From:" line of the email to be sent. - - --to Specify the primary "To:" line of the email. - - --cc Specify an initial "Cc:" list for the entire series - of emails. - - --cc-cmd Specify a command to execute per file which adds - per file specific cc address entries - - --bcc Specify a list of email addresses that should be Bcc: - on all the emails. - - --compose Use \$GIT_EDITOR, core.editor, \$EDITOR, or \$VISUAL to edit - an introductory message for the patch series. - - --subject Specify the initial "Subject:" line. - Only necessary if --compose is also set. If --compose - is not set, this will be prompted for. - - --in-reply-to Specify the first "In-Reply-To:" header line. - Only used if --compose is also set. If --compose is not - set, this will be prompted for. - - --[no-]chain-reply-to If set, the replies will all be to the previous - email sent, rather than to the first email sent. - Defaults to on. - - --[no-]signed-off-by-cc Automatically add email addresses that appear in - Signed-off-by: or Cc: lines to the cc: list. Defaults to on. - - --identity The configuration identity, a subsection to prioritise over - the default section. - - --smtp-server If set, specifies the outgoing SMTP server to use. - Defaults to localhost. Port number can be specified here with - hostname:port format or by using --smtp-server-port option. - - --smtp-server-port Specify a port on the outgoing SMTP server to connect to. - - --smtp-user The username for SMTP-AUTH. - - --smtp-pass The password for SMTP-AUTH. - - --smtp-encryption Specify 'tls' for STARTTLS encryption, or 'ssl' for SSL. - Any other value disables the feature. - - --smtp-ssl Synonym for '--smtp-encryption=ssl'. Deprecated. - - --suppress-cc Suppress the specified category of auto-CC. The category - can be one of 'author' for the patch author, 'self' to - avoid copying yourself, 'sob' for Signed-off-by lines, - 'cccmd' for the output of the cccmd, or 'all' to suppress - all of these. - - --[no-]suppress-from Suppress sending emails to yourself. Defaults to off. - - --[no-]thread Specify that the "In-Reply-To:" header should be set on all - emails. Defaults to on. - - --quiet Make git-send-email less verbose. One line per email - should be all that is output. - - --dry-run Do everything except actually send the emails. - - --envelope-sender Specify the envelope sender used to send the emails. - - --no-validate Don't perform any sanity checks on patches. + --identity * Use the sendemail. options. + --from * Email From: + --envelope-sender * Email envelope sender. + --to * Email To: + --cc * Email Cc: + --cc-cmd * Email Cc: via ` \$patch_path` + --bcc * Email Bcc: + --subject * Email "Subject:" (only if --compose). + --compose * Open an editor for introduction. + --in-reply-to * First "In-Reply-To:" (only if --compose). + --[no-]chain-reply-to * Chain In-Reply-To: fields. Default on. + --[no-]thread * Use In-Reply-To: field. Default on. + --[no-]signed-off-by-cc * Actually send to Cc: and Signed-off-by: + addresses. Default on. + --suppress-cc * author, self, sob, cccmd, all. + --[no-]suppress-from * Don't send email to self. Default off. + --smtp-server * Outgoing SMTP server to use. The port + is optional. Default 'localhost'. + --smtp-server-port * Outgoing SMTP server port. + --smtp-user * The username for SMTP-AUTH. + --smtp-pass * The password for SMTP-AUTH; not necessary. + --smtp-encryption * tls or ssl; anything else disables. + --smtp-ssl * Deprecated. Use '--smtp-encryption ssl'. + --quiet * Output one line of info per email. + --dry-run * Don't actually send the emails. + --no-validate * Don't perform sanity checks on patches. EOT exit(1); -- cgit v1.2.1 From dbf5e1e974ff6264b04759a4a3e04966b056e533 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Tue, 30 Sep 2008 07:58:27 -0500 Subject: send-email: change --no-validate to boolean --[no-]validate There is also now a configuration variable: sendemail[.].validate Signed-off-by: Michael Witten Acked-by: Jeff King Signed-off-by: Shawn O. Pearce --- git-send-email.perl | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 2c31a257e..3467cf1cc 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -65,7 +65,7 @@ Options: --smtp-ssl * Deprecated. Use '--smtp-encryption ssl'. --quiet * Output one line of info per email. --dry-run * Don't actually send the emails. - --no-validate * Don't perform sanity checks on patches. + --[no-]validate * Perform patch sanity checks. Default on. EOT exit(1); @@ -147,7 +147,7 @@ my ($quiet, $dry_run) = (0, 0); my ($thread, $chain_reply_to, $suppress_from, $signed_off_cc, $cc_cmd); my ($smtp_server, $smtp_server_port, $smtp_authuser, $smtp_encryption); my ($identity, $aliasfiletype, @alias_files, @smtp_host_parts); -my ($no_validate); +my ($validate); my (@suppress_cc); my %config_bool_settings = ( @@ -155,6 +155,7 @@ my %config_bool_settings = ( "chainreplyto" => [\$chain_reply_to, 1], "suppressfrom" => [\$suppress_from, undef], "signedoffcc" => [\$signed_off_cc, undef], + "validate" => [\$validate, 1], ); my %config_settings = ( @@ -221,7 +222,7 @@ my $rc = GetOptions("sender|from=s" => \$sender, "dry-run" => \$dry_run, "envelope-sender=s" => \$envelope_sender, "thread!" => \$thread, - "no-validate" => \$no_validate, + "validate!" => \$validate, ); unless ($rc) { @@ -374,7 +375,7 @@ for my $f (@ARGV) { } } -if (!$no_validate) { +if ($validate) { foreach my $f (@files) { unless (-p $f) { my $error = validate_patch($f); -- cgit v1.2.1 From 4ed62b0316619b70e9dc9868e93c33815ff678d5 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Tue, 30 Sep 2008 07:58:30 -0500 Subject: Docs: send-email: Create logical groupings for --help text The options are partitioned into more digestible groups. Signed-off-by: Michael Witten Acked-by: Jeff King Signed-off-by: Shawn O. Pearce --- git-send-email.perl | 61 +++++++++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 27 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 3467cf1cc..80dae88c7 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -39,33 +39,40 @@ package main; sub usage { print <... -Options: - --identity * Use the sendemail. options. - --from * Email From: - --envelope-sender * Email envelope sender. - --to * Email To: - --cc * Email Cc: - --cc-cmd * Email Cc: via ` \$patch_path` - --bcc * Email Bcc: - --subject * Email "Subject:" (only if --compose). - --compose * Open an editor for introduction. - --in-reply-to * First "In-Reply-To:" (only if --compose). - --[no-]chain-reply-to * Chain In-Reply-To: fields. Default on. - --[no-]thread * Use In-Reply-To: field. Default on. - --[no-]signed-off-by-cc * Actually send to Cc: and Signed-off-by: - addresses. Default on. - --suppress-cc * author, self, sob, cccmd, all. - --[no-]suppress-from * Don't send email to self. Default off. - --smtp-server * Outgoing SMTP server to use. The port - is optional. Default 'localhost'. - --smtp-server-port * Outgoing SMTP server port. - --smtp-user * The username for SMTP-AUTH. - --smtp-pass * The password for SMTP-AUTH; not necessary. - --smtp-encryption * tls or ssl; anything else disables. - --smtp-ssl * Deprecated. Use '--smtp-encryption ssl'. - --quiet * Output one line of info per email. - --dry-run * Don't actually send the emails. - --[no-]validate * Perform patch sanity checks. Default on. + + Composing: + --from * Email From: + --to * Email To: + --cc * Email Cc: + --bcc * Email Bcc: + --subject * Email "Subject:" + --in-reply-to * Email "In-Reply-To:" + --compose * Open an editor for introduction. + + Sending: + --envelope-sender * Email envelope sender. + --smtp-server * Outgoing SMTP server to use. The port + is optional. Default 'localhost'. + --smtp-server-port * Outgoing SMTP server port. + --smtp-user * Username for SMTP-AUTH. + --smtp-pass * Password for SMTP-AUTH; not necessary. + --smtp-encryption * tls or ssl; anything else disables. + --smtp-ssl * Deprecated. Use '--smtp-encryption ssl'. + + Automating: + --identity * Use the sendemail. options. + --cc-cmd * Email Cc: via ` \$patch_path` + --suppress-cc * author, self, sob, cccmd, all. + --[no-]signed-off-by-cc * Send to Cc: and Signed-off-by: + addresses. Default on. + --[no-]suppress-from * Send to self. Default off. + --[no-]chain-reply-to * Chain In-Reply-To: fields. Default on. + --[no-]thread * Use In-Reply-To: field. Default on. + + Administering: + --quiet * Output one line of info per email. + --dry-run * Don't actually send the emails. + --[no-]validate * Perform patch sanity checks. Default on. EOT exit(1); -- cgit v1.2.1 From ddc3d4fe84d245b81afddf305b7d92ae1f0bc556 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Tue, 30 Sep 2008 07:58:32 -0500 Subject: send-email: signedoffcc -> signedoffbycc, but handle both The documentation now mentions sendemail.signedoffbycc instead of sendemail.signedoffcc in order to match with the options --signed-off-by-cc; the code has been updated to reflect this as well, but sendemail.signedoffcc is still handled. Signed-off-by: Michael Witten Acked-by: Jeff King Signed-off-by: Shawn O. Pearce --- git-send-email.perl | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 80dae88c7..bdbfac662 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -151,7 +151,7 @@ if ($@) { my ($quiet, $dry_run) = (0, 0); # Variables with corresponding config settings -my ($thread, $chain_reply_to, $suppress_from, $signed_off_cc, $cc_cmd); +my ($thread, $chain_reply_to, $suppress_from, $signed_off_by_cc, $cc_cmd); my ($smtp_server, $smtp_server_port, $smtp_authuser, $smtp_encryption); my ($identity, $aliasfiletype, @alias_files, @smtp_host_parts); my ($validate); @@ -161,7 +161,8 @@ my %config_bool_settings = ( "thread" => [\$thread, 1], "chainreplyto" => [\$chain_reply_to, 1], "suppressfrom" => [\$suppress_from, undef], - "signedoffcc" => [\$signed_off_cc, undef], + "signedoffbycc" => [\$signed_off_by_cc, undef], + "signedoffcc" => [\$signed_off_by_cc, undef], # Deprecated "validate" => [\$validate, 1], ); @@ -225,7 +226,7 @@ my $rc = GetOptions("sender|from=s" => \$sender, "cc-cmd=s" => \$cc_cmd, "suppress-from!" => \$suppress_from, "suppress-cc=s" => \@suppress_cc, - "signed-off-cc|signed-off-by-cc!" => \$signed_off_cc, + "signed-off-cc|signed-off-by-cc!" => \$signed_off_by_cc, "dry-run" => \$dry_run, "envelope-sender=s" => \$envelope_sender, "thread!" => \$thread, @@ -301,7 +302,7 @@ if ($suppress_cc{'all'}) { # If explicit old-style ones are specified, they trump --suppress-cc. $suppress_cc{'self'} = $suppress_from if defined $suppress_from; -$suppress_cc{'sob'} = !$signed_off_cc if defined $signed_off_cc; +$suppress_cc{'sob'} = !$signed_off_by_cc if defined $signed_off_by_cc; # Debugging, print out the suppressions. if (0) { -- cgit v1.2.1 From 8c178687959732edab8bf91da9ed9f4fbcf7c14e Mon Sep 17 00:00:00 2001 From: Pierre Habouzit Date: Fri, 31 Oct 2008 18:57:10 +0000 Subject: git send-email: avoid leaking directory file descriptors. Signed-off-by: Pierre Habouzit Signed-off-by: Junio C Hamano --- git-send-email.perl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index d2fd89907..18529c76e 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -407,10 +407,9 @@ for my $f (@ARGV) { push @files, grep { -f $_ } map { +$f . "/" . $_ } sort readdir(DH); - + closedir(DH); } elsif (-f $f or -p $f) { push @files, $f; - } else { print STDERR "Skipping $f - not found.\n"; } -- cgit v1.2.1 From caf0c3d692a5a4639e48499711271cb279ecd0dc Mon Sep 17 00:00:00 2001 From: Pierre Habouzit Date: Tue, 11 Nov 2008 00:53:59 +0100 Subject: git send-email: make the message file name more specific. This helps editors choosing their syntax hilighting properly. Also make the file live under the git directory. Signed-off-by: Pierre Habouzit Signed-off-by: Junio C Hamano --- git-send-email.perl | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 94ca5c89a..aaace02fa 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -124,9 +124,6 @@ my $auth; sub unique_email_list(@); sub cleanup_compose_files(); -# Constants (essentially) -my $compose_filename = ".msg.$$"; - # Variables we fill in automatically, or via prompting: my (@to,@cc,@initial_cc,@bcclist,@xh, $initial_reply_to,$initial_subject,@files,$author,$sender,$smtp_authpass,$compose,$time); @@ -149,6 +146,7 @@ if ($@) { # Behavior modification variables my ($quiet, $dry_run) = (0, 0); +my $compose_filename = $repo->repo_path() . "/.gitsendemail.msg.$$"; # Variables with corresponding config settings my ($thread, $chain_reply_to, $suppress_from, $signed_off_by_cc, $cc_cmd); -- cgit v1.2.1 From 5df9fcf695a0ba85abfeed68efb3b1c5890068d6 Mon Sep 17 00:00:00 2001 From: Pierre Habouzit Date: Tue, 11 Nov 2008 00:54:00 +0100 Subject: git send-email: interpret unknown files as revision lists Filter out all the arguments git-send-email doesn't like to a git format-patch command, that dumps its content to a safe directory. Barf when a file/revision conflict occurs, allow it to be overriden --[no-]format-patch. Signed-off-by: Pierre Habouzit Signed-off-by: Junio C Hamano --- git-send-email.perl | 47 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 5 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index aaace02fa..6f5a61389 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -22,8 +22,12 @@ use Term::ReadLine; use Getopt::Long; use Data::Dumper; use Term::ANSIColor; +use File::Temp qw/ tempdir /; +use Error qw(:try); use Git; +Getopt::Long::Configure qw/ pass_through /; + package FakeTerm; sub new { my ($class, $reason) = @_; @@ -38,7 +42,7 @@ package main; sub usage { print <... +git send-email [options] Composing: --from * Email From: @@ -73,6 +77,8 @@ git send-email [options] ... --quiet * Output one line of info per email. --dry-run * Don't actually send the emails. --[no-]validate * Perform patch sanity checks. Default on. + --[no-]format-patch * understand any non optional arguments as + `git format-patch` ones. EOT exit(1); @@ -146,6 +152,7 @@ if ($@) { # Behavior modification variables my ($quiet, $dry_run) = (0, 0); +my $format_patch; my $compose_filename = $repo->repo_path() . "/.gitsendemail.msg.$$"; # Variables with corresponding config settings @@ -229,6 +236,7 @@ my $rc = GetOptions("sender|from=s" => \$sender, "envelope-sender=s" => \$envelope_sender, "thread!" => \$thread, "validate!" => \$validate, + "format-patch!" => \$format_patch, ); unless ($rc) { @@ -363,23 +371,52 @@ if (@alias_files and $aliasfiletype and defined $parse_alias{$aliasfiletype}) { ($sender) = expand_aliases($sender) if defined $sender; +# returns 1 if the conflict must be solved using it as a format-patch argument +sub check_file_rev_conflict($) { + my $f = shift; + try { + $repo->command('rev-parse', '--verify', '--quiet', $f); + if (defined($format_patch)) { + print "foo\n"; + return $format_patch; + } + die(<command('format-patch', '-o', tempdir(CLEANUP => 1), @rev_list_opts); +} + if ($validate) { foreach my $f (@files) { unless (-p $f) { -- cgit v1.2.1 From 8fd5bb7f44b7192a564ebe4f9db376af9fe148ec Mon Sep 17 00:00:00 2001 From: Pierre Habouzit Date: Tue, 11 Nov 2008 00:54:01 +0100 Subject: git send-email: add --annotate option This allows to review every patch (and fix various aspects of them, or comment them) in an editor just before being sent. Combined to the fact that git send-email can now process revision lists, this makes git send-email and efficient way to review and send patches interactively. Signed-off-by: Pierre Habouzit Signed-off-by: Junio C Hamano --- git-send-email.perl | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 6f5a61389..ccb3b1816 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -51,6 +51,7 @@ git send-email [options] --bcc * Email Bcc: --subject * Email "Subject:" --in-reply-to * Email "In-Reply-To:" + --annotate * Review each patch that will be sent in an editor. --compose * Open an editor for introduction. Sending: @@ -132,7 +133,8 @@ sub cleanup_compose_files(); # Variables we fill in automatically, or via prompting: my (@to,@cc,@initial_cc,@bcclist,@xh, - $initial_reply_to,$initial_subject,@files,$author,$sender,$smtp_authpass,$compose,$time); + $initial_reply_to,$initial_subject,@files, + $author,$sender,$smtp_authpass,$annotate,$compose,$time); my $envelope_sender; @@ -155,6 +157,17 @@ my ($quiet, $dry_run) = (0, 0); my $format_patch; my $compose_filename = $repo->repo_path() . "/.gitsendemail.msg.$$"; +# Handle interactive edition of files. +my $multiedit; +my $editor = $ENV{GIT_EDITOR} || Git::config(@repo, "core.editor") || $ENV{VISUAL} || $ENV{EDITOR} || "vi"; +sub do_edit { + if (defined($multiedit) && !$multiedit) { + map { system('sh', '-c', $editor.' "$@"', $editor, $_); } @_; + } else { + system('sh', '-c', $editor.' "$@"', $editor, @_); + } +} + # Variables with corresponding config settings my ($thread, $chain_reply_to, $suppress_from, $signed_off_by_cc, $cc_cmd); my ($smtp_server, $smtp_server_port, $smtp_authuser, $smtp_encryption); @@ -184,6 +197,7 @@ my %config_settings = ( "aliasesfile" => \@alias_files, "suppresscc" => \@suppress_cc, "envelopesender" => \$envelope_sender, + "multiedit" => \$multiedit, ); # Handle Uncouth Termination @@ -226,6 +240,7 @@ my $rc = GetOptions("sender|from=s" => \$sender, "smtp-ssl" => sub { $smtp_encryption = 'ssl' }, "smtp-encryption=s" => \$smtp_encryption, "identity=s" => \$identity, + "annotate" => \$annotate, "compose" => \$compose, "quiet" => \$quiet, "cc-cmd=s" => \$cc_cmd, @@ -532,7 +547,12 @@ EOT close(C); my $editor = $ENV{GIT_EDITOR} || Git::config(@repo, "core.editor") || $ENV{VISUAL} || $ENV{EDITOR} || "vi"; - system('sh', '-c', $editor.' "$@"', $editor, $compose_filename); + + if ($annotate) { + do_edit($compose_filename, @files); + } else { + do_edit($compose_filename); + } open(C2,">",$compose_filename . ".final") or die "Failed to open $compose_filename.final : " . $!; @@ -581,6 +601,8 @@ EOT } @files = ($compose_filename . ".final", @files); +} elsif ($annotate) { + do_edit(@files); } # Variables we set as part of the loop over files -- cgit v1.2.1 From beece9dab8e26c98062351536ce0d871a066790e Mon Sep 17 00:00:00 2001 From: Pierre Habouzit Date: Tue, 11 Nov 2008 00:54:02 +0100 Subject: git send-email: ask less questions when --compose is used. When --compose is used, we can grab the From/Subject/In-Reply-To from the edited summary, let it be so and don't ask the user silly questions. The summary templates gets quite revamped, and includes the list of patches subjects that are going to be sent with this batch. When having a body full of empty lines, the summary isn't sent. Document that in the git-send-email manpage fully. Note: It doesn't deal with To/Cc/Bcc yet. Signed-off-by: Pierre Habouzit Signed-off-by: Junio C Hamano --- git-send-email.perl | 187 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 114 insertions(+), 73 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index ccb3b1816..9039cfde0 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -162,9 +162,17 @@ my $multiedit; my $editor = $ENV{GIT_EDITOR} || Git::config(@repo, "core.editor") || $ENV{VISUAL} || $ENV{EDITOR} || "vi"; sub do_edit { if (defined($multiedit) && !$multiedit) { - map { system('sh', '-c', $editor.' "$@"', $editor, $_); } @_; + map { + system('sh', '-c', $editor.' "$@"', $editor, $_); + if (($? & 127) || ($? >> 8)) { + die("the editor exited uncleanly, aborting everything"); + } + } @_; } else { system('sh', '-c', $editor.' "$@"', $editor, @_); + if (($? & 127) || ($? >> 8)) { + die("the editor exited uncleanly, aborting everything"); + } } } @@ -450,6 +458,108 @@ if (@files) { usage(); } +sub get_patch_subject($) { + my $fn = shift; + open (my $fh, '<', $fn); + while (my $line = <$fh>) { + next unless ($line =~ /^Subject: (.*)$/); + close $fh; + return "GIT: $1\n"; + } + close $fh; + die "No subject line in $fn ?"; +} + +if ($compose) { + # Note that this does not need to be secure, but we will make a small + # effort to have it be unique + open(C,">",$compose_filename) + or die "Failed to open for writing $compose_filename: $!"; + + + my $tpl_sender = $sender || $repoauthor || $repocommitter || ''; + my $tpl_subject = $initial_subject || ''; + my $tpl_reply_to = $initial_reply_to || ''; + + print C <",$compose_filename . ".final") + or die "Failed to open $compose_filename.final : " . $!; + + open(C,"<",$compose_filename) + or die "Failed to open $compose_filename : " . $!; + + my $need_8bit_cte = file_has_nonascii($compose_filename); + my $in_body = 0; + my $summary_empty = 1; + while() { + next if m/^GIT: /; + if ($in_body) { + $summary_empty = 0 unless (/^\n$/); + } elsif (/^\n$/) { + $in_body = 1; + if ($need_8bit_cte) { + print C2 "MIME-Version: 1.0\n", + "Content-Type: text/plain; ", + "charset=utf-8\n", + "Content-Transfer-Encoding: 8bit\n"; + } + } elsif (/^MIME-Version:/i) { + $need_8bit_cte = 0; + } elsif (/^Subject:\s*(.+)\s*$/i) { + $initial_subject = $1; + my $subject = $initial_subject; + $_ = "Subject: " . + ($subject =~ /[^[:ascii:]]/ ? + quote_rfc2047($subject) : + $subject) . + "\n"; + } elsif (/^In-Reply-To:\s*(.+)\s*$/i) { + $initial_reply_to = $1; + next; + } elsif (/^From:\s*(.+)\s*$/i) { + $sender = $1; + next; + } elsif (/^(?:To|Cc|Bcc):/i) { + print "To/Cc/Bcc fields are not interpreted yet, they have been ignored\n"; + next; + } + print C2 $_; + } + close(C); + close(C2); + + if ($summary_empty) { + print "Summary email is empty, skipping it\n"; + $compose = -1; + } +} elsif ($annotate) { + do_edit(@files); +} + my $prompting = 0; if (!defined $sender) { $sender = $repoauthor || $repocommitter || ''; @@ -494,17 +604,6 @@ sub expand_aliases { @initial_cc = expand_aliases(@initial_cc); @bcclist = expand_aliases(@bcclist); -if (!defined $initial_subject && $compose) { - while (1) { - $_ = $term->readline("What subject should the initial email start with? ", $initial_subject); - last if defined $_; - print "\n"; - } - - $initial_subject = $_; - $prompting++; -} - if ($thread && !defined $initial_reply_to && $prompting) { while (1) { $_= $term->readline("Message-ID to be used as In-Reply-To for the first email? ", $initial_reply_to); @@ -531,64 +630,6 @@ if (!defined $smtp_server) { } if ($compose) { - # Note that this does not need to be secure, but we will make a small - # effort to have it be unique - open(C,">",$compose_filename) - or die "Failed to open for writing $compose_filename: $!"; - print C "From $sender # This line is ignored.\n"; - printf C "Subject: %s\n\n", $initial_subject; - printf C <",$compose_filename . ".final") - or die "Failed to open $compose_filename.final : " . $!; - - open(C,"<",$compose_filename) - or die "Failed to open $compose_filename : " . $!; - - my $need_8bit_cte = file_has_nonascii($compose_filename); - my $in_body = 0; - while() { - next if m/^GIT: /; - if (!$in_body && /^\n$/) { - $in_body = 1; - if ($need_8bit_cte) { - print C2 "MIME-Version: 1.0\n", - "Content-Type: text/plain; ", - "charset=utf-8\n", - "Content-Transfer-Encoding: 8bit\n"; - } - } - if (!$in_body && /^MIME-Version:/i) { - $need_8bit_cte = 0; - } - if (!$in_body && /^Subject: ?(.*)/i) { - my $subject = $1; - $_ = "Subject: " . - ($subject =~ /[^[:ascii:]]/ ? - quote_rfc2047($subject) : - $subject) . - "\n"; - } - print C2 $_; - } - close(C); - close(C2); - while (1) { $_ = $term->readline("Send this email? (y|n) "); last if defined $_; @@ -600,9 +641,9 @@ EOT exit(0); } - @files = ($compose_filename . ".final", @files); -} elsif ($annotate) { - do_edit(@files); + if ($compose > 0) { + @files = ($compose_filename . ".final", @files); + } } # Variables we set as part of the loop over files -- cgit v1.2.1 From 73c427eb99a9bb8a3ade40809194405ddb1fd733 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Tue, 25 Nov 2008 18:55:00 -0800 Subject: send-email: Fix Pine address book parsing See: http://www.washington.edu/pine/tech-notes/low-level.html Entries with a fcc or comment field after the address weren't parsed correctly. Continuation lines, identified by leading spaces, were also not handled. Distribution lists which had ( ) around a list of addresses did not have the parenthesis removed. Signed-off-by: Trent Piepho Signed-off-by: Junio C Hamano --- git-send-email.perl | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 94ca5c89a..007e2c6ee 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -345,10 +345,13 @@ my %parse_alias = ( # spaces delimit multiple addresses $aliases{$1} = [ split(/\s+/, $2) ]; }}}, - pine => sub { my $fh = shift; while (<$fh>) { - if (/^(\S+)\t.*\t(.*)$/) { + pine => sub { my $fh = shift; my $f='\t[^\t]*'; + for (my $x = ''; defined($x); $x = $_) { + chomp $x; + $x .= $1 while(defined($_ = <$fh>) && /^ +(.*)$/); + $x =~ /^(\S+)$f\t\(?([^\t]+?)\)?(:?$f){0,2}$/ or next; $aliases{$1} = [ split(/\s*,\s*/, $2) ]; - }}}, + }}, gnus => sub { my $fh = shift; while (<$fh>) { if (/\(define-mail-alias\s+"(\S+?)"\s+"(\S+?)"\)/) { $aliases{$1} = [ $2 ]; -- cgit v1.2.1 From 69f4ce553708ee5ce474faaa9c45312f38aad563 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 30 Nov 2008 22:38:20 -0800 Subject: send-email: do not reverse the command line arguments The loop picks elements from @ARGV one by one, sifts them into arguments meant for format-patch and the script itself, and pushes them to @files and @rev_list_opts arrays. Pick elements from @ARGV starting at the beginning using shift, instead of at the end using pop, as push appends them to the end of the array. Signed-off-by: Junio C Hamano --- git-send-email.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 7508f8ff2..3112f769c 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -421,7 +421,7 @@ EOF # Now that all the defaults are set, process the rest of the command line # arguments and collect up the files that need to be processed. my @rev_list_opts; -while (my $f = pop @ARGV) { +while (defined(my $f = shift @ARGV)) { if ($f eq "--") { push @rev_list_opts, "--", @ARGV; @ARGV = (); -- cgit v1.2.1 From 0e73b3ee6ca95e1db2fe801d2b8544f4c27991df Mon Sep 17 00:00:00 2001 From: Wu Fengguang Date: Fri, 19 Dec 2008 16:10:10 +0800 Subject: git-send-email: handle email address with quoted comma Correctly handle email addresses containing quoted commas, e.g. "Zhu, Yi" , "Li, Shaohua" The commas inside the double quotes are not separators. Signed-off-by: Wu Fengguang Signed-off-by: Junio C Hamano --- git-send-email.perl | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 18529c76e..449d938ba 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -20,6 +20,7 @@ use strict; use warnings; use Term::ReadLine; use Getopt::Long; +use Text::ParseWords; use Data::Dumper; use Term::ANSIColor; use Git; @@ -363,6 +364,10 @@ foreach my $entry (@bcclist) { die "Comma in --bcclist entry: $entry'\n" unless $entry !~ m/,/; } +sub split_addrs { + return parse_line('\s*,\s*', 1, @_); +} + my %aliases; my %parse_alias = ( # multiline formats can be supported in the future @@ -371,7 +376,7 @@ my %parse_alias = ( my ($alias, $addr) = ($1, $2); $addr =~ s/#.*$//; # mutt allows # comments # commas delimit multiple addresses - $aliases{$alias} = [ split(/\s*,\s*/, $addr) ]; + $aliases{$alias} = [ split_addrs($addr) ]; }}}, mailrc => sub { my $fh = shift; while (<$fh>) { if (/^alias\s+(\S+)\s+(.*)$/) { @@ -380,7 +385,7 @@ my %parse_alias = ( }}}, pine => sub { my $fh = shift; while (<$fh>) { if (/^(\S+)\t.*\t(.*)$/) { - $aliases{$1} = [ split(/\s*,\s*/, $2) ]; + $aliases{$1} = [ split_addrs($2) ]; }}}, gnus => sub { my $fh = shift; while (<$fh>) { if (/\(define-mail-alias\s+"(\S+?)"\s+"(\S+?)"\)/) { @@ -458,7 +463,7 @@ if (!@to) { } my $to = $_; - push @to, split /,\s*/, $to; + push @to, split_addrs($to); $prompting++; } -- cgit v1.2.1 From 2f0e7cbbb0703d510a761e2892727e84b3cdcbec Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 21 Dec 2008 01:57:59 -0800 Subject: send-email: futureproof split_addrs() sub Matt Kraai points out that calling parse_line() assuming that the caller ever passes only one argument is a bug waiting to happen, and he is right. Signed-off-by: Junio C Hamano --- git-send-email.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 61144011d..77ca8fe88 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -361,7 +361,7 @@ foreach my $entry (@bcclist) { } sub split_addrs { - return parse_line('\s*,\s*', 1, @_); + return quotewords('\s*,\s*', 1, @_); } my %aliases; -- cgit v1.2.1 From eed6ca7c402cb51ff6cfd3ecf1f1cac788579b5d Mon Sep 17 00:00:00 2001 From: Jay Soffian Date: Sat, 14 Feb 2009 23:32:13 -0500 Subject: send-email: allow send-email to run outside a repo send-email is supposed to be able to run from outside a repo. This ability was broken by commits caf0c3d6 (make the message file name more specific) and 5df9fcf6 (interpret unknown files as revision lists). This commit provides a fix for both. Signed-off-by: Jay Soffian Signed-off-by: Junio C Hamano --- git-send-email.perl | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 77ca8fe88..9dad10092 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -23,7 +23,7 @@ use Getopt::Long; use Text::ParseWords; use Data::Dumper; use Term::ANSIColor; -use File::Temp qw/ tempdir /; +use File::Temp qw/ tempdir tempfile /; use Error qw(:try); use Git; @@ -156,7 +156,10 @@ if ($@) { # Behavior modification variables my ($quiet, $dry_run) = (0, 0); my $format_patch; -my $compose_filename = $repo->repo_path() . "/.gitsendemail.msg.$$"; +my $compose_filename = ($repo ? + tempfile(".gitsendemail.msg.XXXXXX", DIR => $repo->repo_path()) : + tempfile(".gitsendemail.msg.XXXXXX", DIR => "."))[1]; + # Handle interactive edition of files. my $multiedit; @@ -267,6 +270,9 @@ unless ($rc) { usage(); } +die "Cannot run git format-patch from outside a repository\n" + if $format_patch and not $repo; + # Now, let's fill any that aren't set in with defaults: sub read_config { @@ -404,6 +410,7 @@ if (@alias_files and $aliasfiletype and defined $parse_alias{$aliasfiletype}) { # returns 1 if the conflict must be solved using it as a format-patch argument sub check_file_rev_conflict($) { + return unless $repo; my $f = shift; try { $repo->command('rev-parse', '--verify', '--quiet', $f); @@ -445,6 +452,8 @@ while (defined(my $f = shift @ARGV)) { } if (@rev_list_opts) { + die "Cannot run git format-patch from outside a repository\n" + unless $repo; push @files, $repo->command('format-patch', '-o', tempdir(CLEANUP => 1), @rev_list_opts); } -- cgit v1.2.1 From 5012699d9840fe34fe0838ea0d529c2f32f76b82 Mon Sep 17 00:00:00 2001 From: Jay Soffian Date: Sat, 14 Feb 2009 23:32:14 -0500 Subject: send-email: handle multiple Cc addresses when reading mbox message When git format-patch is given multiple --cc arguments, it generates a Cc header that looks like: Cc: first@example.com, second@example.com, third@example.com Before this commit, send-email was unable to handle such a message as it did not handle folded header lines, nor multiple recipients in a Cc line. This patch: - Unfolds header lines by pre-processing the header before extracting any of its fields. - Handles Cc lines with multiple recipients. - Adds use of Mail::Address if available for splitting Cc line and the "Who should the emails be sent to?" prompt", with fall back to existing split_addrs() function. - Tests the new functionality and adds two tests for detecting whether "From:" appears correctly in message body when patch author differs from patch sender. Signed-off-by: Jay Soffian Signed-off-by: Junio C Hamano --- git-send-email.perl | 153 +++++++++++++++++++++++++++++----------------------- 1 file changed, 86 insertions(+), 67 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 9dad10092..a6efd1fa2 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -126,6 +126,7 @@ sub format_2822_time { } my $have_email_valid = eval { require Email::Valid; 1 }; +my $have_mail_address = eval { require Mail::Address; 1 }; my $smtp; my $auth; @@ -366,6 +367,14 @@ foreach my $entry (@bcclist) { die "Comma in --bcclist entry: $entry'\n" unless $entry !~ m/,/; } +sub parse_address_line { + if ($have_mail_address) { + return map { $_->format } Mail::Address->parse($_[0]); + } else { + return split_addrs($_[0]); + } +} + sub split_addrs { return quotewords('\s*,\s*', 1, @_); } @@ -602,7 +611,7 @@ if (!@to) { } my $to = $_; - push @to, split_addrs($to); + push @to, parse_address_line($to); $prompting++; } @@ -929,88 +938,98 @@ foreach my $t (@files) { @cc = @initial_cc; @xh = (); my $input_format = undef; - my $header_done = 0; + my @header = (); $message = ""; + # First unfold multiline header fields while() { - if (!$header_done) { - if (/^From /) { - $input_format = 'mbox'; - next; + last if /^\s*$/; + if (/^\s+\S/ and @header) { + chomp($header[$#header]); + s/^\s+/ /; + $header[$#header] .= $_; + } else { + push(@header, $_); + } + } + # Now parse the header + foreach(@header) { + if (/^From /) { + $input_format = 'mbox'; + next; + } + chomp; + if (!defined $input_format && /^[-A-Za-z]+:\s/) { + $input_format = 'mbox'; + } + + if (defined $input_format && $input_format eq 'mbox') { + if (/^Subject:\s+(.*)$/) { + $subject = $1; } - chomp; - if (!defined $input_format && /^[-A-Za-z]+:\s/) { - $input_format = 'mbox'; + elsif (/^From:\s+(.*)$/) { + ($author, $author_encoding) = unquote_rfc2047($1); + next if $suppress_cc{'author'}; + next if $suppress_cc{'self'} and $author eq $sender; + printf("(mbox) Adding cc: %s from line '%s'\n", + $1, $_) unless $quiet; + push @cc, $1; } - - if (defined $input_format && $input_format eq 'mbox') { - if (/^Subject:\s+(.*)$/) { - $subject = $1; - - } elsif (/^(Cc|From):\s+(.*)$/) { - if (unquote_rfc2047($2) eq $sender) { + elsif (/^Cc:\s+(.*)$/) { + foreach my $addr (parse_address_line($1)) { + if (unquote_rfc2047($addr) eq $sender) { next if ($suppress_cc{'self'}); - } - elsif ($1 eq 'From') { - ($author, $author_encoding) - = unquote_rfc2047($2); - next if ($suppress_cc{'author'}); } else { next if ($suppress_cc{'cc'}); } printf("(mbox) Adding cc: %s from line '%s'\n", - $2, $_) unless $quiet; - push @cc, $2; + $addr, $_) unless $quiet; + push @cc, $addr; } - elsif (/^Content-type:/i) { - $has_content_type = 1; - if (/charset="?([^ "]+)/) { - $body_encoding = $1; - } - push @xh, $_; - } - elsif (/^Message-Id: (.*)/i) { - $message_id = $1; - } - elsif (!/^Date:\s/ && /^[-A-Za-z]+:\s+\S/) { - push @xh, $_; - } - - } else { - # In the traditional - # "send lots of email" format, - # line 1 = cc - # line 2 = subject - # So let's support that, too. - $input_format = 'lots'; - if (@cc == 0 && !$suppress_cc{'cc'}) { - printf("(non-mbox) Adding cc: %s from line '%s'\n", - $_, $_) unless $quiet; - - push @cc, $_; - - } elsif (!defined $subject) { - $subject = $_; + } + elsif (/^Content-type:/i) { + $has_content_type = 1; + if (/charset="?([^ "]+)/) { + $body_encoding = $1; } + push @xh, $_; } - - # A whitespace line will terminate the headers - if (m/^\s*$/) { - $header_done = 1; + elsif (/^Message-Id: (.*)/i) { + $message_id = $1; } + elsif (!/^Date:\s/ && /^[-A-Za-z]+:\s+\S/) { + push @xh, $_; + } + } else { - $message .= $_; - if (/^(Signed-off-by|Cc): (.*)$/i) { - next if ($suppress_cc{'sob'}); - chomp; - my $c = $2; - chomp $c; - next if ($c eq $sender and $suppress_cc{'self'}); - push @cc, $c; - printf("(sob) Adding cc: %s from line '%s'\n", - $c, $_) unless $quiet; + # In the traditional + # "send lots of email" format, + # line 1 = cc + # line 2 = subject + # So let's support that, too. + $input_format = 'lots'; + if (@cc == 0 && !$suppress_cc{'cc'}) { + printf("(non-mbox) Adding cc: %s from line '%s'\n", + $_, $_) unless $quiet; + push @cc, $_; + } elsif (!defined $subject) { + $subject = $_; } } } + # Now parse the message body + while() { + $message .= $_; + if (/^(Signed-off-by|Cc): (.*)$/i) { + next if ($suppress_cc{'sob'}); + chomp; + my $c = $2; + chomp $c; + next if ($c eq $sender and $suppress_cc{'self'}); + push @cc, $c; + printf("(sob) Adding cc: %s from line '%s'\n", + $c, $_) unless $quiet; + } + } close F; if (defined $cc_cmd && !$suppress_cc{'cccmd'}) { @@ -1029,7 +1048,7 @@ foreach my $t (@files) { or die "(cc-cmd) failed to close pipe to '$cc_cmd'"; } - if (defined $author) { + if (defined $author and $author ne $sender) { $message = "From: $author\n\n$message"; if (defined $author_encoding) { if ($has_content_type) { -- cgit v1.2.1 From 3531e2703d8e441bfb4a6765459317b3db3f224c Mon Sep 17 00:00:00 2001 From: Jay Soffian Date: Sat, 14 Feb 2009 23:32:15 -0500 Subject: send-email: --suppress-cc improvements Since 6564828 (git-send-email: Generalize auto-cc recipient mechanism., 2007-12-25) we can suppress automatic Cc generation separately for each of the possible address sources. However, --suppress-cc=sob suppressed both SOB lines and body (but not header) Cc lines, contrary to the name. Change --suppress-cc=sob to mean only SOB lines, and add separate choices 'bodycc' (body Cc lines) and 'body' (both 'sob' and 'bodycc'). The option --no-signed-off-by-cc now acts like --suppress-cc=sob, which is not backwards compatible but matches the name of the option. Also update the documentation and add a few tests. Original patch by me. Revised by Thomas Rast, who contributed the documentation and test updates. Signed-off-by: Jay Soffian Signed-off-by: Junio C Hamano --- git-send-email.perl | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index a6efd1fa2..54e76173f 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -68,9 +68,8 @@ git send-email [options] Automating: --identity * Use the sendemail. options. --cc-cmd * Email Cc: via ` \$patch_path` - --suppress-cc * author, self, sob, cccmd, all. - --[no-]signed-off-by-cc * Send to Cc: and Signed-off-by: - addresses. Default on. + --suppress-cc * author, self, sob, cc, cccmd, body, bodycc, all. + --[no-]signed-off-by-cc * Send to Signed-off-by: addresses. Default on. --[no-]suppress-from * Send to self. Default off. --[no-]chain-reply-to * Chain In-Reply-To: fields. Default on. --[no-]thread * Use In-Reply-To: field. Default on. @@ -325,13 +324,13 @@ my(%suppress_cc); if (@suppress_cc) { foreach my $entry (@suppress_cc) { die "Unknown --suppress-cc field: '$entry'\n" - unless $entry =~ /^(all|cccmd|cc|author|self|sob)$/; + unless $entry =~ /^(all|cccmd|cc|author|self|sob|body|bodycc)$/; $suppress_cc{$entry} = 1; } } if ($suppress_cc{'all'}) { - foreach my $entry (qw (ccmd cc author self sob)) { + foreach my $entry (qw (ccmd cc author self sob body bodycc)) { $suppress_cc{$entry} = 1; } delete $suppress_cc{'all'}; @@ -341,6 +340,13 @@ if ($suppress_cc{'all'}) { $suppress_cc{'self'} = $suppress_from if defined $suppress_from; $suppress_cc{'sob'} = !$signed_off_by_cc if defined $signed_off_by_cc; +if ($suppress_cc{'body'}) { + foreach my $entry (qw (sob bodycc)) { + $suppress_cc{$entry} = 1; + } + delete $suppress_cc{'body'}; +} + # Debugging, print out the suppressions. if (0) { print "suppressions:\n"; @@ -1020,13 +1026,17 @@ foreach my $t (@files) { while() { $message .= $_; if (/^(Signed-off-by|Cc): (.*)$/i) { - next if ($suppress_cc{'sob'}); chomp; - my $c = $2; + my ($what, $c) = ($1, $2); chomp $c; - next if ($c eq $sender and $suppress_cc{'self'}); + if ($c eq $sender) { + next if ($suppress_cc{'self'}); + } else { + next if $suppress_cc{'sob'} and $what =~ /Signed-off-by/i; + next if $suppress_cc{'bodycc'} and $what =~ /Cc/i; + } push @cc, $c; - printf("(sob) Adding cc: %s from line '%s'\n", + printf("(body) Adding cc: %s from line '%s'\n", $c, $_) unless $quiet; } } -- cgit v1.2.1 From afe756c936334a5a374a8e0e8ee70a7f319dd71b Mon Sep 17 00:00:00 2001 From: Jay Soffian Date: Mon, 23 Feb 2009 13:51:37 -0500 Subject: send-email: don't create temporary compose file until it is needed Commit eed6ca7 caused a minor regression when it switched to using tempfile() to generate the temporary compose file. Since tempfile() creates the file at the time it generates the filename, zero-length temporary files are being left behind unless --compose is used (in which case the file is cleaned up). This patch fixes the regression by not calling tempfile() to generate the compose filename unless --compose is in use. Signed-off-by: Jay Soffian Signed-off-by: Junio C Hamano --- git-send-email.perl | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 54e76173f..adf7ecb5c 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -156,10 +156,7 @@ if ($@) { # Behavior modification variables my ($quiet, $dry_run) = (0, 0); my $format_patch; -my $compose_filename = ($repo ? - tempfile(".gitsendemail.msg.XXXXXX", DIR => $repo->repo_path()) : - tempfile(".gitsendemail.msg.XXXXXX", DIR => "."))[1]; - +my $compose_filename; # Handle interactive edition of files. my $multiedit; @@ -222,11 +219,13 @@ sub signal_handler { system "stty echo"; # tmp files from --compose - if (-e $compose_filename) { - print "'$compose_filename' contains an intermediate version of the email you were composing.\n"; - } - if (-e ($compose_filename . ".final")) { - print "'$compose_filename.final' contains the composed email.\n" + if (defined $compose_filename) { + if (-e $compose_filename) { + print "'$compose_filename' contains an intermediate version of the email you were composing.\n"; + } + if (-e ($compose_filename . ".final")) { + print "'$compose_filename.final' contains the composed email.\n" + } } exit; @@ -505,6 +504,9 @@ sub get_patch_subject($) { if ($compose) { # Note that this does not need to be secure, but we will make a small # effort to have it be unique + $compose_filename = ($repo ? + tempfile(".gitsendemail.msg.XXXXXX", DIR => $repo->repo_path()) : + tempfile(".gitsendemail.msg.XXXXXX", DIR => "."))[1]; open(C,">",$compose_filename) or die "Failed to open for writing $compose_filename: $!"; -- cgit v1.2.1 From 3e0c4ffdbddf1b3f84e0b8aa70e3b2fff68a56c5 Mon Sep 17 00:00:00 2001 From: Thomas Rast Date: Sun, 1 Mar 2009 23:45:41 +0100 Subject: send-email: respect in-reply-to regardless of threading git-send-email supports the --in-reply-to option even with --no-thread. However, the code that adds the relevant mail headers was guarded by a test for --thread. Remove the test, so that the user's choice is respected. Signed-off-by: Thomas Rast Signed-off-by: Junio C Hamano --- git-send-email.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 449d938ba..734dc9f4f 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -727,7 +727,7 @@ Date: $date Message-Id: $message_id X-Mailer: git-send-email $gitversion "; - if ($thread && $reply_to) { + if ($reply_to) { $header .= "In-Reply-To: $reply_to\n"; $header .= "References: $references\n"; -- cgit v1.2.1 From c1f2aa45b7bdb82c4378443ae23ad9625e782fe2 Mon Sep 17 00:00:00 2001 From: Jay Soffian Date: Mon, 2 Mar 2009 23:52:18 -0500 Subject: send-email: add --confirm option and configuration setting send-email violates the principle of least surprise by automatically cc'ing additional recipients without confirming this with the user. This patch teaches send-email a --confirm option. It takes the following values: --confirm=always always confirm before sending --confirm=never never confirm before sending --confirm=cc confirm before sending when send-email has automatically added addresses from the patch to the Cc list --confirm=compose confirm before sending the first message when using --compose. (Needed to maintain backwards compatibility with existing behavior.) --confirm=auto 'cc' + 'compose' If sendemail.confirm is unconfigured, the option defaults to 'compose' if any suppress-Cc related options have been used, otherwise it defaults to 'auto'. Unfortunately, it is impossible to introduce this patch such that it helps new users without potentially annoying some existing users. We attempt to mitigate the latter by: * Allowing the user to set 'git config sendemail.confirm never' * Allowing the user to say 'all' after the first prompt to not be prompted on remaining emails during the same invocation. * Telling the user about the 'sendemail.confirm' setting if it is unconfigured whenever we prompt due to Cc before sending. * Only prompting if no --suppress related options have been passed, as using such an option is likely to indicate an experienced send-email user. There is a slight fib in message informing the user of the sendemail.confirm setting and this is intentional. Setting 'auto' differs from leaving sendemail.confirm unset in two ways: 1) 'auto' obviously squelches the informational message; 2) 'auto' prompts when the Cc list has been expanded even in the presence of a --suppress related option, where leaving sendemail.confirm unset does not. This is intentional to keep the message simple, and to avoid adding another sendemail.confirm value ('auto-except-suppress'?). Signed-off-by: Jay Soffian Signed-off-by: Junio C Hamano --- git-send-email.perl | 84 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 61 insertions(+), 23 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index adf7ecb5c..57127aa82 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -75,6 +75,8 @@ git send-email [options] --[no-]thread * Use In-Reply-To: field. Default on. Administering: + --confirm * Confirm recipients before sending; + auto, cc, compose, always, or never. --quiet * Output one line of info per email. --dry-run * Don't actually send the emails. --[no-]validate * Perform patch sanity checks. Default on. @@ -181,7 +183,7 @@ sub do_edit { my ($thread, $chain_reply_to, $suppress_from, $signed_off_by_cc, $cc_cmd); my ($smtp_server, $smtp_server_port, $smtp_authuser, $smtp_encryption); my ($identity, $aliasfiletype, @alias_files, @smtp_host_parts); -my ($validate); +my ($validate, $confirm); my (@suppress_cc); my %config_bool_settings = ( @@ -207,6 +209,7 @@ my %config_settings = ( "suppresscc" => \@suppress_cc, "envelopesender" => \$envelope_sender, "multiedit" => \$multiedit, + "confirm" => \$confirm, ); # Handle Uncouth Termination @@ -258,6 +261,7 @@ my $rc = GetOptions("sender|from=s" => \$sender, "suppress-from!" => \$suppress_from, "suppress-cc=s" => \@suppress_cc, "signed-off-cc|signed-off-by-cc!" => \$signed_off_by_cc, + "confirm=s" => \$confirm, "dry-run" => \$dry_run, "envelope-sender=s" => \$envelope_sender, "thread!" => \$thread, @@ -346,6 +350,14 @@ if ($suppress_cc{'body'}) { delete $suppress_cc{'body'}; } +# Set confirm's default value +my $confirm_unconfigured = !defined $confirm; +if ($confirm_unconfigured) { + $confirm = scalar %suppress_cc ? 'compose' : 'auto'; +}; +die "Unknown --confirm setting: '$confirm'\n" + unless $confirm =~ /^(?:auto|cc|compose|always|never)/; + # Debugging, print out the suppressions. if (0) { print "suppressions:\n"; @@ -663,25 +675,13 @@ if (!defined $smtp_server) { $smtp_server ||= 'localhost'; # could be 127.0.0.1, too... *shrug* } -if ($compose) { - while (1) { - $_ = $term->readline("Send this email? (y|n) "); - last if defined $_; - print "\n"; - } - - if (uc substr($_,0,1) ne 'Y') { - cleanup_compose_files(); - exit(0); - } - - if ($compose > 0) { - @files = ($compose_filename . ".final", @files); - } +if ($compose && $compose > 0) { + @files = ($compose_filename . ".final", @files); } # Variables we set as part of the loop over files -our ($message_id, %mail, $subject, $reply_to, $references, $message); +our ($message_id, %mail, $subject, $reply_to, $references, $message, + $needs_confirm, $message_num); sub extract_valid_address { my $address = shift; @@ -837,6 +837,37 @@ X-Mailer: git-send-email $gitversion unshift (@sendmail_parameters, '-f', $raw_from) if(defined $envelope_sender); + if ($needs_confirm && !$dry_run) { + print "\n$header\n"; + if ($needs_confirm eq "inform") { + $confirm_unconfigured = 0; # squelch this message for the rest of this run + print " The Cc list above has been expanded by additional\n"; + print " addresses found in the patch commit message. By default\n"; + print " send-email prompts before sending whenever this occurs.\n"; + print " This behavior is controlled by the sendemail.confirm\n"; + print " configuration setting.\n"; + print "\n"; + print " For additional information, run 'git send-email --help'.\n"; + print " To retain the current behavior, but squelch this message,\n"; + print " run 'git config --global sendemail.confirm auto'.\n\n"; + } + while (1) { + chomp ($_ = $term->readline( + "Send this email? ([y]es|[n]o|[q]uit|[a]ll): " + )); + last if /^(?:yes|y|no|n|quit|q|all|a)/i; + print "\n"; + } + if (/^n/i) { + return; + } elsif (/^q/i) { + cleanup_compose_files(); + exit(0); + } elsif (/^a/i) { + $confirm = 'never'; + } + } + if ($dry_run) { # We don't want to send the email. } elsif ($smtp_server =~ m#^/#) { @@ -935,6 +966,7 @@ X-Mailer: git-send-email $gitversion $reply_to = $initial_reply_to; $references = $initial_reply_to || ''; $subject = $initial_subject; +$message_num = 0; foreach my $t (@files) { open(F,"<",$t) or die "can't open file $t"; @@ -943,11 +975,12 @@ foreach my $t (@files) { my $author_encoding; my $has_content_type; my $body_encoding; - @cc = @initial_cc; + @cc = (); @xh = (); my $input_format = undef; my @header = (); $message = ""; + $message_num++; # First unfold multiline header fields while() { last if /^\s*$/; @@ -1080,6 +1113,14 @@ foreach my $t (@files) { } } + $needs_confirm = ( + $confirm eq "always" or + ($confirm =~ /^(?:auto|cc)$/ && @cc) or + ($confirm =~ /^(?:auto|compose)$/ && $compose && $message_num == 1)); + $needs_confirm = "inform" if ($needs_confirm && $confirm_unconfigured && @cc); + + @cc = (@initial_cc, @cc); + send_message(); # set up for the next message @@ -1094,13 +1135,10 @@ foreach my $t (@files) { $message_id = undef; } -if ($compose) { - cleanup_compose_files(); -} +cleanup_compose_files(); sub cleanup_compose_files() { - unlink($compose_filename, $compose_filename . ".final"); - + unlink($compose_filename, $compose_filename . ".final") if $compose; } $smtp->quit if $smtp; -- cgit v1.2.1 From 6e1825186bd052fc1f77b7c8c9a31fbb9a67d90c Mon Sep 17 00:00:00 2001 From: Jay Soffian Date: Sat, 28 Mar 2009 21:39:10 -0400 Subject: send-email: refactor and ensure prompting doesn't loop forever Several places in send-email prompt for input, and will do so forever when the input is EOF. This is poor behavior when send-email is run unattended (say from cron). This patch refactors the prompting to an ask() function which takes a prompt, an optional default, and an optional regex to validate the input. The function returns on EOF, or if a default is provided and the user simply types return, or if the input passes the validating regex (which accepts all input by default). The ask() function gives up after 10 tries in case of invalid input. There are four callers of the function: 1) "Who should the emails appear to be from?" which provides a default sender. Previously the user would have to type ctrl-d to accept the default. Now the user can just hit return, or type ctrl-d. 2) "Who should the emails be sent to?". Previously this prompt passed a second argument ("") to $term->readline() which was ignored. I believe the intent was to allow the user to just hit return. Now the user can do so, or type ctrl-d. 3) "Message-ID to be used as In-Reply-To for the first email?". Previously this prompt passed a second argument (effectively undef) to $term->readline() which was ignored. I believe the intent was the same as for (2), to allow the user to just hit return. Now the user can do so, or type ctrl-d. 4) "Send this email?". Previously this prompt would loop forever until it got a valid reply. Now it stops prompting on EOF or a valid reply. In the case where confirm = "inform", it now defaults to "y" on EOF or the user hitting return, otherwise an invalid reply causes send-email to terminate. A followup patch adds tests for the new functionality. Signed-off-by: Jay Soffian Signed-off-by: Junio C Hamano --- git-send-email.perl | 66 +++++++++++++++++++++++++++-------------------------- 1 file changed, 34 insertions(+), 32 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 546d2ebc0..5916c86b6 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -606,32 +606,40 @@ EOT do_edit(@files); } +sub ask { + my ($prompt, %arg) = @_; + my $valid_re = $arg{valid_re} || ""; # "" matches anything + my $default = $arg{default}; + my $resp; + my $i = 0; + while ($i++ < 10) { + $resp = $term->readline($prompt); + if (!defined $resp) { # EOF + print "\n"; + return defined $default ? $default : undef; + } + if ($resp eq '' and defined $default) { + return $default; + } + if ($resp =~ /$valid_re/) { + return $resp; + } + } + return undef; +} + my $prompting = 0; if (!defined $sender) { $sender = $repoauthor || $repocommitter || ''; - - while (1) { - $_ = $term->readline("Who should the emails appear to be from? [$sender] "); - last if defined $_; - print "\n"; - } - - $sender = $_ if ($_); + $sender = ask("Who should the emails appear to be from? [$sender] ", + default => $sender); print "Emails will be sent from: ", $sender, "\n"; $prompting++; } if (!@to) { - - - while (1) { - $_ = $term->readline("Who should the emails be sent to? ", ""); - last if defined $_; - print "\n"; - } - - my $to = $_; - push @to, parse_address_line($to); + my $to = ask("Who should the emails be sent to? "); + push @to, parse_address_line($to) if defined $to; # sanitized/validated later $prompting++; } @@ -651,13 +659,8 @@ sub expand_aliases { @bcclist = expand_aliases(@bcclist); if ($thread && !defined $initial_reply_to && $prompting) { - while (1) { - $_= $term->readline("Message-ID to be used as In-Reply-To for the first email? ", $initial_reply_to); - last if defined $_; - print "\n"; - } - - $initial_reply_to = $_; + $initial_reply_to = ask( + "Message-ID to be used as In-Reply-To for the first email? "); } if (defined $initial_reply_to) { $initial_reply_to =~ s/^\s*readline( - "Send this email? ([y]es|[n]o|[q]uit|[a]ll): " - )); - last if /^(?:yes|y|no|n|quit|q|all|a)/i; - print "\n"; - } + $_ = ask("Send this email? ([y]es|[n]o|[q]uit|[a]ll): ", + valid_re => qr/^(?:yes|y|no|n|quit|q|all|a)/i, + default => $ask_default); + die "Send this email reply required" unless defined $_; if (/^n/i) { return; } elsif (/^q/i) { -- cgit v1.2.1 From 5906f54e474c6e8aabb0f6b955d446b509cde06e Mon Sep 17 00:00:00 2001 From: Jay Soffian Date: Tue, 31 Mar 2009 12:22:11 -0400 Subject: send-email: don't attempt to prompt if tty is closed Attempting to prompt when the tty is closed (typically when running from cron) is pointless and emits a warning. This patch causes ask() to return early, squelching the warning. Signed-off-by: Jay Soffian Signed-off-by: Junio C Hamano --- git-send-email.perl | 3 +++ 1 file changed, 3 insertions(+) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 5916c86b6..d790660bc 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -612,6 +612,9 @@ sub ask { my $default = $arg{default}; my $resp; my $i = 0; + return defined $default ? $default : undef + unless defined $term->IN and defined fileno($term->IN) and + defined $term->OUT and defined fileno($term->OUT); while ($i++ < 10) { $resp = $term->readline($prompt); if (!defined $resp) { # EOF -- cgit v1.2.1 From dc1460aa8de64f62b4612b6d2546ed7b88050de2 Mon Sep 17 00:00:00 2001 From: Jay Soffian Date: Tue, 31 Mar 2009 12:22:12 -0400 Subject: send-email: ask_default should apply to all emails, not just the first Commit 6e18251 made the "Send this email?" prompt assume yes if confirm = "inform" when it was unable to get a valid response. However, the "yes" assumption only worked correctly for the first email. This commit fixes the issue and confirms the fix by modifying the existing test for the prompt to send multiple emails. Reported by Matthieu Moy Signed-off-by: Jay Soffian Signed-off-by: Junio C Hamano --- git-send-email.perl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index d790660bc..fc153f945 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -687,7 +687,7 @@ if ($compose && $compose > 0) { # Variables we set as part of the loop over files our ($message_id, %mail, $subject, $reply_to, $references, $message, - $needs_confirm, $message_num); + $needs_confirm, $message_num, $ask_default); sub extract_valid_address { my $address = shift; @@ -845,7 +845,6 @@ X-Mailer: git-send-email $gitversion if ($needs_confirm && !$dry_run) { print "\n$header\n"; - my $ask_default; if ($needs_confirm eq "inform") { $confirm_unconfigured = 0; # squelch this message for the rest of this run $ask_default = "y"; # assume yes on EOF since user hasn't explicitly asked for confirmation -- cgit v1.2.1 From a61c0ffa4474ad6dcec18a5454630371106710f4 Mon Sep 17 00:00:00 2001 From: Jay Soffian Date: Tue, 31 Mar 2009 12:22:14 -0400 Subject: send-email: ensure quoted addresses are rfc2047 encoded sanitize_address assumes that quoted addresses (e.g., "first last" Signed-off-by: Junio C Hamano --- git-send-email.perl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index fc153f945..6bbdfec84 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -776,12 +776,13 @@ sub sanitize_address } # if recipient_name is already quoted, do nothing - if ($recipient_name =~ /^(".*"|=\?utf-8\?q\?.*\?=)$/) { + if ($recipient_name =~ /^("[[:ascii:]]*"|=\?utf-8\?q\?.*\?=)$/) { return $recipient; } # rfc2047 is needed if a non-ascii char is included if ($recipient_name =~ /[^[:ascii:]]/) { + $recipient_name =~ s/^"(.*)"$/$1/; $recipient_name = quote_rfc2047($recipient_name); } -- cgit v1.2.1 From 0da43a685aa061f55ed19ea30e1d6220020059a6 Mon Sep 17 00:00:00 2001 From: Jay Soffian Date: Sat, 4 Apr 2009 23:23:21 -0400 Subject: send-email: fix nasty bug in ask() function Commit 6e18251 (send-email: refactor and ensure prompting doesn't loop forever) introduced an ask function, which unfortunately had a nasty bug. This caused it not to accept anything but the default reply to the "Who should the emails appear to be from?" prompt, and nothing but ctrl-d to the "Who should the emails be sent to?" and "Message-ID to be used as In-Reply-To for the first email?" prompts. This commit corrects the issues and adds a test to confirm the fix. Signed-off-by: Jay Soffian Signed-off-by: Junio C Hamano --- git-send-email.perl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 6bbdfec84..172b53c2d 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -608,7 +608,7 @@ EOT sub ask { my ($prompt, %arg) = @_; - my $valid_re = $arg{valid_re} || ""; # "" matches anything + my $valid_re = $arg{valid_re}; my $default = $arg{default}; my $resp; my $i = 0; @@ -624,7 +624,7 @@ sub ask { if ($resp eq '' and defined $default) { return $default; } - if ($resp =~ /$valid_re/) { + if (!defined $valid_re or $resp =~ /$valid_re/) { return $resp; } } -- cgit v1.2.1 From 40e6e8a0c485e618be366f13247fd745ac00b911 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Mon, 13 Apr 2009 13:23:50 -0500 Subject: send-email: Handle "GIT:" rather than "GIT: " during --compose This should make things a little more robust in terms of user input; before, even the program got it wrong by outputting a line with only "GIT:", which was left in place as a header, because there would be no following space character. Signed-off-by: Michael Witten Signed-off-by: Junio C Hamano --- git-send-email.perl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 172b53c2d..7526ade76 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -529,7 +529,7 @@ if ($compose) { print C <) { - next if m/^GIT: /; + next if m/^GIT:/; if ($in_body) { $summary_empty = 0 unless (/^\n$/); } elsif (/^\n$/) { -- cgit v1.2.1 From 15da10843135490e12efca7f8bc806ae0bcf5c53 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Mon, 13 Apr 2009 13:23:51 -0500 Subject: send-email: 'References:' should only reference what is sent If someone responded with a negative (n|no) to the confirmation, then the Message-ID of the discarded email is no longer used in the References: header of subsequent emails. Consequently, send_message() now returns 1 if the message was sent and 0 otherwise. Signed-off-by: Michael Witten Signed-off-by: Junio C Hamano --- git-send-email.perl | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 7526ade76..43f956b78 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -796,6 +796,10 @@ sub sanitize_address } +# Returns 1 if the message was sent, and 0 otherwise. +# In actuality, the whole program dies when a there +# is an error sending a message. + sub send_message { my @recipients = unique_email_list(@to); @@ -864,7 +868,7 @@ X-Mailer: git-send-email $gitversion default => $ask_default); die "Send this email reply required" unless defined $_; if (/^n/i) { - return; + return 0; } elsif (/^q/i) { cleanup_compose_files(); exit(0); @@ -945,7 +949,7 @@ X-Mailer: git-send-email $gitversion $smtp->data or die $smtp->message; $smtp->datasend("$header\n$message") or die $smtp->message; $smtp->dataend() or die $smtp->message; - $smtp->ok or die "Failed to send $subject\n".$smtp->message; + $smtp->code =~ /250|200/ or die "Failed to send $subject\n".$smtp->message; } if ($quiet) { printf (($dry_run ? "Dry-" : "")."Sent %s\n", $subject); @@ -966,6 +970,8 @@ X-Mailer: git-send-email $gitversion print "Result: OK\n"; } } + + return 1; } $reply_to = $initial_reply_to; @@ -1126,10 +1132,10 @@ foreach my $t (@files) { @cc = (@initial_cc, @cc); - send_message(); + my $message_was_sent = send_message(); # set up for the next message - if ($chain_reply_to || !defined $reply_to || length($reply_to) == 0) { + if ($message_was_sent and $chain_reply_to || not defined $reply_to || length($reply_to) == 0) { $reply_to = $message_id; if (length $references > 0) { $references .= "\n $message_id"; -- cgit v1.2.1 From bec99cfc679b8c754ddd03feeb691b4c054ccc6a Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Mon, 13 Apr 2009 13:23:52 -0500 Subject: send-email: Remove superfluous `my $editor = ...' Not only was it a repeat, but it also had no effect. Signed-off-by: Michael Witten Signed-off-by: Junio C Hamano --- git-send-email.perl | 2 -- 1 file changed, 2 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 43f956b78..04267c58d 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -544,8 +544,6 @@ EOT } close(C); - my $editor = $ENV{GIT_EDITOR} || Git::config(@repo, "core.editor") || $ENV{VISUAL} || $ENV{EDITOR} || "vi"; - if ($annotate) { do_edit($compose_filename, @files); } else { -- cgit v1.2.1 From 7613ea3595f3a56f0f9d827944775940f1e72ef6 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Wed, 22 Apr 2009 09:41:29 -0400 Subject: Add parsing of elm aliases to git-send-email elm stores a text file version of the aliases that is = = This adds the parsing of this file to git-send-email Signed-off-by: Bill Pemberton Signed-off-by: Junio C Hamano --- git-send-email.perl | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 172b53c2d..cccbf4517 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -418,6 +418,14 @@ my %parse_alias = ( $x =~ /^(\S+)$f\t\(?([^\t]+?)\)?(:?$f){0,2}$/ or next; $aliases{$1} = [ split_addrs($2) ]; }}, + elm => sub { my $fh = shift; + while (<$fh>) { + if (/^(\S+)\s+=\s+[^=]+=\s(\S+)/) { + my ($alias, $addr) = ($1, $2); + $aliases{$alias} = [ split_addrs($addr) ]; + } + } }, + gnus => sub { my $fh = shift; while (<$fh>) { if (/\(define-mail-alias\s+"(\S+?)"\s+"(\S+?)"\)/) { $aliases{$1} = [ $2 ]; -- cgit v1.2.1 From 09caa24facae88e19cce1c12f21dac935cbf0909 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Tue, 12 May 2009 15:48:56 -0700 Subject: send-email: Add config option for sender address The sender address, as specified with the '--from' command line option, couldn't be set in the config file. So add a new config option, 'sendemail.from', which sets it. One can use 'sendemail..from' as well of course, which is likely the more useful case. The sender address would default to GIT_AUTHOR_IDENT, which is usually the right thing, but this doesn't allow switching based on the identity selected. It's possible to switch the SMTP server and envelope sender by using the '--identity' option, in which case one probably wants to use a different from address as well, but this had to be manually specified. The documentation for 'from' is also corrected somewhat. If '--from' is specified (or the new sendemail.from option is used) then the user isn't prompted. The default with no '--from' option (or sendemail.from option) is GIT_AUTHOR_IDENT first then GIT_COMMITTER_IDENT, not just GIT_COMMITTER_IDENT. Signed-off-by: Trent Piepho Signed-off-by: Junio C Hamano --- git-send-email.perl | 1 + 1 file changed, 1 insertion(+) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index cccbf4517..d9c7f32aa 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -210,6 +210,7 @@ my %config_settings = ( "envelopesender" => \$envelope_sender, "multiedit" => \$multiedit, "confirm" => \$confirm, + "from" => \$sender, ); # Handle Uncouth Termination -- cgit v1.2.1 From fe87c92138d91e2002c46b06f8389814436de1cf Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Wed, 20 May 2009 19:45:53 -0700 Subject: git-send-email: Handle quotes when parsing .mailrc files It is legal and not uncommon to use quotes in a .mailrc file so you can include a persons fullname as well as their email alias. Handle this by using quotewords instead of split when parsing .mailrc files. Signed-off-by: Eric W. Biederman Signed-off-by: Junio C Hamano --- git-send-email.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index cccbf4517..e3408d513 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -409,7 +409,7 @@ my %parse_alias = ( mailrc => sub { my $fh = shift; while (<$fh>) { if (/^alias\s+(\S+)\s+(.*)$/) { # spaces delimit multiple addresses - $aliases{$1} = [ split(/\s+/, $2) ]; + $aliases{$1} = [ quotewords('\s+', 0, $2) ]; }}}, pine => sub { my $fh = shift; my $f='\t[^\t]*'; for (my $x = ''; defined($x); $x = $_) { -- cgit v1.2.1 From a3a8262bf6e2acbb1b61cc25be073713e183c766 Mon Sep 17 00:00:00 2001 From: Brandon Casey Date: Sun, 7 Jun 2009 19:25:58 -0500 Subject: git-send-email.perl: improve detection of MIME encoded-words According to rfc2047, an encoded word has the following form: encoded-word = "=?" charset "?" encoding "?" encoded-text "?=" charset = token encoding = token token = especials = "(" / ")" / "<" / ">" / "@" / "," / ";" / ":" / " <"> / "/" / "[" / "]" / "?" / "." / "=" encoded-text = And rfc822 defines CHARs and CTLs as: CHAR = ; ( 0-177, 0.-127.) CTL = ; ( 177, 127.) The original code only detected rfc2047 encoded strings when the charset was UTF-8. This patch generalizes the matching expression and breaks the check for an rfc2047 encoded string into its own function. There's no real functional change, since any properly rfc2047 encoded string would have fallen through the remaining 'if' statements and been returned unchanged. Signed-off-by: Brandon Casey Signed-off-by: Junio C Hamano --- git-send-email.perl | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 3d6a98218..8a1a40d18 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -772,6 +772,14 @@ sub quote_rfc2047 { return $_; } +sub is_rfc2047_quoted { + my $s = shift; + my $token = '[^][()<>@,;:"\/?.= \000-\037\177-\377]+'; + my $encoded_text = '[!->@-~]+'; + length($s) <= 75 && + $s =~ m/^(?:"[[:ascii:]]*"|=\?$token\?$token\?$encoded_text\?=)$/o; +} + # use the simplest quoting being able to handle the recipient sub sanitize_address { @@ -783,7 +791,7 @@ sub sanitize_address } # if recipient_name is already quoted, do nothing - if ($recipient_name =~ /^("[[:ascii:]]*"|=\?utf-8\?q\?.*\?=)$/) { + if (is_rfc2047_quoted($recipient_name)) { return $recipient; } -- cgit v1.2.1 From d1fff6fce0e065d1dbb1450146a6f6f79b349229 Mon Sep 17 00:00:00 2001 From: Brandon Casey Date: Sat, 6 Jun 2009 20:12:31 -0500 Subject: send-email: use UTF-8 rather than utf-8 for consistency The rest of the git source has been converted to use upper-case character encoding names to assist older platforms. The charset attribute of MIME is defined to be case-insensitive, but older platforms may still have an easier time dealing with upper-case rather than lower-case. So do so for send-email too. Update t9001 to handle the changes. Signed-off-by: Brandon Casey Signed-off-by: Junio C Hamano --- git-send-email.perl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 8a1a40d18..4c795a4b0 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -577,7 +577,7 @@ EOT if ($need_8bit_cte) { print C2 "MIME-Version: 1.0\n", "Content-Type: text/plain; ", - "charset=utf-8\n", + "charset=UTF-8\n", "Content-Transfer-Encoding: 8bit\n"; } } elsif (/^MIME-Version:/i) { @@ -766,7 +766,7 @@ sub unquote_rfc2047 { sub quote_rfc2047 { local $_ = shift; - my $encoding = shift || 'utf-8'; + my $encoding = shift || 'UTF-8'; s/([^-a-zA-Z0-9!*+\/])/sprintf("=%02X", ord($1))/eg; s/(.*)/=\?$encoding\?q\?$1\?=/; return $_; -- cgit v1.2.1 From 5e9758e2968238906c730c9c77ecc95c21e7495e Mon Sep 17 00:00:00 2001 From: Markus Heidelberg Date: Fri, 12 Jun 2009 12:51:38 +0200 Subject: send-email: fix non-threaded mails After commit 3e0c4ff (send-email: respect in-reply-to regardless of threading, 2009-03-01) the variable $thread was only used for prompting for an "In-Reply-To", but not for controlling whether the "In-Reply-To" and "References" fields should be written into the email. Thus these fields were always used beginning with the second mail and it was not possible to produce non-threaded mails anymore. However, a later commit 15da108 ("send-email: 'References:' should only reference what is sent", 2009-04-13) introduced a regression with the side effect to make non-threaded mails possible again, but only when --no-chain-reply-to was used. Signed-off-by: Markus Heidelberg Signed-off-by: Junio C Hamano --- git-send-email.perl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index cccbf4517..5d5169707 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -1137,7 +1137,8 @@ foreach my $t (@files) { send_message(); # set up for the next message - if ($chain_reply_to || !defined $reply_to || length($reply_to) == 0) { + if ($thread && + ($chain_reply_to || !defined $reply_to || length($reply_to) == 0)) { $reply_to = $message_id; if (length $references > 0) { $references .= "\n $message_id"; -- cgit v1.2.1 From f74fe34b96816bad1f568202ec51ef18ae7513b3 Mon Sep 17 00:00:00 2001 From: Markus Heidelberg Date: Fri, 12 Jun 2009 12:51:41 +0200 Subject: send-email: fix threaded mails without chain-reply-to An earlier commit 15da108 ("send-email: 'References:' should only reference what is sent", 2009-04-13) broke logic to set up threading information for the next message by rewriting "!" to "not" without understanding the precedence rules of the language. Namely, ! defined $reply_to || length($reply_to) == 0 was changed to not defined $reply_to || length($reply_to) == 0 which is not (defined $reply_to || length($reply_to) == 0) and different from what was intended, which is (not defined $reply_to) || (length($reply_to) == 0) Signed-off-by: Markus Heidelberg Signed-off-by: Junio C Hamano --- git-send-email.perl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 4c795a4b0..16d12e082 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -1150,7 +1150,8 @@ foreach my $t (@files) { my $message_was_sent = send_message(); # set up for the next message - if ($message_was_sent and $chain_reply_to || not defined $reply_to || length($reply_to) == 0) { + if ($message_was_sent && + ($chain_reply_to || !defined $reply_to || length($reply_to) == 0)) { $reply_to = $message_id; if (length $references > 0) { $references .= "\n $message_id"; -- cgit v1.2.1 From a1b5b371994beb044053da22ec4a9607630a83a2 Mon Sep 17 00:00:00 2001 From: Markus Heidelberg Date: Fri, 12 Jun 2009 12:51:42 +0200 Subject: send-email: fix a typo in a comment Signed-off-by: Markus Heidelberg Signed-off-by: Junio C Hamano --- git-send-email.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 16d12e082..4a77d445c 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -812,7 +812,7 @@ sub sanitize_address } # Returns 1 if the message was sent, and 0 otherwise. -# In actuality, the whole program dies when a there +# In actuality, the whole program dies when there # is an error sending a message. sub send_message -- cgit v1.2.1 From cb8a9bd518002dd4fb693df6230b4976bafc15e0 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 18 Jun 2009 14:31:32 +0200 Subject: Test cccmd in t9001-send-email.sh and fix some bugs For another patch series I'm working on I needed some tests for the cc-cmd feature of git-send-email. This patch adds 3 tests for the feature and for the possibility to specify --suppress-cc multiple times, and fixes two bugs. The first bug is that the --suppress-cc option for `cccmd' was misspelled as `ccmd' in the code. The second bug, which is actually found only with my other series, is that the argument to the cccmd is never quoted, so the cccmd would fail with patch file names containing a space. A third bug I fix (in the docs) is that the bodycc argument was actually spelled ccbody in the documentation and bash completion. Signed-off-by: Paolo Bonzini Cc: Markus Heidelberg Signed-off-by: Junio C Hamano --- git-send-email.perl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index 303e03a8c..8ce6f1fe5 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -334,7 +334,7 @@ if (@suppress_cc) { } if ($suppress_cc{'all'}) { - foreach my $entry (qw (ccmd cc author self sob body bodycc)) { + foreach my $entry (qw (cccmd cc author self sob body bodycc)) { $suppress_cc{$entry} = 1; } delete $suppress_cc{'all'}; @@ -1104,7 +1104,7 @@ foreach my $t (@files) { close F; if (defined $cc_cmd && !$suppress_cc{'cccmd'}) { - open(F, "$cc_cmd $t |") + open(F, "$cc_cmd \Q$t\E |") or die "(cc-cmd) Could not execute '$cc_cmd'"; while() { my $c = $_; -- cgit v1.2.1 From 302e04ea4d0c0414cedd716de882fa3dbe3480eb Mon Sep 17 00:00:00 2001 From: Jeff King Date: Thu, 23 Jul 2009 07:09:29 -0400 Subject: send-email: detect cycles in alias expansion With the previous code, an alias cycle like: $ echo 'alias a b' >aliases $ echo 'alias b a' >aliases $ git config sendemail.aliasesfile aliases $ git config sendemail.aliasfiletype mutt would put send-email into an infinite loop. This patch detects the situation and complains to the user. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- git-send-email.perl | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'git-send-email.perl') diff --git a/git-send-email.perl b/git-send-email.perl index cccbf4517..f299c2dba 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -655,13 +655,17 @@ if (!@to) { } sub expand_aliases { - my @cur = @_; - my @last; - do { - @last = @cur; - @cur = map { $aliases{$_} ? @{$aliases{$_}} : $_ } @last; - } while (join(',',@cur) ne join(',',@last)); - return @cur; + return map { expand_one_alias($_) } @_; +} + +my %EXPANDED_ALIASES; +sub expand_one_alias { + my $alias = shift; + if ($EXPANDED_ALIASES{$alias}) { + die "fatal: alias '$alias' expands to itself\n"; + } + local $EXPANDED_ALIASES{$alias} = 1; + return $aliases{$alias} ? expand_aliases(@{$aliases{$alias}}) : $alias; } @to = expand_aliases(@to); -- cgit v1.2.1