64 lines
2.0 KiB
Rust
64 lines
2.0 KiB
Rust
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<String> = 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(())
|
|
}
|