From: Junio C Hamano Date: Thu, 13 Jun 2019 20:18:46 +0000 (-0700) Subject: Merge branch 'ab/send-email-transferencoding-fix' X-Git-Tag: v2.23.0-rc0~143 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/86d2271f06382ceeb66e891eff87166d858270e1?hp=-c Merge branch 'ab/send-email-transferencoding-fix' Since "git send-email" learned to take 'auto' as the value for the transfer-encoding, it by mistake stopped honoring the values given to the configuration variables sendemail.transferencoding and/or sendemail..transferencoding. This has been corrected to (finally) redoing the order of setting the default, reading the configuration and command line options. * ab/send-email-transferencoding-fix: send-email: fix regression in sendemail.identity parsing send-email: document --no-[to|cc|bcc] send-email: fix broken transferEncoding tests send-email: remove cargo-culted multi-patch pattern in tests send-email: do defaults -> config -> getopt in that order send-email: rename the @bcclist variable for consistency send-email: move the read_config() function above getopts --- 86d2271f06382ceeb66e891eff87166d858270e1 diff --combined Documentation/git-send-email.txt index 1afe9fc858,cf4e3d99bc..a861934c69 --- a/Documentation/git-send-email.txt +++ b/Documentation/git-send-email.txt @@@ -33,7 -33,7 +33,7 @@@ This is what linkgit:git-format-patch[1 formatting are ignored. 2. The original format used by Greg Kroah-Hartman's 'send_lots_of_email.pl' -script + script + This format expects the first line of the file to contain the "Cc:" value and the "Subject:" of the message as the second line. @@@ -190,9 -190,7 +190,9 @@@ $ git send-email --smtp-auth="PLAIN LOG If at least one of the specified mechanisms matches the ones advertised by the SMTP server and if it is supported by the utilized SASL library, the mechanism is used for authentication. If neither 'sendemail.smtpAuth' nor `--smtp-auth` -is specified, all mechanisms supported by the SASL library can be used. +is specified, all mechanisms supported by the SASL library can be used. The +special value 'none' maybe specified to completely disable authentication +independently of `--smtp-user` --smtp-pass[=]:: Password for SMTP-AUTH. The argument is optional: If no @@@ -206,9 -204,6 +206,9 @@@ or on the command line. If a username h specified (with `--smtp-pass` or `sendemail.smtpPass`), then a password is obtained using 'git-credential'. +--no-smtp-auth:: + Disable SMTP authentication. Short hand for `--smtp-auth=none` + --smtp-server=:: If set, specifies the outgoing SMTP server to use (e.g. `smtp.example.com` or a raw IP address). Alternatively it can @@@ -278,6 -273,14 +278,14 @@@ must be used for each option Automating ~~~~~~~~~~ + --no-[to|cc|bcc]:: + Clears any list of "To:", "Cc:", "Bcc:" addresses previously + set via config. + + --no-identity:: + Clears the previously read value of `sendemail.identity` set + via config, if any. + --to-cmd=:: Specify a command to execute once per patch file which should generate patch file specific "To:" entries. @@@ -326,19 -329,16 +334,19 @@@ auto-cc of: + -- -- 'author' will avoid including the patch author -- 'self' will avoid including the sender +- 'author' will avoid including the patch author. +- 'self' will avoid including the sender. - 'cc' will avoid including anyone mentioned in Cc lines in the patch header except for self (use 'self' for that). - 'bodycc' will avoid including anyone mentioned in Cc lines in the patch body (commit message) except for self (use 'self' for that). - 'sob' will avoid including anyone mentioned in Signed-off-by lines except - for self (use 'self' for that). + for self (use 'self' for that). +- 'misc-by' will avoid including anyone mentioned in Acked-by, + Reviewed-by, Tested-by and other "-by" lines in the patch body, + except Signed-off-by (use 'sob' for that). - 'cccmd' will avoid running the --cc-cmd. -- 'body' is equivalent to 'sob' + 'bodycc' +- 'body' is equivalent to 'sob' + 'bodycc' + 'misc-by'. - 'all' will suppress all auto cc values. -- + @@@ -412,7 -412,7 +420,7 @@@ have been specified, in which case defa 998 characters unless a suitable transfer encoding ('auto', 'base64', or 'quoted-printable') is used; this is due to SMTP limits as described by - http://www.ietf.org/rfc/rfc2821.txt. + http://www.ietf.org/rfc/rfc5322.txt. -- + Default is the value of `sendemail.validate`; if this is not set, diff --combined git-send-email.perl index 24859a7bc3,474598339e..5f92c89c1c --- a/git-send-email.perl +++ b/git-send-email.perl @@@ -82,11 -82,8 +82,11 @@@ git send-email --dump-aliase Pass an empty string to disable certificate verification. --smtp-domain * The domain name sent to HELO/EHLO handshake - --smtp-auth * Space-separated list of allowed AUTH mechanisms. + --smtp-auth * Space-separated list of allowed AUTH mechanisms, or + "none" to disable authentication. This setting forces to use one of the listed mechanisms. + --no-smtp-auth Disable SMTP authentication. Shorthand for + `--smtp-auth=none` --smtp-debug <0|1> * Disable, enable Net::SMTP debug. --batch-size * send max message per connection. @@@ -97,7 -94,7 +97,7 @@@ --identity * Use the sendemail. options. --to-cmd * Email To: via ` \$patch_path` --cc-cmd * Email Cc: via ` \$patch_path` - --suppress-cc * author, self, sob, cc, cccmd, body, bodycc, all. + --suppress-cc * author, self, sob, cc, cccmd, body, bodycc, misc-by, all. --[no-]cc-cover * Email Cc: addresses in the cover letter. --[no-]to-cover * Email To: addresses in the cover letter. --[no-]signed-off-by-cc * Send to Signed-off-by: addresses. Default on. @@@ -122,11 -119,6 +122,11 @@@ EO exit(1); } +sub completion_helper { + print Git::command('format-patch', '--git-completion-helper'); + exit(0); +} + # most mail servers generate the Date: header, but not all... sub format_2822_time { my ($time) = @_; @@@ -177,11 -169,15 +177,15 @@@ my $re_encoded_text = qr/[^? \000-\037\ my $re_encoded_word = qr/=\?($re_token)\?($re_token)\?($re_encoded_text)\?=/; # Variables we fill in automatically, or via prompting: - my (@to,$no_to,@initial_to,@cc,$no_cc,@initial_cc,@bcclist,$no_bcc,@xh, + my (@to,@cc,@xh,$envelope_sender, $initial_in_reply_to,$reply_to,$initial_subject,@files, - $author,$sender,$smtp_authpass,$annotate,$use_xmailer,$compose,$time); - - my $envelope_sender; + $author,$sender,$smtp_authpass,$annotate,$compose,$time); + # Things we either get from config, *or* are overridden on the + # command-line. + my ($no_cc, $no_to, $no_bcc, $no_identity); + my (@config_to, @getopt_to); + my (@config_cc, @getopt_cc); + my (@config_bcc, @getopt_bcc); # Example reply to: #$initial_in_reply_to = ''; #<20050203173208.GA23964@foobar.com>'; @@@ -228,33 -224,37 +232,37 @@@ sub do_edit } # Variables with corresponding config settings - my ($thread, $chain_reply_to, $suppress_from, $signed_off_by_cc); + my ($suppress_from, $signed_off_by_cc); my ($cover_cc, $cover_to); my ($to_cmd, $cc_cmd); my ($smtp_server, $smtp_server_port, @smtp_server_options); my ($smtp_authuser, $smtp_encryption, $smtp_ssl_cert_path); my ($batch_size, $relogin_delay); my ($identity, $aliasfiletype, @alias_files, $smtp_domain, $smtp_auth); - my ($validate, $confirm); + my ($confirm); my (@suppress_cc); my ($auto_8bit_encoding); my ($compose_encoding); - my $target_xfer_encoding = 'auto'; - + # Variables with corresponding config settings & hardcoded defaults my ($debug_net_smtp) = 0; # Net::SMTP, see send_message() + my $thread = 1; + my $chain_reply_to = 0; + my $use_xmailer = 1; + my $validate = 1; + my $target_xfer_encoding = 'auto'; my %config_bool_settings = ( - "thread" => [\$thread, 1], - "chainreplyto" => [\$chain_reply_to, 0], - "suppressfrom" => [\$suppress_from, undef], - "signedoffbycc" => [\$signed_off_by_cc, undef], - "cccover" => [\$cover_cc, undef], - "tocover" => [\$cover_to, undef], - "signedoffcc" => [\$signed_off_by_cc, undef], # Deprecated - "validate" => [\$validate, 1], - "multiedit" => [\$multiedit, undef], - "annotate" => [\$annotate, undef], - "xmailer" => [\$use_xmailer, 1] + "thread" => \$thread, + "chainreplyto" => \$chain_reply_to, + "suppressfrom" => \$suppress_from, + "signedoffbycc" => \$signed_off_by_cc, + "cccover" => \$cover_cc, + "tocover" => \$cover_to, + "signedoffcc" => \$signed_off_by_cc, + "validate" => \$validate, + "multiedit" => \$multiedit, + "annotate" => \$annotate, + "xmailer" => \$use_xmailer, ); my %config_settings = ( @@@ -267,12 -267,12 +275,12 @@@ "smtpauth" => \$smtp_auth, "smtpbatchsize" => \$batch_size, "smtprelogindelay" => \$relogin_delay, - "to" => \@initial_to, + "to" => \@config_to, "tocmd" => \$to_cmd, - "cc" => \@initial_cc, + "cc" => \@config_cc, "cccmd" => \$cc_cmd, "aliasfiletype" => \$aliasfiletype, - "bcc" => \@bcclist, + "bcc" => \@config_bcc, "suppresscc" => \@suppress_cc, "envelopesender" => \$envelope_sender, "confirm" => \$confirm, @@@ -315,13 -315,86 +323,87 @@@ sub signal_handler $SIG{TERM} = \&signal_handler; $SIG{INT} = \&signal_handler; + # Read our sendemail.* config + sub read_config { + my ($configured, $prefix) = @_; + + foreach my $setting (keys %config_bool_settings) { + my $target = $config_bool_settings{$setting}; + my $v = Git::config_bool(@repo, "$prefix.$setting"); + next unless defined $v; + next if $configured->{$setting}++; + $$target = $v; + } + + foreach my $setting (keys %config_path_settings) { + my $target = $config_path_settings{$setting}; + if (ref($target) eq "ARRAY") { + my @values = Git::config_path(@repo, "$prefix.$setting"); + next unless @values; + next if $configured->{$setting}++; + @$target = @values; + } + else { + my $v = Git::config_path(@repo, "$prefix.$setting"); + next unless defined $v; + next if $configured->{$setting}++; + $$target = $v; + } + } + + foreach my $setting (keys %config_settings) { + my $target = $config_settings{$setting}; + if (ref($target) eq "ARRAY") { + my @values = Git::config(@repo, "$prefix.$setting"); + next unless @values; + next if $configured->{$setting}++; + @$target = @values; + } + else { + my $v = Git::config(@repo, "$prefix.$setting"); + next unless defined $v; + next if $configured->{$setting}++; + $$target = $v; + } + } + + if (!defined $smtp_encryption) { + my $setting = "$prefix.smtpencryption"; + my $enc = Git::config(@repo, $setting); + return unless defined $enc; + return if $configured->{$setting}++; + if (defined $enc) { + $smtp_encryption = $enc; + } elsif (Git::config_bool(@repo, "$prefix.smtpssl")) { + $smtp_encryption = 'ssl'; + } + } + } + + # sendemail.identity yields to --identity. We must parse this + # special-case first before the rest of the config is read. + $identity = Git::config(@repo, "sendemail.identity"); + my $rc = GetOptions( + "identity=s" => \$identity, + "no-identity" => \$no_identity, + ); + usage() unless $rc; + undef $identity if $no_identity; + + # Now we know enough to read the config + { + my %configured; + read_config(\%configured, "sendemail.$identity") if defined $identity; + read_config(\%configured, "sendemail"); + } + # Begin by accumulating all the variables (defined above), that we will end up # needing, first, from the command line: my $help; +my $git_completion_helper; - my $rc = GetOptions("h" => \$help, - "dump-aliases" => \$dump_aliases); + $rc = GetOptions("h" => \$help, + "dump-aliases" => \$dump_aliases); usage() unless $rc; die __("--dump-aliases incompatible with other options\n") if !$help and $dump_aliases and @ARGV; @@@ -330,12 -403,12 +412,12 @@@ $rc = GetOptions "in-reply-to=s" => \$initial_in_reply_to, "reply-to=s" => \$reply_to, "subject=s" => \$initial_subject, - "to=s" => \@initial_to, + "to=s" => \@getopt_to, "to-cmd=s" => \$to_cmd, "no-to" => \$no_to, - "cc=s" => \@initial_cc, + "cc=s" => \@getopt_cc, "no-cc" => \$no_cc, - "bcc=s" => \@bcclist, + "bcc=s" => \@getopt_bcc, "no-bcc" => \$no_bcc, "chain-reply-to!" => \$chain_reply_to, "no-chain-reply-to" => sub {$chain_reply_to = 0}, @@@ -350,8 -423,6 +432,7 @@@ "smtp-debug:i" => \$debug_net_smtp, "smtp-domain:s" => \$smtp_domain, "smtp-auth=s" => \$smtp_auth, + "no-smtp-auth" => sub {$smtp_auth = 'none'}, - "identity=s" => \$identity, "annotate!" => \$annotate, "no-annotate" => sub {$annotate = 0}, "compose" => \$compose, @@@ -383,11 -454,14 +464,16 @@@ "no-xmailer" => sub {$use_xmailer = 0}, "batch-size=i" => \$batch_size, "relogin-delay=i" => \$relogin_delay, + "git-completion-helper" => \$git_completion_helper, ); + # Munge any "either config or getopt, not both" variables + my @initial_to = @getopt_to ? @getopt_to : ($no_to ? () : @config_to); + my @initial_cc = @getopt_cc ? @getopt_cc : ($no_cc ? () : @config_cc); + my @initial_bcc = @getopt_bcc ? @getopt_bcc : ($no_bcc ? () : @config_bcc); + usage() if $help; +completion_helper() if $git_completion_helper; unless ($rc) { usage(); } @@@ -399,65 -473,6 +485,6 @@@ die __("`batch-size` and `relogin` mus "(via command-line or configuration option)\n") if defined $relogin_delay and not defined $batch_size; - # Now, let's fill any that aren't set in with defaults: - - sub read_config { - my ($prefix) = @_; - - foreach my $setting (keys %config_bool_settings) { - my $target = $config_bool_settings{$setting}->[0]; - $$target = Git::config_bool(@repo, "$prefix.$setting") unless (defined $$target); - } - - foreach my $setting (keys %config_path_settings) { - my $target = $config_path_settings{$setting}; - if (ref($target) eq "ARRAY") { - unless (@$target) { - my @values = Git::config_path(@repo, "$prefix.$setting"); - @$target = @values if (@values && defined $values[0]); - } - } - else { - $$target = Git::config_path(@repo, "$prefix.$setting") unless (defined $$target); - } - } - - foreach my $setting (keys %config_settings) { - my $target = $config_settings{$setting}; - next if $setting eq "to" and defined $no_to; - next if $setting eq "cc" and defined $no_cc; - next if $setting eq "bcc" and defined $no_bcc; - if (ref($target) eq "ARRAY") { - unless (@$target) { - my @values = Git::config(@repo, "$prefix.$setting"); - @$target = @values if (@values && defined $values[0]); - } - } - else { - $$target = Git::config(@repo, "$prefix.$setting") unless (defined $$target); - } - } - - if (!defined $smtp_encryption) { - my $enc = Git::config(@repo, "$prefix.smtpencryption"); - if (defined $enc) { - $smtp_encryption = $enc; - } elsif (Git::config_bool(@repo, "$prefix.smtpssl")) { - $smtp_encryption = 'ssl'; - } - } - } - - # read configuration from [sendemail "$identity"], fall back on [sendemail] - $identity = Git::config(@repo, "sendemail.identity") unless (defined $identity); - read_config("sendemail.$identity") if (defined $identity); - read_config("sendemail"); - - # fall back on builtin bool defaults - foreach my $setting (values %config_bool_settings) { - ${$setting->[0]} = $setting->[1] unless (defined (${$setting->[0]})); - } - # 'default' encryption is none -- this only prevents a warning $smtp_encryption = '' unless (defined $smtp_encryption); @@@ -465,16 -480,14 +492,16 @@@ my(%suppress_cc); if (@suppress_cc) { foreach my $entry (@suppress_cc) { + # Please update $__git_send_email_suppresscc_options + # in git-completion.bash when you add new options. die sprintf(__("Unknown --suppress-cc field: '%s'\n"), $entry) - unless $entry =~ /^(?:all|cccmd|cc|author|self|sob|body|bodycc)$/; + unless $entry =~ /^(?:all|cccmd|cc|author|self|sob|body|bodycc|misc-by)$/; $suppress_cc{$entry} = 1; } } if ($suppress_cc{'all'}) { - foreach my $entry (qw (cccmd cc author self sob body bodycc)) { + foreach my $entry (qw (cccmd cc author self sob body bodycc misc-by)) { $suppress_cc{$entry} = 1; } delete $suppress_cc{'all'}; @@@ -485,7 -498,7 +512,7 @@@ $suppress_cc{'self'} = $suppress_from i $suppress_cc{'sob'} = !$signed_off_by_cc if defined $signed_off_by_cc; if ($suppress_cc{'body'}) { - foreach my $entry (qw (sob bodycc)) { + foreach my $entry (qw (sob bodycc misc-by)) { $suppress_cc{$entry} = 1; } delete $suppress_cc{'body'}; @@@ -496,8 -509,6 +523,8 @@@ my $confirm_unconfigured = !defined $co if ($confirm_unconfigured) { $confirm = scalar %suppress_cc ? 'compose' : 'auto'; }; +# Please update $__git_send_email_confirm_options in +# git-completion.bash when you add new options. die sprintf(__("Unknown --confirm setting: '%s'\n"), $confirm) unless $confirm =~ /^(?:auto|cc|compose|always|never)/; @@@ -591,8 -602,6 +618,8 @@@ my %parse_alias = if (/\(define-mail-alias\s+"(\S+?)"\s+"(\S+?)"\)/) { $aliases{$1} = [ $2 ]; }}} + # Please update _git_config() in git-completion.bash when you + # add new MUAs. ); if (@alias_files and $aliasfiletype and defined $parse_alias{$aliasfiletype}) { @@@ -941,7 -950,7 +968,7 @@@ sub expand_one_alias @initial_to = process_address_list(@initial_to); @initial_cc = process_address_list(@initial_cc); - @bcclist = process_address_list(@bcclist); + @initial_bcc = process_address_list(@initial_bcc); if ($thread && !defined $initial_in_reply_to && $prompting) { $initial_in_reply_to = ask( @@@ -1259,7 -1268,7 +1286,7 @@@ sub smtp_host_string # (smtp_user was not specified), and 0 otherwise. sub smtp_auth_maybe { - if (!defined $smtp_authuser || $auth) { + if (!defined $smtp_authuser || $auth || (defined $smtp_auth && $smtp_auth eq "none")) { return 1; } @@@ -1364,7 -1373,7 +1391,7 @@@ sub send_message } @cc); my $to = join (",\n\t", @recipients); - @recipients = unique_email_list(@recipients,@cc,@bcclist); + @recipients = unique_email_list(@recipients,@cc,@initial_bcc); @recipients = (map { extract_valid_address_or_die($_) } @recipients); my $date = format_2822_time($time++); my $gitversion = '@@GIT_VERSION@@'; @@@ -1497,7 -1506,7 +1524,7 @@@ EO SSL => 1); } } - else { + elsif (!$smtp) { $smtp_server_port ||= 25; $smtp ||= Net::SMTP->new($smtp_server, Hello => $smtp_domain, @@@ -1519,6 -1528,7 +1546,6 @@@ $smtp->starttls(ssl_verify_params()) or die sprintf(__("STARTTLS failed! %s"), IO::Socket::SSL::errstr()); } - $smtp_encryption = ''; # Send EHLO again to receive fresh # supported commands $smtp->hello($smtp_domain); @@@ -1699,7 -1709,7 +1726,7 @@@ sub process_file # Now parse the message body while(<$fh>) { $message .= $_; - if (/^(Signed-off-by|Cc): (.*)/i) { + if (/^([a-z][a-z-]*-by|Cc): (.*)/i) { chomp; my ($what, $c) = ($1, $2); # strip garbage for the address we'll use: @@@ -1709,18 -1719,8 +1736,18 @@@ if ($sc eq $sender) { next if ($suppress_cc{'self'}); } else { - next if $suppress_cc{'sob'} and $what =~ /Signed-off-by/i; - next if $suppress_cc{'bodycc'} and $what =~ /Cc/i; + if ($what =~ /^Signed-off-by$/i) { + next if $suppress_cc{'sob'}; + } elsif ($what =~ /-by$/i) { + next if $suppress_cc{'misc-by'}; + } elsif ($what =~ /Cc/i) { + next if $suppress_cc{'bodycc'}; + } + } + if ($c !~ /.+@.+|<.+>/) { + printf("(body) Ignoring %s from line '%s'\n", + $what, $_) unless $quiet; + next; } push @cc, $c; printf(__("(body) Adding cc: %s from line '%s'\n"), @@@ -1862,7 -1862,7 +1889,7 @@@ sub apply_transfer_encoding my $from = shift; my $to = shift; - return $message if ($from eq $to and $from ne '7bit'); + return ($message, $to) if ($from eq $to and $from ne '7bit'); require MIME::QuotedPrint; require MIME::Base64; @@@ -1872,7 -1872,7 +1899,7 @@@ $message = MIME::Base64::decode($message) if ($from eq 'base64'); - $to = ($message =~ /.{999,}/) ? 'quoted-printable' : '8bit' + $to = ($message =~ /(?:.{999,}|\r)/) ? 'quoted-printable' : '8bit' if $to eq 'auto'; die __("cannot send message as 7bit") diff --combined t/t9001-send-email.sh index 1e3ac3c384,4be4b50ff9..997f90b42b --- a/t/t9001-send-email.sh +++ b/t/t9001-send-email.sh @@@ -253,9 -253,10 +253,9 @@@ test_suppress_self () mv msgtxt1 msgtxt1-$3 && sed -e '/^$/q' msgtxt1-$3 >"msghdr1-$3" && - >"expected-no-cc-$3" && (grep '^Cc:' msghdr1-$3 >"actual-no-cc-$3"; - test_cmp expected-no-cc-$3 actual-no-cc-$3) + test_must_be_empty actual-no-cc-$3) } test_suppress_self_unquoted () { @@@ -331,7 -332,7 +331,7 @@@ test_expect_success $PREREQ 'Show all h test_expect_success $PREREQ 'Prompting works' ' clean_fake_sendmail && - (echo "to@example.com" + (echo "to@example.com" && echo "" ) | GIT_SEND_EMAIL_NOTTY=1 git send-email \ --smtp-server="$(pwd)/fake.sendmail" \ @@@ -481,20 -482,6 +481,20 @@@ test_expect_success $PREREQ 'long line grep "Content-Transfer-Encoding: quoted-printable" msgtxt1 ' +test_expect_success $PREREQ 'carriage returns with auto encoding are quoted-printable' ' + clean_fake_sendmail && + cp $patches cr.patch && + printf "this is a line\r\n" >>cr.patch && + git send-email \ + --from="Example " \ + --to=nobody@example.com \ + --smtp-server="$(pwd)/fake.sendmail" \ + --transfer-encoding=auto \ + --no-validate \ + cr.patch && + grep "Content-Transfer-Encoding: quoted-printable" msgtxt1 +' + for enc in auto quoted-printable base64 do test_expect_success $PREREQ "--validate passes with encoding $enc" ' @@@ -506,21 -493,6 +506,21 @@@ --validate \ $patches longline.patch ' + +done + +for enc in 7bit 8bit quoted-printable base64 +do + test_expect_success $PREREQ "--transfer-encoding=$enc produces correct header" ' + clean_fake_sendmail && + git send-email \ + --from="Example " \ + --to=nobody@example.com \ + --smtp-server="$(pwd)/fake.sendmail" \ + --transfer-encoding=$enc \ + $patches && + grep "Content-Transfer-Encoding: $enc" msgtxt1 + ' done test_expect_success $PREREQ 'Invalid In-Reply-To' ' @@@ -537,8 -509,8 +537,8 @@@ test_expect_success $PREREQ 'Valid In-Reply-To when prompting' ' clean_fake_sendmail && - (echo "From Example " - echo "To Example " + (echo "From Example " && + echo "To Example " && echo "" ) | GIT_SEND_EMAIL_NOTTY=1 git send-email \ --smtp-server="$(pwd)/fake.sendmail" \ @@@ -1204,7 -1176,7 +1204,7 @@@ test_expect_success $PREREQ 'no in-repl --from="Example " \ --to=nobody@example.com \ --no-thread \ - $patches $patches >stdout && + $patches >stdout && ! grep "In-Reply-To: " stdout ' @@@ -1224,17 -1196,72 +1224,72 @@@ test_expect_success $PREREQ 'sendemail. git send-email \ --dry-run \ --from="Example " \ - $patches $patches >stdout && + $patches >stdout && grep "To: Somebody " stdout ' + test_expect_success $PREREQ 'setup sendemail.identity' ' + git config --replace-all sendemail.to "default@example.com" && + git config --replace-all sendemail.isp.to "isp@example.com" && + git config --replace-all sendemail.cloud.to "cloud@example.com" + ' + + test_expect_success $PREREQ 'sendemail.identity: reads the correct identity config' ' + git -c sendemail.identity=cloud send-email \ + --dry-run \ + --from="nobody@example.com" \ + $patches >stdout && + grep "To: cloud@example.com" stdout + ' + + test_expect_success $PREREQ 'sendemail.identity: identity overrides sendemail.identity' ' + git -c sendemail.identity=cloud send-email \ + --identity=isp \ + --dry-run \ + --from="nobody@example.com" \ + $patches >stdout && + grep "To: isp@example.com" stdout + ' + + test_expect_success $PREREQ 'sendemail.identity: --no-identity clears previous identity' ' + git -c sendemail.identity=cloud send-email \ + --no-identity \ + --dry-run \ + --from="nobody@example.com" \ + $patches >stdout && + grep "To: default@example.com" stdout + ' + + test_expect_success $PREREQ 'sendemail.identity: bool identity variable existance overrides' ' + git -c sendemail.identity=cloud \ + -c sendemail.xmailer=true \ + -c sendemail.cloud.xmailer=false \ + send-email \ + --dry-run \ + --from="nobody@example.com" \ + $patches >stdout && + grep "To: cloud@example.com" stdout && + ! grep "X-Mailer" stdout + ' + + test_expect_success $PREREQ 'sendemail.identity: bool variable fallback' ' + git -c sendemail.identity=cloud \ + -c sendemail.xmailer=false \ + send-email \ + --dry-run \ + --from="nobody@example.com" \ + $patches >stdout && + grep "To: cloud@example.com" stdout && + ! grep "X-Mailer" stdout + ' + test_expect_success $PREREQ '--no-to overrides sendemail.to' ' git send-email \ --dry-run \ --from="Example " \ --no-to \ --to=nobody@example.com \ - $patches $patches >stdout && + $patches >stdout && grep "To: nobody@example.com" stdout && ! grep "To: Somebody " stdout ' @@@ -1245,7 -1272,7 +1300,7 @@@ test_expect_success $PREREQ 'sendemail. --dry-run \ --from="Example " \ --to=nobody@example.com \ - $patches $patches >stdout && + $patches >stdout && grep "Cc: Somebody " stdout ' @@@ -1256,7 -1283,7 +1311,7 @@@ test_expect_success $PREREQ '--no-cc ov --no-cc \ --cc=bodies@example.com \ --to=nobody@example.com \ - $patches $patches >stdout && + $patches >stdout && grep "Cc: bodies@example.com" stdout && ! grep "Cc: Somebody " stdout ' @@@ -1268,7 -1295,7 +1323,7 @@@ test_expect_success $PREREQ 'sendemail. --from="Example " \ --to=nobody@example.com \ --smtp-server relay.example.com \ - $patches $patches >stdout && + $patches >stdout && grep "RCPT TO:" stdout ' @@@ -1280,7 -1307,7 +1335,7 @@@ test_expect_success $PREREQ '--no-bcc o --bcc=bodies@example.com \ --to=nobody@example.com \ --smtp-server relay.example.com \ - $patches $patches >stdout && + $patches >stdout && grep "RCPT TO:" stdout && ! grep "RCPT TO:" stdout ' @@@ -1437,10 -1464,10 +1492,10 @@@ test_expect_success $PREREQ 'setup expe EOF ' - test_expect_success $PREREQ 'sendemail.transferencoding=7bit fails on 8bit data' ' + test_expect_success $PREREQ '--transfer-encoding overrides sendemail.transferEncoding' ' clean_fake_sendmail && - git config sendemail.transferEncoding 7bit && - test_must_fail git send-email \ + test_must_fail git -c sendemail.transferEncoding=8bit \ + send-email \ --transfer-encoding=7bit \ --smtp-server="$(pwd)/fake.sendmail" \ email-using-8bit \ @@@ -1449,11 -1476,10 +1504,10 @@@ test -z "$(ls msgtxt*)" ' - test_expect_success $PREREQ '--transfer-encoding overrides sendemail.transferEncoding' ' + test_expect_success $PREREQ 'sendemail.transferEncoding via config' ' clean_fake_sendmail && - git config sendemail.transferEncoding 8bit && - test_must_fail git send-email \ - --transfer-encoding=7bit \ + test_must_fail git -c sendemail.transferEncoding=7bit \ + send-email \ --smtp-server="$(pwd)/fake.sendmail" \ email-using-8bit \ 2>errors >out && @@@ -1461,16 -1487,15 +1515,15 @@@ test -z "$(ls msgtxt*)" ' - test_expect_success $PREREQ 'sendemail.transferencoding=8bit' ' + test_expect_success $PREREQ 'sendemail.transferEncoding via cli' ' clean_fake_sendmail && - git send-email \ - --transfer-encoding=8bit \ + test_must_fail git send-email \ + --transfer-encoding=7bit \ --smtp-server="$(pwd)/fake.sendmail" \ email-using-8bit \ 2>errors >out && - sed '1,/^$/d' msgtxt1 >actual && - sed '1,/^$/d' email-using-8bit >expected && - test_cmp expected actual + grep "cannot send message as 7bit" errors && + test -z "$(ls msgtxt*)" ' test_expect_success $PREREQ 'setup expect' ' @@@ -1787,6 -1812,15 +1840,15 @@@ test_expect_success '--dump-aliases mus test_must_fail git send-email --dump-aliases --to=janice@example.com -1 refs/heads/accounting ' + test_expect_success $PREREQ 'aliases and sendemail.identity' ' + test_must_fail git \ + -c sendemail.identity=cloud \ + -c sendemail.aliasesfile=default-aliases \ + -c sendemail.cloud.aliasesfile=cloud-aliases \ + send-email -1 2>stderr && + test_i18ngrep "cloud-aliases" stderr + ' + test_sendmail_aliases () { msg="$1" && shift && expect="$@" && @@@ -2051,11 -2085,11 +2113,11 @@@ test_expect_success $PREREQ 'invoke hoo # Verify error message when a patch is rejected by the hook sed -e "s/add master/x/" ../0001-add-master.patch >../another.patch && - git send-email \ + test_must_fail git send-email \ --from="Example " \ --to=nobody@example.com \ --smtp-server="$(pwd)/../fake.sendmail" \ - ../another.patch 2>err + ../another.patch 2>err && test_i18ngrep "rejected by sendemail-validate hook" err ) '