@@ -28,6 +28,7 @@ type Repo struct {
28
28
BranchName string
29
29
Config config.ServerConfig
30
30
CloneURL string
31
+ Shallow bool
31
32
32
33
// exposed state
33
34
Directory string
@@ -46,6 +47,10 @@ func New(cfg config.ServerConfig, cloneUrl, branchName string) *Repo {
46
47
}
47
48
48
49
func (r * Repo ) Clone (ctx context.Context ) error {
50
+ if r .Shallow {
51
+ return r .ShallowClone (ctx )
52
+ }
53
+
49
54
var err error
50
55
51
56
r .Directory , err = os .MkdirTemp ("/tmp" , "kubechecks-repo-" )
@@ -85,6 +90,61 @@ func (r *Repo) Clone(ctx context.Context) error {
85
90
return nil
86
91
}
87
92
93
+ func (r * Repo ) ShallowClone (ctx context.Context ) error {
94
+ var err error
95
+
96
+ r .Directory , err = os .MkdirTemp ("/tmp" , "kubechecks-repo-" )
97
+ if err != nil {
98
+ return errors .Wrap (err , "failed to make temp dir" )
99
+ }
100
+
101
+ log .Info ().
102
+ Str ("temp-dir" , r .Directory ).
103
+ Str ("clone-url" , r .CloneURL ).
104
+ Str ("branch" , r .BranchName ).
105
+ Msg ("cloning git repo" )
106
+
107
+ // Attempt to locally clone the repo based on the provided information stored within
108
+ _ , span := tracer .Start (ctx , "ShallowCloneRepo" )
109
+ defer span .End ()
110
+
111
+ args := []string {"clone" , r .CloneURL , r .Directory , "--depth" , "1" }
112
+ cmd := r .execGitCommand (args ... )
113
+ out , err := cmd .CombinedOutput ()
114
+ if err != nil {
115
+ log .Error ().Err (err ).Msgf ("unable to clone repository, %s" , out )
116
+ return err
117
+ }
118
+
119
+ if r .BranchName != "HEAD" {
120
+ // Fetch SHA
121
+ args = []string {"fetch" , "origin" , r .BranchName , "--depth" , "1" }
122
+ cmd = r .execGitCommand (args ... )
123
+ out , err = cmd .CombinedOutput ()
124
+ if err != nil {
125
+ log .Error ().Err (err ).Msgf ("unable to fetch %s repository, %s" , r .BranchName , out )
126
+ return err
127
+ }
128
+ // Checkout SHA
129
+ args = []string {"checkout" , r .BranchName }
130
+ cmd = r .execGitCommand (args ... )
131
+ out , err = cmd .CombinedOutput ()
132
+ if err != nil {
133
+ log .Error ().Err (err ).Msgf ("unable to checkout branch %s repository, %s" , r .BranchName , out )
134
+ return err
135
+ }
136
+ }
137
+
138
+ if log .Trace ().Enabled () {
139
+ if err = filepath .WalkDir (r .Directory , printFile ); err != nil {
140
+ log .Warn ().Err (err ).Msg ("failed to walk directory" )
141
+ }
142
+ }
143
+
144
+ log .Info ().Msg ("repo has been cloned" )
145
+ return nil
146
+ }
147
+
88
148
func printFile (s string , d fs.DirEntry , err error ) error {
89
149
if err != nil {
90
150
return err
@@ -118,8 +178,23 @@ func (r *Repo) MergeIntoTarget(ctx context.Context, ref string) error {
118
178
attribute .String ("sha" , ref ),
119
179
))
120
180
defer span .End ()
181
+ merge_command := []string {"merge" , ref }
182
+ // For shallow clones, we need to pull the ref into the repo
183
+ if r .Shallow {
184
+ ref = strings .TrimPrefix (ref , "origin/" )
185
+ cmd := r .execGitCommand ("fetch" , "origin" , fmt .Sprintf ("%s:%s" , ref , ref ), "--depth" , "1" )
186
+ out , err := cmd .CombinedOutput ()
187
+ if err != nil {
188
+ telemetry .SetError (span , err , "fetch origin ref" )
189
+ log .Error ().Err (err ).Msgf ("unable to fetch ref %s, %s" , ref , out )
190
+ return err
191
+ }
192
+ // When merging shallow clones, we need to allow unrelated histories
193
+ // and use the "theirs" strategy to avoid conflicts
194
+ merge_command = []string {"merge" , ref , "--allow-unrelated-histories" , "-X" , "theirs" }
195
+ }
121
196
122
- cmd := r .execGitCommand ("merge" , ref )
197
+ cmd := r .execGitCommand (merge_command ... )
123
198
out , err := cmd .CombinedOutput ()
124
199
if err != nil {
125
200
telemetry .SetError (span , err , "merge commit into branch" )
@@ -130,7 +205,12 @@ func (r *Repo) MergeIntoTarget(ctx context.Context, ref string) error {
130
205
return nil
131
206
}
132
207
208
+ // Since we're shallow cloning, to update we need to wipe the directory and re-clone
133
209
func (r * Repo ) Update (ctx context.Context ) error {
210
+ if r .Shallow {
211
+ r .Wipe ()
212
+ return r .Clone (ctx )
213
+ }
134
214
cmd := r .execGitCommand ("pull" )
135
215
cmd .Stdout = os .Stdout
136
216
cmd .Stderr = os .Stdout
0 commit comments