Skip to content

Commit d67a240

Browse files
author
Stephan Dilly
committed
fix reset hunk in untracked file
1 parent dfe284a commit d67a240

File tree

3 files changed

+70
-5
lines changed

3 files changed

+70
-5
lines changed

asyncgit/src/sync/diff.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ pub struct FileDiff {
7373
pub hunks: Vec<Hunk>,
7474
/// lines total summed up over hunks
7575
pub lines: usize,
76+
///
77+
pub untracked: bool,
7678
}
7779

7880
pub(crate) fn get_diff_raw<'a>(
@@ -150,8 +152,6 @@ fn raw_diff_to_file_diff<'a>(
150152
diff: &'a Diff,
151153
work_dir: &Path,
152154
) -> Result<FileDiff> {
153-
// scope_time!("raw_diff_to_file_diff");
154-
155155
let mut res: FileDiff = FileDiff::default();
156156
let mut current_lines = Vec::new();
157157
let mut current_hunk: Option<HunkHeader> = None;
@@ -251,6 +251,10 @@ fn raw_diff_to_file_diff<'a>(
251251
adder(&current_hunk.unwrap(), &current_lines);
252252
}
253253

254+
if new_file_diff {
255+
res.untracked = true;
256+
}
257+
254258
Ok(res)
255259
}
256260

asyncgit/src/sync/hunks.rs

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ pub fn stage_hunk(
3232
Ok(())
3333
}
3434

35-
///
35+
/// this will fail for an all untracked file
3636
pub fn reset_hunk(
3737
repo_path: &str,
3838
file_path: String,
@@ -134,3 +134,45 @@ pub fn unstage_hunk(
134134

135135
Ok(count == 1)
136136
}
137+
138+
#[cfg(test)]
139+
mod tests {
140+
use super::*;
141+
use crate::{
142+
error::Result,
143+
sync::{diff::get_diff, tests::repo_init_empty},
144+
};
145+
use std::{
146+
fs::{self, File},
147+
io::Write,
148+
path::Path,
149+
};
150+
151+
#[test]
152+
fn reset_untracked_file_which_will_not_find_hunk() -> Result<()> {
153+
let file_path = Path::new("foo/foo.txt");
154+
let (_td, repo) = repo_init_empty()?;
155+
let root = repo.path().parent().unwrap();
156+
let repo_path = root.as_os_str().to_str().unwrap();
157+
158+
let sub_path = root.join("foo/");
159+
160+
fs::create_dir_all(&sub_path)?;
161+
File::create(&root.join(file_path))?.write_all(b"test")?;
162+
163+
let diff = get_diff(
164+
sub_path.to_str().unwrap(),
165+
String::from(file_path.to_str().unwrap()),
166+
false,
167+
)?;
168+
169+
assert!(reset_hunk(
170+
repo_path,
171+
String::from(file_path.to_str().unwrap()),
172+
diff.hunks[0].header_hash,
173+
)
174+
.is_err());
175+
176+
Ok(())
177+
}
178+
}

src/components/diff.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use super::{CommandBlocking, DrawableComponent, ScrollType};
22
use crate::{
33
components::{CommandInfo, Component},
44
keys,
5-
queue::{Action, InternalEvent, Queue},
5+
queue::{Action, InternalEvent, Queue, ResetItem},
66
strings,
77
ui::{calc_scroll_top, style::Theme},
88
};
@@ -303,6 +303,21 @@ impl DiffComponent {
303303
Ok(())
304304
}
305305

306+
fn reset_untracked(&self) -> Result<()> {
307+
self.queue
308+
.as_ref()
309+
.expect("try using queue in immutable diff")
310+
.borrow_mut()
311+
.push_back(InternalEvent::ConfirmAction(Action::Reset(
312+
ResetItem {
313+
path: self.current.path.clone(),
314+
is_folder: false,
315+
},
316+
)));
317+
318+
Ok(())
319+
}
320+
306321
fn is_immutable(&self) -> bool {
307322
self.queue.is_none()
308323
}
@@ -426,7 +441,11 @@ impl Component for DiffComponent {
426441
if !self.is_immutable()
427442
&& !self.is_stage() =>
428443
{
429-
self.reset_hunk()?;
444+
if self.diff.untracked {
445+
self.reset_untracked()?;
446+
} else {
447+
self.reset_hunk()?;
448+
}
430449
Ok(true)
431450
}
432451
_ => Ok(false),

0 commit comments

Comments
 (0)