mirror of
https://github.com/gitui-org/gitui
synced 2026-05-24 01:18:21 +00:00
fixed issue with utracked files.
This commit is contained in:
parent
dd459ecb8a
commit
ea244b8cfa
2 changed files with 51 additions and 16 deletions
|
|
@ -1,5 +1,5 @@
|
||||||
use super::{utils::repo, CommitId};
|
use super::{stash::is_stash_commit, utils::repo, CommitId};
|
||||||
use crate::{error::Result, StatusItem, StatusItemType};
|
use crate::{error::Result, StatusItem, StatusItemType, CWD};
|
||||||
use git2::{Diff, DiffDelta, DiffOptions, Repository};
|
use git2::{Diff, DiffDelta, DiffOptions, Repository};
|
||||||
use scopetime::scope_time;
|
use scopetime::scope_time;
|
||||||
|
|
||||||
|
|
@ -33,6 +33,22 @@ pub fn get_commit_files(
|
||||||
None,
|
None,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
// stash commits have parent commits containing untracked files and if we want to show
|
||||||
|
// these files as if they were actually in the stash commit we have to have some specific
|
||||||
|
// handling regarding these special stash commits.
|
||||||
|
// more info can be found at https://stackoverflow.com/questions/51275777/why-does-git-stash-pop-say-that-it-could-not-restore-untracked-files-from-stash/51276389#51276389
|
||||||
|
if is_stash_commit(repo_path, &id)? {
|
||||||
|
let commit = repo.find_commit(id.into())?;
|
||||||
|
let untracked_commit = commit.parent_id(2)?;
|
||||||
|
|
||||||
|
let mut untracked_files = get_commit_files(
|
||||||
|
repo_path,
|
||||||
|
CommitId::new(untracked_commit),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
res.append(&mut untracked_files);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -52,7 +68,7 @@ pub(crate) fn get_commit_diff(
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut opt = pathspec.map(|p| {
|
let mut opt = pathspec.clone().map(|p| {
|
||||||
let mut opts = DiffOptions::new();
|
let mut opts = DiffOptions::new();
|
||||||
opts.pathspec(p);
|
opts.pathspec(p);
|
||||||
opts.show_binary(true);
|
opts.show_binary(true);
|
||||||
|
|
@ -65,6 +81,16 @@ pub(crate) fn get_commit_diff(
|
||||||
opt.as_mut(),
|
opt.as_mut(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
if diff.deltas().len() == 0 && is_stash_commit(CWD, &id)? {
|
||||||
|
let untracked_commit = commit.parent_id(2)?;
|
||||||
|
|
||||||
|
return get_commit_diff(
|
||||||
|
repo,
|
||||||
|
CommitId::new(untracked_commit),
|
||||||
|
(&pathspec).clone(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(diff)
|
Ok(diff)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -81,31 +107,31 @@ mod tests {
|
||||||
use std::{fs::File, io::Write, path::Path};
|
use std::{fs::File, io::Write, path::Path};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_smoke() {
|
fn test_smoke() -> Result<()> {
|
||||||
let file_path = Path::new("file1.txt");
|
let file_path = Path::new("file1.txt");
|
||||||
let (_td, repo) = repo_init().unwrap();
|
let (_td, repo) = repo_init()?;
|
||||||
let root = repo.path().parent().unwrap();
|
let root = repo.path().parent().unwrap();
|
||||||
let repo_path = root.as_os_str().to_str().unwrap();
|
let repo_path = root.as_os_str().to_str().unwrap();
|
||||||
|
|
||||||
File::create(&root.join(file_path))
|
File::create(&root.join(file_path))?
|
||||||
.unwrap()
|
.write_all(b"test file1 content")?;
|
||||||
.write_all(b"test file1 content")
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
stage_add_file(repo_path, file_path).unwrap();
|
stage_add_file(repo_path, file_path)?;
|
||||||
|
|
||||||
let id = commit(repo_path, "commit msg").unwrap();
|
let id = commit(repo_path, "commit msg")?;
|
||||||
|
|
||||||
let diff = get_commit_files(repo_path, id).unwrap();
|
let diff = get_commit_files(repo_path, id)?;
|
||||||
|
|
||||||
assert_eq!(diff.len(), 1);
|
assert_eq!(diff.len(), 1);
|
||||||
assert_eq!(diff[0].status, StatusItemType::New);
|
assert_eq!(diff[0].status, StatusItemType::New);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_stashed_untracked() -> Result<()> {
|
fn test_stashed_untracked() -> Result<()> {
|
||||||
let file_path = Path::new("file1.txt");
|
let file_path = Path::new("file1.txt");
|
||||||
let (_td, repo) = repo_init().unwrap();
|
let (_td, repo) = repo_init()?;
|
||||||
let root = repo.path().parent().unwrap();
|
let root = repo.path().parent().unwrap();
|
||||||
let repo_path = root.as_os_str().to_str().unwrap();
|
let repo_path = root.as_os_str().to_str().unwrap();
|
||||||
|
|
||||||
|
|
@ -117,10 +143,10 @@ mod tests {
|
||||||
//TODO: https://github.com/extrawurst/gitui/issues/130
|
//TODO: https://github.com/extrawurst/gitui/issues/130
|
||||||
// `get_commit_diff` actually needs to merge the regular diff
|
// `get_commit_diff` actually needs to merge the regular diff
|
||||||
// and a third parent diff containing the untracked files
|
// and a third parent diff containing the untracked files
|
||||||
let _diff = get_commit_files(repo_path, id)?;
|
let diff = get_commit_files(repo_path, id)?;
|
||||||
|
|
||||||
// assert_eq!(diff.len(), 1);
|
assert_eq!(diff.len(), 1);
|
||||||
// assert_eq!(diff[0].status, StatusItemType::New);
|
assert_eq!(diff[0].status, StatusItemType::New);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,15 @@ pub fn get_stashes(repo_path: &str) -> Result<Vec<CommitId>> {
|
||||||
Ok(list)
|
Ok(list)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// checks whether a given commit is a stash commit.
|
||||||
|
pub fn is_stash_commit(
|
||||||
|
repo_path: &str,
|
||||||
|
id: &CommitId,
|
||||||
|
) -> Result<bool> {
|
||||||
|
let stashes = get_stashes(repo_path)?;
|
||||||
|
Ok(stashes.contains(&id))
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
pub fn stash_drop(repo_path: &str, stash_id: CommitId) -> Result<()> {
|
pub fn stash_drop(repo_path: &str, stash_id: CommitId) -> Result<()> {
|
||||||
scope_time!("stash_drop");
|
scope_time!("stash_drop");
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue