X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=graph.c;h=162a516ee15cca1f8ab118dd41b803a5d76e42ff;hb=550806439402877e6dab22cacfc6de8757d18593;hp=edfab2d5b461f5bfd39d32fa843ee59841b4ce0a;hpb=f1979d6b3fba41fb6ca92290bf8e10d58ede8970;p=git.git diff --git a/graph.c b/graph.c index edfab2d5b..162a516ee 100644 --- a/graph.c +++ b/graph.c @@ -4,6 +4,43 @@ #include "diff.h" #include "revision.h" +/* Internal API */ + +/* + * Output the next line for a graph. + * This formats the next graph line into the specified strbuf. It is not + * terminated with a newline. + * + * Returns 1 if the line includes the current commit, and 0 otherwise. + * graph_next_line() will return 1 exactly once for each time + * graph_update() is called. + */ +static int graph_next_line(struct git_graph *graph, struct strbuf *sb); + +/* + * Output a padding line in the graph. + * This is similar to graph_next_line(). However, it is guaranteed to + * never print the current commit line. Instead, if the commit line is + * next, it will simply output a line of vertical padding, extending the + * branch lines downwards, but leaving them otherwise unchanged. + */ +static void graph_padding_line(struct git_graph *graph, struct strbuf *sb); + +/* + * Print a strbuf to stdout. If the graph is non-NULL, all lines but the + * first will be prefixed with the graph output. + * + * If the strbuf ends with a newline, the output will end after this + * newline. A new graph line will not be printed after the final newline. + * If the strbuf is empty, no output will be printed. + * + * Since the first line will not include the graph ouput, the caller is + * responsible for printing this line's graph (perhaps via + * graph_show_commit() or graph_show_oneline()) before calling + * graph_show_strbuf(). + */ +static void graph_show_strbuf(struct git_graph *graph, struct strbuf const *sb); + /* * TODO: * - Add colors to the graph. @@ -180,14 +217,6 @@ struct git_graph *graph_init(struct rev_info *opt) return graph; } -void graph_release(struct git_graph *graph) -{ - free(graph->columns); - free(graph->new_columns); - free(graph->mapping); - free(graph); -} - static void graph_update_state(struct git_graph *graph, enum graph_state s) { graph->prev_state = graph->state; @@ -237,18 +266,58 @@ static int graph_is_interesting(struct git_graph *graph, struct commit *commit) return (commit->object.flags & (UNINTERESTING | TREESAME)) ? 0 : 1; } +static struct commit_list *next_interesting_parent(struct git_graph *graph, + struct commit_list *orig) +{ + struct commit_list *list; + + /* + * If revs->first_parent_only is set, only the first + * parent is interesting. None of the others are. + */ + if (graph->revs->first_parent_only) + return NULL; + + /* + * Return the next interesting commit after orig + */ + for (list = orig->next; list; list = list->next) { + if (graph_is_interesting(graph, list->item)) + return list; + } + + return NULL; +} + +static struct commit_list *first_interesting_parent(struct git_graph *graph) +{ + struct commit_list *parents = graph->commit->parents; + + /* + * If this commit has no parents, ignore it + */ + if (!parents) + return NULL; + + /* + * If the first parent is interesting, return it + */ + if (graph_is_interesting(graph, parents->item)) + return parents; + + /* + * Otherwise, call next_interesting_parent() to get + * the next interesting parent + */ + return next_interesting_parent(graph, parents); +} + static void graph_insert_into_new_columns(struct git_graph *graph, struct commit *commit, int *mapping_index) { int i; - /* - * Ignore uinteresting commits - */ - if (!graph_is_interesting(graph, commit)) - return; - /* * If the commit is already in the new_columns list, we don't need to * add it. Just update the mapping correctly. @@ -373,9 +442,9 @@ static void graph_update_columns(struct git_graph *graph) int old_mapping_idx = mapping_idx; seen_this = 1; graph->commit_index = i; - for (parent = graph->commit->parents; + for (parent = first_interesting_parent(graph); parent; - parent = parent->next) { + parent = next_interesting_parent(graph, parent)) { graph_insert_into_new_columns(graph, parent->item, &mapping_idx); @@ -420,9 +489,11 @@ void graph_update(struct git_graph *graph, struct commit *commit) * Count how many interesting parents this commit has */ graph->num_parents = 0; - for (parent = commit->parents; parent; parent = parent->next) { - if (graph_is_interesting(graph, parent->item)) - graph->num_parents++; + for (parent = first_interesting_parent(graph); + parent; + parent = next_interesting_parent(graph, parent)) + { + graph->num_parents++; } /* @@ -637,27 +708,13 @@ static void graph_output_commit_char(struct git_graph *graph, struct strbuf *sb) return; } - /* - * Print 'M' for merge commits - * - * Note that we don't check graph->num_parents to determine if the - * commit is a merge, since that only tracks the number of - * "interesting" parents. We want to print 'M' for merge commits - * even if they have less than 2 interesting parents. - */ - if (graph->commit->parents != NULL && - graph->commit->parents->next != NULL) { - strbuf_addch(sb, 'M'); - return; - } - /* * Print '*' in all other cases */ strbuf_addch(sb, '*'); } -void graph_output_commit_line(struct git_graph *graph, struct strbuf *sb) +static void graph_output_commit_line(struct git_graph *graph, struct strbuf *sb) { int seen_this = 0; int i, j; @@ -732,7 +789,7 @@ void graph_output_commit_line(struct git_graph *graph, struct strbuf *sb) graph_update_state(graph, GRAPH_COLLAPSING); } -void graph_output_post_merge_line(struct git_graph *graph, struct strbuf *sb) +static void graph_output_post_merge_line(struct git_graph *graph, struct strbuf *sb) { int seen_this = 0; int i, j; @@ -773,7 +830,7 @@ void graph_output_post_merge_line(struct git_graph *graph, struct strbuf *sb) graph_update_state(graph, GRAPH_COLLAPSING); } -void graph_output_collapsing_line(struct git_graph *graph, struct strbuf *sb) +static void graph_output_collapsing_line(struct git_graph *graph, struct strbuf *sb) { int i; int *tmp_mapping; @@ -878,7 +935,7 @@ void graph_output_collapsing_line(struct git_graph *graph, struct strbuf *sb) graph_update_state(graph, GRAPH_PADDING); } -int graph_next_line(struct git_graph *graph, struct strbuf *sb) +static int graph_next_line(struct git_graph *graph, struct strbuf *sb) { switch (graph->state) { case GRAPH_PADDING: @@ -905,7 +962,7 @@ int graph_next_line(struct git_graph *graph, struct strbuf *sb) return 0; } -void graph_padding_line(struct git_graph *graph, struct strbuf *sb) +static void graph_padding_line(struct git_graph *graph, struct strbuf *sb) { int i, j; @@ -953,14 +1010,12 @@ int graph_is_commit_finished(struct git_graph const *graph) void graph_show_commit(struct git_graph *graph) { - struct strbuf msgbuf; + struct strbuf msgbuf = STRBUF_INIT; int shown_commit_line = 0; if (!graph) return; - strbuf_init(&msgbuf, 0); - while (!shown_commit_line) { shown_commit_line = graph_next_line(graph, &msgbuf); fwrite(msgbuf.buf, sizeof(char), msgbuf.len, stdout); @@ -974,12 +1029,11 @@ void graph_show_commit(struct git_graph *graph) void graph_show_oneline(struct git_graph *graph) { - struct strbuf msgbuf; + struct strbuf msgbuf = STRBUF_INIT; if (!graph) return; - strbuf_init(&msgbuf, 0); graph_next_line(graph, &msgbuf); fwrite(msgbuf.buf, sizeof(char), msgbuf.len, stdout); strbuf_release(&msgbuf); @@ -987,12 +1041,11 @@ void graph_show_oneline(struct git_graph *graph) void graph_show_padding(struct git_graph *graph) { - struct strbuf msgbuf; + struct strbuf msgbuf = STRBUF_INIT; if (!graph) return; - strbuf_init(&msgbuf, 0); graph_padding_line(graph, &msgbuf); fwrite(msgbuf.buf, sizeof(char), msgbuf.len, stdout); strbuf_release(&msgbuf); @@ -1000,7 +1053,7 @@ void graph_show_padding(struct git_graph *graph) int graph_show_remainder(struct git_graph *graph) { - struct strbuf msgbuf; + struct strbuf msgbuf = STRBUF_INIT; int shown = 0; if (!graph) @@ -1009,7 +1062,6 @@ int graph_show_remainder(struct git_graph *graph) if (graph_is_commit_finished(graph)) return 0; - strbuf_init(&msgbuf, 0); for (;;) { graph_next_line(graph, &msgbuf); fwrite(msgbuf.buf, sizeof(char), msgbuf.len, stdout); @@ -1027,7 +1079,7 @@ int graph_show_remainder(struct git_graph *graph) } -void graph_show_strbuf(struct git_graph *graph, struct strbuf const *sb) +static void graph_show_strbuf(struct git_graph *graph, struct strbuf const *sb) { char *p;