From d67a240bc7767e39c89e5eb9c51df8179c84df68 Mon Sep 17 00:00:00 2001 From: Stephan Dilly Date: Sun, 14 Jun 2020 23:34:54 +0200 Subject: [PATCH] fix reset hunk in untracked file --- asyncgit/src/sync/diff.rs | 8 +++++-- asyncgit/src/sync/hunks.rs | 44 +++++++++++++++++++++++++++++++++++++- src/components/diff.rs | 23 ++++++++++++++++++-- 3 files changed, 70 insertions(+), 5 deletions(-) diff --git a/asyncgit/src/sync/diff.rs b/asyncgit/src/sync/diff.rs index b535e73d..c745b2c9 100644 --- a/asyncgit/src/sync/diff.rs +++ b/asyncgit/src/sync/diff.rs @@ -73,6 +73,8 @@ pub struct FileDiff { pub hunks: Vec, /// lines total summed up over hunks pub lines: usize, + /// + pub untracked: bool, } pub(crate) fn get_diff_raw<'a>( @@ -150,8 +152,6 @@ fn raw_diff_to_file_diff<'a>( diff: &'a Diff, work_dir: &Path, ) -> Result { - // scope_time!("raw_diff_to_file_diff"); - let mut res: FileDiff = FileDiff::default(); let mut current_lines = Vec::new(); let mut current_hunk: Option = None; @@ -251,6 +251,10 @@ fn raw_diff_to_file_diff<'a>( adder(¤t_hunk.unwrap(), ¤t_lines); } + if new_file_diff { + res.untracked = true; + } + Ok(res) } diff --git a/asyncgit/src/sync/hunks.rs b/asyncgit/src/sync/hunks.rs index 271a2fd3..e56c7694 100644 --- a/asyncgit/src/sync/hunks.rs +++ b/asyncgit/src/sync/hunks.rs @@ -32,7 +32,7 @@ pub fn stage_hunk( Ok(()) } -/// +/// this will fail for an all untracked file pub fn reset_hunk( repo_path: &str, file_path: String, @@ -134,3 +134,45 @@ pub fn unstage_hunk( Ok(count == 1) } + +#[cfg(test)] +mod tests { + use super::*; + use crate::{ + error::Result, + sync::{diff::get_diff, tests::repo_init_empty}, + }; + use std::{ + fs::{self, File}, + io::Write, + path::Path, + }; + + #[test] + fn reset_untracked_file_which_will_not_find_hunk() -> Result<()> { + let file_path = Path::new("foo/foo.txt"); + let (_td, repo) = repo_init_empty()?; + let root = repo.path().parent().unwrap(); + let repo_path = root.as_os_str().to_str().unwrap(); + + let sub_path = root.join("foo/"); + + fs::create_dir_all(&sub_path)?; + File::create(&root.join(file_path))?.write_all(b"test")?; + + let diff = get_diff( + sub_path.to_str().unwrap(), + String::from(file_path.to_str().unwrap()), + false, + )?; + + assert!(reset_hunk( + repo_path, + String::from(file_path.to_str().unwrap()), + diff.hunks[0].header_hash, + ) + .is_err()); + + Ok(()) + } +} diff --git a/src/components/diff.rs b/src/components/diff.rs index 06514c8c..fc719689 100644 --- a/src/components/diff.rs +++ b/src/components/diff.rs @@ -2,7 +2,7 @@ use super::{CommandBlocking, DrawableComponent, ScrollType}; use crate::{ components::{CommandInfo, Component}, keys, - queue::{Action, InternalEvent, Queue}, + queue::{Action, InternalEvent, Queue, ResetItem}, strings, ui::{calc_scroll_top, style::Theme}, }; @@ -303,6 +303,21 @@ impl DiffComponent { Ok(()) } + fn reset_untracked(&self) -> Result<()> { + self.queue + .as_ref() + .expect("try using queue in immutable diff") + .borrow_mut() + .push_back(InternalEvent::ConfirmAction(Action::Reset( + ResetItem { + path: self.current.path.clone(), + is_folder: false, + }, + ))); + + Ok(()) + } + fn is_immutable(&self) -> bool { self.queue.is_none() } @@ -426,7 +441,11 @@ impl Component for DiffComponent { if !self.is_immutable() && !self.is_stage() => { - self.reset_hunk()?; + if self.diff.untracked { + self.reset_untracked()?; + } else { + self.reset_hunk()?; + } Ok(true) } _ => Ok(false),