Git 3.0's SHA-256 default is a costly mistake, says Chacon
Scott Chacon says Git 3.0's SHA-256 default fixes a problem no repository has hit and breaks 40-character hashes everywhere. Git says no date is set.
4 min read

By the numbers
- to hash the 35GB Chromium tree, per Chacon's test
- 5 s
- to hash the 1.5GB Linux kernel tree
- 257 ms
- hex characters in a SHA-256 object name, up from 40
- 64
Scott Chacon says Git's plan to make SHA-256 the default hash for new repositories in version 3.0 will be a costly mistake. His argument, published on the GitButler blog on September 30, 2026, lands as the Git project itself says the switch will wait until the wider ecosystem is ready. The dispute matters because every tool that stores or parses a Git commit ID is affected by the answer.
Tech AI Wire covered the Git 3.0 plan in September. New repositories get SHA-256 object names, the reftable format and a main branch, and building Git will require Rust.
What Chacon argues
Git identifies every file, folder and commit by a hash, a fixed-length fingerprint computed from its contents. Git has used the SHA-1 algorithm for this since the beginning. SHA-1 is known to be weak. With enough effort, researchers can produce two different inputs with the same fingerprint, which is called a collision.
Chacon's case is that this weakness is theoretical for Git. No collision has been documented across billions of Git repositories, he writes, despite SHA-1's known mathematical flaws.
He then lists the cost. A SHA-256 repository breaks every existing SHA-1 hash. URLs, commit references in bug trackers and anything else that quotes a 40-character ID stop matching. Most Git library implementations, he says, lack full SHA-256 support.
His alternative is to verify integrity without changing the object names. Chacon reports that hashing an entire checked-out tree is fast. His tests took about 5 seconds for the 35GB Chromium tree of 2.1 million files, and 257 milliseconds for the 1.5GB Linux kernel. He proposes embedding SHA-256 checksums in signed objects alongside the SHA-1 names. A project could then verify with the stronger hash without splitting the ecosystem in two. He points to git-evtag, a tool from 2015, as prior art for the idea.
What the Git project says
Git's own breaking-changes document describes the plan Chacon is arguing against. Git 3.0 changes the default hash to SHA-256 for newly initialized repositories only. Existing SHA-1 repositories keep working, and the document says there is no plan to deprecate the SHA-1 object format.
The document also explains why the project wants the change. It calls SHA-1 cryptographically broken and lists the evidence.
| Milestone | Year |
|---|---|
| NIST deprecates SHA-1 | 2011 |
| SHAppening attack | 2015 |
| SHAttered collision | 2017 |
| Git picks SHA-256 as the successor | late 2018 |
| Birthday-near-collision attack | 2019 |
| Shambles attack | 2020 |
Two points in the document cut in Chacon's favor. The Git project says it will not make the change until libraries, hosting platforms and third-party applications show they are ready for SHA-256. And it sets no release date for Git 3.0. Earlier reports had put the release around the end of 2026; the document itself names no date.
How the transition is meant to work
Git's hash-function-transition design shows the project has thought about interoperability. The choice of SHA-256 dates to late 2018. The design lets each repository move on its own schedule. A SHA-256 repository keeps a translation table in both directions, so an object can be referred to by either hash during the transition.
Network operations are covered too. The design describes push and fetch between SHA-256 and SHA-1 servers, converting objects while packing them. Commits can carry two signatures, one in the existing gpgsig field and one in a new gpgsig-sha256 field. The work is split into five phases, ending with a full transition once enough repositories have moved. Two limits remain: shallow clones and alternates do not work between SHA-1 and SHA-256 repositories.
The visible difference is length. A SHA-1 object name is 40 hexadecimal characters. A SHA-256 name is 64.
What this means for developers
Nothing changes for you today. Git 3.0 has no release date, and existing repositories stay SHA-1 either way. The question is what to do before a new default arrives, whenever that is.
First, test your tooling against a SHA-256 repository now. Chacon's claim that most Git libraries lack full support is testable. Create a test repository in SHA-256 mode and run your CI scripts, deployment hooks and code-review integrations against it.
Second, audit anything that assumes a 40-character ID. Database columns, regular expressions and URL patterns that hard-code that length will truncate or reject 64-character names. Our September article made the same point. Chacon's post is a reminder that the breakage spreads to every stored link.
Third, weigh his alternative on its merits. If your concern is tamper detection rather than naming, signed checksums over the tree deliver it today without a format change. If you need SHA-256 object names, the transition design already supports a per-repository move with SHA-1 interoperability. You do not have to wait for 3.0.
Finally, watch the project's readiness test rather than the version number. The breaking-changes document ties the default switch to ecosystem readiness. That means forges and libraries, not the Git release calendar, decide when this happens.
Sources
- Git 3.0's upcoming SHA-256 default will be a costly mistake - GitButler Blog
- Breaking changes in Git 3.0 - git-scm.com
- Git hash function transition - git-scm.com (design document)
Related articles

npm trusted publishing can now move dist-tags over OIDC
npm trusted publishing can now add, move and remove dist-tags such as latest with short-lived OIDC tokens. It is off by default and needs npm 11.21.0.

Git 2.56.0 ships faster merge-base and smaller repacks
Git 2.56.0 cuts a Linux kernel merge-base walk from 167,441 steps to 3,887 and shrinks one test repository's pack by 71%. It shipped September 28.

Node.js 22.23.3 LTS fixes an HTTP/2 use-after-free bug
Node.js 22.23.3 LTS, out September 23, fixes an HTTP/2 use-after-free bug, adds SharedArrayBuffer support to Node-API and moves to OpenSSL 3.5.8.
The daily brief
Three to five stories a day, and what each one means for the people who build software. Free, no spam.