Skip to content

feat(git): SHA256 repository support#16939

Draft
weihanglo wants to merge 7 commits into
rust-lang:masterfrom
weihanglo:sha256-git2
Draft

feat(git): SHA256 repository support#16939
weihanglo wants to merge 7 commits into
rust-lang:masterfrom
weihanglo:sha256-git2

Conversation

@weihanglo
Copy link
Copy Markdown
Member

@weihanglo weihanglo commented Apr 24, 2026

What does this PR try to resolve?

This wires the unstable libgit2 SHA256 support into Cargo.

SHA256 repositories usage are gated behind -Zgit=sha256.

Before looking at a repo,
Cargo now try to guess whether this git dep is SHA1 or SHA256
from these places (in this order):

  • locked rev in Cargo.lock
  • local db (with or without -sha256 suffix)
  • Create a detached remote and probe its object format

What works and doesn't:

  • Git CLI and libgit2 interop works
  • SHA1 and SHA256 git db coexist (via -sha256 dir suffix)
  • -Zgit=sha256 gates during early fetch paths,
    so even have local db cached you cannot use without Z flag
  • gitoxide hasn't yet supported, and will fall back to libgit2 when sha256 is used

Some known issues and regressions:

  • Probing adds a silent extra round-trip on every first fetch,
    even for SHA1 repos.
    An alternative is to assume SHA1 and retry on mismatch,
    though it has cost of a wasted fetch attempt for SHA256 repos.

How to test and review this PR?

Fixes #14942

This is currently blocked on libgit2 and git2-rs to cut a new release that contain all fixes we want listed in #14942.

I haven't tried it end-to-end though

The current model also means that Cargo will always vendor libgit2, which I guess will cause some headache on downstream packagers (Fedora, Debian, NixOS, etc.)

@rustbot rustbot added A-documenting-cargo-itself Area: Cargo's documentation A-git Area: anything dealing with git A-testing-cargo-itself Area: cargo's tests A-unstable Area: nightly unstable support labels Apr 24, 2026
@weihanglo
Copy link
Copy Markdown
Member Author

Created for showcasing it works btw.

weihanglo added 7 commits May 7, 2026 20:09
Also Adapt `rev_to_oid()` to the new `Oid::from_str` signature
The flag is accepted but has no effect yet.
This wires the unstable libgit2 SHA256 support into Cargo.

SHA256 repositories usage are gated behind `-Zgit=sha256`.

Before looking at a repo,
Cargo now try to guess whether this git dep is SHA1 or SHA256
from these places (in this order):

* locked rev in Cargo.lock
* local db (with or without `-sha256` suffix)
* Create a detached remote and probe its object format

What works and doesn't:

* Git CLI and libgit2 interop works
* SHA1 and SHA256 git db coexist (via `-sha256` dir suffix)
* `-Zgit=sha256` gates during early fetch paths,
  so even have local db cached you cannot use without Z flag
* gitoxide hasn't yet supported

Some known issues and regressions:

* Probing adds a silent extra round-trip on every first fetch,
  even for SHA1 repos.
  An alternative is to assume SHA1 and retry on mismatch,
  though it has cost of a wasted fetch attempt for SHA256 repos.
///
/// NOTE: The auth/certificate_check setup is duplicated from
/// [`with_fetch_options`] above. Keep them in sync.
pub(crate) fn probe_remote_object_format(
Copy link
Copy Markdown
Member Author

@weihanglo weihanglo May 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The other alternative is cloning it to a temporary directory, say foo-ed128302-unknown and check the object format, and then rename it to -sha256 suffix if it is SHA256 repo.

The downside of this is that we then always clone SHA256 repo even when -Zgit=sha256 is off, and then need to clean up the temp directory because it is disabled.

If we unconditionally support SHA256, probably this alternative is the best option.

View changes since the review

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we do the init-then-fetch way, we need to know the repo object format in advance to init a repo. There is no way to avoid this unless we switch to clone.

Copy link
Copy Markdown
Member Author

@weihanglo weihanglo May 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current model also means that Cargo will always vendor libgit2, which I guess will cause some headache on downstream packagers (Fedora, Debian, NixOS, etc.)

libgit2-sys probes libgit2-experimental.so when building with experimental sha256 support. I don't know if downstream packager what to ship those though.

https://github.com/rust-lang/git2-rs/blob/main/libgit2-sys/CHANGELOG.md#0184193---2026-05-07

Alternatively we wait for libgit2 v2 in May and ship the SHA256 support without any feature flag: libgit2/libgit2#7149 (reply in thread)

View changes since the review

Copy link
Copy Markdown
Member Author

@weihanglo weihanglo May 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In terms of testing it more broadly, we could swap all sha2 repo to use SHA256 just like how __CARGO_USE_GITOXIDE_INSTEAD_OF_GIT2 is working today

View changes since the review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-documenting-cargo-itself Area: Cargo's documentation A-git Area: anything dealing with git A-testing-cargo-itself Area: cargo's tests A-unstable Area: nightly unstable support

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support SHA256 Git repositories

2 participants