@@ -380,114 +380,118 @@ func NewWorktrees(
380380 repoCommit := gitRunner .GetHeadCommit (ctx )
381381
382382 // Wrap entire worktree creation process with telemetry
383- traceErr := filter .TraceGitWorktreesCreate (ctx , workingDir , len (gitRefs ), repoRemote , repoBranch , repoCommit , func (ctx context.Context ) error {
384- var (
385- errs []error
386- mu sync.Mutex
387- )
383+ traceErr := filter .TraceGitWorktreesCreate (
384+ ctx , workingDir , len (gitRefs ), repoRemote , repoBranch , repoCommit ,
385+ func (ctx context.Context ) error {
386+ var (
387+ errs []error
388+ mu sync.Mutex
389+ )
388390
389- expressionsToDiffs := make (map [* filter.GitExpression ]* git.Diffs , len (gitExpressions ))
391+ expressionsToDiffs := make (map [* filter.GitExpression ]* git.Diffs , len (gitExpressions ))
390392
391- gitCmdGroup , gitCmdCtx := errgroup .WithContext (ctx )
392- // Cap concurrent git commands to the number of refs, but no more than available CPUs.
393- gitCmdGroup .SetLimit (min (runtime .GOMAXPROCS (0 ), len (gitRefs )))
393+ gitCmdGroup , gitCmdCtx := errgroup .WithContext (ctx )
394+ // Cap concurrent git commands to the number of refs, but no more than available CPUs.
395+ gitCmdGroup .SetLimit (min (runtime .GOMAXPROCS (0 ), len (gitRefs )))
394396
395- refsToPaths := make (map [string ]string , len (gitRefs ))
397+ refsToPaths := make (map [string ]string , len (gitRefs ))
398+
399+ if len (gitRefs ) > 0 {
400+ gitCmdGroup .Go (func () error {
401+ paths , err := createGitWorktrees (gitCmdCtx , l , gitRunner , gitRefs , repoRemote , repoBranch , repoCommit , experiments )
402+ if err != nil {
403+ mu .Lock ()
404+
405+ errs = append (errs , err )
406+
407+ mu .Unlock ()
408+
409+ return err
410+ }
396411
397- if len (gitRefs ) > 0 {
398- gitCmdGroup .Go (func () error {
399- paths , err := createGitWorktrees (gitCmdCtx , l , gitRunner , gitRefs , repoRemote , repoBranch , repoCommit , experiments )
400- if err != nil {
401412 mu .Lock ()
402413
403- errs = append ( errs , err )
414+ maps . Copy ( refsToPaths , paths )
404415
405416 mu .Unlock ()
406417
407- return err
408- }
418+ return nil
419+ })
420+ }
409421
410- mu .Lock ()
422+ for _ , gitExpression := range gitExpressions {
423+ gitCmdGroup .Go (func () error {
424+ // Wrap git diff with telemetry
425+ var diffs * git.Diffs
411426
412- maps .Copy (refsToPaths , paths )
427+ diffErr := filter .TraceGitDiff (
428+ gitCmdCtx , gitExpression .FromRef , gitExpression .ToRef , repoRemote ,
429+ func (ctx context.Context ) error {
430+ var err error
413431
414- mu . Unlock ( )
432+ diffs , err = gitRunner . Diff ( ctx , gitExpression . FromRef , gitExpression . ToRef )
415433
416- return nil
417- })
418- }
434+ return err
435+ })
436+ if diffErr != nil {
437+ mu .Lock ()
419438
420- for _ , gitExpression := range gitExpressions {
421- gitCmdGroup .Go (func () error {
422- // Wrap git diff with telemetry
423- var diffs * git.Diffs
439+ errs = append (errs , diffErr )
424440
425- diffErr := filter .TraceGitDiff (gitCmdCtx , gitExpression .FromRef , gitExpression .ToRef , repoRemote , func (ctx context.Context ) error {
426- var err error
441+ mu .Unlock ()
427442
428- diffs , err = gitRunner .Diff (ctx , gitExpression .FromRef , gitExpression .ToRef )
443+ return nil
444+ }
429445
430- return err
431- })
432- if diffErr != nil {
433446 mu .Lock ()
434447
435- errs = append ( errs , diffErr )
448+ expressionsToDiffs [ gitExpression ] = diffs
436449
437450 mu .Unlock ()
438451
439452 return nil
440- }
453+ })
454+ }
441455
442- mu .Lock ()
456+ if err := gitCmdGroup .Wait (); err != nil {
457+ worktrees = & Worktrees {
458+ WorktreePairs : make (map [string ]WorktreePair ),
459+ OriginalWorkingDir : workingDir ,
460+ gitRunner : gitRunner ,
461+ }
462+ outerErr = err
443463
444- expressionsToDiffs [gitExpression ] = diffs
464+ return err
465+ }
445466
446- mu .Unlock ()
467+ worktreePairs := make (map [string ]WorktreePair , len (gitExpressions ))
468+ for _ , gitExpression := range gitExpressions {
469+ worktreePairs [gitExpression .String ()] = WorktreePair {
470+ GitExpression : gitExpression ,
471+ Diffs : expressionsToDiffs [gitExpression ],
472+ FromWorktree : Worktree {Ref : gitExpression .FromRef , Path : refsToPaths [gitExpression .FromRef ]},
473+ ToWorktree : Worktree {Ref : gitExpression .ToRef , Path : refsToPaths [gitExpression .ToRef ]},
474+ }
447475
448- return nil
449- })
450- }
476+ // Record telemetry for diff results
477+ if diffs := expressionsToDiffs [gitExpression ]; diffs != nil {
478+ recordDiffTelemetry (ctx , diffs )
479+ }
480+ }
451481
452- if err := gitCmdGroup .Wait (); err != nil {
453482 worktrees = & Worktrees {
454- WorktreePairs : make ( map [ string ] WorktreePair ) ,
483+ WorktreePairs : worktreePairs ,
455484 OriginalWorkingDir : workingDir ,
456485 gitRunner : gitRunner ,
457486 }
458- outerErr = err
459-
460- return err
461- }
462487
463- worktreePairs := make (map [string ]WorktreePair , len (gitExpressions ))
464- for _ , gitExpression := range gitExpressions {
465- worktreePairs [gitExpression .String ()] = WorktreePair {
466- GitExpression : gitExpression ,
467- Diffs : expressionsToDiffs [gitExpression ],
468- FromWorktree : Worktree {Ref : gitExpression .FromRef , Path : refsToPaths [gitExpression .FromRef ]},
469- ToWorktree : Worktree {Ref : gitExpression .ToRef , Path : refsToPaths [gitExpression .ToRef ]},
488+ if len (errs ) > 0 {
489+ outerErr = errors .Join (errs ... )
490+ return outerErr
470491 }
471492
472- // Record telemetry for diff results
473- if diffs := expressionsToDiffs [gitExpression ]; diffs != nil {
474- recordDiffTelemetry (ctx , diffs )
475- }
476- }
477-
478- worktrees = & Worktrees {
479- WorktreePairs : worktreePairs ,
480- OriginalWorkingDir : workingDir ,
481- gitRunner : gitRunner ,
482- }
483-
484- if len (errs ) > 0 {
485- outerErr = errors .Join (errs ... )
486- return outerErr
487- }
488-
489- return nil
490- })
493+ return nil
494+ })
491495
492496 if traceErr != nil && outerErr == nil {
493497 l .Warnf ("telemetry trace error during worktree creation: %v" , traceErr )
@@ -599,18 +603,20 @@ func createGitWorktrees(
599603 }
600604
601605 // Wrap individual worktree creation with telemetry including repo info
602- err = filter .TraceGitWorktreeCreate (ctx , ref , tmpDir , repoRemote , repoBranch , repoCommit , func (ctx context.Context ) error {
603- if slowReporting {
604- return util .NotifyIfSlow (ctx , l , util .SpinnerWriter (), time .Second , util.SlowNotifyMsg {
605- Spinner : fmt .Sprintf ("Creating Git worktree for reference %s..." , ref ),
606- Done : "Created Git worktree for reference " + ref ,
607- }, func () error {
608- return gitRunner .CreateDetachedWorktree (ctx , tmpDir , ref )
609- })
610- }
606+ err = filter .TraceGitWorktreeCreate (
607+ ctx , ref , tmpDir , repoRemote , repoBranch , repoCommit ,
608+ func (ctx context.Context ) error {
609+ if slowReporting {
610+ return util .NotifyIfSlow (ctx , l , util .SpinnerWriter (), time .Second , util.SlowNotifyMsg {
611+ Spinner : fmt .Sprintf ("Creating Git worktree for reference %s..." , ref ),
612+ Done : "Created Git worktree for reference " + ref ,
613+ }, func () error {
614+ return gitRunner .CreateDetachedWorktree (ctx , tmpDir , ref )
615+ })
616+ }
611617
612- return gitRunner .CreateDetachedWorktree (ctx , tmpDir , ref )
613- })
618+ return gitRunner .CreateDetachedWorktree (ctx , tmpDir , ref )
619+ })
614620 if err != nil {
615621 if cleanErr := os .RemoveAll (tmpDir ); cleanErr != nil {
616622 l .Warnf ("failed to clean worktree directory %s: %v" , tmpDir , cleanErr )
0 commit comments