Thread (6 messages) 6 messages, 2 authors, 21h ago

Re: [PATCH 0/4] send-pack: introduce a `no-ref-delta` capability

From: Taylor Blau <hidden>
Date: 2026-07-18 21:02:44

On Sat, Jul 18, 2026 at 05:05:27AM -0400, Jeff King wrote:
On Tue, Jul 14, 2026 at 02:58:36PM -0700, Taylor Blau wrote:
quoted
quoted
So I have the feeling that there's some ulterior motive, or that this is
part of a larger system, but I don't quite understand what it is. And so
it's hard to say whether this is a sensible approach.
The implementation motivating this is write-through in the sense that it
first parses and spools the incoming pack, then replays those exact
bytes together with the same ref commands to an upstream receive-pack.
OK, that kind-of makes sense. But is that intermediate layer not
indexing at all? As in, it does not know which OIDs are present in the
incoming pack?
It does. The receive path computes object IDs while ingesting and
validating the incoming pack. The index I was referring to is the
durable index for the stored pack, not what we would compute in memory
during receipt of the incoming push. That durable index is built
asynchronously after the push is accepted.
It sounds like you _do_ index it based on this:
quoted
In retrospect, I don't think the cover letter distinguishes this well.
The pack that we receive over the wire is stored byte-for-byte as an
immutable artifact, and the per-object physical index is derived
asynchronously. That indexer is designed to operate in a single pass
forward over the pack.
So I can see how REF_DELTA makes a single streaming pass harder. But can
you actually do a single pass even with OFS_DELTA? You'll need to look
at earlier bytes in order to resolve each new object. And possibly
recursively. So you must maintain random access to the new pack data,
and you must maintain some kind of in-memory structure, at least for
each delta family (especially if you want to avoid re-generating deltas
over and over as you satisfy a long chain).
"Single pass" here means one forward read of the pack entries, with
random access to a disk-backed store of already-resolved objects. But...
I.e., I am having trouble understanding what makes REF_DELTA more
expensive than OFS_DELTA, either in terms of random-access to the pack
or in terms of indexing memory. It's more _complicated_ for sure,
though.
...by restricting objects to only be encoded as OFS_DELTA, we can always
load the base object knowing that it has already been processed. That
trivially permits you to avoid holding the entire pack in resident
memory, since you are able to look-up the right chunk(s) as needed.

If you have REF_DELTAs, the story is much more complicated. In that
case, you must be prepared to keep unresolved deltas around until the
base appears, which may be very far ahead in the pack. Alternatively,
you could build a map of pack positions by OID, but even in that case
you have to keep a pending work queue to be prepared for deltas whose
base object we have not yet seen.
That doesn't seem all _that_ compelling to me. I think the more
interesting thing is that in the worst case, a single REF_DELTA can kill
your pipeline entirely (assuming you are trying to do as much CPU-heavy
resolving work as possible while the pack is transferring). Imagine a
pack like this:

  0: REF_DELTA(abcd)
  1: OFS_DELTA(offsetof(0))
  2: OFS_DELTA(offsetof(1))
  3: OFS_DELTA(offsetof(2))
  ...
  N: base object with hash "abcd"

You can't resolve a single delta until you hit object N, after which you
must then resolve each of 0..N-1 sequentially because they all depend on
each other.

The problem there is not REF_DELTA itself, but the fact that REF_DELTA
allows you to place a base after the delta which depends on it.
Exactly.
If _that_ is your main concern, would it be worth a tighter capability
advertisement that insists that bases come before their deltas (if they
are in the pack at all)? We already generate packs that way by default,
and it would really just give the server a license to reject these
non-standard packs.
That would address the ordering problem, but is weaker than the format
restriction this receiver wants. Even a backward REF_DELTA requires an
OID-to-entry lookup, whereas the retained pack's reconstruction metadata
is addressed by offset alone. Supporting that is possible, of course,
but adds another way to locate a base.
But now I'm about 3 levels deep in guessing at your real issues, so I'll
stop for now and see how close I got. ;)
I think you got pretty close ;-).

Thanks,
Taylor
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help