feat(s3fs): implement lazy, range-based reads with read-ahead window
Replace eager GetObject+ReadAll buffering with lazy on-demand fetching.
Files now stream their bodies only when read, and ReadAt uses S3 Range
requests backed by a 1 MiB read-ahead window. This prevents whole-object
buffering in RAM (critical for large pack files since feat: keep pushed
packs whole) and reduces redundant HeadObject calls by deriving metadata
from the GetObject response.
Sequential Read opens a body at Open or on first read (depending on cache
hit); body streams on demand and reopens after Seek. ReadAt issues Range
requests; nearby offsets are served from the window without new S3 calls.
The redundant HeadObject is dropped from the main path; only Stat on a
never-read handle falls back to it (effectively unreachable in normal flow).
The public billy.File API is unchanged; this is a performance and memory
optimization. All three transport protocols (HTTP, git://, SSH) exercise
real pack/idx reads through go-git's FSObject and Scanner; the full test
suite passes.
See docs/plans/s3fs-lazy-read.md for the design.
Assisted-by: Claude Haiku 4.5 via claude.ai
Signed-off-by: Xe Iaso <me@xeiaso.net>