-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Inconsistent .gitignore handling of symlinks in cargo package #10032
Comments
I suspect this may partially be a bug in the |
Okay, a couple of things from digging deeper:
|
Failing test: #[cargo_test]
/// Test that .gitignore is respected even if Cargo.toml isn't in git.
fn gitignore_with_untracked_cargo_toml() {
if !symlink_supported() {
return;
}
let (p, repo) = git::new_repo("foo", |p| {
p.file("src/main.rs", r#"fn main() { println!("hello"); }"#)
.file("foo.txt", "hello")
.file(".gitignore", "foo.txt")
});
let mut index = repo.index().unwrap();
index.remove_path(&Path::new("Cargo.toml")).unwrap();
index.write().unwrap();
p.cargo("package -l --no-metadata --allow-dirty")
.with_stderr("")
.with_stdout(
"\
.gitignore
Cargo.lock
Cargo.toml
Cargo.toml.orig
src/main.rs
",
)
.run();
} Fails with
|
The rabbithole continues. This appears to be intentional: cargo/src/cargo/sources/path.rs Lines 181 to 182 in b747054
cargo/src/cargo/sources/path.rs Lines 216 to 221 in b747054
In fact, the commit that originally introduced this logic states cargo/src/cargo/sources/path.rs Lines 122 to 124 in 9185445
But I think maybe there's a case missing here, which is that if no other git repositories are found, then we should go with the "topmost" one that is at or above the found Ultimately though, I'll leave it up to you all to decide whether that should be considered a bug or more like a lack of a feature. In the meantime I'll close this issue, since the issue as reported is not actually present. |
I'll add that one place where this comes up is if someone tries to do the following: $ cargo new project
$ cd project
$ $EDITOR # implement the first alpha of the project
$ $EDITOR .gitignore # add some huge log files to gitignore
$ cargo publish --allow-dirty Then they'll accidentally include all the logfiles in their published artifact. It's fixed if they |
Add tests for ignoring symlinks This adds tests for the expected behavior in #10032. Interestingly, these tests pass (🎉). Will update that issue with more details shortly, but figured these tests were worthwhile to add to the testsuite anyway now that I've written them.
Problem
cargo package
does not handle.gitignore
rules the same as git for symlinks. Specifically, in.gitignore
,/symlink
will match a symlink whether even if it is a symlink to a directory, whereas Cargo will not matchsymlink
in that case, causing it to fail to ignore the symlink and its target.Similarly,
/symlink/
in.gitignore
will ignore the files undersymlink
in git, but not the symlink itself, whereas Cargo just dereferences the symlink and includes the referent directory contents, and essentially ends up ignoring the/symlink/
rule.Furthermore, Cargo's behavior changes if
--allow-dirty
is passed. See below.Steps
Now,
cargo --allow-dirty
:Notice that the files under both symlinks are included, and no actual symlinks are included.
Now, commit and try again without
--allow-dirty
:Ignoring the
.cargo_vcs_info.json
file, and the fact that.gitignore
is now included(?), notice that this now (correctly) does not includesrc1
or the contents of its referent directory. But it still includessrc2
as a directory even though/src2/
was specified as an ignore.Constrast that with
git ls-files
:Which represents the "true" behavior:
src1
is not included (it matches/src1
), andsrc2
is included, but only as a symlink.Possible Solution(s)
Assuming we want to continue to not include symlinks in
.crate
files, the solution here is to make the walk implementation for--allow-dirty
to make/symlink
matchsymlink
regardless of whether it points to a directory or not, and to make the git-based walk correctly handle/symlink/
exclusions. My first instinct was that for the former,cargo/src/cargo/sources/path.rs
Line 395 in b747054
should be
but unfortunately I don't think that'll work since we should continue to treat the symlink as a directory for recursion purposes. I'm not sure how best to augment the git walking.
Notes
Here is a failing test for
--allow-dirty
:I'm not sure how to best trigger the git-based walk inside the test suite.
Version
Though also occurs on
master
@ 94ca096The text was updated successfully, but these errors were encountered: