Skip to content

Commit 135a712

Browse files
derrickstoleegitster
authored andcommitted
commit-graph: add --split option to builtin
Add a new "--split" option to the 'git commit-graph write' subcommand. This option allows the optional behavior of writing a commit-graph chain. The current behavior will add a tip commit-graph containing any commits that are not in the existing commit-graph or commit-graph chain. Later changes will allow merging the chain and expiring out-dated files. Add a new test script (t5324-split-commit-graph.sh) that demonstrates this behavior. Helped-by: Johannes Schindelin <[email protected]> Signed-off-by: Derrick Stolee <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 6c622f9 commit 135a712

File tree

3 files changed

+138
-8
lines changed

3 files changed

+138
-8
lines changed

builtin/commit-graph.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ static char const * const builtin_commit_graph_usage[] = {
1010
N_("git commit-graph [--object-dir <objdir>]"),
1111
N_("git commit-graph read [--object-dir <objdir>]"),
1212
N_("git commit-graph verify [--object-dir <objdir>]"),
13-
N_("git commit-graph write [--object-dir <objdir>] [--append] [--reachable|--stdin-packs|--stdin-commits]"),
13+
N_("git commit-graph write [--object-dir <objdir>] [--append|--split] [--reachable|--stdin-packs|--stdin-commits]"),
1414
NULL
1515
};
1616

@@ -25,7 +25,7 @@ static const char * const builtin_commit_graph_read_usage[] = {
2525
};
2626

2727
static const char * const builtin_commit_graph_write_usage[] = {
28-
N_("git commit-graph write [--object-dir <objdir>] [--append] [--reachable|--stdin-packs|--stdin-commits]"),
28+
N_("git commit-graph write [--object-dir <objdir>] [--append|--split] [--reachable|--stdin-packs|--stdin-commits]"),
2929
NULL
3030
};
3131

@@ -35,9 +35,9 @@ static struct opts_commit_graph {
3535
int stdin_packs;
3636
int stdin_commits;
3737
int append;
38+
int split;
3839
} opts;
3940

40-
4141
static int graph_verify(int argc, const char **argv)
4242
{
4343
struct commit_graph *graph = NULL;
@@ -156,6 +156,8 @@ static int graph_write(int argc, const char **argv)
156156
N_("start walk at commits listed by stdin")),
157157
OPT_BOOL(0, "append", &opts.append,
158158
N_("include all commits already in the commit-graph file")),
159+
OPT_BOOL(0, "split", &opts.split,
160+
N_("allow writing an incremental commit-graph file")),
159161
OPT_END(),
160162
};
161163

@@ -169,6 +171,8 @@ static int graph_write(int argc, const char **argv)
169171
opts.obj_dir = get_object_directory();
170172
if (opts.append)
171173
flags |= COMMIT_GRAPH_APPEND;
174+
if (opts.split)
175+
flags |= COMMIT_GRAPH_SPLIT;
172176

173177
read_replace_refs = 0;
174178

commit-graph.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1472,12 +1472,16 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx)
14721472
}
14731473

