1use crate::{Repository, Result, VcsError};
2
3pub struct Stash;
7
8#[derive(Debug, Clone)]
10pub struct StashEntry {
11 pub index: usize,
13 pub message: String,
15}
16
17impl Stash {
18 pub fn list(repo: &Repository) -> Result<Vec<StashEntry>> {
22 let lines = repo.run_git_str(["stash", "list"])?;
23 let mut entries = Vec::new();
24 for (i, line) in lines.lines().enumerate() {
25 if line.trim().is_empty() {
26 continue;
27 }
28 entries.push(StashEntry {
29 index: i,
30 message: line.trim().to_string(),
31 });
32 }
33 Ok(entries)
34 }
35
36 pub fn apply(repo: &Repository, index: usize) -> Result<()> {
40 let refspec = format!("stash@{{{}}}", index);
41 repo.run_git(["stash", "apply", &refspec])
42 .map(|_| ())
43 .map_err(|e| VcsError::Stash(format!("stash apply {}: {}", index, e)))
44 }
45
46 pub fn pop(repo: &Repository, index: usize) -> Result<()> {
50 let refspec = format!("stash@{{{}}}", index);
51 repo.run_git(["stash", "pop", &refspec])
52 .map(|_| ())
53 .map_err(|e| VcsError::Stash(format!("stash pop {}: {}", index, e)))
54 }
55
56 pub fn drop(repo: &Repository, index: usize) -> Result<()> {
60 let refspec = format!("stash@{{{}}}", index);
61 repo.run_git(["stash", "drop", &refspec])
62 .map(|_| ())
63 .map_err(|e| VcsError::Stash(format!("stash drop {}: {}", index, e)))
64 }
65
66 pub fn create(repo: &Repository, message: Option<&str>, include_untracked: bool) -> Result<()> {
73 let mut args: Vec<String> = vec!["stash".into(), "push".into()];
74 if include_untracked {
75 args.push("--include-untracked".into());
76 }
77 if let Some(msg) = message {
78 args.push("-m".into());
79 args.push(msg.into());
80 }
81 let refs: Vec<&str> = args.iter().map(|s| s.as_str()).collect();
82 repo.run_git(refs)
83 .map(|_| ())
84 .map_err(|e| VcsError::Stash(format!("stash create: {}", e)))
85 }
86}