According to the man page for git-init for version 2.30.0, the sha-256 support is still considered experimental:
Actually, Git 2.42 (Q3 2023) tones down the warning on SHA-256 repositories being an experimental curiosity.
There is no support (yet) for them to interoperate with traditional SHA-1 repositories, but at this point, there is no plan to make breaking changes to SHA-256 repositories and there is no longer need for such a strongly phrased warning.
See commit 8e42eb0 (31 Jul 2023) by Adam Majer (AdamMajer
).
(Merged by Junio C Hamano -- gitster
-- in commit e48d9c7, 07 Aug 2023)
doc
: sha256 is no longer experimental
Signed-off-by: Adam Majer
Remove scary wording that basically stops people using sha256 repositories not because of interoperability issues with sha1 repositories, but from fear that their work will suddenly become incompatible in some future version of git.
We should be clear that currently sha256 repositories will not work with sha1 repositories but stop the scary words.
git
now includes in its man page:
is always used. The default is "sha1".
See --object-format
in git init
.
Git 2.43 (Q4 2023), adds more details about the SHA-256 hash: the "streaming" interface used for bulk-checkin codepath has been narrowed to take only blob objects for now, with no real loss of functionality.
See commit 9eb5419 (26 Sep 2023) by Eric W. Biederman (ebiederm
).
(Merged by Junio C Hamano -- gitster
-- in commit 3df51ea, 10 Oct 2023)
bulk-checkin
: only support blobs in index_bulk_checkin
Inspired-by: brian m. carlson
Signed-off-by: "Eric W. Biederman"
As the code is written today index_bulk_checkin
only accepts blobs.
Remove the enum object_type
parameter and rename index_bulk_checkin
to index_blob_bulk_checkin,
index_stream
to index_blob_stream,
deflate_to_pack
to deflate_blob_to_pack,
stream_to_pack
to stream_blob_to_pack,
to make this explicit.
Not supporting commits, tags, or trees has no downside as it is not currently supported now, and commits, tags, and trees being smaller by design do not have the problem that the problem that index_bulk_checkin
was built to solve.
Before we start adding code to support the hash function transition supporting additional objects types in index_bulk_checkin
has no real additional cost, just an extra function parameter to know what the object type is.
Once we begin the hash function transition this is not the case.
The hash function transition document specifies that a repository with compatObjectFormat
enabled will compute and store both the SHA-1 and SHA-256 hash of every object in the repository.
What makes this a challenge is that it is not just an additional hash over the same object.
Instead the hash function transition document specifies that the compatibility hash (specified with compatObjectFormat
) be computed over the equivalent object that another git repository whose storage hash (specified with objectFormat) would store.
When comparing equivalent repositories built with different storage hash functions, the oids embedded in objects used to refer to other objects differ and the location of signatures within objects differ.
As blob objects have neither oids referring to other objects nor stored signatures their storage hash and their compatibility hash are computed over the same object.
The other kinds of objects: trees, commits, and tags, all store oids referring to other objects.
Signatures are stored in commit and tag objects.
As oids and the tags to store signatures are not the same size in repositories built with different storage hashes the size of the equivalent objects are also different.
A version of index_bulk_checkin
that supports more than just blobs when computing both the SHA-1 and the SHA-256 of every object added would need a different, and more expensive structure.
The structure is more expensive because it would be required to temporarily buffering the equivalent object the compatibility hash needs to be computed over.
A temporary object is needed, because before a hash over an object can computed it's object header needs to be computed.
One of the members of the object header is the entire size of the object.
To know the size of an equivalent object an entire pass over the original object needs to be made, as trees, commits, and tags are composed of a variable number of variable sized pieces.
Unfortunately there is no formula to compute the size of an equivalent object from just the size of the original object.
Avoid all of those future complications by limiting index_bulk_checkin
to only work on blobs.
With Git 2.46 (Q3 2024), batch 15, it is confirmed: the future Git 3.0 will use SHA256!
See commit 028bb23, commit fcf0f48, commit 6ccf041, commit 57ec925 (14 Jun 2024) by Patrick Steinhardt (pks-t
).
(Merged by Junio C Hamano -- gitster
-- in commit 166cdd8, 20 Jun 2024)
BreakingChanges
: document upcoming change from "sha1" to "sha256"
Signed-off-by: Patrick Steinhardt
Starting with 8e42eb0 ("doc
: sha256 is no longer experimental", 2023-07-31, Git v2.42.0-rc1 -- merge), the "sha256" object format is no longer considered to be experimental.
Furthermore, the SHA-1 hash function is actively recommended against by for example NIST and FIPS 140-2, and attacks against it are becoming more practical both due to new weaknesses (SHAppening, SHAttered, Shambles) and due to the ever-increasing computing power.
It is only a matter of time before it can be considered to be broken completely.
Let's plan for this event by being active instead of waiting for it to happend and announce that the default object format is going to change from "sha1" to "sha256" with Git 3.0.
All major Git implementations (libgit2, JGit, go-git) support the "sha256" object format and are thus prepared for this change.
The most important missing piece in the puzzle is support in forges.
But while GitLab recently gained experimental support for the "sha256" object format though, to the best of my knowledge GitHub doesn't support it yet.
Ideally, announcing this upcoming change will encourage forges to start building that support.
BreakingChanges
now includes in its man page:
The default hash function for new repositories will be changed from "sha1" to "sha256".
SHA-1 has been deprecated by NIST in 2011 and is nowadays recommended against in FIPS 140-2 and similar certifications.
Furthermore, there are practical attacks on SHA-1 that weaken its cryptographic properties:
- The SHAppening (2015). The first demonstration of a practical attack
against SHA-1 with 2^57 operations.
- SHAttered (2017). Generation of two valid PDF files with 2^63 operations.
- Birthday-Near-Collision (2019). This attack allows for chosen prefix
attacks with 2^68 operations.
- Shambles (2020). This attack allows for chosen prefix attacks with 2^63
operations.
While we have protections in place against known attacks, it is expected
that more attacks against SHA-1 will be found by future research. Paired
with the ever-growing capability of hardware, it is only a matter of time
before SHA-1 will be considered broken completely. We want to be prepared
and will thus change the default hash algorithm to "sha256" for newly
initialized repositories.
An important requirement for this change is that the ecosystem is ready to
support the "sha256" object format. This includes popular Git libraries,
applications and forges.
There is no plan to deprecate the "sha1" object format at this point in time.
Cf. patches.
object-format-disclaimer
now includes in its man page:
Note: At present, there is no interoperability between SHA-256
repositories and SHA-1 repositories.
Historically, we warned that SHA-256 repositories may later need
backward incompatible changes when we introduce such interoperability
features. Today, we only expect compatible changes.
Furthermore, if such
changes prove to be necessary, it can be expected that SHA-256 repositories created with today's Git will be usable by future versions of Git without data loss.