From: Jay Soffian <jaysoffian@gmail.com>
To: git@vger.kernel.org
Cc: Jay Soffian <jaysoffian@gmail.com>,
Nanako Shiraishi <nanako3@lavabit.com>,
Junio C Hamano <gitster@pobox.com>,
Paul Gortmaker <paul.gortmaker@windriver.com>
Subject: [PATCH] send-email: add --confirm option
Date: Sun, 1 Mar 2009 03:23:21 -0500 [thread overview]
Message-ID: <1235895801-80414-1-git-send-email-jaysoffian@gmail.com> (raw)
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'
The option defaults to 'compose' if any suppress Cc related options have
been used, otherwise it defaults to 'auto'.
Signed-off-by: Jay Soffian <jaysoffian@gmail.com>
---
Junio,
I based this on top of js/send-email.
j.
Documentation/git-send-email.txt | 16 ++++++++
git-send-email.perl | 68 +++++++++++++++++++++++------------
t/t9001-send-email.sh | 72 +++++++++++++++++++++++++++++--------
3 files changed, 117 insertions(+), 39 deletions(-)
diff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt
index 164d149..bcf7ff1 100644
--- a/Documentation/git-send-email.txt
+++ b/Documentation/git-send-email.txt
@@ -199,6 +199,22 @@ specified, as well as 'body' if --no-signed-off-cc is specified.
Administering
~~~~~~~~~~~~~
+--confirm::
+ Confirm just before sending:
++
+--
+- 'always' will always confirm before sending
+- 'never' will never confirm before sending
+- 'cc' will confirm before sending when send-email has automatically
+ added addresses from the patch to the Cc list
+- 'compose' will confirm before sending the first message when using --compose.
+- 'auto' is equivalent to 'cc' + 'compose'
+--
++
+Default is the value of 'sendemail.confirm' configuration value; if that
+is unspecified, default to 'auto' unless any of the suppress options
+have been specified, in which case default to 'compose'.
+
--dry-run::
Do everything except actually send the emails.
diff --git a/git-send-email.perl b/git-send-email.perl
index adf7ecb..a777e3f 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -75,6 +75,8 @@ git send-email [options] <file | directory | rev-list options >
--[no-]thread * Use In-Reply-To: field. Default on.
Administering:
+ --confirm <str> * 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,11 @@ if ($suppress_cc{'body'}) {
delete $suppress_cc{'body'};
}
+# Set confirm
+if (!defined $confirm) {
+ $confirm = scalar %suppress_cc ? 'compose' : 'auto';
+};
+
# Debugging, print out the suppressions.
if (0) {
print "suppressions:\n";
@@ -663,25 +672,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 +834,25 @@ 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";
+ 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 +951,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 +960,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(<F>) {
last if /^\s*$/;
@@ -1080,6 +1098,13 @@ foreach my $t (@files) {
}
}
+ $needs_confirm = (
+ $confirm eq "always" or
+ ($confirm =~ /^(?:auto|cc)$/ && @cc) or
+ ($confirm =~ /^(?:auto|compose)$/ && $compose && $message_num == 1));
+
+ @cc = (@initial_cc, @cc);
+
send_message();
# set up for the next message
@@ -1094,13 +1119,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;
diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh
index 4df4f96..2f4a654 100755
--- a/t/t9001-send-email.sh
+++ b/t/t9001-send-email.sh
@@ -31,6 +31,11 @@ clean_fake_sendmail() {
rm -f commandline* msgtxt*
}
+# Prevent any tests from hanging
+test_expect_success 'Set sendemail.confirm=never' '
+ git config sendemail.confirm never
+'
+
test_expect_success 'Extract patches' '
patches=`git format-patch -s --cc="One <one@example.com>" --cc=two@example.com -n HEAD^1`
'
@@ -175,15 +180,13 @@ test_set_editor "$(pwd)/fake-editor"
test_expect_success '--compose works' '
clean_fake_sendmail &&
- echo y | \
- GIT_SEND_EMAIL_NOTTY=1 \
- git send-email \
- --compose --subject foo \
- --from="Example <nobody@example.com>" \
- --to=nobody@example.com \
- --smtp-server="$(pwd)/fake.sendmail" \
- $patches \
- 2>errors
+ git send-email \
+ --compose --subject foo \
+ --from="Example <nobody@example.com>" \
+ --to=nobody@example.com \
+ --smtp-server="$(pwd)/fake.sendmail" \
+ $patches \
+ 2>errors
'
test_expect_success 'first message is compose text' '
@@ -375,15 +378,56 @@ test_expect_success '--suppress-cc=cc' '
test_suppression cc
'
+test_confirm () {
+ echo y | \
+ GIT_SEND_EMAIL_NOTTY=1 \
+ git send-email \
+ --from="Example <nobody@example.com>" \
+ --to=nobody@example.com \
+ --smtp-server="$(pwd)/fake.sendmail" \
+ $@ \
+ $patches | grep "Send this email"
+}
+
+test_expect_success '--confirm=always' '
+ test_confirm --confirm=always --suppress-cc=all
+'
+
+test_expect_success '--confirm=auto' '
+ test_confirm --confirm=auto
+'
+
+test_expect_success '--confirm=cc' '
+ test_confirm --confirm=cc
+'
+
+test_expect_success '--confirm=compose' '
+ test_confirm --confirm=compose --compose
+'
+
+test_expect_success 'confirm by default (due to cc)' '
+ CONFIRM=$(git config --get sendemail.confirm) &&
+ git config --unset sendemail.confirm &&
+ test_confirm &&
+ git config sendemail.confirm $CONFIRM
+'
+
+test_expect_success 'confirm by default (due to --compose)' '
+ CONFIRM=$(git config --get sendemail.confirm) &&
+ git config --unset sendemail.confirm &&
+ test_confirm --suppress-cc=all --compose
+ ret="$?"
+ git config sendemail.confirm ${CONFIRM:-never}
+ test $ret = "0"
+'
+
test_expect_success '--compose adds MIME for utf8 body' '
clean_fake_sendmail &&
(echo "#!$SHELL_PATH" &&
echo "echo utf8 body: àéìöú >>\"\$1\""
) >fake-editor-utf8 &&
chmod +x fake-editor-utf8 &&
- echo y | \
GIT_EDITOR="\"$(pwd)/fake-editor-utf8\"" \
- GIT_SEND_EMAIL_NOTTY=1 \
git send-email \
--compose --subject foo \
--from="Example <nobody@example.com>" \
@@ -405,9 +449,7 @@ test_expect_success '--compose respects user mime type' '
echo " echo utf8 body: àéìöú) >\"\$1\""
) >fake-editor-utf8-mime &&
chmod +x fake-editor-utf8-mime &&
- echo y | \
GIT_EDITOR="\"$(pwd)/fake-editor-utf8-mime\"" \
- GIT_SEND_EMAIL_NOTTY=1 \
git send-email \
--compose --subject foo \
--from="Example <nobody@example.com>" \
@@ -421,9 +463,7 @@ test_expect_success '--compose respects user mime type' '
test_expect_success '--compose adds MIME for utf8 subject' '
clean_fake_sendmail &&
- echo y | \
GIT_EDITOR="\"$(pwd)/fake-editor\"" \
- GIT_SEND_EMAIL_NOTTY=1 \
git send-email \
--compose --subject utf8-sübjëct \
--from="Example <nobody@example.com>" \
@@ -445,7 +485,7 @@ test_expect_success 'detects ambiguous reference/file conflict' '
test_expect_success 'feed two files' '
rm -fr outdir &&
git format-patch -2 -o outdir &&
- GIT_SEND_EMAIL_NOTTY=1 git send-email \
+ git send-email \
--dry-run \
--from="Example <nobody@example.com>" \
--to=nobody@example.com \
--
1.6.2.rc1.309.g5f417
next reply other threads:[~2009-03-01 8:24 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-03-01 8:23 Jay Soffian [this message]
2009-03-01 9:03 ` [PATCH] send-email: add --confirm option Junio C Hamano
2009-03-01 14:05 ` Jay Soffian
2009-03-01 16:17 ` [PATCH v2] " Jay Soffian
2009-03-01 17:09 ` Paul Gortmaker
2009-03-01 17:49 ` Jay Soffian
2009-03-02 8:24 ` Nanako Shiraishi
2009-03-02 9:01 ` Junio C Hamano
2009-03-02 9:23 ` Nanako Shiraishi
2009-03-02 10:35 ` Felipe Contreras
2009-03-02 12:33 ` Jay Soffian
2009-03-02 7:34 ` Junio C Hamano
2009-03-02 12:35 ` Jay Soffian
2009-03-03 2:47 ` Junio C Hamano
2009-03-03 4:52 ` [PATCH v3] send-email: add --confirm option and configuration setting Jay Soffian
2009-03-03 6:53 ` Junio C Hamano
2009-03-03 10:11 ` Nanako Shiraishi
2009-03-03 11:54 ` Bert Wesarg
2009-03-03 16:22 ` Jay Soffian
2009-03-03 16:48 ` Junio C Hamano
2009-03-03 18:05 ` Bert Wesarg
2009-03-03 18:18 ` Jay Soffian
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1235895801-80414-1-git-send-email-jaysoffian@gmail.com \
--to=jaysoffian@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=nanako3@lavabit.com \
--cc=paul.gortmaker@windriver.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).