Copilot Chat startup force-opens historical repositories outside the current workspace
- Dominant language
- TypeScript
- Stars
- 193k
- Forks
- 42.4k
- PR merge metrics
- PR metrics pending
Description
- Copilot Chat Extension Version: 0.57.0
- VS Code Version: 1.129.1 (`8a7abeba6e03ea3af87bfbce9a1b7e48fed567b8`)
- OS Version: macOS
- Feature (e.g. agent/edit/ask mode): Copilot CLI session initialization / repository metadata
- Selected model (e.g. GPT 4.1, Claude 3.7 Sonnet): N/A; occurs during startup before model interaction
- Logs: Relevant excerpts below
Steps to Reproduce:
1. Create a repository with several linked Git worktrees. Keep `git.detectWorktrees` enabled.
2. Use Copilot/Copilot CLI across the main checkout and multiple worktrees so those repositories appear in Git's recent-repository cache and/or historical session metadata.
3. Open one individual worktree as the only workspace folder in a VS Code window.
4. Set `git.autoRepositoryDetection` to `false` and `git.openRepositoryInParentFolders` to `never` to rule out normal repository scanning.
5. Reload the window.
6. Observe that the Source Control repository list first contains only the current worktree, then the main checkout and sibling worktrees appear.
## Expected behavior
A window opened on an individual worktree should show only that worktree. Copilot may read historical session metadata, but it should not mutate the current window's SCM repository list by opening repositories outside the current workspace.
A separate window opened on the main checkout should continue to discover all linked worktrees through `git.detectWorktrees`.
## Actual behavior
After the Git extension's initial scan correctly opens only the current worktree, Copilot Chat calls the public Git API's `openRepository` for repositories outside the workspace. When it opens the main checkout, built-in Git then correctly applies `git.detectWorktrees` and opens every linked worktree. This turns a few cross-workspace Copilot lookups into dozens of entries in the Source Control list.
Disabling `git.autoRepositoryDetection` and setting `git.openRepositoryInParentFolders` to `never` do not prevent this because the public Git API call uses the explicit API path that bypasses those discovery boundaries.
## Instrumented evidence
I temporarily instrumented `vscode.git`'s public API wrapper. On reload, the initial scan completed with one repository:
```text
[Model][openRepository] Opened repository (path): /Users/me/repos/project.worktrees/current-worktree
[Model][openRepository] Opened repository (kind): worktree
[Model][doInitialScan] Initial repository scan completed - repositories (1)
```
Copilot then invoked the Git API for outside-workspace paths:
```text
[GitAPI][openRepository] Path: /Users/me/repos/project.worktrees/another-worktree
Caller:
at Fm.openRepository (.../extensions/git/dist/main.js)
at .../extensions/copilot/dist/extension.js
[GitAPI][openRepository] Path: /Users/me/repos/project
Caller:
at Fm.openRepository (.../extensions/git/dist/main.js)
at .../extensions/copilot/dist/extension.js
```
Inspection of the bundled Copilot code shows the mutation in `GitServiceImpl._getRepository`:
```ts
let repository = gitApi.getRepository(uri);
if (!repository && openIfMissing) {
repository = await gitApi.openRepository(uri);
}
```
The startup logs around the calls show Copilot CLI session initialization (`CopilotCLIChatSessionContentProvider.listSessions`) and Git service activation. The repository paths match built-in Git's global `recentRepositories` entries.
## Tested fix
Guarding the fallback so Copilot opens missing repositories only when the URI belongs to the current workspace fixes the issue:
```ts
if (
openIfMissing &&
(!workspace.workspaceFolders?.length || workspace.getWorkspaceFolder(uri))
) {
repository = await gitApi.openRepository(uri);
}
```
After applying that guard and repeatedly reloading both windows:
- The individual worktree window consistently opens exactly one repository.
- The main-checkout window still opens the main repository and all linked worktrees through `git.detectWorktrees`.
- Copilot CLI, its MCP bridge, remote support, and session loading remain enabled.
## Related issues
- #307688 identified the same cross-workspace startup path: historical sessions call `gitService.getRepository(uri, true)`, which falls back to `openRepository(uri)` and bypasses workspace boundaries. That issue was closed after fixing the expensive `git add -A` behavior, but suggested fix 2, "Don't force-open repositories that aren't in the current workspace," remains reproducible in 0.57.0.
- #307695 covers a related Source Control Graph visibility problem after Copilot has registered an outside-workspace repository. This report concerns the earlier mutation: Copilot opening those repositories in the first place.
Contributor guide
Assessment
This issue has not been assessed yet.