summaryrefslogtreecommitdiffabout
path: root/ui-log.c
authorJohan Herland <johan@herland.net>2010-11-15 17:39:50 (UTC)
committer Lars Hjemli <hjemli@gmail.com>2010-11-16 07:18:36 (UTC)
commit9a8d39c668b98464bac97d4e5442966de63f97b2 (patch) (side-by-side diff)
treeee1a7766d6d9365ae45f694939c20cab811abd84 /ui-log.c
parent5a36c2a291a00b59b8ec2f112453e117797c2fe5 (diff)
downloadcgit-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>
Diffstat (limited to 'ui-log.c') (more/less context) (ignore whitespace changes)
-rw-r--r--ui-log.c103
1 files changed, 82 insertions, 21 deletions
diff --git a/ui-log.c b/ui-log.c
index 6d7fcae..0d86fd5 100644
--- a/ui-log.c
+++ b/ui-log.c
@@ -79,3 +79,3 @@ void show_commit_decorations(struct commit *commit)
-void print_commit(struct commit *commit)
+void print_commit(struct commit *commit, struct rev_info *revs)
{
@@ -84,2 +84,21 @@ void print_commit(struct commit *commit)
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 */
+ }
@@ -93,4 +112,13 @@ void print_commit(struct commit *commit)
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,
@@ -114,23 +142,49 @@ void print_commit(struct commit *commit)
- 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;
- if (info->msg && *(info->msg)) {
- strbuf_addstr(&msgbuf, info->msg);
+ 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,
+ NOTES_SHOW_HEADER | NOTES_INDENT);
strbuf_addch(&msgbuf, '\n');
+ strbuf_ltrim(&msgbuf);
}
- 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);
@@ -140,2 +194,3 @@ void print_commit(struct commit *commit)
+ strbuf_release(&graphbuf);
cgit_free_commitinfo(info);
@@ -218,2 +273,6 @@ 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);
+ }
@@ -244,4 +303,6 @@ void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern
- 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) {
@@ -276,3 +337,3 @@ 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);