Skip to content

Commit beece9d

Browse files
MadCodergitster
authored andcommitted
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 <madcoder@debian.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 8fd5bb7 commit beece9d

File tree

2 files changed

+123
-73
lines changed

2 files changed

+123
-73
lines changed

Documentation/git-send-email.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,15 @@ The --cc option must be repeated for each user you want on the cc list.
4545
--compose::
4646
Use $GIT_EDITOR, core.editor, $VISUAL, or $EDITOR to edit an
4747
introductory message for the patch series.
48+
+
49+
When compose is in used, git send-email gets less interactive will use the
50+
values of the headers you set there. If the body of the email (what you type
51+
after the headers and a blank line) only contains blank (or GIT: prefixed)
52+
lines, the summary won't be sent, but git-send-email will still use the
53+
Headers values if you don't removed them.
54+
+
55+
If it wasn't able to see a header in the summary it will ask you about it
56+
interactively after quitting your editor.
4857

4958
--from::
5059
Specify the sender of the emails. This will default to

git-send-email.perl

Lines changed: 114 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -162,9 +162,17 @@ sub format_2822_time {
162162
my $editor = $ENV{GIT_EDITOR} || Git::config(@repo, "core.editor") || $ENV{VISUAL} || $ENV{EDITOR} || "vi";
163163
sub do_edit {
164164
if (defined($multiedit) && !$multiedit) {
165-
map { system('sh', '-c', $editor.' "$@"', $editor, $_); } @_;
165+
map {
166+
system('sh', '-c', $editor.' "$@"', $editor, $_);
167+
if (($? & 127) || ($? >> 8)) {
168+
die("the editor exited uncleanly, aborting everything");
169+
}
170+
} @_;
166171
} else {
167172
system('sh', '-c', $editor.' "$@"', $editor, @_);
173+
if (($? & 127) || ($? >> 8)) {
174+
die("the editor exited uncleanly, aborting everything");
175+
}
168176
}
169177
}
170178

@@ -450,6 +458,108 @@ ($)
450458
usage();
451459
}
452460

