100 Commits
Author SHA1 Message Date
Andrew Gallant 82313cf958 ignore-0.4.26 2026-06-05 07:03:03 -04:00
Andrew Gallant 48a6ad93f1 ci: add support for aarch64-unknown-linux-musl
This includes running tests and binary artifacts.

Fixes #2739
2026-06-03 14:29:59 -04:00
Andrew Gallant c28ce760df docs: update GUIDE to use lexopt
... we migrated off of `clap` long ago.
2026-06-03 18:50:44 +02:00
Andrew Gallant 4857d6fa67 docs: s/our projects/this project in AI policy
This was an artifact of using uv's policy. I thought I had changed most
of these but didn't catch this one.
2026-05-26 08:36:15 -04:00
Andrew Gallant f0cec341ab docs: add AI policy for contributors
I've shamlessly adapted this from [uv's AI policy].

[uv's AI policy]: https://github.com/astral-sh/.github/blob/c5187e200db51bfe11d56e13053d29bd3793fdd8/AI_POLICY.md
2026-05-26 00:02:44 -04:00
Andrew Gallant cb66736f14 core: bleat a DEBUG message when RIPGREP_CONFIG_PATH is not set
It seems to be common that folks either don't understand how to set
environment variables in a way that propagates to subprocesses, or just
forget to include `export` and think ripgrep is somehow broken.

While `RIPGREP_CONFIG_PATH` not being set is not an error, it still
seems useful to log a debug message when it isn't. This should hopefully
provide a clue that, no, ripgrep isn't broken. It just doesn't see the
environment variable.

Ref #3277
2026-02-20 16:18:05 -05:00
Andrew Gallant 57c190d56e ignore-0.4.25 2025-10-30 13:30:14 -04:00
Andrew Gallant 36b7597693 changelog: start next section 2025-10-22 09:02:40 -04:00
Andrew Gallant a132e56b8c pkg/brew: update tap 2025-10-22 09:01:12 -04:00
Andrew Gallant af60c2de9d 15.1.0 2025-10-22 08:30:04 -04:00
Andrew Gallant a63671efb0 deps: bump to grep 0.4.1 2025-10-22 08:29:19 -04:00
Andrew Gallant 2ea06d69aa grep-0.4.1 2025-10-22 08:28:53 -04:00
Andrew Gallant 85006b08d6 deps: bump to grep-printer 0.3.1 2025-10-22 08:28:32 -04:00
Andrew Gallant 423afb8513 grep-printer-0.3.1 2025-10-22 08:28:06 -04:00
Andrew Gallant 4694800be5 deps: bump to grep-searcher 0.1.16 2025-10-22 08:26:22 -04:00
Andrew Gallant 86e0ab12ef grep-searcher-0.1.16 2025-10-22 08:25:01 -04:00
Andrew Gallant 7189950799 deps: bump to globset 0.4.18 2025-10-22 08:24:51 -04:00
Andrew Gallant 0b0e013f5a globset-0.4.18 2025-10-22 08:23:57 -04:00
Andrew Gallant cac9870a02 doc: update date in man page template 2025-10-22 08:23:05 -04:00
Andrew Gallant bee13375ed deps: update everything 2025-10-22 08:21:56 -04:00
Andrew Gallant f5be160839 changelog: 15.1.0 2025-10-22 08:21:34 -04:00
Andrew Gallant 5748f81bb1 printer: use doc_cfg instead of doc_auto_cfg
Fixes #3202
2025-10-22 07:47:07 -04:00
Andrew Gallant d47663b1b4 searcher: fix regression with --line-buffered flag
In my fix for #3184, I actually had two fixes. One was a tweak to how we
read data and the other was a tweak to how we determined how much of the
buffer we needed to keep around. It turns out that fixing #3184 only
required the latter fix, found in commit
d4b77a8d89. The former fix also helped the
specific case of #3184, but it ended up regressing `--line-buffered`.

Specifically, previous to 8c6595c215 (the
first fix), we would do one `read` syscall. This call might not fill our
caller provided buffer. And in particular, `stdin` seemed to fill fewer
bytes than reading from a file. So the "fix" was to put `read` in a loop
and keep calling it until the caller provided buffer was full or until
the stream was exhausted. This helped alleviate #3184 by amortizing
`read` syscalls better.

But of course, in retrospect, this change is clearly contrary to how
`--line-buffered` works. We specifically do _not_ want to wait around
until the buffer is full. We want to read what we can, search it and
move on.

So this reverts the first fix but leaves the second, which still
keeps #3184 fixed and also fixes #3194 (the regression).

This reverts commit 8c6595c215.

Fixes #3194
2025-10-19 11:06:39 -04:00
Andrew Gallant b3dc4b0998 globset: improve debug log
This shows the regex that the glob was compiled to.
2025-10-17 10:27:19 -04:00
Andrew Gallant f09b55b8e7 changelog: start next section 2025-10-15 23:32:00 -04:00
Andrew Gallant 0551c6b931 pkg/brew: update tap 2025-10-15 23:31:35 -04:00
Andrew Gallant 3a612f88b8 15.0.0 2025-10-15 23:07:50 -04:00
Andrew Gallant ca2e34f37c grep-0.4.0 2025-10-15 23:06:34 -04:00
Andrew Gallant a6092beee4 deps: bump to grep-printer 0.3.0 2025-10-15 23:05:10 -04:00
Andrew Gallant a0d61a063f grep-printer-0.3.0 2025-10-15 23:04:24 -04:00
Andrew Gallant c22fc0f13c deps: bump to grep-searcher 0.1.15 2025-10-15 23:02:59 -04:00
Andrew Gallant 087f82273d grep-searcher-0.1.15 2025-10-15 23:02:33 -04:00
Andrew Gallant a3a30896be deps: bump to grep-pcre2 0.1.9 2025-10-15 23:01:31 -04:00
Andrew Gallant 7397ab7d97 grep-pcre2-0.1.9 2025-10-15 23:01:07 -04:00
Andrew Gallant cf1dab0d5a deps: bump to grep-regex 0.1.14 2025-10-15 23:00:58 -04:00
Andrew Gallant e523c6bf32 grep-regex-0.1.14 2025-10-15 23:00:22 -04:00
Andrew Gallant 720376ead6 deps: bump to grep-matcher 0.1.8 2025-10-15 23:00:12 -04:00
Andrew Gallant a5ba50ceaf grep-matcher-0.1.8 2025-10-15 22:59:35 -04:00
Andrew Gallant a766f79710 deps: bump to grep-cli 0.1.12 2025-10-15 22:59:17 -04:00
Andrew Gallant 4aafe45760 grep-cli-0.1.12 2025-10-15 22:58:42 -04:00
Andrew Gallant c03e49b8c5 deps: bump to ignore 0.4.24 2025-10-15 22:58:35 -04:00
Andrew Gallant 70ae7354e1 ignore-0.4.24 2025-10-15 22:57:50 -04:00
Andrew Gallant 19c2a6e0d9 deps: bump to globset 0.4.17 2025-10-15 22:57:28 -04:00
Andrew Gallant 064b36b115 globset-0.4.17 2025-10-15 22:55:55 -04:00
Andrew Gallant 365384a5c1 doc: move CHANGELOG update before dependency updates
It seems better to write this first. Especially so it gets included into
crate publishes.
2025-10-15 22:54:51 -04:00
Andrew Gallant 72a5291b4e doc: update date in man page template 2025-10-15 22:54:11 -04:00
Andrew Gallant 62e676843a deps: update everything 2025-10-15 22:53:30 -04:00
Andrew Gallant 3780168c13 changelog: 15.0.0 2025-10-15 22:53:30 -04:00
Andrew Gallant 4c953731c4 release: finally switch to LTO for release binaries
There seems to be a modest improvement on some workloads:

```
$ time rg -co '\w+' sixteenth.txt
158520346

real    8.457
user    8.426
sys     0.020
maxmem  779 MB
faults  0

$ time rg-lto -co '\w+' sixteenth.txt
158520346

real    8.200
user    8.178
sys     0.012
maxmem  778 MB
faults  0
```

I've somewhat reversed course on my previous thoughts here. The
improvement isn't much, but the hit to compile times in CI isn't
terrible. Mostly I'm doing this out of "good sense," and I think it's
generally unlikely to make it more difficult for me to diagnose
performance problems. (Since I still use the default `release` profile
locally, since it's about an order of magnitude quicker to compile.)

Ref #325, Ref #413, Ref #1187, Ref #1255
2025-10-15 22:51:41 -04:00
Andrew Gallant 79d393a302 release: remove riscv64 and powerpc64 artifacts
Their CI workflows broke for different reasons.

I perceive these as niche platforms that aren't worth blocking
a release on. And not worth my time investigating CI problems.
2025-10-15 22:42:51 -04:00
Andrew Gallant 85eaf95833 ci: testing release 2025-10-15 22:41:46 -04:00
Andrew Gallant 63209ae0b9 printer: fix --stats for --json
Somehow, the JSON printer seems to have never emitted correct summary
statistics. And I believe #3178 is the first time anyone has ever
reported it. I believe this bug has persisted for years. That's
surprising.

Anyway, the problem here was that we were bailing out of `finish()` on
the sink if we weren't supposed to print anything. But we bailed out
before we tallied our summary statistics. Obviously we shouldn't do
that.

Fixes #3178
2025-10-15 21:21:20 -04:00
Andrew Gallant b610d1cb15 ignore: fix global gitignore bug that arises with absolute paths
The `ignore` crate currently handles two different kinds of "global"
gitignore files: gitignores from `~/.gitconfig`'s `core.excludesFile`
and gitignores passed in via `WalkBuilder::add_ignore` (corresponding to
ripgrep's `--ignore-file` flag).

In contrast to any other kind of gitignore file, these gitignore files
should have their patterns interpreted relative to the current working
directory. (Arguably there are other choices we could make here, e.g.,
based on the paths given. But the `ignore` infrastructure can't handle
that, and it's not clearly correct to me.) Normally, a gitignore file
has its patterns interpreted relative to where the gitignore file is.
This relative interpretation matters for patterns like `/foo`, which are
anchored to _some_ directory.

Previously, we would generally get the global gitignores correct because
it's most common to use ripgrep without providing a path. Thus, it
searches the current working directory. In this case, no stripping of
the paths is needed in order for the gitignore patterns to be applied
directly.

But if one provides an absolute path (or something else) to ripgrep to
search, the paths aren't stripped correctly. Indeed, in the core, I had
just given up and not provided a "root" path to these global gitignores.
So it had no hope of getting this correct.

We fix this assigning the CWD to the `Gitignore` values created from
global gitignore files. This was a painful thing to do because we'd
ideally:

1. Call `std::env::current_dir()` at most once for each traversal.
2. Provide a way to avoid the library calling `std::env::current_dir()`
   at all. (Since this is global process state and folks might want to
   set it to different values for $reasons.)

The `ignore` crate's internals are a total mess. But I think I've
addressed the above 2 points in a semver compatible manner.

Fixes #3179
2025-10-15 19:44:23 -04:00
Andrew Gallant d4b77a8d89 searcher: fix a performance bug with -A/--after-context
Previously (with the previous commit):

```
$ cat bigger.txt | (time rg ZQZQZQZQZQ -A999) | wc -l

real    2.321
user    0.674
sys     0.735
maxmem  30 MB
faults  0
1000

$ cat bigger.txt | (time rg ZQZQZQZQZQ -A9999) | wc -l

real    2.513
user    0.823
sys     0.686
maxmem  30 MB
faults  0
10000

$ cat bigger.txt | (time rg ZQZQZQZQZQ -A99999) | wc -l

real    5.067
user    3.254
sys     0.676
maxmem  30 MB
faults  0
100000

$ cat bigger.txt | (time rg ZQZQZQZQZQ -A999999) | wc -l

real    6.658
user    4.841
sys     0.778
maxmem  51 MB
faults  0
1000000
```

Now with this commit:

```
$ cat bigger.txt | (time rg ZQZQZQZQZQ -A999) | wc -l

real    1.845
user    0.328
sys     0.757
maxmem  30 MB
faults  0
1000

$ cat bigger.txt | (time rg ZQZQZQZQZQ -A9999) | wc -l

real    1.917
user    0.334
sys     0.771
maxmem  30 MB
faults  0
10000

$ cat bigger.txt | (time rg ZQZQZQZQZQ -A99999) | wc -l

real    1.972
user    0.319
sys     0.812
maxmem  30 MB
faults  0
100000

$ cat bigger.txt | (time rg ZQZQZQZQZQ -A999999) | wc -l

real    2.005
user    0.333
sys     0.855
maxmem  30 MB
faults  0
1000000
```

And compare to GNU grep:

```
$ cat bigger.txt | (time grep ZQZQZQZQZQ -A999) | wc -l

real    1.488
user    0.143
sys     0.866
maxmem  30 MB
faults  0
1000

$ cat bigger.txt | (time grep ZQZQZQZQZQ -A9999) | wc -l

real    1.697
user    0.170
sys     0.986
maxmem  30 MB
faults  1
10000

$ cat bigger.txt | (time grep ZQZQZQZQZQ -A99999) | wc -l

real    1.515
user    0.166
sys     0.856
maxmem  29 MB
faults  0
100000

$ cat bigger.txt | (time grep ZQZQZQZQZQ -A999999) | wc -l

real    1.490
user    0.174
sys     0.851
maxmem  30 MB
faults  0
1000000
```

Interestingly, GNU grep is still a bit faster. But both commands remain
roughly invariant in search time as `-A` is increased.

There is definitely something "odd" about searching `stdin`, where it
seems substantially slower. We can also observe with GNU grep:

```
$ (time grep ZQZQZQZQZQ -A999999 bigger.txt) | wc -l

real    0.692
user    0.184
sys     0.506
maxmem  30 MB
faults  0
1000000

$ cat bigger.txt | (time grep ZQZQZQZQZQ -A999999) | wc -l

real    1.700
user    0.201
sys     0.954
maxmem  30 MB
faults  0
1000000

$ (time rg ZQZQZQZQZQ -A999999 bigger.txt) | wc -l

real    0.640
user    0.428
sys     0.209
maxmem  7734 MB
faults  0
1000000

$ (time rg ZQZQZQZQZQ --no-mmap -A999999 bigger.txt) | wc -l

real    0.866
user    0.282
sys     0.581
maxmem  30 MB
faults  0
1000000

$ cat bigger.txt | (time rg ZQZQZQZQZQ -A999999) | wc -l

real    1.991
user    0.338
sys     0.819
maxmem  30 MB
faults  0
1000000
```

I wonder if this is related to my discovery in the previous commit where
`read` calls on `stdin` seem to never return anything more than ~64K. Oh
well, I'm satisfied at this point, especially given that GNU grep seems
to do a lot worse than ripgrep with bigger values of
`-B/--before-context`:

```
$ cat bigger.txt | (time grep ZQZQZQZQZQ -B9) | wc -l

real    1.568
user    0.170
sys     0.885
maxmem  30 MB
faults  0
1

$ cat bigger.txt | (time grep ZQZQZQZQZQ -B99) | wc -l

real    1.734
user    0.338
sys     0.879
maxmem  30 MB
faults  0
1

$ cat bigger.txt | (time grep ZQZQZQZQZQ -B999) | wc -l

real    2.349
user    1.723
sys     0.620
maxmem  30 MB
faults  0
1

$ cat bigger.txt | (time grep ZQZQZQZQZQ -B9999) | wc -l

real    16.459
user    15.848
sys     0.586
maxmem  30 MB
faults  0
1

$ time grep ZQZQZQZQZQ -B99999 bigger.txt
ZQZQZQZQZQ

real    1:45.06
user    1:44.12
sys     0.772
maxmem  30 MB
faults  0
```

The above pattern occurs regardless of whether you put `bigger.txt` on
stdin or whether you search it directly.

And now ripgrep:

```
$ cat bigger.txt | (time rg ZQZQZQZQZQ -B9) | wc -l

real    1.965
user    0.326
sys     0.814
maxmem  29 MB
faults  0
1

$ cat bigger.txt | (time rg ZQZQZQZQZQ -B99) | wc -l

real    1.941
user    0.423
sys     0.813
maxmem  29 MB
faults  0
1

$ cat bigger.txt | (time rg ZQZQZQZQZQ -B999) | wc -l

real    2.372
user    0.759
sys     0.703
maxmem  30 MB
faults  0
1

$ cat bigger.txt | (time rg ZQZQZQZQZQ -B9999) | wc -l

real    2.638
user    0.895
sys     0.665
maxmem  29 MB
faults  0
1

$ cat bigger.txt | (time rg ZQZQZQZQZQ -B99999) | wc -l

real    5.172
user    3.282
sys     0.748
maxmem  29 MB
faults  0
1
```

NOTE: To get `bigger.txt`:

```
$ curl -LO 'https://burntsushi.net/stuff/opensubtitles/2018/en/sixteenth.txt.gz'
$ gzip -d sixteenth.txt.gz
$ (echo ZQZQZQZQZQ && for ((i=0;i<10;i++)); do cat sixteenth.txt; done) > bigger.txt
```
2025-10-14 14:27:43 -04:00
Andrew Gallant 8c6595c215 searcher: fix performance bug with -A/--after-context when searching stdin
This was a crazy subtle bug where ripgrep could slow down exponentially
as increasingly larger values of `-A/--after-context` were used. But,
interestingly, this would only occur when searching `stdin` and _not_
when searching the same data as a regular file.

This confounded me because ripgrep, pretty early on, erases the
difference between searching a single file and `stdin`. So it wasn't
like there were different code paths. And I mistakenly assumed that they
would otherwise behave the same as they are just treated as streams.

But... it turns out that running `read` on a `stdin` versus a regular
file seems to behave differently. At least on my Linux system, with
`stdin`, `read` never seems to fill the buffer with more than 64K. But
with a regular file, `read` pretty reliably fills the caller's buffer
with as much space as declared.

Of course, it is expected that `read` doesn't *have* to fill up the
caller's buffer, and ripgrep is generally fine with that. But when
`-A/--after-context` is used with a very large value---big enough that
the default buffer capacity is too small---then more heap memory needs
to be allocated to correctly handle all cases. This can result in
passing buffers bigger than 64K to `read`.

While we *correctly* handle `read` calls that don't fill the buffer,
it turns out that if we don't fill the buffer, then we get into a
pathological case where we aren't processing as many bytes as we could.
That is, because of the `-A/--after-context` causing us to keep a lot of
bytes around while we roll the buffer and because reading from `stdin`
gives us fewer bytes than normal, we weren't amortizing our `read` calls
as well as we should have been. Indeed, our buffer capacity increases
specifically take this amortization into account, but we weren't taking
advantage of it.

We fix this by putting `read` into an inner loop that ensures our
buffer gets filled up. This fixes the performance bug:

```
$ (time rg ZQZQZQZQZQ bigger.txt --no-mmap -A9999) | wc -l

real    1.330
user    0.767
sys     0.559
maxmem  29 MB
faults  0
10000

$ cat bigger.txt | (time rg ZQZQZQZQZQ --no-mmap -A9999) | wc -l

real    2.355
user    0.860
sys     0.613
maxmem  29 MB
faults  0
10000

$ (time rg ZQZQZQZQZQ bigger.txt --no-mmap -A99999) | wc -l

real    3.636
user    3.091
sys     0.537
maxmem  29 MB
faults  0
100000

$ cat bigger.txt | (time rg ZQZQZQZQZQ --no-mmap -A99999) | wc -l

real    4.918
user    3.236
sys     0.710
maxmem  29 MB
faults  0
100000

$ (time rg ZQZQZQZQZQ bigger.txt --no-mmap -A999999) | wc -l

real    5.430
user    4.666
sys     0.750
maxmem  51 MB
faults  0
1000000

$ cat bigger.txt | (time rg ZQZQZQZQZQ --no-mmap -A999999) | wc -l

real    6.894
user    4.907
sys     0.850
maxmem  51 MB
faults  0
1000000
```

For comparison, here is GNU grep:

```
$ cat bigger.txt | (time grep ZQZQZQZQZQ -A9999) | wc -l

real    1.466
user    0.159
sys     0.839
maxmem  29 MB
faults  0
10000

$ cat bigger.txt | (time grep ZQZQZQZQZQ -A99999) | wc -l

real    1.663
user    0.166
sys     0.941
maxmem  29 MB
faults  0
100000

$ cat bigger.txt | (time grep ZQZQZQZQZQ -A999999) | wc -l

real    1.631
user    0.204
sys     0.910
maxmem  29 MB
faults  0
1000000
```

GNU grep is still notably faster. We'll fix that in the next commit.

Fixes #3184
2025-10-14 14:27:43 -04:00
Andrew Gallant de2567a4c7 printer: fix panic in replacements in look-around corner case
The abstraction boundary fuck up is the gift that keeps on giving. It
turns out that the invariant that the match would never exceed the range
given is not always true. So we kludge around it.

Also, update the CHANGELOG to include the fix for #2111.

Fixes #3180
2025-10-12 17:25:19 -04:00
Andrew Gallant 916415857f core: don't build decompression reader unless we intend to use it
Building it can consume resources. In particular, on Windows, the
various binaries are eagerly resolved.

I think this originally wasn't done. The eager resolution was added
later for security purposes. But the "eager" part isn't actually
necessary.

It would probably be better to change the decompression reader to do
lazy resolution only when the binary is needed. But this will at least
avoid doing anything when the `-z/--search-zip` flag isn't used. But
when it is, ripgrep will still eagerly resolve all possible binaries.

Fixes #2111
2025-10-12 16:31:20 -04:00
Andrew Gallant 5c42c8c48f test: add regression test for fixed bug
It turns out that #2094 was fixed in my `--max-count` refactor a few
commits back. This commit adds a regression test for it.

Closes #2094
2025-10-12 12:45:34 -04:00
Andrew Gallant f0faa91c68 doc: clarify --ignore-file precedence
Fixes #2777
2025-10-10 22:06:59 -04:00
Andrew Gallant a5d9e03c68 test: attempt to fix flaky time-reliant test
Fixes #2794
2025-10-10 22:06:59 -04:00
Andrew Gallant 924ba101ee test: fix Command::current_dir API
Every single call site wants to pass a path relative to the directory
the command was created for. So just make it do that automatically,
similar to `Dir::create` and friends.
2025-10-10 22:06:59 -04:00
Andrew Gallant 293ef80eaf test: add another regression test for gitignore matching bug
I believe this was also fixed by #2933.

Closes #2770
2025-10-10 22:06:59 -04:00
Andrew Gallant fa80aab6b0 test: add regression test for fixed gitignore bug
I believe this was actually fixed by #2933.

Closes #3067
2025-10-10 22:06:59 -04:00
Andrew Gallant 096f79ab98 deps: update everything
This includes an update to `regex 1.12.1`, which fixes a couple of
outstanding bugs in ripgrep.

Fixes #2750, Fixes #3135
2025-10-10 20:13:29 -04:00
Andrew Gallant 0407e104f6 ignore: fix problem with searching whitelisted hidden files
... specifically, when the whitelist comes from a _parent_ gitignore
file.

Our handling of parent gitignores is pretty ham-fisted and has been a
source of some unfortunate bugs. The problem is that we need to strip
the parent path from the path we're searching in order to correctly
apply the globs. But getting this stripping correct seems to be a subtle
affair.

Fixes #3173
2025-10-08 21:16:59 -04:00
Andrew Gallant bb88a1ac45 deps: semver compatible updated to dependencies 2025-10-05 10:52:46 -04:00
Andrew Gallant 9d8016d10c printer: finish removal of max_matches
This finishes what I started in commit
a6e0be3c90.
Specifically, the `max_matches` configuration has been moved to the
`grep-searcher` crate and *removed* from the `grep-printer` crate. The
commit message has the details for why we're doing this, but the short
story is to fix #3076.

Note that this is a breaking change for `grep-printer`, so this will
require a semver incompatible release.
2025-10-04 09:19:53 -04:00
Andrew Gallant 9802945e63 doc: update the CentOS, RHEL and Rocky Linux installation instructions
I've split the previously singular "CentOS/RHEL/Rocky" section into 3
sections. They each benefit from having their own steps.

I've also copied steps from [EPEL Getting Started] documentation,
including steps that don't seem to be required because it seems to be
best practice (although I do not understand it). Notably, this is not
required for CentOS Stream:

```
dnf config-manager --set-enabled crb
```

And this is not required for Red Hat:

```
subscription-manager repos --enable codeready-builder-for-rhel-10-$(arch)-rpms
```

And neither are available on Rocky Linux 10. Hence, all 3 have slightly
different instructions.

It has been suggested (see [here][suggest1] and [here][suggest2]) that
the installation instructions should just link to the [EPEL Getting
Started] documentation and just contain this step:

```
sudo dnf install ripgrep
```

However, this is not sufficient to actually install ripgrep from a
base installation of these Linux distributions. I tested this via the
`dokken/centos-stream-10:sha-d1e294f`, `rockylinux/rockylinux:10` and
`redhat/ubi10` Docker images on DockerHub.

While this does mean ripgrep's installation instructions can become out
of sync from upstream, this is *always* a risk regardless of platform.
The instructions are provided on a best effort basis and generally
should work on the latest release of said platform. If the instructions
result in unhelpful errors (like `dnf install ripgrep` does if you
don't enable EPEL), then that isn't being maximally helpful to users.
I'd rather attempt to give the entire set of instructions and risk
being out of sync.

Also, since the installation instructions include URLs with version
numbers in them, I made the section names include version numbers as
well.

Note: I found using the `dokken/centos-stream-10:sha-d1e294f` Docker
image to be somewhat odd, as I could not find any official CentOS
Docker images. [This][DockerHub-CentOS] is still the first hit on
Google, but all of its tags have been deleted and the image is
deprecated. I was profoundly confused by this given that the [EPEL
Getting Started] documentation *specifically* cites CentOS 10. In fact,
it is citing CentOS *Stream* 10, which is something wholly distinct
from CentOS. What an absolute **clusterfuck**. If I had just read this
paragraph on Wikipedia from the beginning, I would have saved myself a
lot of confusion:

> In December 2020, Red Hat unilaterally terminated CentOS development in favor
> of CentOS Stream 9, a distribution positioned upstream of RHEL. In March
> 2021, CloudLinux (makers of CloudLinux OS) released a RHEL derivative called
> AlmaLinux. Later in May 2021, one of the CentOS founders (Gregory Kurtzer)
> created the competing Rocky Linux project as a successor to the original
> mission of CentOS.

Ref #2981, Ref #2924

[EPEL Getting Started]: https://docs.fedoraproject.org/en-US/epel/getting-started/
[suggest1]: https://github.com/BurntSushi/ripgrep/pull/2981#issuecomment-3204114293
[suggest2]: https://github.com/BurntSushi/ripgrep/issues/2924#issuecomment-3326357254
[DockerHub-CentOS]: https://hub.docker.com/_/centos
2025-09-24 10:02:46 -04:00
Andrew Gallant fdea9723ca doc: clarify a case where -m/--max-count is not strictly respected
In #2843, it's requested that these trailing contextual lines should be
displayed as non-matching because they exceed the limit. While
reasonable, I think that:

1. This would be a weird complication to the implementation.
2. This would overall be less intuitive and more complex. Today, there
   is never a case where ripgrep emits a matching line in a way where
   the match isn't highlighted.

Closes #2843
2025-09-22 22:12:15 -04:00
Andrew Gallant c45ec16360 doc: clarify --multiline --count
Specifically, it is only equivalent to `--count-matches` when the
pattern(s) given can match over multiple lines.

We could have instead made `--multiline --count` always equivalent to
`--multiline --count-matches`, but this seems plausibly less useful.
Indeed, I think it's generally a good thing that users can enable
`-U/--multiline` but still use patterns that only match a single line.
Changing how that behaves would I think be more surprising.

Either way we slice this, it's unfortunately pretty subtle.

Fixes #2852
2025-09-22 22:00:15 -04:00
Andrew Gallant e42432cc5d ignore: clarify WalkBuilder::filter_entry
Fixes #2913
2025-09-22 21:49:29 -04:00
Andrew Gallant 6e77339f30 cli: tweak docs for resolve_binary
Fixes #2928
2025-09-22 21:38:08 -04:00
Andrew Gallant 1b07c6616a cli: document that -c/--count can be inconsistent with -l/--files-with-matches
This is unfortunate, but is a known bug that I don't think can be fixed
without either making `-l/--files-with-matches` much slower or changing
what "binary filtering" means by default.

In this PR, we document this inconsistency since users may find it quite
surprising. The actual work-around is to disable binary filtering with
the `--binary` flag.

We add a test confirming this behavior.

Closes #3131
2025-09-22 20:24:53 -04:00
Andrew Gallant c1fc6a5eb8 release: build aarch64 artifacts for macos on GitHub Actions
GitHub now supports this natively, so there's no need for me to do it
any more.

Fixes #3155
2025-09-22 11:56:33 -04:00
Andrew Gallant 8b5d3d1c1e printer: hack in a fix for -l/--files-with-matches when using --pcre2 --multiline with look-around
The underlying issue here is #2528, which was introduced by commit
efd9cfb2fc which fixed another bug.

For the specific case of "did a file match," we can always assume the
match count is at least 1 here. But this doesn't fix the underlying
problem.

Fixes #3139
2025-09-22 09:12:16 -04:00
Andrew Gallant 491bf3f6d5 deps: update everything else 2025-09-21 11:39:04 -04:00
Andrew Gallant 81bed78654 deps: update to PCRE2 10.46
This is for completely static builds of ripgrep.
2025-09-21 11:39:04 -04:00
Andrew Gallant 1b6177bc5c cargo: set MSRV to 1.85
I believe the current stable version of Debian packages 1.85 rustc. So
if the next release of ripgrep uses a higher MSRV, then I think Debian
won't be able to package it.

It also turned out that I wasn't using anything from beyond Rust 1.85
anyway.

It's likely that I could make use of let-chains in various places, but I
don't think it's worth combing through the code to switch to them at
this point.
2025-09-21 09:51:15 -04:00
Andrew Gallant bb8172fe9b style: apply rustfmt
Maybe 2024 changes?

Note that we now set `edition = "2024"` explicitly in `rustfmt.toml`.
Without this, it seems like it's possible in some cases for rustfmt to
run under an older edition's style. Not sure how though.
2025-09-19 21:08:19 -04:00
Andrew Gallant a60e62d9ac rust: move to Rust 2024
I'd like to use let chains.

Probably this isn't necessary to do for every crate, but I don't feel
like maintaining a mismash.
2025-09-19 21:08:19 -04:00
Andrew Gallant 74959a14cb man: escape all hyphens in flag names
Apparently, if we don't do this, some roff renderers with use a special
Unicode hyphen. That in turn makes searching a man page not work as one
would expect.

Fixes #3140
2025-09-19 21:08:19 -04:00
Andrew Gallant fdfda9ae73 doc: actually fix deb download link
Amazingly, there were about a dozen PRs fixing this same thing, and I
happened to choose the one that didn't actually fix the URL completely.

Apparently some users found this "interesting":
https://github.com/BurntSushi/ripgrep/pull/3065#issuecomment-3204275122
2025-09-19 21:08:19 -04:00
Andrew Gallant 126bbeab8c printer: fix handling of has_match for summary printer
Previously, `Quiet` mode in the summary printer always acted like
"print matching paths," except without the printing. This happened even
if we wanted to "print non-matching paths." Since this only afflicted
quiet mode, this had the effect of flipping the exit status when
`--files-without-match --quiet` was used.

Fixes #3108, Ref #3118
2025-09-19 21:08:19 -04:00
Andrew Gallant 2ebd768d40 doc: remove CentOS/RHEL installation instructions
These distros, or their Docker images, appear FUBAR. The UX is so poor
that I cannot verify the correct installation instructions. So I'm
removing them.

Ref https://github.com/BurntSushi/ripgrep/pull/2981#issuecomment-3202063173

Closes #2981, Closes #3124
2025-09-19 21:08:19 -04:00
Andrew Gallant 4df1298127 globset: fix bug where trailing . in file name was incorrectly handled
I'm not sure why I did this, but I think I was trying to imitate the
contract of [`std::path::Path::file_name`]:

> Returns None if the path terminates in `..`.

But the status quo clearly did not implement this. And as a result, if
you have a glob that ends in a `.`, it was instead treated as the empty
string (which only matches the empty string).

We fix this by implementing the semantic from the standard library
correctly.

Fixes #2990

[`std::path::Path::file_name`]: https://doc.rust-lang.org/std/path/struct.Path.html#method.file_name
2025-09-19 21:08:19 -04:00
Andrew Gallant 7339bdf4b5 test: check binary file detection when using memory maps
This resolves a TODO comment I wrote a while back.

Memory maps behave a little differently in terms of detecting binary
data, so the tests have somewhat different results than the tests that
disable memory maps.

Closes #3002
2025-09-19 21:08:19 -04:00
Andrew Gallant 4ab1862dc0 stats: fix case where "bytes searched" could be wrong
Specifically, if the search was instructed to quit early, we might not
have correctly marked the number of bytes consumed.

I don't think this bug occurs when memory maps are used to read the
haystack.

Closes #2944
2025-09-19 21:08:19 -04:00
Andrew Gallant ab4665a164 globset: remove __Nonexhaustive work-around
This existed before the `#[non_exhaustive]` attribute was a thing. Since
it was not part of the API of the crate, it is not a semver incompatible
change.
2025-09-19 21:08:19 -04:00
Andrew Gallant d199058e77 cli: make rg -vf file behave sensibly
Previously, when `file` is empty (literally empty, as in, zero byte),
`rg -f file` and `rg -vf file` would behave identically. This is odd
and also doesn't match how GNU grep behaves. It's also not logically
correct. An empty file means _zero_ patterns which is an empty set. An
empty set matches nothing. Inverting the empty set should result in
matching everything.

This was because of an errant optimization that lets ripgrep quit early
if it can statically detect that no matches are possible.

Moreover, there was *also* a bug in how we constructed the PCRE2 pattern
when there are zero patterns. PCRE2 doesn't have a concept of sets of
patterns (unlike the `regex` crate), so we need to fake it with an empty
character class.

Fixes #1332, Fixes #3001, Closes #3041
2025-09-19 21:08:19 -04:00
Andrew Gallant bfe2def121 tests: add test for filtering hidden files
Note that this isn't a regression test. In particular, this didn't fail
with ripgrep 14.1.1. I couldn't figure out how to turn what the OP gave
me into a failing test.

With #829 fixed, if the OP can provide a better regression test, it
might make sense to re-investigate this.

Closes #2711
2025-09-19 21:08:19 -04:00
Andrew Gallant 119a58a400 msrv: bump to Rust 1.88
This is to prep for the next release. I don't know if the requirement
will actually be for Rust 1.88, but it is intended to support the latest
version of stable Rust.
2025-07-26 10:41:47 -04:00
Andrew Gallant 3b7fd442a6 deps: update everything
It looks like a new dependency on `getrandom` was added (which brings in
a few more dependencies itself) because of `jobserver`. Thankfully,
`jobserver` is only used when ripgrep's `pcre2` feature is enabled, so
this still keeps the default set of dependencies very small.
2025-07-04 10:12:38 -04:00
Andrew Gallant de4baa1002 globset-0.4.16 2025-02-27 12:46:58 -05:00
Andrew Gallant 163ac157d3 globset: escape { and } in escape
This appears to be an oversight from when `escape` was
implemented in #2061.
2025-02-27 12:46:48 -05:00
Andrew Gallant e2362d4d51 searcher: add log message noting detected encoding
This helps improve diagnostics. Otherwise it can be easy to miss that
ripgrep is doing transcoding.

Fixes #2979
2025-01-25 14:27:00 -05:00
Andrew Gallant 79cbe89deb doc: tweak wording for stdin detection
This makes it slightly more precise to cover weird cases like trying to
pass a directory on stdin.

Closes #2906
2024-09-30 07:38:05 -04:00
Andrew Gallant 8bd5950296 changelog: add next section 2024-09-08 22:32:09 -04:00
Andrew Gallant 6e0539ab91 pkg/brew: update tap 2024-09-08 22:32:02 -04:00
Andrew Gallant 4649aa9700 14.1.1 2024-09-08 22:15:00 -04:00
Andrew Gallant c009652e77 changelog: 14.1.1 2024-09-08 22:13:53 -04:00