author | Johan Herland <johan@herland.net> | 2010-11-15 17:39:50 (UTC) |
---|---|---|
committer | Lars Hjemli <hjemli@gmail.com> | 2010-11-16 07:18:36 (UTC) |
commit | 9a8d39c668b98464bac97d4e5442966de63f97b2 (patch) (side-by-side diff) | |
tree | ee1a7766d6d9365ae45f694939c20cab811abd84 | |
parent | 5a36c2a291a00b59b8ec2f112453e117797c2fe5 (diff) | |
download | cgit-9a8d39c668b98464bac97d4e5442966de63f97b2.zip cgit-9a8d39c668b98464bac97d4e5442966de63f97b2.tar.gz cgit-9a8d39c668b98464bac97d4e5442966de63f97b2.tar.bz2 |
ui-log: Implement support for commit graphs
Teach CGit to print an ASCII art commit graph to the left of the commit
message, similar to 'git log --graph'. The graph adds extra lines (table
rows) to the log when needed to add/remove/shuffle edges in the graph.
When 'showmsg' is enabled, the graph is automatically padded to account
for the extra lines added by the commit message/notes.
This feature is controlled by a new config variable: "enable-commit-graph"
(disabled by default), and individual repos can control it by setting
"repo.enable-commit-graph".
Signed-off-by: Johan Herland <johan@herland.net>
Signed-off-by: Lars Hjemli <hjemli@gmail.com>
-rw-r--r-- | cgit.c | 6 | ||||
-rw-r--r-- | cgit.css | 5 | ||||
-rw-r--r-- | cgit.h | 3 | ||||
-rw-r--r-- | cgitrc.5.txt | 13 | ||||
-rw-r--r-- | shared.c | 1 | ||||
-rw-r--r-- | ui-log.c | 93 |
6 files changed, 105 insertions, 16 deletions
@@ -58,4 +58,6 @@ void repo_config(struct cgit_repo *repo, const char *name, const char *value) else if (!strcmp(name, "snapshots")) repo->snapshots = ctx.cfg.snapshots & cgit_parse_snapshots_mask(value); + else if (!strcmp(name, "enable-commit-graph")) + repo->enable_commit_graph = ctx.cfg.enable_commit_graph * atoi(value); else if (!strcmp(name, "enable-log-filecount")) repo->enable_log_filecount = ctx.cfg.enable_log_filecount * atoi(value); @@ -142,4 +144,6 @@ void config_cb(const char *name, const char *value) else if (!strcmp(name, "enable-index-links")) ctx.cfg.enable_index_links = atoi(value); + else if (!strcmp(name, "enable-commit-graph")) + ctx.cfg.enable_commit_graph = atoi(value); else if (!strcmp(name, "enable-log-filecount")) ctx.cfg.enable_log_filecount = atoi(value); @@ -541,4 +545,6 @@ void print_repo(FILE *f, struct cgit_repo *repo) if (repo->clone_url) fprintf(f, "repo.clone-url=%s\n", repo->clone_url); + fprintf(f, "repo.enable-commit-graph=%d\n", + repo->enable_commit_graph); fprintf(f, "repo.enable-log-filecount=%d\n", repo->enable_log_filecount); @@ -154,4 +154,9 @@ table.list td { } +table.list td.commitgraph { + font-family: monospace; + white-space: pre; +} + table.list td.logsubject { font-family: monospace; @@ -21,4 +21,5 @@ #include <utf8.h> #include <notes.h> +#include <graph.h> @@ -72,4 +73,5 @@ struct cgit_repo { char *clone_url; int snapshots; + int enable_commit_graph; int enable_log_filecount; int enable_log_linecount; @@ -189,4 +191,5 @@ struct cgit_config { int enable_gitweb_owner; int enable_index_links; + int enable_commit_graph; int enable_log_filecount; int enable_log_linecount; diff --git a/cgitrc.5.txt b/cgitrc.5.txt index 75b6584..b45c46b 100644 --- a/cgitrc.5.txt +++ b/cgitrc.5.txt @@ -92,4 +92,9 @@ embedded:: also: "noheader". +enable-commit-graph:: + Flag which, when set to "1", will make cgit print an ASCII-art commit + history graph to the left of the commit messages in the repository + log page. Default value: "0". + enable-filter-overrides:: Flag which, when set to "1", allows all filter settings to be @@ -355,4 +360,8 @@ repo.desc:: The value to show as repository description. Default value: none. +repo.enable-commit-graph:: + A flag which can be used to disable the global setting + `enable-commit-graph'. Default value: none. + repo.enable-log-filecount:: A flag which can be used to disable the global setting @@ -442,4 +451,8 @@ enable-index-links=1 +# Enable ASCII art commit history graph on the log pages +enable-commit-graph=1 + + # Show number of affected files per commit on the log pages enable-log-filecount=1 @@ -57,4 +57,5 @@ struct cgit_repo *cgit_add_repo(const char *url) ret->defbranch = "master"; ret->snapshots = ctx.cfg.snapshots; + ret->enable_commit_graph = ctx.cfg.enable_commit_graph; ret->enable_log_filecount = ctx.cfg.enable_log_filecount; ret->enable_log_linecount = ctx.cfg.enable_log_linecount; @@ -78,9 +78,28 @@ void show_commit_decorations(struct commit *commit) } -void print_commit(struct commit *commit) +void print_commit(struct commit *commit, struct rev_info *revs) { struct commitinfo *info; char *tmp; int cols = 2; + struct strbuf graphbuf = STRBUF_INIT; + + if (ctx.repo->enable_log_filecount) { + cols++; + if (ctx.repo->enable_log_linecount) + cols++; + } + + if (revs->graph) { + /* Advance graph until current commit */ + while (!graph_next_line(revs->graph, &graphbuf)) { + /* Print graph segment in otherwise empty table row */ + html("<tr class='nohover'><td/><td class='commitgraph'>"); + html(graphbuf.buf); + htmlf("</td><td colspan='%d' /></tr>\n", cols); + strbuf_setlen(&graphbuf, 0); + } + /* Current commit's graph segment is now ready in graphbuf */ + } info = cgit_parse_commit(commit); @@ -92,6 +111,15 @@ void print_commit(struct commit *commit) cgit_print_age(commit->date, TM_WEEK * 2, FMT_SHORTDATE); html_link_close(); - htmlf("</td><td%s>", - ctx.qry.showmsg ? " class='logsubject'" : ""); + html("</td>"); + + if (revs->graph) { + /* Print graph segment for current commit */ + html("<td class='commitgraph'>"); + html(graphbuf.buf); + html("</td>"); + strbuf_setlen(&graphbuf, 0); + } + + htmlf("<td%s>", ctx.qry.showmsg ? " class='logsubject'" : ""); cgit_commit_link(info->subject, NULL, NULL, ctx.qry.head, sha1_to_hex(commit->object.sha1), ctx.qry.vpath, 0); @@ -113,25 +141,51 @@ void print_commit(struct commit *commit) html("</td></tr>\n"); - if (ctx.qry.showmsg) { /* Print message + notes in a second table row */ - /* Concatenate commit message and notes in msgbuf */ + if (revs->graph || ctx.qry.showmsg) { /* Print a second table row */ struct strbuf msgbuf = STRBUF_INIT; + html("<tr class='nohover'><td/>"); /* Empty 'Age' column */ + + if (ctx.qry.showmsg) { + /* Concatenate commit message + notes in msgbuf */ if (info->msg && *(info->msg)) { strbuf_addstr(&msgbuf, info->msg); strbuf_addch(&msgbuf, '\n'); } - format_note(NULL, commit->object.sha1, &msgbuf, PAGE_ENCODING, + format_note(NULL, commit->object.sha1, &msgbuf, + PAGE_ENCODING, NOTES_SHOW_HEADER | NOTES_INDENT); strbuf_addch(&msgbuf, '\n'); strbuf_ltrim(&msgbuf); + } - if (ctx.repo->enable_log_filecount) { - cols++; - if (ctx.repo->enable_log_linecount) - cols++; + if (revs->graph) { + int lines = 0; + + /* Calculate graph padding */ + if (ctx.qry.showmsg) { + /* Count #lines in commit message + notes */ + const char *p = msgbuf.buf; + lines = 1; + while ((p = strchr(p, '\n'))) { + p++; + lines++; + } + } + + /* Print graph padding */ + html("<td class='commitgraph'>"); + while (lines > 0 || !graph_is_commit_finished(revs->graph)) { + if (graphbuf.len) + html("\n"); + strbuf_setlen(&graphbuf, 0); + graph_next_line(revs->graph, &graphbuf); + html(graphbuf.buf); + lines--; + } + html("</td>\n"); } - /* Create second table row containing msgbuf */ - htmlf("<tr class='nohover'><td/><td colspan='%d' class='logmsg'>", - cols); + /* Print msgbuf into remainder of table row */ + htmlf("<td colspan='%d'%s>\n", cols, + ctx.qry.showmsg ? " class='logmsg'" : ""); html_txt(msgbuf.buf); html("</td></tr>\n"); @@ -139,4 +193,5 @@ void print_commit(struct commit *commit) } + strbuf_release(&graphbuf); cgit_free_commitinfo(info); } @@ -217,4 +272,8 @@ void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern } } + if (ctx.repo->enable_commit_graph) { + static const char *graph_arg = "--graph"; + vector_push(&vec, &graph_arg, 0); + } if (path) { @@ -243,6 +302,8 @@ void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern html("<table class='list nowrap'>"); - html("<tr class='nohover'><th class='left'>Age</th>" - "<th class='left'>Commit message"); + html("<tr class='nohover'><th class='left'>Age</th>"); + if (ctx.repo->enable_commit_graph) + html("<th></th>"); + html("<th class='left'>Commit message"); if (pager) { html(" ("); @@ -275,5 +336,5 @@ void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern for (i = 0; i < cnt && (commit = get_revision(&rev)) != NULL; i++) { - print_commit(commit); + print_commit(commit, &rev); free(commit->buffer); commit->buffer = NULL; |