diff --git a/crates/project/src/ignore.rs b/crates/project/src/ignore.rs index a29e00501960367c72beca7e364b418cfbac8901..ed1ce4006d9ed90269d5d3ca184b0ff9c5fde590 100644 --- a/crates/project/src/ignore.rs +++ b/crates/project/src/ignore.rs @@ -20,10 +20,6 @@ impl IgnoreStack { Arc::new(Self::All) } - pub fn is_all(&self) -> bool { - matches!(self, Self::All) - } - pub fn append(self: Arc, abs_base_path: Arc, ignore: Arc) -> Arc { match self.as_ref() { IgnoreStack::All => self, diff --git a/crates/project/src/worktree.rs b/crates/project/src/worktree.rs index e8114832c24576fe888ae1d8e72630e6269e467d..1dd0771cfe3deb1fb43bacd1c05f8f0e171335bb 100644 --- a/crates/project/src/worktree.rs +++ b/crates/project/src/worktree.rs @@ -2234,8 +2234,8 @@ impl LocalSnapshot { } impl BackgroundScannerState { - fn should_scan_directory(&self, entry: &Entry, entry_abs_path: &Path) -> bool { - !entry.is_external && !self.snapshot.is_abs_path_excluded(entry_abs_path) + fn should_scan_directory(&self, entry: &Entry) -> bool { + (!entry.is_external && !entry.is_ignored) || entry.path.file_name() == Some(&*DOT_GIT) || self.scanned_dirs.contains(&entry.id) // If we've ever scanned it, keep scanning || self @@ -2253,7 +2253,7 @@ impl BackgroundScannerState { let ignore_stack = self.snapshot.ignore_stack_for_abs_path(&abs_path, true); let mut ancestor_inodes = self.snapshot.ancestor_inodes_for_path(&path); let mut containing_repository = None; - if !ignore_stack.is_all() && !self.snapshot.is_abs_path_excluded(&abs_path) { + if !ignore_stack.is_abs_path_ignored(&abs_path, true) { if let Some((workdir_path, repo)) = self.snapshot.local_repo_for_path(&path) { if let Ok(repo_path) = path.strip_prefix(&workdir_path.0) { containing_repository = Some(( @@ -2338,6 +2338,7 @@ impl BackgroundScannerState { self.scanned_dirs.insert(parent_entry_id); let mut entries_by_path_edits = vec![Edit::Insert(parent_entry)]; let mut entries_by_id_edits = Vec::new(); + for entry in entries { entries_by_id_edits.push(Edit::Insert(PathEntry { id: entry.id, @@ -2852,7 +2853,7 @@ pub struct Entry { pub mtime: SystemTime, pub is_symlink: bool, - /// Whether this entry is ignored by Zed. + /// Whether this entry is ignored by Git. /// /// We only scan ignored entries once the directory is expanded and /// exclude them from searches. @@ -3326,7 +3327,9 @@ impl BackgroundScanner { return false; } if snapshot.is_abs_path_excluded(abs_path) { - log::debug!("ignoring event {relative_path:?} within excluded directory"); + log::debug!( + "ignoring FS event for path {relative_path:?} within excluded directory" + ); return false; } @@ -3638,6 +3641,7 @@ impl BackgroundScanner { ancestor_inodes.insert(child_entry.inode); new_jobs.push(Some(ScanJob { + abs_path: child_abs_path, path: child_path, is_external: child_entry.is_external, ignore_stack: if child_entry.is_ignored { @@ -3646,7 +3650,6 @@ impl BackgroundScanner { ignore_stack.clone() }, ancestor_inodes, - abs_path: child_abs_path, scan_queue: job.scan_queue.clone(), containing_repository: job.containing_repository.clone(), })); @@ -3655,17 +3658,19 @@ impl BackgroundScanner { } } else { child_entry.is_ignored = ignore_stack.is_abs_path_ignored(&child_abs_path, false); - if let Some((repository_dir, repository, staged_statuses)) = - &job.containing_repository - { - if let Ok(repo_path) = child_entry.path.strip_prefix(&repository_dir.0) { - let repo_path = RepoPath(repo_path.into()); - child_entry.git_status = combine_git_statuses( - staged_statuses.get(&repo_path).copied(), - repository - .lock() - .unstaged_status(&repo_path, child_entry.mtime), - ); + if !child_entry.is_ignored { + if let Some((repository_dir, repository, staged_statuses)) = + &job.containing_repository + { + if let Ok(repo_path) = child_entry.path.strip_prefix(&repository_dir.0) { + let repo_path = RepoPath(repo_path.into()); + child_entry.git_status = combine_git_statuses( + staged_statuses.get(&repo_path).copied(), + repository + .lock() + .unstaged_status(&repo_path, child_entry.mtime), + ); + } } } } @@ -3680,9 +3685,7 @@ impl BackgroundScanner { for entry in &mut new_entries { state.reuse_entry_id(entry); if entry.is_dir() { - if !ignore_stack.is_all() - && state.should_scan_directory(&entry, &root_abs_path.join(&entry.path)) - { + if state.should_scan_directory(&entry) { job_ix += 1; } else { log::debug!("defer scanning directory {:?}", entry.path); @@ -3773,9 +3776,7 @@ impl BackgroundScanner { fs_entry.is_ignored = ignore_stack.is_abs_path_ignored(&abs_path, is_dir); fs_entry.is_external = !canonical_path.starts_with(&root_canonical_path); - if !is_dir - && !(fs_entry.is_ignored || state.snapshot.is_abs_path_excluded(&abs_path)) - { + if !is_dir && !fs_entry.is_ignored { if let Some((work_dir, repo)) = state.snapshot.local_repo_for_path(&path) { if let Ok(repo_path) = path.strip_prefix(work_dir.0) { let repo_path = RepoPath(repo_path.into()); @@ -3786,7 +3787,7 @@ impl BackgroundScanner { } if let (Some(scan_queue_tx), true) = (&scan_queue_tx, fs_entry.is_dir()) { - if state.should_scan_directory(&fs_entry, &abs_path) { + if state.should_scan_directory(&fs_entry) { state.enqueue_scan_dir(abs_path, &fs_entry, scan_queue_tx); } else { fs_entry.kind = EntryKind::UnloadedDir; @@ -3942,7 +3943,7 @@ impl BackgroundScanner { // Scan any directories that were previously ignored and weren't previously scanned. if was_ignored && !entry.is_ignored && entry.kind.is_unloaded() { let state = self.state.lock(); - if state.should_scan_directory(&entry, &abs_path) { + if state.should_scan_directory(&entry) { state.enqueue_scan_dir(abs_path.clone(), &entry, &job.scan_queue); } } diff --git a/crates/project/src/worktree_tests.rs b/crates/project/src/worktree_tests.rs index cd7f3cff81d0d0101cdf871c3c5e255d675a2e71..f2b519021cdb48ac17b0646a88b94bf76ad75ffa 100644 --- a/crates/project/src/worktree_tests.rs +++ b/crates/project/src/worktree_tests.rs @@ -946,7 +946,7 @@ async fn test_file_scan_exclusions(cx: &mut TestAppContext) { "src/.DS_Store", ".DS_Store", ], - &["target/index", "node_modules/prettier/package.json"], + &["target", "node_modules"], &["src/lib.rs", "src/bar/bar.rs", ".gitignore"], ) }); @@ -967,8 +967,9 @@ async fn test_file_scan_exclusions(cx: &mut TestAppContext) { &[ "node_modules/prettier/package.json", "node_modules/.DS_Store", + "node_modules", ], - &["target/index"], + &["target"], &[ ".gitignore", "src/lib.rs",