@@ -2,6 +2,7 @@ package mirror
2
2
3
3
import (
4
4
"context"
5
+ "errors"
5
6
"fmt"
6
7
"io/fs"
7
8
"log/slog"
@@ -25,6 +26,9 @@ const (
25
26
)
26
27
27
28
var (
29
+ ErrRepoMirrorFailed = errors .New ("repository mirror failed" )
30
+ ErrRepoWTUpdateFailed = errors .New ("repository worktree update failed" )
31
+
28
32
gitExecutablePath string
29
33
staleTimeout time.Duration = 10 * time .Second // time for stale worktrees to be cleaned up
30
34
@@ -135,7 +139,7 @@ func NewRepository(repoConf RepositoryConfig, envs []string, log *slog.Logger) (
135
139
136
140
for _ , wtc := range repoConf .Worktrees {
137
141
if err := repo .AddWorktreeLink (wtc ); err != nil {
138
- return nil , fmt .Errorf ("unable to create worktree link err:%w" , err )
142
+ return nil , fmt .Errorf ("unable to add worktree link err:%w" , err )
139
143
}
140
144
}
141
145
return repo , nil
@@ -477,35 +481,40 @@ func (r *Repository) Mirror(ctx context.Context) error {
477
481
start := time .Now ()
478
482
479
483
if err := r .init (ctx ); err != nil {
480
- return fmt .Errorf ("unable to init repo:%s err:%w" , r .gitURL .Repo , err )
484
+ r .log .Error ("unable to init repo" , "err" , err )
485
+ return ErrRepoMirrorFailed
481
486
}
482
487
483
488
refs , err := r .fetch (ctx )
484
489
if err != nil {
485
- return fmt .Errorf ("unable to fetch repo:%s err:%w" , r .gitURL .Repo , err )
490
+ r .log .Error ("unable to fetch repo" , "err" , err )
491
+ return ErrRepoMirrorFailed
486
492
}
487
493
488
494
fetchTime := time .Since (start )
489
495
496
+ var wtError error
490
497
// worktree might need re-creating if it fails check
491
- // so always ensure worktree even if nothing fetched
498
+ // so always ensure worktree even if nothing fetched.
499
+ // continue on error to make sync process more resilient
492
500
for _ , wl := range r .workTreeLinks {
493
501
if err := r .ensureWorktreeLink (ctx , wl ); err != nil {
494
- return fmt .Errorf ("unable to ensure worktree links repo:%s link:%s err:%w" , r .gitURL .Repo , wl .link , err )
502
+ r .log .Error ("unable to ensure worktree links" , "err" , err )
503
+ wtError = ErrRepoWTUpdateFailed
495
504
}
496
505
}
497
506
498
507
// clean-up can be skipped
499
508
if len (refs ) == 0 {
500
- return nil
509
+ return wtError
501
510
}
502
511
503
512
if err := r .cleanup (ctx ); err != nil {
504
- return fmt . Errorf ("unable to cleanup repo:%s err:%w " , r . gitURL . Repo , err )
513
+ r . log . Error ("unable to cleanup repo" , "err" , err )
505
514
}
506
515
507
516
r .log .Debug ("mirror cycle complete" , "time" , time .Since (start ), "fetch-time" , fetchTime , "updated-refs" , len (refs ))
508
- return nil
517
+ return wtError
509
518
}
510
519
511
520
// RemoveWorktreeLink removes workTree link from the mirror repository.
@@ -742,6 +751,13 @@ func (r *Repository) ensureWorktreeLink(ctx context.Context, wl *WorkTreeLink) e
742
751
if err != nil {
743
752
return fmt .Errorf ("unable to get hash for worktree:%s err:%w" , wl .link , err )
744
753
}
754
+
755
+ // if we get empty remote hash so either given worktree ref do not exits yet or
756
+ // its removed from the remote
757
+ if remoteHash == "" {
758
+ return fmt .Errorf ("hash not found for given ref:%s for worktree:%s" , wl .ref , wl .link )
759
+ }
760
+
745
761
var currentHash , currentPath string
746
762
747
763
// we do not care if we cant get old worktree path as we can create it
@@ -760,26 +776,6 @@ func (r *Repository) ensureWorktreeLink(ctx context.Context, wl *WorkTreeLink) e
760
776
}
761
777
}
762
778
763
- // we got empty remote hash so either given worktree ref do not exits yet or
764
- // its removed from the remote
765
- if remoteHash == "" {
766
- wt , err := wl .currentWorktree ()
767
- if err != nil {
768
- wl .log .Error ("can't get current worktree" , "err" , err )
769
- return nil
770
- }
771
- if wt == "" {
772
- return nil
773
- }
774
-
775
- wl .log .Info ("remote hash is empty, removing old worktree" , "path" , currentPath )
776
- if err := r .removeWorktree (ctx , wt ); err != nil {
777
- wl .log .Error ("unable to remove old worktree" , "err" , err )
778
- }
779
-
780
- return nil
781
- }
782
-
783
779
if currentHash == remoteHash {
784
780
if wl .sanityCheckWorktree (ctx ) {
785
781
return nil
@@ -815,6 +811,8 @@ func (r *Repository) createWorktree(ctx context.Context, wl *WorkTreeLink, hash
815
811
816
812
// remove any existing worktree as we cant create new worktree if path is
817
813
// not empty
814
+ // since wtPath contains git hash it will always be either new path or
815
+ // existing worktree with failed sanity check
818
816
if err := r .removeWorktree (ctx , wtPath ); err != nil {
819
817
return wtPath , err
820
818
}
0 commit comments