mirror of
https://github.com/gitui-org/gitui
synced 2026-05-23 17:08:21 +00:00
reset: simply delete files if they are new/untracked
This commit is contained in:
parent
a4ac4158aa
commit
aea8725d1a
1 changed files with 77 additions and 18 deletions
|
|
@ -1,7 +1,7 @@
|
|||
use super::utils::repo;
|
||||
use git2::{build::CheckoutBuilder, ObjectType};
|
||||
use git2::{build::CheckoutBuilder, ObjectType, Status};
|
||||
use scopetime::scope_time;
|
||||
use std::path::Path;
|
||||
use std::{fs, path::Path};
|
||||
|
||||
///
|
||||
pub fn reset_stage(repo_path: &str, path: &Path) -> bool {
|
||||
|
|
@ -30,25 +30,48 @@ pub fn reset_workdir(repo_path: &str, path: &Path) -> bool {
|
|||
|
||||
let repo = repo(repo_path);
|
||||
|
||||
let mut checkout_opts = CheckoutBuilder::new();
|
||||
checkout_opts
|
||||
.remove_untracked(true)
|
||||
.force()
|
||||
.update_index(false)
|
||||
.path(&path);
|
||||
// Note: early out for removing untracked files, due to bug in checkout_head code:
|
||||
// see https://github.com/libgit2/libgit2/issues/5089
|
||||
if let Ok(status) = repo.status_file(&path) {
|
||||
dbg!(status);
|
||||
|
||||
//first reset working dir file
|
||||
repo.checkout_head(Some(&mut checkout_opts)).unwrap();
|
||||
let removed_file_wd = if status == Status::WT_NEW
|
||||
|| (status == Status::WT_MODIFIED | Status::INDEX_NEW)
|
||||
{
|
||||
fs::remove_file(Path::new(repo_path).join(path)).is_ok()
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
let mut checkout_opts = CheckoutBuilder::new();
|
||||
checkout_opts
|
||||
.update_index(true) // windows: needs this to be true WTF?!
|
||||
.path(&path);
|
||||
if status == Status::WT_NEW {
|
||||
return removed_file_wd;
|
||||
}
|
||||
|
||||
// now reset staged changes back to working dir
|
||||
repo.checkout_index(None, Some(&mut checkout_opts)).unwrap();
|
||||
if status != Status::WT_MODIFIED | Status::INDEX_NEW {
|
||||
let mut checkout_opts = CheckoutBuilder::new();
|
||||
checkout_opts
|
||||
.remove_untracked(true)
|
||||
.force()
|
||||
.update_index(false)
|
||||
.path(&path);
|
||||
|
||||
true
|
||||
//first reset working dir file
|
||||
repo.checkout_head(Some(&mut checkout_opts)).unwrap();
|
||||
}
|
||||
|
||||
let mut checkout_opts = CheckoutBuilder::new();
|
||||
checkout_opts
|
||||
.update_index(true) // windows: needs this to be true WTF?!
|
||||
.allow_conflicts(true)
|
||||
.path(&path);
|
||||
|
||||
// now reset staged changes back to working dir
|
||||
repo.checkout_index(None, Some(&mut checkout_opts)).unwrap();
|
||||
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
@ -59,7 +82,11 @@ mod tests {
|
|||
tests::{debug_cmd_print, repo_init},
|
||||
utils::stage_add,
|
||||
};
|
||||
use std::{fs::File, io::Write, path::Path};
|
||||
use std::{
|
||||
fs::{self, File},
|
||||
io::Write,
|
||||
path::Path,
|
||||
};
|
||||
|
||||
static HUNK_A: &str = r"
|
||||
1 start
|
||||
|
|
@ -138,4 +165,36 @@ mod tests {
|
|||
0
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_reset_untracked_in_subdir() {
|
||||
let (_td, repo) = repo_init();
|
||||
let root = repo.path().parent().unwrap();
|
||||
let repo_path = root.as_os_str().to_str().unwrap();
|
||||
|
||||
{
|
||||
fs::create_dir(&root.join("foo")).unwrap();
|
||||
File::create(&root.join("foo/bar.txt"))
|
||||
.unwrap()
|
||||
.write_all(b"test\nfoo")
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
debug_cmd_print(repo_path, "git status");
|
||||
|
||||
assert_eq!(
|
||||
get_status(repo_path, StatusType::WorkingDir).len(),
|
||||
1
|
||||
);
|
||||
|
||||
let res = reset_workdir(repo_path, Path::new("foo/bar.txt"));
|
||||
assert_eq!(res, true);
|
||||
|
||||
debug_cmd_print(repo_path, "git status");
|
||||
|
||||
assert_eq!(
|
||||
get_status(repo_path, StatusType::WorkingDir).len(),
|
||||
0
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue