git_x/
what.rs

1use std::process::Command;
2
3pub fn run(target: Option<String>) {
4    let target_branch = target.unwrap_or_else(|| "main".to_string());
5
6    // Get current branch name
7    let current_branch_output = Command::new("git")
8        .args(["rev-parse", "--abbrev-ref", "HEAD"])
9        .output()
10        .expect("Failed to get current branch");
11    let current_branch = String::from_utf8_lossy(&current_branch_output.stdout)
12        .trim()
13        .to_string();
14
15    println!("Branch: {current_branch} vs {target_branch}");
16
17    // Get ahead/behind commit counts
18    let rev_list_output = Command::new("git")
19        .args([
20            "rev-list",
21            "--left-right",
22            "--count",
23            &format!("{target_branch}...{current_branch}"),
24        ])
25        .output()
26        .expect("Failed to get ahead/behind count");
27    let output_str = String::from_utf8_lossy(&rev_list_output.stdout);
28    let counts = output_str.split_whitespace().collect::<Vec<&str>>();
29    let behind = counts.first().unwrap_or(&"0");
30    let ahead = counts.get(1).unwrap_or(&"0");
31
32    println!("+ {ahead} commits ahead");
33    println!("- {behind} commits behind");
34
35    // Get diff summary
36    let diff_output = Command::new("git")
37        .args([
38            "diff",
39            "--name-status",
40            &format!("{target_branch}...{current_branch}"),
41        ])
42        .output()
43        .expect("Failed to get diff");
44    let diff = String::from_utf8_lossy(&diff_output.stdout);
45
46    println!("Changes:");
47    for line in diff.lines() {
48        let parts: Vec<&str> = line.split_whitespace().collect();
49        if parts.len() >= 2 {
50            let symbol = match parts[0] {
51                "A" => "+",
52                "M" => "~",
53                "D" => "-",
54                other => other,
55            };
56            println!(" - {} {}", symbol, parts[1]);
57        }
58    }
59}