From 5af43bb3f9705488bbfdf646c7ae15e8d5b68101 Mon Sep 17 00:00:00 2001 From: --help Date: Sat, 13 Jun 2026 13:51:29 +0100 Subject: [PATCH 1/6] Avoid unnecessary git repo rescans when unrelated git files change --- crates/git/src/git.rs | 6 +- crates/worktree/src/worktree.rs | 21 +++++-- .../tests/integration/worktree_tests.rs | 60 ++++++++++++++----- 3 files changed, 67 insertions(+), 20 deletions(-) diff --git a/crates/git/src/git.rs b/crates/git/src/git.rs index c61f819ea27cdc..7792f55e6e3aa0 100644 --- a/crates/git/src/git.rs +++ b/crates/git/src/git.rs @@ -20,8 +20,12 @@ pub const DOT_GIT: &str = ".git"; pub const GITIGNORE: &str = ".gitignore"; pub const FSMONITOR_DAEMON: &str = "fsmonitor--daemon"; pub const LFS_DIR: &str = "lfs"; +pub const OBJECTS_DIR: &str = "objects"; +pub const HOOKS_DIR: &str = "hooks"; +pub const LOGS_HEAD: &str = "logs/HEAD"; +pub const LOGS_REFS_HEADS_DIR: &str = "logs/refs/heads"; +pub const LOGS_REFS_REMOTES_DIR: &str = "logs/refs/remotes"; pub const COMMIT_MESSAGE: &str = "COMMIT_EDITMSG"; -pub const INDEX_LOCK: &str = "index.lock"; pub const REPO_EXCLUDE: &str = "info/exclude"; actions!( diff --git a/crates/worktree/src/worktree.rs b/crates/worktree/src/worktree.rs index af365d828fa3ff..f36ffdd9325330 100644 --- a/crates/worktree/src/worktree.rs +++ b/crates/worktree/src/worktree.rs @@ -22,8 +22,8 @@ use futures::{ }; use fuzzy::CharBag; use git::{ - COMMIT_MESSAGE, DOT_GIT, FSMONITOR_DAEMON, GITIGNORE, INDEX_LOCK, LFS_DIR, REPO_EXCLUDE, - status::GitSummary, + COMMIT_MESSAGE, DOT_GIT, FSMONITOR_DAEMON, GITIGNORE, HOOKS_DIR, LFS_DIR, LOGS_HEAD, + LOGS_REFS_HEADS_DIR, LOGS_REFS_REMOTES_DIR, OBJECTS_DIR, REPO_EXCLUDE, status::GitSummary, }; use gpui::{ App, AppContext as _, AsyncApp, BackgroundExecutor, Context, Entity, EventEmitter, Priority, @@ -4420,8 +4420,16 @@ impl BackgroundScanner { // // Certain directories may have FS changes, but do not lead to git data changes that Zed cares about. // Ignore these, to avoid Zed unnecessarily rescanning git metadata. - let skipped_file_names_in_dot_git = [COMMIT_MESSAGE, INDEX_LOCK]; - let skipped_dirs_in_dot_git = [FSMONITOR_DAEMON, LFS_DIR]; + let skipped_file_names_in_dot_git = [COMMIT_MESSAGE]; + let skipped_dirs_in_dot_git = [ + FSMONITOR_DAEMON, + LFS_DIR, + OBJECTS_DIR, + HOOKS_DIR, + LOGS_HEAD, + LOGS_REFS_HEADS_DIR, + LOGS_REFS_REMOTES_DIR, + ]; let mut dot_git_abs_paths = Vec::new(); let mut work_dirs_needing_exclude_update = Vec::new(); @@ -4456,7 +4464,10 @@ impl BackgroundScanner { .is_some_and(|file_name| file_name == OsStr::new(skipped)) }) || skipped_dirs_in_dot_git .iter() - .any(|skipped_git_subdir| path_in_git_dir.starts_with(skipped_git_subdir)); + .any(|skipped_git_subdir| path_in_git_dir.starts_with(skipped_git_subdir)) + || path_in_git_dir + .extension() + .is_some_and(|extension| extension == "lock"); let is_dot_git = path_in_git_dir == Path::new("") && matches!(event.kind, Some(PathEventKind::Changed)) && self.fs.is_dir(&dot_git_abs_path).await; diff --git a/crates/worktree/tests/integration/worktree_tests.rs b/crates/worktree/tests/integration/worktree_tests.rs index 66cd5f9ba1b33e..e52011471355e4 100644 --- a/crates/worktree/tests/integration/worktree_tests.rs +++ b/crates/worktree/tests/integration/worktree_tests.rs @@ -4108,14 +4108,16 @@ async fn test_linked_worktree_gitfile_event_preserves_repo( } #[gpui::test] -async fn test_linked_worktree_index_lock_event_does_not_emit_git_repo_update( +async fn test_noisy_dot_git_events_do_not_emit_git_repo_update( executor: BackgroundExecutor, cx: &mut TestAppContext, ) { - // Regression test: in a linked worktree, git operations like `git status` - // can touch the worktree-specific `index.lock` under the main repo's - // `.git/worktrees//`. We intend to ignore those events so they do not - // spuriously emit `UpdatedGitRepositories`. + // Events for object database writes, hook files, lock files, and the + // reflogs of HEAD/branches/remote-tracking branches carry no git state + // changes that Zed cares about beyond what the accompanying ref or index + // events already convey, so they must not trigger a git metadata rescan. + // The stash reflog and ref updates themselves must still trigger one. + // init_test(cx); use git::repository::Worktree as GitWorktree; @@ -4177,17 +4179,47 @@ async fn test_linked_worktree_index_lock_event_does_not_emit_git_repo_update( } }); - fs.emit_fs_event( + let skipped_paths = [ + // Standard common git dir skipped paths + path!("/main_repo/.git/objects/aa/bbccddee"), + path!("/main_repo/.git/objects/pack/pack-1234.pack"), + path!("/main_repo/.git/hooks/pre-commit"), + path!("/main_repo/.git/logs/HEAD"), + path!("/main_repo/.git/logs/refs/heads/main"), + path!("/main_repo/.git/logs/refs/remotes/origin/main"), + path!("/main_repo/.git/index.lock"), + path!("/main_repo/.git/refs/heads/main.lock"), + path!("/main_repo/.git/COMMIT_EDITMSG"), + // Linked-worktree specific skipped paths path!("/main_repo/.git/worktrees/feature/index.lock"), - Some(PathEventKind::Changed), - ); - cx.run_until_parked(); + ]; + for path in skipped_paths { + fs.emit_fs_event(path, Some(PathEventKind::Changed)); + cx.run_until_parked(); + assert_eq!( + repo_update_count.get(), + 0, + "event for {path} should not emit UpdatedGitRepositories" + ); + } - assert_eq!( - repo_update_count.get(), - 0, - "linked-worktree index.lock events should not emit UpdatedGitRepositories" - ); + let rescan_paths = [ + // Standard common git dir rescan paths + path!("/main_repo/.git/logs/refs/stash"), + path!("/main_repo/.git/refs/heads/main"), + // Linked-worktree worktree-specific rescan paths + path!("/main_repo/.git/worktrees/feature/index"), + path!("/main_repo/.git/worktrees/feature/HEAD"), + ]; + for path in rescan_paths { + let count_before = repo_update_count.get(); + fs.emit_fs_event(path, Some(PathEventKind::Changed)); + cx.run_until_parked(); + assert!( + repo_update_count.get() > count_before, + "event for {path} should emit UpdatedGitRepositories" + ); + } } #[gpui::test] From 27b915ca54dd08f0d354bfe97e4de55650ff9ba6 Mon Sep 17 00:00:00 2001 From: --help Date: Mon, 15 Jun 2026 00:25:51 +0100 Subject: [PATCH 2/6] Ignore some more git files/dirs --- crates/git/src/git.rs | 11 +++++-- crates/worktree/src/worktree.rs | 30 +++++++++++-------- .../tests/integration/worktree_tests.rs | 11 +++++++ 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/crates/git/src/git.rs b/crates/git/src/git.rs index 7792f55e6e3aa0..0fd3d67814d203 100644 --- a/crates/git/src/git.rs +++ b/crates/git/src/git.rs @@ -22,10 +22,15 @@ pub const FSMONITOR_DAEMON: &str = "fsmonitor--daemon"; pub const LFS_DIR: &str = "lfs"; pub const OBJECTS_DIR: &str = "objects"; pub const HOOKS_DIR: &str = "hooks"; -pub const LOGS_HEAD: &str = "logs/HEAD"; -pub const LOGS_REFS_HEADS_DIR: &str = "logs/refs/heads"; -pub const LOGS_REFS_REMOTES_DIR: &str = "logs/refs/remotes"; +pub const LOGS_DIR: &str = "logs"; +pub const LOGS_REF_STASH: &str = "logs/refs/stash"; +pub const REBASE_MERGE_DIR: &str = "rebase-merge"; +pub const REBASE_APPLY_DIR: &str = "rebase-apply"; +pub const SEQUENCER_DIR: &str = "sequencer"; pub const COMMIT_MESSAGE: &str = "COMMIT_EDITMSG"; +pub const FETCH_HEAD: &str = "FETCH_HEAD"; +pub const ORIG_HEAD: &str = "ORIG_HEAD"; +pub const BISECT_LOG: &str = "BISECT_LOG"; pub const REPO_EXCLUDE: &str = "info/exclude"; actions!( diff --git a/crates/worktree/src/worktree.rs b/crates/worktree/src/worktree.rs index f36ffdd9325330..6a5767daf001a8 100644 --- a/crates/worktree/src/worktree.rs +++ b/crates/worktree/src/worktree.rs @@ -22,8 +22,9 @@ use futures::{ }; use fuzzy::CharBag; use git::{ - COMMIT_MESSAGE, DOT_GIT, FSMONITOR_DAEMON, GITIGNORE, HOOKS_DIR, LFS_DIR, LOGS_HEAD, - LOGS_REFS_HEADS_DIR, LOGS_REFS_REMOTES_DIR, OBJECTS_DIR, REPO_EXCLUDE, status::GitSummary, + BISECT_LOG, COMMIT_MESSAGE, DOT_GIT, FETCH_HEAD, FSMONITOR_DAEMON, GITIGNORE, HOOKS_DIR, + LFS_DIR, LOGS_DIR, LOGS_REF_STASH, OBJECTS_DIR, ORIG_HEAD, REBASE_APPLY_DIR, REBASE_MERGE_DIR, + REPO_EXCLUDE, SEQUENCER_DIR, status::GitSummary, }; use gpui::{ App, AppContext as _, AsyncApp, BackgroundExecutor, Context, Entity, EventEmitter, Priority, @@ -4420,15 +4421,16 @@ impl BackgroundScanner { // // Certain directories may have FS changes, but do not lead to git data changes that Zed cares about. // Ignore these, to avoid Zed unnecessarily rescanning git metadata. - let skipped_file_names_in_dot_git = [COMMIT_MESSAGE]; + let skipped_file_names_in_dot_git = [COMMIT_MESSAGE, FETCH_HEAD, ORIG_HEAD, BISECT_LOG]; + let skipped_extensions_in_dot_git = ["lock", "new", "tmp"]; let skipped_dirs_in_dot_git = [ FSMONITOR_DAEMON, LFS_DIR, OBJECTS_DIR, HOOKS_DIR, - LOGS_HEAD, - LOGS_REFS_HEADS_DIR, - LOGS_REFS_REMOTES_DIR, + REBASE_MERGE_DIR, + REBASE_APPLY_DIR, + SEQUENCER_DIR, ]; let mut dot_git_abs_paths = Vec::new(); @@ -4462,12 +4464,16 @@ impl BackgroundScanner { path_in_git_dir .file_name() .is_some_and(|file_name| file_name == OsStr::new(skipped)) - }) || skipped_dirs_in_dot_git - .iter() - .any(|skipped_git_subdir| path_in_git_dir.starts_with(skipped_git_subdir)) - || path_in_git_dir - .extension() - .is_some_and(|extension| extension == "lock"); + }) || (path_in_git_dir.starts_with(LOGS_DIR) + && path_in_git_dir != Path::new(LOGS_REF_STASH)) + || skipped_dirs_in_dot_git.iter().any(|skipped_git_subdir| { + path_in_git_dir.starts_with(skipped_git_subdir) + }) + || path_in_git_dir.extension().is_some_and(|ext| { + skipped_extensions_in_dot_git + .iter() + .any(|&skipped| ext == skipped) + }); let is_dot_git = path_in_git_dir == Path::new("") && matches!(event.kind, Some(PathEventKind::Changed)) && self.fs.is_dir(&dot_git_abs_path).await; diff --git a/crates/worktree/tests/integration/worktree_tests.rs b/crates/worktree/tests/integration/worktree_tests.rs index e52011471355e4..0427db492ad71e 100644 --- a/crates/worktree/tests/integration/worktree_tests.rs +++ b/crates/worktree/tests/integration/worktree_tests.rs @@ -4187,9 +4187,20 @@ async fn test_noisy_dot_git_events_do_not_emit_git_repo_update( path!("/main_repo/.git/logs/HEAD"), path!("/main_repo/.git/logs/refs/heads/main"), path!("/main_repo/.git/logs/refs/remotes/origin/main"), + path!("/main_repo/.git/logs/refs/tags/v1.0"), + path!("/main_repo/.git/rebase-merge/done"), + path!("/main_repo/.git/rebase-apply/onto"), + path!("/main_repo/.git/sequencer/todo"), path!("/main_repo/.git/index.lock"), path!("/main_repo/.git/refs/heads/main.lock"), path!("/main_repo/.git/COMMIT_EDITMSG"), + path!("/main_repo/.git/packed-refs.new"), + path!("/main_repo/.git/config.new"), + path!("/main_repo/.git/index.new"), + path!("/main_repo/.git/index-abc123.tmp"), + path!("/main_repo/.git/FETCH_HEAD"), + path!("/main_repo/.git/ORIG_HEAD"), + path!("/main_repo/.git/BISECT_LOG"), // Linked-worktree specific skipped paths path!("/main_repo/.git/worktrees/feature/index.lock"), ]; From bc30bea708af0a2c9d5957fcdb84ecd10fee256f Mon Sep 17 00:00:00 2001 From: --help Date: Mon, 15 Jun 2026 01:15:14 +0100 Subject: [PATCH 3/6] Ignore gc.pid and similar --- crates/worktree/src/worktree.rs | 2 +- crates/worktree/tests/integration/worktree_tests.rs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/worktree/src/worktree.rs b/crates/worktree/src/worktree.rs index 6a5767daf001a8..21ee9ec05e3ad6 100644 --- a/crates/worktree/src/worktree.rs +++ b/crates/worktree/src/worktree.rs @@ -4422,7 +4422,7 @@ impl BackgroundScanner { // Certain directories may have FS changes, but do not lead to git data changes that Zed cares about. // Ignore these, to avoid Zed unnecessarily rescanning git metadata. let skipped_file_names_in_dot_git = [COMMIT_MESSAGE, FETCH_HEAD, ORIG_HEAD, BISECT_LOG]; - let skipped_extensions_in_dot_git = ["lock", "new", "tmp"]; + let skipped_extensions_in_dot_git = ["lock", "new", "tmp", "pid"]; let skipped_dirs_in_dot_git = [ FSMONITOR_DAEMON, LFS_DIR, diff --git a/crates/worktree/tests/integration/worktree_tests.rs b/crates/worktree/tests/integration/worktree_tests.rs index 0427db492ad71e..9dfe6af6792243 100644 --- a/crates/worktree/tests/integration/worktree_tests.rs +++ b/crates/worktree/tests/integration/worktree_tests.rs @@ -4201,6 +4201,7 @@ async fn test_noisy_dot_git_events_do_not_emit_git_repo_update( path!("/main_repo/.git/FETCH_HEAD"), path!("/main_repo/.git/ORIG_HEAD"), path!("/main_repo/.git/BISECT_LOG"), + path!("/main_repo/.git/gc.pid"), // Linked-worktree specific skipped paths path!("/main_repo/.git/worktrees/feature/index.lock"), ]; From 1deea354bb5056e6cd77048ae34f29e2bab033d2 Mon Sep 17 00:00:00 2001 From: --help Date: Mon, 15 Jun 2026 01:15:48 +0100 Subject: [PATCH 4/6] Ignore full info/ dir --- crates/git/src/git.rs | 1 + crates/worktree/src/worktree.rs | 6 ++++-- crates/worktree/tests/integration/worktree_tests.rs | 3 +++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/crates/git/src/git.rs b/crates/git/src/git.rs index 0fd3d67814d203..f0e5e03aa5751b 100644 --- a/crates/git/src/git.rs +++ b/crates/git/src/git.rs @@ -31,6 +31,7 @@ pub const COMMIT_MESSAGE: &str = "COMMIT_EDITMSG"; pub const FETCH_HEAD: &str = "FETCH_HEAD"; pub const ORIG_HEAD: &str = "ORIG_HEAD"; pub const BISECT_LOG: &str = "BISECT_LOG"; +pub const INFO_DIR: &str = "info"; pub const REPO_EXCLUDE: &str = "info/exclude"; actions!( diff --git a/crates/worktree/src/worktree.rs b/crates/worktree/src/worktree.rs index 21ee9ec05e3ad6..16d6c39422e201 100644 --- a/crates/worktree/src/worktree.rs +++ b/crates/worktree/src/worktree.rs @@ -23,8 +23,8 @@ use futures::{ use fuzzy::CharBag; use git::{ BISECT_LOG, COMMIT_MESSAGE, DOT_GIT, FETCH_HEAD, FSMONITOR_DAEMON, GITIGNORE, HOOKS_DIR, - LFS_DIR, LOGS_DIR, LOGS_REF_STASH, OBJECTS_DIR, ORIG_HEAD, REBASE_APPLY_DIR, REBASE_MERGE_DIR, - REPO_EXCLUDE, SEQUENCER_DIR, status::GitSummary, + INFO_DIR, LFS_DIR, LOGS_DIR, LOGS_REF_STASH, OBJECTS_DIR, ORIG_HEAD, REBASE_APPLY_DIR, + REBASE_MERGE_DIR, REPO_EXCLUDE, SEQUENCER_DIR, status::GitSummary, }; use gpui::{ App, AppContext as _, AsyncApp, BackgroundExecutor, Context, Entity, EventEmitter, Priority, @@ -4466,6 +4466,8 @@ impl BackgroundScanner { .is_some_and(|file_name| file_name == OsStr::new(skipped)) }) || (path_in_git_dir.starts_with(LOGS_DIR) && path_in_git_dir != Path::new(LOGS_REF_STASH)) + || (path_in_git_dir.starts_with(INFO_DIR) + && path_in_git_dir != Path::new(REPO_EXCLUDE)) || skipped_dirs_in_dot_git.iter().any(|skipped_git_subdir| { path_in_git_dir.starts_with(skipped_git_subdir) }) diff --git a/crates/worktree/tests/integration/worktree_tests.rs b/crates/worktree/tests/integration/worktree_tests.rs index 9dfe6af6792243..29fb9ea0f3d270 100644 --- a/crates/worktree/tests/integration/worktree_tests.rs +++ b/crates/worktree/tests/integration/worktree_tests.rs @@ -4201,6 +4201,8 @@ async fn test_noisy_dot_git_events_do_not_emit_git_repo_update( path!("/main_repo/.git/FETCH_HEAD"), path!("/main_repo/.git/ORIG_HEAD"), path!("/main_repo/.git/BISECT_LOG"), + path!("/main_repo/.git/info/refs"), + path!("/main_repo/.git/info/refs_lzOf51"), path!("/main_repo/.git/gc.pid"), // Linked-worktree specific skipped paths path!("/main_repo/.git/worktrees/feature/index.lock"), @@ -4219,6 +4221,7 @@ async fn test_noisy_dot_git_events_do_not_emit_git_repo_update( // Standard common git dir rescan paths path!("/main_repo/.git/logs/refs/stash"), path!("/main_repo/.git/refs/heads/main"), + path!("/main_repo/.git/info/exclude"), // Linked-worktree worktree-specific rescan paths path!("/main_repo/.git/worktrees/feature/index"), path!("/main_repo/.git/worktrees/feature/HEAD"), From 306c6ef55341583096881d0e35aee40f18e1c283 Mon Sep 17 00:00:00 2001 From: --help Date: Mon, 15 Jun 2026 01:41:04 +0100 Subject: [PATCH 5/6] Make gc.pid ignore explicit since it seems like it's the only .pid file generated by git --- crates/git/src/git.rs | 1 + crates/worktree/src/worktree.rs | 11 ++++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/crates/git/src/git.rs b/crates/git/src/git.rs index f0e5e03aa5751b..5b31243fb9a99c 100644 --- a/crates/git/src/git.rs +++ b/crates/git/src/git.rs @@ -31,6 +31,7 @@ pub const COMMIT_MESSAGE: &str = "COMMIT_EDITMSG"; pub const FETCH_HEAD: &str = "FETCH_HEAD"; pub const ORIG_HEAD: &str = "ORIG_HEAD"; pub const BISECT_LOG: &str = "BISECT_LOG"; +pub const GC_PID: &str = "gc.pid"; pub const INFO_DIR: &str = "info"; pub const REPO_EXCLUDE: &str = "info/exclude"; diff --git a/crates/worktree/src/worktree.rs b/crates/worktree/src/worktree.rs index 16d6c39422e201..b04aa933c6ed4d 100644 --- a/crates/worktree/src/worktree.rs +++ b/crates/worktree/src/worktree.rs @@ -22,9 +22,9 @@ use futures::{ }; use fuzzy::CharBag; use git::{ - BISECT_LOG, COMMIT_MESSAGE, DOT_GIT, FETCH_HEAD, FSMONITOR_DAEMON, GITIGNORE, HOOKS_DIR, - INFO_DIR, LFS_DIR, LOGS_DIR, LOGS_REF_STASH, OBJECTS_DIR, ORIG_HEAD, REBASE_APPLY_DIR, - REBASE_MERGE_DIR, REPO_EXCLUDE, SEQUENCER_DIR, status::GitSummary, + BISECT_LOG, COMMIT_MESSAGE, DOT_GIT, FETCH_HEAD, FSMONITOR_DAEMON, GC_PID, GITIGNORE, + HOOKS_DIR, INFO_DIR, LFS_DIR, LOGS_DIR, LOGS_REF_STASH, OBJECTS_DIR, ORIG_HEAD, + REBASE_APPLY_DIR, REBASE_MERGE_DIR, REPO_EXCLUDE, SEQUENCER_DIR, status::GitSummary, }; use gpui::{ App, AppContext as _, AsyncApp, BackgroundExecutor, Context, Entity, EventEmitter, Priority, @@ -4421,8 +4421,9 @@ impl BackgroundScanner { // // Certain directories may have FS changes, but do not lead to git data changes that Zed cares about. // Ignore these, to avoid Zed unnecessarily rescanning git metadata. - let skipped_file_names_in_dot_git = [COMMIT_MESSAGE, FETCH_HEAD, ORIG_HEAD, BISECT_LOG]; - let skipped_extensions_in_dot_git = ["lock", "new", "tmp", "pid"]; + let skipped_file_names_in_dot_git = + [COMMIT_MESSAGE, FETCH_HEAD, ORIG_HEAD, BISECT_LOG, GC_PID]; + let skipped_extensions_in_dot_git = ["lock", "new", "tmp"]; let skipped_dirs_in_dot_git = [ FSMONITOR_DAEMON, LFS_DIR, From b666bbb8f7f1dd5064c6829a8920e7489bd71642 Mon Sep 17 00:00:00 2001 From: --help Date: Mon, 15 Jun 2026 01:53:26 +0100 Subject: [PATCH 6/6] Only ignore changes to *.new and *.tmp files in the top level dir since they are allowed branch suffixes --- crates/worktree/src/worktree.rs | 11 +++++------ crates/worktree/tests/integration/worktree_tests.rs | 2 ++ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/crates/worktree/src/worktree.rs b/crates/worktree/src/worktree.rs index b04aa933c6ed4d..a340fbf90e7900 100644 --- a/crates/worktree/src/worktree.rs +++ b/crates/worktree/src/worktree.rs @@ -4423,7 +4423,6 @@ impl BackgroundScanner { // Ignore these, to avoid Zed unnecessarily rescanning git metadata. let skipped_file_names_in_dot_git = [COMMIT_MESSAGE, FETCH_HEAD, ORIG_HEAD, BISECT_LOG, GC_PID]; - let skipped_extensions_in_dot_git = ["lock", "new", "tmp"]; let skipped_dirs_in_dot_git = [ FSMONITOR_DAEMON, LFS_DIR, @@ -4472,11 +4471,11 @@ impl BackgroundScanner { || skipped_dirs_in_dot_git.iter().any(|skipped_git_subdir| { path_in_git_dir.starts_with(skipped_git_subdir) }) - || path_in_git_dir.extension().is_some_and(|ext| { - skipped_extensions_in_dot_git - .iter() - .any(|&skipped| ext == skipped) - }); + || path_in_git_dir.extension().is_some_and(|ext| ext == "lock") + || (path_in_git_dir.components().count() == 1 + && path_in_git_dir + .extension() + .is_some_and(|ext| ext == "new" || ext == "tmp")); let is_dot_git = path_in_git_dir == Path::new("") && matches!(event.kind, Some(PathEventKind::Changed)) && self.fs.is_dir(&dot_git_abs_path).await; diff --git a/crates/worktree/tests/integration/worktree_tests.rs b/crates/worktree/tests/integration/worktree_tests.rs index 29fb9ea0f3d270..3331168b454bb1 100644 --- a/crates/worktree/tests/integration/worktree_tests.rs +++ b/crates/worktree/tests/integration/worktree_tests.rs @@ -4222,6 +4222,8 @@ async fn test_noisy_dot_git_events_do_not_emit_git_repo_update( path!("/main_repo/.git/logs/refs/stash"), path!("/main_repo/.git/refs/heads/main"), path!("/main_repo/.git/info/exclude"), + path!("/main_repo/.git/refs/heads/branch.new"), + path!("/main_repo/.git/refs/heads/branch.tmp"), // Linked-worktree worktree-specific rescan paths path!("/main_repo/.git/worktrees/feature/index"), path!("/main_repo/.git/worktrees/feature/HEAD"),