Handle git deleted files with dirty worktree.

This commit is contained in:
Eric Huss 2021-07-01 18:10:35 -07:00
parent 4952979031
commit 97a135049a
2 changed files with 60 additions and 8 deletions

View File

@ -1,3 +1,4 @@
use std::collections::HashSet;
use std::fmt::{self, Debug, Formatter};
use std::fs;
use std::path::{Path, PathBuf};
@ -261,19 +262,36 @@ impl<'cfg> PathSource<'cfg> {
opts.pathspec(suffix);
}
let statuses = repo.statuses(Some(&mut opts))?;
let untracked = statuses.iter().filter_map(|entry| match entry.status() {
// Don't include Cargo.lock if it is untracked. Packaging will
// generate a new one as needed.
git2::Status::WT_NEW if entry.path() != Some("Cargo.lock") => {
Some((join(root, entry.path_bytes()), None))
}
_ => None,
});
let mut skip_paths = HashSet::new();
let untracked: Vec<_> = statuses
.iter()
.filter_map(|entry| {
match entry.status() {
// Don't include Cargo.lock if it is untracked. Packaging will
// generate a new one as needed.
git2::Status::WT_NEW if entry.path() != Some("Cargo.lock") => {
Some(Ok((join(root, entry.path_bytes()), None)))
}
git2::Status::WT_DELETED => {
let path = match join(root, entry.path_bytes()) {
Ok(p) => p,
Err(e) => return Some(Err(e)),
};
skip_paths.insert(path);
None
}
_ => None,
}
})
.collect::<CargoResult<_>>()?;
let mut subpackages_found = Vec::new();
for (file_path, is_dir) in index_files.chain(untracked) {
let file_path = file_path?;
if skip_paths.contains(&file_path) {
continue;
}
// Filter out files blatantly outside this package. This is helped a
// bit above via the `pathspec` function call, but we need to filter

View File

@ -2071,3 +2071,37 @@ fn package_with_resolver_and_metadata() {
p.cargo("package").run();
}
#[cargo_test]
fn deleted_git_working_tree() {
// When deleting a file, but not staged, cargo should ignore the file.
let (p, repo) = git::new_repo("foo", |p| {
p.file("src/lib.rs", "").file("src/main.rs", "fn main() {}")
});
p.root().join("src/lib.rs").rm_rf();
p.cargo("package --allow-dirty --list")
.with_stdout(
"\
Cargo.lock
Cargo.toml
Cargo.toml.orig
src/main.rs
",
)
.run();
p.cargo("package --allow-dirty").run();
let mut index = t!(repo.index());
t!(index.remove(Path::new("src/lib.rs"), 0));
t!(index.write());
p.cargo("package --allow-dirty --list")
.with_stdout(
"\
Cargo.lock
Cargo.toml
Cargo.toml.orig
src/main.rs
",
)
.run();
p.cargo("package --allow-dirty").run();
}