@@ -13,26 +13,26 @@ import (
13
13
)
14
14
15
15
type gitWalker struct {
16
- root string
17
- paths chan string
18
- repo * git.Repository
16
+ root string
17
+ paths chan string
18
+ repo * git.Repository
19
+ relPathOffset int
19
20
}
20
21
21
- func (g * gitWalker ) Root () string {
22
+ func (g gitWalker ) Root () string {
22
23
return g .root
23
24
}
24
25
25
- func (g * gitWalker ) Walk (ctx context.Context , fn WalkFunc ) error {
26
- // for quick relative paths
27
- relPathOffset := len (g .root ) + 1
28
-
29
- relPathFn := func (path string ) (relPath string ) {
30
- if len (path ) >= relPathOffset {
31
- relPath = path [relPathOffset :]
32
- }
33
- return
26
+ func (g gitWalker ) relPath (path string ) (string , error ) {
27
+ // quick optimization for the majority of use cases
28
+ if len (path ) >= g .relPathOffset && path [:len (g .root )] == g .root {
29
+ return path [g .relPathOffset :], nil
34
30
}
31
+ // fallback to proper relative path resolution
32
+ return filepath .Rel (g .root , path )
33
+ }
35
34
35
+ func (g gitWalker ) Walk (ctx context.Context , fn WalkFunc ) error {
36
36
idx , err := g .repo .Storer .Index ()
37
37
if err != nil {
38
38
return fmt .Errorf ("failed to open git index: %w" , err )
@@ -57,11 +57,21 @@ func (g *gitWalker) Walk(ctx context.Context, fn WalkFunc) error {
57
57
58
58
// stat the file
59
59
path := filepath .Join (g .root , entry .Name )
60
+
60
61
info , err := os .Lstat (path )
62
+ if err != nil {
63
+ return fmt .Errorf ("failed to stat %s: %w" , path , err )
64
+ }
65
+
66
+ // determine a relative path
67
+ relPath , err := g .relPath (path )
68
+ if err != nil {
69
+ return fmt .Errorf ("failed to determine a relative path for %s: %w" , path , err )
70
+ }
61
71
62
72
file := File {
63
73
Path : path ,
64
- RelPath : relPathFn ( path ) ,
74
+ RelPath : relPath ,
65
75
Info : info ,
66
76
}
67
77
@@ -97,9 +107,9 @@ func (g *gitWalker) Walk(ctx context.Context, fn WalkFunc) error {
97
107
return nil
98
108
}
99
109
100
- relPath , err := filepath . Rel ( g . root , path )
110
+ relPath , err := g . relPath ( path )
101
111
if err != nil {
102
- return err
112
+ return fmt . Errorf ( "failed to determine a relative path for %s: %w" , path , err )
103
113
}
104
114
105
115
if _ , ok := cache [relPath ]; ! ok {
@@ -109,7 +119,7 @@ func (g *gitWalker) Walk(ctx context.Context, fn WalkFunc) error {
109
119
110
120
file := File {
111
121
Path : path ,
112
- RelPath : relPathFn ( path ) ,
122
+ RelPath : relPath ,
113
123
Info : info ,
114
124
}
115
125
@@ -125,5 +135,10 @@ func NewGit(root string, paths chan string) (Walker, error) {
125
135
if err != nil {
126
136
return nil , fmt .Errorf ("failed to open git repo: %w" , err )
127
137
}
128
- return & gitWalker {root , paths , repo }, nil
138
+ return & gitWalker {
139
+ root : root ,
140
+ paths : paths ,
141
+ repo : repo ,
142
+ relPathOffset : len (root ) + 1 ,
143
+ }, nil
129
144
}
0 commit comments