@@ -219,6 +219,44 @@ export namespace Worktree {
219219 return [ outputText ( result . stderr ) , outputText ( result . stdout ) ] . filter ( Boolean ) . join ( "\n" )
220220 }
221221
222+ function failed ( result : { stdout ?: Uint8Array ; stderr ?: Uint8Array } ) {
223+ return [ outputText ( result . stderr ) , outputText ( result . stdout ) ] . filter ( Boolean ) . flatMap ( ( chunk ) =>
224+ chunk
225+ . split ( "\n" )
226+ . map ( ( line ) => line . trim ( ) )
227+ . flatMap ( ( line ) => {
228+ const match = line . match ( / ^ w a r n i n g : \s + f a i l e d t o r e m o v e \s + ( .+ ) : \s + / i)
229+ if ( ! match ) return [ ]
230+ const value = match [ 1 ] ?. trim ( ) . replace ( / ^ [ ' " ] | [ ' " ] $ / g, "" )
231+ if ( ! value ) return [ ]
232+ return [ value ]
233+ } ) ,
234+ )
235+ }
236+
237+ async function prune ( root : string , entries : string [ ] ) {
238+ const base = await canonical ( root )
239+ await Promise . all (
240+ entries . map ( async ( entry ) => {
241+ const target = await canonical ( path . resolve ( root , entry ) )
242+ if ( target === base ) return
243+ if ( ! target . startsWith ( `${ base } ${ path . sep } ` ) ) return
244+ await fs . rm ( target , { recursive : true , force : true } ) . catch ( ( ) => undefined )
245+ } ) ,
246+ )
247+ }
248+
249+ async function sweep ( root : string ) {
250+ const first = await $ `git clean -ffdx` . quiet ( ) . nothrow ( ) . cwd ( root )
251+ if ( first . exitCode === 0 ) return first
252+
253+ const entries = failed ( first )
254+ if ( ! entries . length ) return first
255+
256+ await prune ( root , entries )
257+ return $ `git clean -ffdx` . quiet ( ) . nothrow ( ) . cwd ( root )
258+ }
259+
222260 async function canonical ( input : string ) {
223261 const abs = path . resolve ( input )
224262 const real = await fs . realpath ( abs ) . catch ( ( ) => abs )
@@ -536,7 +574,7 @@ export namespace Worktree {
536574 throw new ResetFailedError ( { message : errorText ( resetToTarget ) || "Failed to reset worktree to target" } )
537575 }
538576
539- const clean = await $ `git clean -fdx` . quiet ( ) . nothrow ( ) . cwd ( worktreePath )
577+ const clean = await sweep ( worktreePath )
540578 if ( clean . exitCode !== 0 ) {
541579 throw new ResetFailedError ( { message : errorText ( clean ) || "Failed to clean worktree" } )
542580 }
0 commit comments