[RFC PATCH 0/2] Re: An endless loop fetching issue with partial clone, alternates and commit graph
- From
Han Xin <hanxin.hx@bytedance.com>
- Date
- Jun 16, 2022, 03:38 UTC
- Message-ID
- <cover.1655350442.git.hanxin.hx@bytedance.com>
- In-Reply-To
- <YqlBjET0tf7V9/sg@nand.local>
On Wed, Jun 15, 2022 at 10:18 AM Taylor Blau <me@ttaylorr.com> wrote:
Show 16 quoted lines
> > [+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@gmail.com/
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