Skip to content

Git - respect configured submodule names in SCM - #269902

Open
Tci Gravifer Fang (Gravifer) wants to merge 9 commits into
microsoft:mainfrom
Gravifer:patch-1
Open

Git - respect configured submodule names in SCM#269902
Tci Gravifer Fang (Gravifer) wants to merge 9 commits into
microsoft:mainfrom
Gravifer:patch-1

Conversation

@Gravifer

@Gravifer Tci Gravifer Fang (Gravifer) commented Oct 5, 2025

Copy link
Copy Markdown

Summary

  • respect customized submodule names from the superproject's .gitmodules throughout SCM UI
  • add a creation-time repository name to the proposed scmProviderOptions API
  • preserve existing workspace-folder and basename behavior for ordinary repositories, worktrees, generated submodule names, and independently opened submodules
  • use the same resolved name in the built-in Git repository picker

Addresses #269812

Behavior

A submodule discovered through an open superproject uses its configured name only when that name differs from its path. The explicit name flows into ISCMProvider.name, so the repositories tree, active repository status, SCM and history pickers, accessibility text, and Git repository picker remain consistent. Opening the submodule independently retains the current behavior.

Validation

  • npm run typecheck-client
  • npm run gulp compile-extension:git
  • npm run valid-layers-check
  • git diff --check upstream/main...HEAD

The full compile-extensions command was also attempted; it stopped in the unrelated CSS language extension because that extension's separate Node typings were not installed in this clone. Focused core and Git test launchers could not start because the local .build/electron test runtime is absent.

@Gravifer

This comment was marked as resolved.

@Gravifer

This comment was marked as outdated.

@Gravifer

This comment was marked as outdated.

@Gravifer
Tci Gravifer Fang (Gravifer) marked this pull request as ready for review October 5, 2025 14:03
Copilot AI review requested due to automatic review settings October 5, 2025 14:03

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.

Pull Request Overview

This PR introduces the ability to use custom labels for repositories in the Source Control Management (SCM) panel instead of always using the root directory name. The changes focus on allowing repository labels to be specified, particularly useful for submodules which can now display their meaningful names from .gitmodules instead of just their directory names.

Key changes:

  • Added support for optional repository labels that override the default root directory basename
  • Modified the label resolution logic to prefer supplied labels while falling back to directory names
  • Updated submodule handling to use submodule names as repository labels

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
extensions/git/src/repository.ts Adds getter for accessing repository label property
extensions/git/src/model.ts Updates label logic to use custom labels and modifies repository tracking to support labels
extensions/git/src/git.ts Adds label parameter to Repository constructor and open method

Comment thread extensions/git/src/model.ts Outdated
Comment thread extensions/git/src/git.ts Outdated
Comment thread extensions/git/src/model.ts Outdated
@Gravifer Tci Gravifer Fang (Gravifer) changed the title [WIP] [extensions/git] Custom repo label in SVM panel other than root dirname [extensions/git] Custom repo label in SVM panel other than root dirname Oct 6, 2025
@Gravifer Tci Gravifer Fang (Gravifer) changed the title [extensions/git] Custom repo label in SVM panel other than root dirname (help wanted) [extensions/git] Custom repo label in SVM panel other than root dirname Oct 18, 2025

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.

Pull Request Overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

Comment thread extensions/git/src/git.ts Outdated
Comment thread extensions/git/src/model.ts Outdated
@vs-code-engineering

vs-code-engineering Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

📬 CODENOTIFY

The following users are being notified based on files changed in this PR:

Ladislau Szomoru (@lszomoru)

Matched files:

  • extensions/git/src/git.ts
  • extensions/git/src/model.ts
  • extensions/git/src/repository.ts
  • extensions/git/src/test/git.test.ts
  • src/vs/workbench/contrib/scm/browser/scmRepositoryRenderer.ts
  • src/vs/workbench/contrib/scm/browser/scmViewService.ts
  • src/vs/workbench/contrib/scm/test/browser/scmViewService.test.ts

@Gravifer Tci Gravifer Fang (Gravifer) changed the title (help wanted) [extensions/git] Custom repo label in SVM panel other than root dirname Git - respect configured submodule names in SCM Jul 14, 2026
@Gravifer

Tci Gravifer Fang (Gravifer) commented Jul 14, 2026

Copy link
Copy Markdown
Author

I have substantially revised the approach taken.

My original attempt carried an optional label through the repository scan queue, Model.openRepository, Git.open, and the low-level Git repository object. That label was then used only by the Git extension’s repository quick picker. Besides changing several unrelated method signatures, this produced an incomplete result: the picker could show the configured submodule name while the persistent SCM tree, status bar, history views, accessibility text, and other SCM surfaces continued to show the directory name. The result could also depend on repository discovery order.

