mirror of
https://github.com/gitui-org/gitui
synced 2026-05-23 17:08:21 +00:00
Fix 576 stash apply conflicts (#578)
* unittest that applying with conflicts errors out and prepare for stash apply to allow creating conflicts for later * mark conflicting items
This commit is contained in:
parent
cfd5c6ad03
commit
c79b3d74fa
5 changed files with 87 additions and 4 deletions
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ pub enum StatusItemType {
|
|||
Renamed,
|
||||
///
|
||||
Typechange,
|
||||
///
|
||||
Conflicted,
|
||||
}
|
||||
|
||||
impl From<Status> for StatusItemType {
|
||||
|
|
@ -30,6 +32,8 @@ impl From<Status> 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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -142,6 +142,7 @@ impl FileTreeComponent {
|
|||
StatusItemType::Deleted => '-',
|
||||
StatusItemType::Renamed => 'R',
|
||||
StatusItemType::Typechange => ' ',
|
||||
StatusItemType::Conflicted => '!',
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -135,6 +135,9 @@ impl Theme {
|
|||
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(),
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue