summaryrefslogtreecommitdiffstats
path: root/src/modules/git_status.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules/git_status.rs')
-rw-r--r--src/modules/git_status.rs50
1 files changed, 34 insertions, 16 deletions
diff --git a/src/modules/git_status.rs b/src/modules/git_status.rs
index 7a5f20abf..db02083f5 100644
--- a/src/modules/git_status.rs
+++ b/src/modules/git_status.rs
@@ -27,11 +27,11 @@ const ALL_STATUS_FORMAT: &str = "$conflicted$stashed$deleted$renamed$modified$st
/// - `ยป` โ€” A renamed file has been added to the staging area
/// - `โœ˜` โ€” A file's deletion has been added to the staging area
pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
- let info = Arc::new(GitStatusInfo::load(context));
-
let mut module = context.new_module("git_status");
let config: GitStatusConfig = GitStatusConfig::try_load(module.config);
+ let info = Arc::new(GitStatusInfo::load(context, config.clone()));
+
//Return None if not in git repository
context.get_repo().ok()?;
@@ -116,14 +116,16 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
struct GitStatusInfo<'a> {
context: &'a Context<'a>,
+ config: GitStatusConfig<'a>,
repo_status: OnceCell<Option<RepoStatus>>,
stashed_count: OnceCell<Option<usize>>,
}
impl<'a> GitStatusInfo<'a> {
- pub fn load(context: &'a Context) -> Self {
+ pub fn load(context: &'a Context, config: GitStatusConfig<'a>) -> Self {
Self {
context,
+ config,
repo_status: OnceCell::new(),
stashed_count: OnceCell::new(),
}
@@ -135,7 +137,7 @@ impl<'a> GitStatusInfo<'a> {
pub fn get_repo_status(&self) -> &Option<RepoStatus> {
self.repo_status
- .get_or_init(|| match get_repo_status(self.context) {
+ .get_or_init(|| match get_repo_status(self.context, &self.config) {
Some(repo_status) => Some(repo_status),
None => {
log::debug!("get_repo_status: git status execution failed");
@@ -181,21 +183,37 @@ impl<'a> GitStatusInfo<'a> {
}
/// Gets the number of files in various git states (staged, modified, deleted, etc...)
-fn get_repo_status(context: &Context) -> Option<RepoStatus> {
+fn get_repo_status(context: &Context, config: &GitStatusConfig) -> Option<RepoStatus> {
log::debug!("New repo status created");
let mut repo_status = RepoStatus::default();
- let status_output = context.exec_cmd(
- "git",
- &[
- OsStr::new("-C"),
- context.current_dir.as_os_str(),
- OsStr::new("--no-optional-locks"),
- OsStr::new("status"),
- OsStr::new("--porcelain=2"),
- OsStr::new("--branch"),
- ],
- )?;
+ let mut args = vec![
+ OsStr::new("-C"),
+ context.current_dir.as_os_str(),
+ OsStr::new("--no-optional-locks"),
+ OsStr::new("status"),
+ OsStr::new("--porcelain=2"),
+ ];
+
+ // for performance reasons, only pass flags if necessary...
+ let has_ahead_behind = !config.ahead.is_empty() || !config.behind.is_empty();
+ let has_up_to_date_diverged = !config.up_to_date.is_empty() || !config.diverged.is_empty();
+ if has_ahead_behind || has_up_to_date_diverged {
+ args.push(OsStr::new("--branch"));
+ }
+
+ // ... and add flags that omit information the user doesn't want
+ let has_untracked = !config.untracked.is_empty();
+ if !has_untracked {
+ args.push(OsStr::new("--untracked-files=no"));
+ }
+ if config.ignore_submodules {
+ args.push(OsStr::new("--ignore-submodules=dirty"));
+ } else if !has_untracked {
+ args.push(OsStr::new("--ignore-submodules=untracked"));
+ }
+
+ let status_output = context.exec_cmd("git", &args)?;
let statuses = status_output.stdout.lines();
statuses.for_each(|status| {