Skip to content

SCM - keep previously hidden repositories hidden when they are discovered late - #348396

Draft
Ladislau Szomoru (lszomoru) wants to merge 2 commits into
mainfrom
lszomoru/agents/fix-scm-submodule-selection-bug
Draft

Ladislau Szomoru (lszomoru) wants to merge 2 commits into
mainfrom
lszomoru/agents/fix-scm-submodule-selection-bug

Conversation

@lszomoru

Copy link
Copy Markdown
Member

Fixes #265510

Repro steps

  1. Create a repository with two submodules nested below the repository root (e.g. deps/sub1, deps/sub2), so that they are found through submodule detection rather than the workspace folder scan (git.repositoryScanMaxDepth).
  2. Open the folder with the default settings (scm.repositories.selectionMode: multiple, git.detectSubmodules: true) and show the Repositories view.
  3. Select only the parent repository (deselect the submodules).
  4. Run Developer: Reload Window.
  5. 🐛 Once the submodules are discovered, they are selected again (visible in the Changes view).

The submodules are only opened after the parent repository's first git status finishes. With large repositories (or many repositories, as in the issue's recording) that takes longer than the 5s after which the SCM view considers the repositories "finished loading".

Root cause

SCMViewService.onDidAddRepository only consults the persisted scm:view:visibleRepositories state while didFinishLoadingRepositories is false. That flag flips 5s after the last repository was added. Any repository added after that point (late submodules) skips the persisted state. In multiple selection mode it is then always made visible, even if the user explicitly hid it in the previous session.

Fix

When a repository is added after loading has finished, keep it hidden if:

  • the previous state restored an explicit selection (didSelectRepository) and at least one repository is visible, and
  • the repository is part of the previous state (all) but was not visible.

This leaves the other cases unchanged:

  • Brand-new repositories that are not in the previous state still become visible, so the first-run default is the same.
  • Workspaces without a persisted state behave as before.
  • Single selection mode behaves as before: with a repository already visible, a newly added repository was already added unselected.

Validation

Command Result
pnpm run typecheck-client ✅ Passed
pnpm run oxlint src/vs/workbench/contrib/scm/browser/scmViewService.ts src/vs/workbench/contrib/scm/test/browser/scmViewService.test.ts ✅ Passed (no issues)
./scripts/test.sh --run src/vs/workbench/contrib/scm/test/browser/scmViewService.test.ts ✅ 2 passing
Same test with the scmViewService.ts change reverted ❌ Fails as expected: parent/submodule is visible again

The git extension is unchanged.

Evidence

I recorded the repro steps above with the validate-ui-scenario harness on a Code OSS dev build (macOS, throwaway profile, scratch repository), once with the fix reverted and once with the fix. To make the timing deterministic, a git wrapper on PATH delays git status in the parent repository by 8s. In both runs the Git log shows the submodules opened about 9s after the parent, both before and after the reload.

  • Before (without fix): after the reload, the Repositories view shows ws, sub1 and sub2 all selected, and the Changes view lists all three repositories. The scenario's final assertion fails.
  • After (with fix): after the reload, only ws is selected, sub1 and sub2 stay deselected, and the Changes view only shows ws. All steps pass.

A side-by-side video (before on the left, after on the right, aligned by step) and before/after screenshots of the moment after the reload are available on request. gh cannot attach them here.

Repositories (ex: submodules) that are discovered after the SCM view finished
restoring its state were always made visible, even if the user had explicitly
hidden them in the previous session.

Fixes #265510

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings November 15, 2026 10:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

A routine storage flush can discard a saved hidden state for an undiscovered submodule, causing it to be selected when registered later; the state must be preserved and covered by a regression test.

1 open issue
What changed in this PR

This PR updates SCM selection restoration to keep previously deselected repositories hidden when discovery occurs after the initial loading window, addressing late submodule discovery in #265510.

Changes:

  • Consults saved selection state for late-discovered repositories while preserving visibility for new repositories.
  • Adds a regression test covering a late hidden submodule and a newly discovered repository.
File Description
src/​vs/​workbench/​contrib/​scm/​test/​browser/​scmViewService.test.ts Tests late-discovery selection behavior using fake timers.
src/​vs/​workbench/​contrib/​scm/​browser/​scmViewService.ts Applies saved hidden state after the loading window ends.

Review effort: Balanced

…shes

`onWillSaveState()` replaced the in-memory previous state with only the
registered repositories, so a routine storage flush before a submodule was
discovered lost its saved (hidden) visibility. Keep the previous visibility
of repositories that have not been discovered yet in memory, and extend the
test to cover a storage flush before the late repository is added.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

This branch has not been deployed

No deployments
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.

Submodule auto selected every time

2 participants