Skip to content

Commit d551a48

Browse files
Marius Storm-Olsengitster
authored andcommitted
Add mailmap.file as configurational option for mailmap location
This allows us to augment the repo mailmap file, and to use mailmap files elsewhere than the repository root. Meaning that the entries in mailmap.file will override the entries in "./.mailmap", should they match. Signed-off-by: Marius Storm-Olsen <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 88ccb9f commit d551a48

File tree

10 files changed

+147
-7
lines changed

10 files changed

+147
-7
lines changed

Documentation/config.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,6 +1012,14 @@ log.showroot::
10121012
Tools like linkgit:git-log[1] or linkgit:git-whatchanged[1], which
10131013
normally hide the root commit will now show it. True by default.
10141014

1015+
mailmap.file::
1016+
The location of an augmenting mailmap file. The default
1017+
mailmap, located in the root of the repository, is loaded
1018+
first, then the mailmap file pointed to by this variable.
1019+
The location of the mailmap file may be in a repository
1020+
subdirectory, or somewhere outside of the repository itself.
1021+
See linkgit:git-shortlog[1] and linkgit:git-blame[1].
1022+
10151023
man.viewer::
10161024
Specify the programs that may be used to display help in the
10171025
'man' format. See linkgit:git-help[1].

Documentation/git-shortlog.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ OPTIONS
4848
FILES
4949
-----
5050

