Surfaced by CodeRabbit on #46.
The clone/fetch serve path in api/repos.rs runs the full visibility_pack::withheld_blob_oids ref walk on every request before deciding whether any blob is actually withheld, then falls back to a plain upload_pack when the set comes back empty. For repos with no path-scoped rules (the common public case) that walk can never withhold anything, so it is pure overhead per clone.
This got more expensive with #42: blob_paths now walks every ref via git ls-tree -r rather than just heads/tags, so the wasted scan is broader. Short-circuit before spawning the walk when the rule set is empty or root-only (no rule with a non-"/" path glob), and only run withheld_blob_oids when a path-scoped rule exists.
Owning PR: #28/#33 (serve path); cost amplified by #42.
Surfaced by CodeRabbit on #46.
The clone/fetch serve path in
api/repos.rsruns the fullvisibility_pack::withheld_blob_oidsref walk on every request before deciding whether any blob is actually withheld, then falls back to a plainupload_packwhen the set comes back empty. For repos with no path-scoped rules (the common public case) that walk can never withhold anything, so it is pure overhead per clone.This got more expensive with #42:
blob_pathsnow walks every ref viagit ls-tree -rrather than just heads/tags, so the wasted scan is broader. Short-circuit before spawning the walk when the rule set is empty or root-only (no rule with a non-"/" path glob), and only runwithheld_blob_oidswhen a path-scoped rule exists.Owning PR: #28/#33 (serve path); cost amplified by #42.