fangorn/ex_git_objectstore
public
ref:81b6f84d5c73fe2f46b44fb2bae5f28d96a22e3e
fix(upload-pack): don't taint reachability with gitlink (mode 160000) SHAs
A v2 fetch on fangorn/hephaestus failed with
`did not receive expected object 36e9a223...`. Trace:
1. Tree d85a381c has a gitlink entry `{mode: "160000", name: "ecad-drc",
sha: 36e9a223...}`. By coincidence (or because the submodule URL
loops back at this repo), 36e9a223 is *also* a real commit in this
repo's history, reachable from every wanted branch tip.
2. collect_single_tree_entry dispatched the gitlink to the same head as
regular files (the function head matched on `%{sha: sha}` without
checking mode). That head did `MapSet.put(vis, sha)` before calling
read_blob_entry. The read returned %Commit{}, not %Blob{}, so the
entry produced no pack output — but the SHA was now in `vis`.
3. Walking parent_chain from a tip eventually reached abc92a55, whose
parent is 36e9a223. collect_reachable saw 36e9a223 in `visited` and
short-circuited (`{[], visited}`), never reading it, never recursing
into its parents, never emitting it into the pack.
4. Result: 1043 reachable objects omitted (121 commits + 562 trees +
360 blobs). Client's index-pack rejected the resulting pack.
Fix: give mode 160000 its own function head that returns `{acc, vis}`
unchanged. Submodule pointers never emit anything and never touch the
visited set.
Regression test builds a 3-commit chain where the middle commit's tree
has a gitlink whose SHA equals the root commit, and asserts all three
commits land in the pack.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
SHA:
81b6f84d5c73fe2f46b44fb2bae5f28d96a22e3e
Author:
CI <ci@anvil.test>
Date:
2026-05-14 03:32
Parents:
44a1729
2 files changed
+207
-0
| Type | ||
|---|---|---|
|
|
lib/ex_git_objectstore/protocol/upload_pack_v2.ex | +12 −0 |
|
||