Don't create repos for invisible worktrees (#27894)

Closes #ISSUE

Release Notes:

- Fixed git repositories being added for files outside the project
This commit is contained in:
Cole Miller 2025-04-02 11:11:12 -04:00 committed by GitHub
parent d82bf132ca
commit 8ac4cbcbb9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 76 additions and 5 deletions

View file

@ -1017,7 +1017,18 @@ impl GitStore {
} }
} }
WorktreeStoreEvent::WorktreeUpdatedGitRepositories(worktree_id, changed_repos) => { WorktreeStoreEvent::WorktreeUpdatedGitRepositories(worktree_id, changed_repos) => {
self.update_repositories_from_worktrees( let Some(worktree) = worktree_store.read(cx).worktree_for_id(*worktree_id, cx)
else {
return;
};
if !worktree.read(cx).is_visible() {
log::debug!(
"not adding repositories for local worktree {:?} because it's not visible",
worktree.read(cx).abs_path()
);
return;
}
self.update_repositories_from_worktree(
project_environment.clone(), project_environment.clone(),
next_repository_id.clone(), next_repository_id.clone(),
downstream downstream
@ -1027,9 +1038,7 @@ impl GitStore {
fs.clone(), fs.clone(),
cx, cx,
); );
if let Some(worktree) = worktree_store.read(cx).worktree_for_id(*worktree_id, cx) { self.local_worktree_git_repos_changed(worktree, changed_repos, cx);
self.local_worktree_git_repos_changed(worktree, changed_repos, cx);
}
} }
_ => {} _ => {}
} }
@ -1050,7 +1059,7 @@ impl GitStore {
} }
/// Update our list of repositories and schedule git scans in response to a notification from a worktree, /// Update our list of repositories and schedule git scans in response to a notification from a worktree,
fn update_repositories_from_worktrees( fn update_repositories_from_worktree(
&mut self, &mut self,
project_environment: Entity<ProjectEnvironment>, project_environment: Entity<ProjectEnvironment>,
next_repository_id: Arc<AtomicU64>, next_repository_id: Arc<AtomicU64>,

View file

@ -7851,6 +7851,68 @@ async fn test_file_status(cx: &mut gpui::TestAppContext) {
}); });
} }
#[gpui::test]
async fn test_repos_in_invisible_worktrees(
executor: BackgroundExecutor,
cx: &mut gpui::TestAppContext,
) {
init_test(cx);
let fs = FakeFs::new(executor);
fs.insert_tree(
path!("/root"),
json!({
"dir1": {
".git": {},
"dep1": {
".git": {},
"src": {
"a.txt": "",
},
},
"b.txt": "",
},
}),
)
.await;
let project = Project::test(fs.clone(), [path!("/root/dir1/dep1").as_ref()], cx).await;
let visible_worktree =
project.read_with(cx, |project, cx| project.worktrees(cx).next().unwrap());
visible_worktree
.read_with(cx, |tree, _| tree.as_local().unwrap().scan_complete())
.await;
let repos = project.read_with(cx, |project, cx| {
project
.repositories(cx)
.values()
.map(|repo| repo.read(cx).work_directory_abs_path.clone())
.collect::<Vec<_>>()
});
pretty_assertions::assert_eq!(repos, [Path::new(path!("/root/dir1/dep1")).into()]);
let (invisible_worktree, _) = project
.update(cx, |project, cx| {
project.worktree_store.update(cx, |worktree_store, cx| {
worktree_store.find_or_create_worktree(path!("/root/dir1/b.txt"), false, cx)
})
})
.await
.expect("failed to create worktree");
invisible_worktree
.read_with(cx, |tree, _| tree.as_local().unwrap().scan_complete())
.await;
let repos = project.read_with(cx, |project, cx| {
project
.repositories(cx)
.values()
.map(|repo| repo.read(cx).work_directory_abs_path.clone())
.collect::<Vec<_>>()
});
pretty_assertions::assert_eq!(repos, [Path::new(path!("/root/dir1/dep1")).into()]);
}
#[gpui::test(iterations = 10)] #[gpui::test(iterations = 10)]
async fn test_rescan_with_gitignore(cx: &mut gpui::TestAppContext) { async fn test_rescan_with_gitignore(cx: &mut gpui::TestAppContext) {
init_test(cx); init_test(cx);