use anyhow::{Context, Result, anyhow};
use std::path::Path;
use std::process::Command;
use crate::cmd::Cmd;
pub fn commit_with_editor(worktree_path: &Path) -> Result<()> {
let status = Command::new("git")
.current_dir(worktree_path)
.arg("commit")
.status()
.context("Failed to run git commit")?;
if !status.success() {
return Err(anyhow!("Commit was aborted or failed"));
}
Ok(())
}
pub fn merge_in_worktree(worktree_path: &Path, branch_name: &str) -> Result<()> {
Cmd::new("git")
.workdir(worktree_path)
.args(&["merge", branch_name])
.run()
.context("Failed to merge")?;
Ok(())
}
pub fn rebase_branch_onto_base(worktree_path: &Path, base_branch: &str) -> Result<()> {
Cmd::new("git")
.workdir(worktree_path)
.args(&["rebase", base_branch])
.run()
.with_context(|| format!("Failed to rebase onto '{}'", base_branch))?;
Ok(())
}
pub fn merge_squash_in_worktree(worktree_path: &Path, branch_name: &str) -> Result<()> {
Cmd::new("git")
.workdir(worktree_path)
.args(&["merge", "--squash", branch_name])
.run()
.context("Failed to perform squash merge")?;
Ok(())
}
pub fn switch_branch_in_worktree(worktree_path: &Path, branch_name: &str) -> Result<()> {
Cmd::new("git")
.workdir(worktree_path)
.args(&["switch", branch_name])
.run()
.with_context(|| {
format!(
"Failed to switch to branch '{}' in worktree '{}'",
branch_name,
worktree_path.display()
)
})?;
Ok(())
}
pub fn stash_push(message: &str, include_untracked: bool, patch: bool) -> Result<()> {
if patch {
let status = Command::new("git")
.args(["stash", "push", "-m", message, "--patch"])
.status()
.context("Failed to run interactive git stash")?;
if !status.success() {
return Err(anyhow!(
"Git stash --patch failed. Make sure you select at least one hunk."
));
}
} else {
let mut cmd = Cmd::new("git").args(&["stash", "push", "-m", message]);
if include_untracked {
cmd = cmd.arg("--include-untracked");
}
cmd.run().context("Failed to stash changes")?;
}
Ok(())
}
pub fn stash_pop(worktree_path: &Path) -> Result<()> {
Cmd::new("git")
.workdir(worktree_path)
.args(&["stash", "pop"])
.run()
.context("Failed to apply stashed changes. Conflicts may have occurred.")?;
Ok(())
}
pub fn reset_hard(worktree_path: &Path) -> Result<()> {
Cmd::new("git")
.workdir(worktree_path)
.args(&["reset", "--hard", "HEAD"])
.run()
.context("Failed to reset worktree")?;
Ok(())
}
pub fn abort_merge_in_worktree(worktree_path: &Path) -> Result<()> {
Cmd::new("git")
.workdir(worktree_path)
.args(&["merge", "--abort"])
.run()
.context("Failed to abort merge. The worktree may not be in a merging state.")?;
Ok(())
}