diff options
context:
space:
mode:
Diffstat (limited to 'source/ui-commit.c')
-rw-r--r--source/ui-commit.c57
1 file changed, 40 insertions, 17 deletions
diff --git a/source/ui-commit.c b/source/ui-commit.c
index b67f5db..ba079a0 100644
--- a/source/ui-commit.c
+++ b/source/ui-commit.c
@@ -1,9 +1,10 @@
/*
* The commit page, which shows one commit on its own and is where the log and
- * the ref listings link. It renders the idents, the object ids, the message
- * and any note, then hands off to ui-diff.c for the diff against the first
- * parent. Free text and addresses are written through the repository's commit
- * and email filters, so a site can rewrite either on the way out.
+ * the ref listings link. It renders the idents, the object ids, the message,
+ * the trailer table when the repository asks for one and any note, then hands
+ * off to ui-diff.c for the diff against the first parent. Free text and
+ * addresses are written through the repository's commit, trailer and email
+ * filters, so a site can rewrite any of them on the way out.
*/
#define USE_THE_REPOSITORY_VARIABLE
@@ -19,6 +20,7 @@
#include "ui-shared.h"
#include <list.h>
+#include <mailmap.h>
#include <trailer.h>
// The diff below the message is always taken against the first parent alone,
@@ -81,30 +83,46 @@ static void print_filtered_text(const char *text)
/*
* A value shaped like an ident is written the way the author row is, through
- * the email filter. Anything else goes through the trailer filter when one is
- * set, and otherwise through the commit filter, so the links a site already
- * draws in message text keep appearing on trailer lines.
+ * the mailmap and the email filter, and anything after the address, such as a
+ * role in parentheses, follows as text. Anything else goes through the trailer
+ * filter when one is set, and otherwise through the commit filter, so the
+ * links a site already draws in message text keep appearing on trailer lines.
*/
static void print_trailer_value(const char *key, const char *value)
{
struct ident_split ident;
- struct strbuf name = STRBUF_INIT, email = STRBUF_INIT;
+ struct string_list *map;
+ struct strbuf email = STRBUF_INIT;
+ const char *name, *mail, *rest;
+ size_t name_len, mail_len;
if (!split_ident_line(&ident, value, strlen(value)) &&
memchr(ident.mail_begin, '@', ident.mail_end - ident.mail_begin)) {
- strbuf_add(&name, ident.name_begin, ident.name_end - ident.name_begin);
+ name = ident.name_begin;
+ name_len = ident.name_end - ident.name_begin;
+ mail = ident.mail_begin;
+ mail_len = ident.mail_end - ident.mail_begin;
+ map = cgit_mailmap();
+ if (map)
+ map_user(map, &mail, &mail_len, &name, &name_len);
strbuf_addch(&email, '<');
- strbuf_add(&email, ident.mail_begin, ident.mail_end - ident.mail_begin);
+ strbuf_add(&email, mail, mail_len);
strbuf_addch(&email, '>');
cgit_open_filter(ctx.repo->email_filter, email.buf, "commit");
- html_txt(name.buf);
+ html_ntxt(name, name_len);
if (ctx.cfg.enable_plain_email) {
html(" ");
html_txt(email.buf);
}
cgit_close_filter(ctx.repo->email_filter);
- strbuf_release(&name);
strbuf_release(&email);
+ rest = ident.mail_end + 1;
+ while (isspace((unsigned char)*rest))
+ rest++;
+ if (*rest) {
+ html(" ");
+ html_txt(rest);
+ }
} else if (ctx.repo->trailer_filter) {
cgit_open_filter(ctx.repo->trailer_filter, key, "commit");
html_txt(value);
@@ -114,14 +132,15 @@ static void print_trailer_value(const char *key, const char *value)
}
/*
- * One row per trailer, except that a run of trailers sharing a key becomes a
- * single row listing every value. A line git kept in the block without being
- * able to split it, such as a cherry-pick note, gets a row of its own.
+ * One row per trailer, except that a run of trailers sharing a key, compared
+ * without regard to case, becomes a single row listing every value. A line git
+ * kept in the block without a value, such as a cherry-pick note or a key with
+ * nothing after its colon, gets a row of its own as written.
*/
static void print_trailers(const char *msg)
{
struct trailer_iterator iter;
- struct strbuf key = STRBUF_INIT;
+ struct strbuf key = STRBUF_INIT, line = STRBUF_INIT;
int open = 0;
html("<table class='commit-trailers'>\n");
@@ -131,8 +150,11 @@ static void print_trailers(const char *msg)
if (open)
html("</td></tr>\n");
open = 0;
+ strbuf_reset(&line);
+ strbuf_addstr(&line, iter.raw);
+ strbuf_rtrim(&line);
html("<tr><td colspan='2'>");
- print_filtered_text(iter.key.buf);
+ print_filtered_text(line.buf);
html("</td></tr>\n");
continue;
}
@@ -155,6 +177,7 @@ static void print_trailers(const char *msg)
html("</table>\n");
trailer_iterator_release(&iter);
strbuf_release(&key);
+ strbuf_release(&line);
}
/*