Skip to content

Commit 7e2ad1c

Browse files
jonathantanmygitster
authored andcommitted
commit: don't lazy-fetch commits
When parsing commits, fail fast when the commit is missing or corrupt, instead of attempting to fetch them. This is done by inlining repo_read_object_file() and setting the flag that prevents fetching. This is motivated by a situation in which through a bug (not necessarily through Git), there was corruption in the object store of a partial clone. In this particular case, the problem was exposed when "git gc" tried to expire reflogs, which calls repo_parse_commit(), which triggers fetches of the missing commits. (There are other possible solutions to this problem including passing an argument from "git gc" to "git reflog" to inhibit all lazy fetches, but I think that this fix is at the wrong level - fixing "git reflog" means that this particular command works fine, or so we think (it will fail if it somehow needs to read a legitimately missing blob, say, a .gitmodules file), but fixing repo_parse_commit() will fix a whole class of bugs.) Signed-off-by: Jonathan Tan <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 9e59b38 commit 7e2ad1c

File tree

1 file changed

+13
-2
lines changed

1 file changed

+13
-2
lines changed

commit.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,17 @@ int repo_parse_commit_internal(struct repository *r,
508508
enum object_type type;
509509
void *buffer;
510510
unsigned long size;
511+
struct object_info oi = {
512+
.typep = &type,
513+
.sizep = &size,
514+
.contentp = &buffer,
515+
};
516+
/*
517+
* Git does not support partial clones that exclude commits, so set
518+
* OBJECT_INFO_SKIP_FETCH_OBJECT to fail fast when an object is missing.
519+
*/
520+
int flags = OBJECT_INFO_LOOKUP_REPLACE | OBJECT_INFO_SKIP_FETCH_OBJECT |
521+
OBJECT_INFO_DIE_IF_CORRUPT;
511522
int ret;
512523

513524
if (!item)
@@ -516,8 +527,8 @@ int repo_parse_commit_internal(struct repository *r,
516527
return 0;
517528
if (use_commit_graph && parse_commit_in_graph(r, item))
518529
return 0;
519-
buffer = repo_read_object_file(r, &item->object.oid, &type, &size);
520-
if (!buffer)
530+
531+
if (oid_object_info_extended(r, &item->object.oid, &oi, flags) < 0)
521532
return quiet_on_missing ? -1 :
522533
error("Could not read %s",
523534
oid_to_hex(&item->object.oid));

0 commit comments

Comments
 (0)