Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import * as vscode from 'vscode';
import { ChatExtendedRequestHandler, Uri } from 'vscode';
import { IRunCommandExecutionService } from '../../../platform/commands/common/runCommandExecutionService';
import { IVSCodeExtensionContext } from '../../../platform/extContext/common/extensionContext';
import { IGitExtensionService } from '../../../platform/git/common/gitExtensionService';
import { IGitService } from '../../../platform/git/common/gitService';
import { toGitUri } from '../../../platform/git/common/utils';
import { ILogService } from '../../../platform/log/common/logService';
Expand Down Expand Up @@ -229,7 +228,6 @@ export class CopilotCLIChatSessionItemProvider extends Disposable implements vsc
@ICopilotCLISessionService private readonly copilotcliSessionService: ICopilotCLISessionService,
@ICopilotCLITerminalIntegration private readonly terminalIntegration: ICopilotCLITerminalIntegration,
@IGitService private readonly gitService: IGitService,
@IGitExtensionService private readonly gitExtensionService: IGitExtensionService,
@IRunCommandExecutionService private readonly commandExecutionService: IRunCommandExecutionService,
) {
super();
Expand Down Expand Up @@ -278,7 +276,6 @@ export class CopilotCLIChatSessionItemProvider extends Disposable implements vsc
tooltipLines.push(vscode.l10n.t(`Worktree: {0}`, worktreeRelativePath));

// Statistics
// Make sure the repository is opened
const stats = await this.getStatisticsForWorktree(worktreeUri);
if (stats && stats.length > 0) {
CachedSessionStats.set(resource, stats);
Expand All @@ -298,35 +295,23 @@ export class CopilotCLIChatSessionItemProvider extends Disposable implements vsc
} satisfies vscode.ChatSessionItem;
}

private async getStatisticsForWorktree(worktreeUri: Uri) {
const repository = await this.gitService.getRepository(worktreeUri);
const details: vscode.ChatSessionChangedFile[] = [];
if (repository?.changes) {
const allChanges = [...repository.changes.indexChanges, ...repository.changes.workingTree];
const gitAPI = this.gitExtensionService.getExtensionApi();
const gitRepository = gitAPI?.getRepository(worktreeUri);

for (const change of allChanges) {
let insertions = 0;
let deletions = 0;

if (gitRepository && gitRepository.diffIndexWithHEADShortStats) {
try {
const fileStats = await gitRepository.diffIndexWithHEADShortStats(change.uri.fsPath);
if (fileStats) {
insertions = fileStats.insertions;
deletions = fileStats.deletions;
}
} catch (error) { }
}
private async getStatisticsForWorktree(worktreeUri: Uri): Promise<vscode.ChatSessionChangedFile[]> {
const repository = await this.gitService.getRepository(worktreeUri, false);
if (!repository?.changes) {
return [];
}

const details: vscode.ChatSessionChangedFile[] = [];
for (const change of [...repository.changes.indexChanges, ...repository.changes.workingTree]) {
try {
const fileStats = await this.gitService.diffIndexWithHEADShortStats(change.uri);
Copy link

Copilot AI Dec 7, 2025

Choose a reason for hiding this comment

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

The diffIndexWithHEADShortStats method is being called with change.uri, but the implementation in gitServiceImpl.ts (line 220-227) doesn't pass the file path to the underlying repository method. The repository's diffIndexWithHEADShortStats(path?: string) method expects an optional path parameter (a string), but the service implementation calls it without any arguments.

This means the method will return stats for the entire repository instead of per-file stats. You should either:

  1. Update the service method signature to accept a URI and extract uri.fsPath to pass to the repository method, or
  2. Call the method differently to get per-file statistics.

The old code called gitRepository.diffIndexWithHEADShortStats(change.uri.fsPath) directly, which was correct.

Suggested change
const fileStats = await this.gitService.diffIndexWithHEADShortStats(change.uri);
const fileStats = await this.gitService.diffIndexWithHEADShortStats(change.uri.fsPath);

Copilot uses AI. Check for mistakes.
details.push(new vscode.ChatSessionChangedFile(
change.uri,
insertions,
deletions,
change.originalUri,
fileStats?.insertions ?? 0,
fileStats?.deletions ?? 0,
change.originalUri
));
}
} catch (error) { }
}
return details;
}
Expand Down
2 changes: 1 addition & 1 deletion src/platform/git/common/gitService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export interface IGitService extends IDisposable {
readonly repositories: Array<RepoContext>;
readonly isInitialized: boolean;

getRepository(uri: URI): Promise<RepoContext | undefined>;
getRepository(uri: URI, forceOpen?: boolean): Promise<RepoContext | undefined>;
getRepositoryFetchUrls(uri: URI): Promise<Pick<RepoContext, 'rootUri' | 'remoteFetchUrls'> | undefined>;
initialize(): Promise<void>;
add(uri: URI, paths: string[]): Promise<void>;
Expand Down
11 changes: 10 additions & 1 deletion src/platform/git/vscode/gitServiceImpl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ export class GitServiceImpl extends Disposable implements IGitService {
return this._isInitialized.get();
}

async getRepository(uri: URI): Promise<RepoContext | undefined> {
async getRepository(uri: URI, forceOpen = true): Promise<RepoContext | undefined> {
const gitAPI = this.gitExtensionService.getExtensionApi();
if (!gitAPI) {
return undefined;
Expand All @@ -110,13 +110,22 @@ export class GitServiceImpl extends Disposable implements IGitService {
uri = vscode.Uri.parse(uri.toString());
}

// Ensure that the initial
// repository discovery is
// finished
await this.initialize();

// Query opened repositories
let repository = gitAPI.getRepository(uri);
if (repository) {
await this.waitForRepositoryState(repository);
return GitServiceImpl.repoToRepoContext(repository);
}

if (!forceOpen) {
return undefined;
}

// Open repository
repository = await gitAPI.openRepository(uri);
if (!repository) {
Expand Down
2 changes: 1 addition & 1 deletion src/platform/test/node/simulationWorkspaceServices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -674,7 +674,7 @@ export class TestingGitService implements IGitService {
}

// TODO implement later if tests use this, only used by ignore service
getRepository(uri: URI): Promise<RepoContext | undefined> {
getRepository(uri: URI, forceOpen?: boolean): Promise<RepoContext | undefined> {
return Promise.resolve(undefined);
}

Expand Down