use anyhow::Result; use crate::git; use super::helpers::require_session; pub async fn action(branch: &str) -> Result<()> { let (_, session) = require_session(branch).await; // Check for uncommitted changes (staged + unstaged) let status = tokio::process::Command::new("git") .args(["-C", &session.worktree, "status", "--porcelain"]) .stdout(std::process::Stdio::piped()) .stderr(std::process::Stdio::piped()) .output() .await; let status = match status { Ok(o) if o.status.success() => String::from_utf8_lossy(&o.stdout).to_string(), _ => { eprintln!("\u{2716} git status failed"); std::process::exit(1); } }; let args: Vec = if !status.trim().is_empty() { // Show uncommitted changes let has_head = tokio::process::Command::new("git") .args(["-C", &session.worktree, "rev-parse", "--verify", "HEAD"]) .stdout(std::process::Stdio::null()) .stderr(std::process::Stdio::null()) .status() .await; if has_head.is_ok_and(|s| s.success()) { vec!["diff".into(), "HEAD".into()] } else { vec!["diff".into()] } } else { // No uncommitted changes — show full branch diff vs main let main = git::main_branch(Some(&session.worktree)).await?; vec!["diff".into(), format!("{main}...{branch}")] }; // Run git diff with inherited stdio let status = std::process::Command::new("git") .args( std::iter::once("-C".to_string()) .chain(std::iter::once(session.worktree.clone())) .chain(args), ) .stdin(std::process::Stdio::inherit()) .stdout(std::process::Stdio::inherit()) .stderr(std::process::Stdio::inherit()) .spawn()? .wait()?; if !status.success() { std::process::exit(status.code().unwrap_or(1)); } Ok(()) }