diff --git a/CHANGELOG.md b/CHANGELOG.md index be1efc2..c3bef47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Features +- Add flag --no-require-git to always respect gitignore files, see #1216 (@vegerot) + ## Bugfixes - Fix logic for when to use global ignore file. There was a bug where the only case where the diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8a2313e..b3a7480 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -13,11 +13,11 @@ give us the chance to discuss any potential changes first. ## Add an entry to the changelog If your contribution changes the behavior of `fd` (as opposed to a typo-fix -in the documentation), please update the [`CHANGELOG.md`](CHANGELOG.md) file +in the documentation), please update the [`CHANGELOG.md`](CHANGELOG.md#upcoming-release) file and describe your changes. This makes the release process much easier and therefore helps to get your changes into a new `fd` release faster. -The top of the `CHANGELOG` contains a *"unreleased"* section with a few +The top of the `CHANGELOG` contains an *"Upcoming release"* section with a few subsections (Features, Bugfixes, …). Please add your entry to the subsection that best describes your change. diff --git a/src/cli.rs b/src/cli.rs index 8e97f1c..55fbca8 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -74,6 +74,28 @@ pub struct Opts { #[arg(long, overrides_with = "no_ignore_vcs", hide = true, action = ArgAction::SetTrue)] ignore_vcs: (), + /// Do not require a git repository to respect gitignores. + /// By default, fd will only respect global gitignore rules, .gitignore rules, + /// and local exclude rules if fd detects that you are searching inside a + /// git repository. This flag allows you to relax this restriction such that + /// fd will respect all git related ignore rules regardless of whether you're + /// searching in a git repository or not. + /// + /// + /// This flag can be disabled with --require-git. + #[arg( + long, + overrides_with = "require_git", + hide_short_help = true, + // same description as ripgrep's flag: ripgrep/crates/core/app.rs + long_help + )] + pub no_require_git: bool, + + /// Overrides --no-require-git + #[arg(long, overrides_with = "no_require_git", hide = true, action = ArgAction::SetTrue)] + require_git: (), + /// Show search results from files and directories that would otherwise be /// ignored by '.gitignore', '.ignore', or '.fdignore' files in parent directories. #[arg( diff --git a/src/config.rs b/src/config.rs index 7003a01..75b4c2b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -30,6 +30,9 @@ pub struct Config { /// Whether to respect VCS ignore files (`.gitignore`, ..) or not. pub read_vcsignore: bool, + /// Whether to require a `.git` directory to respect gitignore files. + pub require_git_to_read_vcsignore: bool, + /// Whether to respect the global ignore file or not. pub read_global_ignore: bool, diff --git a/src/main.rs b/src/main.rs index 001ba5a..567058c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -239,6 +239,7 @@ fn construct_config(mut opts: Opts, pattern_regexps: &[String]) -> Result>, config: Arc) - .git_ignore(config.read_vcsignore) .git_global(config.read_vcsignore) .git_exclude(config.read_vcsignore) + .require_git(config.require_git_to_read_vcsignore) .overrides(overrides) .follow_links(config.follow_links) // No need to check for supported platforms, option is unavailable on unsupported ones diff --git a/tests/tests.rs b/tests/tests.rs index 98fe9c8..6c27a02 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -808,6 +808,62 @@ fn test_custom_ignore_precedence() { te.assert_output(&["--no-ignore", "foo"], "inner/foo"); } +/// Don't require git to respect gitignore (--no-require-git) +#[test] +fn test_respect_ignore_files() { + let te = TestEnv::new(DEFAULT_DIRS, DEFAULT_FILES); + + // Not in a git repo anymore + fs::remove_dir(te.test_root().join(".git")).unwrap(); + + // don't respect gitignore because we're not in a git repo + te.assert_output( + &["foo"], + "a.foo + gitignored.foo + one/b.foo + one/two/c.foo + one/two/C.Foo2 + one/two/three/d.foo + one/two/three/directory_foo/", + ); + + // respect gitignore because we set `--no-require-git` + te.assert_output( + &["--no-require-git", "foo"], + "a.foo + one/b.foo + one/two/c.foo + one/two/C.Foo2 + one/two/three/d.foo + one/two/three/directory_foo/", + ); + + // make sure overriding works + te.assert_output( + &["--no-require-git", "--require-git", "foo"], + "a.foo + gitignored.foo + one/b.foo + one/two/c.foo + one/two/C.Foo2 + one/two/three/d.foo + one/two/three/directory_foo/", + ); + + te.assert_output( + &["--no-require-git", "--no-ignore", "foo"], + "a.foo + gitignored.foo + fdignored.foo + one/b.foo + one/two/c.foo + one/two/C.Foo2 + one/two/three/d.foo + one/two/three/directory_foo/", + ); +} + /// VCS ignored files (--no-ignore-vcs) #[test] fn test_no_ignore_vcs() { @@ -2406,6 +2462,7 @@ fn test_number_parsing_errors() { #[test_case("--hidden", &["--no-hidden"] ; "hidden")] #[test_case("--no-ignore", &["--ignore"] ; "no-ignore")] #[test_case("--no-ignore-vcs", &["--ignore-vcs"] ; "no-ignore-vcs")] +#[test_case("--no-require-git", &["--require-git"] ; "no-require-git")] #[test_case("--follow", &["--no-follow"] ; "follow")] #[test_case("--absolute-path", &["--relative-path"] ; "absolute-path")] #[test_case("-u", &["--ignore", "--no-hidden"] ; "u")]