Skip to content

Commit 1359972

Browse files
committed
Merge branch 'ga/send-email-sendmail-cmd'
"git send-email" learned the "--sendmail-cmd" command line option and the "sendemail.sendmailCmd" configuration variable, which is a more sensible approach than the current way of repurposing the "smtp-server" that is meant to name the server to instead name the command to talk to the server. * ga/send-email-sendmail-cmd: git-send-email: add option to specify sendmail command
2 parents 289af16 + cd5b33f commit 1359972

File tree

3 files changed

+76
-14
lines changed

3 files changed

+76
-14
lines changed

Documentation/git-send-email.txt

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,14 @@ Sending
167167
`sendemail.envelopeSender` configuration variable; if that is
168168
unspecified, choosing the envelope sender is left to your MTA.
169169

170+
--sendmail-cmd=<command>::
171+
Specify a command to run to send the email. The command should
172+
be sendmail-like; specifically, it must support the `-i` option.
173+
The command will be executed in the shell if necessary. Default
174+
is the value of `sendemail.sendmailcmd`. If unspecified, and if
175+
--smtp-server is also unspecified, git-send-email will search
176+
for `sendmail` in `/usr/sbin`, `/usr/lib` and $PATH.
177+
170178
--smtp-encryption=<encryption>::
171179
Specify the encryption to use, either 'ssl' or 'tls'. Any other
172180
value reverts to plain SMTP. Default is the value of
@@ -211,13 +219,16 @@ a password is obtained using 'git-credential'.
211219

212220
--smtp-server=<host>::
213221
If set, specifies the outgoing SMTP server to use (e.g.
214-
`smtp.example.com` or a raw IP address). Alternatively it can
215-
specify a full pathname of a sendmail-like program instead;
216-
the program must support the `-i` option. Default value can
217-
be specified by the `sendemail.smtpServer` configuration
218-
option; the built-in default is to search for `sendmail` in
219-
`/usr/sbin`, `/usr/lib` and $PATH if such program is
220-
available, falling back to `localhost` otherwise.
222+
`smtp.example.com` or a raw IP address). If unspecified, and if
223+
`--sendmail-cmd` is also unspecified, the default is to search
224+
for `sendmail` in `/usr/sbin`, `/usr/lib` and $PATH if such a
225+
program is available, falling back to `localhost` otherwise.
226+
+
227+
For backward compatibility, this option can also specify a full pathname
228+
of a sendmail-like program instead; the program must support the `-i`
229+
option. This method does not support passing arguments or using plain
230+
command names. For those use cases, consider using `--sendmail-cmd`
231+
instead.
221232

