Skip to content

fix: honor include-submodules across incremental updates and upgrades#381

Merged
RaghavChamadiya merged 2 commits into
mainfrom
fix/update-path-submodule-flags
Jun 5, 2026
Merged

fix: honor include-submodules across incremental updates and upgrades#381
RaghavChamadiya merged 2 commits into
mainfrom
fix/update-path-submodule-flags

Conversation

@RaghavChamadiya
Copy link
Copy Markdown
Member

@RaghavChamadiya RaghavChamadiya commented Jun 5, 2026

Summary

Two follow-ups from the pruned-resolver-scans work (#380):

1. repowise update ignored submodule/nested-repo flags

A repo indexed with init --include-submodules silently dropped its submodule files (and their manifests) on every incremental update: the update path constructed FileTraverser and GraphBuilder with default flags, so the update''s metadata diverged from what a fresh init would produce. Same class of bug as the git_tier gap fixed in #369 — and fixed with the same pattern:

  • init now persists include_submodules into .repowise/state.json (both the index-only base_state write and save_full_state_and_config; the interactive advanced-config reassignment lands before both writes).
  • update reads it back (missing key → False, legacy behavior) and threads it through _rebuild_graph_and_git_build_repo_graph into both constructors — covering the incremental rebuild and the config-triggered health re-score.
  • upgrade_to_full''s docs re-parse (upgrade_flow._reparse) honors the persisted flags too.

2. --include-submodules was defeated for initialized submodules

Pre-existing traverser bug, confirmed: .gitmodules was only parsed when include_submodules=False, so with the flag on the submodule set was empty and an initialized submodule — whose .git file makes _is_nested_git_repo true — fell through to the nested-git boundary skip and was dropped anyway. The flag only ever worked for uninitialized submodules, which contain no files.

Fix: parse .gitmodules unconditionally and exempt opted-in submodules from the nested-git skip, while:

  • still applying gitignore/.repowiseIgnore/exclude checks to included submodules,
  • still skipping non-submodule nested repos (the opt-in does not widen),
  • keeping the default path byte-for-byte legacy-equivalent (skip order, stats counters).

_detect_monorepo''s package scans now mirror GraphBuilder._prune_nested_git (not (include_submodules or include_nested_repos)) so traversal, package detection, and resolver scans agree.

Testing

  • New tests/unit/cli/test_update_include_submodules.py mirrors the perf: cache parsing and betweenness across incremental updates #369 tier test: update-built graph keeps libs/sub/mod.py with the flag, drops it without (legacy fallback).
  • New traverser regression tests cover an initialized submodule (.git file) with the flag on/off, and confirm sibling nested repos stay skipped.
  • 445 CLI + 956 ingestion (+2 xfail) unit tests pass. Ruff clean on changed lines (remaining findings in touched files are pre-existing, untouched).

Follow-up (out of scope)

Standalone repowise health / repowise dead-code build flagless traversers on already-indexed repos — same inconsistency class, read-only impact; to be addressed separately along with routing workspace updates through the incremental path.

@RaghavChamadiya RaghavChamadiya requested a review from swati510 as a code owner June 5, 2026 10:27
@repowise-bot
Copy link
Copy Markdown

repowise-bot Bot commented Jun 5, 2026

✅ Health: 7.0 (unchanged)
5 hotspots · 5 hidden couplings · 4 with fix history

⚠️ Change risk: moderate (riskier than 48% of this repo's commits · raw 8.6/10)
This change's risk is driven by:

  • large diff (many lines added)
  • scattered, high-entropy change

🩹 Review priority (files here with the most recent bug-fix history — defects cluster, so review these first)

🔥 Hotspots touched (5)
  • .../commands/update_cmd.py — 36 commits/90d, 11 dependents · primary owner: Raghav Chamadiya (66%)
  • .../init_cmd/command.py — 4 commits/90d, 1 dependents · primary owner: Raghav Chamadiya (98%)
  • .../ingestion/traverser.py — 8 commits/90d, 5 dependents · primary owner: Raghav Chamadiya (96%)
2 more
  • .../commands/upgrade_flow.py — 4 commits/90d, 1 dependents · primary owner: Raghav Chamadiya (100%)
  • .../ingestion/test_traverser.py — 7 commits/90d, 1 dependents · primary owner: Raghav Chamadiya (98%)
🔗 Hidden coupling (1 file)
  • .../commands/update_cmd.py co-changes with these files (not in this PR):
    • .../pipeline/orchestrator.py (8× — 🟢 routine)
    • .../cli/helpers.py (8× — 🟢 routine)
    • .../persistence/models.py (6× — 🟢 routine)
    • .../cli/test_commands.py (6× — 🟢 routine)
    • .../cli/test_helpers.py (5× — 🟢 routine)

📊 Full report · ⭐ Star Repowise · 📥 Install bot · Last updated 2026-06-05 10:33 UTC
Silence on a single PR with [skip repowise] in the title · Per-repo toggle on repowise.dev/settings?tab=bot

Two related gaps following the pruned-resolver-scans work (#380):

1. `repowise update` ignored submodule/nested-repo flags: the update
   path constructed FileTraverser and GraphBuilder with defaults, so a
   repo indexed with `init --include-submodules` silently dropped its
   submodule files on every incremental update. The flag is now
   persisted to state.json at init (same pattern as git_tier) and read
   back in update_cmd, threaded through _rebuild_graph_and_git /
   _build_repo_graph into both constructors (incremental rebuild and
   the config-triggered health re-score). Missing keys keep legacy
   behavior (False).

2. `--include-submodules` was defeated for *initialized* submodules:
   `.gitmodules` was only parsed when the flag was off, so an
   initialized submodule (whose `.git` file makes it look like a
   nested repo) fell through to the nested-git boundary skip and was
   dropped anyway. The traverser now parses `.gitmodules`
   unconditionally and exempts opted-in submodules from the nested-git
   skip — while still applying gitignore/exclude checks and still
   skipping non-submodule nested repos. _detect_monorepo package scans
   now mirror GraphBuilder._prune_nested_git semantics.
upgrade_to_full re-parses the repo for doc generation via _reparse,
which constructed FileTraverser without the submodule flags — a fast
index built with --include-submodules would drop submodule files from
the ASTs/source fed to generation. Read the persisted state.json flags
there too (missing -> False).
@swati510 swati510 force-pushed the fix/update-path-submodule-flags branch from b609299 to 1bc8cf5 Compare June 5, 2026 10:33
@RaghavChamadiya RaghavChamadiya merged commit 93764d6 into main Jun 5, 2026
5 checks passed
@RaghavChamadiya RaghavChamadiya deleted the fix/update-path-submodule-flags branch June 5, 2026 10:36
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.

2 participants