use crate::cli::UI;
use crate::ops::oplog;
use anyhow::Result;
use std::path::Path;
pub fn save(path: &Path, message: Option<&str>, ui: &UI) -> Result<()> {
let desc = format!("stash save '{}'", message.unwrap_or("WIP"));
oplog::with_oplog(path, "stash", &desc, || save_inner(path, message, ui))
}
fn save_inner(path: &Path, message: Option<&str>, ui: &UI) -> Result<()> {
let mut repo = crate::ops::open_repo(path)?;
let sig = repo.signature()?;
let msg = message.unwrap_or("WIP on stash");
let flags = git2::StashFlags::DEFAULT;
repo.stash_save(&sig, msg, Some(flags))?;
ui.success(format!("Saved working directory: {}", msg));
Ok(())
}
pub fn pop(path: &Path, index: usize, ui: &UI) -> Result<()> {
oplog::with_oplog(path, "stash", &format!("pop stash@{{{}}}", index), || {
pop_inner(path, index, ui)
})
}
fn pop_inner(path: &Path, index: usize, ui: &UI) -> Result<()> {
let mut repo = crate::ops::open_repo(path)?;
repo.stash_pop(index, None)?;
ui.success(format!("Dropped stash@{{{}}}", index));
Ok(())
}
pub fn apply(path: &Path, index: usize, ui: &UI) -> Result<()> {
let mut repo = crate::ops::open_repo(path)?;
repo.stash_apply(index, None)?;
ui.success(format!("Applied stash@{{{}}}", index));
Ok(())
}
pub fn list_compact(path: &Path) -> Result<String> {
let mut repo = crate::ops::open_repo(path)?;
let mut entries = Vec::new();
repo.stash_foreach(|index, message, _oid| {
let msg = message
.find(": ")
.map(|i| &message[i + 2..])
.unwrap_or(message);
entries.push(format!("stash@{{{}}}: {}", index, msg));
true
})?;
if entries.is_empty() {
Ok("(no stashes)".to_string())
} else {
Ok(entries.join("\n"))
}
}
pub fn list(path: &Path, ui: &UI) -> Result<()> {
let mut repo = crate::ops::open_repo(path)?;
let mut entries = Vec::new();
repo.stash_foreach(|index, message, _oid| {
entries.push((index, message.to_string()));
true
})?;
for (index, message) in &entries {
ui.list_item(format!("stash@{{{}}}: {}", index, message));
}
if entries.is_empty() {
ui.info("No stash entries found");
}
Ok(())
}
pub fn drop_stash(path: &Path, index: usize, ui: &UI) -> Result<()> {
oplog::with_oplog(path, "stash", &format!("drop stash@{{{}}}", index), || {
drop_inner(path, index, ui)
})
}
fn drop_inner(path: &Path, index: usize, ui: &UI) -> Result<()> {
let mut repo = crate::ops::open_repo(path)?;
repo.stash_drop(index)?;
ui.success(format!("Dropped stash@{{{}}}", index));
Ok(())
}