deniz.in

Markets

Weather

Loading weather

· via dev.to (home feed)

Git 3.0's SHA-256 default threatens CI scripts built around 40-character hashes

Git 3.0 will make SHA-256 the default hash for new repositories, stretching commit IDs to 64 characters and breaking tooling that assumes 40. Git co-creator Scott Chacon calls the switch a costly mistake.

Git 3.0's SHA-256 default threatens CI scripts built around 40-character hashes

Git 3.0 will default new repositories to SHA-256

The next major version of Git will switch the default hash algorithm for newly created repositories from SHA-1 to SHA-256, turning the familiar 40-character commit identifier into a 64-character one. According to a dev.to analysis of the change, that mechanical detail is where most of the breakage will land: build pipelines, issue trackers and deployment scripts that silently assume how long a hash is.

The shift is not live yet. As of Git 2.55, the release current at the time of the dev.to write-up, SHA-1 remains the default, and the new behavior only applies when Git is built in the breaking-changes mode that will define version 3.0, which has no release date. Anyone can check what a build uses by running git init followed by git rev-parse --show-object-format.

The official BreakingChanges documentation scopes the change narrowly: it applies only to newly initialised repositories, existing SHA-1 repositories will not be converted, and there is currently no plan to retire the SHA-1 object format. The hash-function-transition design doc adds that a repository must be entirely one format or the other, and submodules have to match their parent's format.

The co-creator's objection

Scott Chacon, co-author of the Pro Git book and founder of both GitHub and GitButler, published a post this week arguing the switch will be a costly mistake. It climbed to third place on Hacker News with 549 points in under a day, according to the dev.to write-up.

Chacon does not claim SHA-1 is fine. The SHAttered attack demonstrated a collision in 2017, and the 2020 SHA-1 is a Shambles research pushed chosen-prefix collisions down to roughly 2^63 operations. His argument is that the weakness is impractical to exploit against Git: an attacker would need to manufacture two identically-hashing file variants and get victims to fetch the malicious one with no prior history. By his math, brute-forcing a meaningful collision would take billions of years of GPU time, chosen-prefix attacks on contrived content run into the tens of thousands of dollars, and simply buying out an exhausted maintainer for $40,000 is far cheaper and more likely to succeed.

The migration cost, in his view, lands on everyone instead. GitHub cannot currently host SHA-256 repositories, a gap HN commenters say is in private beta and that Chacon believes is probably the main thing delaying 3.0. Code forges will need format pickers, every script and pipeline that assumes a 40-character hash needs updating, and because Git is hard to embed as a library, much of the tooling ecosystem reimplements it from scratch with little SHA-256 support. Converting an existing project would also invalidate signatures and historical links embedding old hashes.

His alternative is to keep SHA-1 as a mere database key and add an independent, signed hash of the full tree as an extra header. His proof of concept checksummed the 1.5 GB Linux kernel tree in 257 ms and Git's own tree in 17 ms, and he argues this also addresses NIST's 2030 retirement of SHA-1 as a protective algorithm, since SHA-1 would no longer be protecting anything.

Why the Git project is switching anyway

The project's stated reasoning is a timeline, not a live incident. The documentation cites NIST's deprecation of SHA-1 and the existing chosen-prefix attacks, expects more attacks as hardware gets cheaper, and frames the move as preparation while there is still years of runway rather than a response to a break.

Chacon's alternative has a hole, though, and the dev.to write-up credits the HN thread with surfacing it: a second hash over tree contents verifies files but not history. Commit graphs are chains of hash references, so a forged lineage could still restructure what a commit claims to be built on. Chacon reportedly concedes his scheme covers objects carrying the header rather than every commit.

The official transition design is also gentler than the criticism implies. It defines a bidirectional mapping between SHA-1 and SHA-256 names, so old hashes in documentation, links and signatures stay resolvable, and converted repositories can interoperate with SHA-1 remotes. One HN tester found that SHA-1 submodules already work inside a SHA-256 parent on current Git.

Why it matters

The dev.to author's own anecdote sets the stakes: after helping migrate a legacy service from Bitbucket Server to GitHub, a post-mortem revealed half the team's CI scripts parsed commit hashes with a 40-character regex, and finding every instance took a full day. Once Git 3.0 ships, every git init will produce a repository that older tooling may choke on, so teams would be wise to audit their pipelines for fixed-length hash assumptions before the default flips. Beyond the breakage, the dispute is an unresolved argument about how the backbone of version control migrates its trust model: re-key every repository, or bolt stronger verification onto the keys it already has.

  • #git
  • #sha-256
  • #version-control
  • #ci-cd
  • #developer-tools

Related posts