If a mailmap file is present in the repo, it will be used to coalesce
commits by the same person, just like git does. When no mailmap file is
found then it functions as before.
Signed-off-by: Jason A. Smith <[email protected]>
---
cgit.h | 2 ++
parsing.c | 39 +++++++++++++++++++++++++++++++++++++++
ui-atom.c | 9 +++++++--
ui-commit.c | 4 ++++
ui-log.c | 4 ++++
ui-stats.c | 8 ++++++--
6 files changed, 62 insertions(+), 4 deletions(-)
diff --git a/cgit.h b/cgit.h
index 325432b..cd89c36 100644
--- a/cgit.h
+++ b/cgit.h
@@ -24,6 +24,7 @@
#include <utf8.h>
#include <notes.h>
#include <graph.h>
+#include <mailmap.h>
/* Add isgraph(x) to Git's sane ctype support (see git-compat-util.h) */
#undef isgraph
@@ -370,6 +371,7 @@ extern char *fmtalloc(const char *format,...);
extern struct commitinfo *cgit_parse_commit(struct commit *commit);
extern struct taginfo *cgit_parse_tag(struct tag *tag);
extern void cgit_parse_url(const char *url);
+extern int cgit_map_user(struct string_list *map, char **email, char **name);
extern const char *cgit_repobasename(const char *reponame);
diff --git a/parsing.c b/parsing.c
index 9dacb16..4113d98 100644
--- a/parsing.c
+++ b/parsing.c
@@ -88,6 +88,45 @@ static void parse_user(const char *t, char **name, char **email, unsigned long *
}
}
+/*
+ * Cgit surrounds the email address with angle brackets while git does not.
+ * Copy the email address, remove the angle brackets, perform the mailmap
+ * user lookup and finally replace the name and email address with the new
+ * values, and put the angle brackets back around the email.
+ */
+int cgit_map_user(struct string_list *map, char **email, char **name)
+{
+ char *map_email, *map_name;
+ size_t emaillen, namelen;
+ int ret;
+
+ emaillen = strlen(*email);
+ namelen = strlen(*name);
+ map_email = xmalloc(emaillen + 1);
+ map_name = xmalloc(namelen + 1);
+ strncpy(map_email, *email, emaillen + 1);
+ strncpy(map_name, *name, namelen + 1);
+ memmove(map_email, map_email+1, emaillen-2);
+ map_email[emaillen-2] = '\0';
+ emaillen = emaillen - 2;
+ ret = map_user(map, (const char**)&map_email, &emaillen,
+ (const char**)&map_name, &namelen);
+ if (ret) {
+ *email = xmalloc(strlen("<") + emaillen + strlen(">") + 1);
+ sprintf(*email, "<%.*s>", (int)emaillen, map_email);
+ *name = xmalloc(namelen + 1);
+ strncpy(*name, map_name, namelen + 1);
+ } else {
+ /*
+ * When a mapping is found they are pointing to the
+ * actual mailmap list entry and cannot be freed.
+ */
+ free(map_email);
+ free(map_name);
+ }
+ return ret;
+}
+
#ifdef NO_ICONV
#define reencode(a, b, c)
#else
diff --git a/ui-atom.c b/ui-atom.c
index 41838d3..c22b30d 100644
--- a/ui-atom.c
+++ b/ui-atom.c
@@ -11,7 +11,8 @@
#include "html.h"
#include "ui-shared.h"
-static void add_entry(struct commit *commit, const char *host)
+static void add_entry(struct commit *commit, const char *host,
+ struct string_list *mailmap)
{
char delim = '&';
char *hex;
@@ -19,6 +20,7 @@ static void add_entry(struct commit *commit, const char *host)
struct commitinfo *info;
info = cgit_parse_commit(commit);
+ cgit_map_user(mailmap, &(info->author_email), &(info->author));
hex = oid_to_hex(&commit->object.oid);
html("<entry>\n");
html("<title>");
@@ -89,6 +91,7 @@ void cgit_print_atom(char *tip, char *path, int max_count)
const char *argv[] = {NULL, tip, NULL, NULL, NULL};
struct commit *commit;
struct rev_info rev;
+ struct string_list mailmap = STRING_LIST_INIT_NODUP;
int argc = 2;
if (ctx.qry.show_all)
@@ -108,6 +111,8 @@ void cgit_print_atom(char *tip, char *path, int max_count)
rev.show_root_diff = 0;
rev.max_count = max_count;
setup_revisions(argc, argv, &rev, NULL);
+ read_mailmap(&mailmap, NULL);
+ rev.mailmap = &mailmap;
prepare_revision_walk(&rev);
host = cgit_hosturl();
@@ -139,7 +144,7 @@ void cgit_print_atom(char *tip, char *path, int max_count)
free(repourl);
}
while ((commit = get_revision(&rev)) != NULL) {
- add_entry(commit, host);
+ add_entry(commit, host, &mailmap);
free_commit_buffer(commit);
free_commit_list(commit->parents);
commit->parents = NULL;
diff --git a/ui-commit.c b/ui-commit.c
index 099d294..85389a0 100644
--- a/ui-commit.c
+++ b/ui-commit.c
@@ -18,6 +18,7 @@ void cgit_print_commit(char *hex, const char *prefix)
struct commit *commit, *parent;
struct commitinfo *info, *parent_info;
struct commit_list *p;
+ struct string_list mailmap = STRING_LIST_INIT_NODUP;
struct strbuf notes = STRBUF_INIT;
unsigned char sha1[20];
char *tmp, *tmp2;
@@ -38,6 +39,9 @@ void cgit_print_commit(char *hex, const char *prefix)
return;
}
info = cgit_parse_commit(commit);
+ read_mailmap(&mailmap, NULL);
+ cgit_map_user(&mailmap, &(info->author_email), &(info->author));
+ cgit_map_user(&mailmap, &(info->committer_email), &(info->committer));
format_display_notes(sha1, ¬es, PAGE_ENCODING, 0);
diff --git a/ui-log.c b/ui-log.c
index c97b8e0..dedab8e 100644
--- a/ui-log.c
+++ b/ui-log.c
@@ -238,6 +238,7 @@ static void print_commit(struct commit *commit, struct rev_info *revs)
oid_to_hex(&commit->object.oid), ctx.qry.vpath);
show_commit_decorations(commit);
html("</td><td>");
+ cgit_map_user(revs->mailmap, &(info->author_email), &(info->author));
cgit_open_filter(ctx.repo->email_filter, info->author_email, "log");
html_txt(info->author);
cgit_close_filter(ctx.repo->email_filter);
@@ -360,6 +361,7 @@ static char *next_token(char **src)
void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern,
char *path, int pager, int commit_graph, int commit_sort)
{
+ struct string_list mailmap = STRING_LIST_INIT_NODUP;
struct rev_info rev;
struct commit *commit;
struct argv_array rev_argv = ARGV_ARRAY_INIT;
@@ -443,6 +445,8 @@ void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern
DIFF_XDL_SET(&rev.diffopt, IGNORE_WHITESPACE);
compile_grep_patterns(&rev.grep_filter);
+ read_mailmap(&mailmap, NULL);
+ rev.mailmap = &mailmap;
prepare_revision_walk(&rev);
if (pager) {
diff --git a/ui-stats.c b/ui-stats.c
index 7acd358..eb30f28 100644
--- a/ui-stats.c
+++ b/ui-stats.c
@@ -159,7 +159,7 @@ const char *cgit_find_stats_periodname(int idx)
}
static void add_commit(struct string_list *authors, struct commit *commit,
- const struct cgit_period *period)
+ const struct cgit_period *period, struct string_list *mailmap)
{
struct commitinfo *info;
struct string_list_item *author, *item;
@@ -171,6 +171,7 @@ static void add_commit(struct string_list *authors, struct commit *commit,
uintptr_t *counter;
info = cgit_parse_commit(commit);
+ cgit_map_user(mailmap, &(info->author_email), &(info->author));
tmp = xstrdup(info->author);
author = string_list_insert(authors, tmp);
if (!author->util)
@@ -209,6 +210,7 @@ static int cmp_total_commits(const void *a1, const void *a2)
static struct string_list collect_stats(const struct cgit_period *period)
{
struct string_list authors;
+ struct string_list mailmap = STRING_LIST_INIT_NODUP;
struct rev_info rev;
struct commit *commit;
const char *argv[] = {NULL, ctx.qry.head, NULL, NULL, NULL, NULL};
@@ -237,10 +239,12 @@ static struct string_list collect_stats(const struct cgit_period *period)
rev.verbose_header = 1;
rev.show_root_diff = 0;
setup_revisions(argc, argv, &rev, NULL);
+ read_mailmap(&mailmap, NULL);
+ rev.mailmap = &mailmap;
prepare_revision_walk(&rev);
memset(&authors, 0, sizeof(authors));
while ((commit = get_revision(&rev)) != NULL) {
- add_commit(&authors, commit, period);
+ add_commit(&authors, commit, period, &mailmap);
free_commit_buffer(commit);
free_commit_list(commit->parents);
commit->parents = NULL;
_______________________________________________
CGit mailing list
[email protected]
http://lists.zx2c4.com/mailman/listinfo/cgit