fix working dir checkout (revert)

This commit is contained in:
Stephan Dilly 2020-03-27 22:10:56 +01:00
parent 2b45a039d1
commit c455f3e316
7 changed files with 222 additions and 52 deletions

8
Cargo.lock generated
View file

@ -270,9 +270,9 @@ dependencies = [
[[package]]
name = "git2"
version = "0.10.2"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c1af51ea8a906616af45a4ce78eacf25860f7a13ae7bf8a814693f0f4037a26"
checksum = "b7da16ceafe24cedd9ba02c4463a2b506b6493baf4317c79c5acb553134a3c15"
dependencies = [
"bitflags",
"libc",
@ -379,9 +379,9 @@ checksum = "eb147597cdf94ed43ab7a9038716637d2d1bf2bc571da995d0028dec06bd3018"
[[package]]
name = "libgit2-sys"
version = "0.9.2"
version = "0.12.0+0.99.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4870c781f6063efb83150cd22c1ddf6ecf58531419e7570cdcced46970f64a16"
checksum = "05dff41ac39e7b653f5f1550886cf00ba52f8e7f57210b633cdeedb3de5b236c"
dependencies = [
"cc",
"libc",

View file

@ -55,7 +55,6 @@ GITUI_LOGGING=true gitui
# todo for 0.1 (first release)
* [ ] fix: reset unstaged file also resets staged hunks
* [ ] better help command
* [ ] -> fix: dont show scroll option when any popup open
* [ ] confirm destructive commands (revert/reset)

View file

@ -10,7 +10,7 @@ license = "MIT"
categories = ["concurrency","asynchronous"]
[dependencies]
git2 = "0.10"
git2 = "0.13"
rayon-core = "1.7"
crossbeam-channel = "0.4"
log = "0.4"

View file

@ -1,7 +1,9 @@
//! sync git api
pub mod diff;
mod reset;
pub mod status;
pub mod utils;
pub use utils::{commit, index_reset, stage_add, stage_reset};
pub use reset::{index_reset, stage_reset};
pub use utils::{commit, stage_add};

191
asyncgit/src/sync/reset.rs Normal file
View file

@ -0,0 +1,191 @@
use super::utils::repo_at;
use git2::ObjectType;
use scopetime::scope_time;
use std::{path::Path, process::Command};
///
pub fn stage_reset(path: &Path) -> bool {
stage_reset_at("./", path)
}
///
pub fn stage_reset_at(repo_path: &str, path: &Path) -> bool {
scope_time!("stage_reset_at");
let repo = repo_at(repo_path);
let reference = repo.head().unwrap();
let obj = repo
.find_object(
reference.target().unwrap(),
Some(ObjectType::Commit),
)
.unwrap();
if repo.reset_default(Some(&obj), &[path]).is_ok() {
return true;
}
false
}
///
pub fn index_reset(path: &Path) -> bool {
index_reset_at("./", path)
}
///
pub fn index_reset_at(repo_path: &str, path: &Path) -> bool {
let cmd = format!("git checkout {:?}", path);
let output = if cfg!(target_os = "windows") {
Command::new("cmd")
.args(&["/C", cmd.as_str()])
.current_dir(repo_path)
.output()
} else {
Command::new("sh")
.arg("-c")
.arg(cmd.as_str())
.current_dir(repo_path)
.output()
};
output.is_ok()
//------------------------------------
//TODO: why is this broken with libgit2 ???
//------------------------------------
// scope_time!("index_reset");
// let repo = repo_at(repo_path);
// let mut checkout_opts = CheckoutBuilder::new();
// checkout_opts
// .remove_untracked(true)
// .force()
// .update_index(false)
// .allow_conflicts(true)
// .path(&path);
// if repo.checkout_head(Some(&mut checkout_opts)).is_ok() {
// return true;
// }
// false
}
#[cfg(test)]
mod tests {
use super::index_reset_at;
use crate::sync::{
status::{get_index_at, StatusType},
utils::stage_add_at,
};
use git2::Repository;
use std::{fs::File, io::Write, path::Path};
use tempfile::TempDir;
pub fn repo_init() -> (TempDir, Repository) {
let td = TempDir::new().unwrap();
let repo = Repository::init(td.path()).unwrap();
{
let mut config = repo.config().unwrap();
config.set_str("user.name", "name").unwrap();
config.set_str("user.email", "email").unwrap();
let mut index = repo.index().unwrap();
let id = index.write_tree().unwrap();
let tree = repo.find_tree(id).unwrap();
let sig = repo.signature().unwrap();
repo.commit(
Some("HEAD"),
&sig,
&sig,
"initial",
&tree,
&[],
)
.unwrap();
}
(td, repo)
}
static HUNK_A: &str = r"
1 start
2
3
4
5
6 middle
7
8
9
0
1 end";
static HUNK_B: &str = r"
1 start
2 newa
3
4
5
6 middle
7
8
9
0 newb
1 end";
#[test]
fn test_reset_only_unstaged() {
let (_td, repo) = repo_init();
let root = repo.path().parent().unwrap();
let repo_path = root.as_os_str().to_str().unwrap();
let res = get_index_at(repo_path, StatusType::WorkingDir);
assert_eq!(res.len(), 0);
let file_path = root.join("bar.txt");
{
File::create(&file_path)
.unwrap()
.write_all(HUNK_A.as_bytes())
.unwrap();
}
stage_add_at(repo_path, Path::new("bar.txt"));
// overwrite with next content
{
File::create(&file_path)
.unwrap()
.write_all(HUNK_B.as_bytes())
.unwrap();
}
assert_eq!(
get_index_at(repo_path, StatusType::Stage).len(),
1
);
assert_eq!(
get_index_at(repo_path, StatusType::WorkingDir).len(),
1
);
let res = index_reset_at(repo_path, Path::new("bar.txt"));
assert_eq!(res, true);
assert_eq!(
get_index_at(repo_path, StatusType::Stage).len(),
1
);
assert_eq!(
get_index_at(repo_path, StatusType::WorkingDir).len(),
0
);
}
}

View file

@ -64,9 +64,17 @@ impl Into<StatusShow> for StatusType {
///
pub fn get_index(status_type: StatusType) -> Vec<StatusItem> {
get_index_at("./", status_type)
}
///
pub fn get_index_at(
repo_path: &str,
status_type: StatusType,
) -> Vec<StatusItem> {
scope_time!("get_index");
let repo = utils::repo();
let repo = utils::repo_at(repo_path);
let statuses = repo
.statuses(Some(

View file

@ -1,16 +1,19 @@
//! sync git api (various methods)
use git2::{
build::CheckoutBuilder, IndexAddOption, ObjectType, Repository,
RepositoryOpenFlags,
};
use git2::{IndexAddOption, Repository, RepositoryOpenFlags};
use scopetime::scope_time;
use std::path::Path;
//TODO: get rid of this
///
pub fn repo() -> Repository {
repo_at("./")
}
///
pub fn repo_at(repo_path: &str) -> Repository {
let repo = Repository::open_ext(
"./",
repo_path,
RepositoryOpenFlags::empty(),
Vec::<&Path>::new(),
)
@ -50,9 +53,14 @@ pub fn commit(msg: &str) {
///
pub fn stage_add(path: &Path) -> bool {
stage_add_at("./", path)
}
///
pub fn stage_add_at(repo_path: &str, path: &Path) -> bool {
scope_time!("stage_add");
let repo = repo();
let repo = repo_at(repo_path);
let mut index = repo.index().unwrap();
@ -75,41 +83,3 @@ pub fn stage_add(path: &Path) -> bool {
false
}
///
pub fn stage_reset(path: &Path) -> bool {
scope_time!("stage_reset");
let repo = repo();
let reference = repo.head().unwrap();
let obj = repo
.find_object(
reference.target().unwrap(),
Some(ObjectType::Commit),
)
.unwrap();
if repo.reset_default(Some(&obj), &[path]).is_ok() {
return true;
}
false
}
///
pub fn index_reset(path: &Path) -> bool {
scope_time!("index_reset");
let repo = repo();
let mut checkout_opts = CheckoutBuilder::new();
checkout_opts.remove_untracked(true);
checkout_opts.path(&path).force();
if repo.checkout_head(Some(&mut checkout_opts)).is_ok() {
return true;
}
false
}