Skip to content

fix(git)!: Default to net.git-fetch-with-cli if git is present - #17329

Open
epage wants to merge 4 commits into
rust-lang:masterfrom
epage:lazy-git
Open

fix(git)!: Default to net.git-fetch-with-cli if git is present#17329
epage wants to merge 4 commits into
rust-lang:masterfrom
epage:lazy-git

Conversation

@epage

@epage epage commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

What does this PR try to resolve?

This changes the default for how we fetch to use the git CLI if present for better conformity and performance without breaking people (yet) who don't have it.

Part of #17227

How to test and review this PR?

I have triaged open issues related to git-fetch-with-cli.

corrupt_git.rs is an interesting case. From what an agent told me that sounds reasonable, we hit an infinite loop in libgit2. We should report that but not feeling it is bad enough to be a blocker for merging this, especially since people are using a sparse index.

Future goals:

  • Remove git2 fetch to unblock moving off of curl
  • Remove git2 to speed up startup and reduce C deps

Future steps:

  1. Add future-incompat when the default falls back to git2
  2. Remove the git check, always defaulting to git-cli
  3. Remove git2 fetch

@rustbot rustbot added A-git Area: anything dealing with git S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 6, 2026
@rustbot

rustbot commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

r? @weihanglo

rustbot has assigned @weihanglo.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: @epage, @weihanglo
  • @epage, @weihanglo expanded to epage, weihanglo

@weihanglo

Copy link
Copy Markdown
Member

corrupt_git.rs is an interesting case. From what an agent told me that sounds reasonable, we hit an infinite loop in libgit2. We should report that but not feeling it is bad enough to be a blocker for merging this, especially since people are using a sparse index.

A possible upstream fix: libgit2/libgit2#7346

Comment thread src/sources/git/utils.rs Outdated
}

