Skip to content

fix(watch): stop re-reading the ignore rules on a read of their files - #3584

Merged
vitali87 merged 1 commit into
mainfrom
ccr-9f6abec3-i33uiv
Nov 8, 2026
Merged

vitali87 merged 1 commit into
mainfrom
ccr-9f6abec3-i33uiv

Conversation

@vitali87

@vitali87 vitali87 commented Nov 8, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • cgr watch re-read its ignore rules on any event naming .gitignore, .cgrignore or the git index, reads included. Re-reading them opens those same files, so on Linux each reload raised the opened / closed_no_write events of the next one. A single git status (VS Code's Source Control panel runs them) started a loop that re-read .gitignore every few milliseconds, forever, flooding the log with Loaded N exclude and 0 unignore patterns.
  • Now only a write, creation, deletion or rename of one of those files re-reads the rules (RULE_INPUT_EVENT_TYPES). Editing an ignore file, git add, git mv and git rm still apply exactly as before.

Demo

Terminal output of a reproduction script that runs the real watchdog observer and real IgnoreRules on a temporary git repo, counting reads of .gitignore over 2 seconds (no VHS recording available in this environment):

Before (main):

one read-only `cat .gitignore`, then wait 2s ...
  .gitignore reads after one read: 801
touch a file + two `git status` runs (VS Code Source Control), then wait 2s ...
  .gitignore reads after one read: 884

After (this branch):

one read-only `cat .gitignore`, then wait 2s ...
  .gitignore reads after one read: 0
touch a file + two `git status` runs (VS Code Source Control), then wait 2s ...
  .gitignore reads after one read: 2

The 2 remaining reads are the expected single reload after git status actually rewrote the index.

Type of Change

  • Bug fix
  • New feature
  • Performance improvement
  • Refactoring (no functional changes)
  • Documentation
  • CI/CD or tooling
  • Dependencies

Related Issues

Fixes #3583

Test Plan

  • Unit tests pass (make test-parallel or uv run pytest -n auto -m "not integration") — ran the watcher suites only (212 passed, 25 skipped), not the full suite
  • New tests added — codebase_rag/tests/test_watcher_ignore_rule_reads.py: reads of each input leave the rules alone; writes, creations, deletions, closes-after-write and the index.lock → index rename still reload them; and an end-to-end test on the real inotify observer shows one read of .gitignore sets off no reloads. 7 of these fail on main.
  • Integration tests pass (make test-integration, requires Docker)
  • Manual testing (the reproduction above)

Checklist

  • PR title follows Conventional Commits format
  • A breaking change has ! in the title and its release notes in changes/breaking/<PR number>.md (not a breaking change)
  • All pre-commit checks pass (make pre-commit) — all pass except ty check, which fails locally only on unresolved imports of optional extras in untouched files; no new diagnostics
  • No hardcoded strings in non-config/non-constants files
  • No # type: ignore, cast(), Any, or object type hints
  • New comments and docstrings explain why, not what

Summary by CodeRabbit

  • Bug Fixes
    • Ignore rules no longer reload when their input files are only read. Changes such as edits, file creation or deletion, and relevant renames continue to trigger reloads.

The watcher re-read `.gitignore`, `.cgrignore` and the git index on any
event naming them, reads included. Re-reading them opens those same files,
so on Linux each reload raised the `opened` and `closed_no_write` events of
the next: one `git status` (VS Code's Source Control panel runs them) set
off a loop that re-read `.gitignore` every few milliseconds, for good.

Only a write, creation, deletion or rename of an input re-reads the rules
now. Edits to the ignore files and `git add`/`git mv` still apply as before.

Fixes #3583
@greptile-apps

greptile-apps Bot commented Nov 8, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerTREX TREX

Tested 1 flow, found no issues.

What we tested

  • Pass · Read and edit ignore files while watching · View ↗

Took 2 attempts. TREX adjusted its test setup between them.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 8, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-08T00:18:02.109111Z ad8ebb7 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@coderabbitai

coderabbitai Bot commented Nov 8, 2026 •

Copy link
Copy Markdown

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

The watcher now filters filesystem events by event type and configured input paths before reloading ignore rules. New tests cover read events, relevant changes, index replacement, and Linux observer behavior.

Changes: Ignore-rule reload filtering

Layer / File(s) Summary
Define rule-input event types
codebase_rag/constants/core.py
Adds RULE_INPUT_EVENT_TYPES, combining content events with moved and closed events.
Filter reloads and test watcher behavior
codebase_rag/watch.py, codebase_rag/tests/test_watcher_ignore_rule_reads.py
The watcher reloads ignore rules only when an eligible event involves a configured input. Tests cover reads, changes, index replacement, and a Linux observer.

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium

Suggested reviewers: claude

Merge Risk: Minimal · up to ad8eb

The change prevents read-triggered ignore-rule reloads while preserving reloads for relevant file changes. No actionable merge-blocking issue remains; merge after normal checks.

Pre-merge checks: Passed 4

Check name Status Explanation
Title check Passed The title "fix(watch): stop re-reading the ignore rules on a read of their files" is a Conventional Commits title that matches the main change. The PR makes the watcher reload ignore rules only on wri…
Linked Issues check Passed Issue #3583 has one direct coding objective group. Its requirements are: (a) reads of .gitignore, .cgrignore, or .git/index must not trigger ignore-rule reloads; (b) ignore-rule changes must still tri…
Out of Scope Changes check Passed The whole-PR diff against the merge base changes three files, and each serves issue #3583.

1. codebase_rag/constants/core.py: adds RULE_INPUT_EVENT_TYPES. It defines the event types that can change a…
Description check Passed The description covers the required sections well. It gives a clear Summary that explains the bug (ignore-rule reloads triggered by reads, causing a loop on Linux) and the fix (reload only on write, c…
Full details: Title check

Explanation

The title "fix(watch): stop re-reading the ignore rules on a read of their files" is a Conventional Commits title that matches the main change. The PR makes the watcher reload ignore rules only on write, create, delete, or rename events, not on reads. The title names the bug fix and the affected component (watch) and the trigger (read events), so it is specific and accurate.

Full details: Linked Issues check

Explanation

Issue #3583 has one direct coding objective group. Its requirements are: (a) reads of .gitignore, .cgrignore, or .git/index must not trigger ignore-rule reloads; (b) ignore-rule changes must still trigger reloads; (c) source monitoring must continue without excess processing or logging.

(a) Implemented. In codebase_rag/watch.py, _follow_ignore_rules now calls _apply_ignore_rules only when event.event_type is in RULE_INPUT_EVENT_TYPES. RULE_INPUT_EVENT_TYPES (codebase_rag/constants/core.py) is CONTENT_EVENT_TYPES (modified, created, deleted) plus MOVED and CLOSED. EventType.CLOSED is "closed", the close-after-write event. Read events ("opened", "closed_no_write") are excluded, so a read no longer starts a reload. Reloading only reads the files, so the reload loop is broken.

(b) Implemented. Edits (modified), creations, deletions, close-after-write, and renames (MOVED, including index.lock onto index, which git status and git add use) still reload when the path is in rules.inputs. The tests in codebase_rag/tests/test_watcher_ignore_rule_reads.py cover these cases.

(c) Unchanged. The return value of _follow_ignore_rules is unchanged, so non-ignore source events still follow the same path. Only the reload decision changed.

Tests: parametrized tests cover reads (zero reloads) and changes (one reload) for each input. A Linux end-to-end test uses the real observer and checks that one read of .gitignore causes no loads. I did not run the test suite. The PR reports 212 passed and 25 skipped for the watcher suites. The code evidence supports the requirements.

Not assessed: the issue's SQLite backend note is informational, not a coding requirement.

Full details: Out of Scope Changes check

Explanation

The whole-PR diff against the merge base changes three files, and each serves issue #3583.

  1. codebase_rag/constants/core.py: adds RULE_INPUT_EVENT_TYPES. It defines the event types that can change an ignore rule's input. Its comment explains the link to #3583.
  2. codebase_rag/watch.py: imports RULE_INPUT_EVENT_TYPES and gates the reload in _follow_ignore_rules on it. The docstring is updated to match. No other logic changes.
  3. codebase_rag/tests/test_watcher_ignore_rule_reads.py: new tests for the reload behavior described in the issue. These support the change and are not unrelated.

No unrelated files or behavior changes appear in the reviewed diff. The PR description's demo and checklist items are documentation of the change, not code changes.

Full details: Description check

Explanation

The description covers the required sections well. It gives a clear Summary that explains the bug (ignore-rule reloads triggered by reads, causing a loop on Linux) and the fix (reload only on write, create, delete, or rename events via RULE_INPUT_EVENT_TYPES). It includes a Demo with before and after reproduction output, which fits the template's guidance for changes that cannot be shown as a VHS GIF. The Type of Change is marked as Bug fix, Related Issues links Fixes #3583, and the Test Plan lists new tests and manual testing. The Checklist is filled in. Gaps: the unit-test box is unchecked, and the author states only watcher suites were run (212 passed, 25 skipped), not the full suite. The author also says the ty check failure is local and unrelated. The breaking-change item is checked with a note that it is not breaking, which is acceptable. Overall the description is mostly complete.

Finishing Touches

Generate docstrings

  • Commit to this branch
  • Create a new PR
Generate unit tests (beta)

  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

Recent review info

Run configuration

Commits

Reviewing files that changed from the base of the PR and between 3f3866e and ad8ebb7.

Files selected for processing: 3

  • codebase_rag/constants/core.py
  • codebase_rag/tests/test_watcher_ignore_rule_reads.py
  • codebase_rag/watch.py

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.

@greptile-apps

greptile-apps Bot commented Nov 8, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Low impact] The PR appears safe to merge.

Summary

Stops read-only events from reloading the ignore rules in cgr watch.

  • The watcher reloads ignore rules only when their inputs change.

Reviews (1) · Last reviewed commit: "fix(watch): stop re-reading the ignore r..." · Reviewed by Greptile

@sonarqubecloud

sonarqubecloud Bot commented Nov 8, 2026

Copy link
Copy Markdown

@vitali87
vitali87 merged commit fe1a1d3 into main Nov 8, 2026
47 checks passed
@vitali87
vitali87 deleted the ccr-9f6abec3-i33uiv branch November 8, 2026 01:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

[Bug]:

1 participant