222233
--smtp-server-port=<port>::
223234
Specifies a port different from the default port (SMTP

git-send-email.perl

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ sub usage {
7070
7171
Sending:
7272
--envelope-sender <str> * Email envelope sender.
73+
--sendmail-cmd <str> * Command to run to send email.
7374
--smtp-server <str:int> * Outgoing SMTP server to use. The port
7475
is optional. Default 'localhost'.
7576
--smtp-server-option <str> * Outgoing SMTP server option to use.
@@ -262,6 +263,7 @@ sub do_edit {
262263
my (@suppress_cc);
263264
my ($auto_8bit_encoding);
264265
my ($compose_encoding);
266+
my ($sendmail_cmd);
265267
# Variables with corresponding config settings & hardcoded defaults
266268
my ($debug_net_smtp) = 0; # Net::SMTP, see send_message()
267269
my $thread = 1;
@@ -309,6 +311,7 @@ sub do_edit {
309311
"assume8bitencoding" => \$auto_8bit_encoding,
310312
"composeencoding" => \$compose_encoding,
311313
"transferencoding" => \$target_xfer_encoding,
314+
"sendmailcmd" => \$sendmail_cmd,
312315
);
313316

314317
my %config_path_settings = (
@@ -442,6 +445,7 @@ sub read_config {
442445
"no-bcc" => \$no_bcc,
443446
"chain-reply-to!" => \$chain_reply_to,
444447
"no-chain-reply-to" => sub {$chain_reply_to = 0},
448+
"sendmail-cmd=s" => \$sendmail_cmd,
445449
"smtp-server=s" => \$smtp_server,
446450
"smtp-server-option=s" => \@smtp_server_options,
447451
"smtp-server-port=s" => \$smtp_server_port,
@@ -1013,16 +1017,19 @@ sub expand_one_alias {
10131017
$reply_to = sanitize_address($reply_to);
10141018
}
10151019

1016-
if (!defined $smtp_server) {
1020+
if (!defined $sendmail_cmd && !defined $smtp_server) {
10171021
my @sendmail_paths = qw( /usr/sbin/sendmail /usr/lib/sendmail );
10181022
push @sendmail_paths, map {"$_/sendmail"} split /:/, $ENV{PATH};
10191023
foreach (@sendmail_paths) {
10201024
if (-x $_) {
1021-
$smtp_server = $_;
1025+
$sendmail_cmd = $_;
10221026
last;
10231027
}
10241028
}
1025-
$smtp_server ||= 'localhost'; # could be 127.0.0.1, too... *shrug*
1029+
1030+
if (!defined $sendmail_cmd) {
1031+
$smtp_server = 'localhost'; # could be 127.0.0.1, too... *shrug*
1032+
}
10261033
}
10271034

10281035
if ($compose && $compose > 0) {
@@ -1502,11 +1509,17 @@ sub send_message {
15021509

15031510
if ($dry_run) {
15041511
# We don't want to send the email.
1505-
} elsif (file_name_is_absolute($smtp_server)) {
1512+
} elsif (defined $sendmail_cmd || file_name_is_absolute($smtp_server)) {
15061513
my $pid = open my $sm, '|-';
15071514
defined $pid or die $!;
15081515
if (!$pid) {
1509-
exec($smtp_server, @sendmail_parameters) or die $!;
1516+
if (defined $sendmail_cmd) {
1517+
exec ("sh", "-c", "$sendmail_cmd \"\$@\"", "-", @sendmail_parameters)
1518+
or die $!;
1519+
} else {
1520+
exec ($smtp_server, @sendmail_parameters)
1521+
or die $!;
1522+
}
15101523
}
15111524
print $sm "$header\n$message";
15121525
close $sm or die $!;
@@ -1602,14 +1615,21 @@ sub send_message {
16021615
printf($dry_run ? __("Dry-Sent %s\n") : __("Sent %s\n"), $subject);
16031616
} else {
16041617
print($dry_run ? __("Dry-OK. Log says:\n") : __("OK. Log says:\n"));
1605-
if (!file_name_is_absolute($smtp_server)) {
1618+
if (!defined $sendmail_cmd && !file_name_is_absolute($smtp_server)) {
16061619
print "Server: $smtp_server\n";
16071620
print "MAIL FROM:<$raw_from>\n";
16081621
foreach my $entry (@recipients) {
16091622
print "RCPT TO:<$entry>\n";
16101623
}
16111624
} else {
1612-
print "Sendmail: $smtp_server ".join(' ',@sendmail_parameters)."\n";
1625+
my $sm;
1626+
if (defined $sendmail_cmd) {
1627+
$sm = $sendmail_cmd;
1628+
} else {
1629+
$sm = $smtp_server;
1630+
}
1631+
1632+
print "Sendmail: $sm ".join(' ',@sendmail_parameters)."\n";
16131633
}
16141634
print $header, "\n";
16151635
if ($smtp) {

t/t9001-send-email.sh

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2167,6 +2167,37 @@ test_expect_success $PREREQ 'leading and trailing whitespaces are removed' '
21672167
test_cmp expected-list actual-list
21682168
'
21692169

2170+
test_expect_success $PREREQ 'test using command name with --sendmail-cmd' '
2171+
clean_fake_sendmail &&
2172+
PATH="$(pwd):$PATH" \
2173+
git send-email \
2174+
--from="Example <[email protected]>" \
2175+
2176+
--sendmail-cmd="fake.sendmail" \
2177+
HEAD^ &&
2178+
test_path_is_file commandline1
2179+
'
2180+
2181+
test_expect_success $PREREQ 'test using arguments with --sendmail-cmd' '
2182+
clean_fake_sendmail &&
2183+
git send-email \
2184+
--from="Example <[email protected]>" \
2185+
2186+
--sendmail-cmd='\''"$(pwd)/fake.sendmail" -f [email protected]'\'' \
2187+
HEAD^ &&
2188+
test_path_is_file commandline1
2189+
'
2190+
2191+
test_expect_success $PREREQ 'test shell expression with --sendmail-cmd' '
2192+
clean_fake_sendmail &&
2193+
git send-email \
2194+
--from="Example <[email protected]>" \
2195+
2196+
--sendmail-cmd='\''f() { "$(pwd)/fake.sendmail" "$@"; };f'\'' \
2197+
HEAD^ &&
2198+
test_path_is_file commandline1
2199+
'
2200+
21702201
test_expect_success $PREREQ 'invoke hook' '
21712202
mkdir -p .git/hooks &&
21722203

0 commit comments

Comments
 (0)