@@ -2696,13 +2696,28 @@ impl BackgroundScannerState {
Arc<Mutex<dyn GitRepository>>,
TreeMap<RepoPath, GitFileStatus>,
)> {
- log::info!("build git repository {:?}", dot_git_path);
-
- let work_dir_path: Arc<Path> = dot_git_path.parent().unwrap().into();
-
- // Guard against repositories inside the repository metadata
- if work_dir_path.iter().any(|component| component == *DOT_GIT) {
- return None;
+ let work_dir_path: Arc<Path> = match dot_git_path.parent() {
+ Some(parent_dir) => {
+ // Guard against repositories inside the repository metadata
+ if parent_dir.iter().any(|component| component == *DOT_GIT) {
+ log::info!(
+ "not building git repository for nested `.git` directory, `.git` path in the worktree: {dot_git_path:?}"
+ );
+ return None;
+ };
+ log::info!(
+ "building git repository, `.git` path in the worktree: {dot_git_path:?}"
+ );
+ parent_dir.into()
+ }
+ None => {
+ // `dot_git_path.parent().is_none()` means `.git` directory is the opened worktree itself,
+ // no files inside that directory are tracked by git, so no need to build the repo around it
+ log::info!(
+ "not building git repository for the worktree itself, `.git` path in the worktree: {dot_git_path:?}"
+ );
+ return None;
+ }
};
let work_dir_id = self
@@ -1204,6 +1204,43 @@ async fn test_fs_events_in_exclusions(cx: &mut TestAppContext) {
});
}
+#[gpui::test]
+async fn test_fs_events_in_dot_git_worktree(cx: &mut TestAppContext) {
+ init_test(cx);
+ cx.executor().allow_parking();
+ let dir = temp_tree(json!({
+ ".git": {
+ "HEAD": "ref: refs/heads/main\n",
+ "foo": "foo contents",
+ },
+ }));
+ let dot_git_worktree_dir = dir.path().join(".git");
+
+ let tree = Worktree::local(
+ build_client(cx),
+ dot_git_worktree_dir.clone(),
+ true,
+ Arc::new(RealFs),
+ Default::default(),
+ &mut cx.to_async(),
+ )
+ .await
+ .unwrap();
+ cx.read(|cx| tree.read(cx).as_local().unwrap().scan_complete())
+ .await;
+ tree.flush_fs_events(cx).await;
+ tree.read_with(cx, |tree, _| {
+ check_worktree_entries(tree, &[], &["HEAD", "foo"], &[])
+ });
+
+ std::fs::write(dot_git_worktree_dir.join("new_file"), "new file contents")
+ .unwrap_or_else(|e| panic!("Failed to create in {dot_git_worktree_dir:?} a new file: {e}"));
+ tree.flush_fs_events(cx).await;
+ tree.read_with(cx, |tree, _| {
+ check_worktree_entries(tree, &[], &["HEAD", "foo", "new_file"], &[])
+ });
+}
+
#[gpui::test(iterations = 30)]
async fn test_create_directory_during_initial_scan(cx: &mut TestAppContext) {
init_test(cx);