Skip to content

Commit a8022c5

Browse files
Michael Strawbridgegitster
authored andcommitted
send-email: expose header information to git-send-email's sendemail-validate hook
To allow further flexibility in the Git hook, the SMTP header information of the email which git-send-email intends to send, is now passed as the 2nd argument to the sendemail-validate hook. As an example, this can be useful for acting upon keywords in the subject or specific email addresses. Cc: Luben Tuikov <[email protected]> Cc: Junio C Hamano <[email protected]> Cc: Ævar Arnfjörð Bjarmason <[email protected]> Acked-by: Luben Tuikov <[email protected]> Signed-off-by: Michael Strawbridge <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 56addda commit a8022c5

File tree

3 files changed

+77
-25
lines changed

3 files changed

+77
-25
lines changed

Documentation/githooks.txt

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -595,10 +595,29 @@ processed by rebase.
595595
sendemail-validate
596596
~~~~~~~~~~~~~~~~~~
597597

598-
This hook is invoked by linkgit:git-send-email[1]. It takes a single parameter,
599-
the name of the file that holds the e-mail to be sent. Exiting with a
600-
non-zero status causes `git send-email` to abort before sending any
601-
e-mails.
598+
This hook is invoked by linkgit:git-send-email[1].
599+
600+
It takes these command line arguments. They are,
601+
1. the name of the file which holds the contents of the email to be sent.
602+
2. The name of the file which holds the SMTP headers of the email.
603+
604+
The SMTP headers are passed in the exact same way as they are passed to the
605+
user's Mail Transport Agent (MTA). In effect, the email given to the user's
606+
MTA, is the contents of $2 followed by the contents of $1.
607+
608+
An example of a few common headers is shown below. Take notice of the
609+
capitalization and multi-line tab structure.
610+
611+
From: Example <[email protected]>
612+
613+
614+
615+
616+
617+
Subject: PATCH-STRING
618+
619+
Exiting with a non-zero status causes `git send-email` to abort
620+
before sending any e-mails.
602621

603622
fsmonitor-watchman
604623
~~~~~~~~~~~~~~~~~~

git-send-email.perl

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -792,16 +792,31 @@ sub is_format_patch_arg {
792792
@rev_list_opts);
793793
}
794794

795-
@files = handle_backup_files(@files);
795+
if (defined $sender) {
796+
$sender =~ s/^\s+|\s+$//g;
797+
($sender) = expand_aliases($sender);
798+
} else {
799+
$sender = $repoauthor->() || $repocommitter->() || '';
800+
}
801+
802+
# $sender could be an already sanitized address
803+
# (e.g. sendemail.from could be manually sanitized by user).
804+
# But it's a no-op to run sanitize_address on an already sanitized address.
805+
$sender = sanitize_address($sender);
806+
807+
$time = time - scalar $#files;
796808

797809
if ($validate) {
798810
foreach my $f (@files) {
799811
unless (-p $f) {
812+
pre_process_file($f, 1);
800813
validate_patch($f, $target_xfer_encoding);
801814
}
802815
}
803816
}
804817

