Skip to content

Commit b4dd083

Browse files
committed
Merge branch 'jt/commit-graph-missing' into next
A regression where commit objects missing from a commit-graph can cause an infinite loop when doing a fetch in a partial clone has been fixed. * jt/commit-graph-missing: fetch-pack: die if in commit graph but not obj db Revert "fetch-pack: add a deref_without_lazy_fetch_extended()"
2 parents 8c5d529 + 5d4cc78 commit b4dd083

File tree

2 files changed

+24
-22
lines changed

2 files changed

+24
-22
lines changed

fetch-pack.c

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -122,37 +122,49 @@ static void for_each_cached_alternate(struct fetch_negotiator *negotiator,
122122
cb(negotiator, cache.items[i]);
123123
}
124124

125-
static struct commit *deref_without_lazy_fetch_extended(const struct object_id *oid,
126-
int mark_tags_complete,
127-
enum object_type *type,
128-
unsigned int oi_flags)
125+
static void die_in_commit_graph_only(const struct object_id *oid)
129126
{
130-
struct object_info info = { .typep = type };
127+
die(_("You are attempting to fetch %s, which is in the commit graph file but not in the object database.\n"
128+
"This is probably due to repo corruption.\n"
129+
"If you are attempting to repair this repo corruption by refetching the missing object, use 'git fetch --refetch' with the missing object."),
130+
oid_to_hex(oid));
131+
}
132+
133+
static struct commit *deref_without_lazy_fetch(const struct object_id *oid,
134+
int mark_tags_complete_and_check_obj_db)
135+
{
136+
enum object_type type;
137+
struct object_info info = { .typep = &type };
131138
struct commit *commit;
132139

133140
commit = lookup_commit_in_graph(the_repository, oid);
134-
if (commit)
141+
if (commit) {
142+
if (mark_tags_complete_and_check_obj_db) {
143+
if (!has_object(the_repository, oid, 0))
144+
die_in_commit_graph_only(oid);
145+
}
135146
return commit;
147+
}
136148

137149
while (1) {
138150
if (oid_object_info_extended(the_repository, oid, &info,
139-
oi_flags))
151+
OBJECT_INFO_SKIP_FETCH_OBJECT | OBJECT_INFO_QUICK))
140152
return NULL;
141-
if (*type == OBJ_TAG) {
153+
if (type == OBJ_TAG) {
142154
struct tag *tag = (struct tag *)
143155
parse_object(the_repository, oid);
144156

145157
if (!tag->tagged)
146158
return NULL;
147-
if (mark_tags_complete)
159+
if (mark_tags_complete_and_check_obj_db)
148160
tag->object.flags |= COMPLETE;
149161
oid = &tag->tagged->oid;
150162
} else {
151163
break;
152164
}
153165
}
154166

155-
if (*type == OBJ_COMMIT) {
167+
if (type == OBJ_COMMIT) {
156168
struct commit *commit = lookup_commit(the_repository, oid);
157169
if (!commit || repo_parse_commit(the_repository, commit))
158170
return NULL;
@@ -162,16 +174,6 @@ static struct commit *deref_without_lazy_fetch_extended(const struct object_id *
162174
return NULL;
163175
}
164176

165-
166-
static struct commit *deref_without_lazy_fetch(const struct object_id *oid,
167-
int mark_tags_complete)
168-
{
169-
enum object_type type;
170-
unsigned flags = OBJECT_INFO_SKIP_FETCH_OBJECT | OBJECT_INFO_QUICK;
171-
return deref_without_lazy_fetch_extended(oid, mark_tags_complete,
172-
&type, flags);
173-
}
174-
175177
static int rev_list_insert_ref(struct fetch_negotiator *negotiator,
176178
const struct object_id *oid)
177179
{

t/t5330-no-lazy-fetch-with-commit-graph.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ test_expect_success 'fetch any commit from promisor with the usage of the commit
3838
git -C with-commit-graph config remote.origin.partialclonefilter blob:none &&
3939
test_commit -C with-commit any-commit &&
4040
anycommit=$(git -C with-commit rev-parse HEAD) &&
41-
GIT_TRACE="$(pwd)/trace.txt" \
41+
test_must_fail env GIT_TRACE="$(pwd)/trace.txt" \
4242
git -C with-commit-graph fetch origin $anycommit 2>err &&
43-
! grep "fatal: promisor-remote: unable to fork off fetch subprocess" err &&
43+
test_grep ! "fatal: promisor-remote: unable to fork off fetch subprocess" err &&
4444
grep "git fetch origin" trace.txt >actual &&
4545
test_line_count = 1 actual
4646
'

0 commit comments

Comments
 (0)