Fix --git deducing ignored state in unintuitive way

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
This commit is contained in:
ariasuni 2021-04-09 21:30:35 +02:00
parent 2aaead1721
commit 8c10feec51

View File

@ -252,15 +252,21 @@ impl Git {
.unwrap_or_default() .unwrap_or_default()
} }
/// Get the combined status for all the files whose paths begin with the /// Get the combined, user-facing status of a file or directory.
/// path that gets passed in. This is used for getting the status of /// Statuses are aggregating (for example, a directory is considered
/// directories, which dont really have an official status. /// 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 { fn dir_status(&self, dir: &Path) -> f::Git {
let path = reorient(dir); let path = reorient(dir);
let s = self.statuses.iter() let s = self.statuses.iter()
.filter(|p| p.0.starts_with(&path)) .filter(|p| if p.1 == git2::Status::IGNORED {
.fold(git2::Status::empty(), |a, b| a | b.1); 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 staged = index_status(s);
let unstaged = working_tree_status(s); let unstaged = working_tree_status(s);