818+
@files = handle_backup_files(@files);
819+
805820
if (@files) {
806821
unless ($quiet) {
807822
print $_,"\n" for (@files);
@@ -1050,18 +1065,6 @@ sub file_declares_8bit_cte {
10501065
}
10511066
}
10521067
1053-
if (defined $sender) {
1054-
$sender =~ s/^\s+|\s+$//g;
1055-
($sender) = expand_aliases($sender);
1056-
} else {
1057-
$sender = $repoauthor->() || $repocommitter->() || '';
1058-
}
1059-
1060-
# $sender could be an already sanitized address
1061-
# (e.g. sendemail.from could be manually sanitized by user).
1062-
# But it's a no-op to run sanitize_address on an already sanitized address.
1063-
$sender = sanitize_address($sender);
1064-
10651068
my $to_whom = __("To whom should the emails be sent (if anyone)?");
10661069
my $prompting = 0;
10671070
if (!@initial_to && !defined $to_cmd) {
@@ -1221,10 +1224,6 @@ sub make_message_id {
12211224
#print "new message id = $message_id\n"; # Was useful for debugging
12221225
}
12231226

1224-
1225-
1226-
$time = time - scalar $#files;
1227-
12281227
sub unquote_rfc2047 {
12291228
local ($_) = @_;
12301229
my $charset;
@@ -2108,10 +2107,21 @@ sub validate_patch {
21082107
chdir($repo->wc_path() or $repo->repo_path())
21092108
or die("chdir: $!");
21102109
local $ENV{"GIT_DIR"} = $repo->repo_path();
2110+
2111+
my ($recipients_ref, $to, $date, $gitversion, $cc, $ccline, $header) = gen_header();
2112+
2113+
require File::Temp;
2114+
my ($header_filehandle, $header_filename) = File::Temp::tempfile(
2115+
TEMPLATE => ".gitsendemail.header.XXXXXX",
2116+
DIR => $repo->repo_path(),
2117+
UNLINK => 1,
2118+
);
2119+
print $header_filehandle $header;
2120+
21112121
my @cmd = ("git", "hook", "run", "--ignore-missing",
21122122
$hook_name, "--");
2113-
my @cmd_msg = (@cmd, "<patch>");
2114-
my @cmd_run = (@cmd, $target);
2123+
my @cmd_msg = (@cmd, "<patch>", "<header>");
2124+
my @cmd_run = (@cmd, $target, $header_filename);
21152125
$hook_error = system_or_msg(\@cmd_run, undef, "@cmd_msg");
21162126
chdir($cwd_save) or die("chdir: $!");
21172127
}

t/t9001-send-email.sh

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -540,7 +540,7 @@ test_expect_success $PREREQ "--validate respects relative core.hooksPath path" '
540540
test_path_is_file my-hooks.ran &&
541541
cat >expect <<-EOF &&
542542
fatal: longline.patch: rejected by sendemail-validate hook
543-
fatal: command '"'"'git hook run --ignore-missing sendemail-validate -- <patch>'"'"' died with exit code 1
543+
fatal: command '"'"'git hook run --ignore-missing sendemail-validate -- <patch> <header>'"'"' died with exit code 1
544544
warning: no patches were sent
545545
EOF
546546
test_cmp expect actual
@@ -559,12 +559,35 @@ test_expect_success $PREREQ "--validate respects absolute core.hooksPath path" '
559559
test_path_is_file my-hooks.ran &&
560560
cat >expect <<-EOF &&
561561
fatal: longline.patch: rejected by sendemail-validate hook
562-
fatal: command '"'"'git hook run --ignore-missing sendemail-validate -- <patch>'"'"' died with exit code 1
562+
fatal: command '"'"'git hook run --ignore-missing sendemail-validate -- <patch> <header>'"'"' died with exit code 1
563563
warning: no patches were sent
564564
EOF
565565
test_cmp expect actual
566566
'
567567

568+
test_expect_success $PREREQ "--validate hook supports header argument" '
569+
write_script my-hooks/sendemail-validate <<-\EOF &&
570+
if test "$#" -ge 2
571+
then
572+
grep "X-test-header: v1.0" "$2"
573+
else
574+
echo "No header arg passed"
575+
exit 1
576+
fi
577+
EOF
578+
test_config core.hooksPath "my-hooks" &&
579+
rm -fr outdir &&
580+
git format-patch \
581+
--add-header="X-test-header: v1.0" \
582+
-n HEAD^1 -o outdir &&
583+
git send-email \
584+
--dry-run \
585+
586+
--smtp-server="$(pwd)/fake.sendmail" \
587+
--validate \
588+
outdir/000?-*.patch
589+
'
590+
568591
for enc in 7bit 8bit quoted-printable base64
569592
do
570593
test_expect_success $PREREQ "--transfer-encoding=$enc produces correct header" '

0 commit comments

Comments
 (0)