@@ -73,80 +73,89 @@ export class StashGitSubProvider implements GitStashSubProvider {
73
73
) : Promise < GitStash | undefined > {
74
74
if ( repoPath == null ) return undefined ;
75
75
76
- let stash = this . cache . stashes ?. get ( repoPath ) ;
77
- if ( stash == null ) {
78
- const parser = getStashLogParser ( ) ;
79
- const args = [ ...parser . arguments ] ;
76
+ let stashPromise = this . cache . stashes ?. get ( repoPath ) ;
77
+ if ( stashPromise == null ) {
78
+ async function load ( this : StashGitSubProvider ) : Promise < GitStash > {
79
+ const parser = getStashLogParser ( ) ;
80
+ const args = [ ...parser . arguments ] ;
81
+
82
+ const similarityThreshold = configuration . get ( 'advanced.similarityThreshold' ) ;
83
+ args . push ( `-M${ similarityThreshold == null ? '' : `${ similarityThreshold } %` } ` ) ;
84
+
85
+ const result = await this . git . exec (
86
+ { cwd : repoPath , cancellation : cancellation } ,
87
+ 'stash' ,
88
+ 'list' ,
89
+ ...args ,
90
+ ) ;
91
+
92
+ const stashes = new Map < string , GitStashCommit > ( ) ;
93
+
94
+ for ( const s of parser . parse ( result . stdout ) ) {
95
+ stashes . set ( s . sha , createStash ( this . container , s , repoPath ) ) ;
96
+ }
80
97
81
- const similarityThreshold = configuration . get ( 'advanced.similarityThreshold' ) ;
82
- args . push ( `-M ${ similarityThreshold == null ? '' : ` ${ similarityThreshold } %` } ` ) ;
98
+ return { repoPath : repoPath , stashes : stashes } ;
99
+ }
83
100
84
- const result = await this . git . exec ( { cwd : repoPath , cancellation : cancellation } , 'stash' , 'list' , ...args ) ;
101
+ stashPromise = load . call ( this ) ;
102
+ this . cache . stashes ?. set ( repoPath , stashPromise ) ;
103
+ }
85
104
86
- const stashes = new Map < string , GitStashCommit > ( ) ;
105
+ const stash = await stashPromise ;
106
+ if ( ! options ?. reachableFrom || ! stash ?. stashes . size ) return stash ;
87
107
88
- for ( const s of parser . parse ( result . stdout ) ) {
89
- stashes . set ( s . sha , createStash ( this . container , s , repoPath ) ) ;
90
- }
108
+ // Return only reachable stashes from the given ref
109
+ // Create a copy because we are going to modify it and we don't want to mutate the cache
110
+ const stashes = new Map ( stash . stashes ) ;
91
111
92
- stash = { repoPath : repoPath , stashes : stashes } ;
112
+ const oldestStashDate = new Date ( min ( stash . stashes . values ( ) , c => c . date . getTime ( ) ) ) . toISOString ( ) ;
93
113
94
- this . cache . stashes ?. set ( repoPath , stash ) ;
95
- }
114
+ const result = await this . git . exec (
115
+ { cwd : repoPath , cancellation : cancellation , errors : GitErrorHandling . Ignore } ,
116
+ 'rev-list' ,
117
+ `--since="${ oldestStashDate } "` ,
118
+ '--date-order' ,
119
+ options . reachableFrom ,
120
+ '--' ,
121
+ ) ;
96
122
97
- // Return only reachable stashes from the given ref
98
- if ( options ?. reachableFrom && stash ?. stashes . size ) {
99
- // Create a copy because we are going to modify it and we don't want to mutate the cache
100
- stash = { ...stash , stashes : new Map ( stash . stashes ) } ;
101
-
102
- const oldestStashDate = new Date ( min ( stash . stashes . values ( ) , c => c . date . getTime ( ) ) ) . toISOString ( ) ;
103
-
104
- const result = await this . git . exec (
105
- { cwd : repoPath , cancellation : cancellation , errors : GitErrorHandling . Ignore } ,
106
- 'rev-list' ,
107
- `--since="${ oldestStashDate } "` ,
108
- '--date-order' ,
109
- options . reachableFrom ,
110
- '--' ,
111
- ) ;
123
+ const ancestors = result . stdout . trim ( ) . split ( '\n' ) ;
124
+ const reachableCommits =
125
+ ancestors ?. length && ( ancestors . length !== 1 || ancestors [ 0 ] ) ? new Set ( ancestors ) : undefined ;
126
+ if ( reachableCommits ?. size ) {
127
+ const reachableStashes = new Set < string > ( ) ;
112
128
113
- const ancestors = result . stdout . trim ( ) . split ( '\n' ) ;
114
- const reachableCommits =
115
- ancestors ?. length && ( ancestors . length !== 1 || ancestors [ 0 ] ) ? new Set ( ancestors ) : undefined ;
116
- if ( reachableCommits ?. size ) {
117
- const reachableStashes = new Set < string > ( ) ;
129
+ // First pass: mark directly reachable stashes
130
+ for ( const [ sha , s ] of stash . stashes ) {
131
+ if ( s . parents . some ( p => p === options . reachableFrom || reachableCommits . has ( p ) ) ) {
132
+ reachableStashes . add ( sha ) ;
133
+ }
134
+ }
118
135
119
- // First pass: mark directly reachable stashes
136
+ // Second pass: mark stashes that build upon reachable stashes
137
+ let changed ;
138
+ do {
139
+ changed = false ;
120
140
for ( const [ sha , s ] of stash . stashes ) {
121
- if ( s . parents . some ( p => p === options . reachableFrom || reachableCommits . has ( p ) ) ) {
141
+ if ( ! reachableStashes . has ( sha ) && s . parents . some ( p => reachableStashes . has ( p ) ) ) {
122
142
reachableStashes . add ( sha ) ;
143
+ changed = true ;
123
144
}
124
145
}
146
+ } while ( changed ) ;
125
147
126
- // Second pass: mark stashes that build upon reachable stashes
127
- let changed ;
128
- do {
129
- changed = false ;
130
- for ( const [ sha , s ] of stash . stashes ) {
131
- if ( ! reachableStashes . has ( sha ) && s . parents . some ( p => reachableStashes . has ( p ) ) ) {
132
- reachableStashes . add ( sha ) ;
133
- changed = true ;
134
- }
135
- }
136
- } while ( changed ) ;
137
-
138
- // Remove unreachable stashes
139
- for ( const [ sha ] of stash . stashes ) {
140
- if ( ! reachableStashes . has ( sha ) ) {
141
- stash . stashes . delete ( sha ) ;
142
- }
148
+ // Remove unreachable stashes
149
+ for ( const [ sha ] of stash . stashes ) {
150
+ if ( ! reachableStashes . has ( sha ) ) {
151
+ stashes . delete ( sha ) ;
143
152
}
144
- } else {
145
- stash . stashes . clear ( ) ;
146
153
}
154
+ } else {
155
+ stashes . clear ( ) ;
147
156
}
148
157
149
- return stash ;
158
+ return { ... stash , stashes : stashes } ;
150
159
}
151
160
152
161
@log ( )
@@ -342,7 +351,7 @@ export class StashGitSubProvider implements GitStashSubProvider {
342
351
}
343
352
}
344
353
345
- export function convertStashesToStdin ( stashOrStashes : GitStash | Map < string , GitStashCommit > | undefined ) : {
354
+ export function convertStashesToStdin ( stashOrStashes : GitStash | ReadonlyMap < string , GitStashCommit > | undefined ) : {
346
355
readonly stdin : string | undefined ;
347
356
readonly stashes : Map < string , GitStashCommit > ;
348
357
readonly remappedIds : Map < string , string > ;
@@ -351,40 +360,23 @@ export function convertStashesToStdin(stashOrStashes: GitStash | Map<string, Git
351
360
if ( stashOrStashes == null ) return { stdin : undefined , stashes : new Map ( ) , remappedIds : remappedIds } ;
352
361
353
362
let stdin : string | undefined ;
354
- let stashes : Map < string , GitStashCommit > ;
355
-
356
- if ( 'stashes' in stashOrStashes ) {
357
- stashes = new Map ( stashOrStashes . stashes ) ;
358
- if ( stashOrStashes . stashes . size ) {
359
- stdin = '' ;
360
- for ( const stash of stashOrStashes . stashes . values ( ) ) {
361
- stdin += ` ${ stash . sha . substring ( 0 , 9 ) } \n` ;
362
- // Include the stash's 2nd (index files) and 3rd (untracked files) parents
363
- for ( const p of skip ( stash . parents , 1 ) ) {
364
- remappedIds . set ( p , stash . sha ) ;
365
-
363
+ const original = ' stashes' in stashOrStashes ? stashOrStashes . stashes : stashOrStashes ;
364
+ const stashes = new Map < string , GitStashCommit > ( original ) ;
365
+
366
+ if ( original . size ) {
367
+ stdin = '' ;
368
+ for ( const stash of original . values ( ) ) {
369
+ stdin += ` ${ stash . sha . substring ( 0 , 9 ) } \n` ;
370
+ // Include the stash's 2nd (index files) and 3rd (untracked files) parents (if they aren't already in the map)
371
+ for ( const p of skip ( stash . parents , 1 ) ) {
372
+ remappedIds . set ( p , stash . sha ) ;
373
+
374
+ if ( ! stashes . has ( p ) ) {
366
375
stashes . set ( p , stash ) ;
367
376
stdin += `${ p . substring ( 0 , 9 ) } \n` ;
368
377
}
369
378
}
370
379
}
371
- } else {
372
- if ( stashOrStashes . size ) {
373
- stdin = '' ;
374
- for ( const stash of stashOrStashes . values ( ) ) {
375
- stdin += `${ stash . sha . substring ( 0 , 9 ) } \n` ;
376
- // Include the stash's 2nd (index files) and 3rd (untracked files) parents (if they aren't already in the map)
377
- for ( const p of skip ( stash . parents , 1 ) ) {
378
- remappedIds . set ( p , stash . sha ) ;
379
-
380
- if ( ! stashOrStashes . has ( p ) ) {
381
- stashOrStashes . set ( p , stash ) ;
382
- stdin += `${ p . substring ( 0 , 9 ) } \n` ;
383
- }
384
- }
385
- }
386
- }
387
- stashes = stashOrStashes ;
388
380
}
389
381
390
382
return { stdin : stdin || undefined , stashes : stashes , remappedIds : remappedIds } ;
0 commit comments