diff options
context:
space:
mode:
authorBryce Kwon <bryce@brycekwon.com>
committerBryce Kwon <bryce@brycekwon.com>
commit
parent
tree
download
Reuse a blame commit's detail across its entries
Diffstat (limited to 'source/ui-blame.c')
-rw-r--r--source/ui-blame.c18
1 file changed, 15 insertions, 3 deletions
diff --git a/source/ui-blame.c b/source/ui-blame.c
index d6779c0..132121b 100644
--- a/source/ui-blame.c
+++ b/source/ui-blame.c
@@ -52,6 +52,16 @@ static char *emit_suspect_detail(struct blame_origin *suspect)
{
struct commitinfo *info;
struct strbuf detail = STRBUF_INIT;
+ struct string_list_item *cached;
+ char key[GIT_MAX_HEXSZ + 1];
+
+ // A private copy, since oid_to_hex hands back a buffer it reuses and
+ // the commit parse below is free to call it again.
+ oid_to_hex_r(key, &suspect->commit->object.oid);
+
+ cached = string_list_lookup(&suspect_details, key);
+ if (cached)
+ return cached->util;
info = cgit_parse_commit(suspect->commit);
@@ -72,7 +82,9 @@ static char *emit_suspect_detail(struct blame_origin *suspect)
strbuf_addstr(&detail, info->subject);
cgit_free_commitinfo(info);
- return strbuf_detach(&detail, NULL);
+ cached = string_list_insert(&suspect_details, key);
+ cached->util = strbuf_detach(&detail, NULL);
+ return cached->util;
}
static void emit_blame_entry_hash(struct blame_entry *ent)
@@ -80,12 +92,11 @@ static void emit_blame_entry_hash(struct blame_entry *ent)
struct blame_origin *suspect = ent->suspect;
struct object_id *oid = &suspect->commit->object.oid;
- char *detail = emit_suspect_detail(suspect);
+ const char *detail = emit_suspect_detail(suspect);
html("<span class='oid'>");
cgit_commit_link(repo_find_unique_abbrev(the_repository, oid, DEFAULT_ABBREV), detail,
NULL, ctx.qry.head, oid_to_hex(oid), suspect->path);
html("</span>");
- free(detail);
if (!repo_parse_commit(the_repository, suspect->commit) && suspect->commit->parents) {
struct commit *parent = suspect->commit->parents->item;
@@ -274,6 +285,7 @@ cleanup:
/* The binary and oversized branches jump here with the layout still
* open, so close it on every path rather than only the normal one. */
cgit_print_layout_end();
+ free_suspect_details();
free(buf);
}