The branch tip removes that plumbing. Instead, it adds an optional, creation-time repository name to the existing proposed scmProviderOptions API. The name is transported through the extension host and assigned to the core ISCMProvider.name. This is the value the workbench already uses throughout its SCM user interface, so the change applies consistently without modifying each renderer or view individually.

The Git extension now determines the name at the point where it creates the child repository’s source control. If the child is a submodule, its superproject is open, and the matching .gitmodules entry has a logical name different from its path, that configured name is supplied to SCM core. Git’s own repository picker uses the same resolved value.

This yields deliberately contextual behavior:

  • A submodule discovered through its superproject uses the customized .gitmodules name.
  • A submodule created while its matching superproject is not open retains the existing workspace-folder or directory name.
  • A normal, automatically generated submodule name—where name === path—does not override existing behavior.
  • Ordinary repositories and worktrees are unaffected.

I think this distinction is useful. When a repository is opened independently, its folder or workspace name is the most immediate identity available to the user. When it is discovered as part of a superproject, however, the superproject’s .gitmodules file supplies an intentional logical identity. That identity can be much more informative than the final path segment, particularly for deeply nested submodules or layouts where the directory name is generic. The logic is also consistent across the repository tree, status and history surfaces, SCM pickers, accessibility output, and the Git picker.

A customized submodule name takes precedence over a workspace-folder alias when the child is created while its superproject is open and resolvable. This avoids returning to the earlier split behavior, where different SCM surfaces could disagree about the same repository. Existing SCM rendering already handles duplicate names by showing parent and path context where necessary, so no new disambiguation mechanism is required.

The implementation is intentionally narrow from a maintenance perspective. It does not alter the stable extension API, add a setting, create persistent state, introduce a migration, or require dynamic rename events. The proposed API gains one optional final argument; callers that omit it retain the current workspace-folder, basename, and provider-label fallbacks. No existing extension needs to change.

Likewise, the workbench renderers are untouched. They already consume ISCMProvider.name, so the new value flows naturally to the existing UI. The Git-side lookup happens once during repository creation, uses submodule information that has already been parsed, and does not start additional Git processes or watchers. The earlier changes to the scan queue and low-level Git abstraction have been removed.

I hope this would not introduce much burden for the maintainers or become obstructive for future contributors. Thanks to you all for the excellent project that benefits all developers.

@Gravifer
Tci Gravifer Fang (Gravifer) force-pushed the patch-1 branch 5 times, most recently from 4ed8279 to efb78c8 Compare July 22, 2026 04:02
@Gravifer

Tci Gravifer Fang (Gravifer) commented Jul 22, 2026

Copy link
Copy Markdown
Author

Hi Ladislau Szomoru (@lszomoru) — when you have a chance, would you mind taking a look at the revised approach? The PR now routes repository display names through SCM core and removes the original Git-specific discovery plumbing. I’d particularly appreciate feedback on whether this direction fits the SCM API. No rush, and thank you for your time.

CodeRabbit (@coderabbitai) Copilot can you initiate reviews as well? Perhaps focus on whether there are potential drawbacks to this.


I'm force pushing to make rebases from time to time. The material commits are:

  • feat(scm): declare repository display names [wip] [no-ci]
  • feat(scm): transport repository display names [wip] [no-ci]
  • feat(scm): apply repository display names
  • feat(git): select customized submodule names
  • feat(git): name parent-detected submodules
  • feat(git): align repository picker names
    With moving SHAs.

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.

Pull request overview

Copilot reviewed 9 out of 10 changed files in this pull request and generated no new comments.

@Gravifer

Copy link
Copy Markdown
Author

Quoting the Copilot updated overview here

Extends SCM naming so Git submodules display customized .gitmodules names consistently while preserving existing fallback behavior.

Changes:

  • Adds an optional creation-time repository name to the proposed SCM API and RPC flow.
  • Resolves customized submodule names for SCM providers and Git repository picks.
  • Adds coverage for name resolution and forwarding.

Reviewed Changes

File Description
src/vscode-dts/vscode.proposed.scmProviderOptions.d.ts Adds the optional SCM repository name API.
src/vs/workbench/api/test/common/extHostSCM.test.ts Tests name forwarding.
src/vs/workbench/api/common/extHostSCM.ts Passes names through the extension host.
src/vs/workbench/api/common/extHost.protocol.ts Extends the SCM registration protocol.
src/vs/workbench/api/common/extHost.api.impl.ts Exposes and proposal-gates the new argument.
src/vs/workbench/api/browser/mainThreadSCM.ts Applies explicit names with existing fallbacks.
extensions/git/src/test/git.test.ts Tests customized-name resolution.
extensions/git/src/repository.ts Resolves and registers submodule names.
extensions/git/src/model.ts Uses resolved names in repository picks.
extensions/git/src/git.ts Adds the submodule display-name helper.

