You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Source of truth:etc/plan/sha256-support.md in this repository is authoritative. This issue body is a synchronized copy for tracking and discussion; if the issue and the file diverge, follow the file.
Warning
The document below is fully generated and wasn't vetted at all. So it still needs double-checking and common sense before picking any of this up.
SHA256 / Object-Hash Transition Plan
Source issue: GitoxideLabs/gitoxide#281
Imported on: 2026-04-22
Last reconciled: 2026-05-08
Working assumption: checkboxes in this file reflect current checkout, not only historical issue state.
Mission
Make object-hash kind first-class across config, protocol, storage, tests, and clone flow so SHA1 and SHA256 are both deliberate runtime choices instead of SHA1 being hidden fallback everywhere.
Constraints
Use current workspace as source of truth.
Treat old issue checkmarks as historical context only.
Prefer end-to-end correctness over isolated enum or parser support.
Keep scope on actual supported transition path, not abandoned pack-index-v3 speculation.
Reconciled Status
Remove hash-type specific methods from gix-hash and lean on gix_hash::Kind-parametric usage.
Evidence: gix-hash still contains new_sha1, new_sha256, from_20_bytes, from_32_bytes, null_sha1, null_sha256.
Remove len-20 assumptions from all relevant code paths.
Evidence: big progress exists, but 79 non-plan/non-changelog Kind::Sha1.null()/ObjectId::null(...Sha1) call sites still remain, plus a few explicit 20-byte comments and helpers.
Provide visible CLI path for choosing object hash kind.
Evidence: src/plumbing/options/mod.rs and src/plumbing/options/free.rs expose clap object_hash fields, which produce --object-hash.
Propagate sha256 feature support through crates that participate in object traversal, object parsing, and object-id storage.
Evidence: 31 workspace packages now define a sha256 feature, including gix-object, gix-index, gix-protocol, gix-ref, gix-refspec, gix-traverse, and top-level gix.
Make SHA256-only builds compile where supported by feature flags.
Evidence: cargo check -p gix --no-default-features --features sha256 fails because gix/src/config/cache/incubate.rs and gix/src/config/tree/sections/core.rs still name gix_hash::Kind::Sha1 unconditionally.
Remove default sha1 feature from gix-hash and deal with fallout.
Evidence: gix-hash has default = [], docs.rs explicitly enables sha1, root gitoxide chooses SHA1 via features, and justfile contains compile-guard checks for missing hash selection.
Remove SHA1 mention from gix-features feature toggles.
Evidence: gix-features/Cargo.toml has no SHA1/SHA256 feature toggles anymore.
Parameterize hash length when decoding non-blob objects.
Evidence: gix-object tree decoding hotspot uses hash_kind.len_in_bytes().
Add Sha256 enum variant and hasher support.
Evidence: gix_hash::Kind::Sha256, ObjectId::Sha256, and Hasher::Sha256 exist.
Add broad dual-hash test hooks for reading refs and objects of different lengths.
Evidence: justfile runs SHA256 fixture suites for gix-object, gix-ref-tests, gix-traverse-tests, and top-level gix.
Add write/read roundtrip coverage for different hash lengths, ideally with stronger repo-level verification.
Evidence: targeted tests exist, but no obvious repo-conversion or full transition verifier is present.
Handle remote object-hash mismatch during clone by configuring repository accordingly.
Evidence: gix/src/clone/fetch/mod.rs still has unimplemented!("configure repository to expect a different object hash as advertised by the server").
Deferred / Out Of Scope
Pack index v3 transition work stays deferred unless Git actually relies on it.
Rationale: issue itself already demoted this from active task to decision point.
Current Snapshot
Workspace signals on 2026-05-08:
gix-hash default hash feature: removed
compile-guard checks for missing hash selection in justfile: 8
crates/packages with explicit sha256 = ... feature declarations: 31
gix-traverse hash feature declarations: sha1 and sha256
Kind::Sha1.null()/ObjectId::null(...Sha1) occurrences outside this plan and changelogs: 79
object-format=sha1 fixture occurrences outside this plan: 10
object-format=sha256 fixture occurrences outside this plan: 0
clone path unimplemented!() for hash mismatch: 1
visible object-hash CLI fields: present in repo and no-repo plumbing options
cargo check -p gix --no-default-features --features sha256: fails on unconditional Kind::Sha1 references in gix
Dual-hash test hooks already exist in justfile for at least:
gix
gix-filter
gix-diff
gix-status-tests
gix-commitgraph
gix-object
gix-ref-tests
gix-pack
gix-diff-tests
gix-traverse-tests
gix-blame
gix-refspec
gix-worktree-stream
gix-hash
Confirmed Done
gix-commitgraph
Evidence: issue marked it complete, dev-dependencies enable gix-hash with sha1 and sha256, and justfile runs it with GIX_TEST_FIXTURE_HASH=sha1 and sha256.
gix-traverse feature declaration
Evidence: gix-traverse/Cargo.toml now defines both sha1 and sha256.
extensions.objectFormat=sha256 parsing
Evidence: gix/src/config/tree/sections/extensions.rs accepts sha256 behind the feature, and gix/tests/gix/config/tree.rs covers lowercase and uppercase SHA256.
Remaining Hotspots
gix/src/config/cache/incubate.rs
Repository object hash still falls back to SHA1 when config does not say otherwise, and the unconditional Kind::Sha1 references break SHA256-only gix builds.
gix/src/config/tree/sections/core.rs core.abbrev validation still passes Kind::Sha1 unconditionally for a context that may compile without SHA1.
gix-protocol/src/fetch/refmap/init.rs object-format capability parsing still rejects anything except sha1.
gix/src/clone/fetch/mod.rs
Clone still aborts on remote hash mismatch instead of configuring repo state.
gix/Cargo.toml
Top-level sha256 currently forwards to gix-hash, gix-pack, and optional gix-worktree-stream, but not to all direct dependencies that define their own hash features; confirm whether this is intentional feature unification or an under-forwarding gap.
gix-worktree-stream/Cargo.toml
Its sha256 feature forwards only gix-hash/sha256. This may be acceptable because dependencies currently avoid SHA-specific cfgs, but it should be verified against feature-isolated builds.
Execution Order
Batch 1: hash API, features, and explicit selection
gix-hash
Remove remaining SHA1/SHA256-shaped helper APIs where Kind-based forms can replace them.
feature propagation
Add and forward sha256 features where crates already have hash-sensitive APIs or compile guards, including gix-traverse.
gitoxide CLI surface
Keep the clap-derived --object-hash selection on plumbing commands.
SHA256-only compile
Replace unconditional Kind::Sha1 fallbacks in gix config/cache paths with feature-aware defaults or required configuration.
gix-refspec
Keep object-hash-looking refspec parsing honest under SHA256-heavy inputs.
Batch 2: config and object parsing
gix
Teach extensions.objectFormat config parsing to accept sha256.
gix
Decide the correct default/fallback behavior when no extensions.objectFormat exists and SHA1 is not compiled in.
gix-object
Keep object parsers hash-length aware and extend tests around non-SHA1 trees and related decode paths.
gix-ref
Expand refs and reflog read/write coverage to both hash lengths.
gix-index
Extend checksum and extension tests to SHA256-sized object ids.
gix-traverse
Add sha256 feature support and a SHA256 fixture run in justfile.
Batch 3: protocol and transport
gix-transport
Add negotiation fixtures that advertise object-format=sha256.
gix-protocol
Accept and preserve SHA256 object-format negotiation end to end.
Batch 4: storage layer
gix-odb
Strengthen loose/packed lookup and prefix behavior under SHA256.
gix-pack
Finish pack data, index, multi-index, and verification assumptions that still lean on SHA1-shaped fixtures or sentinels.
Batch 5: porcelain behavior and sentinel cleanup
gix
Replace clone hash-mismatch unimplemented!() with real repo initialization/configuration.
gix-diff
Remove SHA1-only sentinel assumptions where caller hash kind should drive impossible ids.
gix-blame
Same sentinel cleanup where SHA1 null ids are only placeholders.
gix-traverse
Replace remaining SHA1 defaults in traversal state with caller/repository hash kind where traversal starts from generic object ids.
broad repo sweep
Review remaining Kind::Sha1.null() occurrences one by one and separate acceptable sentinels from real SHA1 assumptions.
Batch 6: acceptance coverage
dual-hash refs/object read suite
dual-hash write/read suite
repo-level transition or conversion verification
CI gating for SHA1 and SHA256 critical paths
Immediate Next Moves
Fix SHA256-only gix compilation by removing unconditional Kind::Sha1 references from config/cache code paths.
Make fetch negotiation accept object-format=sha256.
Remove clone-time unimplemented!() for remote hash mismatch.
Turn current scattered dual-hash tests into named acceptance criteria.
Exit Criteria
SHA256 repository format parses through config without immediate rejection.
SHA256-only top-level gix build compiles when requested by features.
protocol negotiation can roundtrip object-format=sha256.
clone/fetch can initialize repo state for non-SHA1 remotes without panicking or aborting.
no important code path relies on implicit SHA1-only object-id shape.
CI and local test entrypoints exercise both SHA1 and SHA256 where behavior differs.
Source of truth:
etc/plan/sha256-support.mdin this repository is authoritative. This issue body is a synchronized copy for tracking and discussion; if the issue and the file diverge, follow the file.Warning
The document below is fully generated and wasn't vetted at all. So it still needs double-checking and common sense before picking any of this up.
SHA256 / Object-Hash Transition Plan
Source issue: GitoxideLabs/gitoxide#281
Imported on: 2026-04-22
Last reconciled: 2026-05-08
Working assumption: checkboxes in this file reflect current checkout, not only historical issue state.
Mission
Make object-hash kind first-class across config, protocol, storage, tests, and clone flow so SHA1 and SHA256 are both deliberate runtime choices instead of SHA1 being hidden fallback everywhere.
Constraints
Reconciled Status
gix-hashand lean ongix_hash::Kind-parametric usage.Evidence:
gix-hashstill containsnew_sha1,new_sha256,from_20_bytes,from_32_bytes,null_sha1,null_sha256.Evidence: big progress exists, but 79 non-plan/non-changelog
Kind::Sha1.null()/ObjectId::null(...Sha1)call sites still remain, plus a few explicit 20-byte comments and helpers.Evidence:
src/plumbing/options/mod.rsandsrc/plumbing/options/free.rsexpose clapobject_hashfields, which produce--object-hash.sha256feature support through crates that participate in object traversal, object parsing, and object-id storage.Evidence: 31 workspace packages now define a
sha256feature, includinggix-object,gix-index,gix-protocol,gix-ref,gix-refspec,gix-traverse, and top-levelgix.Evidence:
cargo check -p gix --no-default-features --features sha256fails becausegix/src/config/cache/incubate.rsandgix/src/config/tree/sections/core.rsstill namegix_hash::Kind::Sha1unconditionally.sha1feature fromgix-hashand deal with fallout.Evidence:
gix-hashhasdefault = [], docs.rs explicitly enablessha1, rootgitoxidechooses SHA1 via features, andjustfilecontains compile-guard checks for missing hash selection.gix-featuresfeature toggles.Evidence:
gix-features/Cargo.tomlhas no SHA1/SHA256 feature toggles anymore.Evidence:
gix-objecttree decoding hotspot useshash_kind.len_in_bytes().Sha256enum variant and hasher support.Evidence:
gix_hash::Kind::Sha256,ObjectId::Sha256, andHasher::Sha256exist.Evidence:
justfileruns SHA256 fixture suites forgix-object,gix-ref-tests,gix-traverse-tests, and top-levelgix.Evidence: targeted tests exist, but no obvious repo-conversion or full transition verifier is present.
Evidence:
gix/src/clone/fetch/mod.rsstill hasunimplemented!("configure repository to expect a different object hash as advertised by the server").Deferred / Out Of Scope
Rationale: issue itself already demoted this from active task to decision point.
Current Snapshot
Workspace signals on 2026-05-08:
gix-hashdefault hash feature: removedjustfile: 8sha256 = ...feature declarations: 31gix-traversehash feature declarations:sha1andsha256Kind::Sha1.null()/ObjectId::null(...Sha1)occurrences outside this plan and changelogs: 79object-format=sha1fixture occurrences outside this plan: 10object-format=sha256fixture occurrences outside this plan: 0unimplemented!()for hash mismatch: 1cargo check -p gix --no-default-features --features sha256: fails on unconditionalKind::Sha1references ingixDual-hash test hooks already exist in
justfilefor at least:gixgix-filtergix-diffgix-status-testsgix-commitgraphgix-objectgix-ref-testsgix-packgix-diff-testsgix-traverse-testsgix-blamegix-refspecgix-worktree-streamgix-hashConfirmed Done
gix-commitgraphEvidence: issue marked it complete, dev-dependencies enable
gix-hashwithsha1andsha256, andjustfileruns it withGIX_TEST_FIXTURE_HASH=sha1andsha256.gix-traversefeature declarationEvidence:
gix-traverse/Cargo.tomlnow defines bothsha1andsha256.extensions.objectFormat=sha256parsingEvidence:
gix/src/config/tree/sections/extensions.rsacceptssha256behind the feature, andgix/tests/gix/config/tree.rscovers lowercase and uppercase SHA256.Remaining Hotspots
gix/src/config/cache/incubate.rsRepository object hash still falls back to SHA1 when config does not say otherwise, and the unconditional
Kind::Sha1references break SHA256-onlygixbuilds.gix/src/config/tree/sections/core.rscore.abbrevvalidation still passesKind::Sha1unconditionally for a context that may compile without SHA1.gix-protocol/src/fetch/refmap/init.rsobject-formatcapability parsing still rejects anything exceptsha1.gix/src/clone/fetch/mod.rsClone still aborts on remote hash mismatch instead of configuring repo state.
gix/Cargo.tomlTop-level
sha256currently forwards togix-hash,gix-pack, and optionalgix-worktree-stream, but not to all direct dependencies that define their own hash features; confirm whether this is intentional feature unification or an under-forwarding gap.gix-worktree-stream/Cargo.tomlIts
sha256feature forwards onlygix-hash/sha256. This may be acceptable because dependencies currently avoid SHA-specific cfgs, but it should be verified against feature-isolated builds.Execution Order
Batch 1: hash API, features, and explicit selection
gix-hashRemove remaining SHA1/SHA256-shaped helper APIs where
Kind-based forms can replace them.Add and forward
sha256features where crates already have hash-sensitive APIs or compile guards, includinggix-traverse.gitoxideCLI surfaceKeep the clap-derived
--object-hashselection on plumbing commands.Replace unconditional
Kind::Sha1fallbacks ingixconfig/cache paths with feature-aware defaults or required configuration.gix-refspecKeep object-hash-looking refspec parsing honest under SHA256-heavy inputs.
Batch 2: config and object parsing
gixTeach
extensions.objectFormatconfig parsing to acceptsha256.gixDecide the correct default/fallback behavior when no
extensions.objectFormatexists and SHA1 is not compiled in.gix-objectKeep object parsers hash-length aware and extend tests around non-SHA1 trees and related decode paths.
gix-refExpand refs and reflog read/write coverage to both hash lengths.
gix-indexExtend checksum and extension tests to SHA256-sized object ids.
gix-traverseAdd
sha256feature support and a SHA256 fixture run injustfile.Batch 3: protocol and transport
gix-transportAdd negotiation fixtures that advertise
object-format=sha256.gix-protocolAccept and preserve SHA256 object-format negotiation end to end.
Batch 4: storage layer
gix-odbStrengthen loose/packed lookup and prefix behavior under SHA256.
gix-packFinish pack data, index, multi-index, and verification assumptions that still lean on SHA1-shaped fixtures or sentinels.
Batch 5: porcelain behavior and sentinel cleanup
gixReplace clone hash-mismatch
unimplemented!()with real repo initialization/configuration.gix-diffRemove SHA1-only sentinel assumptions where caller hash kind should drive impossible ids.
gix-blameSame sentinel cleanup where SHA1 null ids are only placeholders.
gix-traverseReplace remaining SHA1 defaults in traversal state with caller/repository hash kind where traversal starts from generic object ids.
Review remaining
Kind::Sha1.null()occurrences one by one and separate acceptable sentinels from real SHA1 assumptions.Batch 6: acceptance coverage
Immediate Next Moves
gixcompilation by removing unconditionalKind::Sha1references from config/cache code paths.object-format=sha256.unimplemented!()for remote hash mismatch.Exit Criteria
gixbuild compiles when requested by features.object-format=sha256.