From 32c6ae3188ebd1db206dfa8749540b4f5d285f63 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 8 Jul 2022 11:24:32 +0200 Subject: [PATCH] :art: --- crates/project/src/worktree.rs | 45 ++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/crates/project/src/worktree.rs b/crates/project/src/worktree.rs index 5f8739fd88..dbd4b443a1 100644 --- a/crates/project/src/worktree.rs +++ b/crates/project/src/worktree.rs @@ -102,7 +102,7 @@ pub struct Snapshot { #[derive(Clone)] pub struct LocalSnapshot { abs_path: Arc, - ignores_by_abs_path: HashMap, (Arc, usize)>, + ignores_by_parent_abs_path: HashMap, (Arc, usize)>, removed_entry_ids: HashMap, next_entry_id: Arc, snapshot: Snapshot, @@ -370,7 +370,7 @@ impl LocalWorktree { let tree = cx.add_model(move |cx: &mut ModelContext| { let mut snapshot = LocalSnapshot { abs_path, - ignores_by_abs_path: Default::default(), + ignores_by_parent_abs_path: Default::default(), removed_entry_ids: Default::default(), next_entry_id, snapshot: Snapshot { @@ -1333,7 +1333,7 @@ impl LocalSnapshot { let abs_path = self.abs_path.join(&entry.path); match smol::block_on(build_gitignore(&abs_path, fs)) { Ok(ignore) => { - self.ignores_by_abs_path.insert( + self.ignores_by_parent_abs_path.insert( abs_path.parent().unwrap().into(), (Arc::new(ignore), self.scan_id), ); @@ -1388,7 +1388,7 @@ impl LocalSnapshot { }; if let Some(ignore) = ignore { - self.ignores_by_abs_path.insert( + self.ignores_by_parent_abs_path.insert( self.abs_path.join(&parent_path).into(), (ignore, self.scan_id), ); @@ -1477,7 +1477,9 @@ impl LocalSnapshot { if path.file_name() == Some(&GITIGNORE) { let abs_parent_path = self.abs_path.join(path.parent().unwrap()); - if let Some((_, scan_id)) = self.ignores_by_abs_path.get_mut(abs_parent_path.as_path()) + if let Some((_, scan_id)) = self + .ignores_by_parent_abs_path + .get_mut(abs_parent_path.as_path()) { *scan_id = self.snapshot.scan_id; } @@ -1487,7 +1489,7 @@ impl LocalSnapshot { fn ignore_stack_for_abs_path(&self, abs_path: &Path, is_dir: bool) -> Arc { let mut new_ignores = Vec::new(); for ancestor in abs_path.ancestors().skip(1) { - if let Some((ignore, _)) = self.ignores_by_abs_path.get(ancestor) { + if let Some((ignore, _)) = self.ignores_by_parent_abs_path.get(ancestor) { new_ignores.push((ancestor, Some(ignore.clone()))); } else { new_ignores.push((ancestor, None)); @@ -2063,18 +2065,25 @@ impl BackgroundScanner { { self.snapshot .lock() - .ignores_by_abs_path + .ignores_by_parent_abs_path .insert(ancestor.into(), (ignore.into(), 0)); } } + let ignore_stack = { + let mut snapshot = self.snapshot.lock(); + let ignore_stack = snapshot.ignore_stack_for_abs_path(&root_abs_path, true); + if ignore_stack.is_all() { + if let Some(mut root_entry) = snapshot.root_entry().cloned() { + root_entry.is_ignored = true; + snapshot.insert_entry(root_entry, self.fs.as_ref()); + } + } + ignore_stack + }; + if is_dir { let path: Arc = Arc::from(Path::new("")); - let ignore_stack = self - .snapshot - .lock() - .ignore_stack_for_abs_path(&root_abs_path, true); - let (tx, rx) = channel::unbounded(); self.executor .block(tx.send(ScanJob { @@ -2329,7 +2338,7 @@ impl BackgroundScanner { let mut ignores_to_update = Vec::new(); let mut ignores_to_delete = Vec::new(); - for (parent_abs_path, (_, scan_id)) in &snapshot.ignores_by_abs_path { + for (parent_abs_path, (_, scan_id)) in &snapshot.ignores_by_parent_abs_path { if let Ok(parent_path) = parent_abs_path.strip_prefix(&snapshot.abs_path) { if *scan_id == snapshot.scan_id && snapshot.entry_for_path(parent_path).is_some() { ignores_to_update.push(parent_abs_path.clone()); @@ -2343,10 +2352,10 @@ impl BackgroundScanner { } for parent_abs_path in ignores_to_delete { - snapshot.ignores_by_abs_path.remove(&parent_abs_path); + snapshot.ignores_by_parent_abs_path.remove(&parent_abs_path); self.snapshot .lock() - .ignores_by_abs_path + .ignores_by_parent_abs_path .remove(&parent_abs_path); } @@ -2388,7 +2397,7 @@ impl BackgroundScanner { async fn update_ignore_status(&self, job: UpdateIgnoreStatusJob, snapshot: &LocalSnapshot) { let mut ignore_stack = job.ignore_stack; - if let Some((ignore, _)) = snapshot.ignores_by_abs_path.get(&job.abs_path) { + if let Some((ignore, _)) = snapshot.ignores_by_parent_abs_path.get(&job.abs_path) { ignore_stack = ignore_stack.append(job.abs_path.clone(), ignore.clone()); } @@ -2955,7 +2964,7 @@ mod tests { let mut initial_snapshot = LocalSnapshot { abs_path: root_dir.path().into(), removed_entry_ids: Default::default(), - ignores_by_abs_path: Default::default(), + ignores_by_parent_abs_path: Default::default(), next_entry_id: next_entry_id.clone(), snapshot: Snapshot { id: WorktreeId::from_usize(0), @@ -3240,7 +3249,7 @@ mod tests { .collect::>(); assert_eq!(dfs_paths_via_traversal, dfs_paths_via_iter); - for (ignore_parent_abs_path, _) in &self.ignores_by_abs_path { + for (ignore_parent_abs_path, _) in &self.ignores_by_parent_abs_path { let ignore_parent_path = ignore_parent_abs_path.strip_prefix(&self.abs_path).unwrap(); assert!(self.entry_for_path(&ignore_parent_path).is_some());