Skip to content

Commit fdbde82

Browse files
ttaylorrgitster
authored andcommitted
builtin/commit-graph.c: introduce split strategy 'no-merge'
In the previous commit, we laid the groundwork for supporting different splitting strategies. In this commit, we introduce the first splitting strategy: 'no-merge'. Passing '--split=no-merge' is useful for callers which wish to write a new incremental commit-graph, but do not want to spend effort condensing the incremental chain [1]. Previously, this was possible by passing '--size-multiple=0', but this no longer the case following 63020f1 (commit-graph: prefer default size_mult when given zero, 2020-01-02). When '--split=no-merge' is given, the commit-graph machinery will never condense an existing chain, and it will always write a new incremental. [1]: This might occur when, for example, a server administrator running some program after each push may want to ensure that each job runs proportional in time to the size of the push, and does not "jump" when the commit-graph machinery decides to trigger a merge. Signed-off-by: Taylor Blau <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 4f02735 commit fdbde82

File tree

5 files changed

+36
-9
lines changed

5 files changed

+36
-9
lines changed

Documentation/git-commit-graph.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ chain of multiple commit-graph files stored in
6363
strategy and other splitting options. The new commits not already in the
6464
commit-graph are added in a new "tip" file. This file is merged with the
6565
existing file if the following merge conditions are met:
66+
* If `--split=no-merge` is specified, a merge is never performed, and
67+
the remaining options are ignored. A bare `--split` defers to the
68+
remaining options. (Note that merging a chain of commit graphs replaces
69+
the existing chain with a length-1 chain where the first and only
70+
incremental holds the entire graph).
6671
+
6772
* If `--size-multiple=<X>` is not specified, let `X` equal 2. If the new
6873
tip file would have `N` commits and the previous tip has `M` commits and

builtin/commit-graph.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,16 @@ static struct split_commit_graph_opts split_opts;
118118
static int write_option_parse_split(const struct option *opt, const char *arg,
119119
int unset)
120120
{
121+
enum commit_graph_split_flags *flags = opt->value;
122+
121123
opts.split = 1;
122124
if (!arg)
123125
return 0;
124126

125-
die(_("unrecognized --split argument, %s"), arg);
127+
if (!strcmp(arg, "no-merge"))
128+
*flags = COMMIT_GRAPH_SPLIT_MERGE_PROHIBITED;
129+
else
130+
die(_("unrecognized --split argument, %s"), arg);
126131

127132
return 0;
128133
}

commit-graph.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1529,6 +1529,7 @@ static void split_graph_merge_strategy(struct write_commit_graph_context *ctx)
15291529
{
15301530
struct commit_graph *g;
15311531
uint32_t num_commits;
1532+
enum commit_graph_split_flags flags = COMMIT_GRAPH_SPLIT_UNSPECIFIED;
15321533
uint32_t i;
15331534

15341535
int max_commits = 0;
@@ -1539,21 +1540,25 @@ static void split_graph_merge_strategy(struct write_commit_graph_context *ctx)
15391540

15401541
if (ctx->split_opts->size_multiple)
15411542
size_mult = ctx->split_opts->size_multiple;
1543+
1544+
flags = ctx->split_opts->flags;
15421545
}
15431546

15441547
g = ctx->r->objects->commit_graph;
15451548
num_commits = ctx->commits.nr;
15461549
ctx->num_commit_graphs_after = ctx->num_commit_graphs_before + 1;
15471550

1548-
while (g && (g->num_commits <= size_mult * num_commits ||
1549-
(max_commits && num_commits > max_commits))) {
1550-
if (g->odb != ctx->odb)
1551-
break;
1551+
if (flags != COMMIT_GRAPH_SPLIT_MERGE_PROHIBITED) {
1552+
while (g && (g->num_commits <= size_mult * num_commits ||
1553+
(max_commits && num_commits > max_commits))) {
1554+
if (g->odb != ctx->odb)
1555+
break;
15521556

1553-
num_commits += g->num_commits;
1554-
g = g->base_graph;
1557+
num_commits += g->num_commits;
1558+
g = g->base_graph;
15551559

1556-
ctx->num_commit_graphs_after--;
1560+
ctx->num_commit_graphs_after--;
1561+
}
15571562
}
15581563

15591564
ctx->new_base_graph = g;

commit-graph.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ enum commit_graph_write_flags {
8383
};
8484

8585
enum commit_graph_split_flags {
86-
COMMIT_GRAPH_SPLIT_UNSPECIFIED = 0
86+
COMMIT_GRAPH_SPLIT_UNSPECIFIED = 0,
87+
COMMIT_GRAPH_SPLIT_MERGE_PROHIBITED = 1
8788
};
8889

8990
struct split_commit_graph_opts {

t/t5324-split-commit-graph.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,4 +344,15 @@ test_expect_success 'split across alternate where alternate is not split' '
344344
test_cmp commit-graph .git/objects/info/commit-graph
345345
'
346346

347+
test_expect_success '--split=no-merge always writes an incremental' '
348+
test_when_finished rm -rf a b &&
349+
rm -rf $graphdir $infodir/commit-graph &&
350+
git reset --hard commits/2 &&
351+
git rev-list HEAD~1 >a &&
352+
git rev-list HEAD >b &&
353+
git commit-graph write --split --stdin-commits <a &&
354+
git commit-graph write --split=no-merge --stdin-commits <b &&
355+
test_line_count = 2 $graphdir/commit-graph-chain
356+
'
357+
347358
test_done

0 commit comments

Comments
 (0)