mailmap: support reading mailmap from blobs
In a bare repository, there isn't a simple way to respect an in-tree mailmap without extracting it to a temporary file. This patch provides a config variable, similar to mailmap.file, which reads the mailmap from a blob in the repository. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
7c8ce308d3
commit
086109006f
@ -1517,6 +1517,12 @@ mailmap.file::
|
|||||||
subdirectory, or somewhere outside of the repository itself.
|
subdirectory, or somewhere outside of the repository itself.
|
||||||
See linkgit:git-shortlog[1] and linkgit:git-blame[1].
|
See linkgit:git-shortlog[1] and linkgit:git-blame[1].
|
||||||
|
|
||||||
|
mailmap.blob::
|
||||||
|
Like `mailmap.file`, but consider the value as a reference to a
|
||||||
|
blob in the repository (e.g., `HEAD:.mailmap`). If both
|
||||||
|
`mailmap.file` and `mailmap.blob` are given, both are parsed,
|
||||||
|
with entries from `mailmap.file` taking precedence.
|
||||||
|
|
||||||
man.viewer::
|
man.viewer::
|
||||||
Specify the programs that may be used to display help in the
|
Specify the programs that may be used to display help in the
|
||||||
'man' format. See linkgit:git-help[1].
|
'man' format. See linkgit:git-help[1].
|
||||||
|
1
cache.h
1
cache.h
@ -1155,6 +1155,7 @@ extern int author_ident_sufficiently_given(void);
|
|||||||
extern const char *git_commit_encoding;
|
extern const char *git_commit_encoding;
|
||||||
extern const char *git_log_output_encoding;
|
extern const char *git_log_output_encoding;
|
||||||
extern const char *git_mailmap_file;
|
extern const char *git_mailmap_file;
|
||||||
|
extern const char *git_mailmap_blob;
|
||||||
|
|
||||||
/* IO helper functions */
|
/* IO helper functions */
|
||||||
extern void maybe_flush_or_die(FILE *, const char *);
|
extern void maybe_flush_or_die(FILE *, const char *);
|
||||||
|
2
config.c
2
config.c
@ -839,6 +839,8 @@ static int git_default_mailmap_config(const char *var, const char *value)
|
|||||||
{
|
{
|
||||||
if (!strcmp(var, "mailmap.file"))
|
if (!strcmp(var, "mailmap.file"))
|
||||||
return git_config_string(&git_mailmap_file, var, value);
|
return git_config_string(&git_mailmap_file, var, value);
|
||||||
|
if (!strcmp(var, "mailmap.blob"))
|
||||||
|
return git_config_string(&git_mailmap_blob, var, value);
|
||||||
|
|
||||||
/* Add other config variables here and to Documentation/config.txt. */
|
/* Add other config variables here and to Documentation/config.txt. */
|
||||||
return 0;
|
return 0;
|
||||||
|
49
mailmap.c
49
mailmap.c
@ -10,6 +10,7 @@ static inline void debug_mm(const char *format, ...) {}
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
const char *git_mailmap_file;
|
const char *git_mailmap_file;
|
||||||
|
const char *git_mailmap_blob;
|
||||||
|
|
||||||
struct mailmap_info {
|
struct mailmap_info {
|
||||||
char *name;
|
char *name;
|
||||||
@ -177,12 +178,56 @@ static int read_mailmap_file(struct string_list *map, const char *filename,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void read_mailmap_buf(struct string_list *map,
|
||||||
|
const char *buf, unsigned long len,
|
||||||
|
char **repo_abbrev)
|
||||||
|
{
|
||||||
|
while (len) {
|
||||||
|
const char *end = strchrnul(buf, '\n');
|
||||||
|
unsigned long linelen = end - buf + 1;
|
||||||
|
char *line = xmemdupz(buf, linelen);
|
||||||
|
|
||||||
|
read_mailmap_line(map, line, repo_abbrev);
|
||||||
|
|
||||||
|
free(line);
|
||||||
|
buf += linelen;
|
||||||
|
len -= linelen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int read_mailmap_blob(struct string_list *map,
|
||||||
|
const char *name,
|
||||||
|
char **repo_abbrev)
|
||||||
|
{
|
||||||
|
unsigned char sha1[20];
|
||||||
|
char *buf;
|
||||||
|
unsigned long size;
|
||||||
|
enum object_type type;
|
||||||
|
|
||||||
|
if (!name)
|
||||||
|
return 1;
|
||||||
|
if (get_sha1(name, sha1) < 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
buf = read_sha1_file(sha1, &type, &size);
|
||||||
|
if (!buf)
|
||||||
|
return 1;
|
||||||
|
if (type != OBJ_BLOB)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
read_mailmap_buf(map, buf, size, repo_abbrev);
|
||||||
|
|
||||||
|
free(buf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int read_mailmap(struct string_list *map, char **repo_abbrev)
|
int read_mailmap(struct string_list *map, char **repo_abbrev)
|
||||||
{
|
{
|
||||||
map->strdup_strings = 1;
|
map->strdup_strings = 1;
|
||||||
/* each failure returns 1, so >1 means both calls failed */
|
/* each failure returns 1, so >2 means all calls failed */
|
||||||
return read_mailmap_file(map, ".mailmap", repo_abbrev) +
|
return read_mailmap_file(map, ".mailmap", repo_abbrev) +
|
||||||
read_mailmap_file(map, git_mailmap_file, repo_abbrev) > 1;
|
read_mailmap_blob(map, git_mailmap_blob, repo_abbrev) +
|
||||||
|
read_mailmap_file(map, git_mailmap_file, repo_abbrev) > 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear_mailmap(struct string_list *map)
|
void clear_mailmap(struct string_list *map)
|
||||||
|
@ -149,6 +149,79 @@ test_expect_success 'No mailmap files, but configured' '
|
|||||||
test_cmp expect actual
|
test_cmp expect actual
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'setup mailmap blob tests' '
|
||||||
|
git checkout -b map &&
|
||||||
|
test_when_finished "git checkout master" &&
|
||||||
|
cat >just-bugs <<-\EOF &&
|
||||||
|
Blob Guy <bugs@company.xx>
|
||||||
|
EOF
|
||||||
|
cat >both <<-\EOF &&
|
||||||
|
Blob Guy <author@example.com>
|
||||||
|
Blob Guy <bugs@company.xx>
|
||||||
|
EOF
|
||||||
|
git add just-bugs both &&
|
||||||
|
git commit -m "my mailmaps" &&
|
||||||
|
echo "Repo Guy <author@example.com>" >.mailmap &&
|
||||||
|
echo "Internal Guy <author@example.com>" >internal.map
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'mailmap.blob set' '
|
||||||
|
cat >expect <<-\EOF &&
|
||||||
|
Blob Guy (1):
|
||||||
|
second
|
||||||
|
|
||||||
|
Repo Guy (1):
|
||||||
|
initial
|
||||||
|
|
||||||
|
EOF
|
||||||
|
git -c mailmap.blob=map:just-bugs shortlog HEAD >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'mailmap.blob overrides .mailmap' '
|
||||||
|
cat >expect <<-\EOF &&
|
||||||
|
Blob Guy (2):
|
||||||
|
initial
|
||||||
|
second
|
||||||
|
|
||||||
|
EOF
|
||||||
|
git -c mailmap.blob=map:both shortlog HEAD >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'mailmap.file overrides mailmap.blob' '
|
||||||
|
cat >expect <<-\EOF &&
|
||||||
|
Blob Guy (1):
|
||||||
|
second
|
||||||
|
|
||||||
|
Internal Guy (1):
|
||||||
|
initial
|
||||||
|
|
||||||
|
EOF
|
||||||
|
git \
|
||||||
|
-c mailmap.blob=map:both \
|
||||||
|
-c mailmap.file=internal.map \
|
||||||
|
shortlog HEAD >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'mailmap.blob can be missing' '
|
||||||
|
cat >expect <<-\EOF &&
|
||||||
|
Repo Guy (1):
|
||||||
|
initial
|
||||||
|
|
||||||
|
nick1 (1):
|
||||||
|
second
|
||||||
|
|
||||||
|
EOF
|
||||||
|
git -c mailmap.blob=map:nonexistent shortlog HEAD >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'cleanup after mailmap.blob tests' '
|
||||||
|
rm -f .mailmap
|
||||||
|
'
|
||||||
|
|
||||||
# Extended mailmap configurations should give us the following output for shortlog
|
# Extended mailmap configurations should give us the following output for shortlog
|
||||||
cat >expect <<\EOF
|
cat >expect <<\EOF
|
||||||
A U Thor <author@example.com> (1):
|
A U Thor <author@example.com> (1):
|
||||||
|
Loading…
Reference in New Issue
Block a user