Skip to main content

worktree_io/git/
mod.rs

1mod branch;
2mod clone;
3mod local_branch;
4
5pub use branch::{branch_exists_remote, detect_default_branch};
6pub use clone::{bare_clone, git_fetch};
7pub use local_branch::{branch_exists_local, detect_local_default_branch};
8
9use anyhow::{bail, Context, Result};
10use std::path::Path;
11use std::process::Command;
12
13/// Create a worktree from a local (non-bare) repository without referencing a remote.
14///
15/// When `branch_exists` is false a new branch is created from HEAD.
16/// When `branch_exists` is true the existing local branch is checked out.
17pub fn create_local_worktree(
18    repo: &Path,
19    dest: &Path,
20    branch: &str,
21    branch_exists: bool,
22) -> Result<()> {
23    let mut cmd = Command::new("git");
24    cmd.args(["-C"]).arg(repo).arg("worktree").arg("add");
25
26    if branch_exists {
27        cmd.arg(dest).arg(branch);
28    } else {
29        // Create new branch from HEAD (no origin/ reference needed)
30        cmd.arg(dest).arg("-b").arg(branch);
31    }
32
33    let status = cmd.status().context("Failed to run `git worktree add`")?;
34
35    if !status.success() {
36        bail!("git worktree add failed for branch {branch}"); // LLVM_COV_EXCL_LINE
37    }
38    Ok(())
39}
40
41pub fn create_worktree(
42    bare: &Path,
43    dest: &Path,
44    branch: &str,
45    base_branch: &str,
46    branch_exists: bool,
47) -> Result<()> {
48    let mut cmd = Command::new("git");
49    cmd.args(["-C"]).arg(bare).arg("worktree").arg("add");
50
51    if branch_exists {
52        cmd.arg(dest).arg(branch);
53    } else {
54        cmd.arg(dest)
55            .arg("-b")
56            .arg(branch)
57            .arg(format!("origin/{base_branch}"));
58    }
59
60    let status = cmd.status().context("Failed to run `git worktree add`")?;
61
62    if !status.success() {
63        bail!("git worktree add failed for branch {branch}"); // LLVM_COV_EXCL_LINE
64    }
65    Ok(())
66}