All of lore.kernel.org
 help / color / mirror / Atom feed
From: Patrick Steinhardt <ps@pks.im>
To: Junio C Hamano <gitster@pobox.com>
Cc: git@vger.kernel.org, Christian Couder <chriscool@tuxfamily.org>
Subject: Re: [PATCH v2 4/4] connected: search promisor objects generically
Date: Thu, 25 Jun 2026 07:54:22 +0200	[thread overview]
Message-ID: <ajzCjgLJ5pzBph2Z@pks.im> (raw)
In-Reply-To: <xmqqjyrnkinn.fsf@gitster.g>

On Wed, Jun 24, 2026 at 09:27:56AM -0700, Junio C Hamano wrote:
> Patrick Steinhardt <ps@pks.im> writes:
> > diff --git a/connected.c b/connected.c
> > index d2b334173f..b557ff5db9 100644
> > --- a/connected.c
> > +++ b/connected.c
> > @@ -11,6 +11,13 @@
> >  #include "packfile.h"
> >  #include "promisor-remote.h"
> >  
> > +static int promised_object_cb(const struct object_id *oid UNUSED,
> > +			      struct object_info *oi UNUSED,
> > +			      void *payload UNUSED)
> > +{
> > +	return 1;
> > +}
> > +
> >  /*
> >   * For partial clones, we don't want to have to do a regular connectivity check
> >   * because we have to enumerate and exclude all promisor objects (slow), and
> > @@ -30,25 +37,28 @@ static int check_connected_promisor(oid_iterate_fn fn,
> >  				    void *cb_data,
> >  				    const struct object_id **oid)
> >  {
> > +	struct odb_for_each_object_options opts = {
> > +		.flags = ODB_FOR_EACH_OBJECT_PROMISOR_ONLY,
> > +		.prefix_hex_len = the_repository->hash_algo->hexsz,
> > +	};
> > +	int err;
> > +
> >  	odb_reprepare(the_repository->objects);
> >  	do {
> > -		struct packed_git *p;
> > +		opts.prefix = *oid;
> >  
> > -		repo_for_each_pack(the_repository, p) {
> > -			if (!p->pack_promisor)
> > -				continue;
> > -			if (find_pack_entry_one(*oid, p))
> > -				goto promisor_pack_found;
> > -		}
> > +		err = odb_for_each_object_ext(the_repository->objects,
> > +					      NULL, promised_object_cb,
> > +					      NULL, &opts);
> 
> promised_object_cb() returns 1 without any computation since we are
> only interested in learning ODB_FOR_EACH_OBJECT_PROMISOR_ONLY finds
> any such object.
> 
> odb_for_each_object_ext() returns 0 (if it iterates all the sources
> to the end), but if its call to odb_source_for_each_object() yields
> non-zero value, the returned value comes back as "err" here,
> terminating the for-each iteration immediately.
> 
> odb_source_for_each_object() is implemented differently per the
> source backend, but taking an example of "packfile" backend,
> packfile_loose_for_each_object() ends up calling cb (wrapped in
> packfile_store_for_each_object_wrapper_data) via
> for_each_object_in_pack(), which stops immediately when cb returns
> non-zero and the value returned from there is the value given by cb,
> i.e., 1.  So we will have err==1 when we find any object.
> 
> > +		if (err < 0)
> > +			return err;
> 
> And err presumably is 1 in such a case, so this does not trigger.
> 
> >  		/*
> >  		 * We have found an object that is not part of a promisor pack,
> >  		 * and thus we cannot skip the full connectivity check.
> >  		 */
> > -		return 0;
> > -
> > -promisor_pack_found:
> > -		;
> > +		if (err > 0)
> > +			return 0;
> 
> And this does.
> 
> I may be misreading the patch, but as we return 0 from here, do we
> cause the caller to fall back to full connectivity check?  The
> caller, check_connected(), sees a zero returned from here.

You're right, this is a result of the refactor. Previously we had it
like this:

    err = odb_for_each_object_ext(the_repository->objects,
                              NULL, promised_object_cb,
                              NULL, &opts);
    if (err < 0)
            break;
    if (err > 0) {
            err = 0;
            continue;
    }

