Skip to content

Commit

Permalink
git send-email: ask less questions when --compose is used.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Pierre Habouzit authored and Junio C Hamano committed Nov 12, 2008
1 parent 8fd5bb7 commit beece9d
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 73 deletions.
9 changes: 9 additions & 0 deletions Documentation/git-send-email.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,15 @@ The --cc option must be repeated for each user you want on the cc list.
--compose::
Use $GIT_EDITOR, core.editor, $VISUAL, or $EDITOR to edit an
introductory message for the patch series.
+
When compose is in used, git send-email gets less interactive will use the
values of the headers you set there. If the body of the email (what you type
after the headers and a blank line) only contains blank (or GIT: prefixed)
lines, the summary won't be sent, but git-send-email will still use the
Headers values if you don't removed them.
+
If it wasn't able to see a header in the summary it will ask you about it
interactively after quitting your editor.

--from::
Specify the sender of the emails. This will default to
Expand Down
187 changes: 114 additions & 73 deletions git-send-email.perl
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,17 @@ sub format_2822_time {
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");
}
}
}

Expand Down Expand Up @@ -450,6 +458,108 @@ ($)
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 || '';
Expand Down Expand Up @@ -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);
Expand All @@ -531,64 +630,6 @@ sub expand_aliases {
}

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 $_;
Expand All @@ -600,9 +641,9 @@ sub expand_aliases {
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
Expand Down

0 comments on commit beece9d

Please sign in to comment.