Byte by Mahmud logoByteby Mahmud
Git 3.0 Is Coming With SHA-256, a Rust Requirement — and One Very Angry GitHub Co-Founder
Technology6 min read13 views

Git 3.0 Is Coming With SHA-256, a Rust Requirement — and One Very Angry GitHub Co-Founder

Mahmud Hasan

Mahmud Hasan

October 2, 2026

Git 3.0 is quietly approaching, and when it lands it changes the defaults underneath every developer who types git init. The big one: new repositories will hash contents with SHA-256 instead of SHA-1. That sentence sounds boring. It started the loudest argument in the Git world in years — 500 points and 472 comments on Hacker News — and one of the loudest voices is GitHub co-founder Scott Chacon, who calls the switch "a costly mistake." He's worth listening to, and worth arguing with. Here's what's actually changing, why the fight matters, and five things to do before the release ships.

What Git 3.0 actually changes

Git's own BreakingChanges document is the authoritative list, and it's refreshingly blunt about what's coming. For repositories created after 3.0, five defaults flip:

  • SHA-256 becomes the default object hash (SHA-1 stays supported — "there is no plan to deprecate the sha1 object format at this point in time").
  • Reftable replaces files as the default ref storage — correct on case-insensitive filesystems, and far faster for repos with many references.
  • main becomes the default branch name, finally matching the big forges.
  • safe.bareRepository flips from all to explicit — a real security fix. Today Git can discover an attacker-planted bare repo inside a directory tree and fire its malicious hooks the moment your shell prompt runs git status in the background. The new default refuses implicit discovery.
  • Rust becomes a mandatory build dependency — the end of a ramp that started with auto-detection in 2.52 and default-enabled Rust in 2.55.

The old stuff goes too: grafts, git pack-redundant, git whatchanged, and legacy branch/remote directories are removed. There is no firm release date — maintainers are talking about the end of 2026, gated on ecosystem readiness: forges like GitHub, and libraries like JGit, libgit2, and Gitoxide. The signal to watch is the designated LTS, the last 2.x, which gets four cycles of bug fixes and six of security fixes. That's your migration window.

Why SHA-1 got a retirement notice

Git is a content-addressable database: every file, tree, and commit gets hashed, and the hash is the key. Commits encode the hash of the commit before them, so integrity propagates — hashing the tip commit effectively hashes everything behind it. SHA-1 is called "broken," but broken doesn't mean what most people think.

That's the attack SHA-1 is theoretically vulnerable to: SHAppening (2015), SHAttered (2017, two colliding PDFs), and Shambles (2020, chosen-prefix). Git ships countermeasures against the known attacks, but the maintainers' position is that more attacks are coming and it's only a matter of time before SHA-1 is considered fully broken. That's the honest case for the switch: NIST deprecation, FIPS compliance, and getting ahead of cheaper GPU attacks.

Why Chacon thinks it's a mistake anyway

His argument isn't that SHA-1 is fine forever — it's that hashing was never the trust mechanism. "I really think people should not consider the sha1 the 'security'. The real security is in distribution," as Linus Torvalds wrote in 2005. Trust is based on where you pull from. Nobody rents a GPU farm to brute-force a hash collision when they can socially-engineer write access to an unloved npm package used by millions of projects. Real supply-chain attacks are a billion times simpler than hash collisions — and don't care whether the hash is SHA-1 or SHA-256.

After 3.0, forges become two-bucket systems — SHA-1 repos and SHA-256 repos that cannot be mixed. Push a Git 3.0 repo to a server that doesn't speak SHA-256 and you get fatal: the receiving end does not support this repository's hash algorithm. Every developer will suddenly need to know which object format their local git defaults to and pick the matching server-side option — a setting most people have never heard of.

Tooling that assumes 40-hex-character hashes will break in subtle ways: Microsoft's VFSForGit just shipped a patch pinning git init --object-format=sha1 because its code hardcodes 20-byte hashes throughout. Multiply that friction by every team, every CI pipeline, every script, and you get Chacon's "costly global nightmare."

The counterpoint: the bridge already exists

The strongest rebuttal, raised repeatedly in the Hacker News thread, is that the transition machinery Chacon worries about has already been built. Git's hash-function-transition documentation describes a full interop design: pack index v3 files carry a bidirectional translation table between SHA-1 and SHA-256 names, so a SHA-256 repo can talk to a SHA-1 server with on-the-fly conversion during fetch. A transitioned repo carries both extensions.objectFormat = sha256 and extensions.compatObjectFormat = sha1. Signed commits get a new gpgsig-sha256 field so signatures don't depend on SHA-1 at all. Chacon himself concedes the key point: GitHub accepting SHA-256 pushes "will almost certainly be fixed by the time Git 3.0 is released" — and that readiness is the main thing currently delaying 3.0. The maintainers are gating the release on exactly the thing he says is missing.

So both things are true: the theoretical security benefit is thin (trust lives in distribution, and accidental collisions are mathematically negligible), and the practical train wreck may be smaller than feared, because the ecosystem gets veto power over the release date. The honest read is that this is a decades-long hygiene migration — FIPS compliance and future-proofing — priced in developer confusion. Whether the price is worth it depends on how much of the confusion actually materializes. Your job is to make sure none of it lands on you.

Five things to do before Git 3.0 ships

  1. Pin the object format in anything automated. Any script or CI job that runs bare git init will silently change behavior when runners upgrade. Be explicit now: git init --object-format=sha1 (or sha256, if you're feeling brave). Defaults you don't choose are the ones that bite you.
  2. Grep your tooling for 40-hex assumptions. Regexes like [0-9a-f]{40}, substring offsets, and "SHA-1 is 20 bytes" constants are the quiet breakage surface. SHA-256 hashes are 64 hex characters.
  3. Try a SHA-256 repo today. git init --object-format=sha256 /tmp/twofiddy works on any recent Git 2.x. See what your editor plugins, Git GUI, and deployment scripts do with it — and notice that pushing to GitHub currently fails, so you know exactly what the interop gap looks like.
  4. Check the other 3.0 defaults against your setup. Anything depending on the default branch being master, on discovering bare repos by directory-walking, or on grafts needs fixing now — those changes have no interop bridge at all.
  5. Watch the LTS. The last 2.x release, when declared, is the starting gun. Don't upgrade CI images past it casually.

The deeper lesson survives whichever side of the argument you land on. Chacon's core point — that security lives in where you pull from — is the most actionable sentence in the whole debate. Verify your remotes, pin your dependencies, sign your commits. The hash algorithm is the last mile of a trust chain that starts long before it.

References

Comments

Leave a comment

Your email stays private — only your name is shown.

More in Technology