Skip to content

fix: filter gitignored directories from inotify recursive watches#12114

Draft
warp-dev-github-integration[bot] wants to merge 1 commit into
masterfrom
fix/inotify-watch-gitignore-filtering
Draft

fix: filter gitignored directories from inotify recursive watches#12114
warp-dev-github-integration[bot] wants to merge 1 commit into
masterfrom
fix/inotify-watch-gitignore-filtering

Conversation

@warp-dev-github-integration
Copy link
Copy Markdown

@warp-dev-github-integration warp-dev-github-integration Bot commented Jun 3, 2026

Description

Fix excessive memory usage (11+ GB) caused by inotify registering watches on gitignored directory trees (e.g. node_modules/, target/).

Root cause: repo_watch_filter() only pruned .git/ internal directories from the recursive walk, but did not skip gitignored directories. When watching a repository recursively on Linux, inotify creates a watch on every subdirectory. For projects with large ignored trees, the notify crate's internal HashMap<PathBuf, (WatchDescriptor, WatchMask, ...)> grew to ~3 GB from rehashing, and Vec<u8>::clone during rehashing consumed ~8 GB.

Heap profile evidence (Sentry event 82189ab726af469a990bbe20819b78ca):

  • 11.23 GB total in-use
  • 98.48% (11.05 GB) from notify::inotify::EventLoop::add_watchadd_single_watch
  • 71.66% (8.04 GB) from Vec<u8>::clone (HashMap buffer rehashing)
  • 26.73% (3 GB) from hashbrown::raw::RawTable::reserve_rehash

Fix:

  1. Add repo_watch_filter_with_gitignores() that combines the existing .git/ filtering with gitignore-based directory pruning in the descend predicate. This follows the pattern already used by the codebase indexer (CodebaseIndexManager::watch_path).
  2. Update DirectoryWatcher::start_watching_directory() and LocalRepoMetadataModel::add_repository_internal() to load root-level gitignore rules and use the new filter.
  3. Fix FileModel::register_file_path() and fallback_to_individual_watchers() to use NonRecursive mode on the parent directory (matching open()'s existing correct behavior) instead of Recursive on the file path.

Linked Issue

Testing

  • Verified cargo check and cargo clippy pass for repo_metadata and warp_files.
  • The fix is structural: gitignored directories are pruned from the inotify recursive walk, preventing watch registration on those subtrees. This directly addresses the allocation sites shown in the heap profile.

Agent Mode

  • Warp Agent Mode - This PR was created via Warp's AI Agent Mode

Conversation: https://staging.warp.dev/conversation/cba99240-32b8-48ea-a4f4-c74fe5ae592c
Run: https://oz.staging.warp.dev/runs/019e8db0-eeaf-7b89-81bf-181eae1835e7

This PR was generated with Oz.

@cla-bot cla-bot Bot added the cla-signed label Jun 3, 2026
The repo_watch_filter() used by repository and metadata watchers only
pruned .git/ internal directories but did not skip gitignored
directories (node_modules/, target/, etc.). When watching a repository
recursively, inotify registers watches on every subdirectory — for
projects with large ignored trees this consumed 11+ GB of memory from
HashMap growth and rehashing in the notify crate's EventLoop.

Changes:
- Add repo_watch_filter_with_gitignores() that combines git-internal
  path filtering with gitignore-based directory pruning in the descend
  predicate, following the pattern already used by the codebase indexer.
- Update DirectoryWatcher::start_watching_directory() and
  LocalRepoMetadataModel::add_repository_internal() to load root-level
  gitignore rules and pass them to the new filter.
- Fix FileModel::register_file_path() and fallback_to_individual_watchers()
  to use NonRecursive mode on the parent directory (matching open()'s
  existing correct behavior) instead of Recursive on the file path.

Co-Authored-By: Oz <oz-agent@warp.dev>
@warp-dev-github-integration warp-dev-github-integration Bot force-pushed the fix/inotify-watch-gitignore-filtering branch from 56894c1 to cf3ee43 Compare June 3, 2026 13:45
@warp-dev-github-integration warp-dev-github-integration Bot changed the title fix: skip gitignored directories in inotify watch registration fix: filter gitignored directories from inotify recursive watches Jun 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant