Code

Merge branch 'ph/send-email'
[git.git] / git-send-email.perl
index ccb3b1816c69f6c24c653e71c7978cc4b6b922c9..7508f8ff242854462d0b5b505621dd840b551641 100755 (executable)
@@ -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");
+               }
        }
 }
 
@@ -366,10 +374,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 ];
@@ -450,6 +461,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 <<EOT;
+From $tpl_sender # This line is ignored.
+GIT: Lines beginning in "GIT: " will be removed.
+GIT: Consider including an overall diffstat or table of contents
+GIT: for the patch you are writing.
+GIT:
+GIT: Clear the body content if you don't wish to send a summary.
+From: $tpl_sender
+Subject: $tpl_subject
+In-Reply-To: $tpl_reply_to
+
+EOT
+       for my $f (@files) {
+               print C get_patch_subject($f);
+       }
+       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 {
+               do_edit($compose_filename);
+       }
+
+       open(C2,">",$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(<C>) {
+               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 +607,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 +633,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 <<EOT;
-GIT: Please enter your email below.
-GIT: Lines beginning in "GIT: " will be removed.
-GIT: Consider including an overall diffstat or table of contents
-GIT: for the patch you are writing.
-
-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 {
-               do_edit($compose_filename);
-       }
-
-       open(C2,">",$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(<C>) {
-               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 +644,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