Merge branch 'xz/send-email-batch-size'

"git send-email" learned to overcome some SMTP server limitation
that does not allow many pieces of e-mails to be sent over a single
session.

* xz/send-email-batch-size:
  send-email: --batch-size to work around some SMTP server limit
This commit is contained in:
Junio C Hamano 2017-07-06 18:14:46 -07:00
commit eb37527ab0
4 changed files with 45 additions and 0 deletions

@ -2946,6 +2946,16 @@ sendemail.xmailer::
sendemail.signedoffcc (deprecated):: sendemail.signedoffcc (deprecated)::
Deprecated alias for `sendemail.signedoffbycc`. Deprecated alias for `sendemail.signedoffbycc`.
sendemail.smtpBatchSize::
Number of messages to be sent per connection, after that a relogin
will happen. If the value is 0 or undefined, send all messages in
one connection.
See also the `--batch-size` option of linkgit:git-send-email[1].
sendemail.smtpReloginDelay::
Seconds wait before reconnecting to smtp server.
See also the `--relogin-delay` option of linkgit:git-send-email[1].
showbranch.default:: showbranch.default::
The default set of branches for linkgit:git-show-branch[1]. The default set of branches for linkgit:git-show-branch[1].
See linkgit:git-show-branch[1]. See linkgit:git-show-branch[1].

@ -248,6 +248,21 @@ must be used for each option.
commands and replies will be printed. Useful to debug TLS commands and replies will be printed. Useful to debug TLS
connection and authentication problems. connection and authentication problems.
--batch-size=<num>::
Some email servers (e.g. smtp.163.com) limit the number emails to be
sent per session (connection) and this will lead to a faliure when
sending many messages. With this option, send-email will disconnect after
sending $<num> messages and wait for a few seconds (see --relogin-delay)
and reconnect, to work around such a limit. You may want to
use some form of credential helper to avoid having to retype
your password every time this happens. Defaults to the
`sendemail.smtpBatchSize` configuration variable.
--relogin-delay=<int>::
Waiting $<int> seconds before reconnecting to SMTP server. Used together
with --batch-size option. Defaults to the `sendemail.smtpReloginDelay`
configuration variable.
Automating Automating
~~~~~~~~~~ ~~~~~~~~~~

@ -2641,6 +2641,8 @@ _git_config ()
sendemail.thread sendemail.thread
sendemail.to sendemail.to
sendemail.validate sendemail.validate
sendemail.smtpbatchsize
sendemail.smtprelogindelay
showbranch.default showbranch.default
status.relativePaths status.relativePaths
status.showUntrackedFiles status.showUntrackedFiles

@ -82,6 +82,10 @@ git send-email --dump-aliases
This setting forces to use one of the listed mechanisms. This setting forces to use one of the listed mechanisms.
--smtp-debug <0|1> * Disable, enable Net::SMTP debug. --smtp-debug <0|1> * Disable, enable Net::SMTP debug.
--batch-size <int> * send max <int> message per connection.
--relogin-delay <int> * delay <int> seconds between two successive login.
This option can only be used with --batch-size
Automating: Automating:
--identity <str> * Use the sendemail.<id> options. --identity <str> * Use the sendemail.<id> options.
--to-cmd <str> * Email To: via `<str> \$patch_path` --to-cmd <str> * Email To: via `<str> \$patch_path`
@ -154,6 +158,7 @@ my $have_email_valid = eval { require Email::Valid; 1 };
my $have_mail_address = eval { require Mail::Address; 1 }; my $have_mail_address = eval { require Mail::Address; 1 };
my $smtp; my $smtp;
my $auth; my $auth;
my $num_sent = 0;
# Regexes for RFC 2047 productions. # Regexes for RFC 2047 productions.
my $re_token = qr/[^][()<>@,;:\\"\/?.= \000-\037\177-\377]+/; my $re_token = qr/[^][()<>@,;:\\"\/?.= \000-\037\177-\377]+/;
@ -217,6 +222,7 @@ my ($cover_cc, $cover_to);
my ($to_cmd, $cc_cmd); my ($to_cmd, $cc_cmd);
my ($smtp_server, $smtp_server_port, @smtp_server_options); my ($smtp_server, $smtp_server_port, @smtp_server_options);
my ($smtp_authuser, $smtp_encryption, $smtp_ssl_cert_path); my ($smtp_authuser, $smtp_encryption, $smtp_ssl_cert_path);
my ($batch_size, $relogin_delay);
my ($identity, $aliasfiletype, @alias_files, $smtp_domain, $smtp_auth); my ($identity, $aliasfiletype, @alias_files, $smtp_domain, $smtp_auth);
my ($validate, $confirm); my ($validate, $confirm);
my (@suppress_cc); my (@suppress_cc);
@ -248,6 +254,8 @@ my %config_settings = (
"smtppass" => \$smtp_authpass, "smtppass" => \$smtp_authpass,
"smtpdomain" => \$smtp_domain, "smtpdomain" => \$smtp_domain,
"smtpauth" => \$smtp_auth, "smtpauth" => \$smtp_auth,
"smtpbatchsize" => \$batch_size,
"smtprelogindelay" => \$relogin_delay,
"to" => \@initial_to, "to" => \@initial_to,
"tocmd" => \$to_cmd, "tocmd" => \$to_cmd,
"cc" => \@initial_cc, "cc" => \@initial_cc,
@ -359,6 +367,8 @@ $rc = GetOptions(
"force" => \$force, "force" => \$force,
"xmailer!" => \$use_xmailer, "xmailer!" => \$use_xmailer,
"no-xmailer" => sub {$use_xmailer = 0}, "no-xmailer" => sub {$use_xmailer = 0},
"batch-size=i" => \$batch_size,
"relogin-delay=i" => \$relogin_delay,
); );
usage() if $help; usage() if $help;
@ -1681,6 +1691,14 @@ foreach my $t (@files) {
} }
} }
$message_id = undef; $message_id = undef;
$num_sent++;
if (defined $batch_size && $num_sent == $batch_size) {
$num_sent = 0;
$smtp->quit if defined $smtp;
undef $smtp;
undef $auth;
sleep($relogin_delay) if defined $relogin_delay;
}
} }
# Execute a command (e.g. $to_cmd) to get a list of email addresses # Execute a command (e.g. $to_cmd) to get a list of email addresses