@matheusbsbs / matheus-bagliano / commits / 3395908ee4
Fork 0

graph API: improve display of merge commits

This change improves the way merge commits are displayed, to eliminate a few visual artifacts. Previously, merge commits were displayed as: | M \ | |\ | As pointed out by Teemu Likonen, this didn't look nice if the rightmost branch line was displayed as '\' on the previous line, as it then appeared to have an extra space in it: | |\ | M \ | |\ | This change updates the code so that branch lines to the right of merge commits are printed slightly differently depending on how the previous line was displayed: | |\ | | | | | / | M \ | M | | M | | |\ \ | |\ \ | |\ \ Signed-off-by: Adam Simpkins <adam@adamsimpkins.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Adam Simpkins committed Jun 1, 2008 at 13:56 UTC 3395908ee481e91bbe3ba054a7419b071b09cdef
1 file changed +93 -17
graph.c
+93 -17
@@ -80,6 +80,27 @@ struct git_graph {
80 * This tells us what kind of line graph_next_line() should output.
81 */
82 enum graph_state state;
83 + /*
84 + * The output state for the previous line of output.
85 + * This is primarily used to determine how the first merge line
86 + * should appear, based on the last line of the previous commit.
87 + */
88 + enum graph_state prev_state;
89 + /*
90 + * The index of the column that refers to this commit.
91 + *
92 + * If none of the incoming columns refer to this commit,
93 + * this will be equal to num_columns.
94 + */
95 + int commit_index;
96 + /*
97 + * The commit_index for the previously displayed commit.
98 + *
99 + * This is used to determine how the first line of a merge
100 + * graph output should appear, based on the last line of the
101 + * previous commit.
102 + */
103 + int prev_commit_index;
104 /*
105 * The maximum number of columns that can be stored in the columns
106 * and new_columns arrays. This is also half the number of entries
@@ -137,6 +158,9 @@ struct git_graph *graph_init(struct rev_info *opt)
158 graph->num_parents = 0;
159 graph->expansion_row = 0;
160 graph->state = GRAPH_PADDING;
161 + graph->prev_state = GRAPH_PADDING;
162 + graph->commit_index = 0;
163 + graph->prev_commit_index = 0;
164 graph->num_columns = 0;
165 graph->num_new_columns = 0;
166 graph->mapping_size = 0;
@@ -164,6 +188,12 @@ void graph_release(struct git_graph *graph)
188 free(graph);
189 }
190
191 +static void graph_update_state(struct git_graph *graph, enum graph_state s)
192 +{
193 + graph->prev_state = graph->state;
194 + graph->state = s;
195 +}
196 +
197 static void graph_ensure_capacity(struct git_graph *graph, int num_columns)
198 {
199 if (graph->column_capacity >= num_columns)
@@ -342,6 +372,7 @@ static void graph_update_columns(struct git_graph *graph)
372 if (col_commit == graph->commit) {
373 int old_mapping_idx = mapping_idx;
374 seen_this = 1;
375 + graph->commit_index = i;
376 for (parent = graph->commit->parents;
377 parent;
378 parent = parent->next) {
@@ -394,6 +425,13 @@ void graph_update(struct git_graph *graph, struct commit *commit)
425 graph->num_parents++;
426 }
427
428 + /*
429 + * Store the old commit_index in prev_commit_index.
430 + * graph_update_columns() will update graph->commit_index for this
431 + * commit.
432 + */
433 + graph->prev_commit_index = graph->commit_index;
434 +
435 /*
436 * Call graph_update_columns() to update
437 * columns, new_columns, and mapping.
@@ -404,6 +442,9 @@ void graph_update(struct git_graph *graph, struct commit *commit)
442
443 /*
444 * Update graph->state.
445 + * Note that we don't call graph_update_state() here, since
446 + * we don't want to update graph->prev_state. No line for
447 + * graph->state was ever printed.
448 *
449 * If the previous commit didn't get to the GRAPH_PADDING state,
450 * it never finished its output. Goto GRAPH_SKIP, to print out
@@ -498,9 +539,9 @@ static void graph_output_skip_line(struct git_graph *graph, struct strbuf *sb)
539 graph_pad_horizontally(graph, sb);
540
541 if (graph->num_parents >= 3)
501 - graph->state = GRAPH_PRE_COMMIT;
542 + graph_update_state(graph, GRAPH_PRE_COMMIT);
543 else
503 - graph->state = GRAPH_COMMIT;
544 + graph_update_state(graph, GRAPH_COMMIT);
545 }
546
547 static void graph_output_pre_commit_line(struct git_graph *graph,
@@ -535,7 +576,22 @@ static void graph_output_pre_commit_line(struct git_graph *graph,
576 if (col->commit == graph->commit) {
577 seen_this = 1;
578 strbuf_addf(sb, "| %*s", graph->expansion_row, "");
538 - } else if (seen_this) {
579 + } else if (seen_this && (graph->expansion_row == 0)) {
580 + /*
581 + * This is the first line of the pre-commit output.
582 + * If the previous commit was a merge commit and
583 + * ended in the GRAPH_POST_MERGE state, all branch
584 + * lines after graph->prev_commit_index were
585 + * printed as "\" on the previous line. Continue
586 + * to print them as "\" on this line. Otherwise,
587 + * print the branch lines as "|".
588 + */
589 + if (graph->prev_state == GRAPH_POST_MERGE &&
590 + graph->prev_commit_index < i)
591 + strbuf_addstr(sb, "\\ ");
592 + else
593 + strbuf_addstr(sb, "| ");
594 + } else if (seen_this && (graph->expansion_row > 0)) {
595 strbuf_addstr(sb, "\\ ");
596 } else {
597 strbuf_addstr(sb, "| ");
@@ -550,7 +606,7 @@ static void graph_output_pre_commit_line(struct git_graph *graph,
606 */
607 graph->expansion_row++;
608 if (graph->expansion_row >= num_expansion_rows)
553 - graph->state = GRAPH_COMMIT;
609 + graph_update_state(graph, GRAPH_COMMIT);
610 }
611
612 static void graph_output_commit_char(struct git_graph *graph, struct strbuf *sb)
@@ -625,10 +681,8 @@ void graph_output_commit_line(struct git_graph *graph, struct strbuf *sb)
681 seen_this = 1;
682 graph_output_commit_char(graph, sb);
683
628 - if (graph->num_parents < 2)
684 + if (graph->num_parents < 3)
685 strbuf_addch(sb, ' ');
630 - else if (graph->num_parents == 2)
631 - strbuf_addstr(sb, " ");
686 else {
687 int num_dashes =
688 ((graph->num_parents - 2) * 2) - 1;
@@ -636,8 +690,27 @@ void graph_output_commit_line(struct git_graph *graph, struct strbuf *sb)
690 strbuf_addch(sb, '-');
691 strbuf_addstr(sb, ". ");
692 }
639 - } else if (seen_this && (graph->num_parents > 1)) {
693 + } else if (seen_this && (graph->num_parents > 2)) {
694 strbuf_addstr(sb, "\\ ");
695 + } else if (seen_this && (graph->num_parents == 2)) {
696 + /*
697 + * This is a 2-way merge commit.
698 + * There is no GRAPH_PRE_COMMIT stage for 2-way
699 + * merges, so this is the first line of output
700 + * for this commit. Check to see what the previous
701 + * line of output was.
702 + *
703 + * If it was GRAPH_POST_MERGE, the branch line
704 + * coming into this commit may have been '\',
705 + * and not '|' or '/'. If so, output the branch
706 + * line as '\' on this line, instead of '|'. This
707 + * makes the output look nicer.
708 + */
709 + if (graph->prev_state == GRAPH_POST_MERGE &&
710 + graph->prev_commit_index < i)
711 + strbuf_addstr(sb, "\\ ");
712 + else
713 + strbuf_addstr(sb, "| ");
714 } else {
715 strbuf_addstr(sb, "| ");
716 }
@@ -649,11 +722,11 @@ void graph_output_commit_line(struct git_graph *graph, struct strbuf *sb)
722 * Update graph->state
723 */
724 if (graph->num_parents > 1)
652 - graph->state = GRAPH_POST_MERGE;
725 + graph_update_state(graph, GRAPH_POST_MERGE);
726 else if (graph_is_mapping_correct(graph))
654 - graph->state = GRAPH_PADDING;
727 + graph_update_state(graph, GRAPH_PADDING);
728 else
656 - graph->state = GRAPH_COLLAPSING;
729 + graph_update_state(graph, GRAPH_COLLAPSING);
730 }
731
732 void graph_output_post_merge_line(struct git_graph *graph, struct strbuf *sb)
@@ -679,9 +752,7 @@ void graph_output_post_merge_line(struct git_graph *graph, struct strbuf *sb)
752 strbuf_addch(sb, '|');
753 for (j = 0; j < graph->num_parents - 1; j++)
754 strbuf_addstr(sb, "\\ ");
682 - if (graph->num_parents == 2)
683 - strbuf_addch(sb, ' ');
684 - } else if (seen_this && (graph->num_parents > 2)) {
755 + } else if (seen_this) {
756 strbuf_addstr(sb, "\\ ");
757 } else {
758 strbuf_addstr(sb, "| ");
@@ -694,9 +765,9 @@ void graph_output_post_merge_line(struct git_graph *graph, struct strbuf *sb)
765 * Update graph->state
766 */
767 if (graph_is_mapping_correct(graph))
697 - graph->state = GRAPH_PADDING;
768 + graph_update_state(graph, GRAPH_PADDING);
769 else
699 - graph->state = GRAPH_COLLAPSING;
770 + graph_update_state(graph, GRAPH_COLLAPSING);
771 }
772
773 void graph_output_collapsing_line(struct git_graph *graph, struct strbuf *sb)
@@ -801,7 +872,7 @@ void graph_output_collapsing_line(struct git_graph *graph, struct strbuf *sb)
872 * Otherwise, we need to collapse some branch lines together.
873 */
874 if (graph_is_mapping_correct(graph))
804 - graph->state = GRAPH_PADDING;
875 + graph_update_state(graph, GRAPH_PADDING);
876 }
877
878 int graph_next_line(struct git_graph *graph, struct strbuf *sb)
@@ -865,6 +936,11 @@ void graph_padding_line(struct git_graph *graph, struct strbuf *sb)
936 }
937
938 graph_pad_horizontally(graph, sb);
939 +
940 + /*
941 + * Update graph->prev_state since we have output a padding line
942 + */
943 + graph->prev_state = GRAPH_PADDING;
944 }
945
946 int graph_is_commit_finished(struct git_graph const *graph)