Skip to content

Commit 5f25919

Browse files
peffgitster
authored andcommitted
commit-graph: report incomplete chains during verification
The load_commit_graph_chain_fd_st() function will stop loading chains when it sees an error. But if it has loaded any graph slice at all, it will return it. This is a good thing for normal use (we use what data we can, and this is just an optimization). But it's a bad thing for "commit-graph verify", which should be careful about finding any irregularities. We do complain to stderr with a warning(), but the verify command still exits with a successful return code. The new tests here cover corruption of both the base and tip slices of the chain. The corruption of the base file already works (it is the first file we look at, so when we see the error we return NULL). The "tip" case is what is fixed by this patch (it complains to stderr but still returns the base slice). Likewise the existing tests for corruption of the commit-graph-chain file itself need to be updated. We already exited non-zero correctly for the "base" case, but the "tip" case can now do so, too. Note that this also causes us to adjust a test later in the file that similarly corrupts a tip (though confusingly the test script calls this "base"). It checks stderr but erroneously expects the whole "verify" command to exit with a successful code. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 7754a56 commit 5f25919

File tree

4 files changed

+45
-7
lines changed

4 files changed

+45
-7
lines changed

builtin/commit-graph.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ static int graph_verify(int argc, const char **argv, const char *prefix)
7474
int fd;
7575
struct stat st;
7676
int flags = 0;
77+
int incomplete_chain = 0;
7778
int ret;
7879

7980
static struct option builtin_commit_graph_verify_options[] = {
@@ -122,13 +123,20 @@ static int graph_verify(int argc, const char **argv, const char *prefix)
122123
else if (opened == OPENED_GRAPH)
123124
graph = load_commit_graph_one_fd_st(the_repository, fd, &st, odb);
124125
else
125-
graph = load_commit_graph_chain_fd_st(the_repository, fd, &st);
126+
graph = load_commit_graph_chain_fd_st(the_repository, fd, &st,
127+
&incomplete_chain);
126128

127129
if (!graph)
128130
return 1;
129131

130132
ret = verify_commit_graph(the_repository, graph, flags);
131133
free_commit_graph(graph);
134+
135+
if (incomplete_chain) {
136+
error("one or more commit-graph chain files could not be loaded");
137+
ret |= 1;
138+
}
139+
132140
return ret;
133141
}
134142

commit-graph.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,8 @@ int open_commit_graph_chain(const char *chain_file,
563563
}
564564

565565
struct commit_graph *load_commit_graph_chain_fd_st(struct repository *r,
566-
int fd, struct stat *st)
566+
int fd, struct stat *st,
567+
int *incomplete_chain)
567568
{
568569
struct commit_graph *graph_chain = NULL;
569570
struct strbuf line = STRBUF_INIT;
@@ -618,6 +619,7 @@ struct commit_graph *load_commit_graph_chain_fd_st(struct repository *r,
618619
fclose(fp);
619620
strbuf_release(&line);
620621

622+
*incomplete_chain = !valid;
621623
return graph_chain;
622624
}
623625

@@ -630,8 +632,9 @@ static struct commit_graph *load_commit_graph_chain(struct repository *r,
630632
struct commit_graph *g = NULL;
631633

632634
if (open_commit_graph_chain(chain_file, &fd, &st)) {
635+
int incomplete;
633636
/* ownership of fd is taken over by load function */
634-
g = load_commit_graph_chain_fd_st(r, fd, &st);
637+
g = load_commit_graph_chain_fd_st(r, fd, &st, &incomplete);
635638
}
636639

637640
free(chain_file);

commit-graph.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,8 @@ struct commit_graph *load_commit_graph_one_fd_st(struct repository *r,
107107
int fd, struct stat *st,
108108
struct object_directory *odb);
109109
struct commit_graph *load_commit_graph_chain_fd_st(struct repository *r,
110-
int fd, struct stat *st);
110+
int fd, struct stat *st,
111+
int *incomplete_chain);
111112
struct commit_graph *read_commit_graph_one(struct repository *r,
112113
struct object_directory *odb);
113114

t/t5324-split-commit-graph.sh

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,32 @@ test_expect_success 'verify hashes along chain, even in shallow' '
285285
)
286286
'
287287

288+
test_expect_success 'verify notices chain slice which is bogus (base)' '
289+
git clone --no-hardlinks . verify-chain-bogus-base &&
290+
(
291+
cd verify-chain-bogus-base &&
292+
git commit-graph verify &&
293+
base_file=$graphdir/graph-$(sed -n 1p $graphdir/commit-graph-chain).graph &&
294+
echo "garbage" >$base_file &&
295+
test_must_fail git commit-graph verify 2>test_err &&
296+
grep -v "^+" test_err >err &&
297+
grep "commit-graph file is too small" err
298+
)
299+
'
300+
301+
test_expect_success 'verify notices chain slice which is bogus (tip)' '
302+
git clone --no-hardlinks . verify-chain-bogus-tip &&
303+
(
304+
cd verify-chain-bogus-tip &&
305+
git commit-graph verify &&
306+
tip_file=$graphdir/graph-$(sed -n 2p $graphdir/commit-graph-chain).graph &&
307+
echo "garbage" >$tip_file &&
308+
test_must_fail git commit-graph verify 2>test_err &&
309+
grep -v "^+" test_err >err &&
310+
grep "commit-graph file is too small" err
311+
)
312+
'
313+
288314
test_expect_success 'verify --shallow does not check base contents' '
289315
git clone --no-hardlinks . verify-shallow &&
290316
(
@@ -306,7 +332,7 @@ test_expect_success 'warn on base graph chunk incorrect' '
306332
git commit-graph verify &&
307333
base_file=$graphdir/graph-$(tail -n 1 $graphdir/commit-graph-chain).graph &&
308334
corrupt_file "$base_file" $(test_oid base) "\01" &&
309-
git commit-graph verify --shallow 2>test_err &&
335+
test_must_fail git commit-graph verify --shallow 2>test_err &&
310336
grep -v "^+" test_err >err &&
311337
test_i18ngrep "commit-graph chain does not match" err
312338
)
@@ -332,11 +358,11 @@ test_expect_success 'verify after commit-graph-chain corruption (tip)' '
332358
(
333359
cd verify-chain-tip &&
334360
corrupt_file "$graphdir/commit-graph-chain" 70 "G" &&
335-
git commit-graph verify 2>test_err &&
361+
test_must_fail git commit-graph verify 2>test_err &&
336362
grep -v "^+" test_err >err &&
337363
test_i18ngrep "invalid commit-graph chain" err &&
338364
corrupt_file "$graphdir/commit-graph-chain" 70 "A" &&
339-
git commit-graph verify 2>test_err &&
365+
test_must_fail git commit-graph verify 2>test_err &&
340366
grep -v "^+" test_err >err &&
341367
test_i18ngrep "unable to find all commit-graph files" err
342368
)

0 commit comments

Comments
 (0)