51-
If a file `.mailmap` exists at the toplevel of the repository,
51+
If a file `.mailmap` exists at the toplevel of the repository, or at the
52+
location pointed to by the log.mailmap configuration option,
5253
it is used to map an author email address to a canonical real name. This
5354
can be used to coalesce together commits by the same person where their
5455
name was spelled differently (whether with the same email address or

builtin-blame.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2394,7 +2394,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
23942394
die("reading graft file %s failed: %s",
23952395
revs_file, strerror(errno));
23962396

2397-
read_mailmap(&mailmap, ".mailmap", NULL);
2397+
read_mailmap(&mailmap, NULL);
23982398

23992399
if (!incremental)
24002400
setup_pager();

builtin-shortlog.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ void shortlog_init(struct shortlog *log)
219219
{
220220
memset(log, 0, sizeof(*log));
221221

222-
read_mailmap(&log->mailmap, ".mailmap", &log->common_repo_prefix);
222+
read_mailmap(&log->mailmap, &log->common_repo_prefix);
223223

224224
log->list.strdup_strings = 1;
225225
log->wrap = DEFAULT_WRAPLEN;
@@ -248,6 +248,7 @@ int cmd_shortlog(int argc, const char **argv, const char *prefix)
248248
struct parse_opt_ctx_t ctx;
249249

250250
prefix = setup_git_directory_gently(&nongit);
251+
git_config(git_default_config, NULL);
251252
shortlog_init(&log);
252253
init_revisions(&rev, prefix);
253254
parse_options_start(&ctx, argc, argv, PARSE_OPT_KEEP_DASHDASH |

cache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -867,6 +867,7 @@ extern int user_ident_explicitly_given;
867867

868868
extern const char *git_commit_encoding;
869869
extern const char *git_log_output_encoding;
870+
extern const char *git_mailmap_file;
870871

871872
/* IO helper functions */
872873
extern void maybe_flush_or_die(FILE *, const char *);

config.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,15 @@ static int git_default_branch_config(const char *var, const char *value)
565565
return 0;
566566
}
567567

568+
static int git_default_mailmap_config(const char *var, const char *value)
569+
{
570+
if (!strcmp(var, "mailmap.file"))
571+
return git_config_string(&git_mailmap_file, var, value);
572+
573+
/* Add other config variables here and to Documentation/config.txt. */
574+
return 0;
575+
}
576+
568577
int git_default_config(const char *var, const char *value, void *dummy)
569578
{
570579
if (!prefixcmp(var, "core."))
@@ -579,6 +588,9 @@ int git_default_config(const char *var, const char *value, void *dummy)
579588
if (!prefixcmp(var, "branch."))
580589
return git_default_branch_config(var, value);
581590

591+
if (!prefixcmp(var, "mailmap."))
592+
return git_default_mailmap_config(var, value);
593+
582594
if (!strcmp(var, "pager.color") || !strcmp(var, "color.pager")) {
583595
pager_use_color = git_config_bool(var,value);
584596
return 0;

mailmap.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22
#include "string-list.h"
33
#include "mailmap.h"
44

5-
int read_mailmap(struct string_list *map, const char *filename, char **repo_abbrev)
5+
const char *git_mailmap_file;
6+
static int read_single_mailmap(struct string_list *map, const char *filename, char **repo_abbrev)
67
{
78
char buffer[1024];
8-
FILE *f = fopen(filename, "r");
9+
FILE *f = (filename == NULL ? NULL : fopen(filename, "r"));
910

1011
if (f == NULL)
1112
return 1;
@@ -60,6 +61,13 @@ int read_mailmap(struct string_list *map, const char *filename, char **repo_abbr
6061
return 0;
6162
}
6263

64+
int read_mailmap(struct string_list *map, char **repo_abbrev)
65+
{
66+
/* each failure returns 1, so >1 means both calls failed */
67+
return read_single_mailmap(map, ".mailmap", repo_abbrev) +
68+
read_single_mailmap(map, git_mailmap_file, repo_abbrev) > 1;
69+
}
70+
6371
int map_email(struct string_list *map, const char *email, char *name, int maxlen)
6472
{
6573
char *p;

mailmap.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#ifndef MAILMAP_H
22
#define MAILMAP_H
33

4-
int read_mailmap(struct string_list *map, const char *filename, char **repo_abbrev);
4+
int read_mailmap(struct string_list *map, char **repo_abbrev);
55
int map_email(struct string_list *mailmap, const char *email, char *name, int maxlen);
66

77
#endif

pretty.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ static int mailmap_name(struct strbuf *sb, const char *email)
312312

313313
if (!mail_map) {
314314
mail_map = xcalloc(1, sizeof(*mail_map));
315-
read_mailmap(mail_map, ".mailmap", NULL);
315+
read_mailmap(mail_map, NULL);
316316
}
317317

318318
if (!mail_map->nr)

t/t4203-mailmap.sh

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
#!/bin/sh
2+
3+
test_description='.mailmap configurations'
4+
5+
. ./test-lib.sh
6+
7+
test_expect_success setup '
8+
echo one >one &&
9+
git add one &&
10+
test_tick &&
11+
git commit -m initial &&
12+
echo two >>one &&
13+
git add one &&
14+
git commit --author "nick1 <[email protected]>" -m second
15+
'
16+
17+
cat >expect <<\EOF
18+
A U Thor (1):
19+
initial
20+
21+
nick1 (1):
22+
second
23+
24+
EOF
25+
26+
test_expect_success 'No mailmap' '
27+
git shortlog HEAD >actual &&
28+
test_cmp expect actual
29+
'
30+
31+
cat >expect <<\EOF
32+
Repo Guy (1):
33+
initial
34+
35+
nick1 (1):
36+
second
37+
38+
EOF
39+
40+
test_expect_success 'default .mailmap' '
41+
echo "Repo Guy <[email protected]>" > .mailmap &&
42+
git shortlog HEAD >actual &&
43+
test_cmp expect actual
44+
'
45+
46+
# Using a mailmap file in a subdirectory of the repo here, but
47+
# could just as well have been a file outside of the repository
48+
cat >expect <<\EOF
49+
Internal Guy (1):
50+
second
51+
52+
Repo Guy (1):
53+
initial
54+
55+
EOF
56+
test_expect_success 'mailmap.file set' '
57+
mkdir internal_mailmap &&
58+
echo "Internal Guy <[email protected]>" > internal_mailmap/.mailmap &&
59+
git config mailmap.file internal_mailmap/.mailmap &&
60+
git shortlog HEAD >actual &&
61+
test_cmp expect actual
62+
'
63+
64+
cat >expect <<\EOF
65+
External Guy (1):
66+
initial
67+
68+
Internal Guy (1):
69+
second
70+
71+
EOF
72+
test_expect_success 'mailmap.file override' '
73+
echo "External Guy <[email protected]>" >> internal_mailmap/.mailmap &&
74+
git config mailmap.file internal_mailmap/.mailmap &&
75+
git shortlog HEAD >actual &&
76+
test_cmp expect actual
77+
'
78+
79+
cat >expect <<\EOF
80+
Repo Guy (1):
81+
initial
82+
83+
nick1 (1):
84+
second
85+
86+
EOF
87+
88+
test_expect_success 'mailmap.file non-existant' '
89+
rm internal_mailmap/.mailmap &&
90+
rmdir internal_mailmap &&
91+
git shortlog HEAD >actual &&
92+
test_cmp expect actual
93+
'
94+
95+
cat >expect <<\EOF
96+
A U Thor (1):
97+
initial
98+
99+
nick1 (1):
100+
second
101+
102+
EOF
103+
test_expect_success 'No mailmap files, but configured' '
104+
rm .mailmap &&
105+
git shortlog HEAD >actual &&
106+
test_cmp expect actual
107+
'
108+
109+
test_done

0 commit comments

Comments
 (0)