microsoft / microsoft/vscode

Session list change counts show the whole branch divergence, not the session's changes

Open
#330,941 3 comments 0 reactions 1 assignee Claimed by @osortega View on GitHub
Dominant language
TypeScript
Stars
193k
Forks
42.4k
PR merge metrics
PR metrics pending

Description

> **Update:** struck-through passages below are corrections to my original report — two measurements came from the wrong repository, and the suggested fix turned out to be wrong. Details, re-measured figures and further evidence in [this comment](https://github.com/microsoft/vscode/issues/330941#issuecomment-5299050850). The report itself stands.

### Summary

The change counts shown against a session in the sessions list are the whole branch's divergence from its base branch, not that session's changes. On a long-lived shared branch the number grows without bound, is identical for every session in the repository, and wildly overstates what an agent did.

### Repro

1. Work on a branch that is well ahead of the default branch (a long-lived `dev`, say).
2. Start a session there and let it edit one or two files.
3. Look at the session in the sessions list.

Observed: a count in the thousands, close to identical for every session in that repository, growing over time.

Expected: what this session changed.

### Cause

The list chip renders `changes.insertions/deletions` ([agentSessionsViewer.ts:542](https://github.com/microsoft/vscode/blob/main/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsViewer.ts#L542)), sourced from the Branch changeset summary ([agentHostChangesetService.ts:1356](https://github.com/microsoft/vscode/blob/main/src/vs/platform/agentHost/node/agentHostChangesetService.ts#L1356)), which is `git diff` against `merge-base HEAD origin/` ([agentHostGitService.ts:474](https://github.com/microsoft/vscode/blob/main/src/vs/platform/agentHost/node/agentHostGitService.ts#L474)).

That is correct when a session owns its branch, which is the cloud/PR shape. For a local session started on an existing shared branch, the merge-base is far behind and the diff is dominated by work no session performed.

~~Measured on a real repository: a session that touched two files sat on a `dev` branch whose `git diff --shortstat $(git merge-base HEAD origin/main)` was `104 files changed, 11448 insertions(+), 1285 deletions(-)`. A second repository whose branch was level with its remote correctly showed only its uncommitted `209 insertions, 6 deletions`, which is the same code path behaving differently purely because of branch position.~~

**Corrected.** Both figures above were misreported: the first came from a different repository than the screenshot, and the second was not a second repository at all. Re-measured on the repository this report came from, on its `dev` branch:

```
$ git diff --shortstat $(git merge-base HEAD origin/main)
166 files changed, 11329 insertions(+), 634 deletions(-)

$ git ls-files --others --exclude-standard | wc -l # 17 untracked files,
17 # totalling 4741 lines

$ git diff --shortstat origin/dev # same repo, own remote
9 files changed, 209 insertions(+), 6 deletions(-) # HEAD level with origin/dev
```

`166 + 17 = 183` files and `11329 + 4741 = 16070` insertions is exactly what the chip displays (`183 files, +16070 -634`); the branch changeset includes untracked files, `--shortstat` alone does not. The `209 insertions, 6 deletions` is the *same* repository measured against its own remote branch rather than the default branch — which still makes the original point, and makes it on one repository: the identical code path reports `11329` or `209` purely according to which base it resolves.

### Suggested fix

~~The host already captures a per-session baseline checkpoint per repository (`IAgentHostCheckpointService.captureBaselineCheckpoint`, retrievable via `getBaselineCheckpoint`). Anchoring the branch diff there makes the number the session's own footprint, and leaves a branch-owning session unchanged because its baseline is the branch point.~~

~~PR follows. Happy to close it if the current definition is deliberate, in which case the counts may still be worth relabelling, since as displayed they read as the session's work.~~

**Withdrawn.** That was tried in #330942 and closed: a baseline checkpoint is a parentless snapshot commit rather than an ancestor of `HEAD`, so it cannot be used as the base of a merge-base working-tree diff — doing so compared unrelated trees and produced a worse number than the one it replaced.

No new computation is needed in any case. The `session` changeset already diffs the session's baseline checkpoint against its latest turn checkpoint via the two-ref primitive ([agentHostChangesetService.ts:1541-1566](https://github.com/microsoft/vscode/blob/main/src/vs/platform/agentHost/node/agentHostChangesetService.ts#L1541-L1566)), which is the session's own footprint. The open question is only which changeset feeds the chip — and that is a product decision, since the branch-derived chip is deliberate (#323852, pinned by a characterization test). The counts may still be worth relabelling, since as displayed they read as the session's work.

*AI disclosure: this issue was written with the assistance of AI.*

### Public patches and patcher scripts

[Public patch catalog and patcher scripts](https://github.com/RyanEwen/vscode-patches/blob/main/CATALOG.md) · [Source patch index](https://github.com/RyanEwen/vscode-patches/blob/main/SOURCE-PATCHES.md). The [public collection](https://github.com/RyanEwen/vscode-patches) includes the maintained patchers, rollback instructions, regression scripts, and historical snapshots. Build restrictions and exact installer coverage are documented there.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.