git-internal v0.9.0
Release date: 2026-09-04 · Crate: git-internal 0.9.0 · Full changelog: CHANGELOG.md
git-internal 0.9.0 adds BLAKE3-256 object IDs as a git-internal / Libra extension, backed by an explicit-kind hash API and fully cross-verified pack/idx/protocol integrity. It also hardens pack decoding and smart-protocol negotiation to fail closed instead of silently falling back.
Important
This is a 0.x breaking minor release. New enum variants and fail-closed protocol changes require downstream code adjustments — see the Migration section below.
Highlights
BLAKE3-256 object IDs (git-internal / Libra extension)
HashKind::Blake3,ObjectHash::Blake3andHashAlgorithm::Blake3(32-byte / 64-hex digests) join SHA-1 and SHA-256. BLAKE3 is a separate object namespace: it is never inferred from an ID's width, only from an explicit repository kind or ablake3:HEXtagged ID.- Every layer supports it end-to-end: loose objects, trees/commits/tags/notes, pack encode/decode, idx v2,
.git/index, cache spill paths (kind-namespaced), and the smart protocol (object-format=blake3). - The AI
IntegrityHashremains SHA-256 regardless of the repository kind.
Explicit-kind ("context") API
New _for_kind / _with_kind APIs never read the thread-local HashKind and never infer an algorithm from length — they fail closed with diagnostic HashErrors instead:
- Hashing/parsing:
ObjectHash::{new_for_kind, from_type_and_data_for_kind, from_hex_for_kind, from_bytes_for_kind, from_stream_for_kind, zero_for_kind, ensure_kind, to_tagged_string, from_tagged_str},HashAlgorithm::new_for_kind. - Object model:
Blob::from_content_with_kind,Tree::from_tree_items_with_kind/rehash_with_kind,Commit::new_with_kind,Tag::new_with_kind,Note::new_with_kind,ObjectTrait::from_buf_read_with_kind, and more. - Pack / idx / index:
Pack::new_with_hash_kind,PackEncoder::new_with_hash_kind,encode_and_output_to_files_with_hash_kind,PackStats::analyze_with_hash_kind,pack_index::parse_idx_v2_from,Index::{from_file,to_file,load,save,refresh}_with_hash_kind. - Protocol:
RepositoryAccess::object_hash_kind(),SmartProtocol::ensure_hash_kind_consistency,PackGenerator::new_with_hash_kind.
Hardened pack / idx / protocol integrity
- Pack decoding now cross-verifies every object against an existing
.idx(streamed content hash, CRC over the encoded entry, real start offset), always rebuilds delta payloads, and treats a present-but-invalid.idxas an error instead of falling back to a scan. - The shared idx v2 reader validates fanout, strictly ascending names, unique offsets, large-offset slots and both checksums.
- Smart-protocol negotiation is fail-closed: an unknown or mismatching
object-formatis a hardProtocolError::InvalidRequest(no warn-and-ignore, no SHA-1 fallback), and the repository/local/wire kind invariant is re-checked at every await and side-effect boundary. - Upload-pack streams carry
Result<Vec<u8>, ProtocolError>items so producer failures are reported instead of surfacing as truncated packs.
Fixed
IdxBuildernow includes the pack checksum in the idx checksum (matching Git).- Encoder idx CRC32 values are computed over the encoded pack entry, not the decompressed content.
- Thin/malformed packs whose delta base never appears return an error instead of panicking.
Signatureformats negative half-hour time zones correctly.
Deprecated
ObjectHash::from_bytes_infer_kind— width inference can never distinguish SHA-256 from BLAKE3.
Migration (0.8.7 → 0.9.0)
- Exhaustive
matchexpressions overHashKind,ObjectHashorHashAlgorithmwill fail to compile until aBlake3arm is added (the enums are intentionally not#[non_exhaustive]). - Replace length inference with explicit kinds.
ObjectHash::from_strreturnsSha256for any 64-hex ID — including BLAKE3 — andfrom_bytes_infer_kinddoes the same for raw 32-byte digests. Parse IDs withfrom_hex_for_kind(repository_kind, …)at every boundary that may serve more than one repository. Where tagged IDs are accepted, followfrom_tagged_strwithensure_kind(repository_kind). - Implement
RepositoryAccess::object_hash_kind()for repositories whose format is known; the smart protocol binds to it at construction. - Handle
Erritems in upload-pack streams. - Single-repository flows using
set_hash_kindand the thread-local constructors (ObjectHash::new,from_bytes,Blob::from_content, …) keep working unchanged.
See docs/development/blake3-integration.md for the full downstream handoff contract, compatibility matrix, and acceptance checklist.
Compatibility
| SHA-1 | SHA-256 | BLAKE3 | |
|---|---|---|---|
| Standard Git | ✔ | ✔ | ✘ (extension) |
| In-place migration | — | — | not supported; create new repositories with core.objectformat=blake3 |
| Pack kind sniffing | — | — | impossible by design (32-byte width is shared); supply the kind explicitly |
AI IntegrityHash |
SHA-256 | SHA-256 | SHA-256 (unchanged) |
Known limitations
- The unified-diff writer does not emit
\ No newline at end of filemarkers, so a change touching only a file's terminal newline is not representable (tracked as FIX-05).
Verification
- Full test suite green: 361 passed (355 unit, 4 integration, 2 doc), 0 failures; 6 pre-existing ignores requiring large remote pack fixtures.
- 17 dedicated BLAKE3 tests cover official vectors, canonical object hashing, pack/idx round-trips, cross-kind rejection, protocol negotiation, cache-spill namespaces, and byte-identical legacy rkyv archives from 0.8.7.