From: Christian Couder <christian.couder@gmail.com>
To: git@vger.kernel.org
Cc: Junio C Hamano <gitster@pobox.com>,
"brian m . carlson" <sandals@crustytoothpaste.net>,
Patrick Steinhardt <ps@pks.im>,
Karthik Nayak <karthik.188@gmail.com>, Jeff King <peff@peff.net>,
Elijah Newren <newren@gmail.com>,
Christian Couder <christian.couder@gmail.com>
Subject: [PATCH v4 1/5] promisor-remote: factor out lazy_fetch_objects()
Date: Mon, 28 Sep 2026 15:38:42 +0200 [thread overview]
Message-ID: <20260928133846.2094261-2-christian.couder@gmail.com> (raw)
In-Reply-To: <20260928133846.2094261-1-christian.couder@gmail.com>
In "promisor-remote.c:fetch_objects()", there is a check to disable
lazy fetching when the `GIT_NO_LAZY_FETCH` environment variable is
set. The fetch_objects() function is called once per promisor remote
though. So the check might be performed more times than necessary.
Also promisor_remote_get_direct() mixes up the logic deciding which
promisor remotes to try with the logic checking that the objects
that could not be fetched are promisor objects.
Let's refactor the lazy fetching logic out of these two functions
into a new lazy_fetch_objects() function.
This is a pure refactoring with no intended behavior change. Two
things shift in ways that are observably equivalent though:
- the `GIT_NO_LAZY_FETCH` check is now performed once up front,
instead of once per promisor remote, and
- promisor_remote_init() is no longer called when lazy fetching
is disabled.
The latter is fine because the convention around promisor_remote_init()
is that whoever needs to access the promisor remote information is
expected to initialize it beforehand, and not that it should be
initialized once at the very beginning before doing random things on
promisor remotes. So moving its call site into lazy_fetch_objects(),
which is the only code that needs the promisor remotes here, follows
that convention. Nothing downstream of it, like is_promisor_object(),
needs it when lazy fetching is disabled.
While at it, let's document try_promisor_remotes() and the new
lazy_fetch_objects() function, especially how their `remaining_oids`,
`remaining_nr` and `to_free` arguments are used, as the ownership
rules around `to_free` are easy to get wrong.
Signed-off-by: Christian Couder <christian.couder@gmail.com>
---
promisor-remote.c | 83 ++++++++++++++++++++++++++++++++---------------
1 file changed, 57 insertions(+), 26 deletions(-)
diff --git a/promisor-remote.c b/promisor-remote.c
index 43505d1e1a..91245fe9a8 100644
--- a/promisor-remote.c
+++ b/promisor-remote.c
@@ -31,15 +31,6 @@ static int fetch_objects(struct repository *repo,
FILE *child_in;
int quiet;
- if (git_env_bool(NO_LAZY_FETCH_ENVIRONMENT, 0)) {
- static int warning_shown;
- if (!warning_shown) {
- warning_shown = 1;
- warning(_("lazy fetching disabled; some objects may not be available"));
- }
- return -1;
- }
-
child.git_cmd = 1;
child.in = -1;
if (repo != the_repository)
@@ -270,9 +261,27 @@ static int remove_fetched_oids(struct repository *repo,
return remaining_nr;
}
+/*
+ * Fetch the remaining objects (given in '*remaining_oids', which
+ * contains '*remaining_nr' object ids) from the known promisor
+ * remotes. If 'accepted_only' is true, ignore promisor remotes with
+ * their 'accepted' member unset.
+ *
+ * When a fetch from a remote fails, the objects that are still
+ * missing are computed, and '*remaining_oids' and '*remaining_nr' are
+ * updated accordingly before trying the next remote. In that case
+ * '*remaining_oids' points to a new array that this function
+ * allocated, and '*to_free' is set to 1 to tell the caller that it
+ * owns that array and should free it. '*to_free' should be 0 on the
+ * first call.
+ *
+ * Return 1 when all the requested objects have been fetched, 0
+ * otherwise.
+ */
static int try_promisor_remotes(struct repository *repo,
struct object_id **remaining_oids,
- int *remaining_nr, int *to_free,
+ int *remaining_nr,
+ int *to_free,
bool accepted_only)
{
struct promisor_remote *r = repo->promisor_remote_config->promisors;
@@ -295,6 +304,38 @@ static int try_promisor_remotes(struct repository *repo,
return 0;
}
+/*
+ * Lazily fetch the objects given in '*remaining_oids' from the
+ * promisor remotes, trying the accepted ones first. See
+ * try_promisor_remotes() above for how '*remaining_oids',
+ * '*remaining_nr' and '*to_free' are used.
+ *
+ * Return 1 when all the requested objects have been fetched, 0
+ * otherwise.
+ */
+static int lazy_fetch_objects(struct repository *repo,
+ struct object_id **remaining_oids,
+ int *remaining_nr,
+ int *to_free)
+{
+ if (git_env_bool(NO_LAZY_FETCH_ENVIRONMENT, 0)) {
+ static int warning_shown;
+ if (!warning_shown) {
+ warning_shown = 1;
+ warning(_("lazy fetching disabled; some objects may not be available"));
+ }
+ return 0;
+ }
+
+ promisor_remote_init(repo);
+
+ /* Try accepted remotes first (those the server told us to use) */
+ return try_promisor_remotes(repo, remaining_oids, remaining_nr,
+ to_free, true) ||
+ try_promisor_remotes(repo, remaining_oids, remaining_nr,
+ to_free, false);
+}
+
void promisor_remote_get_direct(struct repository *repo,
const struct object_id *oids,
int oid_nr)
@@ -302,28 +343,18 @@ void promisor_remote_get_direct(struct repository *repo,
struct object_id *remaining_oids = (struct object_id *)oids;
int remaining_nr = oid_nr;
int to_free = 0;
- int i;
if (oid_nr == 0)
return;
- promisor_remote_init(repo);
-
- /* Try accepted remotes first (those the server told us to use) */
- if (try_promisor_remotes(repo, &remaining_oids, &remaining_nr,
- &to_free, true))
- goto all_fetched;
- if (try_promisor_remotes(repo, &remaining_oids, &remaining_nr,
- &to_free, false))
- goto all_fetched;
-
- for (i = 0; i < remaining_nr; i++) {
- if (is_promisor_object(repo, &remaining_oids[i]))
- die(_("could not fetch %s from promisor remote"),
- oid_to_hex(&remaining_oids[i]));
+ if (!lazy_fetch_objects(repo, &remaining_oids, &remaining_nr, &to_free)) {
+ for (int i = 0; i < remaining_nr; i++) {
+ if (is_promisor_object(repo, &remaining_oids[i]))
+ die(_("could not fetch %s from promisor remote"),
+ oid_to_hex(&remaining_oids[i]));
+ }
}
-all_fetched:
if (to_free)
free(remaining_oids);
}
--
2.56.0.rc2.20.g34f06850c1
next prev parent reply other threads:[~2026-09-28 13:39 UTC|newest]
Thread overview: 70+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-10 8:51 [PATCH 0/3] Introduce a 'fromAccepted' option to GIT_NO_LAZY_FETCH Christian Couder
2026-07-10 8:51 ` [PATCH 1/3] promisor-remote: factor out lazy_fetch_objects() Christian Couder
2026-07-10 8:51 ` [PATCH 2/3] promisor-remote: introduce enum allow_lazy_fetch Christian Couder
2026-07-10 8:51 ` [PATCH 3/3] promisor-remote: teach 'fromAccepted' to GIT_NO_LAZY_FETCH Christian Couder
2026-07-10 19:50 ` [PATCH 0/3] Introduce a 'fromAccepted' option " brian m. carlson
2026-07-12 9:06 ` Christian Couder
2026-08-07 13:55 ` [PATCH 0/5] Introduce 'uploadpack.lazyFetchTrusted' Christian Couder
2026-08-07 13:55 ` [PATCH 1/5] promisor-remote: factor out lazy_fetch_objects() Christian Couder
2026-08-07 13:58 ` Christian Couder
2026-08-07 13:55 ` [PATCH 2/5] setup: extract path_allowlist_apply() Christian Couder
2026-08-07 13:55 ` [PATCH 3/5] setup: add 'allow_dot' arg to path_allowlist_apply() Christian Couder
2026-08-07 13:55 ` [PATCH 4/5] upload-pack: read uploadpack.lazyFetchTrusted Christian Couder
2026-08-07 13:55 ` [PATCH 5/5] builtin/upload-pack: set GIT_NO_LAZY_FETCH to 0 on trusted repo Christian Couder
2026-08-07 18:31 ` [PATCH 0/5] Introduce 'uploadpack.lazyFetchTrusted' Junio C Hamano
2026-08-10 8:06 ` Christian Couder
2026-08-11 5:55 ` Junio C Hamano
2026-08-13 15:47 ` [PATCH v2 " Christian Couder
2026-08-13 20:31 ` Junio C Hamano
2026-08-14 16:31 ` Christian Couder
2026-08-14 16:40 ` Junio C Hamano
2026-09-08 16:41 ` [PATCH v3 " Christian Couder
2026-09-08 16:41 ` [PATCH v3 1/5] promisor-remote: factor out lazy_fetch_objects() Christian Couder
2026-09-08 17:39 ` Junio C Hamano
2026-09-28 13:39 ` Christian Couder
2026-09-08 16:41 ` [PATCH v3 2/5] setup: extract path_allowlist_apply() Christian Couder
2026-09-08 17:48 ` Junio C Hamano
2026-09-28 13:40 ` Christian Couder
2026-09-08 16:41 ` [PATCH v3 3/5] upload-pack: read uploadpack.lazyFetchTrusted Christian Couder
2026-09-08 16:41 ` [PATCH v3 4/5] promisor-remote: prevent infinite recursion when lazy fetching Christian Couder
2026-09-08 18:12 ` Junio C Hamano
2026-09-09 10:00 ` Christian Couder
2026-09-09 21:39 ` Junio C Hamano
2026-09-28 13:41 ` Christian Couder
2026-09-08 16:41 ` [PATCH v3 5/5] builtin/upload-pack: set GIT_NO_LAZY_FETCH to 0 on trusted repo Christian Couder
2026-09-08 18:34 ` Junio C Hamano
2026-09-28 13:42 ` Christian Couder
2026-09-28 13:38 ` [PATCH v4 0/5] Introduce 'uploadpack.lazyFetchTrusted' Christian Couder
2026-09-28 13:38 ` Christian Couder [this message]
2026-09-28 13:38 ` [PATCH v4 2/5] setup: extract path_allowlist_apply() Christian Couder
2026-09-29 17:26 ` Junio C Hamano
2026-10-02 9:00 ` Christian Couder
2026-09-28 13:38 ` [PATCH v4 3/5] upload-pack: read uploadpack.lazyFetchTrusted Christian Couder
2026-09-28 13:38 ` [PATCH v4 4/5] promisor-remote: prevent infinite recursion when lazy fetching Christian Couder
2026-09-28 13:38 ` [PATCH v4 5/5] builtin/upload-pack: don't disable lazy fetching on trusted repo Christian Couder
2026-09-29 17:47 ` Junio C Hamano
2026-10-02 8:57 ` Christian Couder
2026-10-02 9:18 ` Christian Couder
2026-10-02 8:23 ` [PATCH v5 0/5] Introduce 'uploadpack.lazyFetchTrusted' Christian Couder
2026-10-02 8:23 ` [PATCH v5 1/5] promisor-remote: factor out lazy_fetch_objects() Christian Couder
2026-10-02 8:23 ` [PATCH v5 2/5] setup: extract path_allowlist_apply() Christian Couder
2026-10-02 8:23 ` [PATCH v5 3/5] upload-pack: read uploadpack.lazyFetchTrusted Christian Couder
2026-10-02 8:23 ` [PATCH v5 4/5] promisor-remote: prevent infinite recursion when lazy fetching Christian Couder
2026-10-02 8:23 ` [PATCH v5 5/5] builtin/upload-pack: don't disable lazy fetching on trusted repo Christian Couder
2026-10-05 15:37 ` [PATCH v5 0/5] Introduce 'uploadpack.lazyFetchTrusted' Junio C Hamano
2026-10-06 14:54 ` Christian Couder
2026-08-13 15:47 ` [PATCH v2 1/5] promisor-remote: factor out lazy_fetch_objects() Christian Couder
2026-08-14 17:49 ` Junio C Hamano
2026-09-08 17:11 ` Christian Couder
2026-08-13 15:47 ` [PATCH v2 2/5] setup: extract path_allowlist_apply() Christian Couder
2026-08-14 17:56 ` Junio C Hamano
2026-09-08 16:46 ` Christian Couder
2026-09-08 17:49 ` Junio C Hamano
2026-08-13 15:47 ` [PATCH v2 3/5] setup: add 'allow_dot' arg to path_allowlist_apply() Christian Couder
2026-08-14 18:12 ` Junio C Hamano
2026-09-08 16:55 ` Christian Couder
2026-08-13 15:47 ` [PATCH v2 4/5] upload-pack: read uploadpack.lazyFetchTrusted Christian Couder
2026-08-14 18:56 ` Junio C Hamano
2026-08-13 15:47 ` [PATCH v2 5/5] builtin/upload-pack: set GIT_NO_LAZY_FETCH to 0 on trusted repo Christian Couder
2026-08-14 19:35 ` Junio C Hamano
2026-09-08 17:02 ` Christian Couder
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260928133846.2094261-2-christian.couder@gmail.com \
--to=christian.couder@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=karthik.188@gmail.com \
--cc=newren@gmail.com \
--cc=peff@peff.net \
--cc=ps@pks.im \
--cc=sandals@crustytoothpaste.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox