From f50b9a9ac735b43ca8baca93af54e1a7a981ed7b Mon Sep 17 00:00:00 2001 From: nityam <185968020+Nixxx19@users.noreply.github.com> Date: Wed, 2 Sep 2026 03:18:22 +0530 Subject: [PATCH] fix: only treat files literally named .gitignore as ignore files in the untracked walk --- crates/turborepo-scm/src/repo_index.rs | 33 +++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/crates/turborepo-scm/src/repo_index.rs b/crates/turborepo-scm/src/repo_index.rs index fe3afc914e804..fda713f819589 100644 --- a/crates/turborepo-scm/src/repo_index.rs +++ b/crates/turborepo-scm/src/repo_index.rs @@ -995,7 +995,7 @@ fn find_untracked_files( .filter(|e| !e.is_delete) .map(|e| e.path.as_str()), ) - .filter(|s| *s == ".gitignore" || s.ends_with("/.gitignore")) + .filter(|s| is_gitignore_file(s)) .collect(); gitignore_paths.sort_unstable(); gitignore_paths.dedup(); @@ -1225,7 +1225,7 @@ fn find_untracked_files( let untracked_gitignores: Vec<&RelativeUnixPathBuf> = untracked .paths .iter() - .filter(|p| p.as_str().ends_with(".gitignore")) + .filter(|p| is_gitignore_file(p.as_str())) .collect(); if !untracked_gitignores.is_empty() { @@ -1244,7 +1244,7 @@ fn find_untracked_files( } if !extra_matchers.is_empty() { let not_ignored = |p: &RelativeUnixPathBuf| { - if p.as_str().ends_with(".gitignore") { + if is_gitignore_file(p.as_str()) { return true; } let abs = root.join(p.as_str()); @@ -1357,6 +1357,10 @@ impl UntrackedScope { } } +fn is_gitignore_file(path: &str) -> bool { + path == ".gitignore" || path.ends_with("/.gitignore") +} + fn is_nested_path(path: &str, prefix: &str) -> bool { is_nested_path_bytes(path.as_bytes(), prefix.as_bytes()) } @@ -2091,6 +2095,29 @@ mod tests { assert_eq!(untracked, vec![path("pkg/debug.log")]); } + #[test] + fn test_find_untracked_files_ignores_untracked_suffix_named_gitignore_files() { + let tempdir = TempDir::new().unwrap(); + let root = tempdir.path(); + let git = test_git_repo(root); + + write_file(root, "pkg/Node.gitignore", "*.log\n"); + write_file(root, "pkg/debug.log", "untracked"); + + let index = make_index(vec![], vec![]); + + let mut untracked = + find_untracked_files(&git, &index.ls_tree_hashes, &index.status_entries, None) + .unwrap() + .paths; + untracked.sort(); + + assert_eq!( + untracked, + vec![path("pkg/Node.gitignore"), path("pkg/debug.log")] + ); + } + #[test] fn test_status_binary_search_matches_linear_scan() { let index = make_index(