diff --git a/crates/pi-walker/src/cache.rs b/crates/pi-walker/src/cache.rs index 82afdea6e..eca9caa62 100644 --- a/crates/pi-walker/src/cache.rs +++ b/crates/pi-walker/src/cache.rs @@ -305,7 +305,8 @@ fn build_walker_for_options_inner( .git_exclude(true) .git_global(true) .ignore(true) - .parents(true); + .parents(true) + .require_git(false); } else { builder .git_ignore(false) diff --git a/crates/pi-walker/src/lib.rs b/crates/pi-walker/src/lib.rs index e2100f02b..2c63090ac 100644 --- a/crates/pi-walker/src/lib.rs +++ b/crates/pi-walker/src/lib.rs @@ -2490,7 +2490,6 @@ impl FastIgnore { saw_git = saw_git || frame.has_git; current = frame.parent.as_deref(); } - match ignore_match { ignore::Match::Ignore(_) => return true, ignore::Match::Whitelist(_) => return false, @@ -3866,6 +3865,42 @@ mod tests { ); } + #[test] + fn collect_entries_with_exact_workspace_options() { + let tree = temp_tree("exact-options"); + fs::write(tree.path().join(".gitignore"), "ignored.txt\n") + .expect(".gitignore should be written"); + fs::write(tree.path().join("ignored.txt"), "ignored") + .expect("ignored file should be written"); + fs::write(tree.path().join("kept.txt"), "keep").expect("kept file should be written"); + + let scan = collect_entries( + tree.path(), + WalkOptions { + include_hidden: false, + use_gitignore: true, + detail: WalkDetail::Full, + max_depth: 4, + ..test_options() + }, + || Ok::<(), Infallible>(()), + ) + .expect("collection should not fail"); + let EntryScan::Entries(scan) = scan else { + panic!("expected entries"); + }; + let paths = scan + .entries + .into_iter() + .map(|entry| entry.path) + .collect::>(); + + assert!( + !paths.iter().any(|path| path == "ignored.txt"), + "should exclude ignored.txt, got: {paths:?}" + ); + } + #[test] fn collect_entries_prunes_hidden_git_and_node_modules() { let tree = temp_tree("filters");