Merge branch 'mh/maint-fix-send-email-threaded' into mh/fix-send-email-threaded
authorJunio C Hamano <gitster@pobox.com>
Fri, 12 Jun 2009 16:23:43 +0000 (09:23 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 12 Jun 2009 16:23:43 +0000 (09:23 -0700)
* mh/maint-fix-send-email-threaded:
doc/send-email: clarify the behavior of --in-reply-to with --no-thread
send-email: fix non-threaded mails
add a test for git-send-email for non-threaded mails

Conflicts:
git-send-email.perl
t/t9001-send-email.sh

1  2 
Documentation/git-send-email.txt
git-send-email.perl
t/t9001-send-email.sh
index e7cb0e6c71e84c896ecf2d232c906c5cb0de6b08,0ec53431a5e6e4d40f52dcba5bd2d4c6cf1d587c..9902da43c7c24342346f2fcdce86c8db9411b28d
@@@ -43,10 -43,6 +43,10 @@@ OPTION
  Composing
  ~~~~~~~~~
  
 +--annotate::
 +      Review and edit each patch you're about to send. See the
 +      CONFIGURATION section for 'sendemail.multiedit'.
 +
  --bcc=<address>::
        Specify a "Bcc:" value for each email. Default is the value of
        'sendemail.bcc'.
@@@ -59,6 -55,11 +59,6 @@@ The --bcc option must be repeated for e
  +
  The --cc option must be repeated for each user you want on the cc list.
  
 ---annotate::
 -      Review each patch you're about to send in an editor. The setting
 -      'sendemail.multiedit' defines if this will spawn one editor per patch
 -      or one for all of them at once.
 -
  --compose::
        Use $GIT_EDITOR, core.editor, $VISUAL, or $EDITOR to edit an
        introductory message for the patch series.
@@@ -70,16 -71,11 +70,16 @@@ In-Reply-To headers specified in the me
  and In-Reply-To headers will be used unless they are removed.
  +
  Missing From or In-Reply-To headers will be prompted for.
 ++
 +See the CONFIGURATION section for 'sendemail.multiedit'.
  
  --from=<address>::
 -      Specify the sender of the emails.  This will default to
 -      the value GIT_COMMITTER_IDENT, as returned by "git var -l".
 -      The user will still be prompted to confirm this entry.
 +      Specify the sender of the emails.  If not specified on the command line,
 +      the value of the 'sendemail.from' configuration option is used.  If
 +      neither the command line option nor 'sendemail.from' are set, then the
 +      user will be prompted for the value.  The default for the prompt will be
 +      the value of GIT_AUTHOR_IDENT, or GIT_COMMITTER_IDENT if that is not
 +      set, as returned by "git var -l".
  
  --in-reply-to=<identifier>::
        Specify the contents of the first In-Reply-To header.
@@@ -143,9 -139,7 +143,9 @@@ user is prompted for a password while t
  --smtp-server-port=<port>::
        Specifies a port different from the default port (SMTP
        servers typically listen to smtp port 25 and ssmtp port
 -      465). This can be set with 'sendemail.smtpserverport'.
 +      465); symbolic port names (e.g. "submission" instead of 465)
 +      are also accepted. The port can also be set with the
 +      'sendemail.smtpserverport' configuration variable.
  
  --smtp-ssl::
        Legacy alias for '--smtp-encryption ssl'.
@@@ -165,7 -159,7 +165,7 @@@ Automatin
        Output of this command must be single email address per line.
        Default is the value of 'sendemail.cccmd' configuration value.
  
- --[no-]chain-reply-to=<identifier>::
+ --[no-]chain-reply-to::
        If this is set, each email will be sent as a reply to the previous
        email sent.  If disabled with "--no-chain-reply-to", all emails after
        the first will be sent as replies to the first email sent.  When using
@@@ -214,7 -208,8 +214,8 @@@ specified, as well as 'body' if --no-si
  --[no-]thread::
        If this is set, the In-Reply-To header will be set on each email sent.
        If disabled with "--no-thread", no emails will have the In-Reply-To
-       header set. Default is the value of the 'sendemail.thread' configuration
+       header set, unless specified with --in-reply-to.
+       Default is the value of the 'sendemail.thread' configuration
        value; if that is unspecified, default to --thread.
  
  
@@@ -240,12 -235,6 +241,12 @@@ have been specified, in which case defa
  --dry-run::
        Do everything except actually send the emails.
  
 +--[no-]format-patch::
 +      When an argument may be understood either as a reference or as a file name,
 +      choose to understand it as a format-patch argument ('--format-patch')
 +      or as a file name ('--no-format-patch'). By default, when such a conflict
 +      occurs, git send-email will fail.
 +
  --quiet::
        Make git-send-email less verbose.  One line per email should be
        all that is output.
  Default is the value of 'sendemail.validate'; if this is not set,
  default to '--validate'.
  
 ---[no-]format-patch::
 -      When an argument may be understood either as a reference or as a file name,
 -      choose to understand it as a format-patch argument ('--format-patch')
 -      or as a file name ('--no-format-patch'). By default, when such a conflict
 -      occurs, git send-email will fail.
 -
  
  CONFIGURATION
  -------------
