git_x/
prune_branches.rs

1use std::io::{BufRead, BufReader};
2use std::process::{Command, exit};
3
4pub fn run(except: Option<String>) {
5    let mut protected_branches = vec!["main", "master", "develop"];
6
7    // Extend protected list with user-supplied excluded branches
8    if let Some(ref input) = except {
9        let extras: Vec<&str> = input
10            .split(',')
11            .map(|s| s.trim())
12            .filter(|s| !s.is_empty())
13            .collect();
14        protected_branches.extend(extras);
15    }
16
17    // Step 1: Get current branch
18    let output = Command::new("git")
19        .args(["rev-parse", "--abbrev-ref", "HEAD"])
20        .output()
21        .expect("Failed to get current branch");
22
23    if !output.status.success() {
24        eprintln!("Error: Could not determine current branch.");
25        exit(1);
26    }
27
28    let current_branch = String::from_utf8_lossy(&output.stdout).trim().to_string();
29
30    // Step 2: Get merged branches
31    let output = Command::new("git")
32        .args(["branch", "--merged"])
33        .output()
34        .expect("Failed to get merged branches");
35
36    if !output.status.success() {
37        eprintln!("Error: Failed to list merged branches.");
38        exit(1);
39    }
40
41    let reader = BufReader::new(output.stdout.as_slice());
42    let branches: Vec<String> = reader
43        .lines()
44        .map_while(Result::ok)
45        .map(|b| b.trim().trim_start_matches("* ").to_string())
46        .filter(|b| b != &current_branch && !protected_branches.iter().any(|pb| pb == b))
47        .collect();
48
49    if branches.is_empty() {
50        println!("✅ No merged branches to prune.");
51        return;
52    }
53
54    // Step 3: Delete branches
55    for branch in branches {
56        let status = Command::new("git")
57            .args(["branch", "-d", &branch])
58            .status()
59            .expect("Failed to delete branch");
60
61        if status.success() {
62            println!("🧹 Deleted merged branch '{branch}'");
63        } else {
64            eprintln!("⚠️ Failed to delete branch '{branch}'");
65        }
66    }
67}