Skip to content

Commit 73c6501

Browse files
author
Stephan Dilly
committed
fix staging removed files (fixes #24)
1 parent 6fa620e commit 73c6501

File tree

3 files changed

+66
-6
lines changed

3 files changed

+66
-6
lines changed

asyncgit/src/sync/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ pub mod utils;
1010
pub use hooks::{hooks_commit_msg, hooks_post_commit, HookResult};
1111
pub use hunks::{stage_hunk, unstage_hunk};
1212
pub use reset::{reset_stage, reset_workdir};
13-
pub use utils::{commit, stage_add};
13+
pub use utils::{commit, stage_add, stage_addremoved};
1414

1515
#[cfg(test)]
1616
mod tests {

asyncgit/src/sync/utils.rs

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ pub fn commit(repo_path: &str, msg: &str) {
6262
.unwrap();
6363
}
6464

65-
///
65+
/// add a file diff from workingdir to stage (will not add removed files see `stage_addremoved`)
6666
pub fn stage_add(repo_path: &str, path: &Path) -> bool {
6767
scope_time!("stage_add");
6868

@@ -78,6 +78,22 @@ pub fn stage_add(repo_path: &str, path: &Path) -> bool {
7878
false
7979
}
8080

81+
/// stage a removed file
82+
pub fn stage_addremoved(repo_path: &str, path: &Path) -> bool {
83+
scope_time!("stage_addremoved");
84+
85+
let repo = repo(repo_path);
86+
87+
let mut index = repo.index().unwrap();
88+
89+
if index.remove_path(path).is_ok() {
90+
index.write().unwrap();
91+
return true;
92+
}
93+
94+
false
95+
}
96+
8197
#[cfg(test)]
8298
mod tests {
8399
use super::*;
@@ -86,7 +102,11 @@ mod tests {
86102
status::{get_status, StatusType},
87103
tests::{repo_init, repo_init_empty},
88104
};
89-
use std::{fs::File, io::Write, path::Path};
105+
use std::{
106+
fs::{remove_file, File},
107+
io::Write,
108+
path::Path,
109+
};
90110

91111
#[test]
92112
fn test_commit() {
@@ -172,4 +192,38 @@ mod tests {
172192
assert_eq!(status_count(StatusType::WorkingDir), 1);
173193
assert_eq!(status_count(StatusType::Stage), 1);
174194
}
195+
196+
#[test]
197+
fn test_staging_deleted_file() {
198+
let file_path = Path::new("file1.txt");
199+
let (_td, repo) = repo_init();
200+
let root = repo.path().parent().unwrap();
201+
let repo_path = root.as_os_str().to_str().unwrap();
202+
203+
let status_count = |s: StatusType| -> usize {
204+
get_status(repo_path, s).len()
205+
};
206+
207+
let full_path = &root.join(file_path);
208+
209+
File::create(full_path)
210+
.unwrap()
211+
.write_all(b"test file1 content")
212+
.unwrap();
213+
214+
assert_eq!(stage_add(repo_path, file_path), true);
215+
216+
commit(repo_path, "commit msg");
217+
218+
// delete the file now
219+
assert_eq!(remove_file(full_path).is_ok(), true);
220+
221+
// deleted file in diff now
222+
assert_eq!(status_count(StatusType::WorkingDir), 1);
223+
224+
assert_eq!(stage_addremoved(repo_path, file_path), true);
225+
226+
assert_eq!(status_count(StatusType::WorkingDir), 0);
227+
assert_eq!(status_count(StatusType::Stage), 1);
228+
}
175229
}

src/components/changes.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,15 @@ impl ChangesComponent {
114114
fn index_add_remove(&mut self) -> bool {
115115
if let Some(i) = self.selection() {
116116
if self.is_working_dir {
117-
let path = Path::new(i.path.as_str());
118-
119-
return sync::stage_add(CWD, path);
117+
if let Some(status) = i.status {
118+
let path = Path::new(i.path.as_str());
119+
return match status {
120+
StatusItemType::Deleted => {
121+
sync::stage_addremoved(CWD, path)
122+
}
123+
_ => sync::stage_add(CWD, path),
124+
};
125+
}
120126
} else {
121127
let path = Path::new(i.path.as_str());
122128

0 commit comments

Comments
 (0)