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