@@ -43,6 +43,7 @@ type Handler struct {
4343 gitRepo * git.Repository
4444 tempDir string
4545 commitSHA string
46+ files []string
4647}
4748
4849func (h * Handler ) Init (ctx context.Context , cloneURL , commitSHA string ) {
@@ -51,6 +52,7 @@ func (h *Handler) Init(ctx context.Context, cloneURL, commitSHA string) {
5152 h .ctx = ctx
5253 h .cloneURL = cloneURL
5354 h .commitSHA = commitSHA
55+ h .files = nil
5456}
5557
5658func (h * Handler ) setup () error {
@@ -85,6 +87,15 @@ func (h *Handler) setup() error {
8587 return
8688 }
8789 }
90+
91+ // go-git is not thread-safe so list the files inside this sync.Once and save them
92+ // https://github.com/go-git/go-git/issues/773
93+ files , err := enumerateFiles (h .gitRepo )
94+ if err != nil {
95+ h .errSetup = err
96+ return
97+ }
98+ h .files = files
8899 })
89100 return h .errSetup
90101}
@@ -100,12 +111,27 @@ func (h *Handler) ListFiles(predicate func(string) (bool, error)) ([]string, err
100111 if err := h .setup (); err != nil {
101112 return nil , fmt .Errorf ("setup: %w" , err )
102113 }
103- ref , err := h .gitRepo .Head ()
114+ var files []string
115+ for _ , f := range h .files {
116+ shouldInclude , err := predicate (f )
117+ if err != nil {
118+ return nil , fmt .Errorf ("error applying predicate to file %s: %w" , f , err )
119+ }
120+
121+ if shouldInclude {
122+ files = append (files , f )
123+ }
124+ }
125+ return files , nil
126+ }
127+
128+ func enumerateFiles (repo * git.Repository ) ([]string , error ) {
129+ ref , err := repo .Head ()
104130 if err != nil {
105131 return nil , fmt .Errorf ("git.Head: %w" , err )
106132 }
107133
108- commit , err := h . gitRepo .CommitObject (ref .Hash ())
134+ commit , err := repo .CommitObject (ref .Hash ())
109135 if err != nil {
110136 return nil , fmt .Errorf ("git.CommitObject: %w" , err )
111137 }
@@ -117,14 +143,7 @@ func (h *Handler) ListFiles(predicate func(string) (bool, error)) ([]string, err
117143
118144 var files []string
119145 err = tree .Files ().ForEach (func (f * object.File ) error {
120- shouldInclude , err := predicate (f .Name )
121- if err != nil {
122- return fmt .Errorf ("error applying predicate to file %s: %w" , f .Name , err )
123- }
124-
125- if shouldInclude {
126- files = append (files , f .Name )
127- }
146+ files = append (files , f .Name )
128147 return nil
129148 })
130149 if err != nil {
0 commit comments