-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve performance of fetching git dependencies by rev #10078
Comments
Here is a test program to validate any change to libgit2: // [dependencies]
// git2 = "0.13"
fn main() -> Result<(), git2::Error> {
let _ = std::fs::remove_dir_all("cargo");
eprintln!("done rmdir");
let repo = git2::Repository::init("cargo")?;
eprintln!("done init");
let mut remote = repo.remote_anonymous("https://github.com/rust-lang/cargo")?;
eprintln!("done remote");
remote.fetch(&["+88117505b8b691e0e7892630a71a85bb5e9945de:refs/success"], None, None)?;
eprintln!("done fetch");
let thing = repo.revparse_single("refs/success")?;
println!("{}", thing.id());
Ok(())
} Currently, the If the server never offers the ref you are looking for, the filter never passes, and nothing gets fetched. Implementing "reachable sha1 in want" in libgit2 will involve sending the server a |
I posted libgit2/libgit2#6135 for upstream request. |
libgit2 1.4.0 was just released and contains the functionality needed for this. We're now blocked on a libgit2 bump in the |
The libgit2 functionality for this is now supported by the git2 crate in versions 0.14.0 and newer. With that, I believe this issue is unblocked and the remaining work just needs to be done in Cargo. |
Out of curious. Does it help even without shallow fetch support? |
Yes; see #10079.
|
Problem
GitHub recently enabled support for fetching individual commits by commit hash (
uploadpack.allowReachableSHA1InWant
on the server side).Notice the presence of
allow-reachable-sha1-in-want
in the advertised protocol capabilities.Example of using "reachable sha1 in want" on the CLI:
Notice in the above log that only 2.08 MiB total were downloaded. This is significantly less than the 50+ MiB of the whole Cargo repo. For larger repos the difference can be even more significant.
Unfortunately today Cargo doesn't make use of "reachable sha1 in want". Instead, when you specify a git dependency like
cargo = { git = "https://github.com/rust-lang/cargo", rev = "88117505b8b691e0e7892630a71a85bb5e9945de" }
, Cargo fetches all branches and tags and their entire history, hoping that the requested commit id is somewhere among that potentially enormous pile of commits:cargo/src/cargo/sources/git/utils.rs
Lines 809 to 814 in 458d345
Proposed Solution
I've opened a PR containing the Cargo side of the implementation:
However libgit2, which is the C library wrapped by Cargo's
git2
dependency, does not yet support "reachable sha1 in want" as far as I can tell (thegit
cli does, which is not based on libgit2, and is why thegit fetch
above is able to use it).Someone will need to send a PR to libgit2 implementing "reachable sha1 in want", then pull the changes into https://github.com/rust-lang/git2-rs, and finally land the Cargo change to use it.
Notes
As a side benefit, this change will make
rev = "..."
dependencies support revs which are not in the history of any upstream branch or tag. But the performance or disk usage improvement will be the more noticeable benefit to most Cargo users.The text was updated successfully, but these errors were encountered: