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 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 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 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 != ¤t_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 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}