Re: [PATCH] fetch: commit references fetched before backfilling tags
- From
Karthik Nayak <karthik.188@gmail.com>
- Date
- Oct 9, 2026, 22:16 UTC
- Message-ID
- <CAOLa=ZRML58095JPz1kzOyDTFwsdcoVx9jyxyf4gRppX1h8tVw@mail.gmail.com>
- In-Reply-To
- <askY2aq8--2I2lEN@denethor>
Justin Tobler <jltobler@gmail.com> writes:
Show 38 quoted lines
> On 26/10/09 01:26PM, Patrick Steinhardt wrote:
>> On Fri, Oct 09, 2026 at 12:10:37AM +0200, Karthik Nayak wrote:
>> > In 0e358de64a (fetch: use batched reference updates, 2025-05-19), the
>> > fetch code was modified to use batched updates to provide a good
>> > performance improvement. Wherein batched updates were used to fetch both
>> > references and backfill tags.
>> >
>> > When using batched updates, the references aren't yet committed to disk
>> > when we start backfilling tags. This means in situations such as shallow
>> > fetching the negotiation during backfilling tags, the client doesn't
>> > have any references to report in the 'have' section. Since backfilling
>> > doesn't use a depth limit, this can cause the server to send all the
>> > objects present in the repository.
>>
>> So in my own words: the server sends the reference, we queue them in a
>> transaction, but don't commit it yet. We then try to backfill tags, and
>> because we don't have the refs committed yet the backfill will think we
>> don't have any of the relevant commits that those tags point to.
>> Consequently, the packfile negotiation will result in way more objects
>> being fetched than necessary.
>>
>> This makes me wonder why we even do a proper fetch. In theory, we could
>> basically just ask the server for the individual tagged objects without
>> performing any negotiation, right?
>>
>> Or... well, would that work with nested annotated tags? No idea.
>
> IIUC, when we backfill tags, we only fetch tags that reference objects
> that we have locally. The server advertises the tag reference OID and
> its recursively peeled non-tag OID so the client can figure this out:
>
> efe1aaafb77990c4f023cec81b198e0af55bbfb5 refs/tags/foo
> c8dd1e3bb1152844983558802a52c9e4c17652b4 refs/tags/foo^{}
>
> So because there could be nested annontated tags, I think we would need
> to fetch to get the intermediate objects.
>
> -JustinYup exactly this. Afaik the protocol also works by transferring the set of objects that form the closure of between have <> want.
So for:
foo -> [tag A] -> [tag B] -> [commit C]
We cannot simply request for A without saying we have C. We have C and we know it, but the haves are obtained from the committed refs, so until refs are written to disk we never advertise C.