Repository: rust-lang/cargo (rust)

Issue:
Failed to `cargo package --allow-dirty` for repo with no commit
### Problem

<https://github.com/rust-lang/cargo/pull/13960> unconditionally checks VCS status when doing `cargo package`.
However, a VCS (Git specifically) repository could have no commit history, and then it fails `cargo package` with such an error:

```
cargo +beta package --allow-dirty
warning: manifest has no description, license, license-file, documentation, homepage or repository.
See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info.
error: revspec 'HEAD' not found; class=Reference (4); code=NotFound (-3)
```

### Steps

1. `cargo new foo`
2. cd foo
3. `cargo package --allow-dirty`

### Possible Solution(s)

The current `.cargo_vcs_info.json` format looks like:

```json
{
 "git": {
   "sha1": "aac20b6e7e543e6dd4118b246c77225e3a3a1302",
   "dirty": true
 },
 "path_in_vcs": ""
}
```

If the `HEAD` hash cannot be determined, should we instead emit a JSON like

```json
{
 "git": {
   "dirty": true
 },
 "path_in_vcs": ""
}
```

or just don't generate `.cargo_vcs_info.json` at all?

### Notes

_No response_

### Version

```text
cargo 1.81.0-beta.2 (a2b58c3da 2024-07-16)
release: 1.81.0-beta.2
commit-hash: a2b58c3dad4d554ba01ed6c45c41ff85390560f2
commit-date: 2024-07-16
```


<!-- TRIAGEBOT_START -->

<!-- TRIAGEBOT_ASSIGN_START -->

<!-- TRIAGEBOT_ASSIGN_DATA_START$${"user":"linyihai"}$$TRIAGEBOT_ASSIGN_DATA_END -->

<!-- TRIAGEBOT_ASSIGN_END -->
<!-- TRIAGEBOT_END -->

Pull request:
Fix: `cargo package` failed on bare commit git repo.
### What does this PR try to resolve?
Fixes #14354 

This approach chose to not generate a `.cargo_vcs_info.json` for bare commit git repo.

### How should we test and review this PR?
Compare the test changes before and after the two commits

### Additional information




Patch:
diff --git a/src/cargo/core/compiler/standard_lib.rs b/src/cargo/core/compiler/standard_lib.rs
index 92b3474d3..8b24cf7cd 100644
--- a/src/cargo/core/compiler/standard_lib.rs
+++ b/src/cargo/core/compiler/standard_lib.rs
@@ -6,12 +6,13 @@ use crate::core::compiler::{CompileKind, CompileMode, RustcTargetData, Unit};
 use crate::core::profiles::{Profiles, UnitFor};
 use crate::core::resolver::features::{CliFeatures, FeaturesFor, ResolvedFeatures};
 use crate::core::resolver::HasDevUnits;
-use crate::core::{PackageId, PackageSet, Resolve, Workspace};
+use crate::core::{Dependency, PackageId, PackageSet, Resolve, SourceId, Workspace};
 use crate::ops::{self, Packages};
 use crate::util::errors::CargoResult;
 use crate::GlobalContext;
 use std::collections::{HashMap, HashSet};
 use std::path::PathBuf;
+use std::rc::Rc;
 
 use super::BuildConfig;
 
@@ -73,11 +74,60 @@ pub fn resolve_std<'gctx>(
     }
 
     let src_path = detect_sysroot_src_path(target_data)?;
-    let std_ws_manifest_path = src_path.join("library").join("Cargo.toml");
+    let to_patch = [
+        "rustc-std-workspace-core",
+        "rustc-std-workspace-alloc",
+        "rustc-std-workspace-std",
+    ];
+    let patches = to_patch
+        .iter()
+        .map(|&name| {
+            let source_path = SourceId::for_path(&src_path.join("library").join(name))?;
+            let dep = Dependency::parse(name, None, source_path)?;
+            Ok(dep)
+        })
+        .collect::<CargoResult<Vec<_>>>()?;
+    let crates_io_url = crate::sources::CRATES_IO_INDEX.parse().unwrap();
+    let patch = HashMap::from([(crates_io_url, patches)]);
+    let members = vec![
+        String::from("library/std"),
+        String::from("library/core"),
+        String::from("library/alloc"),
+        String::from("library/sysroot"),
+    ];
+    let ws_config = crate::core::WorkspaceConfig::Root(crate::core::WorkspaceRootConfig::new(
+        &src_path,
+        &Some(members),
+        /*default_members*/ &None,
+        /*exclude*/ &None,
+        /*inheritable*/ &None,
+        /*custom_metadata*/ &None,
+    ));
+    let virtual_manifest = crate::core::VirtualManifest::new(
+        Rc::default(),
+        Rc::new(toml_edit::ImDocument::parse("".to_owned()).expect("empty is valid TOML")),
+        Rc::default(),
+        Rc::default(),
+        /*replace*/ Vec::new(),
+        patch,
+        ws_config,
+        crate::core::Features::default(),
+        None,
+    );
+
     let gctx = ws.gctx();
+    // This is a delicate hack. In order for features to resolve correctly,
+    // the resolver needs to run a specific "current" member of the workspace.
+    // Thus, in order to set the features for `std`, we need to set `sysroot`
+    // to be the "current" member. `sysroot` is the root, and all other
+    // standard library crates are dependencies from there. Since none of the
+    // other crates need to alter their features, this should be fine, for
+    // now. Perhaps in the future features will be decoupled from the resolver
+    // and it will be easier to control feature selection.
+    let current_manifest = src_path.join("library/sysroot/Cargo.toml");
     // TODO: Consider doing something to enforce --locked? Or to prevent the
     // lock file from being written, such as setting ephemeral.
-    let mut std_ws = Workspace::new(&std_ws_manifest_path, gctx)?;
+    let mut std_ws = Workspace::new_virtual(src_path, current_manifest, virtual_manifest, gctx)?;
     // Don't require optional dependencies in this workspace, aka std's own
     // `[dev-dependencies]`. No need for us to generate a `Resolve` which has
     // those included because we'll never use them anyway.
diff --git a/src/cargo/core/workspace.rs b/src/cargo/core/workspace.rs
index 3a2588e41..0e538c698 100644
--- a/src/cargo/core/workspace.rs
+++ b/src/cargo/core/workspace.rs
@@ -244,6 +244,25 @@ impl<'gctx> Workspace<'gctx> {
         }
     }
 
+    pub fn new_virtual(
+        root_path: PathBuf,
+        current_manifest: PathBuf,
+        manifest: VirtualManifest,
+        gctx: &'gctx GlobalContext,
+    ) -> CargoResult<Workspace<'gctx>> {
+        let mut ws = Workspace::new_default(current_manifest, gctx);
+        ws.root_manifest = Some(root_path.join("Cargo.toml"));
+        ws.target_dir = gctx.target_dir()?;
+        ws.packages
+            .packages
+            .insert(root_path, MaybePackage::Virtual(manifest));
+        ws.find_members()?;
+        ws.set_resolve_behavior()?;
+        // TODO: validation does not work because it walks up the directory
+        // tree looking for the root which is a fake file that doesn't exist.
+        Ok(ws)
+    }
+
     /// Creates a "temporary workspace" from one package which only contains
     /// that package.
     ///
