@@ -9,21 +9,19 @@ import { CancellationToken } from 'vscode-languageserver-protocol';
99import { IVSCodeExtensionContext } from '../../../platform/extContext/common/extensionContext' ;
1010import { IGitCommitMessageService } from '../../../platform/git/common/gitCommitMessageService' ;
1111import { IGitService , RepoContext } from '../../../platform/git/common/gitService' ;
12- import { toGitUri } from '../../../platform/git/common/utils' ;
1312import { ILogService } from '../../../platform/log/common/logService' ;
1413import { IWorkspaceService } from '../../../platform/workspace/common/workspaceService' ;
1514import { Disposable } from '../../../util/vs/base/common/lifecycle' ;
1615import * as path from '../../../util/vs/base/common/path' ;
1716import { basename , isEqual } from '../../../util/vs/base/common/resources' ;
18- import { ChatSessionWorktreeData , ChatSessionWorktreeProperties , IChatSessionWorktreeService } from '../common/chatSessionWorktreeService' ;
17+ import { ChatSessionWorktreeData , ChatSessionWorktreeFile , ChatSessionWorktreeProperties , IChatSessionWorktreeService } from '../common/chatSessionWorktreeService' ;
1918
2019const CHAT_SESSION_WORKTREE_MEMENTO_KEY = 'github.copilot.cli.sessionWorktrees' ;
2120
2221export class ChatSessionWorktreeService extends Disposable implements IChatSessionWorktreeService {
2322 declare _serviceBrand : undefined ;
2423
2524 private _sessionWorktrees : Map < string , string | ChatSessionWorktreeProperties > = new Map ( ) ;
26- private _sessionWorktreeChanges : Map < string , vscode . ChatSessionChangedFile2 [ ] | undefined > = new Map ( ) ;
2725
2826 constructor (
2927 @IGitCommitMessageService private readonly gitCommitMessageService : IGitCommitMessageService ,
@@ -165,8 +163,13 @@ export class ChatSessionWorktreeService extends Disposable implements IChatSessi
165163 untracked : true
166164 } ) ;
167165
168- // Clear worktree changes cache
169- this . _sessionWorktreeChanges . delete ( sessionId ) ;
166+ // Delete worktree changes cache
167+ if ( worktreeProperties ) {
168+ this . setWorktreeProperties ( sessionId , {
169+ ...worktreeProperties ,
170+ changes : undefined
171+ } ) ;
172+ }
170173
171174 return ;
172175 }
@@ -211,70 +214,82 @@ export class ChatSessionWorktreeService extends Disposable implements IChatSessi
211214 } ) ;
212215 }
213216
214- // Clear worktree changes cache
215- this . _sessionWorktreeChanges . delete ( sessionId ) ;
217+ // Delete worktree changes cache
218+ this . setWorktreeProperties ( sessionId , {
219+ ...worktreeProperties ,
220+ changes : undefined
221+ } ) ;
216222 }
217223
218- async getWorktreeChanges ( sessionId : string ) : Promise < vscode . ChatSessionChangedFile2 [ ] | undefined > {
219- if ( this . _sessionWorktreeChanges . has ( sessionId ) ) {
220- return this . _sessionWorktreeChanges . get ( sessionId ) ;
224+ async getWorktreeChanges ( sessionId : string ) : Promise < readonly ChatSessionWorktreeFile [ ] | undefined > {
225+ // Get worktree properties
226+ const worktreeProperties = this . getWorktreeProperties ( sessionId ) ;
227+ if ( ! worktreeProperties ) {
228+ return undefined ;
221229 }
222230
223- // Check whether the session has an associated worktree
224- const worktreePath = this . getWorktreePath ( sessionId ) ;
225- if ( ! worktreePath ) {
226- return undefined ;
231+ // Return cached changes
232+ if ( worktreeProperties . changes ) {
233+ return worktreeProperties . changes ;
227234 }
228235
236+ const worktreePath = vscode . Uri . file ( worktreeProperties . worktreePath ) ;
237+
229238 // Ensure the initial repository discovery is completed and the repository
230239 // states are initialized in the vscode.git extension. This is needed as these
231240 // will be the repositories that we use to compute the worktree changes. We do
232241 // not have to open each worktree individually since the changes are committed
233242 // so we can get them from the main repository or discovered worktree.
234243 await this . gitService . initialize ( ) ;
235244
245+ // TODO@lszomoru : Remove this change to support welcome view
236246 // Check whether the worktree belongs to any of the discovered repositories
237247 const repository = this . gitService . repositories
238248 . find ( r => r . worktrees . some ( w => isEqual ( vscode . Uri . file ( w . path ) , worktreePath ) ) ) ;
239249
240250 if ( ! repository ) {
241- this . _sessionWorktreeChanges . set ( sessionId , undefined ) ;
242251 return undefined ;
243252 }
244253
245- // Get worktree properties
246- const worktreeProperties = this . getWorktreeProperties ( sessionId ) ;
247-
248- if ( worktreeProperties === undefined || worktreeProperties . autoCommit === false ) {
254+ if ( worktreeProperties . autoCommit === false ) {
249255 // These changes are staged in the worktree but not yet committed. Since the
250256 // changes are not committed, we need to get them from the worktree repository
251257 // state. To do that we need to open the worktree repository. The source control
252258 // provider will not be shown in the Source Control view since it is being hidden.
253259 const worktreeRepository = await this . gitService . getRepository ( worktreePath ) ;
254260
255261 if ( ! worktreeRepository ?. changes ) {
256- this . _sessionWorktreeChanges . set ( sessionId , [ ] ) ;
262+ this . setWorktreeProperties ( sessionId , {
263+ ...worktreeProperties ,
264+ changes : [ ]
265+ } ) ;
266+
257267 return [ ] ;
258268 }
259269
260- const changes : vscode . ChatSessionChangedFile2 [ ] = [ ] ;
270+ const changes : ChatSessionWorktreeFile [ ] = [ ] ;
261271 for ( const change of [ ...worktreeRepository . changes . indexChanges , ...worktreeRepository . changes . workingTree ] ) {
262272 try {
263273 const fileStats = await this . gitService . diffIndexWithHEADShortStats ( change . uri ) ;
264- changes . push ( new vscode . ChatSessionChangedFile2 (
265- change . uri ,
266- change . status !== 1 /* INDEX_ADDED */
267- ? change . originalUri
274+ changes . push ( {
275+ filePath : change . uri . fsPath ,
276+ originalFilePath : change . status !== 1 /* INDEX_ADDED */
277+ ? change . originalUri ?. fsPath
268278 : undefined ,
269- change . status !== 2 /* INDEX_DELETED */
270- ? change . uri
279+ modifiedFilePath : change . status !== 2 /* INDEX_DELETED */
280+ ? change . uri . fsPath
271281 : undefined ,
272- fileStats ?. insertions ?? 0 ,
273- fileStats ?. deletions ?? 0 ) ) ;
282+ statistics : {
283+ additions : fileStats ?. insertions ?? 0 ,
284+ deletions : fileStats ?. deletions ?? 0
285+ }
286+ } satisfies ChatSessionWorktreeFile ) ;
274287 } catch ( error ) { }
275288 }
276289
277- this . _sessionWorktreeChanges . set ( sessionId , changes ) ;
290+ this . setWorktreeProperties ( sessionId , {
291+ ...worktreeProperties , changes
292+ } ) ;
278293 return changes ;
279294 }
280295
@@ -287,24 +302,32 @@ export class ChatSessionWorktreeService extends Disposable implements IChatSessi
287302 worktreeProperties . branchName ) ;
288303
289304 if ( ! diff ) {
290- this . _sessionWorktreeChanges . set ( sessionId , [ ] ) ;
305+ this . setWorktreeProperties ( sessionId , {
306+ ...worktreeProperties ,
307+ changes : [ ]
308+ } ) ;
309+
291310 return [ ] ;
292311 }
293312
294- const changes = diff . map ( change => {
295- return new vscode . ChatSessionChangedFile2 (
296- change . uri ,
297- change . status !== 1 /* INDEX_ADDED */
298- ? toGitUri ( change . originalUri , worktreeProperties . baseCommit )
299- : undefined ,
300- change . status !== 6 /* DELETED */
301- ? toGitUri ( change . uri , worktreeProperties . branchName )
302- : undefined ,
303- change . insertions ,
304- change . deletions ) ;
313+ const changes = diff . map ( change => ( {
314+ filePath : change . uri . fsPath ,
315+ originalFilePath : change . status !== 1 /* INDEX_ADDED */
316+ ? change . originalUri ?. fsPath
317+ : undefined ,
318+ modifiedFilePath : change . status !== 6 /* DELETED */
319+ ? change . uri . fsPath
320+ : undefined ,
321+ statistics : {
322+ additions : change . insertions ,
323+ deletions : change . deletions
324+ }
325+ } satisfies ChatSessionWorktreeFile ) ) ;
326+
327+ this . setWorktreeProperties ( sessionId , {
328+ ...worktreeProperties , changes
305329 } ) ;
306330
307- this . _sessionWorktreeChanges . set ( sessionId , changes ) ;
308331 return changes ;
309332 }
310333
@@ -340,7 +363,10 @@ export class ChatSessionWorktreeService extends Disposable implements IChatSessi
340363 await this . gitService . commit ( vscode . Uri . file ( worktreePath ) , message , { all : true , noVerify : true , signCommit : false } ) ;
341364 this . logService . trace ( `[ChatSessionWorktreeService] Committed all changes in working directory ${ worktreePath } ` ) ;
342365
343- // Delete worktree changes from cache
344- this . _sessionWorktreeChanges . delete ( sessionId ) ;
366+ // Delete worktree changes cache
367+ this . setWorktreeProperties ( sessionId , {
368+ ...worktreeProperties ,
369+ changes : undefined
370+ } ) ;
345371 }
346372}
0 commit comments