diff --git a/src/app.rs b/src/app.rs index a505963a..4533cd6e 100644 --- a/src/app.rs +++ b/src/app.rs @@ -5,7 +5,7 @@ use crate::{ git_utils::{self, Diff, DiffLine, DiffLineType}, }; use crossterm::event::{Event, KeyCode, MouseEvent}; -use git2::{IndexAddOption, StatusShow}; +use git2::StatusShow; use itertools::Itertools; use std::{borrow::Cow, path::Path}; use tui::{ @@ -226,7 +226,7 @@ impl App { } if ev == Event::Key(KeyCode::Enter.into()) { - self.index_add(); + self.index_add_remove(); } } } @@ -273,31 +273,20 @@ impl App { self.update_diff(); } - fn index_add(&mut self) { + fn index_add_remove(&mut self) { if self.index_wd.focused() { if let Some(i) = self.index_wd.selection() { - let repo = git_utils::repo(); - - let mut index = repo.index().unwrap(); - let path = Path::new(i.path.as_str()); - let cb = - &mut |p: &Path, _matched_spec: &[u8]| -> i32 { - if p == path { - 0 - } else { - 1 - } - }; + if git_utils::stage_add(path) { + self.update(); + } + } + } else { + if let Some(i) = self.index.selection() { + let path = Path::new(i.path.as_str()); - if let Ok(_) = index.add_all( - path, - IndexAddOption::DISABLE_PATHSPEC_MATCH - | IndexAddOption::CHECK_PATHSPEC, - Some(cb as &mut git2::IndexMatchedPath), - ) { - index.write().unwrap(); + if git_utils::stage_reset(path) { self.update(); } } diff --git a/src/git_utils.rs b/src/git_utils.rs index 7bf32633..c76b6ce1 100644 --- a/src/git_utils.rs +++ b/src/git_utils.rs @@ -1,5 +1,6 @@ use git2::{ - DiffFormat, DiffOptions, Repository, StatusOptions, StatusShow, + DiffFormat, DiffOptions, IndexAddOption, ObjectType, Repository, + StatusOptions, StatusShow, }; use std::path::Path; @@ -134,3 +135,48 @@ pub fn index_empty() -> bool { statuses.is_empty() } + +pub fn stage_add(path: &Path) -> bool { + let repo = repo(); + + let mut index = repo.index().unwrap(); + + let cb = &mut |p: &Path, _matched_spec: &[u8]| -> i32 { + if p == path { + 0 + } else { + 1 + } + }; + let cb = Some(cb as &mut git2::IndexMatchedPath); + + let flags = IndexAddOption::DISABLE_PATHSPEC_MATCH + | IndexAddOption::CHECK_PATHSPEC; + + if let Ok(_) = index.add_all(path, flags, cb) { + index.write().unwrap(); + return true; + } + + false +} + +pub fn stage_reset(path: &Path) -> bool { + let repo = repo(); + + let mut index = repo.index().unwrap(); + + let reference = repo.head().unwrap(); + let obj = repo + .find_object( + reference.target().unwrap(), + Some(ObjectType::Commit), + ) + .unwrap(); + + if let Ok(_) = repo.reset_default(Some(&obj), &[path]) { + return true; + } + + false +}