diff --git a/src/cargo/ops/vendor.rs b/src/cargo/ops/vendor.rs index f3d0883bd9e..35d0e0c9417 100644 --- a/src/cargo/ops/vendor.rs +++ b/src/cargo/ops/vendor.rs @@ -207,8 +207,10 @@ fn sync( let dst = canonical_destination.join(&dst_name); to_remove.remove(&dst); let cksum = dst.join(".cargo-checksum.json"); - if dir_has_version_suffix && cksum.exists() { - // Always re-copy directory without version suffix in case the version changed + // Registries are the only immutable sources, + // path and git dependencies' versions cannot be trusted to mean "no change" + if dir_has_version_suffix && id.source_id().is_registry() && cksum.exists() { + // Don't re-copy directory with version suffix in case it comes from a registry continue; } diff --git a/tests/testsuite/vendor.rs b/tests/testsuite/vendor.rs index 7f7ef2b24a6..39651268b3c 100644 --- a/tests/testsuite/vendor.rs +++ b/tests/testsuite/vendor.rs @@ -1568,6 +1568,67 @@ path = [..] ); } +#[cargo_test] +fn git_update_rev() { + let (git_project, git_repo) = git::new_repo("git", |p| { + p.file("Cargo.toml", &basic_manifest("a", "0.1.0")) + .file("src/lib.rs", "") + }); + let url = git_project.url(); + let ref_1 = "initial"; + let ref_2 = "update"; + + git::tag(&git_repo, ref_1); + + git_project.change_file("src/lib.rs", "pub fn f() {}"); + git::add(&git_repo); + git::commit(&git_repo); + git::tag(&git_repo, ref_2); + + let p = project() + .file( + "Cargo.toml", + &format!( + r#" + [package] + name = "foo" + version = "0.1.0" + + [dependencies] + a = {{ git = '{url}', rev = '{ref_1}' }} + "# + ), + ) + .file("src/lib.rs", "") + .build(); + + p.cargo("vendor --respect-source-config --versioned-dirs") + .run(); + + let lib = p.read_file("vendor/a-0.1.0/src/lib.rs"); + assert_e2e().eq(lib, ""); + + p.change_file( + "Cargo.toml", + &format!( + r#" + [package] + name = "foo" + version = "0.1.0" + + [dependencies] + a = {{ git = '{url}', rev = '{ref_2}' }} + "# + ), + ); + + p.cargo("vendor --respect-source-config --versioned-dirs") + .run(); + + let lib = p.read_file("vendor/a-0.1.0/src/lib.rs"); + assert_e2e().eq(lib, "pub fn f() {}"); +} + #[cargo_test] fn depend_on_vendor_dir_not_deleted() { let p = project()