graph: flatten edges that fuse with their right neighbor
When a merge commit is printed and its final parent is the same commit that occupies the column to the right of the merge, this results in a kink in the displayed edges: * | |\ \ | |/ | * Graphs containing these shapes can be hard to read, as the expansion to the right followed immediately by collapsing back to the left creates a lot of zig-zagging edges, especially when many columns are present. We can improve this by eliminating the zig-zag and having the merge's final parent edge fuse immediately with its neighbor: * | |\| | * This reduces the horizontal width for the current commit by 2, and requires one less row, making the graph display more compact. Taken in combination with other graph-smoothing enhancements, it greatly compresses the space needed to display certain histories: * |\ | * * | |\ |\ | | * | * | | | | |\ | | \ | | * | *-. \ | * | | |\ \ \ => |/|\| |/ / / / | | * | | | / | * | | | |/ | |/ | | * * / | * | |/ | |/ * * | |/ * One of the test cases here cannot be correctly rendered in Git v2.23.0; it produces this output following commit E: | | *-. \ 5_E | | |\ \ \ | |/ / / / | | | / _ | |_|/ |/| | The new implementation makes sure that the rightmost edge in this history is not left dangling as above. Signed-off-by: James Coglan <jcoglan@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>maint
parent
479db18bc0
commit
92beecc136
34
graph.c
34
graph.c
|
@ -557,8 +557,24 @@ static void graph_insert_into_new_columns(struct git_graph *graph,
|
||||||
shift = (dist > 1) ? 2 * dist - 3 : 1;
|
shift = (dist > 1) ? 2 * dist - 3 : 1;
|
||||||
|
|
||||||
graph->merge_layout = (dist > 0) ? 0 : 1;
|
graph->merge_layout = (dist > 0) ? 0 : 1;
|
||||||
|
graph->edges_added = graph->num_parents + graph->merge_layout - 2;
|
||||||
|
|
||||||
mapping_idx = graph->width + (graph->merge_layout - 1) * shift;
|
mapping_idx = graph->width + (graph->merge_layout - 1) * shift;
|
||||||
graph->width += 2 * graph->merge_layout;
|
graph->width += 2 * graph->merge_layout;
|
||||||
|
|
||||||
|
} else if (graph->edges_added > 0 && i == graph->mapping[graph->width - 2]) {
|
||||||
|
/*
|
||||||
|
* If some columns have been added by a merge, but this commit
|
||||||
|
* was found in the last existing column, then adjust the
|
||||||
|
* numbers so that the two edges immediately join, i.e.:
|
||||||
|
*
|
||||||
|
* * | * |
|
||||||
|
* |\ \ => |\|
|
||||||
|
* | |/ | *
|
||||||
|
* | *
|
||||||
|
*/
|
||||||
|
mapping_idx = graph->width - 2;
|
||||||
|
graph->edges_added = -1;
|
||||||
} else {
|
} else {
|
||||||
mapping_idx = graph->width;
|
mapping_idx = graph->width;
|
||||||
graph->width += 2;
|
graph->width += 2;
|
||||||
|
@ -604,6 +620,8 @@ static void graph_update_columns(struct git_graph *graph)
|
||||||
graph->mapping[i] = -1;
|
graph->mapping[i] = -1;
|
||||||
|
|
||||||
graph->width = 0;
|
graph->width = 0;
|
||||||
|
graph->prev_edges_added = graph->edges_added;
|
||||||
|
graph->edges_added = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Populate graph->new_columns and graph->mapping
|
* Populate graph->new_columns and graph->mapping
|
||||||
|
@ -731,9 +749,6 @@ void graph_update(struct git_graph *graph, struct commit *commit)
|
||||||
*/
|
*/
|
||||||
graph_update_columns(graph);
|
graph_update_columns(graph);
|
||||||
|
|
||||||
graph->prev_edges_added = graph->edges_added;
|
|
||||||
graph->edges_added = graph->num_parents + graph->merge_layout - 2;
|
|
||||||
|
|
||||||
graph->expansion_row = 0;
|
graph->expansion_row = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1041,7 +1056,7 @@ const char merge_chars[] = {'/', '|', '\\'};
|
||||||
static void graph_output_post_merge_line(struct git_graph *graph, struct graph_line *line)
|
static void graph_output_post_merge_line(struct git_graph *graph, struct graph_line *line)
|
||||||
{
|
{
|
||||||
int seen_this = 0;
|
int seen_this = 0;
|
||||||
int i;
|
int i, j;
|
||||||
|
|
||||||
struct commit_list *first_parent = first_interesting_parent(graph);
|
struct commit_list *first_parent = first_interesting_parent(graph);
|
||||||
int seen_parent = 0;
|
int seen_parent = 0;
|
||||||
|
@ -1073,16 +1088,19 @@ static void graph_output_post_merge_line(struct git_graph *graph, struct graph_l
|
||||||
char c;
|
char c;
|
||||||
seen_this = 1;
|
seen_this = 1;
|
||||||
|
|
||||||
for (; parents; parents = next_interesting_parent(graph, parents)) {
|
for (j = 0; j < graph->num_parents; j++) {
|
||||||
par_column = graph_find_new_column_by_commit(graph, parents->item);
|
par_column = graph_find_new_column_by_commit(graph, parents->item);
|
||||||
assert(par_column >= 0);
|
assert(par_column >= 0);
|
||||||
|
|
||||||
c = merge_chars[idx];
|
c = merge_chars[idx];
|
||||||
graph_line_write_column(line, &graph->new_columns[par_column], c);
|
graph_line_write_column(line, &graph->new_columns[par_column], c);
|
||||||
if (idx == 2)
|
if (idx == 2) {
|
||||||
graph_line_addch(line, ' ');
|
if (graph->edges_added > 0 || j < graph->num_parents - 1)
|
||||||
else
|
graph_line_addch(line, ' ');
|
||||||
|
} else {
|
||||||
idx++;
|
idx++;
|
||||||
|
}
|
||||||
|
parents = next_interesting_parent(graph, parents);
|
||||||
}
|
}
|
||||||
if (graph->edges_added == 0)
|
if (graph->edges_added == 0)
|
||||||
graph_line_addch(line, ' ');
|
graph_line_addch(line, ' ');
|
||||||
|
|
|
@ -11,9 +11,8 @@ test_expect_success 'log --graph with merge fusing with its left and right neigh
|
||||||
| * G
|
| * G
|
||||||
| |\
|
| |\
|
||||||
| | * F
|
| | * F
|
||||||
| * | E
|
| * | E
|
||||||
|/|\ \
|
|/|\|
|
||||||
| | |/
|
|
||||||
| | * D
|
| | * D
|
||||||
| * | C
|
| * | C
|
||||||
| |/
|
| |/
|
||||||
|
@ -43,9 +42,9 @@ test_expect_success 'log --graph with left-skewed merge' '
|
||||||
| | | | * 0_G
|
| | | | * 0_G
|
||||||
| |_|_|/|
|
| |_|_|/|
|
||||||
|/| | | |
|
|/| | | |
|
||||||
| | | * | 0_F
|
| | | * | 0_F
|
||||||
| |_|/|\ \
|
| |_|/|\|
|
||||||
|/| | | |/
|
|/| | | |
|
||||||
| | | | * 0_E
|
| | | | * 0_E
|
||||||
| |_|_|/
|
| |_|_|/
|
||||||
|/| | |
|
|/| | |
|
||||||
|
@ -153,9 +152,8 @@ test_expect_success 'log --graph with nested right-skewed merge following left-s
|
||||||
| | * 3_G
|
| | * 3_G
|
||||||
| * | 3_F
|
| * | 3_F
|
||||||
|/| |
|
|/| |
|
||||||
| * | 3_E
|
| * | 3_E
|
||||||
| |\ \
|
| |\|
|
||||||
| | |/
|
|
||||||
| | * 3_D
|
| | * 3_D
|
||||||
| * | 3_C
|
| * | 3_C
|
||||||
| |/
|
| |/
|
||||||
|
@ -216,4 +214,44 @@ test_expect_success 'log --graph with right-skewed merge following a left-skewed
|
||||||
test_cmp expect actual
|
test_cmp expect actual
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'log --graph with octopus merge with column joining its penultimate parent' '
|
||||||
|
cat >expect <<-\EOF &&
|
||||||
|
* 5_H
|
||||||
|
|\
|
||||||
|
| *-. 5_G
|
||||||
|
| |\ \
|
||||||
|
| | | * 5_F
|
||||||
|
| | * | 5_E
|
||||||
|
| |/|\ \
|
||||||
|
| |_|/ /
|
||||||
|
|/| | /
|
||||||
|
| | |/
|
||||||
|
* | | 5_D
|
||||||
|
| | * 5_C
|
||||||
|
| |/
|
||||||
|
|/|
|
||||||
|
| * 5_B
|
||||||
|
|/
|
||||||
|
* 5_A
|
||||||
|
EOF
|
||||||
|
|
||||||
|
git checkout --orphan 5_p &&
|
||||||
|
test_commit 5_A &&
|
||||||
|
git branch 5_q &&
|
||||||
|
git branch 5_r &&
|
||||||
|
test_commit 5_B &&
|
||||||
|
git checkout 5_q && test_commit 5_C &&
|
||||||
|
git checkout 5_r && test_commit 5_D &&
|
||||||
|
git checkout 5_p &&
|
||||||
|
git merge --no-ff 5_q 5_r -m 5_E &&
|
||||||
|
git checkout 5_q && test_commit 5_F &&
|
||||||
|
git checkout -b 5_s 5_p^ &&
|
||||||
|
git merge --no-ff 5_p 5_q -m 5_G &&
|
||||||
|
git checkout 5_r &&
|
||||||
|
git merge --no-ff 5_s -m 5_H &&
|
||||||
|
|
||||||
|
git log --graph --pretty=tformat:%s | sed "s/ *$//" >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
|
|
@ -67,11 +67,10 @@ test_expect_success '--graph --all' '
|
||||||
echo "| * $C4" >> expected &&
|
echo "| * $C4" >> expected &&
|
||||||
echo "| * $C3" >> expected &&
|
echo "| * $C3" >> expected &&
|
||||||
echo "* | $A5" >> expected &&
|
echo "* | $A5" >> expected &&
|
||||||
echo "| | " >> expected &&
|
echo "| | " >> expected &&
|
||||||
echo "| \\ " >> expected &&
|
echo "| \\ " >> expected &&
|
||||||
echo "*-. \\ $A4" >> expected &&
|
echo "*-. | $A4" >> expected &&
|
||||||
echo "|\\ \\ \\ " >> expected &&
|
echo "|\\ \\| " >> expected &&
|
||||||
echo "| | |/ " >> expected &&
|
|
||||||
echo "| | * $C2" >> expected &&
|
echo "| | * $C2" >> expected &&
|
||||||
echo "| | * $C1" >> expected &&
|
echo "| | * $C1" >> expected &&
|
||||||
echo "| * | $B2" >> expected &&
|
echo "| * | $B2" >> expected &&
|
||||||
|
@ -97,11 +96,10 @@ test_expect_success '--graph --simplify-by-decoration' '
|
||||||
echo "| * $C4" >> expected &&
|
echo "| * $C4" >> expected &&
|
||||||
echo "| * $C3" >> expected &&
|
echo "| * $C3" >> expected &&
|
||||||
echo "* | $A5" >> expected &&
|
echo "* | $A5" >> expected &&
|
||||||
echo "| | " >> expected &&
|
echo "| | " >> expected &&
|
||||||
echo "| \\ " >> expected &&
|
echo "| \\ " >> expected &&
|
||||||
echo "*-. \\ $A4" >> expected &&
|
echo "*-. | $A4" >> expected &&
|
||||||
echo "|\\ \\ \\ " >> expected &&
|
echo "|\\ \\| " >> expected &&
|
||||||
echo "| | |/ " >> expected &&
|
|
||||||
echo "| | * $C2" >> expected &&
|
echo "| | * $C2" >> expected &&
|
||||||
echo "| | * $C1" >> expected &&
|
echo "| | * $C1" >> expected &&
|
||||||
echo "| * | $B2" >> expected &&
|
echo "| * | $B2" >> expected &&
|
||||||
|
@ -131,9 +129,8 @@ test_expect_success '--graph --simplify-by-decoration prune branch B' '
|
||||||
echo "| * $C4" >> expected &&
|
echo "| * $C4" >> expected &&
|
||||||
echo "| * $C3" >> expected &&
|
echo "| * $C3" >> expected &&
|
||||||
echo "* | $A5" >> expected &&
|
echo "* | $A5" >> expected &&
|
||||||
echo "* | $A4" >> expected &&
|
echo "* | $A4" >> expected &&
|
||||||
echo "|\\ \\ " >> expected &&
|
echo "|\\| " >> expected &&
|
||||||
echo "| |/ " >> expected &&
|
|
||||||
echo "| * $C2" >> expected &&
|
echo "| * $C2" >> expected &&
|
||||||
echo "| * $C1" >> expected &&
|
echo "| * $C1" >> expected &&
|
||||||
echo "* | $A3" >> expected &&
|
echo "* | $A3" >> expected &&
|
||||||
|
@ -151,10 +148,9 @@ test_expect_success '--graph --full-history -- bar.txt' '
|
||||||
echo "|\\ " >> expected &&
|
echo "|\\ " >> expected &&
|
||||||
echo "| * $C4" >> expected &&
|
echo "| * $C4" >> expected &&
|
||||||
echo "* | $A5" >> expected &&
|
echo "* | $A5" >> expected &&
|
||||||
echo "* | $A4" >> expected &&
|
echo "* | $A4" >> expected &&
|
||||||
echo "|\\ \\ " >> expected &&
|
echo "|\\| " >> expected &&
|
||||||
echo "| |/ " >> expected &&
|
echo "* | $A3" >> expected &&
|
||||||
echo "* / $A3" >> expected &&
|
|
||||||
echo "|/ " >> expected &&
|
echo "|/ " >> expected &&
|
||||||
echo "* $A2" >> expected &&
|
echo "* $A2" >> expected &&
|
||||||
git rev-list --graph --full-history --all -- bar.txt > actual &&
|
git rev-list --graph --full-history --all -- bar.txt > actual &&
|
||||||
|
|
Loading…
Reference in New Issue