From c403c8b0e1d42e1904e681591f98b10fab7aed8a Mon Sep 17 00:00:00 2001 From: Bradley Axen Date: Thu, 5 Feb 2026 23:46:42 -0800 Subject: [PATCH 1/4] fix: create workspace bug --- src-tauri/src/git/mod.rs | 6 ++--- src-tauri/src/git/worktree.rs | 36 +++++++++++++++++++++++++ src-tauri/src/lib.rs | 22 +++++++--------- src/lib/BranchHome.svelte | 49 +++++++++++++++++++++++------------ src/lib/NewBranchModal.svelte | 31 +++++++++++++--------- 5 files changed, 101 insertions(+), 43 deletions(-) diff --git a/src-tauri/src/git/mod.rs b/src-tauri/src/git/mod.rs index 7e07614..0e55a08 100644 --- a/src-tauri/src/git/mod.rs +++ b/src-tauri/src/git/mod.rs @@ -23,7 +23,7 @@ pub use refs::{ }; pub use types::*; pub use worktree::{ - branch_exists, create_worktree, create_worktree_from_pr, get_commits_since_base, get_head_sha, - get_parent_commit, list_worktrees, remove_worktree, reset_to_commit, update_branch_from_pr, - worktree_path_for, CommitInfo, UpdateFromPrResult, + branch_exists, create_worktree, create_worktree_for_existing_branch, create_worktree_from_pr, + get_commits_since_base, get_head_sha, get_parent_commit, list_worktrees, remove_worktree, + reset_to_commit, update_branch_from_pr, worktree_path_for, CommitInfo, UpdateFromPrResult, }; diff --git a/src-tauri/src/git/worktree.rs b/src-tauri/src/git/worktree.rs index c686ef0..c2c68a6 100644 --- a/src-tauri/src/git/worktree.rs +++ b/src-tauri/src/git/worktree.rs @@ -79,6 +79,42 @@ pub fn create_worktree( Ok(worktree_path) } +/// Create a new worktree for an existing local branch. +/// +/// Uses the standard worktree location and checks out `branch_name` there. +/// Fails if the worktree path already exists. +pub fn create_worktree_for_existing_branch( + repo: &Path, + branch_name: &str, +) -> Result { + let worktree_path = worktree_path_for(repo, branch_name)?; + + // Ensure parent directory exists + if let Some(parent) = worktree_path.parent() { + std::fs::create_dir_all(parent).map_err(|e| { + GitError::CommandFailed(format!("Failed to create worktree directory: {e}")) + })?; + } + + // Check if worktree already exists + if worktree_path.exists() { + return Err(GitError::CommandFailed(format!( + "Worktree already exists at {}", + worktree_path.display() + ))); + } + + let worktree_str = worktree_path + .to_str() + .ok_or_else(|| GitError::InvalidPath(worktree_path.display().to_string()))?; + + // Create worktree for existing branch: + // git worktree add + cli::run(repo, &["worktree", "add", worktree_str, branch_name])?; + + Ok(worktree_path) +} + /// Remove a worktree and its associated branch. /// /// Removes the worktree directory, git worktree reference, and the local git branch. diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 00c01d0..89b47d9 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -1657,17 +1657,15 @@ async fn create_branch( _ => git::detect_default_branch(repo).map_err(|e| e.to_string())?, }; - // Create the worktree (this will fail atomically if branch already exists) - let worktree_path = - git::create_worktree(repo, &branch_name, &base_branch).map_err(|e| { - // Provide user-friendly error for common case - let msg = e.to_string(); - if msg.contains("already exists") { - format!("Branch '{branch_name}' already exists") - } else { - msg - } - })?; + // If branch already exists locally, set up a worktree for it instead of failing. + // Otherwise create both branch and worktree from the selected base. + let branch_exists = git::branch_exists(repo, &branch_name).map_err(|e| e.to_string())?; + let worktree_path = if branch_exists { + git::create_worktree_for_existing_branch(repo, &branch_name) + .map_err(|e| e.to_string())? + } else { + git::create_worktree(repo, &branch_name, &base_branch).map_err(|e| e.to_string())? + }; // Create the branch record let branch = Branch::new( @@ -1678,7 +1676,7 @@ async fn create_branch( &base_branch, ); - // If DB insert fails, clean up the worktree + // If DB insert fails, clean up the worktree. if let Err(e) = store.create_branch(&branch) { let _ = git::remove_worktree(repo, &worktree_path); // Best-effort cleanup return Err(e.to_string()); diff --git a/src/lib/BranchHome.svelte b/src/lib/BranchHome.svelte index 362f7db..ba7b450 100644 --- a/src/lib/BranchHome.svelte +++ b/src/lib/BranchHome.svelte @@ -9,7 +9,7 @@ - Escape: Close modals --> +
diff --git a/src/lib/TabBar.svelte b/src/lib/TabBar.svelte index f5b4f4d..130d239 100644 --- a/src/lib/TabBar.svelte +++ b/src/lib/TabBar.svelte @@ -119,6 +119,7 @@ }); +
{#if onBack}