The first Git 3.0 bug many teams meet could come from a validator, database column, or deployment script that assumes every object ID is 40 hexadecimal characters. Git's planned SHA-256 default gives new repositories 64-character object IDs, and the project's own transition checklist calls for removing hardcoded constants such as 20-byte hashes and 40-character strings. Git's transition document makes that cleanup part of the migration, not a cosmetic detail.
That mundane failure mode is getting attention because Scott Chacon, a GitHub co-founder and Pro Git author, argues that changing the default will split tools and hosts between two object formats. His case against the Git 3.0 change is forceful, but several parts of the plan are less final than the headline suggests. Git 3.0 has no release date, existing SHA-1 repositories are not scheduled for removal, and the Git project says the new default depends on libraries, applications, and forges being ready.
A new default does not rewrite old repositories
Git names blobs, trees, commits, and tags by hashing their contents. Those names connect the object graph that holds a repository's files and history. Git has used SHA-1 since its first release, which is why a full object ID normally looks like a 40-character string. In a SHA-256 repository, the same role belongs to a 64-character ID, and references inside commits and trees use the new format too. The official format design says the two representations differ for objects that refer to other objects, while blob contents remain the same.
Current Git already lets a developer create the newer format explicitly. The git init manual accepts --object-format=sha256, although SHA-1 remains the default today. Git 3.0 is expected to reverse that default for newly initialized repositories. It will not silently convert an existing repository, and the project's breaking-changes document says there is no plan to deprecate the SHA-1 object format at this point.
That boundary matters. A team with a ten-year-old repository will not wake up after a client upgrade to find every commit renamed. A developer creating a fresh repository with a Git 3.0 client may get SHA-256 unless a configuration or command-line option selects SHA-1. The project also plans to declare the last pre-3.0 release a long-term support version, according to the same Git 3.0 plan.
SHA-1 has a real cryptographic problem
The reason for moving is not an accidental collision between ordinary commits. Researchers have demonstrated practical collision and chosen-prefix attacks against SHA-1, including SHAttered in 2017 and Shambles in 2020. Git uses hardened collision detection against known attacks, but the Git project's rationale says future research and faster hardware could produce attacks those defenses do not catch. It chose SHA-256 as the successor in 2018.
NIST has set a separate clock. The agency plans to finish its transition away from SHA-1 for applying cryptographic protection by December 31, 2030. NIST's transition notice also says SHA-1 may still be needed afterward to handle information protected before that date. The wording is narrower than deleting every SHA-1 value from every system, but it gives regulated users a reason to stop building new trust mechanisms on the algorithm.
Chacon disputes whether changing Git's storage identity is the right fix. He argues that developers usually trust the forge and the repository owner, and that stealing a maintainer account is a cheaper path to malicious code than manufacturing a collision. He proposes signing an independent stronger tree hash while keeping SHA-1 as the storage key. That is an alternative design in his article, not the Git project's current plan, and it does not erase the project's concern that object IDs are also used to communicate and verify exact content.
The weak seam is outside the Git binary
A Git object ID rarely stays inside .git/objects. CI systems put it in environment variables. Deployment services use it as a release identifier. Databases attach build results to it, while issue trackers and chat messages turn it into a link. Chacon warns that conversions can invalidate old links and signatures if a host cannot preserve a mapping. Git's design answers with a bidirectional table that maps SHA-1 and SHA-256 names for the same object, but every surrounding tool still has to accept both forms.
The 40-character assumption can hide in a regular expression such as ^[0-9a-f]{40}$, a fixed database field, or code that slices a log line at byte 40. Short object IDs need care too. Git abbreviates an ID only as far as it stays unique inside a repository, so applications should not replace one fixed length with another. The current git rev-parse documentation can report the repository's storage format and translate output to SHA-1, SHA-256, or the storage format when the repository supports the requested representation.
A local smoke test needs only a recent Git build:
git init --object-format=sha256 oid-test
cd oid-test
printf 'test\n' > README.md
git add README.md
git commit -m 'test SHA-256 object IDs'
git rev-parse --show-object-format
git rev-parse HEAD
The output lets a team feed a 64-character ID through its parsers, database writes, web routes, CI variables, and release metadata. It does not prove that a hosted forge accepts the repository. In fact, the current git init manual still states that SHA-256 and SHA-1 repositories do not interoperate at present. Testing the data path is useful now. Moving a production remote is a separate decision.
Git has translation machinery, not a finished bridge
The core project has been laying groundwork for years. Git 2.29 added experimental SHA-256 repositories in 2020, and Git 2.42 removed the experimental label. Git 2.45 then added preliminary support for a compatibility object format, allowing some commands to calculate and address both SHA-1 and SHA-256 names. GitHub's Git 2.45 explanation shows one commit with a 64-character storage ID and a corresponding 40-character compatibility ID.
That progress should not be confused with complete network compatibility. The latest format design lists push and fetch translation as goals, while today's git init documentation still says repositories using different formats do not interoperate. The design also says older Git versions cannot read a SHA-256 repository. Its published caveats include shallow clones, unfetched submodules, alternates, Git notes, and the cost of translating objects on public servers.
The Git 3.0 plan has a release check for this exact gap. Before SHA-256 becomes the default, popular libraries, applications, and forges must support the format. That makes readiness a condition, though the breaking-changes page does not define a compatibility matrix or a launch date. Chacon's warning is useful here because a green check in core Git does not say whether an IDE's embedded library, a self-hosted forge, or an old build agent can follow.
Audit the assumption before choosing a side
Teams do not need to settle the cryptographic argument to remove brittle code. An object identifier should be stored as an algorithm plus a value, or at least in a field that can hold both 40- and 64-character forms. Parsers can ask Git for the active format with git rev-parse --show-object-format instead of inferring it from length. When a service exposes an object ID in a URL or API, its tests can exercise both formats and confirm that abbreviations remain repository-specific. Those steps follow the capabilities documented in git rev-parse without requiring a repository conversion.
Tool maintainers have a broader job. They need to test their Git library, network operations, signatures, submodules, shallow clones, and any cache keyed by an object ID. The official design calls out several of those incomplete paths, and it discourages SHA-256 storage on public-facing servers until protocol support is ready. That warning in the hash transition document is a strong reason to keep experiments isolated from production hosting.
The next evidence to watch is concrete: a Git 3.0 release date, a published readiness list for major libraries and forges, and current documentation that replaces the present no-interoperability warning. Until those appear, the sensible preparation is smaller. Make one 64-character test ID pass through your tooling now, so Git's eventual default change finds an ordinary compatibility test instead of a production system that thought every future commit would always fit in 40 characters.