diff --git a/Cargo.lock b/Cargo.lock index 749fc2ce841..f470b7638bd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1519,9 +1519,8 @@ dependencies = [ [[package]] name = "git2" -version = "0.20.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b88256088d75a56f8ecfa070513a775dd9107f6530ef14919dac831af9cfe2b" +version = "0.21.0" +source = "git+https://github.com/rust-lang/git2-rs.git?rev=refs%2Fpull%2F1206%2Fhead#e6919b76ae08e2fc60291d414fab9af6a67feae3" dependencies = [ "bitflags", "libc", @@ -1534,9 +1533,8 @@ dependencies = [ [[package]] name = "git2-curl" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be8dcabbc09ece4d30a9aa983d5804203b7e2f8054a171f792deff59b56d31fa" +version = "0.22.0" +source = "git+https://github.com/rust-lang/git2-rs.git?rev=refs%2Fpull%2F1206%2Fhead#e6919b76ae08e2fc60291d414fab9af6a67feae3" dependencies = [ "curl", "git2", @@ -3115,8 +3113,7 @@ checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" [[package]] name = "libgit2-sys" version = "0.18.3+1.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9b3acc4b91781bb0b3386669d325163746af5f6e4f73e6d2d630e09a35f3487" +source = "git+https://github.com/rust-lang/git2-rs.git?rev=refs%2Fpull%2F1206%2Fhead#e6919b76ae08e2fc60291d414fab9af6a67feae3" dependencies = [ "cc", "libc", diff --git a/Cargo.toml b/Cargo.toml index ab0eb9c94a7..462d0b30f64 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,8 +51,8 @@ filetime = "0.2.27" flate2 = { version = "1.1.9", default-features = false, features = ["zlib-rs"] } futures = { version = "0.3.32", default-features = false, features = ["std", "executor", "async-await"]} futures-timer = "3.0.3" -git2 = "0.20.4" -git2-curl = "0.21.0" +git2 = { git = "https://github.com/rust-lang/git2-rs.git", rev = "refs/pull/1206/head", features = ["unstable-sha256", "ssh", "https"] } +git2-curl = { git = "https://github.com/rust-lang/git2-rs.git", rev = "refs/pull/1206/head" } # When updating this, also see if `gix-transport` further down needs updating or some auth-related tests will fail. gix = { version = "0.81.0", default-features = false, features = ["sha1", "progress-tree", "parallel", "dirwalk", "status"] } gix-transport = "0.55.1" @@ -71,7 +71,7 @@ itertools = "0.14.0" jiff = { version = "0.2.23", default-features = false, features = [ "std" ] } jobserver = "0.1.34" libc = "0.2.184" -libgit2-sys = "0.18.3" +libgit2-sys = { git = "https://github.com/rust-lang/git2-rs.git", rev = "refs/pull/1206/head", features = ["unstable-sha256"] } libloading = "0.9.0" memchr = "2.8.0" memfd = "0.6.5" diff --git a/crates/cargo-test-support/src/git.rs b/crates/cargo-test-support/src/git.rs index d0826299531..e2872684c17 100644 --- a/crates/cargo-test-support/src/git.rs +++ b/crates/cargo-test-support/src/git.rs @@ -144,6 +144,17 @@ pub fn init(path: &Path) -> git2::Repository { repo } +/// *(`git2`)* Initialize a new SHA256 repository at the given path. +pub fn init_sha256(path: &Path) -> git2::Repository { + default_search_path(); + let mut opts = git2::RepositoryInitOptions::new(); + opts.external_template(false) + .object_format(git2::ObjectFormat::Sha256); + let repo = t!(git2::Repository::init_opts(path, &opts)); + default_repo_cfg(&repo); + repo +} + fn default_search_path() { use crate::paths::global_root; use git2::{ConfigLevel, opts::set_search_path}; @@ -187,6 +198,21 @@ where (git_project, repo) } +/// Create a new [`Project`] in a SHA256 git [`Repository`] +pub fn new_sha256_repo(name: &str, callback: F) -> (Project, git2::Repository) +where + F: FnOnce(ProjectBuilder) -> ProjectBuilder, +{ + let mut git_project = project().at(name); + git_project = callback(git_project); + let git_project = git_project.build(); + + let repo = init_sha256(&git_project.root()); + add(&repo); + commit(&repo); + (git_project, repo) +} + /// *(`git2`)* Add all files in the working directory to the git index pub fn add(repo: &git2::Repository) { let mut index = t!(repo.index()); diff --git a/src/cargo/core/features.rs b/src/cargo/core/features.rs index f7c8a75bea4..e0edde31bf8 100644 --- a/src/cargo/core/features.rs +++ b/src/cargo/core/features.rs @@ -1028,6 +1028,8 @@ pub struct GitFeatures { pub shallow_index: bool, /// When cloning git dependencies, perform a shallow clone and maintain shallowness on subsequent fetches. pub shallow_deps: bool, + /// Allow SHA256 git repositories. + pub sha256: bool, } impl GitFeatures { @@ -1035,11 +1037,12 @@ impl GitFeatures { GitFeatures { shallow_index: true, shallow_deps: true, + sha256: true, } } fn expecting() -> String { - let fields = ["`shallow-index`", "`shallow-deps`"]; + let fields = ["`shallow-index`", "`shallow-deps`", "`sha256`"]; format!( "unstable 'git' only takes {} as valid inputs", fields.join(" and ") @@ -1103,12 +1106,14 @@ fn parse_git(it: impl Iterator>) -> CargoResult *shallow_index = true, "shallow-deps" => *shallow_deps = true, + "sha256" => *sha256 = true, _ => { bail!(GitFeatures::expecting()) } diff --git a/src/cargo/sources/git/source.rs b/src/cargo/sources/git/source.rs index 1db73a1b9b3..9a6858903c6 100644 --- a/src/cargo/sources/git/source.rs +++ b/src/cargo/sources/git/source.rs @@ -8,6 +8,7 @@ use crate::sources::IndexSummary; use crate::sources::RecursivePathSource; use crate::sources::git::utils::GitDatabase; use crate::sources::git::utils::GitRemote; +use crate::sources::git::utils::probe_remote_object_format; use crate::sources::git::utils::rev_to_oid; use crate::sources::source::MaybePackage; use crate::sources::source::QueryKind; @@ -47,14 +48,17 @@ use url::Url; /// │ │ └── e33d1ac/ /// │ ├── log-c58e1db3de7c154d-shallow/ /// │ │ └── 11eda98/ +/// │ └── foo-9f1e8cfc50c5ba7d-sha256/ +/// │ └── cfc50c5/ /// └── db/ /// ├── gimli-a0d193bd15a5ed96/ -/// └── log-c58e1db3de7c154d-shallow/ +/// ├── log-c58e1db3de7c154d-shallow/ +/// └── foo-9f1e8cfc50c5ba7d-sha256/ /// ``` /// /// For more on Git cache directory, see ["Cargo Home"] in The Cargo Book. /// -/// For more on the directory format `-[-shallow]`, see [`ident`] +/// For more on the directory format `-[-shallow][-sha256]`, see [`ident`] /// and [`ident_shallow`]. /// /// ## Locked to a revision @@ -171,23 +175,81 @@ impl<'gctx> GitSource<'gctx> { } fn mark_used(&self) -> CargoResult<()> { + let format = match &*self.locked_rev.borrow() { + Revision::Locked(oid) => oid.object_format(), + _ => unreachable!("locked_rev must be resolved before mark_used"), + }; + let ident = self.ident_for_format(format); self.gctx .deferred_global_last_use()? .mark_git_checkout_used(global_cache_tracker::GitCheckout { - encoded_git_name: self.ident, + encoded_git_name: ident, short_name: self.short_id.borrow().expect("update before download"), size: None, }); Ok(()) } + fn ident_for_format(&self, format: git2::ObjectFormat) -> InternedString { + match format { + git2::ObjectFormat::Sha1 => self.ident, + git2::ObjectFormat::Sha256 => format!("{}-sha256", self.ident).into(), + } + } + + /// Determines the Git object format for this remote. + /// + /// This may probe the remote repository if needed. + fn object_format_hint(&self) -> CargoResult> { + if let Revision::Locked(oid) = &*self.locked_rev.borrow() { + return Ok(Some(oid.object_format())); + } + + let git_db_path = self.gctx.git_db_path(); + self.gctx + .assert_package_cache_locked(CacheLockMode::DownloadExclusive, &git_db_path); + let git_db_path = git_db_path.as_path_unlocked(); + + for format in [git2::ObjectFormat::Sha1, git2::ObjectFormat::Sha256] { + let ident = self.ident_for_format(format); + let path = git_db_path.join(ident); + if path.exists() + && let Ok(db) = self.remote.db_at(&path) + { + return Ok(Some(db.object_format())); + } + } + + Ok(None) + } + /// Fetch and return a [`GitDatabase`] with the resolved revision /// for this source, /// /// This won't fetch anything if the required revision is /// already available locally. pub(crate) fn fetch_db(&self, is_submodule: bool) -> CargoResult<(GitDatabase, git2::Oid)> { - let db_path = self.gctx.git_db_path().join(&self.ident); + let mut is_update_status_shown = false; + + let format = if let Some(format) = self.object_format_hint()? { + format + } else { + if !is_update_status_shown { + is_update_status_shown = true; + self.show_update_status(is_submodule)?; + } + if let Some(offline_flag) = self.gctx.offline_flag() { + anyhow::bail!( + "can't checkout from '{}': you are in the offline mode ({offline_flag})", + self.remote.url() + ); + } + + trace!("probing git source `{:?}`", self.remote); + probe_remote_object_format(self.source_id.borrow().url(), self.gctx)? + }; + + let db_path = self.gctx.git_db_path().join(self.ident_for_format(format)); let db_path = db_path.into_path_unlocked(); let db = self.remote.db_at(&db_path).ok(); @@ -226,28 +288,41 @@ impl<'gctx> GitSource<'gctx> { ); } - if !self.quiet { - let scope = if is_submodule { - "submodule" - } else { - "repository" - }; - self.gctx - .shell() - .status("Updating", format!("git {scope} `{}`", self.remote.url()))?; + if !is_update_status_shown { + self.show_update_status(is_submodule)?; } trace!("updating git source `{:?}`", self.remote); let locked_rev = locked_rev.clone().into(); let manifest_reference = self.source_id.borrow().git_reference().unwrap(); - self.remote - .checkout(&db_path, db, manifest_reference, &locked_rev, self.gctx)? + self.remote.checkout( + &db_path, + db, + manifest_reference, + &locked_rev, + format, + self.gctx, + )? } }; Ok((db, actual_rev)) } + fn show_update_status(&self, is_submodule: bool) -> CargoResult<()> { + if self.quiet { + return Ok(()); + } + let scope = if is_submodule { + "submodule" + } else { + "repository" + }; + self.gctx + .shell() + .status("Updating", format!("git {scope} `{}`", self.remote.url())) + } + fn update(&self) -> CargoResult<()> { if self.path_source.borrow().is_some() { self.mark_used()?; @@ -282,10 +357,11 @@ impl<'gctx> GitSource<'gctx> { // Check out `actual_rev` from the database to a scoped location on the // filesystem. This will use hard links and such to ideally make the // checkout operation here pretty fast. + let ident = self.ident_for_format(actual_rev.object_format()); let checkout_path = self .gctx .git_checkouts_path() - .join(&self.ident) + .join(ident) .join(short_id.as_str()); let checkout_path = checkout_path.into_path_unlocked(); db.copy_to(actual_rev, &checkout_path, self.gctx, self.quiet)?; @@ -360,6 +436,7 @@ fn ident(id: &SourceId) -> String { /// Like [`ident()`], but appends `-shallow` to it, turning /// `proto://host/path/repo` into `repo--shallow`. +/// SHA256 repositories add the `-sha256` suffix on top of this identifier. /// /// It's important to separate shallow from non-shallow clones for reasons of /// backwards compatibility --- older cargo's aren't necessarily handling diff --git a/src/cargo/sources/git/utils.rs b/src/cargo/sources/git/utils.rs index d09636c0a8d..12665ca2ea2 100644 --- a/src/cargo/sources/git/utils.rs +++ b/src/cargo/sources/git/utils.rs @@ -14,7 +14,9 @@ use crate::util::{GlobalContext, IntoUrl, MetricsCounter, Progress, network}; use anyhow::{Context as _, anyhow}; use cargo_util::{ProcessBuilder, paths}; use cargo_util_terminal::Verbosity; -use git2::{ErrorClass, ObjectType, Oid}; +use git2::ErrorClass; +use git2::ObjectType; +use git2::Oid; use http::{Request, StatusCode}; use tracing::{debug, info}; use url::Url; @@ -112,6 +114,7 @@ impl GitRemote { db: Option, manifest_reference: &GitReference, reference: &GitReference, + object_format: git2::ObjectFormat, gctx: &GlobalContext, ) -> CargoResult<(GitDatabase, git2::Oid)> { if let Some(mut db) = db { @@ -137,7 +140,7 @@ impl GitRemote { paths::remove_dir_all(into)?; } paths::create_dir_all(into)?; - let mut repo = init(into, true)?; + let mut repo = init(into, true, object_format)?; fetch( &mut repo, self.url(), @@ -212,6 +215,11 @@ impl GitDatabase { self.repo.revparse_single(&oid.to_string()).is_ok() } + /// Gets the object format for this database. + pub fn object_format(&self) -> git2::ObjectFormat { + self.repo.object_format() + } + /// [`resolve_ref`]s this reference with this database. pub fn resolve(&self, r: &GitReference) -> CargoResult { resolve_ref(r, &self.repo) @@ -471,7 +479,10 @@ impl<'a> GitCheckout<'a> { Err(..) => { let path = parent.workdir().unwrap().join(child.path()); let _ = paths::remove_dir_all(&path); - init(&path, false)? + // Inherit the parent repo's object format. + // Git does not support mixed-format submodules as of Git 2.54. + // https://github.com/git/git/blob/94f057755b7941b321fd11fec1b2e3ca5313a4e0/object-file.c#L1747 + init(&path, false, head.object_format())? } }; // Fetch submodule database and checkout to target revision @@ -890,6 +901,9 @@ fn reset(repo: &git2::Repository, obj: &git2::Object<'_>, gctx: &GlobalContext) /// /// The callback is provided a fetch options, which can be used by the actual /// git fetch. +/// +/// NOTE: The auth/certificate_check setup is duplicated in +/// [`probe_remote_object_format`]. Keep them in sync. pub fn with_fetch_options( git_config: &git2::Config, url: &str, @@ -981,6 +995,67 @@ pub fn with_fetch_options( }) } +/// Probes a remote for its object format (SHA-1 vs SHA-256) without fetching. +/// +/// NOTE: The auth/certificate_check setup is duplicated from +/// [`with_fetch_options`] above. Keep them in sync. +pub(crate) fn probe_remote_object_format( + remote_url: &Url, + gctx: &GlobalContext, +) -> CargoResult { + let git_config = git2::Config::open_default()?; + let ssh_config = gctx.net_config()?.ssh.as_ref(); + let config_known_hosts = ssh_config.and_then(|ssh| ssh.known_hosts.as_ref()); + let diagnostic_home_config = gctx.diagnostic_home_config(); + let remote_url = remote_url.as_str(); + network::retry::with_retry(gctx, || { + // Hack: libgit2 disallows overriding the error from check_cb since v1.8.0, + // so we store the error additionally and unwrap it later + let mut check_cb_result = Ok(()); + let auth_result = with_authentication(gctx, remote_url, &git_config, |f| { + let port = Url::parse(remote_url).ok().and_then(|url| url.port()); + let mut rcb = git2::RemoteCallbacks::new(); + rcb.credentials(f); + rcb.certificate_check(|cert, host| { + match super::known_hosts::certificate_check( + gctx, + cert, + host, + port, + config_known_hosts, + &diagnostic_home_config, + ) { + Ok(status) => Ok(status), + Err(e) => { + check_cb_result = Err(e); + // This is not really used because it'll be overridden by libgit2 + // See https://github.com/libgit2/libgit2/commit/9a9f220119d9647a352867b24b0556195cb26548 + Err(git2::Error::from_str( + "invalid or unknown remote ssh hostkey", + )) + } + } + }); + + let proxy_options = git2::ProxyOptions::new(); + // FIXME: Remove this comment when https://github.com/libgit2/libgit2/pull/7195 merges + // This doesn't respect insteadOf from global gitconfig + // If libgit2 can't get this fixed timely, we need to switch to + // probing a temporary on-disk repo. + let mut remote = git2::Remote::create_detached(remote_url)?; + let mut conn = + remote.connect_auth(git2::Direction::Fetch, Some(rcb), Some(proxy_options))?; + // Query while connected — libgit2's local transport frees the + // repo handle on disconnect, causing a SIGSEGV if queried after. + Ok(conn.remote().object_format()?) + }); + if auth_result.is_err() { + check_cb_result?; + } + auth_result + }) +} + /// Attempts to fetch the given git `reference` for a Git repository. /// /// This is the main entry for git clone/fetch. It does the followings: @@ -1084,11 +1159,17 @@ pub fn fetch( } debug!("doing a fetch for {remote_url}"); + let format = repo.object_format(); let result = if let Some(true) = gctx.net_config()?.git_fetch_with_cli { + ensure_sha256_allowed(format, gctx)?; fetch_with_cli(repo, remote_url, &refspecs, tags, shallow, gctx) } else if gctx.cli_unstable().gitoxide.map_or(false, |git| git.fetch) { + if matches!(format, git2::ObjectFormat::Sha256) { + anyhow::bail!("gitoxide does not yet support SHA256 repositories"); + } fetch_with_gitoxide(repo, remote_url, refspecs, tags, shallow, gctx) } else { + ensure_sha256_allowed(format, gctx)?; fetch_with_libgit2(repo, remote_url, refspecs, tags, shallow, gctx) }; @@ -1100,6 +1181,15 @@ pub fn fetch( result } +fn ensure_sha256_allowed(format: git2::ObjectFormat, gctx: &GlobalContext) -> CargoResult<()> { + if matches!(format, git2::ObjectFormat::Sha256) + && !gctx.cli_unstable().git.map_or(false, |git| git.sha256) + { + anyhow::bail!("SHA256 git repositories require `-Zgit=sha256` to be enabled"); + } + Ok(()) +} + /// `gitoxide` uses shallow locks to assure consistency when fetching to and to avoid races, and to write /// files atomically. /// Cargo has its own lock files and doesn't need that mechanism for race protection, so a stray lock means @@ -1438,6 +1528,7 @@ fn clean_repo_temp_files(repo: &git2::Repository) { /// Reinitializes a given Git repository. This is useful when a Git repository /// seems corrupted and we want to start over. fn reinitialize(repo: &mut git2::Repository) -> CargoResult<()> { + let format = repo.object_format(); // Here we want to drop the current repository object pointed to by `repo`, // so we initialize temporary repository in a sub-folder, blow away the // existing git folder, and then recreate the git repo. Finally we blow away @@ -1446,7 +1537,7 @@ fn reinitialize(repo: &mut git2::Repository) -> CargoResult<()> { debug!("reinitializing git repo at {:?}", path); let tmp = path.join("tmp"); let bare = !repo.path().ends_with(".git"); - *repo = init(&tmp, false)?; + *repo = init(&tmp, false, format)?; for entry in path.read_dir()? { let entry = entry?; if entry.file_name().to_str() == Some("tmp") { @@ -1455,19 +1546,20 @@ fn reinitialize(repo: &mut git2::Repository) -> CargoResult<()> { let path = entry.path(); drop(paths::remove_file(&path).or_else(|_| paths::remove_dir_all(&path))); } - *repo = init(&path, bare)?; + *repo = init(&path, bare, format)?; paths::remove_dir_all(&tmp)?; Ok(()) } /// Initializes a Git repository at `path`. -fn init(path: &Path, bare: bool) -> CargoResult { +fn init(path: &Path, bare: bool, format: git2::ObjectFormat) -> CargoResult { let mut opts = git2::RepositoryInitOptions::new(); // Skip anything related to templates, they just call all sorts of issues as // we really don't want to use them yet they insist on being used. See #6240 // for an example issue that comes up. opts.external_template(false); opts.bare(bare); + opts.object_format(format); Ok(git2::Repository::init_opts(&path, &opts)?) } @@ -1779,7 +1871,10 @@ mod tests { /// * /// * pub(super) fn rev_to_oid(rev: &str) -> Option { - Oid::from_str(rev) - .ok() - .filter(|oid| oid.as_bytes().len() * 2 == rev.len()) + let format = match rev.len() { + 40 => git2::ObjectFormat::Sha1, + 64 => git2::ObjectFormat::Sha256, + _ => return None, + }; + Oid::from_str(rev, format).ok() } diff --git a/src/doc/src/reference/unstable.md b/src/doc/src/reference/unstable.md index 139b7f7491e..18afdd05be8 100644 --- a/src/doc/src/reference/unstable.md +++ b/src/doc/src/reference/unstable.md @@ -1373,6 +1373,7 @@ Valid operations are the following: * `shallow-index` - perform a shallow clone of the index. * `shallow-deps` - perform a shallow clone of git dependencies. +* `sha256` - allow SHA256 git repositories **Details on shallow clones** @@ -1384,6 +1385,11 @@ Valid operations are the following: * When the unstable feature is on, fetching/cloning a git repository is always a shallow fetch. This roughly equals to `git fetch --depth 1` everywhere. * Even with the presence of `Cargo.lock` or specifying a commit `{ rev = "…" }`, gitoxide and libgit2 are still smart enough to shallow fetch without unshallowing the existing repository. +**Details on SHA256 git repositories** + +* To enable SHA256 git repositories, add `-Zgit=sha256`. +* SHA256 git repositories are only supported when using libgit2. + ## script * Tracking Issue: [#12207](https://github.com/rust-lang/cargo/issues/12207) diff --git a/tests/testsuite/bad_config.rs b/tests/testsuite/bad_config.rs index 8f76dad3f4d..73234543116 100644 --- a/tests/testsuite/bad_config.rs +++ b/tests/testsuite/bad_config.rs @@ -1,7 +1,7 @@ //! Tests for some invalid .cargo/config files. use crate::prelude::*; -use cargo_test_support::git::cargo_uses_gitoxide; + use cargo_test_support::registry::{self, Package}; use cargo_test_support::{Project, basic_bin_manifest, basic_manifest, project, rustc_host, str}; @@ -423,8 +423,7 @@ fn bad_git_dependency() { let p = project() .file( "Cargo.toml", - &format!( - r#" + r#" [package] name = "foo" version = "0.0.0" @@ -432,43 +431,15 @@ fn bad_git_dependency() { authors = [] [dependencies] - foo = {{ git = "{url}" }} + foo = { git = "file:.." } "#, - url = if cargo_uses_gitoxide() { - "git://host.xz" - } else { - "file:.." - } - ), ) .file("src/lib.rs", "") .build(); - if cargo_uses_gitoxide() { - p.cargo("check -v") - .with_status(101) - .with_stderr_data(str![[r#" -[UPDATING] git repository `git://host.xz` -[ERROR] failed to get `foo` as a dependency of package `foo v0.0.0 ([ROOT]/foo)` - -Caused by: - failed to load source for dependency `foo` - -Caused by: - unable to update git://host.xz - -Caused by: - failed to clone into: [ROOT]/home/.cargo/git/db/_empty-[HASH] - -Caused by: - URL "git://host.xz" does not specify a path to a repository - -"#]]) - .run(); - } else { - p.cargo("check -v") - .with_status(101) - .with_stderr_data(str![[r#" + p.cargo("check -v") + .with_status(101) + .with_stderr_data(str![[r#" [UPDATING] git repository `file:///` [ERROR] failed to get `foo` as a dependency of package `foo v0.0.0 ([ROOT]/foo)` @@ -478,15 +449,11 @@ Caused by: Caused by: unable to update file:/// -Caused by: - failed to clone into: [ROOT]/home/.cargo/git/db/_empty-[HASH] - Caused by: 'file:///' is not a valid local file URI; class=Config (7) "#]]) - .run(); - }; + .run(); } #[cargo_test] @@ -2384,9 +2351,6 @@ Caused by: Caused by: unable to update http://127.0.0.1/#foo - -Caused by: - failed to clone into: [ROOT]/home/.cargo/git/db/_empty-[HASH] ... "#]]) diff --git a/tests/testsuite/config.rs b/tests/testsuite/config.rs index fe09aded742..545e138953a 100644 --- a/tests/testsuite/config.rs +++ b/tests/testsuite/config.rs @@ -1995,7 +1995,7 @@ fn git_features() { error in environment variable `CARGO_UNSTABLE_GIT`: could not load config key `unstable.git` Caused by: - unstable 'git' only takes `shallow-index` and `shallow-deps` as valid inputs + unstable 'git' only takes `shallow-index` and `shallow-deps` and `sha256` as valid inputs "#]], ); @@ -2007,6 +2007,7 @@ Caused by: Some(GitFeatures { shallow_index: false, shallow_deps: true, + sha256: false, }), )); @@ -2051,6 +2052,7 @@ git = 'shallow-index' Some(GitFeatures { shallow_index: true, shallow_deps: false, + sha256: false, }), )); diff --git a/tests/testsuite/git_auth.rs b/tests/testsuite/git_auth.rs index a87d35b169f..d800a3cedd1 100644 --- a/tests/testsuite/git_auth.rs +++ b/tests/testsuite/git_auth.rs @@ -10,7 +10,6 @@ use std::thread::{self, JoinHandle}; use crate::prelude::*; use cargo_test_support::basic_manifest; -use cargo_test_support::git::cargo_uses_gitoxide; use cargo_test_support::paths; use cargo_test_support::project; @@ -149,9 +148,6 @@ Caused by: Caused by: unable to update http://{addr}/foo/bar -Caused by: - failed to clone into: [ROOT]/home/.cargo/git/db/bar-[HASH] - Caused by: failed to authenticate when downloading repository @@ -161,16 +157,8 @@ Caused by: https://doc.rust-lang.org/cargo/reference/config.html#netgit-fetch-with-cli Caused by: -{trailer} + no authentication methods succeeded ", - trailer = if cargo_uses_gitoxide() { - format!(r#"[CREDENTIAL]s provided for "http://{addr}/foo/bar" were not accepted by the remote - -Caused by: - Received HTTP status 401"#) - } else { - " no authentication methods succeeded".to_string() - } )) .run(); assert_eq!(connections.load(SeqCst), 2); @@ -228,23 +216,10 @@ Caused by: Caused by: unable to update https://{addr}/foo/bar -Caused by: - failed to clone into: [ROOT]/home/.cargo/git/db/bar-[HASH] - Caused by: {errmsg} ", - errmsg = if cargo_uses_gitoxide() { - r" network failure seems to have happened - if a proxy or similar is necessary `net.git-fetch-with-cli` may help here - https://doc.rust-lang.org/cargo/reference/config.html#netgit-fetch-with-cli - -Caused by: - An IO error occurred when talking to the server - -Caused by: - [35] SSL connect error ([..])" - } else if cfg!(windows) { + errmsg = if cfg!(windows) { "[..]failed to send request: [..]\n..." } else if cfg!(target_os = "macos") { // macOS is difficult to tests as some builds may use Security.framework, @@ -289,34 +264,8 @@ fn ssh_something_happens() { .file("src/main.rs", "") .build(); - let expected = if cargo_uses_gitoxide() { - // Due to the usage of `ssh` and `ssh.exe` respectively, the messages change. - // This will be adjusted to use `ssh2` to get rid of this dependency and have uniform messaging. - let message = if cfg!(windows) { - // The order of multiple possible messages isn't deterministic within `ssh`, and `gitoxide` detects both - // but gets to report only the first. Thus this test can flip-flop from one version of the error to the other - // and we can't test for that. - // We'd want to test for: - // "[..]ssh: connect to host 127.0.0.1 [..]" - // ssh: connect to host example.org port 22: No route to host - // "[..]banner exchange: Connection to 127.0.0.1 [..]" - // banner exchange: Connection to 127.0.0.1 port 62250: Software caused connection abort - // But since there is no common meaningful sequence or word, we can only match a small telling sequence of characters. - "[..]onnect[..]" - } else { - "[..]Connection [..] by [..]" - }; - format!( - "\ -[UPDATING] git repository `ssh://{addr}/foo/bar` -... -{message} -... -" - ) - } else { - format!( - "\ + let expected = format!( + "\ [UPDATING] git repository `ssh://{addr}/foo/bar` [ERROR] failed to get `bar` as a dependency of package `foo v0.0.1 ([ROOT]/foo)` @@ -326,9 +275,6 @@ Caused by: Caused by: unable to update ssh://{addr}/foo/bar -Caused by: - failed to clone into: [ROOT]/home/.cargo/git/db/bar-[HASH] - Caused by: network failure seems to have happened if a proxy or similar is necessary `net.git-fetch-with-cli` may help here @@ -337,8 +283,7 @@ Caused by: Caused by: failed to start SSH session: Failed getting banner; class=Ssh (23) " - ) - }; + ); p.cargo("check -v") .with_status(101) .with_stderr_data(expected) @@ -367,7 +312,7 @@ fn net_err_suggests_fetch_with_cli() { p.cargo("check -v") .with_status(101) - .with_stderr_data(format!( + .with_stderr_data( "\ [UPDATING] git repository `ssh://needs-proxy.invalid/git` [WARNING] spurious network error (3 tries remaining): [..] resolve [..] needs-proxy.invalid: [..] known[..] @@ -381,26 +326,15 @@ Caused by: Caused by: unable to update ssh://needs-proxy.invalid/git -Caused by: - failed to clone into: [ROOT]/home/.cargo/git/db/git-[HASH] - Caused by: network failure seems to have happened if a proxy or similar is necessary `net.git-fetch-with-cli` may help here https://doc.rust-lang.org/cargo/reference/config.html#netgit-fetch-with-cli Caused by: -{trailer} + failed to resolve address for needs-proxy.invalid: [..] known[..]; class=Net (12) ", - trailer = if cargo_uses_gitoxide() { - r" An IO error occurred when talking to the server - -Caused by: - ssh: Could not resolve hostname needs-proxy.invalid[..]" - } else { - " failed to resolve address for needs-proxy.invalid: [..] known[..]; class=Net (12)" - } - )) + ) .run(); p.change_file( @@ -459,9 +393,6 @@ Caused by: Caused by: unable to update https://foo.bar/foo/bar -Caused by: - failed to clone into: [ROOT]/home/.cargo/git/db/bar-[HASH] - Caused by: failed to authenticate when downloading repository: http://{addr}/foo/bar diff --git a/tests/testsuite/git_sha256.rs b/tests/testsuite/git_sha256.rs new file mode 100644 index 00000000000..dcef4029f15 --- /dev/null +++ b/tests/testsuite/git_sha256.rs @@ -0,0 +1,663 @@ +//! Tests for SHA256 git repository support (`-Zgit=sha256`). + +use cargo_test_support::basic_manifest; +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::str; + +use crate::prelude::*; + +#[cargo_test] +fn sha256_gated_libgit2() { + if cargo_uses_gitoxide() { + eprintln!( + "gitoxide hasn't yet supported sha256; ignore __CARGO_USE_GITOXIDE_INSTEAD_OF_GIT2" + ); + return; + } + + let (git_dep, _repo) = git::new_sha256_repo("dep1", |p| { + p.file("Cargo.toml", &basic_manifest("dep1", "1.0.0")) + .file("src/lib.rs", "") + }); + + let p = project() + .file( + "Cargo.toml", + &format!( + r#" + [package] + name = "foo" + edition = "2021" + + [dependencies] + dep1 = {{ git = '{}' }} + "#, + git_dep.url() + ), + ) + .file("src/lib.rs", "") + .build(); + + p.cargo("check") + .with_status(101) + .with_stderr_data(str![[r#" +[UPDATING] git repository `[ROOTURL]/dep1` +[ERROR] failed to get `dep1` as a dependency of package `foo v0.0.0 ([ROOT]/foo)` + +Caused by: + failed to load source for dependency `dep1` + +Caused by: + unable to update [ROOTURL]/dep1 + +Caused by: + failed to clone into: [ROOT]/home/.cargo/git/db/dep1-[HASH]-sha256 + +Caused by: + SHA256 git repositories require `-Zgit=sha256` to be enabled + +"#]]) + .run(); +} + +#[cargo_test] +fn sha256_gated_with_cached_db() { + if cargo_uses_gitoxide() { + eprintln!( + "gitoxide hasn't yet supported sha256; ignore __CARGO_USE_GITOXIDE_INSTEAD_OF_GIT2" + ); + return; + } + + let (git_dep, _repo) = git::new_sha256_repo("dep1", |p| { + p.file("Cargo.toml", &basic_manifest("dep1", "1.0.0")) + .file("src/lib.rs", "") + }); + + let p = project() + .file( + "Cargo.toml", + &format!( + r#" + [package] + name = "foo" + edition = "2021" + + [dependencies] + dep1 = {{ git = '{}' }} + "#, + git_dep.url() + ), + ) + .file("src/lib.rs", "") + .build(); + + // Populate the SHA256 db cache + p.cargo("check -Zgit=sha256") + .masquerade_as_nightly_cargo(&["git=sha256"]) + .run(); + + // Remove lockfile + // so object format hint must derive from the local git db + std::fs::remove_file(p.root().join("Cargo.lock")).unwrap(); + + p.cargo("check") + .with_status(101) + .with_stderr_data(str![[r#" +[UPDATING] git repository `[ROOTURL]/dep1` +[ERROR] failed to get `dep1` as a dependency of package `foo v0.0.0 ([ROOT]/foo)` + +Caused by: + failed to load source for dependency `dep1` + +Caused by: + unable to update [ROOTURL]/dep1 + +Caused by: + failed to fetch into: [ROOT]/home/.cargo/git/db/dep1-[HASH]-sha256 + +Caused by: + SHA256 git repositories require `-Zgit=sha256` to be enabled + +"#]]) + .run(); +} + +#[cargo_test] +fn sha256_gated_with_lockfile() { + if cargo_uses_gitoxide() { + eprintln!( + "gitoxide hasn't yet supported sha256; ignore __CARGO_USE_GITOXIDE_INSTEAD_OF_GIT2" + ); + return; + } + + let (git_dep, _repo) = git::new_sha256_repo("dep1", |p| { + p.file("Cargo.toml", &basic_manifest("dep1", "1.0.0")) + .file("src/lib.rs", "") + }); + + let p = project() + .file( + "Cargo.toml", + &format!( + r#" + [package] + name = "foo" + edition = "2021" + + [dependencies] + dep1 = {{ git = '{}' }} + "#, + git_dep.url() + ), + ) + .file("src/lib.rs", "") + .build(); + + // Generate a lockfile with a SHA256 rev + p.cargo("check -Zgit=sha256") + .masquerade_as_nightly_cargo(&["git=sha256"]) + .run(); + + // Remove local git db + // so object format hint must derive from the lockfile's locked revision + let git_dir = paths::cargo_home().join("git"); + std::fs::remove_dir_all(&git_dir).unwrap(); + + p.cargo("check") + .with_status(101) + .with_stderr_data(str![[r#" +[UPDATING] git repository `[ROOTURL]/dep1` +[ERROR] failed to get `dep1` as a dependency of package `foo v0.0.0 ([ROOT]/foo)` + +Caused by: + failed to load source for dependency `dep1` + +Caused by: + unable to update [ROOTURL]/dep1#[..] + +Caused by: + failed to clone into: [ROOT]/home/.cargo/git/db/dep1-[HASH]-sha256 + +Caused by: + SHA256 git repositories require `-Zgit=sha256` to be enabled + +"#]]) + .run(); +} + +#[cargo_test] +fn sha256_gated_gitoxide_with_sha256_flag() { + let (git_dep, _repo) = git::new_sha256_repo("dep1", |p| { + p.file("Cargo.toml", &basic_manifest("dep1", "1.0.0")) + .file("src/lib.rs", "") + }); + + let p = project() + .file( + "Cargo.toml", + &format!( + r#" + [package] + name = "foo" + edition = "2021" + + [dependencies] + dep1 = {{ git = '{}' }} + "#, + git_dep.url() + ), + ) + .file("src/lib.rs", "") + .build(); + + p.cargo("check -Zgit=sha256 -Zgitoxide=fetch") + .masquerade_as_nightly_cargo(&["git=sha256", "gitoxide=fetch"]) + .with_status(101) + .with_stderr_data(str![[r#" +[UPDATING] git repository `[ROOTURL]/dep1` +[ERROR] failed to get `dep1` as a dependency of package `foo v0.0.0 ([ROOT]/foo)` + +Caused by: + failed to load source for dependency `dep1` + +Caused by: + unable to update [ROOTURL]/dep1 + +Caused by: + failed to clone into: [ROOT]/home/.cargo/git/db/dep1-[..]-sha256 + +Caused by: + gitoxide does not yet support SHA256 repositories + +"#]]) + .run(); +} + +#[cargo_test] +fn sha256_gated_gitoxide_without_sha256_flag() { + let (git_dep, _repo) = git::new_sha256_repo("dep1", |p| { + p.file("Cargo.toml", &basic_manifest("dep1", "1.0.0")) + .file("src/lib.rs", "") + }); + + let p = project() + .file( + "Cargo.toml", + &format!( + r#" + [package] + name = "foo" + edition = "2021" + + [dependencies] + dep1 = {{ git = '{}' }} + "#, + git_dep.url() + ), + ) + .file("src/lib.rs", "") + .build(); + + // gitoxide doesn't support SHA256 yet — Cargo bails early + // with a clear message before attempting the fetch. + p.cargo("check -Zgitoxide=fetch") + .masquerade_as_nightly_cargo(&["gitoxide=fetch"]) + .with_status(101) + .with_stderr_data(str![[r#" +[UPDATING] git repository `[ROOTURL]/dep1` +[ERROR] failed to get `dep1` as a dependency of package `foo v0.0.0 ([ROOT]/foo)` + +Caused by: + failed to load source for dependency `dep1` + +Caused by: + unable to update [ROOTURL]/dep1 + +Caused by: + failed to clone into: [ROOT]/home/.cargo/git/db/dep1-[HASH]-sha256 + +Caused by: + gitoxide does not yet support SHA256 repositories + +"#]]) + .run(); +} + +#[cargo_test] +fn sha256_basic() { + if cargo_uses_gitoxide() { + eprintln!( + "gitoxide hasn't yet supported sha256; ignore __CARGO_USE_GITOXIDE_INSTEAD_OF_GIT2" + ); + return; + } + + let (git_dep, _repo) = git::new_sha256_repo("dep1", |p| { + p.file("Cargo.toml", &basic_manifest("dep1", "1.0.0")) + .file("src/lib.rs", "") + }); + + let p = project() + .file( + "Cargo.toml", + &format!( + r#" + [package] + name = "foo" + edition = "2021" + + [dependencies] + dep1 = {{ git = '{}' }} + "#, + git_dep.url() + ), + ) + .file("src/lib.rs", "") + .build(); + + p.cargo("check -Zgit=sha256") + .masquerade_as_nightly_cargo(&["git=sha256"]) + .with_stderr_data(str![[r#" +[UPDATING] git repository `[ROOTURL]/dep1` +[LOCKING] 1 package to latest compatible version +[CHECKING] dep1 v1.0.0 ([ROOTURL]/dep1#[..]) +[CHECKING] foo v0.0.0 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) + .run(); +} + +#[cargo_test] +fn sha256_lockfile_and_cache_dir() { + if cargo_uses_gitoxide() { + eprintln!( + "gitoxide hasn't yet supported sha256; ignore __CARGO_USE_GITOXIDE_INSTEAD_OF_GIT2" + ); + return; + } + + let (git_dep, _repo) = git::new_sha256_repo("dep1", |p| { + p.file("Cargo.toml", &basic_manifest("dep1", "1.0.0")) + .file("src/lib.rs", "") + }); + + let p = project() + .file( + "Cargo.toml", + &format!( + r#" + [package] + name = "foo" + edition = "2021" + + [dependencies] + dep1 = {{ git = '{}' }} + "#, + git_dep.url() + ), + ) + .file("src/lib.rs", "") + .build(); + + // Generate a lockfile + p.cargo("check -Zgit=sha256") + .masquerade_as_nightly_cargo(&["git=sha256"]) + .run(); + + // Verify lockfile contains a 64-char SHA256 revision + let lock = p.read_lockfile(); + let rev_line = lock + .lines() + .find(|l| l.contains("dep1") && l.contains('#')) + .expect("lockfile must with a rev"); + let rev = rev_line.rsplit('#').next().unwrap().trim_matches('"'); + assert_eq!(rev.len(), 64, "expect SHA256 revision, got {rev:?}"); + + // Verify cache db ends with `-sha256` + let db_paths: Vec<_> = glob::glob(paths::cargo_home().join("git/db/dep1-*").to_str().unwrap()) + .unwrap() + .map(Result::unwrap) + .collect(); + assert_eq!( + db_paths.len(), + 1, + "expected exactly one db dir: {db_paths:?}" + ); + let db_dir_name = db_paths[0].file_name().unwrap().to_str().unwrap(); + assert!( + db_dir_name.ends_with("-sha256"), + "db dir should end with -sha256, got {db_dir_name:?}" + ); + + // Second build should not re-fetch + p.cargo("check -Zgit=sha256") + .masquerade_as_nightly_cargo(&["git=sha256"]) + .with_stderr_data(str![[r#" +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) + .run(); +} + +#[cargo_test] +fn sha256_dep_with_rev() { + if cargo_uses_gitoxide() { + eprintln!( + "gitoxide hasn't yet supported sha256; ignore __CARGO_USE_GITOXIDE_INSTEAD_OF_GIT2" + ); + return; + } + + let (git_dep, repo) = git::new_sha256_repo("dep1", |p| { + p.file("Cargo.toml", &basic_manifest("dep1", "1.0.0")) + .file("src/lib.rs", "") + }); + + let head = repo.revparse_single("HEAD").unwrap().id().to_string(); + assert_eq!(head.len(), 64, "SHA256 must be 64-chars hex"); + + let p = project() + .file( + "Cargo.toml", + &format!( + r#" + [package] + name = "foo" + edition = "2021" + + [dependencies] + dep1 = {{ git = '{}', rev = '{head}' }} + "#, + git_dep.url(), + ), + ) + .file("src/lib.rs", "") + .build(); + + p.cargo("check -Zgit=sha256") + .masquerade_as_nightly_cargo(&["git=sha256"]) + .with_stderr_data(str![[r#" +[UPDATING] git repository `[ROOTURL]/dep1` +[LOCKING] 1 package to latest compatible version +[CHECKING] dep1 v1.0.0 ([ROOTURL]/dep1?rev=[..]#[..]) +[CHECKING] foo v0.0.0 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) + .run(); +} + +#[cargo_test] +fn sha256_update_dep() { + if cargo_uses_gitoxide() { + eprintln!( + "gitoxide hasn't yet supported sha256; ignore __CARGO_USE_GITOXIDE_INSTEAD_OF_GIT2" + ); + return; + } + + let (git_dep, repo) = git::new_sha256_repo("dep1", |p| { + p.file("Cargo.toml", &basic_manifest("dep1", "1.0.0")) + .file("src/lib.rs", "") + }); + + let p = project() + .file( + "Cargo.toml", + &format!( + r#" + [package] + name = "foo" + edition = "2021" + + [dependencies] + dep1 = {{ git = '{}' }} + "#, + git_dep.url() + ), + ) + .file("src/lib.rs", "") + .build(); + + p.cargo("check -Zgit=sha256") + .masquerade_as_nightly_cargo(&["git=sha256"]) + .run(); + + // Modify dep and commit + git_dep.change_file("src/lib.rs", "// updated"); + git::add(&repo); + git::commit(&repo); + + // Update and rebuild + p.cargo("update -Zgit=sha256") + .masquerade_as_nightly_cargo(&["git=sha256"]) + .with_stderr_data(str![[r#" +[UPDATING] git repository `[ROOTURL]/dep1` +[LOCKING] 1 package to latest compatible version +[UPDATING] dep1 v1.0.0 ([ROOTURL]/dep1#[..]) -> #[..] + +"#]]) + .run(); + + p.cargo("check -Zgit=sha256") + .masquerade_as_nightly_cargo(&["git=sha256"]) + .with_stderr_data(str![[r#" +[CHECKING] dep1 v1.0.0 ([ROOTURL]/dep1#[..]) +[CHECKING] foo v0.0.0 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) + .run(); +} + +#[cargo_test] +fn sha256_offline_with_cached_db() { + if cargo_uses_gitoxide() { + eprintln!( + "gitoxide hasn't yet supported sha256; ignore __CARGO_USE_GITOXIDE_INSTEAD_OF_GIT2" + ); + return; + } + + let (git_dep, _repo) = git::new_sha256_repo("dep1", |p| { + p.file("Cargo.toml", &basic_manifest("dep1", "1.0.0")) + .file("src/lib.rs", "") + }); + + let p = project() + .file( + "Cargo.toml", + &format!( + r#" + [package] + name = "foo" + edition = "2021" + + [dependencies] + dep1 = {{ git = '{}' }} + "#, + git_dep.url() + ), + ) + .file("src/lib.rs", "") + .build(); + + // populates cache first + p.cargo("check -Zgit=sha256") + .masquerade_as_nightly_cargo(&["git=sha256"]) + .run(); + + // offline works + p.cargo("check -Zgit=sha256 --frozen") + .masquerade_as_nightly_cargo(&["git=sha256"]) + .with_stderr_data(str![[r#" +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) + .run(); +} + +#[cargo_test] +fn sha256_and_sha1_deps_coexist() { + if cargo_uses_gitoxide() { + eprintln!( + "gitoxide hasn't yet supported sha256; ignore __CARGO_USE_GITOXIDE_INSTEAD_OF_GIT2" + ); + return; + } + + let (sha256_dep, _repo256) = git::new_sha256_repo("dep256", |p| { + p.file("Cargo.toml", &basic_manifest("dep256", "1.0.0")) + .file("src/lib.rs", "") + }); + + let sha1_dep = git::new("dep1", |p| { + p.file("Cargo.toml", &basic_manifest("dep1", "1.0.0")) + .file("src/lib.rs", "") + }); + + let p = project() + .file( + "Cargo.toml", + &format!( + r#" + [package] + name = "foo" + edition = "2021" + + [dependencies] + dep256 = {{ git = '{}' }} + dep1 = {{ git = '{}' }} + "#, + sha256_dep.url(), + sha1_dep.url() + ), + ) + .file("src/lib.rs", "") + .build(); + + p.cargo("check -Zgit=sha256") + .masquerade_as_nightly_cargo(&["git=sha256"]) + .with_stderr_data( + str![[r#" +[UPDATING] git repository `[ROOTURL]/dep1` +[UPDATING] git repository `[ROOTURL]/dep256` +[LOCKING] 2 packages to latest compatible versions +[CHECKING] dep256 v1.0.0 ([ROOTURL]/dep256#[..]) +[CHECKING] dep1 v1.0.0 ([ROOTURL]/dep1#[..]) +[CHECKING] foo v0.0.0 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]] + .unordered(), + ) + .run(); +} + +#[cargo_test] +fn sha256_fetch_with_cli() { + let (git_dep, _repo) = git::new_sha256_repo("dep1", |p| { + p.file("Cargo.toml", &basic_manifest("dep1", "1.0.0")) + .file("src/lib.rs", "") + }); + + let p = project() + .file( + "Cargo.toml", + &format!( + r#" + [package] + name = "foo" + edition = "2021" + + [dependencies] + dep1 = {{ git = '{}' }} + "#, + git_dep.url() + ), + ) + .file("src/lib.rs", "") + .build(); + + p.cargo("check -v -Zgit=sha256") + .env("CARGO_NET_GIT_FETCH_WITH_CLI", "true") + .masquerade_as_nightly_cargo(&["git=sha256"]) + .with_stderr_data(str![[r#" +[UPDATING] git repository `[ROOTURL]/dep1` +[RUNNING] `git fetch --no-tags --verbose --force --update-head-ok [..][ROOTURL]/dep1[..] [..]+HEAD:refs/remotes/origin/HEAD[..]` +... +[CHECKING] dep1 v1.0.0 ([ROOTURL]/dep1#[..]) +[RUNNING] `rustc --crate-name dep1 [..] [ROOT]/home/.cargo/git/checkouts/dep1-[HASH]-sha256/[..]/src/lib.rs [..]` +[CHECKING] foo v0.0.0 ([ROOT]/foo) +[RUNNING] `rustc --crate-name foo [..]` +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) + .run(); +} diff --git a/tests/testsuite/https.rs b/tests/testsuite/https.rs index c4efa733888..d44be819089 100644 --- a/tests/testsuite/https.rs +++ b/tests/testsuite/https.rs @@ -55,9 +55,6 @@ Caused by: Caused by: unable to update https://127.0.0.1:[..]/repos/bar.git -Caused by: - failed to clone into: [ROOT]/home/.cargo/git/db/bar-[HASH] - Caused by: network failure seems to have happened if a proxy or similar is necessary `net.git-fetch-with-cli` may help here diff --git a/tests/testsuite/main.rs b/tests/testsuite/main.rs index 16971afb716..da2587d2330 100644 --- a/tests/testsuite/main.rs +++ b/tests/testsuite/main.rs @@ -108,6 +108,7 @@ mod generate_lockfile; mod git; mod git_auth; mod git_gc; +mod git_sha256; mod git_shallow; mod glob_targets; mod global_cache_tracker; diff --git a/tests/testsuite/offline.rs b/tests/testsuite/offline.rs index cd5d31c9b96..cb1119c5de7 100644 --- a/tests/testsuite/offline.rs +++ b/tests/testsuite/offline.rs @@ -300,6 +300,7 @@ fn cargo_compile_forbird_git_httpsrepo_offline() { .build(); p.cargo("check --offline").with_status(101).with_stderr_data(str![[r#" +[UPDATING] git repository `https://github.com/some_user/dep1.git` [ERROR] failed to get `dep1` as a dependency of package `foo v0.5.0 ([ROOT]/foo)` Caused by: diff --git a/tests/testsuite/patch.rs b/tests/testsuite/patch.rs index bd14ef67dd6..6c4e971faff 100644 --- a/tests/testsuite/patch.rs +++ b/tests/testsuite/patch.rs @@ -394,9 +394,6 @@ fn patch_to_git_pull_request() { Caused by: unable to update https://github.com/rust-lang/does-not-exist/pull/123 -Caused by: - failed to clone into: [ROOT]/home/.cargo/git/db/123-[HASH] - Caused by: network failure seems to have happened if a proxy or similar is necessary `net.git-fetch-with-cli` may help here diff --git a/tests/testsuite/ssh.rs b/tests/testsuite/ssh.rs index b1f2e0faedf..168c9ddb168 100644 --- a/tests/testsuite/ssh.rs +++ b/tests/testsuite/ssh.rs @@ -11,7 +11,6 @@ use std::path::PathBuf; use crate::prelude::*; use cargo_test_support::containers::{Container, ContainerHandle, MkFile}; -use cargo_test_support::git::cargo_uses_gitoxide; use cargo_test_support::{Project, paths, process, project, str}; fn ssh_repo_url(container: &ContainerHandle, name: &str) -> String { @@ -141,9 +140,6 @@ Caused by: Caused by: unable to update ssh://testuser@127.0.0.1:[..]/repos/bar.git -Caused by: - failed to clone into: [ROOT]/home/.cargo/git/db/bar-[HASH] - Caused by: [ERROR] unknown SSH host key The SSH host key for `[127.0.0.1]:[..]` is not known and cannot be validated. @@ -233,9 +229,6 @@ Caused by: Caused by: unable to update ssh://testuser@127.0.0.1:[..]/repos/bar.git -Caused by: - failed to clone into: [ROOT]/home/.cargo/git/db/bar-[HASH] - Caused by: [ERROR] unknown SSH host key The SSH host key for `[127.0.0.1]:[..]` is not known and cannot be validated. @@ -346,9 +339,6 @@ Caused by: Caused by: unable to update ssh://testuser@127.0.0.1:{port}/repos/bar.git -Caused by: - failed to clone into: [ROOT]/home/.cargo/git/db/bar-[HASH] - Caused by: [ERROR] SSH host key has changed for `[127.0.0.1]:{port}` ********************************* @@ -420,19 +410,11 @@ fn invalid_github_key() { .build(); p.cargo("fetch") .with_status(101) - .with_stderr_data(if cargo_uses_gitoxide() { - str![[r#" -... - git@github.com: Permission denied (publickey). -... -"#]] - } else { - str![[r#" + .with_stderr_data(str![[r#" ... [ERROR] SSH host key has changed for `github.com` ... -"#]] - }) +"#]]) .run(); } @@ -465,37 +447,7 @@ fn bundled_github_works() { ) .file("src/lib.rs", "") .build(); - let expected = if cargo_uses_gitoxide() { - str![[r#" -[UPDATING] git repository `ssh://git@github.com/rust-lang/bitflags.git` -[ERROR] failed to get `bitflags` as a dependency of package `foo v0.1.0 ([ROOT]/foo)` - -Caused by: - failed to load source for dependency `bitflags` - -Caused by: - unable to update ssh://git@github.com/rust-lang/bitflags.git?tag=1.3.2 - -Caused by: - failed to clone into: [ROOT]/home/.cargo/git/db/bitflags-[HASH] - -Caused by: - failed to authenticate when downloading repository - - * attempted to find username/password via `credential.helper`, but maybe the found credentials were incorrect - - if the git CLI succeeds then `net.git-fetch-with-cli` may help here - https://doc.rust-lang.org/cargo/reference/config.html#netgit-fetch-with-cli - -Caused by: -[CREDENTIAL]s provided for "ssh://git@github.com/rust-lang/bitflags.git" were not accepted by the remote - -Caused by: - git@github.com: Permission denied (publickey). - -"#]] - } else { - str![[r#" + let expected = str![[r#" [UPDATING] git repository `ssh://git@github.com/rust-lang/bitflags.git` [ERROR] failed to get `bitflags` as a dependency of package `foo v0.1.0 ([ROOT]/foo)` @@ -505,9 +457,6 @@ Caused by: Caused by: unable to update ssh://git@github.com/rust-lang/bitflags.git?tag=1.3.2 -Caused by: - failed to clone into: [ROOT]/home/.cargo/git/db/bitflags-[HASH] - Caused by: failed to authenticate when downloading repository @@ -519,16 +468,14 @@ Caused by: Caused by: no authentication methods succeeded -"#]] - }; +"#]]; p.cargo("fetch") .env("SSH_AUTH_SOCK", &bogus_auth_sock) .with_status(101) .with_stderr_data(expected) .run(); - let expected = if cargo_uses_gitoxide() { - str![[r#" + let expected = str![[r#" [UPDATING] git repository `ssh://git@github.com:22/rust-lang/bitflags.git` [ERROR] failed to get `bitflags` as a dependency of package `foo v0.1.0 ([ROOT]/foo)` @@ -538,38 +485,6 @@ Caused by: Caused by: unable to update ssh://git@github.com:22/rust-lang/bitflags.git?tag=1.3.2 -Caused by: - failed to clone into: [ROOT]/home/.cargo/git/db/bitflags-[HASH] - -Caused by: - failed to authenticate when downloading repository - - * attempted to find username/password via `credential.helper`, but maybe the found credentials were incorrect - - if the git CLI succeeds then `net.git-fetch-with-cli` may help here - https://doc.rust-lang.org/cargo/reference/config.html#netgit-fetch-with-cli - -Caused by: -[CREDENTIAL]s provided for "ssh://git@github.com:22/rust-lang/bitflags.git" were not accepted by the remote - -Caused by: - git@github.com: Permission denied (publickey). - -"#]] - } else { - str![[r#" -[UPDATING] git repository `ssh://git@github.com:22/rust-lang/bitflags.git` -[ERROR] failed to get `bitflags` as a dependency of package `foo v0.1.0 ([ROOT]/foo)` - -Caused by: - failed to load source for dependency `bitflags` - -Caused by: - unable to update ssh://git@github.com:22/rust-lang/bitflags.git?tag=1.3.2 - -Caused by: - failed to clone into: [ROOT]/home/.cargo/git/db/bitflags-[HASH] - Caused by: failed to authenticate when downloading repository @@ -581,8 +496,7 @@ Caused by: Caused by: no authentication methods succeeded -"#]] - }; +"#]]; // Explicit :22 should also work with bundled. p.change_file(