14741474
if (ctx->base_graph_name) {
1475-
result = rename(ctx->base_graph_name,
1476-
ctx->commit_graph_filenames_after[ctx->num_commit_graphs_after - 2]);
1475+
const char *dest = ctx->commit_graph_filenames_after[
1476+
ctx->num_commit_graphs_after - 2];
14771477

1478-
if (result) {
1479-
error(_("failed to rename base commit-graph file"));
1480-
return -1;
1478+
if (strcmp(ctx->base_graph_name, dest)) {
1479+
result = rename(ctx->base_graph_name, dest);
1480+
1481+
if (result) {
1482+
error(_("failed to rename base commit-graph file"));
1483+
return -1;
1484+
}
14811485
}
14821486
} else {
14831487
char *graph_name = get_commit_graph_filename(ctx->obj_dir);

t/t5324-split-commit-graph.sh

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
#!/bin/sh
2+
3+
test_description='split commit graph'
4+
. ./test-lib.sh
5+
6+
GIT_TEST_COMMIT_GRAPH=0
7+
8+
test_expect_success 'setup repo' '
9+
git init &&
10+
git config core.commitGraph true &&
11+
infodir=".git/objects/info" &&
12+
graphdir="$infodir/commit-graphs" &&
13+
test_oid_init
14+
'
15+
16+
graph_read_expect() {
17+
NUM_BASE=0
18+
if test ! -z $2
19+
then
20+
NUM_BASE=$2
21+
fi
22+
cat >expect <<- EOF
23+
header: 43475048 1 1 3 $NUM_BASE
24+
num_commits: $1
25+
chunks: oid_fanout oid_lookup commit_metadata
26+
EOF
27+
git commit-graph read >output &&
28+
test_cmp expect output
29+
}
30+
31+
test_expect_success 'create commits and write commit-graph' '
32+
for i in $(test_seq 3)
33+
do
34+
test_commit $i &&
35+
git branch commits/$i || return 1
36+
done &&
37+
git commit-graph write --reachable &&
38+
test_path_is_file $infodir/commit-graph &&
39+
graph_read_expect 3
40+
'
41+
42+
graph_git_two_modes() {
43+
git -c core.commitGraph=true $1 >output
44+
git -c core.commitGraph=false $1 >expect
45+
test_cmp expect output
46+
}
47+
48+
graph_git_behavior() {
49+
MSG=$1
50+
BRANCH=$2
51+
COMPARE=$3
52+
test_expect_success "check normal git operations: $MSG" '
53+
graph_git_two_modes "log --oneline $BRANCH" &&
54+
graph_git_two_modes "log --topo-order $BRANCH" &&
55+
graph_git_two_modes "log --graph $COMPARE..$BRANCH" &&
56+
graph_git_two_modes "branch -vv" &&
57+
graph_git_two_modes "merge-base -a $BRANCH $COMPARE"
58+
'
59+
}
60+
61+
graph_git_behavior 'graph exists' commits/3 commits/1
62+
63+
verify_chain_files_exist() {
64+
for hash in $(cat $1/commit-graph-chain)
65+
do
66+
test_path_is_file $1/graph-$hash.graph || return 1
67+
done
68+
}
69+
70+
test_expect_success 'add more commits, and write a new base graph' '
71+
git reset --hard commits/1 &&
72+
for i in $(test_seq 4 5)
73+
do
74+
test_commit $i &&
75+
git branch commits/$i || return 1
76+
done &&
77+
git reset --hard commits/2 &&
78+
for i in $(test_seq 6 10)
79+
do
80+
test_commit $i &&
81+
git branch commits/$i || return 1
82+
done &&
83+
git reset --hard commits/2 &&
84+
git merge commits/4 &&
85+
git branch merge/1 &&
86+
git reset --hard commits/4 &&
87+
git merge commits/6 &&
88+
git branch merge/2 &&
89+
git commit-graph write --reachable &&
90+
graph_read_expect 12
91+
'
92+
93+
test_expect_success 'add three more commits, write a tip graph' '
94+
git reset --hard commits/3 &&
95+
git merge merge/1 &&
96+
git merge commits/5 &&
97+
git merge merge/2 &&
98+
git branch merge/3 &&
99+
git commit-graph write --reachable --split &&
100+
test_path_is_missing $infodir/commit-graph &&
101+
test_path_is_file $graphdir/commit-graph-chain &&
102+
ls $graphdir/graph-*.graph >graph-files &&
103+
test_line_count = 2 graph-files &&
104+
verify_chain_files_exist $graphdir
105+
'
106+
107+
graph_git_behavior 'split commit-graph: merge 3 vs 2' merge/3 merge/2
108+
109+
test_expect_success 'add one commit, write a tip graph' '
110+
test_commit 11 &&
111+
git branch commits/11 &&
112+
git commit-graph write --reachable --split &&
113+
test_path_is_missing $infodir/commit-graph &&
114+
test_path_is_file $graphdir/commit-graph-chain &&
115+
ls $graphdir/graph-*.graph >graph-files &&
116+
test_line_count = 3 graph-files &&
117+
verify_chain_files_exist $graphdir
118+
'
119+
120+
graph_git_behavior 'three-layer commit-graph: commit 11 vs 6' commits/11 commits/6
121+
122+
test_done

0 commit comments

Comments
 (0)