Browse Source

Fix deducing git ignored state for files too, not only directories

ariasuni 4 years ago
parent
commit
bd4f144884
1 changed files with 18 additions and 9 deletions
  1. 18 9
      src/fs/feature/git.rs

+ 18 - 9
src/fs/feature/git.rs

@@ -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);