diff --combined git-send-email.perl
index 4a77d445cd5e7c8ffe894da429b7e63ed7aabe8f,5d5169707b452836f3835069e4b015c45d3618af..303e03a8ce4031a1d9d6d00cb67abda1c30a63f3
@@@ -210,7 -210,6 +210,7 @@@ my %config_settings = 
      "envelopesender" => \$envelope_sender,
      "multiedit" => \$multiedit,
      "confirm"   => \$confirm,
 +    "from" => \$sender,
  );
  
  # Handle Uncouth Termination
@@@ -410,7 -409,7 +410,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 = $_) {
@@@ -538,7 -537,7 +538,7 @@@ if ($compose) 
  
        print C <<EOT;
  From $tpl_sender # This line is ignored.
 -GIT: Lines beginning in "GIT: " will be removed.
 +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:
@@@ -553,6 -552,8 +553,6 @@@ EO
        }
        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 {
        my $in_body = 0;
        my $summary_empty = 1;
        while(<C>) {
 -              next if m/^GIT: /;
 +              next if m/^GIT:/;
                if ($in_body) {
                        $summary_empty = 0 unless (/^\n$/);
                } elsif (/^\n$/) {
                        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,20 -767,12 +766,20 @@@ 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 $_;
  }
  
 +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
  {
        }
  
        # if recipient_name is already quoted, do nothing
 -      if ($recipient_name =~ /^("[[:ascii:]]*"|=\?utf-8\?q\?.*\?=)$/) {
 +      if (is_rfc2047_quoted($recipient_name)) {
                return $recipient;
        }
  
  
  }
  
 +# Returns 1 if the message was sent, and 0 otherwise.
 +# In actuality, the whole program dies when there
 +# is an error sending a message.
 +
  sub send_message
  {
        my @recipients = unique_email_list(@to);
@@@ -883,7 -872,7 +883,7 @@@ X-Mailer: git-send-email $gitversio
                         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);
                $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);
                        print "Result: OK\n";
                }
        }
 +
 +      return 1;
  }
  
  $reply_to = $initial_reply_to;
@@@ -1147,10 -1134,10 +1147,10 @@@ foreach my $t (@files) 
  
        @cc = (@initial_cc, @cc);
  
 -      send_message();
 +      my $message_was_sent = send_message();
  
        # set up for the next message
-       if ($message_was_sent &&
 -      if ($thread &&
++      if ($thread && $message_was_sent &&
                ($chain_reply_to || !defined $reply_to || length($reply_to) == 0)) {
                $reply_to = $message_id;
                if (length $references > 0) {
diff --combined t/t9001-send-email.sh
index 8ab1a78bf59e063ca57bcee0bbf26edba0bec9ce,8518acaca6ea01723bd2a2e36c90cae23f6fbdcb..9ce04fd47277e1641979eb583a95de41e2f75570
@@@ -533,7 -533,7 +533,7 @@@ test_expect_success 'utf8 Cc is rfc204
        --smtp-server="$(pwd)/fake.sendmail" \
        outdir/*.patch &&
        grep "^Cc:" msgtxt1 |
 -      grep "=?utf-8?q?=C3=A0=C3=A9=C3=AC=C3=B6=C3=BA?= <utf8@example.com>"
 +      grep "=?UTF-8?q?=C3=A0=C3=A9=C3=AC=C3=B6=C3=BA?= <utf8@example.com>"
  '
  
  test_expect_success '--compose adds MIME for utf8 body' '
          --smtp-server="$(pwd)/fake.sendmail" \
          $patches &&
        grep "^utf8 body" msgtxt1 &&
 -      grep "^Content-Type: text/plain; charset=utf-8" msgtxt1
 +      grep "^Content-Type: text/plain; charset=UTF-8" msgtxt1
  '
  
  test_expect_success '--compose respects user mime type' '
          $patches &&
        grep "^utf8 body" msgtxt1 &&
        grep "^Content-Type: text/plain; charset=iso-8859-1" msgtxt1 &&
 -      ! grep "^Content-Type: text/plain; charset=utf-8" msgtxt1
 +      ! grep "^Content-Type: text/plain; charset=UTF-8" msgtxt1
  '
  
  test_expect_success '--compose adds MIME for utf8 subject' '
          --smtp-server="$(pwd)/fake.sendmail" \
          $patches &&
        grep "^fake edit" msgtxt1 &&
 -      grep "^Subject: =?utf-8?q?utf8-s=C3=BCbj=C3=ABct?=" msgtxt1
 +      grep "^Subject: =?UTF-8?q?utf8-s=C3=BCbj=C3=ABct?=" msgtxt1
  '
  
  test_expect_success 'detects ambiguous reference/file conflict' '
@@@ -621,15 -621,14 +621,25 @@@ test_expect_success 'in-reply-to but n
        grep "In-Reply-To: <in-reply-id@example.com>"
  '
  
+ test_expect_success 'no in-reply-to and no threading' '
+       git send-email \
+               --dry-run \
+               --from="Example <nobody@example.com>" \
+               --to=nobody@example.com \
+               --nothread \
+               $patches $patches >stdout &&
+       ! grep "In-Reply-To: " stdout
+ '
 +test_expect_success 'threading but no chain-reply-to' '
 +      git send-email \
 +              --dry-run \
 +              --from="Example <nobody@example.com>" \
 +              --to=nobody@example.com \
 +              --thread \
 +              --nochain-reply-to \
 +              $patches $patches >stdout &&
 +      grep "In-Reply-To: " stdout
 +'
 +
  test_done