mirror of
https://github.com/zed-industries/zed.git
synced 2024-09-19 18:41:56 +03:00
Properly ignore FS events of excluded files
This commit is contained in:
parent
4a060db801
commit
95a413847a
@ -5835,7 +5835,7 @@ impl Project {
|
||||
ignored_paths_to_process.pop_front()
|
||||
{
|
||||
if !query.file_matches(Some(&ignored_abs_path))
|
||||
|| snapshot.is_abs_path_excluded(&ignored_abs_path)
|
||||
|| snapshot.is_path_excluded(&ignored_abs_path)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -2226,7 +2226,7 @@ impl LocalSnapshot {
|
||||
paths
|
||||
}
|
||||
|
||||
pub fn is_abs_path_excluded(&self, abs_path: &Path) -> bool {
|
||||
pub fn is_path_excluded(&self, abs_path: &Path) -> bool {
|
||||
self.file_scan_exclusions
|
||||
.iter()
|
||||
.any(|exclude_matcher| exclude_matcher.is_match(abs_path))
|
||||
@ -2399,26 +2399,14 @@ impl BackgroundScannerState {
|
||||
self.snapshot.check_invariants(false);
|
||||
}
|
||||
|
||||
fn reload_repositories(&mut self, changed_paths: &[Arc<Path>], fs: &dyn Fs) {
|
||||
fn reload_repositories(&mut self, dot_git_dirs_to_reload: &HashSet<PathBuf>, fs: &dyn Fs) {
|
||||
if dot_git_dirs_to_reload.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
log::debug!("reloading repositories: {dot_git_dirs_to_reload:?}");
|
||||
let scan_id = self.snapshot.scan_id;
|
||||
|
||||
// Find each of the .git directories that contain any of the given paths.
|
||||
let mut prev_dot_git_dir = None;
|
||||
for changed_path in changed_paths {
|
||||
let Some(dot_git_dir) = changed_path
|
||||
.ancestors()
|
||||
.find(|ancestor| ancestor.file_name() == Some(&*DOT_GIT))
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
|
||||
// Avoid processing the same repository multiple times, if multiple paths
|
||||
// within it have changed.
|
||||
if prev_dot_git_dir == Some(dot_git_dir) {
|
||||
continue;
|
||||
}
|
||||
prev_dot_git_dir = Some(dot_git_dir);
|
||||
|
||||
for dot_git_dir in dot_git_dirs_to_reload {
|
||||
// If there is already a repository for this .git directory, reload
|
||||
// the status for all of its files.
|
||||
let repository = self
|
||||
@ -2430,7 +2418,7 @@ impl BackgroundScannerState {
|
||||
});
|
||||
match repository {
|
||||
None => {
|
||||
self.build_git_repository(dot_git_dir.into(), fs);
|
||||
self.build_git_repository(Arc::from(dot_git_dir.as_path()), fs);
|
||||
}
|
||||
Some((entry_id, repository)) => {
|
||||
if repository.git_dir_scan_id == scan_id {
|
||||
@ -2444,7 +2432,7 @@ impl BackgroundScannerState {
|
||||
continue;
|
||||
};
|
||||
|
||||
log::info!("reload git repository {:?}", dot_git_dir);
|
||||
log::info!("reload git repository {dot_git_dir:?}");
|
||||
let repository = repository.repo_ptr.lock();
|
||||
let branch = repository.branch_name();
|
||||
repository.reload_index();
|
||||
@ -2475,7 +2463,9 @@ impl BackgroundScannerState {
|
||||
ids_to_preserve.insert(work_directory_id);
|
||||
} else {
|
||||
let git_dir_abs_path = snapshot.abs_path().join(&entry.git_dir_path);
|
||||
if snapshot.is_abs_path_excluded(&git_dir_abs_path)
|
||||
let git_dir_excluded = snapshot.is_path_excluded(&entry.git_dir_path)
|
||||
|| snapshot.is_path_excluded(&git_dir_abs_path);
|
||||
if git_dir_excluded
|
||||
&& !matches!(smol::block_on(fs.metadata(&git_dir_abs_path)), Ok(None))
|
||||
{
|
||||
ids_to_preserve.insert(work_directory_id);
|
||||
@ -3314,11 +3304,24 @@ impl BackgroundScanner {
|
||||
};
|
||||
|
||||
let mut relative_paths = Vec::with_capacity(abs_paths.len());
|
||||
let mut dot_git_paths_to_reload = HashSet::default();
|
||||
abs_paths.sort_unstable();
|
||||
abs_paths.dedup_by(|a, b| a.starts_with(&b));
|
||||
abs_paths.retain(|abs_path| {
|
||||
let snapshot = &self.state.lock().snapshot;
|
||||
{
|
||||
if let Some(dot_git_dir) = abs_path
|
||||
.ancestors()
|
||||
.find(|ancestor| ancestor.file_name() == Some(&*DOT_GIT))
|
||||
{
|
||||
let dog_git_path = dot_git_dir
|
||||
.strip_prefix(&root_canonical_path)
|
||||
.ok()
|
||||
.map(|path| path.to_path_buf())
|
||||
.unwrap_or_else(|| dot_git_dir.to_path_buf());
|
||||
dot_git_paths_to_reload.insert(dog_git_path.to_path_buf());
|
||||
}
|
||||
|
||||
let relative_path: Arc<Path> =
|
||||
if let Ok(path) = abs_path.strip_prefix(&root_canonical_path) {
|
||||
path.into()
|
||||
@ -3328,24 +3331,29 @@ impl BackgroundScanner {
|
||||
);
|
||||
return false;
|
||||
};
|
||||
let parent_dir_is_loaded = relative_path.parent().map_or(true, |parent| {
|
||||
snapshot
|
||||
.entry_for_path(parent)
|
||||
.map_or(false, |entry| entry.kind == EntryKind::Dir)
|
||||
});
|
||||
if !parent_dir_is_loaded {
|
||||
log::debug!("ignoring event {relative_path:?} within unloaded directory");
|
||||
return false;
|
||||
}
|
||||
|
||||
if !is_git_related(&abs_path) {
|
||||
let parent_dir_is_loaded = relative_path.parent().map_or(true, |parent| {
|
||||
snapshot
|
||||
.entry_for_path(parent)
|
||||
.map_or(false, |entry| entry.kind == EntryKind::Dir)
|
||||
});
|
||||
if !parent_dir_is_loaded {
|
||||
log::debug!("ignoring event {relative_path:?} within unloaded directory");
|
||||
return false;
|
||||
}
|
||||
if snapshot.is_abs_path_excluded(abs_path) {
|
||||
log::debug!(
|
||||
"ignoring FS event for path {relative_path:?} within excluded directory"
|
||||
);
|
||||
return false;
|
||||
// FS events may come for files which parent directory is excluded, need to check ignore those.
|
||||
let mut path_to_test = abs_path.clone();
|
||||
let mut excluded_file_event = snapshot.is_path_excluded(abs_path)
|
||||
|| snapshot.is_path_excluded(&relative_path);
|
||||
while !excluded_file_event && path_to_test.pop() {
|
||||
if snapshot.is_path_excluded(&path_to_test) {
|
||||
excluded_file_event = true;
|
||||
}
|
||||
}
|
||||
if excluded_file_event {
|
||||
log::debug!("ignoring FS event for excluded path {relative_path:?}");
|
||||
return false;
|
||||
}
|
||||
|
||||
relative_paths.push(relative_path);
|
||||
true
|
||||
@ -3376,7 +3384,7 @@ impl BackgroundScanner {
|
||||
|
||||
{
|
||||
let mut state = self.state.lock();
|
||||
state.reload_repositories(&relative_paths, self.fs.as_ref());
|
||||
state.reload_repositories(&dot_git_paths_to_reload, self.fs.as_ref());
|
||||
state.snapshot.completed_scan_id = state.snapshot.scan_id;
|
||||
for (_, entry_id) in mem::take(&mut state.removed_entry_ids) {
|
||||
state.scanned_dirs.remove(&entry_id);
|
||||
@ -3516,7 +3524,7 @@ impl BackgroundScanner {
|
||||
let state = self.state.lock();
|
||||
let snapshot = &state.snapshot;
|
||||
root_abs_path = snapshot.abs_path().clone();
|
||||
if snapshot.is_abs_path_excluded(&job.abs_path) {
|
||||
if snapshot.is_path_excluded(&job.abs_path) {
|
||||
log::error!("skipping excluded directory {:?}", job.path);
|
||||
return Ok(());
|
||||
}
|
||||
@ -3588,7 +3596,7 @@ impl BackgroundScanner {
|
||||
|
||||
{
|
||||
let mut state = self.state.lock();
|
||||
if state.snapshot.is_abs_path_excluded(&child_abs_path) {
|
||||
if state.snapshot.is_path_excluded(&child_abs_path) {
|
||||
let relative_path = job.path.join(child_name);
|
||||
log::debug!("skipping excluded child entry {relative_path:?}");
|
||||
state.remove_path(&relative_path);
|
||||
@ -4130,12 +4138,6 @@ impl BackgroundScanner {
|
||||
}
|
||||
}
|
||||
|
||||
fn is_git_related(abs_path: &Path) -> bool {
|
||||
abs_path
|
||||
.components()
|
||||
.any(|c| c.as_os_str() == *DOT_GIT || c.as_os_str() == *GITIGNORE)
|
||||
}
|
||||
|
||||
fn char_bag_for_path(root_char_bag: CharBag, path: &Path) -> CharBag {
|
||||
let mut result = root_char_bag;
|
||||
result.extend(
|
||||
|
Loading…
Reference in New Issue
Block a user