<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/git-3-0-s-upcoming-sha-256-default-will-be-a-costly-mistake-7bvdmnnws" -->

---
title: Git 3.0&#x27;s upcoming SHA-256 default will be a costly mistake
description: Git co-founder Scott Chacon argues that Git 3.0&#x27;s plan to make SHA-256 the default content hashing algorithm, replacing SHA-1, will be an enormously costly...
canonical: https://daily.dev/posts/git-3-0-s-upcoming-sha-256-default-will-be-a-costly-mistake-7bvdmnnws
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Git 3.0&#x27;s upcoming SHA-256 default will be a costly mistake | daily.dev
og:description: Git co-founder Scott Chacon argues that Git 3.0&#x27;s plan to make SHA-256 the default content hashing algorithm, replacing SHA-1, will be an enormously costly...
og:url: https://daily.dev/posts/git-3-0-s-upcoming-sha-256-default-will-be-a-costly-mistake-7bvdmnnws
og:image: https://api.daily.dev/og/posts/7bvdmnnws.png
og:image:alt: Git 3.0&#x27;s upcoming SHA-256 default will be a costly mistake
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Git 3.0's upcoming SHA-256 default will be a costly mistake

**[GitButler Blog](https://daily.dev/sources/gitbutler)** · 20 min read · 40 upvotes · 10 comments

## Summary

Git co-founder Scott Chacon argues that Git 3.0's plan to make SHA-256 the default content hashing algorithm, replacing SHA-1, will be an enormously costly migration for negligible real-world security benefit. He explains that SHA-1's known weaknesses enable theoretical collision attacks but not practical second-preimage attacks, and that Git's actual trust model has always rested on where you pull code from (e.g., GitHub authentication) rather than on hash strength. He details the practical fallout of the SHA-256 default: incompatible repositories, broken submodules, broken signatures, broken URLs, and tooling that assumes 40-character hashes. As an alternative, he proposes adding an independently computed SHA-256 (or BLAKE3) hash as a signed header on commits/tags for content verification, similar to Colin Walters' git-evtag, without migrating the entire object format, and backs this with benchmark numbers (e.g., checksumming Chromium's 35GB tree in 5 seconds).

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://blog.gitbutler.com/git-3-sha-256>

## Questions this post answers

### What breaking change is Git 3.0 making to the default object hash algorithm?

Git 3.0 will make SHA-256 the default content hashing algorithm for new repositories created with git init, replacing SHA-1. Existing SHA-1 and new SHA-256 repositories are incompatible: they cannot be pushed to hosts expecting the other format, submodules can't mix formats, and converting an existing project to SHA-256 breaks all existing signatures and SHA-1-based URLs.

_Developers tracking Git's object-format migration can follow breaking changes like this one on daily.dev before upgrading tooling._

### Why is SHA-1 considered broken even though Git has never seen an accidental hash collision?

SHA-1 is called broken because published collision attacks (SHAttered in 2017, SHA-1 is a Shambles in 2020) show it is possible to deliberately craft two files with the same hash using GPU compute costing tens of thousands of dollars, not because accidental collisions occur. Accidental collisions remain practically impossible, requiring around 1.4 septillion random files per project to hit the SHA-1 birthday bound.

_Anyone weighing real versus theoretical crypto risk in their stack can dig into threat breakdowns like this on daily.dev._

### How can you add SHA-256 content verification to Git without migrating the whole object hash format?

Independently compute a SHA-256 (or BLAKE3) hash of all tree contents at signing time and inject it as a new header into the commit or tag object before signing, so the signature covers both the SHA-1-based content and the independently calculated hash. Colin Walters' git-evtag has done this since 2015; a proof-of-concept checksummed Chromium's 35GB, 2.1M-file tree in 5 seconds, showing the approach scales without bifurcating the Git ecosystem.

_Teams deciding how to harden commit signing without a full migration can compare approaches like this on daily.dev._

## Community take

How the wider developer community reacted, aggregated from 2 discussions and 390 comments across lobsters, hackernews (as of 2026-10-02).

**TL;DR:** Reaction is split: many find the migration pain (broken hashes, submodules, signatures, Slack/doc links) real and avoidable, but a vocal contingent argues the author understates SHA-1's practical break risk and conflates content hashing with trust/signing, while others see defaults-only change as low-cost and inevitable.

**Sentiment:** 10% positive · 35% mixed · 55% skeptical

**The case for**

- Several argue SHA-1's weaknesses are increasingly practical and will only get cheaper to exploit over time, so moving now is prudent.
- Some note GPG commit signatures ultimately rely on the underlying hash, so hash strength does matter for security, not just distribution trust.
- A few see this as analogous to past painful-but-successful migrations (Python 2→3, SCM changes) that the ecosystem survived.

**The pushback**

- Many warn the migration will break commit-hash references scattered across commit messages, docs, Slack, emails, and GitHub links that can't easily be rewritten.
- Tooling assuming 40-character SHA-1 hashes (submodules, Yocto, Nix, repo, gclient) will break broadly, creating years of workaround work.
- Several argue defaults matter enormously and most users adopting the new default will be unaware of the tradeoffs they're inheriting.
- Some dispute that collision attacks are irrelevant, citing SHAttered as a practical proof of concept already achieved.
- Mixing SHA-1 and SHA-256 objects in one tree is argued to be fundamentally unsafe since overall strength equals the weakest hash present.

**By community**

- lobsters (mixed): Discussion drifts between appreciating the practical breakage concerns and debating whether hash-based deduplication is inherently a security mechanism.
- hackernews (heated): Intense back-and-forth including direct exchanges with the author, split between those who think the security concerns are overstated FUD and those who find the migration genuinely reckless and poorly justified.

**Hottest debate:** Whether Git's commit/content hashes are fundamentally a security mechanism (given signing depends on them) or merely an identification scheme whose trust comes from distribution channels.

**Open questions**

- How would SHA-1 and SHA-256 objects safely interoperate without weakening the overall tree's cryptographic strength?
- What happens to all the commit-hash references embedded in external text (docs, chat logs, emails) once repos migrate?
- Is there a credible, low-pain migration plan at all, given years of discussion haven't produced one?

**Highlights**

> 1) I link to the SHAttered paper, as well as Shambles. Git projects were not affected because it is an inefficient attack vector. I say it's impractical to exploit, which I think everyone agrees with. 2) I specifically argue that even if both attacks were practical and cheap, it's still not the problem we should be focusing on. 3) Have you read this email (that I linked to)? It is almost the same general message (20 years ago) that this blog post is. It literally goes though a theoretical object replacement attack and how dumb this scenario is and so SHA-1 is fine. https://lore.kernel.org/git/Pine.LNX.4.58.0504291221250.1890...
> — [schacon on hackernews · 2 comments](https://news.ycombinator.com/item?id=49924843)

> The design of Git, as a Merkle tree, is meant to allow for use cases like this: * I host a mirror of the Linux git repo. * You download Linux from my mirror. * You check out a commit, say fd179f8a05be3ccae366b9b96e176b51fbe54aab, which you know is a genuine commit through some out-of-band mechanism (mailing list, GitHub web interface, a line in a Nix file, whatever). * You check whether the repository I gave you is legitimate or not by re-computing the hash of the commit which I claimed was fd179f8a05be3ccae366b9b96e176b51fbe54aab. If it comes out to be fd179f8a05be3ccae366b9b96e176b51fbe54aab, you know it's legitimate. If it doesn't, you know it's fake. This is a completely normal use of Git. People download from mirrors all the time. People rely on commit hashes to identify a specific source tree. People trust that if whatever the mirror gave them hashes to the right value, it's genuine. That way, you don't have to trust the mirror. If I can forge my own commits to have any hash I want, this whole model breaks down. I can replace some old commit in the repo with my own forged commit with the same hash, and when you download a copy of the Linux repo from my mirror, you'll receive a repo with malicious content, but it'll hash to the same fd179f8a05be3ccae366b9b96e176b51fbe54aab hash as a genuine repo would. This breaks the security model of Git.
> — [mort96 on hackernews · 1 comments](https://news.ycombinator.com/item?id=49926435)

> No, my argument is that the change should not happen at all and nobody wants it and it gains the community very, very little but the default change is forcing it on everyone and most will be _entirely_ unaware - now having to solve problems that are difficult to understand. Defaults also matter when they are the wrong defaults.
> — [schacon on hackernews · 1 comments](https://news.ycombinator.com/item?id=49924641)

> I think that reasoning led to a svn repository being catastrophically corrupted by the shattered sha-1 collision. It’s a common fallacy that deduplication doesn’t depend on the security properties of cryptographic hash functions: if the system doesn’t have any extra machinery to handle a collision then a broken hash function will cause loss of data integrity and probably availability, two of the three legs of the CIA triad.
> — [fanf on lobsters · 1 points](https://lobste.rs/s/bytzgl/git_3_0_s_upcoming_sha_256_default_will_be#c_w1ol44)

> That is essentially only a second preimage problem, which is basically impossible.
> — [schacon on hackernews · 1 comments](https://news.ycombinator.com/item?id=49925345)

**Source threads**

- [lobsters](https://lobste.rs/s/bytzgl/git_3_0_s_upcoming_sha_256_default_will_be) · 25 points · 25 comments
- [hackernews](https://news.ycombinator.com/item?id=49924179) · 141 points · 365 comments

## Community discussion

Top comments from developers on daily.dev.

**@ristotoldsep** · 2 upvotes

> Submodules are fragile enough already. I’m not volunteering mine for this migration.

**@akkitto** · 2 upvotes

> I already use SHA-256 and cannot wait for it to be the default!

**@sam7work** · 2 upvotes

> yeah go for it, older hashes can be migrated no problem, otherwise who the hell still uses hashes to lock in a certain commit, we have tags for that , if the commit is that important that you want to reference it , put a tag on it

**@ytachy** · 1 upvotes

> The blog analyzes very well. From primitive terms like "broken" and "collision"...etc to the main point!
>
> Very impressed!

**@nark3d** · 0 upvotes

> Chacon has a point about cost, but the alternative has the same gap.  Who checks the independent hash?  A header computed by the same process that builds the commit only moves the trust from the object format to whatever signed it, and if that key lives on the same machine, an attacker who can rewrite history can rewrite the header too.  Chacon's own trust model says we already rely on where the code came from, so an extra hash on top is only worth anything once you say what it's anchored to that the attacker doesn't control.  Otherwise you've added a field to every commit and kept the same...

## Similar posts on daily.dev

- [Evolving Git for the next decade](https://daily.dev/posts/evolving-git-for-the-next-decade-hysn9z0fm) · Lobsters · 1 upvotes · 0 comments
- [Git 2.52-rc0 Starts Working On SHA1-SHA256 Interop, Hints For New Default Branch Name](https://daily.dev/posts/git-2-52-rc0-starts-working-on-sha1-sha256-interop-hints-for-new-default-branch-name-dsftnptfz) · Phoronix · 0 upvotes · 0 comments
- [Git 3.0 Migration Guide: Transitioning to SHA-256 & Reftables](https://daily.dev/posts/git-3-0-migration-guide-transitioning-to-sha-256-reftables-df76xg60l) · SitePoint · 0 upvotes · 0 comments
- [Git 3.0 will use main as the default branch](https://daily.dev/posts/git-3-0-will-use-main-as-the-default-branch-rgi9wcvpe) · thoughbot · 469 upvotes · 156 comments
- [Looking forward to Git 2.56 - and 3.0](https://daily.dev/posts/looking-forward-to-git-2-56---and-3-0-h3in0tamj) · Lobsters · 3 upvotes · 2 comments

---

Tags: [#security](https://daily.dev/tags/security), [#git](https://daily.dev/tags/git), [#version-control](https://daily.dev/tags/version-control)

[View this post on daily.dev](https://daily.dev/posts/git-3-0-s-upcoming-sha-256-default-will-be-a-costly-mistake-7bvdmnnws)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Git 3.0's upcoming SHA-256 default will be a costly mistake","url":"https://daily.dev/posts/git-3-0-s-upcoming-sha-256-default-will-be-a-costly-mistake-7bvdmnnws","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/git-3-0-s-upcoming-sha-256-default-will-be-a-costly-mistake-7bvdmnnws"},"datePublished":"2026-10-01T13:56:39.396Z","dateModified":"2026-10-02T00:05:21.897Z","description":"Git co-founder Scott Chacon argues that Git 3.0's plan to make SHA-256 the default content hashing algorithm, replacing SHA-1, will be an enormously costly...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/a98ea39f67b1c3a47433515443307acf?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/a98ea39f67b1c3a47433515443307acf?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"GitButler Blog","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"GitButler Blog","logo":"https://media.daily.dev/image/upload/s--LrHsyt2T--/f_auto/v1692632054/squad_placeholder_sfwkmj","url":"https://daily.dev/sources/gitbutler"},"commentCount":10,"discussionUrl":"https://daily.dev/posts/git-3-0-s-upcoming-sha-256-default-will-be-a-costly-mistake-7bvdmnnws","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":40},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":10}],"keywords":"security,git,version-control","timeRequired":"PT20M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"GitButler Blog","item":"https://daily.dev/sources/gitbutler"},{"@type":"ListItem","position":3,"name":"Git 3.0's upcoming SHA-256 default will be a costly mistake"}]}
{"@context":"https://schema.org","@type":"WebPage","@id":"https://daily.dev/posts/git-3-0-s-upcoming-sha-256-default-will-be-a-costly-mistake-7bvdmnnws","comment":[{"@type":"Comment","text":"Submodules are fragile enough already. I’m not volunteering mine for this migration.","datePublished":"2026-10-02T11:40:30.713Z","url":"https://daily.dev/posts/7bvdmnnws#c-iIW43hbxd","author":{"@type":"Person","name":"Risto Tõldsep","url":"https://daily.dev/ristotoldsep","image":"https://lh3.googleusercontent.com/a/ACg8ocLDWc6mZn0JwNmXXw6WY0L_HJ6pegzRttooC5VgtXESHSj3MNYx=s96-c"},"interactionStatistic":{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":2}},{"@type":"Comment","text":"I already use SHA-256 and cannot wait for it to be the default!","datePublished":"2026-10-01T23:22:04.713Z","url":"https://daily.dev/posts/7bvdmnnws#c-OJOfrhsLv","author":{"@type":"Person","name":"Daniel","url":"https://daily.dev/akkitto","image":"https://media.daily.dev/image/upload/s--FtwJqX4c--/f_auto/v1754900041/avatars/avatar_29TCpY2hJR72V3BlxPXzX?_a=BAMClqZW0"},"interactionStatistic":{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":2}},{"@type":"Comment","text":"yeah go for it, older hashes can be migrated no problem, otherwise who the hell still uses hashes to lock in a certain commit, we have tags for that , if the commit is that important that you want to reference it , put a tag on it","datePublished":"2026-10-02T15:00:29.677Z","url":"https://daily.dev/posts/7bvdmnnws#c-VpyC0UuKj","author":{"@type":"Person","name":"Sam","url":"https://daily.dev/sam7work","image":"https://lh3.googleusercontent.com/a/ACg8ocJGz1oRsDNA5jHaL8S_Dm_S69r5oVuMT_253w26IC3wacnjq1U=s96-c"},"interactionStatistic":{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":2}},{"@type":"Comment","text":"The blog analyzes very well. From primitive terms like “broken” and “collision”…etc to the main point!\nVery impressed!","datePublished":"2026-10-02T06:13:57.693Z","url":"https://daily.dev/posts/7bvdmnnws#c-NrIQXg5fr","author":{"@type":"Person","name":"Devy","url":"https://daily.dev/ytachy","image":"https://avatars.githubusercontent.com/u/69612646?v=4"},"interactionStatistic":{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":1}},{"@type":"Comment","text":"Chacon has a point about cost, but the alternative has the same gap.  Who checks the independent hash?  A header computed by the same process that builds the commit only moves the trust from the object format to whatever signed it, and if that key lives on the same machine, an attacker who can rewrite history can rewrite the header too.  Chacon’s own trust model says we already rely on where the code came from, so an extra hash on top is only worth anything once you say what it’s anchored to that the attacker doesn’t control.  Otherwise you’ve added a field to every commit and kept the same guarantee.","datePublished":"2026-10-04T16:28:37.788Z","url":"https://daily.dev/posts/7bvdmnnws#c-JryR5e0nZ","author":{"@type":"Person","name":"Adam","url":"https://daily.dev/nark3d","image":"https://avatars.githubusercontent.com/u/2162621?v=4"}}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/git-3-0-s-upcoming-sha-256-default-will-be-a-costly-mistake-7bvdmnnws#faq","mainEntity":[{"@type":"Question","name":"What breaking change is Git 3.0 making to the default object hash algorithm?","acceptedAnswer":{"@type":"Answer","text":"Git 3.0 will make SHA-256 the default content hashing algorithm for new repositories created with git init, replacing SHA-1. Existing SHA-1 and new SHA-256 repositories are incompatible: they cannot be pushed to hosts expecting the other format, submodules can't mix formats, and converting an existing project to SHA-256 breaks all existing signatures and SHA-1-based URLs. Developers tracking Git's object-format migration can follow breaking changes like this one on daily.dev before upgrading tooling."}},{"@type":"Question","name":"Why is SHA-1 considered broken even though Git has never seen an accidental hash collision?","acceptedAnswer":{"@type":"Answer","text":"SHA-1 is called broken because published collision attacks (SHAttered in 2017, SHA-1 is a Shambles in 2020) show it is possible to deliberately craft two files with the same hash using GPU compute costing tens of thousands of dollars, not because accidental collisions occur. Accidental collisions remain practically impossible, requiring around 1.4 septillion random files per project to hit the SHA-1 birthday bound. Anyone weighing real versus theoretical crypto risk in their stack can dig into threat breakdowns like this on daily.dev."}},{"@type":"Question","name":"How can you add SHA-256 content verification to Git without migrating the whole object hash format?","acceptedAnswer":{"@type":"Answer","text":"Independently compute a SHA-256 (or BLAKE3) hash of all tree contents at signing time and inject it as a new header into the commit or tag object before signing, so the signature covers both the SHA-1-based content and the independently calculated hash. Colin Walters' git-evtag has done this since 2015; a proof-of-concept checksummed Chromium's 35GB, 2.1M-file tree in 5 seconds, showing the approach scales without bifurcating the Git ecosystem. Teams deciding how to harden commit signing without a full migration can compare approaches like this on daily.dev."}}]}
```

