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.
SHA256 / Object-Hash Transition Plan
Source issue: GitoxideLabs/gitoxide#281
Imported on: 2026-04-22
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 73 Kind::Sha1.null() call sites still remain, plus a few explicit 20-byte comments and helpers.
Provide visible CLI path for choosing object hash kind.
Evidence: current tree has 0 --object-hash matches.
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 31 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 general tests for reading refs and objects of different lengths.
Evidence: dual-hash coverage exists, but not yet as one clear acceptance layer.
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-04-22:
gix-hash default hash feature: removed
compile-guard checks for missing hash selection in justfile: 31
Kind::Sha1.null() occurrences: 73
object-format=sha1 fixture occurrences: 10
clone path unimplemented!() for hash mismatch: 1
--object-hash CLI flag matches: 0
Dual-hash test hooks already exist in justfile for at least:
gix-filter
gix-commitgraph
gix-object
gix-pack
gix-refspec
gix-hash
Confirmed Done
gix-commitgraph
Evidence: issue marked it complete, crate depends on gix-hash with sha1 and sha256, and justfile runs it with GIX_TEST_FIXTURE_HASH=sha1 and sha256.
Remaining Hotspots
gix/src/config/tree/sections/extensions.rs extensions.objectFormat still only accepts sha1 and explicitly says SHA256 is not fully implemented.
gix-protocol/src/fetch/refmap/init.rs object-format capability parsing still rejects anything except sha1.
gix/src/config/cache/incubate.rs
repository object hash still falls back to SHA1 when config does not say otherwise.
gix/src/clone/fetch/mod.rs
clone still aborts on remote hash mismatch instead of configuring repo state.
Execution Order
Batch 1: hash API and explicit selection
gix-hash
Remove remaining SHA1/SHA256-shaped helper APIs where Kind-based forms can replace them.
gitoxide CLI surface
Decide whether to restore a flag like --object-hash or bless config-only selection and document it clearly.
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-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.
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.
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
Decide whether --object-hash is still required as CLI UX, or whether config plus API is enough.
Make extensions.objectFormat=sha256 parse successfully.
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.
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.SHA256 / Object-Hash Transition Plan
Source issue: GitoxideLabs/gitoxide#281
Imported on: 2026-04-22
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 73
Kind::Sha1.null()call sites still remain, plus a few explicit 20-byte comments and helpers.Evidence: current tree has 0
--object-hashmatches.sha1feature fromgix-hashand deal with fallout.Evidence:
gix-hashhasdefault = [], docs.rs explicitly enablessha1, rootgitoxidechooses SHA1 via features, andjustfilecontains 31 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: dual-hash coverage exists, but not yet as one clear acceptance layer.
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-04-22:
gix-hashdefault hash feature: removedjustfile: 31Kind::Sha1.null()occurrences: 73object-format=sha1fixture occurrences: 10unimplemented!()for hash mismatch: 1--object-hashCLI flag matches: 0Dual-hash test hooks already exist in
justfilefor at least:gix-filtergix-commitgraphgix-objectgix-packgix-refspecgix-hashConfirmed Done
gix-commitgraphEvidence: issue marked it complete, crate depends on
gix-hashwithsha1andsha256, andjustfileruns it withGIX_TEST_FIXTURE_HASH=sha1andsha256.Remaining Hotspots
gix/src/config/tree/sections/extensions.rsextensions.objectFormatstill only acceptssha1and explicitly says SHA256 is not fully implemented.gix-protocol/src/fetch/refmap/init.rsobject-formatcapability parsing still rejects anything exceptsha1.gix/src/config/cache/incubate.rsrepository object hash still falls back to SHA1 when config does not say otherwise.
gix/src/clone/fetch/mod.rsclone still aborts on remote hash mismatch instead of configuring repo state.
Execution Order
Batch 1: hash API and explicit selection
gix-hashRemove remaining SHA1/SHA256-shaped helper APIs where
Kind-based forms can replace them.gitoxideCLI surfaceDecide whether to restore a flag like
--object-hashor bless config-only selection and document it clearly.gix-refspecKeep object-hash-looking refspec parsing honest under SHA256-heavy inputs.
Batch 2: config and object parsing
gixTeach
extensions.objectFormatconfig parsing to acceptsha256.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.
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.
Review remaining
Kind::Sha1.null()occurrences one by one and separate acceptable sentinels from real SHA1 assumptions.Batch 6: acceptance coverage
Immediate Next Moves
--object-hashis still required as CLI UX, or whether config plus API is enough.extensions.objectFormat=sha256parse successfully.object-format=sha256.unimplemented!()for remote hash mismatch.Exit Criteria
object-format=sha256.