# How ripgrep Ignore Precedence Rules Work: .gitignore vs .ignore vs .rgignore

> Understand ripgrep ignore precedence: command line, .rgignore, .ignore, and .gitignore. Learn how deeper directory rules win to optimize your searches.

- Repository: [Andrew Gallant/ripgrep](https://github.com/BurntSushi/ripgrep)
- Tags: internals
- Published: 2026-03-05

---

**ripgrep resolves ignore conflicts using a deterministic six-level precedence chain where command-line globs override custom ignore files (including `.rgignore`), which override `.ignore` files, which in turn override `.gitignore` files, with deeper directory rules always winning over parent directory rules within the same type.**

When searching codebases with BurntSushi/ripgrep, understanding how the tool prioritizes conflicting ignore rules is essential for effective file exclusion. The precedence logic determines whether a `.gitignore` entry can be overridden by a local `.ignore` file or if a `.rgignore` pattern takes ultimate precedence. This article examines the exact hierarchy implemented in the `ignore` crate, referencing the specific source files that govern these rules.

## The Six-Level Precedence Hierarchy

According to [`crates/ignore/src/walk.rs`](https://github.com/BurntSushi/ripgrep/blob/main/crates/ignore/src/walk.rs), ripgrep evaluates ignore sources in the following strict order, with each level capable of masking rules from lower levels.

### 1. Glob Overrides (Highest Priority)

Explicit `--glob` or `--iglob` patterns supplied on the command line are checked first. Whitelist globs (`!pattern`) immediately stop further matching and include the file, while ignore globs (`pattern`) cause the path to be skipped without consulting ignore files. This stage pre-empts all file-based ignore rules entirely.

### 2. Custom Ignore Files Including .rgignore

Files added via `--ignore-file` or the default `.rgignore` filename are processed next. As documented in [`walk.rs`](https://github.com/BurntSushi/ripgrep/blob/main/walk.rs) at lines 743-747, "These ignore files have higher precedence than all other ignore files." In [`crates/core/flags/hiargs.rs`](https://github.com/BurntSushi/ripgrep/blob/main/crates/core/flags/hiargs.rs) at line 905, ripgrep registers `.rgignore` as a custom ignore filename using `builder.add_custom_ignore_filename(".rgignore");`.

### 3. .ignore Files

Project-local `.ignore` files override all `.gitignore` files. The documentation in [`walk.rs`](https://github.com/BurntSushi/ripgrep/blob/main/walk.rs) lines 59-68 clarifies that "any `.ignore` file overrides all `.gitignore` files," making this the standard mechanism for repository-specific exclusions that should not be committed to Git.

### 4. .gitignore and Git-Specific Files

Standard Git ignore files are applied after `.ignore`, including repository `.gitignore`, `<repo>/.git/info/exclude`, and the global Git ignore file located at `$XDG_CONFIG_HOME/git/ignore` or `$HOME/.config/git/ignore`.

### 5. Programmatically Added Ignore Files

Ignore files added via the API using `IgnoreBuilder::add_ignore` receive the lowest precedence among ignore sources.

### 6. Directory Depth Within the Same Type

When multiple files of the same type exist in different directories (e.g., nested `.ignore` files), the more deeply nested file wins. As stated in [`walk.rs`](https://github.com/BurntSushi/ripgrep/blob/main/walk.rs) lines 66-68, the nested rule "has a higher precedence than less nested ignore files."

## Practical Examples of Precedence in Action

The following scenarios demonstrate how ripgrep applies these rules when files contain conflicting patterns.

### Overriding .gitignore with .ignore

Consider a project where you want to track a file in Git but exclude it from ripgrep searches, or vice versa:

```text
project/
├── .gitignore          (contains: secret.txt)
└── src/
    ├── .ignore         (contains: !secret.txt)
    └── secret.txt

```

Running `rg secret.txt` will **find** [`src/secret.txt`](https://github.com/BurntSushi/ripgrep/blob/main/src/secret.txt) because the `.ignore` file in `src/` whitelists it. According to the precedence rules in [`walk.rs`](https://github.com/BurntSushi/ripgrep/blob/main/walk.rs), the `.ignore` file at level 3 overrides the `.gitignore` at level 4.

### Enforcing Rules with .rgignore

Because `.rgignore` is a custom ignore filename, it occupies precedence level 2, outranking both `.ignore` and `.gitignore`:

```text

# .rgignore (repository root)

*.log

```

```bash

# Even if a .gitignore or .ignore explicitly whitelists debug.log,

# the .rgignore pattern wins and the file is omitted:

rg debug.log          # -> no output

```

This makes `.rgignore` ideal for personal exclusions that must apply regardless of project-level ignore files.

### Using --ignore-file for Temporary Rules

You can inject custom ignore files dynamically, which behave exactly like `.rgignore`:

```bash

# myrules.txt contains: *.bak

rg --ignore-file myrules.txt "function" .

```

The rules in [`myrules.txt`](https://github.com/BurntSushi/ripgrep/blob/main/myrules.txt) take precedence over all built-in ignore files (`.ignore`, `.gitignore`) because `--ignore-file` maps to the custom ignore filename precedence level.

## Summary

- **Precedence is deterministic**: ripgrep checks sources in the order: globs → custom files (`.rgignore`) → `.ignore` → `.gitignore` → API-added files.
- **`.rgignore` wins over `.gitignore`**: As a custom ignore filename, `.rgignore` patterns override both `.ignore` and `.gitignore` entries.
- **`.ignore` overrides Git**: Any `.ignore` file takes precedence over all `.gitignore` files, making it suitable for search-specific exclusions.
- **Depth matters**: Within the same file type, rules in deeper directories override parent directory rules.
- **Command-line globs are king**: `--glob` and `--iglob` flags bypass all file-based ignore logic entirely.

## Frequently Asked Questions

### Does .rgignore completely override .gitignore?

Yes. Because `.rgignore` is treated as a custom ignore filename in [`crates/core/flags/hiargs.rs`](https://github.com/BurntSushi/ripgrep/blob/main/crates/core/flags/hiargs.rs), it occupies precedence level 2, while `.gitignore` sits at level 4. Any pattern in `.rgignore` will override conflicting rules in `.gitignore` or `.ignore` files.

### Can I whitelist a file in .gitignore that is ignored by .rgignore?

No. Due to the precedence hierarchy, `.rgignore` (custom ignore) outranks `.gitignore`. Once a path matches a `.rgignore` pattern, ripgrep skips the file unless a command-line glob override (`--glob`) explicitly includes it at level 1.

### What happens when both parent and child directories have .ignore files?

The child directory's `.ignore` file wins. Within the same ignore type, ripgrep applies the "closest" or most deeply nested rule, as implemented in the directory traversal logic in [`walk.rs`](https://github.com/BurntSushi/ripgrep/blob/main/walk.rs) lines 66-68.

### How do I temporarily override all ignore files for a single search?

Use the `--glob` or `--iglob` flag with a whitelist pattern. Command-line globs are evaluated before any ignore files, making them the highest precedence mechanism for inclusion or exclusion according to the override logic in [`crates/ignore/src/overrides.rs`](https://github.com/BurntSushi/ripgrep/blob/main/crates/ignore/src/overrides.rs).