From d551a488169aeb2ac09dba781f2ffbecf3425996 Mon Sep 17 00:00:00 2001 From: Marius Storm-Olsen Date: Sun, 8 Feb 2009 15:34:27 +0100 Subject: [PATCH] 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 Signed-off-by: Junio C Hamano --- Documentation/config.txt | 8 +++ Documentation/git-shortlog.txt | 3 +- builtin-blame.c | 2 +- builtin-shortlog.c | 3 +- cache.h | 1 + config.c | 12 ++++ mailmap.c | 12 +++- mailmap.h | 2 +- pretty.c | 2 +- t/t4203-mailmap.sh | 109 +++++++++++++++++++++++++++++++++ 10 files changed, 147 insertions(+), 7 deletions(-) create mode 100755 t/t4203-mailmap.sh diff --git a/Documentation/config.txt b/Documentation/config.txt index e2b8775dd..6dd57bd52 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -1012,6 +1012,14 @@ log.showroot:: Tools like linkgit:git-log[1] or linkgit:git-whatchanged[1], which normally hide the root commit will now show it. True by default. +mailmap.file:: + The location of an augmenting mailmap file. The default + mailmap, located in the root of the repository, is loaded + first, then the mailmap file pointed to by this variable. + The location of the mailmap file may be in a repository + subdirectory, or somewhere outside of the repository itself. + See linkgit:git-shortlog[1] and linkgit:git-blame[1]. + man.viewer:: Specify the programs that may be used to display help in the 'man' format. See linkgit:git-help[1]. diff --git a/Documentation/git-shortlog.txt b/Documentation/git-shortlog.txt index 498bd2892..66b604584 100644 --- a/Documentation/git-shortlog.txt +++ b/Documentation/git-shortlog.txt @@ -48,7 +48,8 @@ OPTIONS FILES ----- -If a file `.mailmap` exists at the toplevel of the repository, +If a file `.mailmap` exists at the toplevel of the repository, or at the +location pointed to by the log.mailmap configuration option, it is used to map an author email address to a canonical real name. This can be used to coalesce together commits by the same person where their name was spelled differently (whether with the same email address or diff --git a/builtin-blame.c b/builtin-blame.c index aae14ef8b..19edcf33b 100644 --- a/builtin-blame.c +++ b/builtin-blame.c @@ -2394,7 +2394,7 @@ parse_done: die("reading graft file %s failed: %s", revs_file, strerror(errno)); - read_mailmap(&mailmap, ".mailmap", NULL); + read_mailmap(&mailmap, NULL); if (!incremental) setup_pager(); diff --git a/builtin-shortlog.c b/builtin-shortlog.c index 5f9f3f09b..314b6bc5c 100644 --- a/builtin-shortlog.c +++ b/builtin-shortlog.c @@ -219,7 +219,7 @@ void shortlog_init(struct shortlog *log) { memset(log, 0, sizeof(*log)); - read_mailmap(&log->mailmap, ".mailmap", &log->common_repo_prefix); + read_mailmap(&log->mailmap, &log->common_repo_prefix); log->list.strdup_strings = 1; log->wrap = DEFAULT_WRAPLEN; @@ -248,6 +248,7 @@ int cmd_shortlog(int argc, const char **argv, const char *prefix) struct parse_opt_ctx_t ctx; prefix = setup_git_directory_gently(&nongit); + git_config(git_default_config, NULL); shortlog_init(&log); init_revisions(&rev, prefix); parse_options_start(&ctx, argc, argv, PARSE_OPT_KEEP_DASHDASH | diff --git a/cache.h b/cache.h index 45e713e92..e88bcca96 100644 --- a/cache.h +++ b/cache.h @@ -867,6 +867,7 @@ extern int user_ident_explicitly_given; extern const char *git_commit_encoding; extern const char *git_log_output_encoding; +extern const char *git_mailmap_file; /* IO helper functions */ extern void maybe_flush_or_die(FILE *, const char *); diff --git a/config.c b/config.c index 790405a21..0c8c76f13 100644 --- a/config.c +++ b/config.c @@ -565,6 +565,15 @@ static int git_default_branch_config(const char *var, const char *value) return 0; } +static int git_default_mailmap_config(const char *var, const char *value) +{ + if (!strcmp(var, "mailmap.file")) + return git_config_string(&git_mailmap_file, var, value); + + /* Add other config variables here and to Documentation/config.txt. */ + return 0; +} + int git_default_config(const char *var, const char *value, void *dummy) { if (!prefixcmp(var, "core.")) @@ -579,6 +588,9 @@ int git_default_config(const char *var, const char *value, void *dummy) if (!prefixcmp(var, "branch.")) return git_default_branch_config(var, value); + if (!prefixcmp(var, "mailmap.")) + return git_default_mailmap_config(var, value); + if (!strcmp(var, "pager.color") || !strcmp(var, "color.pager")) { pager_use_color = git_config_bool(var,value); return 0; diff --git a/mailmap.c b/mailmap.c index 88fc6f394..d006dad67 100644 --- a/mailmap.c +++ b/mailmap.c @@ -2,10 +2,11 @@ #include "string-list.h" #include "mailmap.h" -int read_mailmap(struct string_list *map, const char *filename, char **repo_abbrev) +const char *git_mailmap_file; +static int read_single_mailmap(struct string_list *map, const char *filename, char **repo_abbrev) { char buffer[1024]; - FILE *f = fopen(filename, "r"); + FILE *f = (filename == NULL ? NULL : fopen(filename, "r")); if (f == NULL) return 1; @@ -60,6 +61,13 @@ int read_mailmap(struct string_list *map, const char *filename, char **repo_abbr return 0; } +int read_mailmap(struct string_list *map, char **repo_abbrev) +{ + /* each failure returns 1, so >1 means both calls failed */ + return read_single_mailmap(map, ".mailmap", repo_abbrev) + + read_single_mailmap(map, git_mailmap_file, repo_abbrev) > 1; +} + int map_email(struct string_list *map, const char *email, char *name, int maxlen) { char *p; diff --git a/mailmap.h b/mailmap.h index 6e48f83ce..ba2ee7670 100644 --- a/mailmap.h +++ b/mailmap.h @@ -1,7 +1,7 @@ #ifndef MAILMAP_H #define MAILMAP_H -int read_mailmap(struct string_list *map, const char *filename, char **repo_abbrev); +int read_mailmap(struct string_list *map, char **repo_abbrev); int map_email(struct string_list *mailmap, const char *email, char *name, int maxlen); #endif diff --git a/pretty.c b/pretty.c index cc460b569..9e03d6ae2 100644 --- a/pretty.c +++ b/pretty.c @@ -312,7 +312,7 @@ static int mailmap_name(struct strbuf *sb, const char *email) if (!mail_map) { mail_map = xcalloc(1, sizeof(*mail_map)); - read_mailmap(mail_map, ".mailmap", NULL); + read_mailmap(mail_map, NULL); } if (!mail_map->nr) diff --git a/t/t4203-mailmap.sh b/t/t4203-mailmap.sh new file mode 100755 index 000000000..fc50ac22e --- /dev/null +++ b/t/t4203-mailmap.sh @@ -0,0 +1,109 @@ +#!/bin/sh + +test_description='.mailmap configurations' + +. ./test-lib.sh + +test_expect_success setup ' + echo one >one && + git add one && + test_tick && + git commit -m initial && + echo two >>one && + git add one && + git commit --author "nick1 " -m second +' + +cat >expect <<\EOF +A U Thor (1): + initial + +nick1 (1): + second + +EOF + +test_expect_success 'No mailmap' ' + git shortlog HEAD >actual && + test_cmp expect actual +' + +cat >expect <<\EOF +Repo Guy (1): + initial + +nick1 (1): + second + +EOF + +test_expect_success 'default .mailmap' ' + echo "Repo Guy " > .mailmap && + git shortlog HEAD >actual && + test_cmp expect actual +' + +# Using a mailmap file in a subdirectory of the repo here, but +# could just as well have been a file outside of the repository +cat >expect <<\EOF +Internal Guy (1): + second + +Repo Guy (1): + initial + +EOF +test_expect_success 'mailmap.file set' ' + mkdir internal_mailmap && + echo "Internal Guy " > internal_mailmap/.mailmap && + git config mailmap.file internal_mailmap/.mailmap && + git shortlog HEAD >actual && + test_cmp expect actual +' + +cat >expect <<\EOF +External Guy (1): + initial + +Internal Guy (1): + second + +EOF +test_expect_success 'mailmap.file override' ' + echo "External Guy " >> internal_mailmap/.mailmap && + git config mailmap.file internal_mailmap/.mailmap && + git shortlog HEAD >actual && + test_cmp expect actual +' + +cat >expect <<\EOF +Repo Guy (1): + initial + +nick1 (1): + second + +EOF + +test_expect_success 'mailmap.file non-existant' ' + rm internal_mailmap/.mailmap && + rmdir internal_mailmap && + git shortlog HEAD >actual && + test_cmp expect actual +' + +cat >expect <<\EOF +A U Thor (1): + initial + +nick1 (1): + second + +EOF +test_expect_success 'No mailmap files, but configured' ' + rm .mailmap && + git shortlog HEAD >actual && + test_cmp expect actual +' + +test_done -- 2.30.2