Skip to content

Commit e100c2b

Browse files
authored
Background - improve worktree changes calculation (#2685)
* Background - improve worktree changes calculation * Adjust order * Pull request feedback
1 parent 233302c commit e100c2b

5 files changed

Lines changed: 37 additions & 9 deletions

File tree

src/extension/chatSessions/vscode-node/chatSessionWorktreeServiceImpl.ts

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { coalesce } from '../../../util/vs/base/common/arrays';
1616
import { Disposable } from '../../../util/vs/base/common/lifecycle';
1717
import { derived, IObservable } from '../../../util/vs/base/common/observable';
1818
import * as path from '../../../util/vs/base/common/path';
19-
import { basename } from '../../../util/vs/base/common/resources';
19+
import { basename, isEqual } from '../../../util/vs/base/common/resources';
2020
import { ChatSessionWorktreeData, ChatSessionWorktreeProperties, IChatSessionWorktreeService } from '../common/chatSessionWorktreeService';
2121

2222
const CHAT_SESSION_WORKTREE_MEMENTO_KEY = 'github.copilot.cli.sessionWorktrees';
@@ -233,24 +233,42 @@ export class ChatSessionWorktreeService extends Disposable implements IChatSessi
233233
}
234234

235235
async getWorktreeChanges(sessionId: string): Promise<vscode.ChatSessionChangedFile[] | undefined> {
236-
await this.gitService.initialize();
237-
238236
if (this._sessionWorktreeChanges.has(sessionId)) {
239237
return this._sessionWorktreeChanges.get(sessionId);
240238
}
241239

240+
// Check whether the session has an associated worktree
242241
const worktreePath = this.getWorktreePath(sessionId);
243-
const worktreeProperties = this.getWorktreeProperties(sessionId);
244-
245242
if (!worktreePath) {
243+
return undefined;
244+
}
245+
246+
// Ensure the initial repository discovery is completed and the repository
247+
// states are initialized in the vscode.git extension. At this point, the
248+
// worktrees may not have been opened yet so we may need to explicitly open
249+
// them.
250+
await this.gitService.initialize();
251+
252+
// Check whether the worktree belongs to any of the discovered repositories
253+
const worktreePaths = this.gitService.repositories.map(r => r.worktrees.map(w => w.path)).flat();
254+
if (!worktreePaths.some(p => isEqual(vscode.Uri.file(p), worktreePath))) {
246255
this._sessionWorktreeChanges.set(sessionId, undefined);
247256
return undefined;
248257
}
249258

259+
// Open the worktree repository. This will initialize the repository state
260+
// in the vscode.git extension but the source control provider will not be
261+
// shown in the Source Control view since it is being hidden.
262+
const repository = await this.gitService.getRepository(worktreePath);
263+
if (!repository) {
264+
this._sessionWorktreeChanges.set(sessionId, undefined);
265+
return undefined;
266+
}
267+
268+
const worktreeProperties = this.getWorktreeProperties(sessionId);
250269
if (worktreeProperties === undefined || worktreeProperties.autoCommit === false) {
251270
// These changes are staged in the worktree but not yet committed
252-
const repository = await this.gitService.getRepository(worktreePath, false);
253-
if (!repository?.changes) {
271+
if (!repository.changes) {
254272
this._sessionWorktreeChanges.set(sessionId, []);
255273
return [];
256274
}

src/platform/git/common/gitService.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { Event } from '../../../util/vs/base/common/event';
99
import { IObservable } from '../../../util/vs/base/common/observableInternal';
1010
import { equalsIgnoreCase } from '../../../util/vs/base/common/strings';
1111
import { URI } from '../../../util/vs/base/common/uri';
12-
import { Change, Commit, CommitShortStat, DiffChange, LogOptions, Ref, RefQuery } from '../vscode/git';
12+
import { Change, Commit, CommitShortStat, DiffChange, LogOptions, Ref, RefQuery, Worktree } from '../vscode/git';
1313
import { CancellationToken } from '../../../util/vs/base/common/cancellation';
1414

1515
export interface RepoContext {
@@ -23,9 +23,9 @@ export interface RepoContext {
2323
// to change every test.
2424
readonly remoteFetchUrls?: Array<string | undefined>;
2525
readonly remotes: string[];
26+
readonly worktrees: Worktree[];
2627
readonly changes: { mergeChanges: Change[]; indexChanges: Change[]; workingTree: Change[]; untrackedChanges: Change[] } | undefined;
2728

28-
2929
readonly headBranchNameObs: IObservable<string | undefined>;
3030
readonly headCommitHashObs: IObservable<string | undefined>;
3131
readonly upstreamBranchNameObs: IObservable<string | undefined>;

src/platform/git/vscode/git.d.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,13 @@ export interface Remote {
7878
readonly isReadOnly: boolean;
7979
}
8080

81+
export interface Worktree {
82+
readonly name: string;
83+
readonly path: string;
84+
readonly ref: string;
85+
readonly detached: boolean;
86+
}
87+
8188
export const enum Status {
8289
INDEX_MODIFIED,
8390
INDEX_ADDED,
@@ -125,6 +132,7 @@ export interface RepositoryState {
125132
readonly refs: Ref[];
126133
readonly remotes: Remote[];
127134
readonly submodules: Submodule[];
135+
readonly worktrees: Worktree[];
128136
readonly rebaseCommit: Commit | undefined;
129137

130138
readonly mergeChanges: Change[];

src/platform/git/vscode/gitServiceImpl.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,7 @@ export class RepoContextImpl implements RepoContext {
386386
public readonly isRebasing = this._repo.state.rebaseCommit !== null;
387387
public readonly remotes = this._repo.state.remotes.map(r => r.name);
388388
public readonly remoteFetchUrls = this._repo.state.remotes.map(r => r.fetchUrl);
389+
public readonly worktrees = this._repo.state.worktrees;
389390

390391
public readonly changes = {
391392
mergeChanges: this._repo.state.mergeChanges,

src/platform/test/node/simulationWorkspaceServices.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,7 @@ export class TestingGitService implements IGitService {
725725
`https://github.com/microsoft/simuluation-test-${basename(workspaceFolderPath)}`
726726
],
727727
remotes: [],
728+
worktrees: [],
728729
changes: undefined,
729730
headBranchNameObs: constObservable(undefined),
730731
headCommitHashObs: constObservable(undefined),

0 commit comments

Comments
 (0)