@@ -2,7 +2,7 @@ import { execFileSync } from 'child_process'
22import { createHash } from 'crypto'
33import fs from 'fs'
44import os from 'os'
5- import { join } from 'path'
5+ import path , { join } from 'path'
66
77import {
88 add ,
@@ -15,6 +15,7 @@ import {
1515 statusMatrix ,
1616} from 'isomorphic-git'
1717
18+ import { buildArray } from 'common/util/array'
1819import { getProjectDataDir } from '../project-files'
1920import { gitCommandIsAvailable } from '../utils/git'
2021import { logger } from '../utils/logger'
@@ -61,12 +62,14 @@ export async function hasUnsavedChanges({
6162 ] ,
6263 { stdio : [ 'ignore' , 'pipe' , 'ignore' ] }
6364 ) . toString ( )
64- return output . trim ( ) . length > 0
65+ return (
66+ buildArray ( output . split ( '\n' ) . filter ( ( line ) => ! line . startsWith ( ' M ' ) ) )
67+ . length > 0
68+ )
6569 } catch ( error ) {
6670 logger . error (
6771 {
68- errorMessage : error instanceof Error ? error . message : String ( error ) ,
69- errorStack : error instanceof Error ? error . stack : undefined ,
72+ error,
7073 projectDir,
7174 bareRepoPath,
7275 } ,
@@ -200,6 +203,8 @@ async function gitAddAll({
200203 projectDir ,
201204 'add' ,
202205 '.' ,
206+ ':!**/*.codebuffbackup' ,
207+ ':!**/*.codebuffbackup/**' ,
203208 ] ,
204209 { stdio : 'ignore' }
205210 )
@@ -271,6 +276,113 @@ async function gitAddAll({
271276 }
272277}
273278
279+ async function gitAddAllIgnoringNestedRepos ( {
280+ projectDir,
281+ bareRepoPath,
282+ relativeFilepaths,
283+ } : {
284+ projectDir : string
285+ bareRepoPath : string
286+ relativeFilepaths : Array < string >
287+ } ) : Promise < void > {
288+ const allNestedRepos : string [ ] = [ ]
289+ try {
290+ while ( true ) {
291+ let output : string
292+ try {
293+ output = execFileSync (
294+ 'git' ,
295+ [
296+ '--git-dir' ,
297+ bareRepoPath ,
298+ '--work-tree' ,
299+ projectDir ,
300+ 'status' ,
301+ '--porcelain' ,
302+ ] ,
303+ { stdio : [ 'ignore' , 'pipe' , 'ignore' ] }
304+ ) . toString ( )
305+ } catch ( error ) {
306+ logger . error (
307+ { error, projectDir, bareRepoPath } ,
308+ 'Failed to get git status while finding nested git repos'
309+ )
310+ return
311+ }
312+
313+ if ( ! output ) {
314+ break
315+ }
316+
317+ const nestedRepos = buildArray ( output . split ( '\n' ) )
318+ . filter ( ( line ) => line [ 1 ] === 'M' )
319+ . map ( ( line ) => line . slice ( 3 ) . trim ( ) )
320+
321+ await gitAddAll ( { projectDir, bareRepoPath, relativeFilepaths } )
322+
323+ if ( nestedRepos . length === 0 ) {
324+ break
325+ }
326+
327+ for ( const nestedRepo of nestedRepos ) {
328+ try {
329+ fs . renameSync (
330+ path . join ( projectDir , nestedRepo , '.git' ) ,
331+ path . join ( projectDir , nestedRepo , '.git.codebuffbackup' )
332+ )
333+ allNestedRepos . push ( nestedRepo )
334+ } catch ( error ) {
335+ logger . error (
336+ {
337+ error,
338+ nestedRepo,
339+ } ,
340+ 'Failed to backup .git directory for nested repo'
341+ )
342+ }
343+ }
344+
345+ execFileSync ( 'git' , [
346+ '--git-dir' ,
347+ bareRepoPath ,
348+ '--work-tree' ,
349+ projectDir ,
350+ '-C' ,
351+ projectDir ,
352+ 'rm' ,
353+ '--cached' ,
354+ '-rf' ,
355+ ...nestedRepos ,
356+ ] )
357+ }
358+ } finally {
359+ for ( const nestedRepo of allNestedRepos ) {
360+ const codebuffBackup = path . join (
361+ projectDir ,
362+ nestedRepo ,
363+ '.git.codebuffbackup'
364+ )
365+ const gitDir = path . join ( projectDir , nestedRepo , '.git' )
366+ try {
367+ fs . renameSync ( codebuffBackup , gitDir )
368+ } catch ( error ) {
369+ console . error (
370+ `Failed to restore .git directory for nested repo. Please rename ${ codebuffBackup } to ${ gitDir } \n${ { error } } `
371+ )
372+ logger . error (
373+ {
374+ errorMessage :
375+ error instanceof Error ? error . message : String ( error ) ,
376+ errorStack : error instanceof Error ? error . stack : undefined ,
377+ nestedRepo,
378+ } ,
379+ 'Failed to restore .git directory for nested repo'
380+ )
381+ }
382+ }
383+ }
384+ }
385+
274386async function gitCommit ( {
275387 projectDir,
276388 bareRepoPath,
@@ -337,8 +449,7 @@ async function gitCommit({
337449 } catch ( error ) {
338450 logger . error (
339451 {
340- errorMessage : error instanceof Error ? error . message : String ( error ) ,
341- errorStack : error instanceof Error ? error . stack : undefined ,
452+ error,
342453 projectDir,
343454 bareRepoPath,
344455 } ,
@@ -372,7 +483,7 @@ export async function storeFileState({
372483 message : string
373484 relativeFilepaths : Array < string >
374485} ) : Promise < string > {
375- await gitAddAll ( {
486+ await gitAddAllIgnoringNestedRepos ( {
376487 projectDir,
377488 bareRepoPath,
378489 relativeFilepaths,
0 commit comments