@@ -7,14 +7,49 @@ import { eq } from "drizzle-orm";
77import type { StageDb } from "../db/client.js" ;
88import type { ChapterRunRow } from "../db/schema/chapter-run.js" ;
99import { chapterRun } from "../db/schema/index.js" ;
10- import { buildDiffArgs } from "../git.js" ;
10+ import { buildDiffArgs , hasStringStdout } from "../git.js" ;
1111import { SCOPE_KIND , WORKING_TREE_REF } from "../schema.js" ;
1212import type { Route } from "../server.js" ;
1313import { writeJson } from "./json.js" ;
1414
1515const execFileAsync = promisify ( execFile ) ;
1616
1717const MAX_FILE_BYTES = 5 * 1024 * 1024 ;
18+ const MAX_DIFF_BYTES = 50 * 1024 * 1024 ;
19+
20+ async function buildUntrackedPatch ( cwd : string ) : Promise < string > {
21+ const { stdout } = await execFileAsync ( "git" , [ "ls-files" , "--others" , "--exclude-standard" ] , {
22+ cwd,
23+ encoding : "utf8" ,
24+ } ) ;
25+ const files = stdout . trim ( ) ? stdout . trim ( ) . split ( "\n" ) : [ ] ;
26+ if ( files . length === 0 ) return "" ;
27+
28+ const patches = await Promise . all (
29+ files . map ( async ( file ) => {
30+ try {
31+ await execFileAsync (
32+ "git" ,
33+ [
34+ "diff" ,
35+ "--no-index" ,
36+ "--no-color" ,
37+ "--src-prefix=a/" ,
38+ "--dst-prefix=b/" ,
39+ "--" ,
40+ "/dev/null" ,
41+ file ,
42+ ] ,
43+ { cwd, encoding : "utf8" , maxBuffer : MAX_DIFF_BYTES } ,
44+ ) ;
45+ return "" ;
46+ } catch ( err : unknown ) {
47+ return hasStringStdout ( err ) ? err . stdout : "" ;
48+ }
49+ } ) ,
50+ ) ;
51+ return patches . filter ( Boolean ) . join ( "\n" ) ;
52+ }
1853
1954export function diffRoutes ( db : StageDb ) : Route [ ] {
2055 return [
@@ -47,11 +82,23 @@ export function diffRoutes(db: StageDb): Route[] {
4782 run . scopeKind === SCOPE_KIND . COMMITTED ? "private, max-age=300" : "no-store" ;
4883
4984 try {
50- const { stdout : patch } = await execFileAsync ( "git" , args , {
85+ const { stdout : trackedPatch } = await execFileAsync ( "git" , args , {
5186 cwd : repoRoot ,
5287 encoding : "utf8" ,
53- maxBuffer : 50 * 1024 * 1024 ,
88+ maxBuffer : MAX_DIFF_BYTES ,
5489 } ) ;
90+
91+ let patch = trackedPatch ;
92+ if (
93+ run . scopeKind === SCOPE_KIND . WORKING_TREE &&
94+ run . workingTreeRef === WORKING_TREE_REF . WORK
95+ ) {
96+ const untrackedPatch = await buildUntrackedPatch ( repoRoot ) ;
97+ if ( untrackedPatch ) {
98+ patch = patch ? `${ patch } \n${ untrackedPatch } ` : untrackedPatch ;
99+ }
100+ }
101+
55102 const fileContents = await buildFileContents ( run , repoRoot , patch ) ;
56103 const body : DiffResponse = { patch, fileContents } ;
57104 res . writeHead ( 200 , {
0 commit comments