checkpoint: resolve, write, and list case-folded shard refs
Commit
#2403 made ParseRef tolerate a checkpoint ref stored under the other
spelling of its shard directory, which fixes checkpoint list. Every
other consumer goes the other way β RefName(cid) then repo.Reference β
and there it was the filesystem masking the collision, not ParseRef: a
case-insensitive filesystem resolves the canonical name onto the folded
directory, but only while the ref is loose. git pack-refs (git gc --auto
runs it) moves the ref into packed-refs under its stored name, where
lookup is an exact string match.
resolveLocalRef falls back to the one alternate-cased spelling, which is
exhaustive rather than a heuristic: each ID format uses one case
exclusively, so a shard bucket has exactly two possible names. That fixes
Read (and so checkpoint explain <id>), refBase, and GetCheckpointAuthor.
writeRefName then targets the spelling an existing ref actually uses, so a write extends the checkpoint instead of forking it. A tolerant read on its own is not enough: refBase would find the old ref and hand back its tip while the CAS created a second ref at the canonical name β and the CAS could not succeed there anyway, since git resolves the expected old value under the name being updated.
List dedupes the two spellings for repos a pre-fix CLI already forked, preferring the canonical one so the listing agrees with what Read serves.
doctor reports both conditions. It offers no rename for a folded ref: on the filesystem that produces it, update-ref to the canonical name and update-ref -d on the folded one hit the same file while the refs are loose, so the pair that looks like a rename is a delete.
Refs #2402
Co-Authored-By: Claude Opus 5 (1M context) noreply@anthropic.com Entire-Checkpoint: 01M2JP7ZYMCG44RMG2RGZS7304