Add mailmap.file as configurational option for mailmap location
authorMarius Storm-Olsen <marius@trolltech.com>
Sun, 8 Feb 2009 14:34:27 +0000 (15:34 +0100)
committerJunio C Hamano <gitster@pobox.com>
Sun, 8 Feb 2009 20:36:26 +0000 (12:36 -0800)
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 <marius@trolltech.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/config.txt
Documentation/git-shortlog.txt
builtin-blame.c
builtin-shortlog.c
cache.h
config.c
mailmap.c
mailmap.h
pretty.c
t/t4203-mailmap.sh [new file with mode: 0755]

index e2b8775..6dd57bd 100644 (file)
@@ -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].
index 498bd28..66b6045 100644 (file)
@@ -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
index aae14ef..19edcf3 100644 (file)
@@ -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();
index 5f9f3f0..314b6bc 100644 (file)
@@ -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 45e713e..e88bcca 100644 (file)
--- 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 *);
index 790405a..0c8c76f 100644 (file)
--- 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;
index 88fc6f3..d006dad 100644 (file)
--- 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;
index 6e48f83..ba2ee76 100644 (file)
--- 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
index cc460b5..9e03d6a 100644 (file)
--- 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 (executable)
index 0000000..fc50ac2
--- /dev/null
@@ -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 <bugs@company.xx>" -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 <author@example.com>" > .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 <bugs@company.xx>" > 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 <author@example.com>" >> 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