From 8b6df911e9c514ba133ce86b0a9a44f580101d4d Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 17 Mar 2026 10:50:05 -0700 Subject: [PATCH] Terminate auto-created worktree paths with the original project name --- crates/agent_ui/src/agent_panel.rs | 8 ++++++-- crates/collab/tests/integration/git_tests.rs | 4 ++-- .../integration/remote_editing_collaboration_tests.rs | 2 +- crates/git/src/repository.rs | 7 +++---- crates/git_ui/src/worktree_picker.rs | 3 ++- crates/project/src/git_store.rs | 10 ++++++---- crates/project/tests/integration/git_store.rs | 4 ++-- 7 files changed, 22 insertions(+), 16 deletions(-) diff --git a/crates/agent_ui/src/agent_panel.rs b/crates/agent_ui/src/agent_panel.rs index 232786f9e543b8ed7903a3a4d5d70ea630bd836e..979d8e2b79fab5c88ba4fbfeaf0d3ea1c30a8fbd 100644 --- a/crates/agent_ui/src/agent_panel.rs +++ b/crates/agent_ui/src/agent_panel.rs @@ -2596,10 +2596,14 @@ impl AgentPanel { for repo in git_repos { let (work_dir, new_path, receiver) = repo.update(cx, |repo, _cx| { let original_repo = repo.original_repo_abs_path.clone(); + let project_name = original_repo + .file_name() + .ok_or_else(|| anyhow!("git repo must have a directory name"))?; let directory = validate_worktree_directory(&original_repo, worktree_directory_setting)?; - let new_path = directory.join(branch_name); - let receiver = repo.create_worktree(branch_name.to_string(), directory, None); + let new_path = directory.join(branch_name).join(project_name); + let receiver = + repo.create_worktree(branch_name.to_string(), new_path.clone(), None); let work_dir = repo.work_directory_abs_path.clone(); anyhow::Ok((work_dir, new_path, receiver)) })?; diff --git a/crates/collab/tests/integration/git_tests.rs b/crates/collab/tests/integration/git_tests.rs index fc20150d662b96be9b6ad4f99ae1f33032b6fb7b..0cbd2a97dabcb832e6b25298341272be783e4024 100644 --- a/crates/collab/tests/integration/git_tests.rs +++ b/crates/collab/tests/integration/git_tests.rs @@ -215,7 +215,7 @@ async fn test_remote_git_worktrees( repo_b.update(cx, |repository, _| { repository.create_worktree( "feature-branch".to_string(), - worktree_directory.clone(), + worktree_directory.join("feature-branch"), Some("abc123".to_string()), ) }) @@ -266,7 +266,7 @@ async fn test_remote_git_worktrees( repo_b.update(cx, |repository, _| { repository.create_worktree( "bugfix-branch".to_string(), - worktree_directory.clone(), + worktree_directory.join("bugfix-branch"), None, ) }) diff --git a/crates/collab/tests/integration/remote_editing_collaboration_tests.rs b/crates/collab/tests/integration/remote_editing_collaboration_tests.rs index ceb7db145970b52d23a6ef7ace82cd84acf1e840..59ba868de745b1364f7dd9cff45030b08e24d6a2 100644 --- a/crates/collab/tests/integration/remote_editing_collaboration_tests.rs +++ b/crates/collab/tests/integration/remote_editing_collaboration_tests.rs @@ -473,7 +473,7 @@ async fn test_ssh_collaboration_git_worktrees( repo_b.update(cx, |repo, _| { repo.create_worktree( "feature-branch".to_string(), - worktree_directory.clone(), + worktree_directory.join("feature-branch"), Some("abc123".to_string()), ) }) diff --git a/crates/git/src/repository.rs b/crates/git/src/repository.rs index 094e634c7ff9265ef60ad0a3b892ef1eebdbad4e..c02909e702e19e3ae970fe0d9238fdbe388aef4c 100644 --- a/crates/git/src/repository.rs +++ b/crates/git/src/repository.rs @@ -769,7 +769,7 @@ pub trait GitRepository: Send + Sync { fn create_worktree( &self, - name: String, + branch_name: String, directory: PathBuf, from_commit: Option, ) -> BoxFuture<'_, Result<()>>; @@ -1717,7 +1717,6 @@ impl GitRepository for RealGitRepository { from_commit: Option, ) -> BoxFuture<'_, Result<()>> { let git_binary = self.git_binary(); - let final_path = directory.join(&name); let mut args = vec![ OsString::from("--no-optional-locks"), OsString::from("worktree"), @@ -1725,7 +1724,7 @@ impl GitRepository for RealGitRepository { OsString::from("-b"), OsString::from(name.as_str()), OsString::from("--"), - OsString::from(final_path.as_os_str()), + OsString::from(directory.as_os_str()), ]; if let Some(from_commit) = from_commit { args.push(OsString::from(from_commit)); @@ -1735,7 +1734,7 @@ impl GitRepository for RealGitRepository { self.executor .spawn(async move { - std::fs::create_dir_all(final_path.parent().unwrap_or(&final_path))?; + std::fs::create_dir_all(directory.parent().unwrap_or(&directory))?; let git = git_binary?; let output = git.build_command(&args).output().await?; if output.status.success() { diff --git a/crates/git_ui/src/worktree_picker.rs b/crates/git_ui/src/worktree_picker.rs index 6c35e7c99ffb8f6efa1a2bd7a07c2ded8d158668..339285a1847492b627dffbfbf329cbc13e6a5363 100644 --- a/crates/git_ui/src/worktree_picker.rs +++ b/crates/git_ui/src/worktree_picker.rs @@ -304,7 +304,8 @@ impl WorktreeListDelegate { let directory = validate_worktree_directory(&original_repo, &worktree_directory_setting)?; let new_worktree_path = directory.join(&branch); - let receiver = repo.create_worktree(branch.clone(), directory, commit); + let receiver = + repo.create_worktree(branch.clone(), new_worktree_path.clone(), commit); anyhow::Ok((receiver, new_worktree_path)) })?; receiver.await??; diff --git a/crates/project/src/git_store.rs b/crates/project/src/git_store.rs index e9330014c3f066705ac3ea1e54f5e498c5d22348..65f390a6793ed8435e7da40d1900f7505467b555 100644 --- a/crates/project/src/git_store.rs +++ b/crates/project/src/git_store.rs @@ -5757,24 +5757,26 @@ impl Repository { pub fn create_worktree( &mut self, - name: String, + branch_name: String, directory: PathBuf, commit: Option, ) -> oneshot::Receiver> { let id = self.id; self.send_job( - Some("git worktree add".into()), + Some(format!("git worktree add - {}", branch_name).into()), move |repo, _cx| async move { match repo { RepositoryState::Local(LocalRepositoryState { backend, .. }) => { - backend.create_worktree(name, directory, commit).await + backend + .create_worktree(branch_name, directory, commit) + .await } RepositoryState::Remote(RemoteRepositoryState { project_id, client }) => { client .request(proto::GitCreateWorktree { project_id: project_id.0, repository_id: id.to_proto(), - name, + name: branch_name, directory: directory.to_string_lossy().to_string(), commit, }) diff --git a/crates/project/tests/integration/git_store.rs b/crates/project/tests/integration/git_store.rs index 82e92bc4f1cfb606fb09d5efd5d341ed2951c067..f9d8862fdb8139e560aaf08f033de7033072e4fa 100644 --- a/crates/project/tests/integration/git_store.rs +++ b/crates/project/tests/integration/git_store.rs @@ -1226,7 +1226,7 @@ mod git_worktrees { repository.update(cx, |repository, _| { repository.create_worktree( "feature-branch".to_string(), - worktree_directory.clone(), + worktree_directory.join("feature-branch"), Some("abc123".to_string()), ) }) @@ -1252,7 +1252,7 @@ mod git_worktrees { repository.update(cx, |repository, _| { repository.create_worktree( "bugfix-branch".to_string(), - worktree_directory.clone(), + worktree_directory.join("bugfix-branch"), None, ) })