Skip to content

checkpoint: accept case-folded shard directories in ParseRef - #2403

Open
KC1706 wants to merge 1 commit into
entireio:mainfrom
KC1706:fix/ulid-shard-case-collision
Open

checkpoint: accept case-folded shard directories in ParseRef#2403
KC1706 wants to merge 1 commit into
entireio:mainfrom
KC1706:fix/ulid-shard-case-collision

Conversation

@KC1706

@KC1706 KC1706 commented Sep 13, 2026

Copy link
Copy Markdown

Fixes #2402

On a case-insensitive-but-case-preserving filesystem (macOS APFS, Windows NTFS defaults), a checkpoint ref's shard directory can get case-folded by the filesystem itself — e.g. a ULID checkpoint whose correct shard is 6B lands inside an already-present 6b directory left by an unrelated legacy hex checkpoint. ParseRef compared the recomputed shard against the ref's actual path component byte-for-byte, so "6B" != "6b" caused a well-formed, intact checkpoint to be rejected as malformed and silently disappear from checkpoint list/explain.

This PR makes that comparison case-insensitive (strings.EqualFold), matching what the filesystem already does, and adds two regression tests reproducing both directions of the collision (ULID→lowercase dir, legacy-hex→uppercase dir).

Verified locally: mise run fmt && mise run lint (0 issues) and mise run test:ci pass.

On a case-insensitive-but-case-preserving filesystem (macOS APFS, Windows
NTFS defaults), git resolves a new checkpoint ref's shard directory against
existing ones case-insensitively. A ULID checkpoint's canonical shard is
uppercase (e.g. "6B"), so if an unrelated legacy hex checkpoint already
shards to the lowercase form ("6b"), the new ref lands inside that same
lowercase directory instead of a distinct one.

ParseRef then rejected such refs outright: it recomputed the ID's shard and
required an exact, case-sensitive match against the ref's actual path
component, so "6B" != "6b" caused a well-formed, intact checkpoint to be
treated as malformed and silently disappear from `entire checkpoint list`/
`explain`.

Fix: compare the shard case-insensitively (strings.EqualFold) instead of
exactly. Adds regression tests reproducing both directions of the collision.

Fixes entireio#2402
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant