pub struct UploadSummary {
pub protocol: ProtocolVersion,
pub ls_refs: usize,
pub fetch_rounds: usize,
pub objects_sent: u32,
pub objects_selected: usize,
pub common: usize,
pub objects_copied_from_pack: usize,
pub objects_recompressed: usize,
pub answered_from_bitmap: bool,
pub thin_bases_offered: usize,
pub thin_bases_vetoed: usize,
pub closure_bases_declined: usize,
}Expand description
What a whole upload-pack session did.
Returned rather than logged because the SSH layer wants it for metrics and
the interop tests want it as evidence: “the fetch succeeded” is true of a
server that negotiated properly and of one that shipped the entire
repository every time, and only fetch_rounds and objects_sent tell them
apart.
Fields§
§protocol: ProtocolVersionWhich protocol was spoken.
ls_refs: usizeHow many ls-refs commands were served.
fetch_rounds: usizeHow many negotiation rounds the client took, the one that carried the packfile included.
objects_sent: u32Objects in the packfile, if one was sent.
This is what the ENGINE emitted, not what this end chose. See
objects_selected for the other half; a
reader that has only this one cannot tell the two apart.
objects_selected: usizeObjects GitServe::select chose — the exact set emit_pack was
handed.
§Why both counts, and why this one is asserted rather than logged
emit_pack’s first parameter is an exact set and the engine must not
close it over reachability (DECIDED 2026-08-10). It may still emit
more than it was given, legitimately: an OFS_DELTA names its base by
a backwards distance inside the pack, so an engine copying stored
entries has to bring along any delta base that fell outside the
selection or emit something unparseable. Caps::thin is the allowance
to skip that, and an engine is free not to take it.
So the gap is expected and unbounded, which is precisely why it has
to be reported rather than assumed small. MEASURED on the laptop 2026-08-10,
the h2h-linear-sha1-2048c-1024f-16k corpus over the znippy engine, a
negotiated fetch from a receiver N commits behind the tip:
N commits behind selected sent amplification
1 18 157 8.72x
256 4382 7801 1.78xUntil this field existed the left-hand column reached exactly one place
— a human-readable sideband progress line that git fetch -q suppresses
and no meter parses — so bench/’s gunnar.vs_git_push could report a
33.6% divergence with nothing anywhere able to attribute it. That is the
failure a published number can hide: one describing a path other than the
one its name claims.
Zero for a session that sent no packfile. Summed over rounds in v2, for
the same reason objects_sent is.
common: usizeHow many haves turned out to be common on the final round.
objects_copied_from_pack: usizeOf objects_sent, how many left as a copy of
the pack entry they were already stored as.
Reported for the same reason fetch_rounds and objects_sent are: “the
clone succeeded” is true of a server that shipped the client’s own
deltas back and of one that inflated and re-deflated 528 MiB to send
18× the bytes, and nothing else on this struct tells them apart. A byte
count cannot either, since it moves with the corpus.
objects_recompressed: usizeOf objects_sent, how many had to be deflated
from their decompressed content: everything, on a store with no packs,
and on a packed one only the loose objects and the deltas whose base
did not come along.
answered_from_bitmap: boolWhether the packfile round’s object selection came from a .bitmap
rather than from the walk.
§Why this is on the summary and not only in a log line
Because the two paths do not produce identical bytes and every
measurement of this server is therefore a measurement of one of them.
The bitmap path vouches for the client’s whole closure
(ClientHas::Bits) where Exclusion::Edges’ walk vouches only for the
frontier, so a delta base the walk expands the bitmap names — same
request, same repository, fewer bytes. Nothing else a server reports
says which one answered, and the failure is silent in the direction that
matters: a repository with no .bitmap on disk falls through to the
walk and every number taken on it is a walk number wearing the
default’s name.
MEASURED 2026-08-04: the head-to-head fetch arm’s server fixture is
a git clone --bare carve, git clone writes no .bitmap, and so
gunnar.vs_git_fetch_divergent — the one arm gunnar loses on bytes —
had never once exercised the shipping path. false here is what says
so.
false for a session that sent no packfile, and for a request shape
[crate::bitmap::select] declines (a filter, a shallow boundary, a
deepening).
thin_bases_offered: usizeThin-delta bases gix offered over the session, and how many
client_has refused. See crate::pack::WriteOutcome::thin_bases_offered.
thin_bases_vetoed: usize§closure_bases_declined: usizeSee crate::pack::WriteOutcome::closure_bases_declined. Non-zero only
on a clone out of a multi-pack store whose selection reaches one
object by two routes, which is the shape no fixture in this tree had
until 2026-08-05.