Skip to content

Commit ea244b8

Browse files
MCordStephan Dilly
authored and
Stephan Dilly
committed
fixed issue with utracked files.
1 parent dd459ec commit ea244b8

File tree

2 files changed

+51
-16
lines changed

2 files changed

+51
-16
lines changed

Diff for: asyncgit/src/sync/commit_files.rs

+42-16
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use super::{utils::repo, CommitId};
2-
use crate::{error::Result, StatusItem, StatusItemType};
1+
use super::{stash::is_stash_commit, utils::repo, CommitId};
2+
use crate::{error::Result, StatusItem, StatusItemType, CWD};
33
use git2::{Diff, DiffDelta, DiffOptions, Repository};
44
use scopetime::scope_time;
55

@@ -33,6 +33,22 @@ pub fn get_commit_files(
3333
None,
3434
)?;
3535

36+
// stash commits have parent commits containing untracked files and if we want to show
37+
// these files as if they were actually in the stash commit we have to have some specific
38+
// handling regarding these special stash commits.
39+
// 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
40+
if is_stash_commit(repo_path, &id)? {
41+
let commit = repo.find_commit(id.into())?;
42+
let untracked_commit = commit.parent_id(2)?;
43+
44+
let mut untracked_files = get_commit_files(
45+
repo_path,
46+
CommitId::new(untracked_commit),
47+
)?;
48+
49+
res.append(&mut untracked_files);
50+
}
51+
3652
Ok(res)
3753
}
3854

@@ -52,7 +68,7 @@ pub(crate) fn get_commit_diff(
5268
None
5369
};
5470

55-
let mut opt = pathspec.map(|p| {
71+
let mut opt = pathspec.clone().map(|p| {
5672
let mut opts = DiffOptions::new();
5773
opts.pathspec(p);
5874
opts.show_binary(true);
@@ -65,6 +81,16 @@ pub(crate) fn get_commit_diff(
6581
opt.as_mut(),
6682
)?;
6783

84+
if diff.deltas().len() == 0 && is_stash_commit(CWD, &id)? {
85+
let untracked_commit = commit.parent_id(2)?;
86+
87+
return get_commit_diff(
88+
repo,
89+
CommitId::new(untracked_commit),
90+
(&pathspec).clone(),
91+
);
92+
}
93+
6894
Ok(diff)
6995
}
7096

@@ -81,31 +107,31 @@ mod tests {
81107
use std::{fs::File, io::Write, path::Path};
82108

83109
#[test]
84-
fn test_smoke() {
110+
fn test_smoke() -> Result<()> {
85111
let file_path = Path::new("file1.txt");
86-
let (_td, repo) = repo_init().unwrap();
112+
let (_td, repo) = repo_init()?;
87113
let root = repo.path().parent().unwrap();
88114
let repo_path = root.as_os_str().to_str().unwrap();
89115

90-
File::create(&root.join(file_path))
91-
.unwrap()
92-
.write_all(b"test file1 content")
93-
.unwrap();
116+
File::create(&root.join(file_path))?
117+
.write_all(b"test file1 content")?;
94118

95-
stage_add_file(repo_path, file_path).unwrap();
119+
stage_add_file(repo_path, file_path)?;
96120

97-
let id = commit(repo_path, "commit msg").unwrap();
121+
let id = commit(repo_path, "commit msg")?;
98122

99-
let diff = get_commit_files(repo_path, id).unwrap();
123+
let diff = get_commit_files(repo_path, id)?;
100124

101125
assert_eq!(diff.len(), 1);
102126
assert_eq!(diff[0].status, StatusItemType::New);
127+
128+
Ok(())
103129
}
104130

105131
#[test]
106132
fn test_stashed_untracked() -> Result<()> {
107133
let file_path = Path::new("file1.txt");
108-
let (_td, repo) = repo_init().unwrap();
134+
let (_td, repo) = repo_init()?;
109135
let root = repo.path().parent().unwrap();
110136
let repo_path = root.as_os_str().to_str().unwrap();
111137

@@ -117,10 +143,10 @@ mod tests {
117143
//TODO: https://github.com/extrawurst/gitui/issues/130
118144
// `get_commit_diff` actually needs to merge the regular diff
119145
// and a third parent diff containing the untracked files
120-
let _diff = get_commit_files(repo_path, id)?;
146+
let diff = get_commit_files(repo_path, id)?;
121147

122-
// assert_eq!(diff.len(), 1);
123-
// assert_eq!(diff[0].status, StatusItemType::New);
148+
assert_eq!(diff.len(), 1);
149+
assert_eq!(diff[0].status, StatusItemType::New);
124150

125151
Ok(())
126152
}

Diff for: asyncgit/src/sync/stash.rs

+9
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,15 @@ pub fn get_stashes(repo_path: &str) -> Result<Vec<CommitId>> {
1919
Ok(list)
2020
}
2121

22+
/// checks whether a given commit is a stash commit.
23+
pub fn is_stash_commit(
24+
repo_path: &str,
25+
id: &CommitId,
26+
) -> Result<bool> {
27+
let stashes = get_stashes(repo_path)?;
28+
Ok(stashes.contains(&id))
29+
}
30+
2231
///
2332
pub fn stash_drop(repo_path: &str, stash_id: CommitId) -> Result<()> {
2433
scope_time!("stash_drop");

0 commit comments

Comments
 (0)