Skip to content

Commit 241499a

Browse files
jacob-kellergitster
authored andcommitted
send-email: add mailmap support via sendemail.mailmap and --mailmap
In some cases, a user may be generating a patch for an old commit which now has an out-of-date author or other identity. For example, consider a team member who contributes to an internal fork of an upstream project, but leaves before this change is submitted upstream. In this case, the team members company address may no longer be valid, and will thus bounce when sending email. This can be manually avoided by editing the generated patch files, or by carefully using --suppress-<cc|to> options. This requires a lot of manual intervention and is easy to forget. Git has support for mapping old email addresses and names to a canonical name and address via the .mailmap file (and its associated mailmap.file, mailmap.blob, and log.mailmap options). Teach git send-email to enable mailmap support for all addresses. This ensures that addresses point to the canonical real name and email address. Add the sendemail.mailmap configuration option and its associated --mailmap (and --use-mailmap for compatibility with git log) options. For now, the default behavior is to disable the mailmap in order to avoid any surprises or breaking any existing setups. These options support per-identity configuration via the sendemail.identity configuration blocks. This enables identity-specific configuration in cases where users may not want to enable support. In addition, support send-email specific mailmap data via sendemail.mailmap.file, sendemail.mailmap.blob and their identity-specific variants. The intention of these options is to enable mapping addresses which are no longer valid to a current project or team maintainer. Such mappings may change the actual person being referred to, and may not make sense in a traditional mailmap file which is intended for updating canonical name and address for the same individual. Signed-off-by: Jacob Keller <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent f54ca6a commit 241499a

File tree

2 files changed

+142
-0
lines changed

2 files changed

+142
-0
lines changed

git-send-email.perl

