Skip to content

Commit

Permalink
Merge pull request #653 from ariasuni/fix-gitignore-option
Browse files Browse the repository at this point in the history
Use git2 instead of parsing .gitignore for --git-ignore
  • Loading branch information
ogham authored Oct 8, 2020
2 parents 4b45963 + 046af5c commit 1fe06a7
Show file tree
Hide file tree
Showing 8 changed files with 26 additions and 236 deletions.
21 changes: 3 additions & 18 deletions src/exa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use ansi_term::{ANSIStrings, Style};
use log::debug;

use crate::fs::{Dir, File};
use crate::fs::feature::ignore::IgnoreCache;
use crate::fs::feature::git::GitCache;
use crate::options::{Options, Vars};
pub use crate::options::vars;
Expand Down Expand Up @@ -44,10 +43,6 @@ pub struct Exa<'args, 'w, W: Write + 'w> {
/// This has to last the lifetime of the program, because the user might
/// want to list several directories in the same repository.
pub git: Option<GitCache>,

/// A cache of git-ignored files.
/// This lasts the lifetime of the program too, for the same reason.
pub ignore: Option<IgnoreCache>,
}

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

fn ignore_cache(options: &Options) -> Option<IgnoreCache> {
use crate::fs::filter::GitIgnore;

match options.filter.git_ignore {
GitIgnore::CheckAndIgnore => Some(IgnoreCache::new()),
GitIgnore::Off => None,
}
}

impl<'args, 'w, W: Write + 'w> Exa<'args, 'w, W> {
pub fn from_args<I>(args: I, writer: &'w mut W) -> Result<Exa<'args, 'w, W>, Misfire>
where I: Iterator<Item=&'args OsString> {
Expand All @@ -95,8 +81,7 @@ impl<'args, 'w, W: Write + 'w> Exa<'args, 'w, W> {
}

let git = git_options(&options, &args);
let ignore = ignore_cache(&options);
Exa { options, writer, args, git, ignore }
Exa { options, writer, args, git }
})
}

Expand Down Expand Up @@ -157,7 +142,7 @@ 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.ignore.as_ref()) {
for file in dir.files(self.options.filter.dot_filter, self.git.as_ref()) {
match file {
Ok(file) => children.push(file),
Err((path, e)) => writeln!(stderr(), "[{}: {}]", path.display(), e)?,
Expand Down Expand Up @@ -217,7 +202,7 @@ impl<'args, 'w, W: Write + 'w> Exa<'args, 'w, W> {
let recurse = self.options.dir_action.recurse_options();

let r = details::Render { dir, files, colours, style, opts, filter, recurse };
r.render(self.git.as_ref(), self.ignore.as_ref(), self.writer)
r.render(self.git.as_ref(), self.writer)
}

Mode::GridDetails(ref opts) => {
Expand Down
16 changes: 8 additions & 8 deletions src/fs/dir.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use crate::fs::feature::git::GitCache;
use crate::fs::fields::GitStatus;
use std::io::{self, Result as IOResult};
use std::fs;
use std::path::{Path, PathBuf};
Expand All @@ -6,7 +8,6 @@ use std::slice::Iter as SliceIter;
use log::info;

use crate::fs::File;
use crate::fs::feature::ignore::IgnoreCache;


/// A **Dir** provides a cached list of the file paths in a directory that's
Expand Down Expand Up @@ -46,15 +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, ignore: Option<&'ig IgnoreCache>) -> Files<'dir, 'ig> {
if let Some(i) = ignore { i.discover_underneath(&self.path); }

pub fn files<'dir, 'ig>(&'dir self, dots: DotFilter, git: Option<&'ig GitCache>) -> Files<'dir, 'ig> {
Files {
inner: self.contents.iter(),
dir: self,
dotfiles: dots.shows_dotfiles(),
dots: dots.dots(),
ignore,
git,
}
}

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

ignore: Option<&'ig IgnoreCache>,
git: Option<&'ig GitCache>,
}

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

if let Some(i) = self.ignore {
if i.is_ignored(path) { continue }
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)
Expand Down
198 changes: 0 additions & 198 deletions src/fs/feature/ignore.rs

This file was deleted.

1 change: 0 additions & 1 deletion src/fs/feature/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
pub mod xattr;
pub mod ignore;

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

Expand Down
1 change: 1 addition & 0 deletions src/fs/fields.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ pub struct Time {
/// A file’s status in a Git repository. Whether a file is in a repository or
/// not is handled by the Git module, rather than having a “null” variant in
/// this enum.
#[derive(PartialEq)]
pub enum GitStatus {

/// This file hasn’t changed since the last commit.
Expand Down
6 changes: 5 additions & 1 deletion src/options/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
use std::ffi::{OsStr, OsString};

use crate::fs::dir_action::DirAction;
use crate::fs::filter::FileFilter;
use crate::fs::filter::{FileFilter,GitIgnore};
use crate::output::{View, Mode, details, grid_details};

mod style;
Expand Down Expand Up @@ -146,6 +146,10 @@ impl Options {
/// status column. It’s only worth trying to discover a repository if the
/// results will end up being displayed.
pub fn should_scan_for_git(&self) -> bool {
if self.filter.git_ignore == GitIgnore::CheckAndIgnore {
return true;
}

match self.view.mode {
Mode::Details(details::Options { table: Some(ref table), .. }) |
Mode::GridDetails(grid_details::Options { details: details::Options { table: Some(ref table), .. }, .. }) => table.columns.git,
Expand Down
Loading

0 comments on commit 1fe06a7

Please sign in to comment.