diff options
| author | Can Celik <ogulcancelik@gmail.com> | 2026-08-28 18:25:07 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-08-28 18:25:07 +0300 |
| commit | 095f1337d6502081658973ae3487dee8c6b34e1a (patch) | |
| tree | 4174cac82dd51dabcc1fcef57b45df2462ef1918 /src/app/api/worktrees.rs | |
| parent | 13a9f6402fb77a31499bf758b56ca42b79936706 (diff) | |
fix: trust worktree repositories per request (#3344)
refs #3044
Diffstat (limited to 'src/app/api/worktrees.rs')
| -rw-r--r-- | src/app/api/worktrees.rs | 101 |
1 files changed, 77 insertions, 24 deletions
diff --git a/src/app/api/worktrees.rs b/src/app/api/worktrees.rs index 774b981a..4a3e23a8 100644 --- a/src/app/api/worktrees.rs +++ b/src/app/api/worktrees.rs @@ -50,11 +50,18 @@ impl App { id: String, params: WorktreeListParams, ) -> String { - let source = match self.resolve_worktree_list_source(params.workspace_id, params.cwd) { + let source = match self.resolve_worktree_list_source( + params.workspace_id, + params.cwd, + params.trust_repository, + ) { Ok(source) => source, Err(err) => return encode_error(id, err.code, err.message), }; - let entries = match crate::worktree::list_existing_worktrees(&source.source_repo_root) { + let entries = match crate::worktree::list_existing_worktrees( + &source.source_repo_root, + params.trust_repository, + ) { Ok(entries) => entries, Err(err) => return encode_error(id, "worktree_list_failed", err), }; @@ -88,7 +95,12 @@ impl App { Ok(source) => source, Err(err) => return encode_error(id, err.code, err.message), }; - let entry = match self.find_worktree_entry(&source, params.path, params.branch) { + let entry = match self.find_worktree_entry( + &source, + params.path, + params.branch, + params.trust_repository, + ) { Ok(entry) => entry, Err(err) => return encode_error(id, err.code, err.message), }; @@ -235,6 +247,7 @@ impl App { &mut self, workspace_id: Option<String>, cwd: Option<String>, + trust_repository: bool, ) -> Result<WorktreeSource, ApiFailure> { if workspace_id.is_some() && cwd.is_some() { return Err(ApiFailure::new( @@ -250,7 +263,7 @@ impl App { format!("workspace {workspace_id} not found"), )); }; - return self.worktree_list_source_from_workspace(ws_idx); + return self.worktree_list_source_from_workspace(ws_idx, trust_repository); } if let Some(cwd) = cwd { @@ -261,8 +274,13 @@ impl App { "Herdr worktree actions require a path inside a Git work tree", ) })?; - let workspace_idx = self.list_source_workspace_idx_for_space(&space); - return Ok(worktree_source_from_space(space, workspace_idx, true)); + let workspace_idx = self.list_source_workspace_idx_for_space(&space, trust_repository); + return Ok(worktree_source_from_space( + space, + workspace_idx, + true, + trust_repository, + )); } let Some(ws_idx) = self.state.active.or_else(|| { @@ -276,7 +294,7 @@ impl App { "workspace_id or cwd is required when no workspace is active", )); }; - self.worktree_list_source_from_workspace(ws_idx) + self.worktree_list_source_from_workspace(ws_idx, trust_repository) } fn worktree_source_from_workspace(&self, ws_idx: usize) -> Result<WorktreeSource, ApiFailure> { @@ -331,6 +349,7 @@ impl App { fn worktree_list_source_from_workspace( &self, ws_idx: usize, + trust_repository: bool, ) -> Result<WorktreeSource, ApiFailure> { let Some(ws) = self.state.workspaces.get(ws_idx) else { return Err(ApiFailure::new( @@ -370,11 +389,16 @@ impl App { )); }; let workspace_idx = if space.is_linked_worktree { - self.list_source_workspace_idx_for_space(&space) + self.list_source_workspace_idx_for_space(&space, trust_repository) } else { Some(ws_idx) }; - Ok(worktree_source_from_space(space, workspace_idx, true)) + Ok(worktree_source_from_space( + space, + workspace_idx, + true, + trust_repository, + )) } fn ensure_source_parent_membership( @@ -415,9 +439,10 @@ impl App { fn list_source_workspace_idx_for_space( &self, space: &crate::workspace::GitSpaceMetadata, + trust_repository: bool, ) -> Option<usize> { if space.is_linked_worktree { - let parent_checkout = parent_checkout_path_for_space(space); + let parent_checkout = parent_checkout_path_for_space(space, trust_repository); self.open_workspace_idx_for_checkout(&parent_checkout) } else { self.find_parent_workspace_for_space(space) @@ -475,9 +500,11 @@ impl App { source: &WorktreeSource, path: Option<String>, branch: Option<String>, + trust_repository: bool, ) -> Result<crate::worktree::ExistingWorktree, ApiFailure> { - let entries = crate::worktree::list_existing_worktrees(&source.source_repo_root) - .map_err(|err| ApiFailure::new("worktree_list_failed", err))?; + let entries = + crate::worktree::list_existing_worktrees(&source.source_repo_root, trust_repository) + .map_err(|err| ApiFailure::new("worktree_list_failed", err))?; if let Some(path) = path { let expected = absolute_user_path(&path)?; let expected = crate::worktree::canonical_or_original(&expected); @@ -667,9 +694,10 @@ fn worktree_source_from_space( space: crate::workspace::GitSpaceMetadata, workspace_idx: Option<usize>, allow_linked: bool, + trust_repository: bool, ) -> WorktreeSource { let source_checkout_path = if allow_linked { - parent_checkout_path_for_space(&space) + parent_checkout_path_for_space(&space, trust_repository) } else { space.repo_root.clone() }; @@ -682,12 +710,15 @@ fn worktree_source_from_space( } } -fn parent_checkout_path_for_space(space: &crate::workspace::GitSpaceMetadata) -> PathBuf { +fn parent_checkout_path_for_space( + space: &crate::workspace::GitSpaceMetadata, + trust_repository: bool, +) -> PathBuf { if !space.is_linked_worktree { return space.repo_root.clone(); } - crate::worktree::list_existing_worktrees(&space.repo_root) + crate::worktree::list_existing_worktrees(&space.repo_root, trust_repository) .ok() .and_then(|entries| { entries.into_iter().find_map(|entry| { @@ -957,8 +988,12 @@ mod tests { for (_, runtime) in app.terminal_runtimes.drain() { runtime.shutdown(); } - let remove = - crate::worktree::build_worktree_remove_command(&repo, Path::new(&worktree.path), false); + let remove = crate::worktree::build_worktree_remove_command( + &repo, + Path::new(&worktree.path), + false, + false, + ); crate::worktree::run_worktree_command(&remove).unwrap(); let _ = std::fs::remove_dir_all(worktree_root); let _ = std::fs::remove_dir_all(repo); @@ -1271,8 +1306,12 @@ mod tests { for (_, runtime) in app.terminal_runtimes.drain() { runtime.shutdown(); } - let remove = - crate::worktree::build_worktree_remove_command(&repo, Path::new(&worktree.path), false); + let remove = crate::worktree::build_worktree_remove_command( + &repo, + Path::new(&worktree.path), + false, + false, + ); crate::worktree::run_worktree_command(&remove).unwrap(); let _ = std::fs::remove_dir_all(worktree_root); let _ = std::fs::remove_dir_all(repo); @@ -1440,7 +1479,7 @@ mod tests { ) })); - let remove = crate::worktree::build_worktree_remove_command(&repo, &checkout, false); + let remove = crate::worktree::build_worktree_remove_command(&repo, &checkout, false, false); crate::worktree::run_worktree_command(&remove).unwrap(); let _ = std::fs::remove_dir_all(repo); } @@ -1518,7 +1557,7 @@ mod tests { ) })); - let remove = crate::worktree::build_worktree_remove_command(&repo, &checkout, false); + let remove = crate::worktree::build_worktree_remove_command(&repo, &checkout, false, false); crate::worktree::run_worktree_command(&remove).unwrap(); let _ = std::fs::remove_dir_all(repo); } @@ -1603,6 +1642,7 @@ mod tests { method: crate::api::schema::Method::WorktreeList(WorktreeListParams { workspace_id: Some(app.state.workspaces[0].id.clone()), cwd: None, + trust_repository: false, }), }); @@ -1620,7 +1660,7 @@ mod tests { ); assert!(entry.is_linked_worktree); - let remove = crate::worktree::build_worktree_remove_command(&repo, &checkout, false); + let remove = crate::worktree::build_worktree_remove_command(&repo, &checkout, false, false); crate::worktree::run_worktree_command(&remove).unwrap(); let _ = std::fs::remove_dir_all(repo); } @@ -1653,10 +1693,12 @@ mod tests { crate::api::schema::Method::WorktreeList(WorktreeListParams { workspace_id: Some(child_id), cwd: None, + trust_repository: false, }), crate::api::schema::Method::WorktreeList(WorktreeListParams { workspace_id: None, cwd: Some(checkout.display().to_string()), + trust_repository: false, }), ] { let response = app.handle_api_request(Request { @@ -1681,7 +1723,7 @@ mod tests { })); } - let remove = crate::worktree::build_worktree_remove_command(&repo, &checkout, false); + let remove = crate::worktree::build_worktree_remove_command(&repo, &checkout, false, false); crate::worktree::run_worktree_command(&remove).unwrap(); let _ = std::fs::remove_dir_all(repo); } @@ -1710,6 +1752,7 @@ mod tests { method: crate::api::schema::Method::WorktreeList(WorktreeListParams { workspace_id: Some(app.state.workspaces[0].id.clone()), cwd: None, + trust_repository: false, }), }); @@ -1767,6 +1810,7 @@ mod tests { method: crate::api::schema::Method::WorktreeRemove(WorktreeRemoveParams { workspace_id: child_id.clone(), force: false, + trust_repository: false, }), }, ); @@ -1782,6 +1826,7 @@ mod tests { method: crate::api::schema::Method::WorktreeRemove(WorktreeRemoveParams { workspace_id: child_id, force: true, + trust_repository: false, }), }, ); @@ -1838,6 +1883,7 @@ mod tests { method: crate::api::schema::Method::WorktreeRemove(WorktreeRemoveParams { workspace_id: child_id.clone(), force: false, + trust_repository: false, }), }, ); @@ -1923,6 +1969,7 @@ mod tests { method: crate::api::schema::Method::WorktreeRemove(WorktreeRemoveParams { workspace_id: child_id.clone(), force: false, + trust_repository: false, }), }, respond_to, @@ -1996,6 +2043,7 @@ mod tests { method: crate::api::schema::Method::WorktreeRemove(WorktreeRemoveParams { workspace_id: child_id.clone(), force: false, + trust_repository: false, }), }, first_tx, @@ -2006,6 +2054,7 @@ mod tests { method: crate::api::schema::Method::WorktreeRemove(WorktreeRemoveParams { workspace_id: child_id, force: false, + trust_repository: false, }), }, second_tx, @@ -2065,6 +2114,7 @@ mod tests { method: crate::api::schema::Method::WorktreeRemove(WorktreeRemoveParams { workspace_id: first_id, force: true, + trust_repository: false, }), }, first_tx, @@ -2075,6 +2125,7 @@ mod tests { method: crate::api::schema::Method::WorktreeRemove(WorktreeRemoveParams { workspace_id: second_id, force: true, + trust_repository: false, }), }, second_tx, @@ -2110,6 +2161,7 @@ mod tests { path: Some(checkout.display().to_string()), label: None, focus: false, + trust_repository: false, }), }, respond_to, @@ -2164,6 +2216,7 @@ mod tests { method: crate::api::schema::Method::WorktreeRemove(WorktreeRemoveParams { workspace_id: child_id, force: false, + trust_repository: false, }), }, respond_to, @@ -2175,7 +2228,7 @@ mod tests { let error: ErrorResponse = serde_json::from_str(&response).unwrap(); assert_eq!(error.error.code, "worktree_operation_in_progress"); assert!(app.event_rx.try_recv().is_err()); - let remove = crate::worktree::build_worktree_remove_command(&repo, &checkout, true); + let remove = crate::worktree::build_worktree_remove_command(&repo, &checkout, true, false); let _ = crate::worktree::run_worktree_command(&remove); let _ = std::fs::remove_dir_all(repo); } |
