From 16d150e601e172518e29f984eff8253fba5d5094 Mon Sep 17 00:00:00 2001 From: Stephan Dilly Date: Tue, 9 Mar 2021 13:47:06 +0100 Subject: [PATCH 1/4] unittest that applying with conflicts errors out and prepare for stash apply to allow creating conflicts for later --- asyncgit/src/sync/stash.rs | 81 ++++++++++++++++++++++++++++++++++++-- src/tabs/stashlist.rs | 2 +- 2 files changed, 79 insertions(+), 4 deletions(-) diff --git a/asyncgit/src/sync/stash.rs b/asyncgit/src/sync/stash.rs index fbd268f0cc..f4c6dd3aa0 100644 --- a/asyncgit/src/sync/stash.rs +++ b/asyncgit/src/sync/stash.rs @@ -1,6 +1,9 @@ use super::{utils::repo, CommitId}; use crate::error::{Error, Result}; -use git2::{Oid, Repository, StashFlags}; +use git2::{ + build::CheckoutBuilder, Oid, Repository, StashApplyOptions, + StashFlags, +}; use scopetime::scope_time; /// @@ -45,6 +48,7 @@ pub fn stash_drop(repo_path: &str, stash_id: CommitId) -> Result<()> { pub fn stash_apply( repo_path: &str, stash_id: CommitId, + allow_conflicts: bool, ) -> Result<()> { scope_time!("stash_apply"); @@ -52,7 +56,12 @@ pub fn stash_apply( let index = get_stash_index(&mut repo, stash_id.get_oid())?; - repo.stash_apply(index, None)?; + let mut checkout = CheckoutBuilder::new(); + checkout.allow_conflicts(allow_conflicts); + + let mut opt = StashApplyOptions::default(); + opt.checkout_options(checkout); + repo.stash_apply(index, Some(&mut opt))?; Ok(()) } @@ -109,7 +118,11 @@ mod tests { use super::*; use crate::sync::{ commit, get_commit_files, get_commits_info, stage_add_file, - tests::{debug_cmd_print, get_statuses, repo_init}, + staging::repo_write_file, + tests::{ + debug_cmd_print, get_statuses, repo_init, + write_commit_file, + }, }; use std::{fs::File, io::Write, path::Path}; @@ -211,4 +224,66 @@ mod tests { Ok(()) } + + #[test] + fn test_stash_apply_conflict() { + let (_td, repo) = repo_init().unwrap(); + let root = repo.path().parent().unwrap(); + let repo_path = root.as_os_str().to_str().unwrap(); + + repo_write_file(&repo, "test.txt", "test").unwrap(); + + let id = + stash_save(repo_path, Some("foo"), true, false).unwrap(); + + repo_write_file(&repo, "test.txt", "foo").unwrap(); + + let res = stash_apply(repo_path, id, false); + + assert!(res.is_err()); + } + + #[test] + fn test_stash_apply_conflict2() { + let (_td, repo) = repo_init().unwrap(); + let root = repo.path().parent().unwrap(); + let repo_path = root.as_os_str().to_str().unwrap(); + + write_commit_file(&repo, "test.txt", "test", "c1"); + + repo_write_file(&repo, "test.txt", "test2").unwrap(); + + let id = + stash_save(repo_path, Some("foo"), true, false).unwrap(); + + repo_write_file(&repo, "test.txt", "test3").unwrap(); + + let res = stash_apply(repo_path, id, false); + + assert!(res.is_err()); + } + + #[test] + fn test_stash_apply_creating_conflict() { + let (_td, repo) = repo_init().unwrap(); + let root = repo.path().parent().unwrap(); + let repo_path = root.as_os_str().to_str().unwrap(); + + write_commit_file(&repo, "test.txt", "test", "c1"); + + repo_write_file(&repo, "test.txt", "test2").unwrap(); + + let id = + stash_save(repo_path, Some("foo"), true, false).unwrap(); + + repo_write_file(&repo, "test.txt", "test3").unwrap(); + + let res = stash_apply(repo_path, id, false); + + assert!(res.is_err()); + + let res = stash_apply(repo_path, id, true); + + assert!(res.is_ok()); + } } diff --git a/src/tabs/stashlist.rs b/src/tabs/stashlist.rs index 98f6c0139a..5d7e12967e 100644 --- a/src/tabs/stashlist.rs +++ b/src/tabs/stashlist.rs @@ -57,7 +57,7 @@ impl StashList { fn apply_stash(&mut self) { if let Some(e) = self.list.selected_entry() { - match sync::stash_apply(CWD, e.id) { + match sync::stash_apply(CWD, e.id, false) { Ok(_) => { self.queue .borrow_mut() From 3471ec2d22107b9d0f5789fa714fe14fe87f3b52 Mon Sep 17 00:00:00 2001 From: Stephan Dilly Date: Tue, 9 Mar 2021 13:56:11 +0100 Subject: [PATCH 2/4] mark conflicting items with a 'C' --- asyncgit/src/sync/status.rs | 4 ++++ src/components/filetree.rs | 1 + src/ui/style.rs | 2 +- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/asyncgit/src/sync/status.rs b/asyncgit/src/sync/status.rs index 0e7343e403..891079d6e0 100644 --- a/asyncgit/src/sync/status.rs +++ b/asyncgit/src/sync/status.rs @@ -18,6 +18,8 @@ pub enum StatusItemType { Renamed, /// Typechange, + /// + Conflicted, } impl From for StatusItemType { @@ -30,6 +32,8 @@ impl From for StatusItemType { Self::Renamed } else if s.is_index_typechange() || s.is_wt_typechange() { Self::Typechange + } else if s.is_conflicted() { + Self::Conflicted } else { Self::Modified } diff --git a/src/components/filetree.rs b/src/components/filetree.rs index fb2f423d89..7d06f3013a 100644 --- a/src/components/filetree.rs +++ b/src/components/filetree.rs @@ -142,6 +142,7 @@ impl FileTreeComponent { StatusItemType::Deleted => '-', StatusItemType::Renamed => 'R', StatusItemType::Typechange => ' ', + StatusItemType::Conflicted => 'C', } } diff --git a/src/ui/style.rs b/src/ui/style.rs index 52ec05d6bf..25fb96faf6 100644 --- a/src/ui/style.rs +++ b/src/ui/style.rs @@ -132,7 +132,7 @@ impl Theme { StatusItemType::Deleted => { Style::default().fg(self.diff_file_removed) } - StatusItemType::Renamed => { + StatusItemType::Renamed | StatusItemType::Conflicted => { Style::default().fg(self.diff_file_moved) } StatusItemType::Typechange => Style::default(), From 2c8b311797e7b2f1c5336c4261707fa948cbdedb Mon Sep 17 00:00:00 2001 From: Stephan Dilly Date: Tue, 9 Mar 2021 13:58:02 +0100 Subject: [PATCH 3/4] conflict state gets !-sign --- src/components/filetree.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/filetree.rs b/src/components/filetree.rs index 7d06f3013a..e1bd3f23be 100644 --- a/src/components/filetree.rs +++ b/src/components/filetree.rs @@ -142,7 +142,7 @@ impl FileTreeComponent { StatusItemType::Deleted => '-', StatusItemType::Renamed => 'R', StatusItemType::Typechange => ' ', - StatusItemType::Conflicted => 'C', + StatusItemType::Conflicted => '!', } } From a0717ea8e59f7caa6662135bd527583f24824a00 Mon Sep 17 00:00:00 2001 From: Stephan Dilly Date: Tue, 9 Mar 2021 14:08:33 +0100 Subject: [PATCH 4/4] bold style --- src/ui/style.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ui/style.rs b/src/ui/style.rs index 25fb96faf6..2a2aa34556 100644 --- a/src/ui/style.rs +++ b/src/ui/style.rs @@ -132,9 +132,12 @@ impl Theme { StatusItemType::Deleted => { Style::default().fg(self.diff_file_removed) } - StatusItemType::Renamed | StatusItemType::Conflicted => { + StatusItemType::Renamed => { Style::default().fg(self.diff_file_moved) } + StatusItemType::Conflicted => Style::default() + .fg(self.diff_file_modified) + .add_modifier(Modifier::BOLD), StatusItemType::Typechange => Style::default(), };