Skip to content

Commit 046af5c

Browse files
committed
Use git2 instead of parsing .gitignore for --git-ignore
Fix #636
1 parent 78ba0b8 commit 046af5c

File tree

8 files changed

+26
-236
lines changed

8 files changed

+26
-236
lines changed

src/exa.rs

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use ansi_term::{ANSIStrings, Style};
1111
use log::debug;
1212

1313
use crate::fs::{Dir, File};
14-
use crate::fs::feature::ignore::IgnoreCache;
1514
use crate::fs::feature::git::GitCache;
1615
use crate::options::{Options, Vars};
1716
pub use crate::options::vars;
@@ -44,10 +43,6 @@ pub struct Exa<'args, 'w, W: Write + 'w> {
4443
/// This has to last the lifetime of the program, because the user might
4544
/// want to list several directories in the same repository.
4645
pub git: Option<GitCache>,
47-
48-
/// A cache of git-ignored files.
49-
/// This lasts the lifetime of the program too, for the same reason.
50-
pub ignore: Option<IgnoreCache>,
5146
}
5247

5348
/// The “real” environment variables type.
@@ -71,15 +66,6 @@ fn git_options(options: &Options, args: &[&OsStr]) -> Option<GitCache> {
7166
}
7267
}
7368

74-
fn ignore_cache(options: &Options) -> Option<IgnoreCache> {
75-
use crate::fs::filter::GitIgnore;
76-
77-
match options.filter.git_ignore {
78-
GitIgnore::CheckAndIgnore => Some(IgnoreCache::new()),
79-
GitIgnore::Off => None,
80-
}
81-
}
82-
8369
impl<'args, 'w, W: Write + 'w> Exa<'args, 'w, W> {
8470
pub fn from_args<I>(args: I, writer: &'w mut W) -> Result<Exa<'args, 'w, W>, Misfire>
8571
where I: Iterator<Item=&'args OsString> {
@@ -95,8 +81,7 @@ impl<'args, 'w, W: Write + 'w> Exa<'args, 'w, W> {
9581
}
9682

9783
let git = git_options(&options, &args);
98-
let ignore = ignore_cache(&options);
99-
Exa { options, writer, args, git, ignore }
84+
Exa { options, writer, args, git }
10085
})
10186
}
10287

@@ -157,7 +142,7 @@ impl<'args, 'w, W: Write + 'w> Exa<'args, 'w, W> {
157142
}
158143

159144
let mut children = Vec::new();
160-
for file in dir.files(self.options.filter.dot_filter, self.ignore.as_ref()) {
145+
for file in dir.files(self.options.filter.dot_filter, self.git.as_ref()) {
161146
match file {
162147
Ok(file) => children.push(file),
163148
Err((path, e)) => writeln!(stderr(), "[{}: {}]", path.display(), e)?,
@@ -217,7 +202,7 @@ impl<'args, 'w, W: Write + 'w> Exa<'args, 'w, W> {
217202
let recurse = self.options.dir_action.recurse_options();
218203

219204
let r = details::Render { dir, files, colours, style, opts, filter, recurse };
220-
r.render(self.git.as_ref(), self.ignore.as_ref(), self.writer)
205+
r.render(self.git.as_ref(), self.writer)
221206
}
222207

223208
Mode::GridDetails(ref opts) => {

src/fs/dir.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use crate::fs::feature::git::GitCache;
2+
use crate::fs::fields::GitStatus;
13
use std::io::{self, Result as IOResult};
24
use std::fs;
35
use std::path::{Path, PathBuf};
@@ -6,7 +8,6 @@ use std::slice::Iter as SliceIter;
68
use log::info;
79

810
use crate::fs::File;
9-
use crate::fs::feature::ignore::IgnoreCache;
1011

1112

1213
/// A **Dir** provides a cached list of the file paths in a directory that's
@@ -46,15 +47,13 @@ impl Dir {
4647

4748
/// Produce an iterator of IO results of trying to read all the files in
4849
/// this directory.
49-
pub fn files<'dir, 'ig>(&'dir self, dots: DotFilter, ignore: Option<&'ig IgnoreCache>) -> Files<'dir, 'ig> {
50-
if let Some(i) = ignore { i.discover_underneath(&self.path); }
51-
50+
pub fn files<'dir, 'ig>(&'dir self, dots: DotFilter, git: Option<&'ig GitCache>) -> Files<'dir, 'ig> {
5251
Files {
5352
inner: self.contents.iter(),
5453
dir: self,
5554
dotfiles: dots.shows_dotfiles(),
5655
dots: dots.dots(),
57-
ignore,
56+
git,
5857
}
5958
}
6059

@@ -86,7 +85,7 @@ pub struct Files<'dir, 'ig> {
8685
/// any files have been listed.
8786
dots: DotsNext,
8887

89-
ignore: Option<&'ig IgnoreCache>,
88+
git: Option<&'ig GitCache>,
9089
}
9190

9291
impl<'dir, 'ig> Files<'dir, 'ig> {
@@ -107,8 +106,9 @@ impl<'dir, 'ig> Files<'dir, 'ig> {
107106
let filename = File::filename(path);
108107
if !self.dotfiles && filename.starts_with('.') { continue }
109108

110-
if let Some(i) = self.ignore {
111-
if i.is_ignored(path) { continue }
109+
let git_status = self.git.map(|g| g.get(path, false)).unwrap_or_default();
110+
if git_status.unstaged == GitStatus::Ignored {
111+
continue;
112112
}
113113

114114
return Some(File::from_args(path.clone(), self.dir, filename)

src/fs/feature/ignore.rs

Lines changed: 0 additions & 198 deletions
This file was deleted.

src/fs/feature/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
pub mod xattr;
2-
pub mod ignore;
32

43
#[cfg(feature="git")] pub mod git;
54

src/fs/fields.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ pub struct Time {
177177
/// A file’s status in a Git repository. Whether a file is in a repository or
178178
/// not is handled by the Git module, rather than having a “null” variant in
179179
/// this enum.
180+
#[derive(PartialEq)]
180181
pub enum GitStatus {
181182

182183
/// This file hasn’t changed since the last commit.

src/options/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272
use std::ffi::{OsStr, OsString};
7373

7474
use crate::fs::dir_action::DirAction;
75-
use crate::fs::filter::FileFilter;
75+
use crate::fs::filter::{FileFilter,GitIgnore};
7676
use crate::output::{View, Mode, details, grid_details};
7777

7878
mod style;
@@ -146,6 +146,10 @@ impl Options {
146146
/// status column. It’s only worth trying to discover a repository if the
147147
/// results will end up being displayed.
148148
pub fn should_scan_for_git(&self) -> bool {
149+
if self.filter.git_ignore == GitIgnore::CheckAndIgnore {
150+
return true;
151+
}
152+
149153
match self.view.mode {
150154
Mode::Details(details::Options { table: Some(ref table), .. }) |
151155
Mode::GridDetails(grid_details::Options { details: details::Options { table: Some(ref table), .. }, .. }) => table.columns.git,

0 commit comments

Comments
 (0)