fn is_git_cli_present() -> bool {
#[tracing::instrument(skip_all)]

@weihanglo weihanglo Aug 16, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think before making it default, we may want to make sure:

  • What the minimum required Git CLI version we depend on.
    • This doesn't need to be precise, but at least we figure out an approximate.
  • What Git CLI v3 would ship and whether it would be hard to keep our compatibility story: https://git-scm.com/docs/BreakingChanges#_git_3_0.
    • Looked over the proposed change, refutable and sha256 may require a bit more attention, as old Git may not be able to read the new index format.
    • If there is any more defaults we need to make explicit and opt-out, it is better to as early as possible. (e.g. safe.bareRepository though we already set GIT_DIR explicitly for fetch in git-fetch-with-cli: Set GIT_DIR for bare repository compatibility #14860).

View changes since the review

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Made this: #17370

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We have Git version detection in #17400.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What the minimum required Git CLI version we depend on.

Just for curiousity I wanted to know, why can't we simply assume the current version(available on user device) to be the appropriate version and if while doing the action we encounter an error, rust's awesome error handling will explain the error to user and may be add a sugestion to upgrade git CLI?
This way If I am using a old unix system with no sudo privilege (like my college HPC server) and cargo needs git pull that could be done by any version, I will not be blocked! Basically it give highest flexibility.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Because that may fail previous-successful builds. To provide a good diagnostic we also need to know what version user need to upgrade to.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

For the change to sha256, the change is for the default for git init. Cargo uses ligit2 instead of git init, so we won't be impacted by the hasher default changing with git v3.

pull Bot pushed a commit to Little-Star888/cargo that referenced this pull request Aug 19, 2026
### What does this PR try to resolve?

Git v3 will enforce `safe.bareRepository=explicit`,
while older versions don't.
See <https://git-scm.com/docs/BreakingChanges/2.55.0#_git_3_0>

This ensures `git gc` work with `safe.bareRepository=explicit`
by setting an explicit `GIT_DIR` environment variable.

This is not a requirement of making CLI fetch the default,
but better to have before Git CLI v3 is out.
CC rust-lang#17329

### How to test and review this PR?

You can basically repro this manually today with Git 2.38.0 and later
(which `safe.bareRepository` first appears).

1. Set `safe.bareRepository=explicit`
2. `cargo fetch` with config `net.git-fetch-with-cli=true`
3. Put a marker file inside `$CARGO_HOME/git/db/<git-dir>/`
4. `cargo update` to force a git fetch
5. Observe the marker is gone, because Cargo reinitialized the entire
db.

I am not sure if there is a better way to test it than a marker file
though.

🤖 **LLM disclosure**: I told Codex to check if Cargo's `git fetch` usage
is not compatibility with Git CLI v3, and surprisingly it told me `git
gc` is not good. I didn't expect this.
pull Bot pushed a commit to coleleavitt/cargo that referenced this pull request Aug 28, 2026
…7400)

### What does this PR try to resolve?

Trying to make the output cleaner, particularly on ambiguous refs, in
prep for rust-lang#17329

### How to test and review this PR?

Since progress does not have end-to-end tests,
I ran
```
cargo new git-dep
cd git-dep
cargo add cargo --git https://github.com/rust-lang/cargo/
rm -rf ~/.cargo/git
CARGO_NET_GIT_FETCH_WITH_CLI=true nargo check
```

Remaining git output is:
```
remote: Enumerating objects: 187021, done.
remote: Counting objects: 100% (326/326), done.
remote: Compressing objects: 100% (155/155), done.
remote: Total 187021 (delta 241), reused 177 (delta 171), pack-reused 186695 (from 3)
Receiving objects: 100% (187021/187021), 69.48 MiB | 4.90 MiB/s, done.
Resolving deltas: 100% (130194/130194), done.
```
@rustbot

This comment has been minimized.

@epage
epage marked this pull request as draft August 28, 2026 21:35
@rustbot rustbot removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Aug 28, 2026
If we get rid of ligit2 fetch, we'll need to re-evaluate how we do retry
testing.
@epage
epage marked this pull request as ready for review September 3, 2026 16:42
@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Sep 3, 2026
@weihanglo weihanglo added the T-cargo Team: Cargo label Sep 3, 2026
@weihanglo

weihanglo commented Sep 3, 2026

Copy link
Copy Markdown
Member

@rfcbot fcp merge

This proposes changing Cargo default backend for network Git fetches.

Before this

  • When net.git-fetch-with-cli is unset, Cargo uses the builtin backend (libgit2 as of 1.100-nightly)
  • net.git-fetch-with-cli=true to opt-in Git CLI for fetches.

After this

  • When net.git-fetch-with-cli is unset, Cargo uses Git CLI by default, and falls back to the builtin backend if the Git CLI is not present.
  • net.git-fetch-with-cli=false to switch back to the builtin backend.

This affects both fetching git dependencies and Git registry index, and only network fetching. Repo checkout is still run on libgit2.

Benefits

  • Address long-standing fetch issue like proxies or SSH authentication that libgit2 doesn't support well.
  • Git CLI is performant, and doesn't need to pay for startup loading cost if not used (this was already partially addressed outside this switch)
  • Reduce the support burden on chasing extra Git configuration supports in upstream libgit2
  • Git CLI is the reference implementation and used by most Git users
  • See Migrate to CLI git fetching #17227 for more
  • Eventually like the PR description has said, we may be able to remove away libgit2 C dep from Cargo.

Downsides

  • Cargo now relies on external tools, and fetches behavior may vary on different systems, user configs, and PATH env vars
    • The expectation is that most dev machines has Git installed, and we also added Git CLI version detection. We can also unset more user configs that may impact on fetch behavior.
  • Due to the lack of programmable output, Git CLI diagnostics slightly regresses, and could be more verbose when --verbose flag is present.
  • With Git CLI, git fetches now doesn't retry for non HTTP 429 transient errors. Previously libgit2 retries 3 times for both network and spurious errors.

@rust-rfcbot

rust-rfcbot commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

@weihanglo has proposed to merge this. The next step is review by the rest of the tagged team members:

No concerns currently listed.

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@rust-rfcbot rust-rfcbot added proposed-final-comment-period An FCP proposal has started, but not yet signed off. disposition-merge FCP with intent to merge labels Sep 3, 2026
Comment thread src/sources/git/utils.rs
Comment on lines +1105 to +1108
let result = if gctx
.net_config()?
.git_fetch_with_cli
.unwrap_or_else(|| git_version().is_some())

@weihanglo weihanglo Sep 3, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We should also update doc for net.git-fetch-with-cli.

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks for catching that!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Not specific to this PR, though there is a catch: cargo config get doesn't really reflect the if something then true else false logic. I don't think this is a blocker though worth some thinking.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Tracked in #9301

@@ -1,7 +1,7 @@
<svg width="740px" height="92px" xmlns="http://www.w3.org/2000/svg">
<svg width="2204px" height="146px" xmlns="http://www.w3.org/2000/svg">

@arlosi arlosi Sep 3, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Any idea why the width increased so much here?

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

That is the git fetch command's full length before redacting content. This happens in other SVG tests.

epage pushed a commit to epage/cargo that referenced this pull request Sep 3, 2026
### What does this PR try to resolve?

It was added for libgit2 but not git-cli

### How to test and review this PR?

I tested this by forcing git-cli for the relevant tests and they still
passed.

I did not add any tests for this because we will get coverage with
rust-lang#17329. I avoided duplicating the tests for each git backend out of
concern for getting more rate limits from github in CI.
@rustbot

rustbot commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@rustbot rustbot added the A-documenting-cargo-itself Area: Cargo's documentation label Sep 3, 2026
@epage
epage force-pushed the lazy-git branch 3 times, most recently from 1aae7d6 to fd77c15 Compare September 4, 2026 15:48
@weihanglo weihanglo mentioned this pull request Sep 4, 2026
14 tasks
This changes the default for how we fetch to use the git CLI if present for better conformity and performance without breaking people (yet) who don't have it.

Part of rust-lang#17227
@epage
epage force-pushed the lazy-git branch 5 times, most recently from 759b6f1 to bfc1332 Compare September 4, 2026 21:44
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 disposition-merge FCP with intent to merge proposed-final-comment-period An FCP proposal has started, but not yet signed off. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-cargo Team: Cargo

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants