Skip to main content

worktree_io/git/
branch.rs

1use anyhow::{bail, Context, Result};
2use std::path::Path;
3use std::process::Command;
4
5pub fn detect_default_branch(bare: &Path) -> Result<String> {
6    let output = Command::new("git")
7        .args(["-C"])
8        .arg(bare)
9        .args(["symbolic-ref", "refs/remotes/origin/HEAD"])
10        .output()
11        .context("Failed to run `git symbolic-ref`")?;
12
13    if output.status.success() {
14        let full = String::from_utf8_lossy(&output.stdout);
15        if let Some(branch) = full.trim().strip_prefix("refs/remotes/origin/") {
16            return Ok(branch.to_string());
17        }
18    }
19
20    let output = Command::new("git")
21        .args(["-C"])
22        .arg(bare)
23        .args(["remote", "show", "origin"])
24        .output()
25        .context("Failed to run `git remote show origin`")?;
26
27    if output.status.success() {
28        let text = String::from_utf8_lossy(&output.stdout);
29        for line in text.lines() {
30            let line = line.trim();
31            if let Some(branch) = line.strip_prefix("HEAD branch: ") {
32                return Ok(branch.to_string()); // LLVM_COV_EXCL_LINE
33            }
34        }
35    }
36
37    for candidate in ["main", "master", "develop"] {
38        let output = Command::new("git")
39            .args(["-C"])
40            .arg(bare)
41            .args([
42                "rev-parse",
43                "--verify",
44                &format!("refs/remotes/origin/{candidate}"),
45            ])
46            .output()
47            .context("Failed to run `git rev-parse`")?;
48        if output.status.success() {
49            return Ok(candidate.to_string()); // LLVM_COV_EXCL_LINE
50        }
51    }
52
53    bail!("Could not detect default branch for the repository"); // LLVM_COV_EXCL_LINE
54}
55
56pub fn branch_exists_remote(bare: &Path, branch: &str) -> bool {
57    Command::new("git")
58        .args(["-C"])
59        .arg(bare)
60        .args([
61            "rev-parse",
62            "--verify",
63            &format!("refs/remotes/origin/{branch}"),
64        ])
65        .output()
66        .map(|o| o.status.success())
67        .unwrap_or(false)
68}