+20
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ sub usage {
4646
--compose-encoding <str> * Encoding to assume for introduction.
4747
--8bit-encoding <str> * Encoding to assume 8bit mails if undeclared
4848
--transfer-encoding <str> * Transfer encoding to use (quoted-printable, 8bit, base64)
49+
--[no-]mailmap * Use mailmap file to map all email addresses to canonical
50+
real names and email addresses.
4951
5052
Sending:
5153
--envelope-sender <str> * Email envelope sender.
@@ -272,12 +274,14 @@ sub do_edit {
272274
my ($auto_8bit_encoding);
273275
my ($compose_encoding);
274276
my ($sendmail_cmd);
277+
my ($mailmap_file, $mailmap_blob);
275278
# Variables with corresponding config settings & hardcoded defaults
276279
my ($debug_net_smtp) = 0; # Net::SMTP, see send_message()
277280
my $thread = 1;
278281
my $chain_reply_to = 0;
279282
my $use_xmailer = 1;
280283
my $validate = 1;
284+
my $mailmap = 0;
281285
my $target_xfer_encoding = 'auto';
282286
my $forbid_sendmail_variables = 1;
283287

@@ -294,6 +298,7 @@ sub do_edit {
294298
"annotate" => \$annotate,
295299
"xmailer" => \$use_xmailer,
296300
"forbidsendmailvariables" => \$forbid_sendmail_variables,
301+
"mailmap" => \$mailmap,
297302
);
298303

299304
my %config_settings = (
@@ -327,6 +332,8 @@ sub do_edit {
327332
my %config_path_settings = (
328333
"aliasesfile" => \@alias_files,
329334
"smtpsslcertpath" => \$smtp_ssl_cert_path,
335+
"mailmap.file" => \$mailmap_file,
336+
"mailmap.blob" => \$mailmap_blob,
330337
);
331338

332339
# Handle Uncouth Termination
@@ -524,6 +531,8 @@ sub config_regexp {
524531
"thread!" => \$thread,
525532
"validate!" => \$validate,
526533
"transfer-encoding=s" => \$target_xfer_encoding,
534+
"mailmap!" => \$mailmap,
535+
"use-mailmap!" => \$mailmap,
527536
"format-patch!" => \$format_patch,
528537
"8bit-encoding=s" => \$auto_8bit_encoding,
529538
"compose-encoding=s" => \$compose_encoding,
@@ -1085,6 +1094,16 @@ sub expand_one_alias {
10851094
our ($message_id, %mail, $subject, $in_reply_to, $references, $message,
10861095
$needs_confirm, $message_num, $ask_default);
10871096
1097+
sub mailmap_address_list {
1098+
return @_ unless @_ and $mailmap;
1099+
my @options = ();
1100+
push(@options, "--mailmap-file=$mailmap_file") if $mailmap_file;
1101+
push(@options, "--mailmap-blob=$mailmap_blob") if $mailmap_blob;
1102+
my @addr_list = Git::command('check-mailmap', @options, @_);
1103+
s/^<(.*)>$/$1/ for @addr_list;
1104+
return @addr_list;
1105+
}
1106+
10881107
sub extract_valid_address {
10891108
my $address = shift;
10901109
my $local_part_regexp = qr/[^<>"\s@]+/;
@@ -1294,6 +1313,7 @@ sub process_address_list {
12941313
@addr_list = expand_aliases(@addr_list);
12951314
@addr_list = sanitize_address_list(@addr_list);
12961315
@addr_list = validate_address_list(@addr_list);
1316+
@addr_list = mailmap_address_list(@addr_list);
12971317
return @addr_list;
12981318
}
12991319

t/t9001-send-email.sh

+122
Original file line numberDiff line numberDiff line change
@@ -2379,6 +2379,128 @@ test_expect_success $PREREQ 'leading and trailing whitespaces are removed' '
23792379
test_cmp expected-list actual-list
23802380
'
23812381

2382+
test_expect_success $PREREQ 'mailmap support with --to' '
2383+
clean_fake_sendmail &&
2384+
test_config mailmap.file "mailmap.test" &&
2385+
cat >mailmap.test <<-EOF &&
2386+
2387+
EOF
2388+
git format-patch --stdout -1 >a.patch &&
2389+
git send-email \
2390+
--from="Example <[email protected]>" \
2391+
--smtp-server="$(pwd)/fake.sendmail" \
2392+
2393+
--mailmap \
2394+
a.patch \
2395+
2>errors >out &&
2396+
grep "^!someone@example\.com!$" commandline1
2397+
'
2398+
2399+
test_expect_success $PREREQ 'sendemail.mailmap configuration' '
2400+
clean_fake_sendmail &&
2401+
test_config mailmap.file "mailmap.test" &&
2402+
test_config sendemail.mailmap "true" &&
2403+
cat >mailmap.test <<-EOF &&
2404+
2405+
EOF
2406+
git format-patch --stdout -1 >a.patch &&
2407+
git send-email \
2408+
--from="Example <[email protected]>" \
2409+
--smtp-server="$(pwd)/fake.sendmail" \
2410+
2411+
a.patch \
2412+
2>errors >out &&
2413+
grep "^!someone@example\.com!$" commandline1
2414+
'
2415+
2416+
test_expect_success $PREREQ 'sendemail.mailmap.file configuration' '
2417+
clean_fake_sendmail &&
2418+
test_config sendemail.mailmap.file "mailmap.test" &&
2419+
test_config sendemail.mailmap "true" &&
2420+
cat >mailmap.test <<-EOF &&
2421+
2422+
EOF
2423+
git format-patch --stdout -1 >a.patch &&
2424+
git send-email \
2425+
--from="Example <[email protected]>" \
2426+
--smtp-server="$(pwd)/fake.sendmail" \
2427+
2428+
a.patch \
2429+
2>errors >out &&
2430+
grep "^!someone@example\.com!$" commandline1
2431+
'
2432+
2433+
test_expect_success $PREREQ 'sendemail.mailmap identity overrides configuration' '
2434+
clean_fake_sendmail &&
2435+
test_config sendemail.cloud.mailmap.file "mailmap.test" &&
2436+
test_config sendemail.mailmap "false" &&
2437+
test_config sendemail.cloud.mailmap "true" &&
2438+
cat >mailmap.test <<-EOF &&
2439+
2440+
EOF
2441+
git format-patch --stdout -1 >a.patch &&
2442+
git send-email \
2443+
--from="Example <[email protected]>" \
2444+
--smtp-server="$(pwd)/fake.sendmail" \
2445+
--identity=cloud \
2446+
2447+
a.patch \
2448+
2>errors >out &&
2449+
grep "^!someone@example\.com!$" commandline1
2450+
'
2451+
2452+
test_expect_success $PREREQ '--no-mailmap overrides configuration' '
2453+
clean_fake_sendmail &&
2454+
test_config sendemail.cloud.mailmap.file "mailmap.test" &&
2455+
test_config sendemail.mailmap "false" &&
2456+
test_config sendemail.cloud.mailmap "true" &&
2457+
cat >mailmap.test <<-EOF &&
2458+
2459+
EOF
2460+
git format-patch --stdout -1 >a.patch &&
2461+
git send-email \
2462+
--from="Example <[email protected]>" \
2463+
--smtp-server="$(pwd)/fake.sendmail" \
2464+
--identity=cloud \
2465+
2466+
--no-mailmap \
2467+
a.patch \
2468+
2>errors >out &&
2469+
grep "^!someone@example\.org!$" commandline1
2470+
'
2471+
2472+
test_expect_success $PREREQ 'mailmap support in To header' '
2473+
clean_fake_sendmail &&
2474+
test_config mailmap.file "mailmap.test" &&
2475+
cat >mailmap.test <<-EOF &&
2476+
2477+
EOF
2478+
git format-patch --stdout -1 [email protected] >a.patch &&
2479+
git send-email \
2480+
--from="Example <[email protected]>" \
2481+
--smtp-server="$(pwd)/fake.sendmail" \
2482+
--mailmap \
2483+
a.patch \
2484+
2>errors >out &&
2485+
grep "^!someone@example\.com!$" commandline1
2486+
'
2487+
2488+
test_expect_success $PREREQ 'mailmap support in Cc header' '
2489+
clean_fake_sendmail &&
2490+
test_config mailmap.file "mailmap.test" &&
2491+
cat >mailmap.test <<-EOF &&
2492+
2493+
EOF
2494+
git format-patch --stdout -1 [email protected] >a.patch &&
2495+
git send-email \
2496+
--from="Example <[email protected]>" \
2497+
--smtp-server="$(pwd)/fake.sendmail" \
2498+
--mailmap \
2499+
a.patch \
2500+
2>errors >out &&
2501+
grep "^!someone@example\.com!$" commandline1
2502+
'
2503+
23822504
test_expect_success $PREREQ 'test using command name with --sendmail-cmd' '
23832505
clean_fake_sendmail &&
23842506
PATH="$PWD:$PATH" \

0 commit comments

Comments
 (0)