@@ -538,8 +538,24 @@ static void graph_insert_into_new_columns(struct git_graph *graph,
shift = (dist > 1) ? 2 * dist - 3 : 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;
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 {
mapping_idx = graph->width;
graph->width += 2;
@@ -585,6 +601,8 @@ static void graph_update_columns(struct git_graph *graph)
graph->mapping[i] = -1;
graph->width = 0;
+ graph->prev_edges_added = graph->edges_added;
+ graph->edges_added = 0;
/*
* Populate graph->new_columns and graph->mapping
@@ -712,9 +730,6 @@ void graph_update(struct git_graph *graph, struct commit *commit)
*/
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;
/*
@@ -1039,7 +1054,7 @@ const char merge_chars[] = {'/', '|', '\\'};
static void graph_output_post_merge_line(struct git_graph *graph, struct strbuf *sb)
{
int seen_this = 0;
- int i;
+ int i, j;
struct commit_list *first_parent = first_interesting_parent(graph);
int seen_parent = 0;
@@ -1071,16 +1086,19 @@ static void graph_output_post_merge_line(struct git_graph *graph, struct strbuf
char c;
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);
assert(par_column >= 0);
c = merge_chars[idx];
strbuf_write_column(sb, &graph->new_columns[par_column], c);
- if (idx == 2)
- strbuf_addch(sb, ' ');
- else
+ if (idx == 2) {
+ if (graph->edges_added > 0 || j < graph->num_parents - 1)
+ strbuf_addch(sb, ' ');
+ } else {
idx++;
+ }
+ parents = next_interesting_parent(graph, parents);
}
if (graph->edges_added == 0)
strbuf_addch(sb, ' ');
@@ -137,9 +137,8 @@ cat > expect <<\EOF
| | * 3_G
| * | 3_F
|/| |
-| * | 3_E
-| |\ \
-| | |/
+| * | 3_E
+| |\|
| | * 3_D
| * | 3_C
| |/
@@ -190,4 +189,79 @@ test_expect_success 'log --graph with right-skewed merge following a left-skewed
test_cmp expect actual
'
+test_expect_success 'setup octopus merge with column joining its penultimate parent' '
+ 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
+'
+
+cat > expect <<\EOF
+* 5_H
+|\
+| *-. 5_G
+| |\ \
+| | | * 5_F
+| | * | 5_E
+| |/|\ \
+| |_|/ /
+|/| | /
+| | |/
+* | | 5_D
+| | * 5_C
+| |/
+|/|
+| * 5_B
+|/
+* 5_A
+EOF
+
+test_expect_success 'log --graph with octopus merge with column joining its penultimate parent' '
+ git log --graph --pretty=tformat:%s | sed "s/ *$//" > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'setup merge fusing with its left and right neighbors' '
+ git checkout --orphan 6_p &&
+ test_commit 6_A &&
+ test_commit 6_B &&
+ git checkout -b 6_q @^ && test_commit 6_C &&
+ git checkout -b 6_r @^ && test_commit 6_D &&
+ git checkout 6_p && git merge --no-ff 6_q 6_r -m 6_E &&
+ git checkout 6_r && test_commit 6_F &&
+ git checkout 6_p && git merge --no-ff 6_r -m 6_G &&
+ git checkout @^^ && git merge --no-ff 6_p -m 6_H
+'
+
+cat > expect <<\EOF
+* 6_H
+|\
+| * 6_G
+| |\
+| | * 6_F
+| * | 6_E
+|/|\|
+| | * 6_D
+| * | 6_C
+| |/
+* / 6_B
+|/
+* 6_A
+EOF
+
+test_expect_success 'log --graph with merge fusing with its left and right neighbors' '
+ git log --graph --pretty=tformat:%s | sed "s/ *$//" > actual &&
+ test_cmp expect actual
+'
+
test_done
@@ -67,11 +67,10 @@ test_expect_success '--graph --all' '
echo "| * $C4" >> expected &&
echo "| * $C3" >> expected &&
echo "* | $A5" >> expected &&
- echo "| | " >> expected &&
- echo "| \\ " >> expected &&
- echo "*-. \\ $A4" >> expected &&
- echo "|\\ \\ \\ " >> expected &&
- echo "| | |/ " >> expected &&
+ echo "| | " >> expected &&
+ echo "| \\ " >> expected &&
+ echo "*-. | $A4" >> expected &&
+ echo "|\\ \\| " >> expected &&
echo "| | * $C2" >> expected &&
echo "| | * $C1" >> expected &&
echo "| * | $B2" >> expected &&
@@ -97,11 +96,10 @@ test_expect_success '--graph --simplify-by-decoration' '
echo "| * $C4" >> expected &&
echo "| * $C3" >> expected &&
echo "* | $A5" >> expected &&
- echo "| | " >> expected &&
- echo "| \\ " >> expected &&
- echo "*-. \\ $A4" >> expected &&
- echo "|\\ \\ \\ " >> expected &&
- echo "| | |/ " >> expected &&
+ echo "| | " >> expected &&
+ echo "| \\ " >> expected &&
+ echo "*-. | $A4" >> expected &&
+ echo "|\\ \\| " >> expected &&
echo "| | * $C2" >> expected &&
echo "| | * $C1" >> expected &&
echo "| * | $B2" >> expected &&
@@ -131,9 +129,8 @@ test_expect_success '--graph --simplify-by-decoration prune branch B' '
echo "| * $C4" >> expected &&
echo "| * $C3" >> expected &&
echo "* | $A5" >> expected &&
- echo "* | $A4" >> expected &&
- echo "|\\ \\ " >> expected &&
- echo "| |/ " >> expected &&
+ echo "* | $A4" >> expected &&
+ echo "|\\| " >> expected &&
echo "| * $C2" >> expected &&
echo "| * $C1" >> expected &&
echo "* | $A3" >> expected &&
@@ -151,10 +148,9 @@ test_expect_success '--graph --full-history -- bar.txt' '
echo "|\\ " >> expected &&
echo "| * $C4" >> expected &&
echo "* | $A5" >> expected &&
- echo "* | $A4" >> expected &&
- echo "|\\ \\ " >> expected &&
- echo "| |/ " >> expected &&
- echo "* / $A3" >> expected &&
+ echo "* | $A4" >> expected &&
+ echo "|\\| " >> expected &&
+ echo "* | $A3" >> expected &&
echo "|/ " >> expected &&
echo "* $A2" >> expected &&
git rev-list --graph --full-history --all -- bar.txt > actual &&