diff --git a/src/cargo/ops/cargo_package.rs b/src/cargo/ops/cargo_package.rs
index fa9f7687b..a25941ed6 100644
--- a/src/cargo/ops/cargo_package.rs
+++ b/src/cargo/ops/cargo_package.rs
@@ -185,76 +185,44 @@ fn infer_registry(
     pkgs: &[&Package],
     reg_or_index: Option<RegistryOrIndex>,
 ) -> CargoResult<SourceId> {
-    let reg_or_index = match reg_or_index {
-        Some(r) => r,
-        None => {
-            if pkgs[1..].iter().all(|p| p.publish() == pkgs[0].publish()) {
-                // If all packages have the same publish settings, we take that as the default.
-                match pkgs[0].publish().as_deref() {
-                    Some([unique_pkg_reg]) => RegistryOrIndex::Registry(unique_pkg_reg.to_owned()),
-                    None | Some([]) => RegistryOrIndex::Registry(CRATES_IO_REGISTRY.to_owned()),
-                    Some([reg, ..]) if pkgs.len() == 1 => {
-                        // For backwards compatibility, avoid erroring if there's only one package.
-                        // The registry doesn't affect packaging in this case.
-                        RegistryOrIndex::Registry(reg.to_owned())
-                    }
-                    Some(regs) => {
-                        let mut regs: Vec<_> = regs.iter().map(|s| format!("\"{}\"", s)).collect();
-                        regs.sort();
-                        regs.dedup();
-                        // unwrap: the match block ensures that there's more than one reg.
-                        let (last_reg, regs) = regs.split_last().unwrap();
-                        bail!(
-                            "--registry is required to disambiguate between {} or {} registries",
-                            regs.join(", "),
-                            last_reg
-                        )
-                    }
-                }
-            } else {
-                let common_regs = pkgs
-                    .iter()
-                    // `None` means "all registries", so drop them instead of including them
-                    // in the intersection.
-                    .filter_map(|p| p.publish().as_deref())
-                    .map(|p| p.iter().collect::<HashSet<_>>())
-                    .reduce(|xs, ys| xs.intersection(&ys).cloned().collect())
-                    .unwrap_or_default();
-                if common_regs.is_empty() {
-                    bail!("conflicts between `package.publish` fields in the selected packages");
-                } else {
-                    bail!(
-                        "--registry is required because not all `package.publish` settings agree",
-                    );
-                }
-            }
+    let publish_registry = if let Some(RegistryOrIndex::Registry(registry)) = reg_or_index.as_ref()
+    {
+        Some(registry.clone())
+    } else if let Some([first_pkg_reg]) = pkgs[0].publish().as_deref() {
+        // If no registry is specified in the command, but all of the packages
+        // to publish have the same, unique allowed registry, push to that one.
+        if pkgs[1..].iter().all(|p| p.publish() == pkgs[0].publish()) {
+            Some(first_pkg_reg.clone())
+        } else {
+            None
         }
+    } else {
+        None
     };
 
     // Validate the registry against the packages' allow-lists. For backwards compatibility, we
     // skip this if only a single package is being published (because in that case the registry
     // doesn't affect the packaging step).
     if pkgs.len() > 1 {
-        if let RegistryOrIndex::Registry(reg_name) = &reg_or_index {
-            for pkg in pkgs {
-                if let Some(allowed) = pkg.publish().as_ref() {
-                    if !allowed.iter().any(|a| a == reg_name) {
-                        bail!(
+        let reg_name = publish_registry.as_deref().unwrap_or(CRATES_IO_REGISTRY);
+        for pkg in pkgs {
+            if let Some(allowed) = pkg.publish().as_ref() {
+                if !allowed.iter().any(|a| a == reg_name) {
+                    bail!(
                         "`{}` cannot be packaged.\n\
                          The registry `{}` is not listed in the `package.publish` value in Cargo.toml.",
                         pkg.name(),
                         reg_name
                     );
-                    }
                 }
             }
         }
     }
 
     let sid = match reg_or_index {
-        RegistryOrIndex::Index(url) => SourceId::for_registry(&url)?,
-        RegistryOrIndex::Registry(reg) if reg == CRATES_IO_REGISTRY => SourceId::crates_io(gctx)?,
-        RegistryOrIndex::Registry(reg) => SourceId::alt_registry(gctx, &reg)?,
+        None => SourceId::crates_io(gctx)?,
+        Some(RegistryOrIndex::Registry(r)) => SourceId::alt_registry(gctx, &r)?,
+        Some(RegistryOrIndex::Index(url)) => SourceId::for_registry(&url)?,
     };
 
     // Load source replacements that are built-in to Cargo.
@@ -775,10 +743,12 @@ fn check_repo_state(
                         .and_then(|p| p.to_str())
                         .unwrap_or("")
                         .replace("\\", "/");
-                    return Ok(Some(VcsInfo {
-                        git: git(p, src_files, &repo, &opts)?,
-                        path_in_vcs,
-                    }));
+                    let Some(git) = git(p, src_files, &repo, &opts)? else {
+                        // If the git repo lacks essensial field like `sha1`, and since this field exists from the beginning,
+                        // then don't generate the corresponding file in order to maintain consistency with past behavior.
+                        return Ok(None);
+                    };
+                    return Ok(Some(VcsInfo { git, path_in_vcs }));
                 }
             }
             gctx.shell().verbose(|shell| {
@@ -804,7 +774,7 @@ fn check_repo_state(
         src_files: &[PathBuf],
         repo: &git2::Repository,
         opts: &PackageOpts<'_>,
-    ) -> CargoResult<GitVcsInfo> {
+    ) -> CargoResult<Option<GitVcsInfo>> {
         // This is a collection of any dirty or untracked files. This covers:
         // - new/modified/deleted/renamed/type change (index or worktree)
         // - untracked files (which are "new" worktree files)
@@ -831,11 +801,16 @@ fn check_repo_state(
             .collect();
         let dirty = !dirty_src_files.is_empty();
         if !dirty || opts.allow_dirty {
+            // Must check whetherthe repo has no commit firstly, otherwise `revparse_single` would fail on bare commit repo.
+            // Due to lacking the `sha1` field, it's better not record the `GitVcsInfo` for consistency.
+            if repo.is_empty()? {
+                return Ok(None);
+            }
             let rev_obj = repo.revparse_single("HEAD")?;
-            Ok(GitVcsInfo {
+            Ok(Some(GitVcsInfo {
                 sha1: rev_obj.id().to_string(),
                 dirty,
-            })
+            }))
         } else {
             anyhow::bail!(
                 "{} files in the working directory contain changes that were \
diff --git a/src/cargo/ops/vendor.rs b/src/cargo/ops/vendor.rs
index 6cd27b288..a060b3cd6 100644
--- a/src/cargo/ops/vendor.rs
+++ b/src/cargo/ops/vendor.rs
@@ -221,7 +221,7 @@ fn sync(
         let pathsource = PathSource::new(src, id.source_id(), gctx);
         let paths = pathsource.list_files(pkg)?;
         let mut map = BTreeMap::new();
-        cp_sources(pkg, src, &paths, &dst, &mut map, &mut tmp_buf, gctx)
+        cp_sources(pkg, src, &paths, &dst, &mut map, &mut tmp_buf)
             .with_context(|| format!("failed to copy over vendored sources for: {}", id))?;
 
         // Finally, emit the metadata about this package
@@ -317,7 +317,6 @@ fn cp_sources(
     dst: &Path,
     cksums: &mut BTreeMap<String, String>,
     tmp_buf: &mut [u8],
-    gctx: &GlobalContext,
 ) -> CargoResult<()> {
     for p in paths {
         let relative = p.strip_prefix(&src).unwrap();
@@ -361,12 +360,7 @@ fn cp_sources(
         let cksum = if dst.file_name() == Some(OsStr::new("Cargo.toml"))
             && pkg.package_id().source_id().is_git()
         {
-            let packaged_files = paths
-                .iter()
-                .map(|p| p.strip_prefix(src).unwrap().to_owned())
-                .collect::<Vec<_>>();
-            let vendored_pkg = prepare_for_vendor(pkg, &packaged_files, gctx)?;
-            let contents = vendored_pkg.manifest().to_normalized_contents()?;
+            let contents = pkg.manifest().to_normalized_contents()?;
             copy_and_checksum(
                 &dst,
                 &mut dst_opts,
@@ -398,119 +392,6 @@ fn cp_sources(
     Ok(())
 }
 
-/// HACK: Perform the bare minimum of `prepare_for_publish` needed for #14348.
-///
-/// There are parts of `prepare_for_publish` that could be directly useful (e.g. stripping
-/// `[workspace]`) while other parts that require other filesystem operations (moving the README
-/// file) and ideally we'd reuse `cargo package` code to take care of all of this for us.
-fn prepare_for_vendor(
-    me: &Package,
-    packaged_files: &[PathBuf],
-    gctx: &GlobalContext,
-) -> CargoResult<Package> {
-    let contents = me.manifest().contents();
-    let document = me.manifest().document();
-    let original_toml = prepare_toml_for_vendor(
-        me.manifest().normalized_toml().clone(),
-        packaged_files,
-        gctx,
-    )?;
-    let normalized_toml = original_toml.clone();
-    let features = me.manifest().unstable_features().clone();
-    let workspace_config = me.manifest().workspace_config().clone();
-    let source_id = me.package_id().source_id();
-    let mut warnings = Default::default();
-    let mut errors = Default::default();
-    let manifest = crate::util::toml::to_real_manifest(
-        contents.to_owned(),
-        document.clone(),
-        original_toml,
-        normalized_toml,
-        features,
-        workspace_config,
-        source_id,
-        me.manifest_path(),
-        gctx,
-        &mut warnings,
-        &mut errors,
-    )?;
-    let new_pkg = Package::new(manifest, me.manifest_path());
-    Ok(new_pkg)
-}
-
-fn prepare_toml_for_vendor(
-    mut me: cargo_util_schemas::manifest::TomlManifest,
-    packaged_files: &[PathBuf],
-    gctx: &GlobalContext,
-) -> CargoResult<cargo_util_schemas::manifest::TomlManifest> {
-    let package = me
-        .package
-        .as_mut()
-        .expect("venedored manifests must have packages");
-    if let Some(cargo_util_schemas::manifest::StringOrBool::String(path)) = &package.build {
-        let path = paths::normalize_path(Path::new(path));
-        let included = packaged_files.contains(&path);
-        let build = if included {
-            let path = path
-                .into_os_string()
-                .into_string()
-                .map_err(|_err| anyhow::format_err!("non-UTF8 `package.build`"))?;
-            let path = crate::util::toml::normalize_path_string_sep(path);
-            cargo_util_schemas::manifest::StringOrBool::String(path)
-        } else {
-            gctx.shell().warn(format!(
-                "ignoring `package.build` as `{}` is not included in the published package",
-                path.display()
-            ))?;
-            cargo_util_schemas::manifest::StringOrBool::Bool(false)
-        };
-        package.build = Some(build);
-    }
-
-    let lib = if let Some(target) = &me.lib {
-        crate::util::toml::prepare_target_for_publish(
-            target,
-            Some(packaged_files),
-            "library",
-            gctx,
-        )?
-    } else {
-        None
-    };
-    let bin = crate::util::toml::prepare_targets_for_publish(
-        me.bin.as_ref(),
-        Some(packaged_files),
-        "binary",
-        gctx,
-    )?;
-    let example = crate::util::toml::prepare_targets_for_publish(
-        me.example.as_ref(),
-        Some(packaged_files),
-        "example",
-        gctx,
-    )?;
-    let test = crate::util::toml::prepare_targets_for_publish(
-        me.test.as_ref(),
-        Some(packaged_files),
-        "test",
-        gctx,
-    )?;
-    let bench = crate::util::toml::prepare_targets_for_publish(
-        me.bench.as_ref(),
-        Some(packaged_files),
-        "benchmark",
-        gctx,
-    )?;
-
-    me.lib = lib;
-    me.bin = bin;
-    me.example = example;
-    me.test = test;
-    me.bench = bench;
-
-    Ok(me)
-}
-
 fn copy_and_checksum<T: Read>(
     dst_path: &Path,
     dst_opts: &mut OpenOptions,
diff --git a/src/cargo/util/toml/mod.rs b/src/cargo/util/toml/mod.rs
index 172a4a736..353189917 100644
--- a/src/cargo/util/toml/mod.rs
+++ b/src/cargo/util/toml/mod.rs
@@ -1086,7 +1086,7 @@ fn deprecated_ws_default_features(
 }
 
 #[tracing::instrument(skip_all)]
-pub fn to_real_manifest(
+fn to_real_manifest(
     contents: String,
     document: toml_edit::ImDocument<String>,
     original_toml: manifest::TomlManifest,
@@ -2889,7 +2889,7 @@ fn prepare_toml_for_publish(
     }
 }
 
-pub fn prepare_targets_for_publish(
+fn prepare_targets_for_publish(
     targets: Option<&Vec<manifest::TomlTarget>>,
     packaged_files: Option<&[PathBuf]>,
     context: &str,
@@ -2915,7 +2915,7 @@ pub fn prepare_targets_for_publish(
     }
 }
 
-pub fn prepare_target_for_publish(
+fn prepare_target_for_publish(
     target: &manifest::TomlTarget,
     packaged_files: Option<&[PathBuf]>,
     context: &str,
@@ -2950,7 +2950,7 @@ fn normalize_path_sep(path: PathBuf, context: &str) -> CargoResult<PathBuf> {
     Ok(path.into())
 }
 
-pub fn normalize_path_string_sep(path: String) -> String {
+fn normalize_path_string_sep(path: String) -> String {
     if std::path::MAIN_SEPARATOR != '/' {
         path.replace(std::path::MAIN_SEPARATOR, "/")
     } else {


Test patch:
diff --git a/tests/build-std/main.rs b/tests/build-std/main.rs
index aec951a95..107564321 100644
--- a/tests/build-std/main.rs
+++ b/tests/build-std/main.rs
@@ -119,31 +119,8 @@ fn basic() {
 
 "#]])
         .run();
-    p.cargo("run")
-        .build_std()
-        .target_host()
-        .with_stderr_data(str![[r#"
-[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
-[RUNNING] `target/[HOST_TARGET]/debug/foo`
-
-"#]])
-        .run();
-    p.cargo("test")
-        .build_std()
-        .target_host()
-        .with_stderr_data(str![[r#"
-[COMPILING] rustc-std-workspace-std [..]
-...
-[COMPILING] test v0.0.0 ([..])
-[COMPILING] foo v0.0.1 ([ROOT]/foo)
-[FINISHED] `test` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
-[RUNNING] unittests src/lib.rs (target/[HOST_TARGET]/debug/deps/foo-[HASH])
-[RUNNING] unittests src/main.rs (target/[HOST_TARGET]/debug/deps/foo-[HASH])
-[RUNNING] tests/smoke.rs (target/[HOST_TARGET]/debug/deps/smoke-[HASH])
-[DOCTEST] foo
-
-"#]])
-        .run();
+    p.cargo("run").build_std().target_host().run();
+    p.cargo("test").build_std().target_host().run();
 
     // Check for hack that removes dylibs.
     let deps_dir = Path::new("target")
diff --git a/tests/testsuite/build.rs b/tests/testsuite/build.rs
index 93254dead..ebbfd8144 100644
--- a/tests/testsuite/build.rs
+++ b/tests/testsuite/build.rs
@@ -6575,7 +6575,7 @@ fn user_specific_cfgs_are_filtered_out() {
         )
         .build();
 
-    p.cargo("rustc -- --cfg debug_assertions --cfg proc_macro -Aunknown_lints -Aexplicit_builtin_cfgs_in_flags")
+    p.cargo("rustc -- --cfg debug_assertions --cfg proc_macro -Aunknown_lints -Aunexpected_builtin_cfgs")
         .run();
     p.process(&p.bin("foo")).run();
 }
diff --git a/tests/testsuite/cargo_add/path_inferred_name/mod.rs b/tests/testsuite/cargo_add/path_inferred_name/mod.rs
index ca77e190e..3729f9946 100644
--- a/tests/testsuite/cargo_add/path_inferred_name/mod.rs
+++ b/tests/testsuite/cargo_add/path_inferred_name/mod.rs
@@ -27,7 +27,7 @@ fn case() {
 
     snapbox::cmd::Command::cargo_ui()
         .arg("add")
-        .arg_line("--path ../dependency")
+        .arg_line("cargo-list-test-fixture-dependency --path ../dependency")
         .current_dir(&cwd)
         .assert()
         .success()
diff --git a/tests/testsuite/mock-std/Cargo.toml b/tests/testsuite/mock-std/Cargo.toml
new file mode 100644
index 000000000..a69aa4b88
--- /dev/null
+++ b/tests/testsuite/mock-std/Cargo.toml
@@ -0,0 +1,8 @@
+[workspace]
+members = [
+  "library/alloc",
+  "library/core",
+  "library/proc_macro",
+  "library/std",
+  "library/test",
+]
diff --git a/tests/testsuite/mock-std/library/Cargo.toml b/tests/testsuite/mock-std/library/Cargo.toml
deleted file mode 100644
index f44d7bef2..000000000
--- a/tests/testsuite/mock-std/library/Cargo.toml
+++ /dev/null
@@ -1,11 +0,0 @@
-[workspace]
-resolver = "1"
-members = [
-  "std",
-  "sysroot",
-]
-
-[patch.crates-io]
-rustc-std-workspace-core = { path = 'rustc-std-workspace-core' }
-rustc-std-workspace-alloc = { path = 'rustc-std-workspace-alloc' }
-rustc-std-workspace-std = { path = 'rustc-std-workspace-std' }
diff --git a/tests/testsuite/package.rs b/tests/testsuite/package.rs
index d8de24c5e..64ef1a9f6 100644
--- a/tests/testsuite/package.rs
+++ b/tests/testsuite/package.rs
@@ -1254,6 +1254,36 @@ fn issue_13695_allowing_dirty_vcs_info_but_clean() {
     );
 }
 
+#[cargo_test]
+fn issue_14354_allowing_dirty_bare_commit() {
+    let p = project().build();
+    // Init a bare commit git repo
+    let _ = git::repo(&paths::root().join("foo"))
+        .file(
+            "Cargo.toml",
+            r#"
+            [package]
+            name = "foo"
+            version = "0.1.0"
+            edition = "2015"
+            description = "foo"
+            license = "foo"
+            documentation = "foo"
+        "#,
+        )
+        .file("src/lib.rs", "");
+
+    p.cargo("package --allow-dirty").run();
+
+    let f = File::open(&p.root().join("target/package/foo-0.1.0.crate")).unwrap();
+    validate_crate_contents(
+        f,
+        "foo-0.1.0.crate",
+        &["Cargo.toml", "Cargo.toml.orig", "src/lib.rs"],
+        &[],
+    );
+}
+
 #[cargo_test]
 fn generated_manifest() {
     let registry = registry::alt_init();
@@ -5943,367 +5973,3 @@ fn workspace_with_local_and_remote_deps() {
         )
         .run();
 }
-
-#[cargo_test]
-fn registry_not_in_publish_list() {
-    let p = project()
-        .file(
-            "Cargo.toml",
-            r#"
-                [package]
-                name = "foo"
-                version = "0.0.1"
-                edition = "2015"
-                authors = []
-                license = "MIT"
-                description = "foo"
-                publish = [
-                    "test"
-                ]
-            "#,
-        )
-        .file("src/main.rs", "fn main() {}")
-        .build();
-
-    p.cargo("package --registry alternative -Zpackage-workspace")
-        .masquerade_as_nightly_cargo(&["package-workspace"])
-        .with_status(101)
-        .with_stderr_data(str![[r#"
-[ERROR] registry index was not found in any configuration: `alternative`
-
-"#]])
-        .run();
-}
-
-#[cargo_test]
-fn registry_inferred_from_unique_option() {
-    let _registry = registry::RegistryBuilder::new()
-        .http_api()
-        .http_index()
-        .alternative()
-        .build();
-
-    let p = project()
-        .file(
-            "Cargo.toml",
-            r#"
-            [workspace]
-            members = ["dep", "main"]
-            "#,
-        )
-        .file(
-            "main/Cargo.toml",
-            r#"
-            [package]
-            name = "main"
-            version = "0.0.1"
-            edition = "2015"
-            authors = []
-            license = "MIT"
-            description = "main"
-            repository = "bar"
-            publish = ["alternative"]
-
-            [dependencies]
-            dep = { path = "../dep", version = "0.1.0", registry = "alternative" }
-        "#,
-        )
-        .file("main/src/main.rs", "fn main() {}")
-        .file(
-            "dep/Cargo.toml",
-            r#"
-            [package]
-            name = "dep"
-            version = "0.1.0"
-            edition = "2015"
-            authors = []
-            license = "MIT"
-            description = "dep"
-            repository = "bar"
-            publish = ["alternative"]
-        "#,
-        )
-        .file("dep/src/lib.rs", "")
-        .build();
-
-    p.cargo("package -Zpackage-workspace")
-        .masquerade_as_nightly_cargo(&["package-workspace"])
-        .with_stderr_data(str![[r#"
-[PACKAGING] dep v0.1.0 ([ROOT]/foo/dep)
-[PACKAGED] 3 files, [FILE_SIZE]B ([FILE_SIZE]B compressed)
-[PACKAGING] main v0.0.1 ([ROOT]/foo/main)
-[UPDATING] `alternative` index
-[PACKAGED] 4 files, [FILE_SIZE]B ([FILE_SIZE]B compressed)
-[VERIFYING] dep v0.1.0 ([ROOT]/foo/dep)
-[COMPILING] dep v0.1.0 ([ROOT]/foo/target/package/dep-0.1.0)
-[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
-[VERIFYING] main v0.0.1 ([ROOT]/foo/main)
-[UPDATING] `alternative` index
-[UNPACKING] dep v0.1.0 (registry `[ROOT]/foo/target/package/tmp-registry`)
-[COMPILING] dep v0.1.0 (registry `alternative`)
-[COMPILING] main v0.0.1 ([ROOT]/foo/target/package/main-0.0.1)
-[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
-
-"#]])
-        .run();
-}
-
-#[cargo_test]
-fn registry_not_inferred_because_of_conflict() {
-    let alt_reg = registry::RegistryBuilder::new()
-        .http_api()
-        .http_index()
-        .alternative()
-        .build();
-
-    let p = project()
-        .file(
-            "Cargo.toml",
-            r#"
-            [workspace]
-            members = ["dep", "main"]
-            "#,
-        )
-        .file(
-            "main/Cargo.toml",
-            r#"
-            [package]
-            name = "main"
-            version = "0.0.1"
-            edition = "2015"
-            authors = []
-            license = "MIT"
-            description = "main"
-            repository = "bar"
-            publish = ["alternative"]
-
-            [dependencies]
-            dep = { path = "../dep", version = "0.1.0", registry = "alternative" }
-        "#,
-        )
-        .file("main/src/main.rs", "fn main() {}")
-        .file(
-            "dep/Cargo.toml",
-            r#"
-            [package]
-            name = "dep"
-            version = "0.1.0"
-            edition = "2015"
-            authors = []
-            license = "MIT"
-            description = "dep"
-            repository = "bar"
-            publish = ["alternative2"]
-        "#,
-        )
-        .file("dep/src/lib.rs", "")
-        .build();
-
-    p.cargo("package -Zpackage-workspace")
-        .masquerade_as_nightly_cargo(&["package-workspace"])
-        .with_status(101)
-        .with_stderr_data(str![[r#"
-[ERROR] conflicts between `package.publish` fields in the selected packages
-
-"#]])
-        .run();
-
-    p.cargo("package -Zpackage-workspace --registry=alternative")
-        .masquerade_as_nightly_cargo(&["package-workspace"])
-        .with_status(101)
-        .with_stderr_data(str![[r#"
-[ERROR] `dep` cannot be packaged.
-The registry `alternative` is not listed in the `package.publish` value in Cargo.toml.
-
-"#]])
-        .run();
-
-    p.cargo(&format!(
-        "package --index {} -Zpackage-workspace",
-        alt_reg.index_url()
-    ))
-    .masquerade_as_nightly_cargo(&["package-workspace"])
-    .with_stderr_data(str![[r#"
-[PACKAGING] dep v0.1.0 ([ROOT]/foo/dep)
-[PACKAGED] 3 files, [FILE_SIZE]B ([FILE_SIZE]B compressed)
-[PACKAGING] main v0.0.1 ([ROOT]/foo/main)
-[UPDATING] `alternative` index
-[PACKAGED] 4 files, [FILE_SIZE]B ([FILE_SIZE]B compressed)
-[VERIFYING] dep v0.1.0 ([ROOT]/foo/dep)
-[COMPILING] dep v0.1.0 ([ROOT]/foo/target/package/dep-0.1.0)
-[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
-[VERIFYING] main v0.0.1 ([ROOT]/foo/main)
-[UPDATING] `alternative` index
-[UNPACKING] dep v0.1.0 (registry `[ROOT]/foo/target/package/tmp-registry`)
-[COMPILING] dep v0.1.0 (registry `alternative`)
-[COMPILING] main v0.0.1 ([ROOT]/foo/target/package/main-0.0.1)
-[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
-
-"#]])
-    .run();
-}
-
-#[cargo_test]
-fn registry_not_inferred_because_of_multiple_options() {
-    let _alt_reg = registry::RegistryBuilder::new()
-        .http_api()
-        .http_index()
-        .alternative()
-        .build();
-
-    let p = project()
-        .file(
-            "Cargo.toml",
-            r#"
-            [workspace]
-            members = ["dep", "main"]
-            "#,
-        )
-        .file(
-            "main/Cargo.toml",
-            r#"
-            [package]
-            name = "main"
-            version = "0.0.1"
-            edition = "2015"
-            authors = []
-            license = "MIT"
-            description = "main"
-            repository = "bar"
-            publish = ["alternative", "alternative2"]
-
-            [dependencies]
-            dep = { path = "../dep", version = "0.1.0", registry = "alternative" }
-        "#,
-        )
-        .file("main/src/main.rs", "fn main() {}")
-        .file(
-            "dep/Cargo.toml",
-            r#"
-            [package]
-            name = "dep"
-            version = "0.1.0"
-            edition = "2015"
-            authors = []
-            license = "MIT"
-            description = "dep"
-            repository = "bar"
-            publish = ["alternative", "alternative2"]
-        "#,
-        )
-        .file("dep/src/lib.rs", "")
-        .build();
-
-    p.cargo("package -Zpackage-workspace")
-        .masquerade_as_nightly_cargo(&["package-workspace"])
-        .with_status(101)
-        .with_stderr_data(str![[r#"
-[ERROR] --registry is required to disambiguate between "alternative" or "alternative2" registries
-
-"#]])
-        .run();
-
-    p.cargo("package -Zpackage-workspace --registry=alternative")
-        .masquerade_as_nightly_cargo(&["package-workspace"])
-        .with_stderr_data(str![[r#"
-[PACKAGING] dep v0.1.0 ([ROOT]/foo/dep)
-[PACKAGED] 3 files, [FILE_SIZE]B ([FILE_SIZE]B compressed)
-[PACKAGING] main v0.0.1 ([ROOT]/foo/main)
-[UPDATING] `alternative` index
-[PACKAGED] 4 files, [FILE_SIZE]B ([FILE_SIZE]B compressed)
-[VERIFYING] dep v0.1.0 ([ROOT]/foo/dep)
-[COMPILING] dep v0.1.0 ([ROOT]/foo/target/package/dep-0.1.0)
-[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
-[VERIFYING] main v0.0.1 ([ROOT]/foo/main)
-[UPDATING] `alternative` index
-[UNPACKING] dep v0.1.0 (registry `[ROOT]/foo/target/package/tmp-registry`)
-[COMPILING] dep v0.1.0 (registry `alternative`)
-[COMPILING] main v0.0.1 ([ROOT]/foo/target/package/main-0.0.1)
-[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
-
-"#]])
-        .run();
-}
-
-#[cargo_test]
-fn registry_not_inferred_because_of_mismatch() {
-    let _alt_reg = registry::RegistryBuilder::new()
-        .http_api()
-        .http_index()
-        .alternative()
-        .build();
-
-    let p = project()
-        .file(
-            "Cargo.toml",
-            r#"
-            [workspace]
-            members = ["dep", "main"]
-            "#,
-        )
-        .file(
-            "main/Cargo.toml",
-            r#"
-            [package]
-            name = "main"
-            version = "0.0.1"
-            edition = "2015"
-            authors = []
-            license = "MIT"
-            description = "main"
-            repository = "bar"
-            publish = ["alternative"]
-
-            [dependencies]
-            dep = { path = "../dep", version = "0.1.0", registry = "alternative" }
-        "#,
-        )
-        .file("main/src/main.rs", "fn main() {}")
-        // No `publish` field means "any registry", but the presence of this package
-        // will stop us from inferring a registry.
-        .file(
-            "dep/Cargo.toml",
-            r#"
-            [package]
-            name = "dep"
-            version = "0.1.0"
-            edition = "2015"
-            authors = []
-            license = "MIT"
-            description = "dep"
-            repository = "bar"
-        "#,
-        )
-        .file("dep/src/lib.rs", "")
-        .build();
-
-    p.cargo("package -Zpackage-workspace")
-        .masquerade_as_nightly_cargo(&["package-workspace"])
-        .with_status(101)
-        .with_stderr_data(str![[r#"
-[ERROR] --registry is required because not all `package.publish` settings agree
-
-"#]])
-        .run();
-
-    p.cargo("package -Zpackage-workspace --registry=alternative")
-        .masquerade_as_nightly_cargo(&["package-workspace"])
-        .with_stderr_data(str![[r#"
-[PACKAGING] dep v0.1.0 ([ROOT]/foo/dep)
-[PACKAGED] 3 files, [FILE_SIZE]B ([FILE_SIZE]B compressed)
-[PACKAGING] main v0.0.1 ([ROOT]/foo/main)
-[UPDATING] `alternative` index
-[PACKAGED] 4 files, [FILE_SIZE]B ([FILE_SIZE]B compressed)
-[VERIFYING] dep v0.1.0 ([ROOT]/foo/dep)
-[COMPILING] dep v0.1.0 ([ROOT]/foo/target/package/dep-0.1.0)
-[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
-[VERIFYING] main v0.0.1 ([ROOT]/foo/main)
-[UPDATING] `alternative` index
-[UNPACKING] dep v0.1.0 (registry `[ROOT]/foo/target/package/tmp-registry`)
-[COMPILING] dep v0.1.0 (registry `alternative`)
-[COMPILING] main v0.0.1 ([ROOT]/foo/target/package/main-0.0.1)
-[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
-
-"#]])
-        .run();
-}
diff --git a/tests/testsuite/vendor.rs b/tests/testsuite/vendor.rs
index 0f3a7f7b4..c103955df 100644
--- a/tests/testsuite/vendor.rs
+++ b/tests/testsuite/vendor.rs
@@ -36,7 +36,7 @@ fn vendor_simple() {
     let lock = p.read_file("vendor/log/Cargo.toml");
     assert!(lock.contains("version = \"0.3.5\""));
 
-    add_crates_io_vendor_config(&p);
+    add_vendor_config(&p);
     p.cargo("check").run();
 }
 
@@ -151,7 +151,7 @@ directory = "deps/.vendor"
     assert!(lock.contains("version = \"0.3.5\""));
 }
 
-fn add_crates_io_vendor_config(p: &Project) {
+fn add_vendor_config(p: &Project) {
     p.change_file(
         ".cargo/config.toml",
         r#"
@@ -164,23 +164,6 @@ fn add_crates_io_vendor_config(p: &Project) {
     );
 }
 
-fn add_git_vendor_config(p: &Project, git_project: &Project) {
-    p.change_file(
-        ".cargo/config.toml",
-        &format!(
-            r#"
-            [source."git+{url}"]
-            git = "{url}"
-            replace-with = 'vendor'
-
-            [source.vendor]
-            directory = 'vendor'
-        "#,
-            url = git_project.url()
-        ),
-    );
-}
-
 #[cargo_test]
 fn package_exclude() {
     let p = project()
@@ -225,554 +208,6 @@ fn package_exclude() {
     assert!(!csum.contains(".dotdir/include"));
 }
 
-#[cargo_test]
-fn discovery_inferred_build_rs_included() {
-    let git_project = git::new("dep", |project| {
-        project
-            .file(
-                "Cargo.toml",
-                r#"
-    [package]
-    name = "dep"
-    version = "0.0.1"
-    edition = "2015"
-    license = "MIT"
-    description = "foo"
-    documentation = "docs.rs/foo"
-    authors = []
-    include = ["src/lib.rs", "build.rs"]
-    "#,
-            )
-            .file("src/lib.rs", "")
-            .file("build.rs", "fn main() {}")
-    });
-
-    let p = project()
-        .file(
-            "Cargo.toml",
-            &format!(
-                r#"
-                    [package]
-                    name = "foo"
-                    version = "0.5.0"
-                    edition = "2015"
-
-                    [dependencies.dep]
-                    git = '{}'
-                "#,
-                git_project.url()
-            ),
-        )
-        .file("src/main.rs", "fn main() {}")
-        .build();
-
-    p.cargo("vendor --respect-source-config").run();
-    add_git_vendor_config(&p, &git_project);
-
-    let lock = p.read_file("vendor/dep/Cargo.toml");
-    assert_e2e().eq(
-        lock,
-        str![[r##"
-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
-#
-# When uploading crates to the registry Cargo will automatically
-# "normalize" Cargo.toml files for maximal compatibility
-# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies.
-#
-# If you are reading this file be aware that the original Cargo.toml
-# will likely look very different (and much more reasonable).
-# See Cargo.toml.orig for the original contents.
-
-[package]
-edition = "2015"
-name = "dep"
-version = "0.0.1"
-authors = []
-build = "build.rs"
-include = [
-    "src/lib.rs",
-    "build.rs",
-]
-autobins = false
-autoexamples = false
-autotests = false
-autobenches = false
-description = "foo"
-documentation = "docs.rs/foo"
-readme = false
-license = "MIT"
-
-[lib]
-name = "dep"
-path = "src/lib.rs"
-
-"##]],
-    );
-
-    p.cargo("check").run();
-}
-
-#[cargo_test]
-fn discovery_inferred_build_rs_excluded() {
-    let git_project = git::new("dep", |project| {
-        project
-            .file(
-                "Cargo.toml",
-                r#"
-    [package]
-    name = "dep"
-    version = "0.0.1"
-    edition = "2015"
-    license = "MIT"
-    description = "foo"
-    documentation = "docs.rs/foo"
-    authors = []
-    include = ["src/lib.rs"]
-    "#,
-            )
-            .file("src/lib.rs", "")
-            .file("build.rs", "fn main() {}")
-    });
-
-    let p = project()
-        .file(
-            "Cargo.toml",
-            &format!(
-                r#"
-                    [package]
-                    name = "foo"
-                    version = "0.5.0"
-                    edition = "2015"
-
-                    [dependencies.dep]
-                    git = '{}'
-                "#,
-                git_project.url()
-            ),
-        )
-        .file("src/main.rs", "fn main() {}")
-        .build();
-
-    p.cargo("vendor --respect-source-config").run();
-    add_git_vendor_config(&p, &git_project);
-
-    let lock = p.read_file("vendor/dep/Cargo.toml");
-    assert_e2e().eq(
-        lock,
-        str![[r##"
-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
-#
-# When uploading crates to the registry Cargo will automatically
-# "normalize" Cargo.toml files for maximal compatibility
-# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies.
-#
-# If you are reading this file be aware that the original Cargo.toml
-# will likely look very different (and much more reasonable).
-# See Cargo.toml.orig for the original contents.
-
-[package]
-edition = "2015"
-name = "dep"
-version = "0.0.1"
-authors = []
-build = false
-include = ["src/lib.rs"]
-autobins = false
-autoexamples = false
-autotests = false
-autobenches = false
-description = "foo"
-documentation = "docs.rs/foo"
-readme = false
-license = "MIT"
-
-[lib]
-name = "dep"
-path = "src/lib.rs"
-
-"##]],
-    );
-
-    p.cargo("check").run();
-}
-
-#[cargo_test]
-fn discovery_inferred_lib_included() {
-    let git_project = git::new("dep", |project| {
-        project
-            .file(
-                "Cargo.toml",
-                r#"
-    [package]
-    name = "dep"
-    version = "0.0.1"
-    edition = "2015"
-    license = "MIT"
-    description = "foo"
-    documentation = "docs.rs/foo"
-    authors = []
-    include = ["src/main.rs", "src/lib.rs"]
-    "#,
-            )
-            .file("src/main.rs", "fn main() {}")
-            .file("src/lib.rs", "")
-    });
-
-    let p = project()
-        .file(
-            "Cargo.toml",
-            &format!(
-                r#"
-                    [package]
-                    name = "foo"
-                    version = "0.5.0"
-                    edition = "2015"
-
-                    [dependencies.dep]
-                    git = '{}'
-                "#,
-                git_project.url()
-            ),
-        )
-        .file("src/main.rs", "fn main() {}")
-        .build();
-
-    p.cargo("vendor --respect-source-config").run();
-    add_git_vendor_config(&p, &git_project);
-
-    let lock = p.read_file("vendor/dep/Cargo.toml");
-    assert_e2e().eq(
-        lock,
-        str![[r##"
-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
-#
-# When uploading crates to the registry Cargo will automatically
-# "normalize" Cargo.toml files for maximal compatibility
-# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies.
-#
-# If you are reading this file be aware that the original Cargo.toml
-# will likely look very different (and much more reasonable).
-# See Cargo.toml.orig for the original contents.
-
-[package]
-edition = "2015"
-name = "dep"
-version = "0.0.1"
-authors = []
-build = false
-include = [
-    "src/main.rs",
-    "src/lib.rs",
-]
-autobins = false
-autoexamples = false
-autotests = false
-autobenches = false
-description = "foo"
-documentation = "docs.rs/foo"
-readme = false
-license = "MIT"
-
-[lib]
-name = "dep"
-path = "src/lib.rs"
-
-[[bin]]
-name = "dep"
-path = "src/main.rs"
-
-"##]],
-    );
-
-    p.cargo("check").run();
-}
-
-#[cargo_test]
-fn discovery_inferred_lib_excluded() {
-    let git_project = git::new("dep", |project| {
-        project
-            .file(
-                "Cargo.toml",
-                r#"
-    [package]
-    name = "dep"
-    version = "0.0.1"
-    edition = "2015"
-    license = "MIT"
-    description = "foo"
-    documentation = "docs.rs/foo"
-    authors = []
-    include = ["src/main.rs"]
-    "#,
-            )
-            .file("src/main.rs", "fn main() {}")
-            .file("src/lib.rs", "")
-    });
-
-    let p = project()
-        .file(
-            "Cargo.toml",
-            &format!(
-                r#"
-                    [package]
-                    name = "foo"
-                    version = "0.5.0"
-                    edition = "2015"
-
-                    [dependencies.dep]
-                    git = '{}'
-                "#,
-                git_project.url()
-            ),
-        )
-        .file("src/main.rs", "fn main() {}")
-        .build();
-
-    p.cargo("vendor --respect-source-config").run();
-    add_git_vendor_config(&p, &git_project);
-
-    let lock = p.read_file("vendor/dep/Cargo.toml");
-    assert_e2e().eq(
-        lock,
-        str![[r##"
-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
-#
-# When uploading crates to the registry Cargo will automatically
-# "normalize" Cargo.toml files for maximal compatibility
-# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies.
-#
-# If you are reading this file be aware that the original Cargo.toml
-# will likely look very different (and much more reasonable).
-# See Cargo.toml.orig for the original contents.
-
-[package]
-edition = "2015"
-name = "dep"
-version = "0.0.1"
-authors = []
-build = false
-include = ["src/main.rs"]
-autobins = false
-autoexamples = false
-autotests = false
-autobenches = false
-description = "foo"
-documentation = "docs.rs/foo"
-readme = false
-license = "MIT"
-
-[[bin]]
-name = "dep"
-path = "src/main.rs"
-
-"##]],
-    );
-
-    p.cargo("check").run();
-}
-
-#[cargo_test]
-fn discovery_inferred_other_included() {
-    let git_project = git::new("dep", |project| {
-        project
-        .file(
-            "Cargo.toml",
-            r#"
-    [package]
-    name = "dep"
-    version = "0.0.1"
-    edition = "2015"
-    license = "MIT"
-    description = "foo"
-    documentation = "docs.rs/foo"
-    authors = []
-    include = ["src/lib.rs", "src/bin/foo/main.rs", "examples/example_foo.rs", "tests/test_foo.rs", "benches/bench_foo.rs"]
-    "#,
-        )
-        .file("src/lib.rs", "")
-        .file("src/bin/foo/main.rs", "fn main() {}")
-        .file("examples/example_foo.rs", "fn main() {}")
-        .file("tests/test_foo.rs", "fn main() {}")
-        .file("benches/bench_foo.rs", "fn main() {}")
-    });
-
-    let p = project()
-        .file(
-            "Cargo.toml",
-            &format!(
-                r#"
-                    [package]
-                    name = "foo"
-                    version = "0.5.0"
-                    edition = "2015"
-
-                    [dependencies.dep]
-                    git = '{}'
-                "#,
-                git_project.url()
-            ),
-        )
-        .file("src/main.rs", "fn main() {}")
-        .build();
-
-    p.cargo("vendor --respect-source-config").run();
-    add_git_vendor_config(&p, &git_project);
-
-    let lock = p.read_file("vendor/dep/Cargo.toml");
-    assert_e2e().eq(
-        lock,
-        str![[r##"
-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
-#
-# When uploading crates to the registry Cargo will automatically
-# "normalize" Cargo.toml files for maximal compatibility
-# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies.
-#
-# If you are reading this file be aware that the original Cargo.toml
-# will likely look very different (and much more reasonable).
-# See Cargo.toml.orig for the original contents.
-
-[package]
-edition = "2015"
-name = "dep"
-version = "0.0.1"
-authors = []
-build = false
-include = [
-    "src/lib.rs",
-    "src/bin/foo/main.rs",
-    "examples/example_foo.rs",
-    "tests/test_foo.rs",
-    "benches/bench_foo.rs",
-]
-autobins = false
-autoexamples = false
-autotests = false
-autobenches = false
-description = "foo"
-documentation = "docs.rs/foo"
-readme = false
-license = "MIT"
-
-[lib]
-name = "dep"
-path = "src/lib.rs"
-
-[[bin]]
-name = "foo"
-path = "src/bin/foo/main.rs"
-
-[[example]]
-name = "example_foo"
-path = "examples/example_foo.rs"
-
-[[test]]
-name = "test_foo"
-path = "tests/test_foo.rs"
-
-[[bench]]
-name = "bench_foo"
-path = "benches/bench_foo.rs"
-
-"##]],
-    );
-
-    p.cargo("check").run();
-}
-
-#[cargo_test]
-fn discovery_inferred_other_excluded() {
-    let git_project = git::new("dep", |project| {
-        project
-            .file(
-                "Cargo.toml",
-                r#"
-    [package]
-    name = "dep"
-    version = "0.0.1"
-    edition = "2015"
-    license = "MIT"
-    description = "foo"
-    documentation = "docs.rs/foo"
-    authors = []
-    include = ["src/lib.rs"]
-    "#,
-            )
-            .file("src/lib.rs", "")
-            .file("src/bin/foo/main.rs", "fn main() {}")
-            .file("examples/example_foo.rs", "fn main() {}")
-            .file("tests/test_foo.rs", "fn main() {}")
-            .file("benches/bench_foo.rs", "fn main() {}")
-    });
-
-    let p = project()
-        .file(
-            "Cargo.toml",
-            &format!(
-                r#"
-                    [package]
-                    name = "foo"
-                    version = "0.5.0"
-                    edition = "2015"
-
-                    [dependencies.dep]
-                    git = '{}'
-                "#,
-                git_project.url()
-            ),
-        )
-        .file("src/main.rs", "fn main() {}")
-        .build();
-
-    p.cargo("vendor --respect-source-config").run();
-    add_git_vendor_config(&p, &git_project);
-
-    let lock = p.read_file("vendor/dep/Cargo.toml");
-    assert_e2e().eq(
-        lock,
-        str![[r##"
-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
-#
-# When uploading crates to the registry Cargo will automatically
-# "normalize" Cargo.toml files for maximal compatibility
-# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies.
-#
-# If you are reading this file be aware that the original Cargo.toml
-# will likely look very different (and much more reasonable).
-# See Cargo.toml.orig for the original contents.
-
-[package]
-edition = "2015"
-name = "dep"
-version = "0.0.1"
-authors = []
-build = false
-include = ["src/lib.rs"]
-autobins = false
-autoexamples = false
-autotests = false
-autobenches = false
-description = "foo"
-documentation = "docs.rs/foo"
-readme = false
-license = "MIT"
-
-[lib]
-name = "dep"
-path = "src/lib.rs"
-
-"##]],
-    );
-
-    p.cargo("check").run();
-}
-
 #[cargo_test]
 fn two_versions() {
     let p = project()
@@ -813,7 +248,7 @@ fn two_versions() {
     let lock = p.read_file("vendor/bitflags-0.7.0/Cargo.toml");
     assert!(lock.contains("version = \"0.7.0\""));
 
-    add_crates_io_vendor_config(&p);
+    add_vendor_config(&p);
     p.cargo("check").run();
 }
 
@@ -858,7 +293,7 @@ fn two_explicit_versions() {
     let lock = p.read_file("vendor/bitflags-0.7.0/Cargo.toml");
     assert!(lock.contains("version = \"0.7.0\""));
 
-    add_crates_io_vendor_config(&p);
+    add_vendor_config(&p);
     p.cargo("check").run();
 }
 
@@ -951,7 +386,7 @@ fn two_lockfiles() {
     let lock = p.read_file("vendor/bitflags-0.7.0/Cargo.toml");
     assert!(lock.contains("version = \"0.7.0\""));
 
-    add_crates_io_vendor_config(&p);
+    add_vendor_config(&p);
     p.cargo("check").cwd("foo").run();
     p.cargo("check").cwd("bar").run();
 }
@@ -1210,7 +645,7 @@ fn vendoring_git_crates() {
     p.cargo("vendor --respect-source-config").run();
     p.read_file("vendor/serde_derive/src/wut.rs");
 
-    add_crates_io_vendor_config(&p);
+    add_vendor_config(&p);
     p.cargo("check").run();
 }
 
@@ -1521,6 +956,10 @@ fn git_deterministic() {
 # will likely look very different (and much more reasonable).
 # See Cargo.toml.orig for the original contents.
 
+bin = []
+test = []
+bench = []
+
 [package]
 edition = "2021"
 name = "git_dep"
@@ -1538,7 +977,7 @@ license = "MIT"
 
 [lib]
 name = "git_dep"
-path = "src/lib.rs"
+path = [..]
 
 [[example]]
 name = "a"