@@ -387,7 +387,9 @@ func (impl *GitManagerBaseImpl) createCmdWithContext(ctx GitContext, name string
387387 //TODO: how to make it generic, currently works because the
388388 // git command is placed at index 2 for current implementations
389389 timeout := 0
390+ command := ""
390391 if len (arg ) > 2 {
392+ command = arg [2 ]
391393 timeout = impl .getCommandTimeout (arg [2 ])
392394 }
393395 if timeout > 0 {
@@ -406,6 +408,13 @@ func (impl *GitManagerBaseImpl) createCmdWithContext(ctx GitContext, name string
406408 } else {
407409 impl .logger .Infow ("sucess cancel command" , "name" , name , "arg" , arg )
408410 }
411+
412+ // Run git gc --prune=now to clean up temp.pack files left by killed git commands
413+ if impl .conf .EnableManualGitGc && name == "git" && command == "fetch" {
414+ if rootDir := impl .extractRootDirFromArgs (arg ); rootDir != "" {
415+ impl .runGitGcWithTimeout (rootDir , 5 * time .Minute )
416+ }
417+ }
409418 return err
410419 }
411420 return cmd , newCtx , cancel
@@ -431,3 +440,35 @@ func (impl *GitManagerBaseImpl) ExecuteCustomCommand(gitContext GitContext, name
431440 output , errMsg , err := impl .runCommandWithCred (cmd , newGitCtx , gitContext .Username , gitContext .Password , tlsPathInfo )
432441 return output , errMsg , err
433442}
443+
444+ // extractRootDirFromArgs extracts the root directory from git command arguments.
445+ // It looks for the -C flag which specifies the directory to run git commands in.
446+ func (impl * GitManagerBaseImpl ) extractRootDirFromArgs (args []string ) string {
447+ for i , arg := range args {
448+ if arg == "-C" && i + 1 < len (args ) {
449+ return args [i + 1 ]
450+ }
451+ }
452+ return ""
453+ }
454+
455+ // runGitGcWithTimeout runs git gc --prune=now with a timeout to clean up
456+ // temporary pack files left behind when git commands are killed/cancelled.
457+ func (impl * GitManagerBaseImpl ) runGitGcWithTimeout (rootDir string , timeout time.Duration ) {
458+ ctx , cancel := context .WithTimeout (context .Background (), timeout )
459+ defer cancel ()
460+
461+ impl .logger .Infow ("running git gc --prune=now" , "rootDir" , rootDir , "timeout" , timeout )
462+ cmd := exec .CommandContext (ctx , "git" , "-C" , rootDir , "gc" , "--prune=now" )
463+ cmd .Env = append (os .Environ (), "HOME=/dev/null" )
464+ output , err := cmd .CombinedOutput ()
465+ if err != nil {
466+ if errors .Is (ctx .Err (), context .DeadlineExceeded ) {
467+ impl .logger .Warnw ("git gc timed out" , "rootDir" , rootDir , "timeout" , timeout )
468+ } else {
469+ impl .logger .Errorw ("error running git gc" , "rootDir" , rootDir , "err" , err , "output" , string (output ))
470+ }
471+ } else {
472+ impl .logger .Infow ("git gc completed successfully" , "rootDir" , rootDir )
473+ }
474+ }
0 commit comments