mirror of
https://github.com/rust-lang/cargo
synced 2024-10-31 07:46:57 +00:00
cfffda9ae5
This allows to use `gitoxide` for all fetch operations, boosting performance for fetching the `crates.io` index by a factor of 2.2x, while being consistent on all platforms. For trying it, nightly builds of `cargo` can specify `-Zgitoxide=fetch`. It's also possible to set the `__CARGO_USE_GITOXIDE_INSTEAD_OF_GIT2=1` environment variable (value matters), which is when `-Zgitoxide=none` can be used to use `git2` instead. Limitations ----------- Note that what follows are current shortcomings that will be addressed in future PRs. - it's likely that authentication around the `ssh` protocol will work differently in practice as it uses the `ssh` program. - clones from `file://` based crates indices will need the `git` binary to serve the locatl repository. - the progress bar shown when fetching doesn't work like the orgiinal, but should already feel 'faster'.
117 lines
3.1 KiB
Rust
117 lines
3.1 KiB
Rust
//! Tests for git garbage collection.
|
|
|
|
use std::env;
|
|
use std::ffi::OsStr;
|
|
use std::path::PathBuf;
|
|
|
|
use cargo_test_support::git;
|
|
use cargo_test_support::git::cargo_uses_gitoxide;
|
|
use cargo_test_support::paths;
|
|
use cargo_test_support::project;
|
|
use cargo_test_support::registry::Package;
|
|
|
|
use url::Url;
|
|
|
|
pub fn find_index() -> PathBuf {
|
|
let dir = paths::home().join(".cargo/registry/index");
|
|
dir.read_dir().unwrap().next().unwrap().unwrap().path()
|
|
}
|
|
|
|
fn run_test(path_env: Option<&OsStr>) {
|
|
const N: usize = 50;
|
|
|
|
let foo = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
authors = []
|
|
|
|
[dependencies]
|
|
bar = "*"
|
|
"#,
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.build();
|
|
Package::new("bar", "0.1.0").publish();
|
|
|
|
foo.cargo("check").run();
|
|
|
|
let index = find_index();
|
|
let path = paths::home().join("tmp");
|
|
let url = Url::from_file_path(&path).unwrap().to_string();
|
|
let repo = git2::Repository::init(&path).unwrap();
|
|
let index = git2::Repository::open(&index).unwrap();
|
|
let mut cfg = repo.config().unwrap();
|
|
cfg.set_str("user.email", "foo@bar.com").unwrap();
|
|
cfg.set_str("user.name", "Foo Bar").unwrap();
|
|
let mut cfg = index.config().unwrap();
|
|
cfg.set_str("user.email", "foo@bar.com").unwrap();
|
|
cfg.set_str("user.name", "Foo Bar").unwrap();
|
|
|
|
for _ in 0..N {
|
|
git::commit(&repo);
|
|
index
|
|
.remote_anonymous(&url)
|
|
.unwrap()
|
|
.fetch(&["refs/heads/master:refs/remotes/foo/master"], None, None)
|
|
.unwrap();
|
|
}
|
|
drop((repo, index));
|
|
Package::new("bar", "0.1.1").publish();
|
|
|
|
let before = find_index()
|
|
.join(".git/objects/pack")
|
|
.read_dir()
|
|
.unwrap()
|
|
.count();
|
|
assert!(before > N);
|
|
|
|
let mut cmd = foo.cargo("update");
|
|
cmd.env("__CARGO_PACKFILE_LIMIT", "10");
|
|
if let Some(path) = path_env {
|
|
cmd.env("PATH", path);
|
|
}
|
|
cmd.env("CARGO_LOG", "trace");
|
|
cmd.run();
|
|
let after = find_index()
|
|
.join(".git/objects/pack")
|
|
.read_dir()
|
|
.unwrap()
|
|
.count();
|
|
assert!(
|
|
after < before,
|
|
"packfiles before: {}\n\
|
|
packfiles after: {}",
|
|
before,
|
|
after
|
|
);
|
|
}
|
|
|
|
#[cargo_test(requires_git)]
|
|
fn use_git_gc() {
|
|
run_test(None);
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn avoid_using_git() {
|
|
if cargo_uses_gitoxide() {
|
|
// file protocol without git binary is currently not possible - needs built-in upload-pack.
|
|
// See https://github.com/Byron/gitoxide/issues/734 (support for the file protocol) progress updates.
|
|
return;
|
|
}
|
|
let path = env::var_os("PATH").unwrap_or_default();
|
|
let mut paths = env::split_paths(&path).collect::<Vec<_>>();
|
|
let idx = paths
|
|
.iter()
|
|
.position(|p| p.join("git").exists() || p.join("git.exe").exists());
|
|
match idx {
|
|
Some(i) => {
|
|
paths.remove(i);
|
|
}
|
|
None => return,
|
|
}
|
|
run_test(Some(&env::join_paths(&paths).unwrap()));
|
|
}
|