Git development
 help / color / mirror / Atom feed
From: Jeff King <peff@peff.net>
To: Junio C Hamano <gitster@pobox.com>
Cc: Igor Wiedler <iwiedler@gitlab.com>, git@vger.kernel.org, ps@pks.im
Subject: Re: [PATCH] connected: do not walk alternate refs in deepening fetches
Date: Thu, 15 Oct 2026 02:41:58 -0400	[thread overview]
Message-ID: <20261015064158.GA1979109@coredump.intra.peff.net> (raw)
In-Reply-To: <xmqqcxtcte5m.fsf@gitster.g>

On Wed, Oct 14, 2026 at 09:55:49AM -0700, Junio C Hamano wrote:

> > That only works because "--alternate-refs" comes after "--not".
> > cf1e7c0770 (fetch-pack: write shallow, then check connectivity,
> > 2018-07-02) drops "--not --all" for deepening fetches, since those
> > need to verify the whole chain up to the new shallow boundary rather
> > than stopping at refs we already had. For such fetches we therefore
> > run
> >
> >   git --shallow-file ... rev-list --objects --stdin --quiet --alternate-refs
> 
> Ouch!  Thanks for spotting the 8-year-old mistake.  It shows how
> rare the deepening fetches together with the use of alternate refs
> in real life?

Thanks for cc-ing me. I looked at Igor's v1 patch, and it's exactly the
solution I would have expected. It should have been written that way in
39b44ba771 (check_everything_connected: assume alternate ref tips are
valid, 2019-07-01), because the intent was "treat alternate ref tips
just like we treat our own existing ref tips". So wherever we use
"--all", we should use "--alternate-refs", and since --all was moved
into that non-deepening conditional, --alternate-refs should go there,
too.

BTW, if you are curious why 39b44ba771 made such an obvious mistake, it
is exactly because it predated that move! The original patch was written
in 2014 and used internally at GitHub. I rebased it forward to send to
the list in 2019, but I don't even think I got a textual conflict at all
(because the movement of "--not" and "--all" were a few lines away).

So it was a very subtle semantic conflict between the two patches. But
because the rebase rewrote history to put mine on top, it looks like I
just did it wrong from the start. ;)

> But stepping back a bit, doesn't the same argument apply even when
> we are a fully populated repository and making a non-deepening
> fetch?  We can trust "--not --all" to make the traversal to stop at
> tips of our local refs and can be assured that all history behind
> the tips we are fetching will still be connected, but a traversal
> that stops at the tip of a shallow repository will break our
> repository, and in a worse form than the shallow repository we are
> borrowing from, because operations in that repository are guarded by
> its shallow boundaries that we usually do not see, but operations in
> our repository do not have the same shallow boundaries in effect.

It took me a few reads to parse this, but I think you are saying: it is
a problem if we are a non-shallow repository trying to use a shallow
alternate for verification?

That sounds likely, though this is the first time I have looked at
cf1e7c0770 (fetch-pack: write shallow, then check connectivity,
2018-07-02) and the surrounding issues. As I understand the issue, it is
really "are the refs we are going to use to verify coming from a shallow
repo which might not have all objects". But I'm not sure how that
interacts with opt->is_deepening_fetch (and why it isn't just checking
if we are in a shallow repo).

> I do agree that for the purpose of "see if this traversal barfs with
> missing objects to see if the updated tips have all the objects
> behind it", listing the alternate refs behind "--not" is the right
> thing to do and it is broken to have "--alternate-refs" without
> having "--not" like the current code does.  But I am not convinced
> that disabling --alternate-refs only when you are deepening is not
> solving the problems of using alternate-refs introduces.  Shouldn't
> the fix be more like two (or more) steps, i.e.,
> 
>  * [1/2] for check_connected(), use the attached patch instead.

OK, so this moves the "--not" out so that we always do it. It's ignored
in the case that we are deepening and don't have any alternates, but it
shouldn't hurt anything.

>  * [2/2] update odb_for_each_alternate_ref() so that it ignores any
>    and all refs from shallow repositories.

Yeah, this seems reasonable. Alternates don't necessarily even have a
full repo, but in that case they wouldn't have any refs, either (IIRC we
do some magic to guess at the containing repo of the alternate).

-Peff

  reply	other threads:[~2026-10-15  6:42 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-14 10:35 [PATCH] connected: do not walk alternate refs in deepening fetches Igor Wiedler
2026-10-14 12:25 ` Patrick Steinhardt
2026-10-14 16:55 ` Junio C Hamano
2026-10-15  6:41   ` Jeff King [this message]
2026-10-14 17:02 ` Justin Tobler
2026-10-14 18:11 ` [PATCH v2 0/2] connected: fix the connectivity check with alternates " Igor Wiedler
2026-10-14 19:23   ` Junio C Hamano
2026-10-14 18:11 ` [PATCH v2 1/2] connected: negate alternate refs in deepening fetches too Igor Wiedler
2026-10-14 18:11 ` [PATCH v2 2/2] odb: ignore refs of shallow and grafted alternates Igor Wiedler
2026-10-15  6:57   ` Jeff King

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=20261015064158.GA1979109@coredump.intra.peff.net \
    --to=peff@peff.net \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=iwiedler@gitlab.com \
    --cc=ps@pks.im \
    /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