From 02bd22d3b30002123e7d6b6c75011a757f2eee1a Mon Sep 17 00:00:00 2001 From: Stephan Dilly Date: Tue, 7 Jul 2020 09:10:10 +0200 Subject: [PATCH] fix crash diffing stash created on cmd line (closes #178) --- CHANGELOG.md | 1 + asyncgit/src/sync/commit_files.rs | 16 +++++++-------- asyncgit/src/sync/stash.rs | 34 ++++++++++++++++++++++++++++--- 3 files changed, 40 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 050d5c32..27afb35c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - switch deprecated transitive dependency `net2`->`socket2` [in `crossterm`->`mio`] ([#66](https://github.com/extrawurst/gitui/issues/66)) +- crash diffing stash created on command line ([#178](https://github.com/extrawurst/gitui/issues/178)) ## [0.8.0] - 2020-07-06 diff --git a/asyncgit/src/sync/commit_files.rs b/asyncgit/src/sync/commit_files.rs index e643ebd1..6d0e9aa6 100644 --- a/asyncgit/src/sync/commit_files.rs +++ b/asyncgit/src/sync/commit_files.rs @@ -69,15 +69,15 @@ pub(crate) fn get_commit_diff( repo.path().to_str().expect("repo path utf8 err"), &id, )? { - let untracked_commit = commit.parent_id(2)?; + if let Ok(untracked_commit) = commit.parent_id(2) { + let untracked_diff = get_commit_diff( + repo, + CommitId::new(untracked_commit), + pathspec, + )?; - let untracked_diff = get_commit_diff( - repo, - CommitId::new(untracked_commit), - pathspec, - )?; - - diff.merge(&untracked_diff)?; + diff.merge(&untracked_diff)?; + } } Ok(diff) diff --git a/asyncgit/src/sync/stash.rs b/asyncgit/src/sync/stash.rs index 01a5c7aa..fbd268f0 100644 --- a/asyncgit/src/sync/stash.rs +++ b/asyncgit/src/sync/stash.rs @@ -108,10 +108,10 @@ pub fn stash_save( mod tests { use super::*; use crate::sync::{ - get_commits_info, - tests::{get_statuses, repo_init}, + commit, get_commit_files, get_commits_info, stage_add_file, + tests::{debug_cmd_print, get_statuses, repo_init}, }; - use std::{fs::File, io::Write}; + use std::{fs::File, io::Write, path::Path}; #[test] fn test_smoke() { @@ -183,4 +183,32 @@ mod tests { Ok(()) } + + #[test] + fn test_stash_without_2nd_parent() -> Result<()> { + let file_path1 = Path::new("file1.txt"); + let (_td, repo) = repo_init()?; + let root = repo.path().parent().unwrap(); + let repo_path = root.as_os_str().to_str().unwrap(); + + File::create(&root.join(file_path1))?.write_all(b"test")?; + stage_add_file(repo_path, file_path1)?; + commit(repo_path, "c1")?; + + File::create(&root.join(file_path1))? + .write_all(b"modified")?; + + //NOTE: apparently `libgit2` works differently to git stash in + //always creating the third parent for untracked files while the + //cli skips that step when no new files exist + debug_cmd_print(repo_path, "git stash"); + + let stash = get_stashes(repo_path)?[0]; + + let diff = get_commit_files(repo_path, stash)?; + + assert_eq!(diff.len(), 1); + + Ok(()) + } }