|
|
@@ -242,21 +242,30 @@ impl Git {
|
|
|
else { self.file_status(index) }
|
|
|
}
|
|
|
|
|
|
- /// Get the status for the file at the given path.
|
|
|
+ /// Get the user-facing status of a file.
|
|
|
+ /// We check the statuses directly applying to a file, and for the ignored
|
|
|
+ /// status we check if any of its parents directories is ignored by git.
|
|
|
fn file_status(&self, file: &Path) -> f::Git {
|
|
|
let path = reorient(file);
|
|
|
|
|
|
- self.statuses.iter()
|
|
|
- .find(|p| p.0.as_path() == path)
|
|
|
- .map(|&(_, s)| f::Git { staged: index_status(s), unstaged: working_tree_status(s) })
|
|
|
- .unwrap_or_default()
|
|
|
+ let s = self.statuses.iter()
|
|
|
+ .filter(|p| if p.1 == git2::Status::IGNORED {
|
|
|
+ path.starts_with(&p.0)
|
|
|
+ } else {
|
|
|
+ p.0 == path
|
|
|
+ })
|
|
|
+ .fold(git2::Status::empty(), |a, b| a | b.1);
|
|
|
+
|
|
|
+ let staged = index_status(s);
|
|
|
+ let unstaged = working_tree_status(s);
|
|
|
+ f::Git { staged, unstaged }
|
|
|
}
|
|
|
|
|
|
- /// Get the combined, user-facing status of a file or directory.
|
|
|
+ /// Get the combined, user-facing status of a 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)
|
|
|
+ /// modified if any file under it has the status modified), except for
|
|
|
+ /// ignored status which applies to files under (for example, a directory
|
|
|
+ /// is considered ignored if one of its parent directories is ignored).
|
|
|
fn dir_status(&self, dir: &Path) -> f::Git {
|
|
|
let path = reorient(dir);
|
|
|
|