Fix bug where files were Git-ignored too often

This was an unintended consequence of #653. The Files iterator stopped using IgnoreCache and started using GitCache, which would always populated when the `--git` option was passed, without checking whether files were meant to be ignored. This meant that passing `--git` started ignoring files even without `--git-ignore`.

The solution for now is to explicitly pass the flag around, which probably should be a better type than bool but isn't. This makes the git-ignoring-related extended tests pass.
This commit is contained in:
Benjamin Sago 2020-10-10 00:09:44 +01:00
parent 7f9773b68e
commit e44858eb41
4 changed files with 25 additions and 9 deletions

View File

@ -11,6 +11,7 @@ use ansi_term::{ANSIStrings, Style};
use log::debug;
use crate::fs::{Dir, File};
use crate::fs::filter::GitIgnore;
use crate::fs::feature::git::GitCache;
use crate::options::{Options, Vars};
pub use crate::options::vars;
@ -142,7 +143,8 @@ impl<'args, 'w, W: Write + 'w> Exa<'args, 'w, W> {
}
let mut children = Vec::new();
for file in dir.files(self.options.filter.dot_filter, self.git.as_ref()) {
let git_ignore = self.options.filter.git_ignore == GitIgnore::CheckAndIgnore;
for file in dir.files(self.options.filter.dot_filter, self.git.as_ref(), git_ignore) {
match file {
Ok(file) => children.push(file),
Err((path, e)) => writeln!(stderr(), "[{}: {}]", path.display(), e)?,
@ -201,7 +203,8 @@ impl<'args, 'w, W: Write + 'w> Exa<'args, 'w, W> {
let filter = &self.options.filter;
let recurse = self.options.dir_action.recurse_options();
let r = details::Render { dir, files, colours, style, opts, filter, recurse };
let git_ignoring = self.options.filter.git_ignore == GitIgnore::CheckAndIgnore;
let r = details::Render { dir, files, colours, style, opts, filter, recurse, git_ignoring };
r.render(self.git.as_ref(), self.writer)
}
@ -211,7 +214,8 @@ impl<'args, 'w, W: Write + 'w> Exa<'args, 'w, W> {
let details = &opts.details;
let row_threshold = opts.row_threshold;
let r = grid_details::Render { dir, files, colours, style, grid, details, filter, row_threshold };
let git_ignoring = self.options.filter.git_ignore == GitIgnore::CheckAndIgnore;
let r = grid_details::Render { dir, files, colours, style, grid, details, filter, row_threshold, git_ignoring };
r.render(self.git.as_ref(), self.writer)
}
}

View File

@ -47,13 +47,13 @@ impl Dir {
/// Produce an iterator of IO results of trying to read all the files in
/// this directory.
pub fn files<'dir, 'ig>(&'dir self, dots: DotFilter, git: Option<&'ig GitCache>) -> Files<'dir, 'ig> {
pub fn files<'dir, 'ig>(&'dir self, dots: DotFilter, git: Option<&'ig GitCache>, git_ignoring: bool) -> Files<'dir, 'ig> {
Files {
inner: self.contents.iter(),
dir: self,
dotfiles: dots.shows_dotfiles(),
dots: dots.dots(),
git,
git, git_ignoring,
}
}
@ -86,6 +86,8 @@ pub struct Files<'dir, 'ig> {
dots: DotsNext,
git: Option<&'ig GitCache>,
git_ignoring: bool,
}
impl<'dir, 'ig> Files<'dir, 'ig> {
@ -106,9 +108,11 @@ impl<'dir, 'ig> Files<'dir, 'ig> {
let filename = File::filename(path);
if !self.dotfiles && filename.starts_with('.') { continue }
let git_status = self.git.map(|g| g.get(path, false)).unwrap_or_default();
if git_status.unstaged == GitStatus::Ignored {
continue;
if self.git_ignoring {
let git_status = self.git.map(|g| g.get(path, false)).unwrap_or_default();
if git_status.unstaged == GitStatus::Ignored {
continue;
}
}
return Some(File::from_args(path.clone(), self.dir, filename)

View File

@ -128,6 +128,9 @@ pub struct Render<'a> {
/// How to sort and filter the files after getting their details.
pub filter: &'a FileFilter,
/// Whether we are skipping Git-ignored files.
pub git_ignoring: bool,
}
@ -303,7 +306,7 @@ impl<'a> Render<'a> {
rows.push(row);
if let Some(ref dir) = egg.dir {
for file_to_add in dir.files(self.filter.dot_filter, git) {
for file_to_add in dir.files(self.filter.dot_filter, git, self.git_ignoring) {
match file_to_add {
Ok(f) => files.push(f),
Err((path, e)) => errors.push((e, Some(path)))

View File

@ -76,6 +76,9 @@ pub struct Render<'a> {
/// The minimum number of rows that there need to be before grid-details
/// mode is activated.
pub row_threshold: RowThreshold,
/// Whether we are skipping Git-ignored files.
pub git_ignoring: bool,
}
impl<'a> Render<'a> {
@ -95,6 +98,7 @@ impl<'a> Render<'a> {
opts: self.details,
recurse: None,
filter: self.filter,
git_ignoring: self.git_ignoring,
}
}
@ -109,6 +113,7 @@ impl<'a> Render<'a> {
opts: self.details,
recurse: None,
filter: &self.filter,
git_ignoring: self.git_ignoring,
}
}