On Wed, Jun 15, 2022 at 10:18 AM Taylor Blau <me@xxxxxxxxxxxx> wrote: > > [+cc Stolee] > > On Tue, Jun 14, 2022 at 03:25:13PM +0800, Haiyng Tan wrote: > > I think it's caused by using lazy-fetch in > > deref_without_lazy_fetch_extended(). In lookup_commit_in_graph(), > > lazy-fetch is initiated by repo_has_object_file() used. has_object() > > should be used, it's no-lazy-fetch. > > Hmm. Are there cases where lookup_commit_in_graph() is expected to > lazily fetch missing objects from promisor remotes? If so, then this > wouldn't quite work. If not, then this seems like an appropriate fix to > me. > > Thanks, > Taylor We can see the use of has_object() in RelNotes/2.29.0.txt[1]: * A new helper function has_object() has been introduced to make it easier to mark object existence checks that do and don't want to trigger lazy fetches, and a few such checks are converted using it. Let's see the difference between has_object() and repo_has_object_file(): int has_object(struct repository *r, const struct object_id *oid, unsigned flags) { int quick = !(flags & HAS_OBJECT_RECHECK_PACKED); unsigned object_info_flags = OBJECT_INFO_SKIP_FETCH_OBJECT | (quick ? OBJECT_INFO_QUICK : 0); if (!startup_info->have_repository) return 0; return oid_object_info_extended(r, oid, NULL, object_info_flags) >= 0; } int repo_has_object_file_with_flags(struct repository *r, const struct object_id *oid, int flags) { if (!startup_info->have_repository) return 0; return oid_object_info_extended(r, oid, NULL, flags) >= 0; } int repo_has_object_file(struct repository *r, const struct object_id *oid) { return repo_has_object_file_with_flags(r, oid, 0); } Now we kown that has_object() add OBJECT_INFO_SKIP_FETCH_OBJECT to skip fetch object. I found that Ævar Arnfjörð Bjarmason added deref_without_lazy_fetch() 4 weeks ago[2]: static struct commit *deref_without_lazy_fetch(const struct object_id *oid, int mark_tags_complete) { enum object_type type; unsigned flags = OBJECT_INFO_SKIP_FETCH_OBJECT | OBJECT_INFO_QUICK; return deref_without_lazy_fetch_extended(oid, mark_tags_complete, &type, flags); } But oi_flags is only used by oid_object_info_extended() and is missed by lookup_commit_in_graph(): static struct commit *deref_without_lazy_fetch_extended(const struct object_id *oid, int mark_tags_complete, enum object_type *type, unsigned int oi_flags) { struct object_info info = { .typep = type }; struct commit *commit; commit = lookup_commit_in_graph(the_repository, oid); if (commit) return commit; while (1) { if (oid_object_info_extended(the_repository, oid, &info, oi_flags)) So, an appropriate fix can be that let lookup_commit_in_graph() pickup oi_flags and pass it to oid_object_info_extended(), then the fetching loop will be prevent by the given flag OBJECT_INFO_SKIP_FETCH_OBJECT. 1. https://github.com/git/git/blob/master/Documentation/RelNotes/2.29.0.txt 2. https://lore.kernel.org/git/2a563b5f18cc9c42cb71a9547344a5435f6bc058.1652731865.git.gitgitgadget@xxxxxxxxx/ Thanks -Han Xin Han Xin (2): commit-graph.c: add "flags" to lookup_commit_in_graph() fetch-pack.c: pass "oi_flags" to lookup_commit_in_graph() builtin/fetch.c | 4 ++- commit-graph.c | 5 ++-- commit-graph.h | 3 +- fetch-pack.c | 10 +++---- revision.c | 2 +- t/t5583-fetch-with-commit-graph.sh | 47 ++++++++++++++++++++++++++++++ upload-pack.c | 5 ++-- 7 files changed, 64 insertions(+), 12 deletions(-) create mode 100644 t/t5583-fetch-with-commit-graph.sh -- 2.36.1