Browse Source

Merge pull request #842 from ariasuni/dont-aggregate-git-ignored-status2

Fix deducing git ignored state for files too, not only directories
Benjamin Sago 4 years ago
parent
commit
051a46c643

+ 2 - 0
devtools/dev-create-test-filesystem.sh

@@ -300,6 +300,8 @@ touch "ignoreds/music.m4a"
 mkdir "ignoreds/nested"
 touch "ignoreds/nested/70s grove.mp3"
 touch "ignoreds/nested/funky chicken.m4a"
+mkdir "ignoreds/nested2"
+touch "ignoreds/nested2/ievan polkka.mp3"
 
 mkdir "target"
 touch "target/another ignored file"

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

+ 10 - 2
xtests/git.toml

@@ -101,13 +101,21 @@ status = 0
 tags = [ 'long', 'git' ]
 
 [[cmd]]
-name = "‘exa --git -l’ with an ignored directory argument does not flag the contents as ignored"
+name = "‘exa --git -l’ with an ignored directory argument flags the contents as ignored"
 shell = "exa --git -l /testcases/git2/target"
 stdout = { file = "outputs/git2_long_ignoreddir.ansitxt" }
 stderr = { empty = true }
 status = 0
 tags = [ 'long', 'git' ]
 
+[[cmd]]
+name = "‘exa --git -l --list-dirs’ with a directory argument doesn’t flag it as ignored if only the content is"
+shell = "exa --git -l --list-dirs /testcases/git2/ignoreds/nested2"
+stdout = { file = "outputs/git2_long_ignoredcontent.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ 'long', 'git' ]
+
 [[cmd]]
 name = "‘exa --git -l’ with a nested repository argument uses the sub-repository rules"
 shell = "exa --git -l /testcases/git2/deeply/nested/repository"
@@ -155,7 +163,7 @@ status = 0
 tags = [ 'long', 'git' ]
 
 [[cmd]]
-name = "‘exa --git -l’ shows a Git status column for multiple repositories across multiple directories"
+name = "‘exa --git -l’ shows a Git status column for multiple repositories across multiple directories 2"
 shell = "exa --git -l /testcases/{git2/deeply/nested/directory,git/edits,git2/target,git2/deeply,git}"
 stdout = { file = "outputs/git1+2_long_nested.ansitxt" }
 stderr = { empty = true }

+ 1 - 1
xtests/outputs/git1+2_long_nested.ansitxt

@@ -8,7 +8,7 @@
 .rw-rw-r-- 20 cassowary  1 Jan 12:34 -M unstaged
 
 /testcases/git2/target:
-.rw-rw-r-- 0 cassowary  1 Jan 12:34 -- another ignored file
+.rw-rw-r-- 0 cassowary  1 Jan 12:34 -I another ignored file
 
 /testcases/git2/deeply:
 drwxrwxr-x - cassowary  1 Jan 12:34 -N nested

+ 1 - 1
xtests/outputs/git2_ignoreds_grid_gitignore.ansitxt

@@ -1 +1 @@
-music.m4a  nested
+music.m4a  nested  nested2

+ 1 - 0
xtests/outputs/git2_ignoreds_lines_gitignore.ansitxt

@@ -1,2 +1,3 @@
 music.m4a
 nested
+nested2

+ 1 - 0
xtests/outputs/git2_ignoreds_long_gitignore.ansitxt

@@ -1,2 +1,3 @@
 .rw-rw-r-- 0 cassowary  1 Jan 12:34 music.m4a
 drwxrwxr-x - cassowary  1 Jan 12:34 nested
+drwxrwxr-x - cassowary  1 Jan 12:34 nested2

+ 1 - 1
xtests/outputs/git2_ignoreds_long_grid_gitignore.ansitxt

@@ -1 +1 @@
-.rw-rw-r-- 0 cassowary  1 Jan 12:34 music.m4a    drwxrwxr-x - cassowary  1 Jan 12:34 nested
+.rw-rw-r-- 0 cassowary  1 Jan 12:34 music.m4a    drwxrwxr-x - cassowary  1 Jan 12:34 nested    drwxrwxr-x - cassowary  1 Jan 12:34 nested2

+ 3 - 0
xtests/outputs/git2_ignoreds_long_recurse_gitignore.ansitxt

@@ -1,5 +1,8 @@
 .rw-rw-r-- 0 cassowary  1 Jan 12:34 music.m4a
 drwxrwxr-x - cassowary  1 Jan 12:34 nested
+drwxrwxr-x - cassowary  1 Jan 12:34 nested2
 
 /testcases/git2/ignoreds/nested:
 .rw-rw-r-- 0 cassowary  1 Jan 12:34 funky chicken.m4a
+
+/testcases/git2/ignoreds/nested2:

+ 3 - 2
xtests/outputs/git2_ignoreds_long_tree_gitignore.ansitxt

@@ -1,4 +1,5 @@
 drwxrwxr-x - cassowary  1 Jan 12:34 /testcases/git2/ignoreds
 .rw-rw-r-- 0 cassowary  1 Jan 12:34 ├── music.m4a
-drwxrwxr-x - cassowary  1 Jan 12:34 └── nested
-.rw-rw-r-- 0 cassowary  1 Jan 12:34    └── funky chicken.m4a
+drwxrwxr-x - cassowary  1 Jan 12:34 ├── nested
+.rw-rw-r-- 0 cassowary  1 Jan 12:34 │  └── funky chicken.m4a
+drwxrwxr-x - cassowary  1 Jan 12:34 └── nested2

+ 3 - 2
xtests/outputs/git2_ignoreds_tree_gitignore.ansitxt

@@ -1,4 +1,5 @@
 /testcases/git2/ignoreds
 ├── music.m4a
-└── nested
-   └── funky chicken.m4a
+├── nested
+│  └── funky chicken.m4a
+└── nested2

+ 1 - 0
xtests/outputs/git2_long_ignoredcontent.ansitxt

@@ -0,0 +1 @@
+drwxrwxr-x - cassowary  1 Jan 12:34 -- /testcases/git2/ignoreds/nested2

+ 1 - 1
xtests/outputs/git2_long_ignoreddir.ansitxt

@@ -1 +1 @@
-.rw-rw-r-- 0 cassowary  1 Jan 12:34 -- another ignored file
+.rw-rw-r-- 0 cassowary  1 Jan 12:34 -I another ignored file

+ 1 - 0
xtests/outputs/git2_long_ignorednested.ansitxt

@@ -1,3 +1,4 @@
 .rw-rw-r-- 0 cassowary  1 Jan 12:34 -N music.m4a
 .rw-rw-r-- 0 cassowary  1 Jan 12:34 -I music.mp3
 drwxrwxr-x - cassowary  1 Jan 12:34 -N nested
+drwxrwxr-x - cassowary  1 Jan 12:34 -- nested2

+ 2 - 1
xtests/outputs/git2_long_multiple.ansitxt

@@ -5,6 +5,7 @@
 .rw-rw-r-- 0 cassowary  1 Jan 12:34 -N music.m4a
 .rw-rw-r-- 0 cassowary  1 Jan 12:34 -I music.mp3
 drwxrwxr-x - cassowary  1 Jan 12:34 -N nested
+drwxrwxr-x - cassowary  1 Jan 12:34 -- nested2
 
 /testcases/git2/target:
-.rw-rw-r-- 0 cassowary  1 Jan 12:34 -- another ignored file
+.rw-rw-r-- 0 cassowary  1 Jan 12:34 -I another ignored file

+ 5 - 1
xtests/outputs/git2_long_recurse.ansitxt

@@ -20,10 +20,14 @@
 .rw-rw-r-- 0 cassowary  1 Jan 12:34 -N music.m4a
 .rw-rw-r-- 0 cassowary  1 Jan 12:34 -I music.mp3
 drwxrwxr-x - cassowary  1 Jan 12:34 -N nested
+drwxrwxr-x - cassowary  1 Jan 12:34 -- nested2
 
 /testcases/git2/ignoreds/nested:
 .rw-rw-r-- 0 cassowary  1 Jan 12:34 -I 70s grove.mp3
 .rw-rw-r-- 0 cassowary  1 Jan 12:34 -N funky chicken.m4a
 
+/testcases/git2/ignoreds/nested2:
+.rw-rw-r-- 0 cassowary  1 Jan 12:34 -I ievan polkka.mp3
+
 /testcases/git2/target:
-.rw-rw-r-- 0 cassowary  1 Jan 12:34 -- another ignored file
+.rw-rw-r-- 0 cassowary  1 Jan 12:34 -I another ignored file

+ 3 - 0
xtests/outputs/git2_long_recurse_gitignore.ansitxt

@@ -18,6 +18,9 @@
 /testcases/git2/ignoreds:
 .rw-rw-r-- 0 cassowary  1 Jan 12:34 music.m4a
 drwxrwxr-x - cassowary  1 Jan 12:34 nested
+drwxrwxr-x - cassowary  1 Jan 12:34 nested2
 
 /testcases/git2/ignoreds/nested:
 .rw-rw-r-- 0 cassowary  1 Jan 12:34 funky chicken.m4a
+
+/testcases/git2/ignoreds/nested2:

+ 6 - 4
xtests/outputs/git2_long_tree.ansitxt

@@ -9,8 +9,10 @@
 drwxrwxr-x  - cassowary  1 Jan 12:34 -N ├── ignoreds
 .rw-rw-r--  0 cassowary  1 Jan 12:34 -N │  ├── music.m4a
 .rw-rw-r--  0 cassowary  1 Jan 12:34 -I │  ├── music.mp3
-drwxrwxr-x  - cassowary  1 Jan 12:34 -N │  └── nested
-.rw-rw-r--  0 cassowary  1 Jan 12:34 -I │     ├── 70s grove.mp3
-.rw-rw-r--  0 cassowary  1 Jan 12:34 -N │     └── funky chicken.m4a
+drwxrwxr-x  - cassowary  1 Jan 12:34 -N │  ├── nested
+.rw-rw-r--  0 cassowary  1 Jan 12:34 -I │  │  ├── 70s grove.mp3
+.rw-rw-r--  0 cassowary  1 Jan 12:34 -N │  │  └── funky chicken.m4a
+drwxrwxr-x  - cassowary  1 Jan 12:34 -- │  └── nested2
+.rw-rw-r--  0 cassowary  1 Jan 12:34 -I │     └── ievan polkka.mp3
 drwxrwxr-x  - cassowary  1 Jan 12:34 -I └── target
-.rw-rw-r--  0 cassowary  1 Jan 12:34 --    └── another ignored file
+.rw-rw-r--  0 cassowary  1 Jan 12:34 -I    └── another ignored file

+ 3 - 2
xtests/outputs/git2_long_tree_gitignore.ansitxt

@@ -8,5 +8,6 @@
 .rw-rw-r--  0 cassowary  1 Jan 12:34 │        └── subfile
 drwxrwxr-x  - cassowary  1 Jan 12:34 └── ignoreds
 .rw-rw-r--  0 cassowary  1 Jan 12:34    ├── music.m4a
-drwxrwxr-x  - cassowary  1 Jan 12:34    └── nested
-.rw-rw-r--  0 cassowary  1 Jan 12:34       └── funky chicken.m4a
+drwxrwxr-x  - cassowary  1 Jan 12:34    ├── nested
+.rw-rw-r--  0 cassowary  1 Jan 12:34    │  └── funky chicken.m4a
+drwxrwxr-x  - cassowary  1 Jan 12:34    └── nested2

+ 3 - 2
xtests/outputs/git2_tree_gitignore.ansitxt

@@ -8,5 +8,6 @@
 │        └── subfile
 └── ignoreds
    ├── music.m4a
-   └── nested
-      └── funky chicken.m4a
+   ├── nested
+   │  └── funky chicken.m4a
+   └── nested2