@@ -440,6 +440,144 @@ describe("Storage Paths Module", () => {
440440 expect ( normalize ( resolved ) ) . toBe ( normalize ( sharedRepoRoot ) ) ;
441441 } ) ;
442442
443+ it ( "falls back to normalized paths when realpathSync.native throws" , ( ) => {
444+ const projectRoot = path . win32 . join ( "X:\\repo" , "worktrees" , "pr-8" ) ;
445+ const gitEntry = path . win32 . join ( projectRoot , ".git" ) ;
446+ const canonicalProjectRoot = path . win32 . join ( "D:\\repo" , "worktrees" , "pr-8" ) ;
447+ const canonicalBackRef = path . win32 . join ( canonicalProjectRoot , ".git" ) ;
448+ const worktreeGitDir = path . win32 . join ( "D:\\repo" , ".git" , "worktrees" , "pr-8" ) ;
449+ const commondirFile = path . win32 . join ( worktreeGitDir , "commondir" ) ;
450+ const gitdirBackRefFile = path . win32 . join ( worktreeGitDir , "gitdir" ) ;
451+ const sharedRepoRoot = "D:\\repo" ;
452+ const sharedGitDir = path . win32 . join ( sharedRepoRoot , ".git" ) ;
453+ const normalize = ( value : string ) => path . win32 . normalize ( value ) . toLowerCase ( ) ;
454+ const aliasPrefix = normalize ( path . win32 . join ( "X:\\repo" ) ) ;
455+ const canonicalBackRefNormalized = normalize ( canonicalBackRef ) ;
456+
457+ mockedRealpathSyncNative . mockImplementation ( ( value ) => {
458+ const normalizedValue = normalize ( String ( value ) ) ;
459+ if ( normalizedValue === canonicalBackRefNormalized ) {
460+ throw new Error ( "simulated native realpath failure" ) ;
461+ }
462+ if ( normalizedValue . startsWith ( aliasPrefix ) ) {
463+ const suffix = normalizedValue . slice ( aliasPrefix . length ) ;
464+ return path . win32 . join ( "D:\\repo" , suffix . replace ( / ^ \\ + / , "" ) ) ;
465+ }
466+ return String ( value ) ;
467+ } ) ;
468+ mockedRealpathSync . mockImplementation ( ( value ) => String ( value ) ) ;
469+
470+ mockedExistsSync . mockImplementation ( ( candidate ) => {
471+ if ( typeof candidate !== "string" ) return false ;
472+ const normalizedCandidate = normalize ( candidate ) ;
473+ return (
474+ normalizedCandidate === normalize ( gitEntry ) ||
475+ normalizedCandidate === normalize ( commondirFile ) ||
476+ normalizedCandidate === normalize ( gitdirBackRefFile ) ||
477+ normalizedCandidate === normalize ( sharedGitDir )
478+ ) ;
479+ } ) ;
480+ mockedStatSync . mockImplementation ( ( candidate ) => {
481+ expect ( normalize ( String ( candidate ) ) ) . toBe ( normalize ( gitEntry ) ) ;
482+ return buildMockStat ( { isDirectory : false , isFile : true } ) ;
483+ } ) ;
484+ mockedReadFileSync . mockImplementation ( ( candidate ) => {
485+ if ( typeof candidate !== "string" ) {
486+ throw new Error ( `Unexpected read path: ${ String ( candidate ) } ` ) ;
487+ }
488+ const normalizedCandidate = normalize ( candidate ) ;
489+ if ( normalizedCandidate === normalize ( gitEntry ) ) {
490+ return `gitdir: ${ worktreeGitDir } \n` ;
491+ }
492+ if ( normalizedCandidate === normalize ( commondirFile ) ) {
493+ return "..\\..\\\n" ;
494+ }
495+ if ( normalizedCandidate === normalize ( gitdirBackRefFile ) ) {
496+ return `${ canonicalBackRef } \n` ;
497+ }
498+ throw new Error ( `Unexpected read path: ${ String ( candidate ) } ` ) ;
499+ } ) ;
500+
501+ const resolved = resolveProjectStorageIdentityRoot ( projectRoot ) ;
502+ expect ( normalize ( resolved ) ) . toBe ( normalize ( sharedRepoRoot ) ) ;
503+ } ) ;
504+
505+ it ( "falls back when realpathSync.native is unavailable and realpathSync throws" , ( ) => {
506+ const projectRoot = path . win32 . join ( "X:\\repo" , "worktrees" , "pr-8" ) ;
507+ const gitEntry = path . win32 . join ( projectRoot , ".git" ) ;
508+ const canonicalProjectRoot = path . win32 . join ( "D:\\repo" , "worktrees" , "pr-8" ) ;
509+ const canonicalBackRef = path . win32 . join ( canonicalProjectRoot , ".git" ) ;
510+ const worktreeGitDir = path . win32 . join ( "D:\\repo" , ".git" , "worktrees" , "pr-8" ) ;
511+ const commondirFile = path . win32 . join ( worktreeGitDir , "commondir" ) ;
512+ const gitdirBackRefFile = path . win32 . join ( worktreeGitDir , "gitdir" ) ;
513+ const sharedRepoRoot = "D:\\repo" ;
514+ const sharedGitDir = path . win32 . join ( sharedRepoRoot , ".git" ) ;
515+ const normalize = ( value : string ) => path . win32 . normalize ( value ) . toLowerCase ( ) ;
516+ const aliasPrefix = normalize ( path . win32 . join ( "X:\\repo" ) ) ;
517+ const canonicalBackRefNormalized = normalize ( canonicalBackRef ) ;
518+ const originalNative = realpathSync . native ;
519+
520+ Object . defineProperty ( realpathSync , "native" , {
521+ value : undefined ,
522+ configurable : true ,
523+ writable : true ,
524+ } ) ;
525+
526+ try {
527+ mockedRealpathSync . mockImplementation ( ( value ) => {
528+ const normalizedValue = normalize ( String ( value ) ) ;
529+ if ( normalizedValue === canonicalBackRefNormalized ) {
530+ throw new Error ( "simulated realpath fallback failure" ) ;
531+ }
532+ if ( normalizedValue . startsWith ( aliasPrefix ) ) {
533+ const suffix = normalizedValue . slice ( aliasPrefix . length ) ;
534+ return path . win32 . join ( "D:\\repo" , suffix . replace ( / ^ \\ + / , "" ) ) ;
535+ }
536+ return String ( value ) ;
537+ } ) ;
538+
539+ mockedExistsSync . mockImplementation ( ( candidate ) => {
540+ if ( typeof candidate !== "string" ) return false ;
541+ const normalizedCandidate = normalize ( candidate ) ;
542+ return (
543+ normalizedCandidate === normalize ( gitEntry ) ||
544+ normalizedCandidate === normalize ( commondirFile ) ||
545+ normalizedCandidate === normalize ( gitdirBackRefFile ) ||
546+ normalizedCandidate === normalize ( sharedGitDir )
547+ ) ;
548+ } ) ;
549+ mockedStatSync . mockImplementation ( ( candidate ) => {
550+ expect ( normalize ( String ( candidate ) ) ) . toBe ( normalize ( gitEntry ) ) ;
551+ return buildMockStat ( { isDirectory : false , isFile : true } ) ;
552+ } ) ;
553+ mockedReadFileSync . mockImplementation ( ( candidate ) => {
554+ if ( typeof candidate !== "string" ) {
555+ throw new Error ( `Unexpected read path: ${ String ( candidate ) } ` ) ;
556+ }
557+ const normalizedCandidate = normalize ( candidate ) ;
558+ if ( normalizedCandidate === normalize ( gitEntry ) ) {
559+ return `gitdir: ${ worktreeGitDir } \n` ;
560+ }
561+ if ( normalizedCandidate === normalize ( commondirFile ) ) {
562+ return "..\\..\\\n" ;
563+ }
564+ if ( normalizedCandidate === normalize ( gitdirBackRefFile ) ) {
565+ return `${ canonicalBackRef } \n` ;
566+ }
567+ throw new Error ( `Unexpected read path: ${ String ( candidate ) } ` ) ;
568+ } ) ;
569+
570+ const resolved = resolveProjectStorageIdentityRoot ( projectRoot ) ;
571+ expect ( normalize ( resolved ) ) . toBe ( normalize ( sharedRepoRoot ) ) ;
572+ } finally {
573+ Object . defineProperty ( realpathSync , "native" , {
574+ value : originalNative ,
575+ configurable : true ,
576+ writable : true ,
577+ } ) ;
578+ }
579+ } ) ;
580+
443581 it ( "falls back to project root for forged worktree pointers" , ( ) => {
444582 const projectRoot = "/repo/attacker" ;
445583 const gitEntry = path . join ( projectRoot , ".git" ) ;
0 commit comments