461+
sub get_patch_subject($) {
462+
my $fn = shift;
463+
open (my $fh, '<', $fn);
464+
while (my $line = <$fh>) {
465+
next unless ($line =~ /^Subject: (.*)$/);
466+
close $fh;
467+
return "GIT: $1\n";
468+
}
469+
close $fh;
470+
die "No subject line in $fn ?";
471+
}
472+
473+
if ($compose) {
474+
# Note that this does not need to be secure, but we will make a small
475+
# effort to have it be unique
476+
open(C,">",$compose_filename)
477+
or die "Failed to open for writing $compose_filename: $!";
478+
479+
480+
my $tpl_sender = $sender || $repoauthor || $repocommitter || '';
481+
my $tpl_subject = $initial_subject || '';
482+
my $tpl_reply_to = $initial_reply_to || '';
483+
484+
print C <<EOT;
485+
From $tpl_sender # This line is ignored.
486+
GIT: Lines beginning in "GIT: " will be removed.
487+
GIT: Consider including an overall diffstat or table of contents
488+
GIT: for the patch you are writing.
489+
GIT:
490+
GIT: Clear the body content if you don't wish to send a summary.
491+
From: $tpl_sender
492+
Subject: $tpl_subject
493+
In-Reply-To: $tpl_reply_to
494+
495+
EOT
496+
for my $f (@files) {
497+
print C get_patch_subject($f);
498+
}
499+
close(C);
500+
501+
my $editor = $ENV{GIT_EDITOR} || Git::config(@repo, "core.editor") || $ENV{VISUAL} || $ENV{EDITOR} || "vi";
502+
503+
if ($annotate) {
504+
do_edit($compose_filename, @files);
505+
} else {
506+
do_edit($compose_filename);
507+
}
508+
509+
open(C2,">",$compose_filename . ".final")
510+
or die "Failed to open $compose_filename.final : " . $!;
511+
512+
open(C,"<",$compose_filename)
513+
or die "Failed to open $compose_filename : " . $!;
514+
515+
my $need_8bit_cte = file_has_nonascii($compose_filename);
516+
my $in_body = 0;
517+
my $summary_empty = 1;
518+
while(<C>) {
519+
next if m/^GIT: /;
520+
if ($in_body) {
521+
$summary_empty = 0 unless (/^\n$/);
522+
} elsif (/^\n$/) {
523+
$in_body = 1;
524+
if ($need_8bit_cte) {
525+
print C2 "MIME-Version: 1.0\n",
526+
"Content-Type: text/plain; ",
527+
"charset=utf-8\n",
528+
"Content-Transfer-Encoding: 8bit\n";
529+
}
530+
} elsif (/^MIME-Version:/i) {
531+
$need_8bit_cte = 0;
532+
} elsif (/^Subject:\s*(.+)\s*$/i) {
533+
$initial_subject = $1;
534+
my $subject = $initial_subject;
535+
$_ = "Subject: " .
536+
($subject =~ /[^[:ascii:]]/ ?
537+
quote_rfc2047($subject) :
538+
$subject) .
539+
"\n";
540+
} elsif (/^In-Reply-To:\s*(.+)\s*$/i) {
541+
$initial_reply_to = $1;
542+
next;
543+
} elsif (/^From:\s*(.+)\s*$/i) {
544+
$sender = $1;
545+
next;
546+
} elsif (/^(?:To|Cc|Bcc):/i) {
547+
print "To/Cc/Bcc fields are not interpreted yet, they have been ignored\n";
548+
next;
549+
}
550+
print C2 $_;
551+
}
552+
close(C);
553+
close(C2);
554+
555+
if ($summary_empty) {
556+
print "Summary email is empty, skipping it\n";
557+
$compose = -1;
558+
}
559+
} elsif ($annotate) {
560+
do_edit(@files);
561+
}
562+
453563
my $prompting = 0;
454564
if (!defined $sender) {
455565
$sender = $repoauthor || $repocommitter || '';
@@ -494,17 +604,6 @@ sub expand_aliases {
494604
@initial_cc = expand_aliases(@initial_cc);
495605
@bcclist = expand_aliases(@bcclist);
496606

497-
if (!defined $initial_subject && $compose) {
498-
while (1) {
499-
$_ = $term->readline("What subject should the initial email start with? ", $initial_subject);
500-
last if defined $_;
501-
print "\n";
502-
}
503-
504-
$initial_subject = $_;
505-
$prompting++;
506-
}
507-
508607
if ($thread && !defined $initial_reply_to && $prompting) {
509608
while (1) {
510609
$_= $term->readline("Message-ID to be used as In-Reply-To for the first email? ", $initial_reply_to);
@@ -531,64 +630,6 @@ sub expand_aliases {
531630
}
532631

533632
if ($compose) {
534-
# Note that this does not need to be secure, but we will make a small
535-
# effort to have it be unique
536-
open(C,">",$compose_filename)
537-
or die "Failed to open for writing $compose_filename: $!";
538-
print C "From $sender # This line is ignored.\n";
539-
printf C "Subject: %s\n\n", $initial_subject;
540-
printf C <<EOT;
541-
GIT: Please enter your email below.
542-
GIT: Lines beginning in "GIT: " will be removed.
543-
GIT: Consider including an overall diffstat or table of contents
544-
GIT: for the patch you are writing.
545-
546-
EOT
547-
close(C);
548-
549-
my $editor = $ENV{GIT_EDITOR} || Git::config(@repo, "core.editor") || $ENV{VISUAL} || $ENV{EDITOR} || "vi";
550-
551-
if ($annotate) {
552-
do_edit($compose_filename, @files);
553-
} else {
554-
do_edit($compose_filename);
555-
}
556-
557-
open(C2,">",$compose_filename . ".final")
558-
or die "Failed to open $compose_filename.final : " . $!;
559-
560-
open(C,"<",$compose_filename)
561-
or die "Failed to open $compose_filename : " . $!;
562-
563-
my $need_8bit_cte = file_has_nonascii($compose_filename);
564-
my $in_body = 0;
565-
while(<C>) {
566-
next if m/^GIT: /;
567-
if (!$in_body && /^\n$/) {
568-
$in_body = 1;
569-
if ($need_8bit_cte) {
570-
print C2 "MIME-Version: 1.0\n",
571-
"Content-Type: text/plain; ",
572-
"charset=utf-8\n",
573-
"Content-Transfer-Encoding: 8bit\n";
574-
}
575-
}
576-
if (!$in_body && /^MIME-Version:/i) {
577-
$need_8bit_cte = 0;
578-
}
579-
if (!$in_body && /^Subject: ?(.*)/i) {
580-
my $subject = $1;
581-
$_ = "Subject: " .
582-
($subject =~ /[^[:ascii:]]/ ?
583-
quote_rfc2047($subject) :
584-
$subject) .
585-
"\n";
586-
}
587-
print C2 $_;
588-
}
589-
close(C);
590-
close(C2);
591-
592633
while (1) {
593634
$_ = $term->readline("Send this email? (y|n) ");
594635
last if defined $_;
@@ -600,9 +641,9 @@ sub expand_aliases {
600641
exit(0);
601642
}
602643

603-
@files = ($compose_filename . ".final", @files);
604-
} elsif ($annotate) {
605-
do_edit(@files);
644+
if ($compose > 0) {
645+
@files = ($compose_filename . ".final", @files);
646+
}
606647
}
607648

608649
# Variables we set as part of the loop over files

0 commit comments

Comments
 (0)