From 8c10feec515bf88556bf4dad60711e04ee2d96b0 Mon Sep 17 00:00:00 2001 From: ariasuni Date: Fri, 9 Apr 2021 21:30:35 +0200 Subject: [PATCH] Fix --git deducing ignored state in unintuitive way MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It makes sense to consider that a directory has the aggregated status of all the files under it. The exception is that for the ignored status, it’s more useful and intuitive to consider that it applies to everything under it. - A directory containing an ignored file is no longer considered ignored - A file inside an ignored directory is now considered ignored --- src/fs/feature/git.rs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/fs/feature/git.rs b/src/fs/feature/git.rs index 61689f2..7372a97 100644 --- a/src/fs/feature/git.rs +++ b/src/fs/feature/git.rs @@ -252,15 +252,21 @@ impl Git { .unwrap_or_default() } - /// Get the combined status for all the files whose paths begin with the - /// path that gets passed in. This is used for getting the status of - /// directories, which don’t really have an ‘official’ status. + /// Get the combined, user-facing status of a file or directory. + /// Statuses are aggregating (for example, a directory is considered + /// modified if any file under it has the status modified), except + /// for ignored which applies to files under (for example, a file is + /// considered ignored if one of its parent directories is ignored) fn dir_status(&self, dir: &Path) -> f::Git { let path = reorient(dir); let s = self.statuses.iter() - .filter(|p| p.0.starts_with(&path)) - .fold(git2::Status::empty(), |a, b| a | b.1); + .filter(|p| if p.1 == git2::Status::IGNORED { + path.starts_with(&p.0) + } else { + p.0.starts_with(&path) + }) + .fold(git2::Status::empty(), |a, b| a | b.1); let staged = index_status(s); let unstaged = working_tree_status(s);