Skip to content

Submodule-aware watcher and git status optimization#120

Merged
actionshrimp merged 3 commits intomainfrom
feature/submodule-aware-watcher
Feb 28, 2026
Merged

Submodule-aware watcher and git status optimization#120
actionshrimp merged 3 commits intomainfrom
feature/submodule-aware-watcher

Conversation

@actionshrimp
Copy link
Owner

Summary

  • Fix gitignore cache for nested paths — the recursive worktree watcher reports paths like build/output.o, but the cache only stores top-level entries like build. Now extracts the first path component before checking the cache. Also fixes .git skip for nested .git/ paths.
  • Submodule path detection with separate debounce — parses .gitmodules at watcher start to build a submodule path cache, then routes submodule file events through a separate debouncer with a longer timeout (default 5s vs 200ms). Prevents build activity and IDE indexing in submodule directories from causing constant stale indicator churn.
  • git.ignore_submodules config option — passes --ignore-submodules to git status, making refreshes dramatically faster in repos with many submodules. Supports false (default), "dirty", "untracked", and "all".

Test plan

  • 15 new unit tests for _is_gitignored, _is_submodule_path, and submodule debouncer
  • 12 new E2E tests for config passthrough, submodule cache building, and --ignore-submodules behavior
  • Full test suite passes (337 tests across 32 suites)
  • Manual test in a large monorepo with submodules: configure git = { ignore_submodules = "dirty" }, verify fast status and reduced watcher churn

The recursive worktree watcher reports nested paths like "build/output.o",
but the gitignore cache only stores top-level entries like "build". This
caused all nested file events in gitignored directories to bypass the
cache filter, triggering unnecessary stale indicators.

Changes:
- Extract first path component from nested paths before checking cache
- Fix .git skip to also catch nested .git/ paths (e.g., .git/objects)
- Add _is_gitignored() method with unit tests for top-level, nested,
  prefix-similar, and empty cache scenarios
In repos with many submodules, build activity and IDE indexing inside
submodule directories triggers constant watcher events, causing the
stale indicator to flash repeatedly.

This routes submodule file events through a separate debouncer with a
longer timeout (default 5000ms), so submodule churn doesn't interfere
with normal workflow responsiveness.

Changes:
- Parse .gitmodules at watcher start to build submodule path cache
- Add _is_submodule_path() to detect files within submodule directories
- Route submodule events to _handle_submodule_event() with separate debouncer
- Rebuild submodule cache when .gitmodules changes
- Add submodule_debounce_ms config option (default 5000ms)
- Pass config through status.lua to watcher constructor
@actionshrimp actionshrimp force-pushed the feature/submodule-aware-watcher branch from 2124134 to 126ba0b Compare February 28, 2026 21:58
In repos with many submodules, `git status` recursively checks each
submodule's working tree, which can be very slow. This adds a config
option to pass --ignore-submodules to git status.

Usage:
  require("gitlad").setup({
    git = { ignore_submodules = "dirty" }
  })

Values: false (default), "dirty", "untracked", "all"

With "dirty", submodules with only working tree changes are hidden from
status while submodules with changed HEAD commit remain visible. The
submodules section (via `git submodule status`) is unaffected.
@actionshrimp actionshrimp force-pushed the feature/submodule-aware-watcher branch from 126ba0b to 5ad6d66 Compare February 28, 2026 22:00
@actionshrimp actionshrimp merged commit cb67b2e into main Feb 28, 2026
3 checks passed
@actionshrimp actionshrimp deleted the feature/submodule-aware-watcher branch February 28, 2026 22:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant