Skip to main content

worktree_io/
workspace.rs

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    /// true if this call actually created the worktree; false if it already existed
11    pub created: bool,
12}
13
14impl Workspace {
15    /// Open an existing worktree or create a fresh one.
16    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        // Fast path: worktree already exists
21        if worktree_path.exists() {
22            return Ok(Self { path: worktree_path, issue, created: false });
23        }
24
25        // Ensure the bare clone exists
26        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}