@@ -24,6 +24,10 @@ export interface FileSourceFetcher {
2424 getFullText ( side : FileSourceSide ) : Promise < string | null > ;
2525}
2626
27+ export interface FileSourceFetcherOptions {
28+ gitExecutable ?: string ;
29+ }
30+
2731interface ResolvedSpecs {
2832 old : FileSourceSpec ;
2933 new : FileSourceSpec ;
@@ -77,27 +81,27 @@ async function readFsSpec(spec: Extract<FileSourceSpec, { kind: "fs" }>): Promis
7781function readGitBlobSpec (
7882 spec : Extract < FileSourceSpec , { kind : "git-blob" } > ,
7983 gitExecutable = "git" ,
80- ) : string | null {
84+ ) : Promise < string | null > {
8185 return readGitObjectSpec ( spec . repoRoot , `${ spec . ref } :${ spec . path } ` , gitExecutable ) ;
8286}
8387
8488function readGitIndexSpec (
8589 spec : Extract < FileSourceSpec , { kind : "git-index" } > ,
8690 gitExecutable = "git" ,
87- ) : string | null {
91+ ) : Promise < string | null > {
8892 return readGitObjectSpec ( spec . repoRoot , `:${ spec . path } ` , gitExecutable ) ;
8993}
9094
9195/** Read a blob-like Git object spec such as `HEAD:path` or `:path`. */
92- function readGitObjectSpec (
96+ async function readGitObjectSpec (
9397 repoRoot : string ,
9498 objectName : string ,
9599 gitExecutable = "git" ,
96- ) : string | null {
97- let proc : ReturnType < typeof Bun . spawnSync > ;
100+ ) : Promise < string | null > {
101+ let proc : Bun . ReadableSubprocess ;
98102
99103 try {
100- proc = Bun . spawnSync ( [ gitExecutable , "show" , objectName ] , {
104+ proc = Bun . spawn ( [ gitExecutable , "show" , objectName ] , {
101105 cwd : repoRoot ,
102106 stdin : "ignore" ,
103107 stdout : "pipe" ,
@@ -108,18 +112,34 @@ function readGitObjectSpec(
108112 return null ;
109113 }
110114
111- if ( proc . exitCode !== 0 ) {
112- const stderr = Buffer . from ( proc . stderr ?? [ ] ) . toString ( "utf8" ) ;
115+ let output : [ number , string , string ] ;
116+ try {
117+ output = await Promise . all ( [
118+ proc . exited ,
119+ new Response ( proc . stdout ) . text ( ) ,
120+ new Response ( proc . stderr ) . text ( ) ,
121+ ] ) ;
122+ } catch ( error ) {
123+ logSourceDiagnostic ( `failed to collect Git source ${ objectName } ` , error ) ;
124+ return null ;
125+ }
126+
127+ const [ exitCode , stdout , stderr ] = output ;
128+
129+ if ( exitCode !== 0 ) {
113130 if ( ! isExpectedMissingGitSource ( stderr ) ) {
114131 logSourceDiagnostic ( `failed to read Git source ${ objectName } in ${ repoRoot } ` , stderr ) ;
115132 }
116133 return null ;
117134 }
118135
119- return Buffer . from ( proc . stdout ?? [ ] ) . toString ( "utf8" ) ;
136+ return stdout ;
120137}
121138
122- async function readSpec ( spec : FileSourceSpec ) : Promise < string | null > {
139+ async function readSpec (
140+ spec : FileSourceSpec ,
141+ { gitExecutable = "git" } : FileSourceFetcherOptions = { } ,
142+ ) : Promise < string | null > {
123143 if ( spec . kind === "none" ) {
124144 return null ;
125145 }
@@ -129,14 +149,17 @@ async function readSpec(spec: FileSourceSpec): Promise<string | null> {
129149 }
130150
131151 if ( spec . kind === "git-index" ) {
132- return readGitIndexSpec ( spec ) ;
152+ return readGitIndexSpec ( spec , gitExecutable ) ;
133153 }
134154
135- return readGitBlobSpec ( spec ) ;
155+ return readGitBlobSpec ( spec , gitExecutable ) ;
136156}
137157
138158/** Build a per-file source fetcher that caches each side's resolved text. */
139- export function createFileSourceFetcher ( specs : ResolvedSpecs ) : FileSourceFetcher {
159+ export function createFileSourceFetcher (
160+ specs : ResolvedSpecs ,
161+ { gitExecutable = "git" } : Readonly < FileSourceFetcherOptions > = { } ,
162+ ) : FileSourceFetcher {
140163 const cache = new Map < FileSourceSide , string | null > ( ) ;
141164
142165 return {
@@ -145,7 +168,7 @@ export function createFileSourceFetcher(specs: ResolvedSpecs): FileSourceFetcher
145168 return cache . get ( side ) ?? null ;
146169 }
147170
148- const text = await readSpec ( specs [ side ] ) ;
171+ const text = await readSpec ( specs [ side ] , { gitExecutable } ) ;
149172 cache . set ( side , text ) ;
150173 return text ;
151174 } ,
0 commit comments