1use anyhow::Result;
2use std::path::PathBuf;
3
4use crate::git::{bare_clone, branch_exists_remote, create_worktree, detect_default_branch, git_fetch};
5use crate::issue::IssueRef;
6
7pub struct Workspace {
8 pub path: PathBuf,
9 pub issue: IssueRef,
10 pub created: bool,
12}
13
14impl Workspace {
15 pub fn open_or_create(issue: IssueRef) -> Result<Self> {
17 let worktree_path = issue.temp_path();
18 let bare_path = issue.bare_clone_path();
19
20 if worktree_path.exists() {
22 return Ok(Self { path: worktree_path, issue, created: false });
23 }
24
25 if !bare_path.exists() {
27 eprintln!("Cloning {} (bare) into {}…", issue.clone_url(), bare_path.display());
28 bare_clone(&issue.clone_url(), &bare_path)?;
29 } else {
30 eprintln!("Fetching origin…");
31 git_fetch(&bare_path)?;
32 }
33
34 let base_branch = detect_default_branch(&bare_path)?;
35 eprintln!("Default branch: {base_branch}");
36
37 let branch = issue.branch_name();
38 let branch_exists = branch_exists_remote(&bare_path, &branch);
39
40 eprintln!("Creating worktree {} at {}…", branch, worktree_path.display());
41 create_worktree(&bare_path, &worktree_path, &branch, &base_branch, branch_exists)?;
42
43 Ok(Self { path: worktree_path, issue, created: true })
44 }
45}