aboutsummaryrefslogtreecommitdiff
path: root/src/app/api/worktrees.rs
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-06-22 00:51:00 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-06-22 00:51:00 +0300
commit89ca3ba933eaf493234912972be8236c9c2493e5 (patch)
tree508a0489cf3aa15f6d454a1c86697b0a7ba4ed72 /src/app/api/worktrees.rs
parenta5182282a490cfb60b22776257edc5ac0fce6adc (diff)
fix: check out existing branches for worktree create
refs #729
Diffstat (limited to 'src/app/api/worktrees.rs')
-rw-r--r--src/app/api/worktrees.rs75
1 files changed, 68 insertions, 7 deletions
diff --git a/src/app/api/worktrees.rs b/src/app/api/worktrees.rs
index 62a46fdb..111d50cf 100644
--- a/src/app/api/worktrees.rs
+++ b/src/app/api/worktrees.rs
@@ -1038,12 +1038,77 @@ mod tests {
let _ = std::fs::remove_dir_all(plugin_root);
}
+ #[tokio::test]
+ async fn deferred_api_worktree_create_checks_out_existing_branch() {
+ let repo = create_committed_repo("api-worktree-create-existing-branch-repo");
+ let worktree_root = unique_temp_path("api-worktree-create-existing-branch-root");
+ let branch = "foo";
+ run_git(&repo, &["branch", branch]);
+ let mut app = test_app();
+ let mut parent = Workspace::test_new("main");
+ parent.identity_cwd = repo.clone();
+ let parent_id = parent.id.clone();
+ app.state.workspaces = vec![parent];
+ app.state.ensure_test_terminals();
+ app.state.worktree_directory = worktree_root.clone();
+ let request = || Request {
+ id: "req".into(),
+ method: crate::api::schema::Method::WorktreeCreate(WorktreeCreateParams {
+ workspace_id: Some(parent_id.clone()),
+ branch: Some(branch.into()),
+ ..WorktreeCreateParams::default()
+ }),
+ };
+
+ let (response_tx, response_rx) = response_channel();
+ assert!(app.handle_deferred_worktree_api_request(request(), response_tx));
+ let event = wait_for_app_event(&mut app);
+ app.handle_internal_event(event);
+ let response = response_rx
+ .recv_timeout(std::time::Duration::from_secs(2))
+ .expect("create should respond");
+ let success: SuccessResponse = serde_json::from_str(&response).unwrap();
+ let ResponseResult::WorktreeCreated { worktree, .. } = success.result else {
+ panic!("expected worktree_created response");
+ };
+ assert_eq!(worktree.branch.as_deref(), Some(branch));
+ let checkout = Path::new(&worktree.path);
+ assert!(checkout.join("README.md").exists());
+ let branch_name = std::process::Command::new("git")
+ .arg("-C")
+ .arg(checkout)
+ .args(["branch", "--show-current"])
+ .output()
+ .unwrap();
+ assert!(branch_name.status.success());
+ assert_eq!(
+ String::from_utf8(branch_name.stdout).unwrap().trim(),
+ branch
+ );
+ assert!(app.pending_api_worktree_creates.is_empty());
+
+ for (_, runtime) in app.terminal_runtimes.drain() {
+ runtime.shutdown();
+ }
+ let _ = std::fs::remove_dir_all(worktree_root);
+ let _ = std::fs::remove_dir_all(repo);
+ }
+
#[test]
fn deferred_api_worktree_create_failure_clears_pending_checkout() {
let repo = create_committed_repo("api-worktree-create-failure-repo");
let worktree_root = unique_temp_path("api-worktree-create-failure-root");
- let branch = "foo";
- run_git(&repo, &["branch", branch]);
+ let branch_name = std::process::Command::new("git")
+ .arg("-C")
+ .arg(&repo)
+ .args(["branch", "--show-current"])
+ .output()
+ .unwrap();
+ assert!(branch_name.status.success());
+ let branch = String::from_utf8(branch_name.stdout)
+ .unwrap()
+ .trim()
+ .to_string();
let mut app = test_app();
let mut parent = Workspace::test_new("main");
parent.identity_cwd = repo.clone();
@@ -1055,7 +1120,7 @@ mod tests {
id: "req".into(),
method: crate::api::schema::Method::WorktreeCreate(WorktreeCreateParams {
workspace_id: Some(parent_id.clone()),
- branch: Some(branch.into()),
+ branch: Some(branch.clone()),
..WorktreeCreateParams::default()
}),
};
@@ -1069,10 +1134,6 @@ mod tests {
.expect("failed create should respond");
let error: ErrorResponse = serde_json::from_str(&response).unwrap();
assert_eq!(error.error.code, "worktree_create_failed");
- assert!(error
- .error
- .message
- .contains("fatal: a branch named 'foo' already exists"));
assert!(app.pending_api_worktree_creates.is_empty());
let (second_tx, second_rx) = response_channel();