security-guidance: git status -uall walks every submodule, ~73s per call in a 66-submodule repo

Status Open
Reported on v2.1.286
Maintainer reply None cached
Activity 2 comments · opened Oct 1, 2026

Summary

security-guidance's gitutil._git_status_porcelain runs git status --porcelain=v1 -uall -z with no --ignore-submodules flag. In a repo with many nested submodules, each call takes over a minute, and the plugin runs it on every UserPromptSubmit, every Edit/Write/MultiEdit/NotebookEdit (PostToolUse) and every Stop/SubagentStop, in every open session.

Environment

  • Claude Code: 2.1.286
  • security-guidance: 2.0.8 (claude-plugins-official)
  • Provider: 1P (claude.ai login)
  • OS: Windows 11, git for Windows, NVMe SSD
  • Repo: private, 66 nested submodule mounts (several repos are mounted more than once at different depths)

Repro

In any repo with dozens of initialized submodules, time the plugin's command against the same command with --ignore-submodules=dirty:

git status --porcelain=v1 -uall -z                            ~73,000 ms
git status --porcelain=v1 -uall -z --ignore-submodules=dirty     ~200 ms

(Measured with git status --porcelain=v2 --branch variants in the same repo: 73,652 ms default vs 227 ms with --ignore-submodules=dirty.)

Impact

  • subprocess.run(..., timeout=30) kills git.exe but on Windows not its per-submodule child processes, so each call keeps walking the tree after the timeout and the hook gets no result.
  • With 4 or 5 sessions open in the repo, these calls overlap and pile up. They competed with other git work on the same disk: a git worktree add that takes about 175 s on a quiet machine took 495 s with sessions open.

Suggested fix

Add --ignore-submodules=dirty to the status call in gitutil._git_status_porcelain (and any sibling status/diff calls). A submodule whose checked-out commit differs from the recorded gitlink still shows as modified, which is the only submodule change a superproject commit can contain. Only uncommitted edits and untracked files inside submodules are skipped, and the review's diff does not descend into submodules anyway.

The same one-flag fix was accepted upstream in the wmux terminal for its pane git-status badge, for the same repo.

Workaround

Disable the plugin per repo with "enabledPlugins": { "security-guidance@claude-plugins-official": false } in .claude/settings.local.json.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