@Gravifer Tci Gravifer Fang (Gravifer) left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Minor follow-up from local validation

For example:

Configured name Root basename Displayed label
zebra alpha parent / zebra
apple zulu parent / apple

The current implementation displays zebra and apple, but sorts using alpha and zulu. Selecting “Sort by Name” could therefore produce:

parent / zebra
parent / apple

The PR already makes the explicit name authoritative while preserving the existing workspace-folder, basename, and provider-label fallbacks.

I am going to try a small follow-up correction that sorts by the displayed provider name:

const nameComparison = compareFileNames(
	op1.repository.provider.name,
	op2.repository.provider.name
);

The existing path tie-breaker and locale-aware comparator would remain unchanged.

I think this is justified within the PR because customized names would otherwise be displayed correctly but behave unexpectedly under the existing “Sort by Name” option. For callers that do not supply an explicit name, provider.name already resolves through the current fallbacks, so ordinary repositories should retain their existing ordering.

I do not plan to modify the pre-existing comparer tests. Their initial local failures came from the direct Electron test host inheriting zh-CN; all 51 relevant tests passed when the host was run with en-US. That appears separate from this small SCM sort-key adjustment.

Comment thread src/vs/workbench/contrib/scm/browser/scmRepositoryRenderer.ts
Comment thread src/vs/workbench/contrib/scm/browser/scmViewService.ts
Comment thread src/vs/workbench/contrib/scm/browser/scmViewService.ts Outdated
@Gravifer

Copy link
Copy Markdown
Author

I have pushed the follow-up correction discussed above.

  • 2b68636 synchronizes the SCM transport test with the asynchronous RPC protocol before asserting registration and after disposal.
  • e4e1568 makes “Sort by Name” use the same canonical ISCMProvider.name displayed by the workbench. The existing locale-aware comparator and root-path tie-breaker remain unchanged.

https://github.com/Gravifer/microsoft.vscode/blob/e4e1568/src/vs/workbench/contrib/scm/browser/scmViewService.ts#L520-L529

The new regression test deliberately opposes provider names and root basenames, while giving two repositories the same provider name in reverse path order. It therefore verifies both that the displayed name controls sorting and that the existing path tie-breaker is preserved.

https://github.com/Gravifer/microsoft.vscode/blob/e4e1568/src/vs/workbench/contrib/scm/test/browser/scmViewService.test.ts#L36-L77

The transport test now explicitly waits for the test RPC queue:

https://github.com/Gravifer/microsoft.vscode/blob/2b68636/src/vs/workbench/api/test/common/extHostSCM.test.ts#L56-L100

Local validation included:

  • typecheck-client: passed
  • Targeted ESLint: passed
  • Client esbuild transpilation: passed
  • Focused SCMViewService suite: 2 passing
  • Focused ExtHostSCM suite: 3 passing
  • Full Git integration suite: 59 passing
  • Broad Electron suite: 27,898 passing, 453 pending, 11 failing

None of the 11 Electron failures involved Git or SCM, and all occurred in source/test files byte-identical to upstream main. Their symptoms were environment-sensitive: Windows environment-variable assumptions, loopback tests interacting with the local proxy, a localized Kerberos error string, display-scale-dependent measurement, and timeouts. I stopped rather than modifying or repeatedly retrying unrelated tests. The four comparer tests that had previously exposed the host zh-CN locale all passed when the Electron host was run with VS Code’s en-US language.

The targeted coverage command also passed its tests, but the existing Electron coverage path produced an empty lcov.info, so I am not claiming numerical coverage.

These results were obtained on the patch-equivalent validation worktree immediately before the branch was refreshed onto newer main; range-diff confirmed that the PR patches and the two follow-up commits were unchanged.

Document where repository names are rendered and sorted without changing runtime behavior. This exposes the relevant SCM lines for discussion before the sorting adjustment.
Synchronize the test RPC protocol before asserting registration and after disposing the source controls. This keeps the transport test aligned with the asynchronous RPC contract.

Tested with the focused ExtHostSCM Electron unit suite.
Use the canonical SCM provider name for name sorting so explicit repository names follow the same order users see. Preserve the existing path tie-breaker and remove the redundant workspace-based name derivation.

Add a focused SCMViewService regression test covering display names that oppose root basenames and duplicate-name path ordering. Tested with typecheck-client, targeted ESLint, and the focused Electron unit suite.
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.

4 participants