But that made us correctly skip to the next object. Now though we have
to check for `if (!err) return 0;` in the refactored code. Makes me
wonder whether the logic would be easier to follow like this:

diff --git a/connected.c b/connected.c
index b557ff5db9..b5a9b0543d 100644
--- a/connected.c
+++ b/connected.c
@@ -13,8 +13,10 @@
 
 static int promised_object_cb(const struct object_id *oid UNUSED,
 			      struct object_info *oi UNUSED,
-			      void *payload UNUSED)
+			      void *payload)
 {
+	bool *found = payload;
+	*found = true;
 	return 1;
 }
 
@@ -45,11 +47,13 @@ static int check_connected_promisor(oid_iterate_fn fn,
 
 	odb_reprepare(the_repository->objects);
 	do {
+		bool found = false;
+
 		opts.prefix = *oid;
 
 		err = odb_for_each_object_ext(the_repository->objects,
 					      NULL, promised_object_cb,
-					      NULL, &opts);
+					      &found, &opts);
 		if (err < 0)
 			return err;
 
@@ -57,7 +61,7 @@ static int check_connected_promisor(oid_iterate_fn fn,
 		 * We have found an object that is not part of a promisor pack,
 		 * and thus we cannot skip the full connectivity check.
 		 */
-		if (err > 0)
+		if (!found)
 			return 0;
 	} while ((*oid = fn(cb_data)) != NULL);
 

It's also a bit concerning that this doesn't cause any tests to fail.
I'll try to figure out whether I can add one.

Thanks!

Patrick

  reply	other threads:[~2026-06-25  5:54 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-22  8:49 [PATCH 0/3] connected: search promisor objects generically Patrick Steinhardt
2026-06-22  8:49 ` [PATCH 1/3] odb/source-packed: extract logic to skip certain packs Patrick Steinhardt
2026-06-22 17:51   ` Junio C Hamano
2026-06-22  8:49 ` [PATCH 2/3] odb/source-packed: support flags when iterating an object prefix Patrick Steinhardt
2026-06-22  8:49 ` [PATCH 3/3] connected: search promisor objects generically Patrick Steinhardt
2026-06-22 17:57   ` Junio C Hamano
2026-06-24  9:33     ` Patrick Steinhardt
2026-06-23  7:45   ` Christian Couder
2026-06-24  9:33     ` Patrick Steinhardt
2026-06-24 10:37 ` [PATCH v2 0/4] " Patrick Steinhardt
2026-06-24 10:37   ` [PATCH v2 1/4] odb/source-packed: extract logic to skip certain packs Patrick Steinhardt
2026-06-24 10:37   ` [PATCH v2 2/4] odb/source-packed: support flags when iterating an object prefix Patrick Steinhardt
2026-06-24 17:02     ` Christian Couder
2026-06-25  5:52       ` Patrick Steinhardt
2026-06-24 10:37   ` [PATCH v2 3/4] connected: split out promisor-based connectivity check Patrick Steinhardt
2026-06-24 10:37   ` [PATCH v2 4/4] connected: search promisor objects generically Patrick Steinhardt
2026-06-24 16:27     ` Junio C Hamano
2026-06-25  5:54       ` Patrick Steinhardt [this message]
2026-06-25  9:57 ` [PATCH v3 0/4] " Patrick Steinhardt
2026-06-25  9:57   ` [PATCH v3 1/4] odb/source-packed: extract logic to skip certain packs Patrick Steinhardt
2026-06-25  9:57   ` [PATCH v3 2/4] odb/source-packed: support flags when iterating an object prefix Patrick Steinhardt
2026-06-25  9:57   ` [PATCH v3 3/4] connected: split out promisor-based connectivity check Patrick Steinhardt
2026-06-25  9:57   ` [PATCH v3 4/4] connected: search promisor objects generically Patrick Steinhardt
2026-06-25 20:22     ` Junio C Hamano
2026-06-26  6:55       ` 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=ajzCjgLJ5pzBph2Z@pks.im \
    --to=ps@pks.im \
    --cc=chriscool@tuxfamily.org \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.