diff --git a/CHANGELOG.md b/CHANGELOG.md index 4eb6e81b66..997eb8cf83 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed * opening tags list without remotes ([#1111](https://github.com/extrawurst/gitui/1111)) * tabs indentation in blame [[@fersilva16](https://github.com/fersilva16)] ([#1111](https://github.com/extrawurst/gitui/issues/1117)) +* switch focus to index after staging last file ([#1169](https://github.com/extrawurst/gitui/1169)) ## [0.20.1] - 2021-01-26 diff --git a/asyncgit/src/sync/mod.rs b/asyncgit/src/sync/mod.rs index 80415e2a3a..3a331b74a3 100644 --- a/asyncgit/src/sync/mod.rs +++ b/asyncgit/src/sync/mod.rs @@ -79,6 +79,7 @@ pub use stash::{ get_stashes, stash_apply, stash_drop, stash_pop, stash_save, }; pub use state::{repo_state, RepoState}; +pub use status::is_workdir_clean; pub use tags::{ delete_tag, get_tags, get_tags_with_metadata, CommitTags, Tag, TagWithMetadata, Tags, diff --git a/asyncgit/src/sync/status.rs b/asyncgit/src/sync/status.rs index 4ec99e1705..345a64b2d1 100644 --- a/asyncgit/src/sync/status.rs +++ b/asyncgit/src/sync/status.rs @@ -94,6 +94,38 @@ impl From for StatusShow { } } +/// +pub fn is_workdir_clean( + repo_path: &RepoPath, + show_untracked: Option, +) -> Result { + let repo = repo(repo_path)?; + + if repo.is_bare() && !repo.is_worktree() { + return Ok(true); + } + + let show_untracked = if let Some(config) = show_untracked { + config + } else { + untracked_files_config_repo(&repo)? + }; + + let mut options = StatusOptions::default(); + options + .show(StatusShow::Workdir) + .update_index(true) + .include_untracked(show_untracked.include_untracked()) + .renames_head_to_index(true) + .recurse_untracked_dirs( + show_untracked.recurse_untracked_dirs(), + ); + + let statuses = repo.statuses(Some(&mut options))?; + + Ok(statuses.is_empty()) +} + /// gurantees sorting pub fn get_status( repo_path: &RepoPath, diff --git a/src/components/changes.rs b/src/components/changes.rs index 7483512bdc..5c7e5d79df 100644 --- a/src/components/changes.rs +++ b/src/components/changes.rs @@ -104,30 +104,34 @@ impl ChangesComponent { path, )?, }; - - if self.is_empty() { - self.queue - .push(InternalEvent::StatusLastFileMoved); - } - - return Ok(true); + } else { + let config = + self.options.borrow().status_show_untracked; + + //TODO: check if we can handle the one file case with it aswell + sync::stage_add_all( + &self.repo.borrow(), + tree_item.info.full_path.as_str(), + config, + )?; } - let config = - self.options.borrow().status_show_untracked; - - //TODO: check if we can handle the one file case with it aswell - sync::stage_add_all( + //TODO: this might be slow in big repos, + // in theory we should be able to ask the tree structure + // if we are currently on a leaf or a lonely branch that + // would mean that after staging the workdir becomes empty + if sync::is_workdir_clean( &self.repo.borrow(), - tree_item.info.full_path.as_str(), - config, - )?; - - return Ok(true); + self.options.borrow().status_show_untracked, + )? { + self.queue + .push(InternalEvent::StatusLastFileMoved); + } + } else { + let path = tree_item.info.full_path.as_str(); + sync::reset_stage(&self.repo.borrow(), path)?; } - let path = tree_item.info.full_path.as_str(); - sync::reset_stage(&self.repo.borrow(), path)?; return Ok(true); }