Skip to content

Global -e/-f patterns before search are silently discarded when supplied again after it #194

Closed

Description

@wuliangtdi

Summary

When patterns are supplied on both sides of the explicit search subcommand, only the child-side patterns are searched. Parent-side patterns are silently discarded. The command still exits 0 if a child pattern matches, so callers can mistake the incomplete result for a complete search.

This affects both repeated -e patterns and -f pattern files. It is different from #181, which concerned preserving the contents of one pattern file.

Reproduce

mkdir repro-pattern-scopes && cd repro-pattern-scopes
mkdir data
printf 'foo\nbar\nbaz\n' > data/input.txt
printf 'foo\n' > p1.txt
printf 'bar\n' > p2.txt

tgrep --no-index -I -e foo search -e bar -- data
rg               -I -e foo        -e bar -- data

tgrep --no-index -I -f p1.txt search -f p2.txt -- data
rg               -I -f p1.txt        -f p2.txt -- data

ripgrep has no search subcommand, so its comparison commands flatten the same two pattern inputs.

Case Actual: tgrep 1.2.0 Expected: rg 15.1.0
Two -e patterns across search bar\n, exit 0 foo\nbar\n, exit 0
Two -f files across search bar\n, exit 0 foo\nbar\n, exit 0

The content-search cases reproduce with --no-index, an on-disk index, and tgrep serve --no-watch.

To repeat the indexed cases, run tgrep index data, remove --no-index, and keep the directory path data. For the server cases, start tgrep serve --no-watch data in another terminal and repeat those directory searches. --stats was used in the Windows harness to verify the selected backend, including (via server).

Environment

  • tgrep 1.2.0, official Windows x86_64 release.
  • Source inspected at release commit 3ba6ee02537281b68ee1366bb40df9f8b7cc54f0.
  • Windows; test harness run with PowerShell 7.
  • ripgrep 15.1.0 (af60c2de9d).
  • Verified on 2026-10-12. The shell examples describe the same fixture bytes and arguments tested on Windows.

Cause

The pattern arguments are global in tgrep-cli/src/main.rs:83. The parser reconstructs the CLI from clap's resolved matches and explicitly repairs only the boundary globals in tgrep-cli/src/main.rs:783. It then copies the resolved pattern fields into search options in tgrep-cli/src/main.rs:924.

The observed behavior indicates that the child value replaces the parent pattern collection instead of accumulating both scopes. The loss happens during argument resolution, before backend selection.

Possible fix

Accumulate pattern inputs from every command scope in their original order, without duplicating values inherited through clap's global propagation. Preserve all -e inputs and all admitted -f inputs.

A regression could check both commands above across scan, local-index, and server searches, and check that moving all patterns to one side of search preserves the same search semantics.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions