mirror of
https://github.com/rust-lang/cargo.git
synced 2025-09-28 11:20:36 +00:00
fix(package): detect dirtiness for symlinks to submodule
If a there is a symlink into a git repository/submodule, when checking its git status with the wrong outer repo, we'll get an NotFound error, as the object doesn't belong to the outer repository. This kind of error blocked the entire `cargo package` operation. This fix additionally discovers the nearest Git repository, and then checks status with that, assuming the repo is the parent of the source file of the symlink. This is a best effort solution, so if the check fails we ignore.
This commit is contained in:
parent
d760263afb
commit
71ea2e5c5f
@ -274,9 +274,28 @@ fn dirty_files_outside_pkg_root(
|
||||
dirty_files.insert(workdir.join(rel_path));
|
||||
}
|
||||
Err(e) => {
|
||||
if e.code() == git2::ErrorCode::NotFound {
|
||||
// Object not found means this file might be inside a subrepo/submodule.
|
||||
// Let's check its status from that repo.
|
||||
let abs_path = workdir.join(&rel_path);
|
||||
if let Ok(repo) = git2::Repository::discover(&abs_path) {
|
||||
let is_dirty = if repo.workdir() == Some(workdir) {
|
||||
false
|
||||
} else if let Ok(path) =
|
||||
paths::strip_prefix_canonical(&abs_path, repo.workdir().unwrap())
|
||||
{
|
||||
repo.status_file(&path) != Ok(git2::Status::CURRENT)
|
||||
} else {
|
||||
false
|
||||
};
|
||||
if is_dirty {
|
||||
dirty_files.insert(abs_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dirtiness check for symlinks is mostly informational.
|
||||
// And changes in submodule would fail git-status as well (see #15384).
|
||||
// To avoid adding complicated logic to handle that,
|
||||
// To avoid adding more complicated logic,
|
||||
// for now we ignore the status check failure.
|
||||
debug!(
|
||||
"failed to get status from file `{}` in git repo at `{}`: {e}",
|
||||
|
@ -1463,13 +1463,16 @@ fn dirty_file_outside_pkg_root_inside_submodule() {
|
||||
p.symlink("submodule/file.txt", "isengard/src/file.txt");
|
||||
git::add(&repo);
|
||||
git::commit(&repo);
|
||||
// This dirtyness should be detected in the future.
|
||||
p.change_file("submodule/file.txt", "changed");
|
||||
|
||||
p.cargo("package --workspace --no-verify")
|
||||
.with_status(101)
|
||||
.with_stderr_data(str![[r#"
|
||||
[PACKAGING] isengard v0.0.0 ([ROOT]/foo/isengard)
|
||||
[PACKAGED] 6 files, [FILE_SIZE]B ([FILE_SIZE]B compressed)
|
||||
[ERROR] 1 files in the working directory contain changes that were not yet committed into git:
|
||||
|
||||
submodule/file.txt
|
||||
|
||||
to proceed despite this and include the uncommitted changes, pass the `--allow-dirty` flag
|
||||
|
||||
"#]])
|
||||
.run();
|
||||
|
Loading…
x
Reference in New Issue
Block a user