@@ -140,6 +140,43 @@ func parseRemoteUpdateOutput(output string) []*mirrorSyncResult {
140
140
return results
141
141
}
142
142
143
+ func pruneBrokenReferences (ctx context.Context ,
144
+ m * models.Mirror ,
145
+ repoPath string ,
146
+ timeout time.Duration ,
147
+ stdoutBuilder , stderrBuilder * strings.Builder ,
148
+ sanitizer * strings.Replacer ,
149
+ isWiki bool ) error {
150
+
151
+ wiki := ""
152
+ if isWiki {
153
+ wiki = "Wiki "
154
+ }
155
+
156
+ stderrBuilder .Reset ()
157
+ stdoutBuilder .Reset ()
158
+ pruneErr := git .NewCommandContext (ctx , "remote" , "prune" , m .GetRemoteName ()).
159
+ SetDescription (fmt .Sprintf ("Mirror.runSync %ssPrune references: %s " , wiki , m .Repo .FullName ())).
160
+ RunInDirTimeoutPipeline (timeout , repoPath , stdoutBuilder , stderrBuilder )
161
+ if pruneErr != nil {
162
+ stdout := stdoutBuilder .String ()
163
+ stderr := stderrBuilder .String ()
164
+
165
+ // sanitize the output, since it may contain the remote address, which may
166
+ // contain a password
167
+ stderrMessage := sanitizer .Replace (stderr )
168
+ stdoutMessage := sanitizer .Replace (stdout )
169
+
170
+ log .Error ("Failed to prune mirror repository %s%-v references:\n Stdout: %s\n Stderr: %s\n Err: %v" , wiki , m .Repo , stdoutMessage , stderrMessage , pruneErr )
171
+ desc := fmt .Sprintf ("Failed to prune mirror repository %s'%s' references: %s" , wiki , repoPath , stderrMessage )
172
+ if err := models .CreateRepositoryNotice (desc ); err != nil {
173
+ log .Error ("CreateRepositoryNotice: %v" , err )
174
+ }
175
+ // this if will only be reached on a successful prune so try to get the mirror again
176
+ }
177
+ return pruneErr
178
+ }
179
+
143
180
// runSync returns true if sync finished without error.
144
181
func runSync (ctx context.Context , m * models.Mirror ) ([]* mirrorSyncResult , bool ) {
145
182
repoPath := m .Repo .RepoPath ()
@@ -160,7 +197,7 @@ func runSync(ctx context.Context, m *models.Mirror) ([]*mirrorSyncResult, bool)
160
197
161
198
stdoutBuilder := strings.Builder {}
162
199
stderrBuilder := strings.Builder {}
163
- if err := git .NewCommand ( gitArgs ... ).
200
+ if err := git .NewCommandContext ( ctx , gitArgs ... ).
164
201
SetDescription (fmt .Sprintf ("Mirror.runSync: %s" , m .Repo .FullName ())).
165
202
RunInDirTimeoutPipeline (timeout , repoPath , & stdoutBuilder , & stderrBuilder ); err != nil {
166
203
stdout := stdoutBuilder .String ()
@@ -178,35 +215,22 @@ func runSync(ctx context.Context, m *models.Mirror) ([]*mirrorSyncResult, bool)
178
215
err = nil
179
216
180
217
// Attempt prune
181
- stderrBuilder .Reset ()
182
- stdoutBuilder .Reset ()
183
- if pruneErr := git .NewCommand ("remote" , "prune" , m .GetRemoteName ()).
184
- SetDescription (fmt .Sprintf ("Mirror.runSync Prune references: %s " , m .Repo .FullName ())).
185
- RunInDirTimeoutPipeline (timeout , repoPath , & stdoutBuilder , & stderrBuilder ); pruneErr != nil {
186
- stdout := stdoutBuilder .String ()
187
- stderr := stderrBuilder .String ()
188
-
189
- // sanitize the output, since it may contain the remote address, which may
190
- // contain a password
191
- stderrMessage := sanitizer .Replace (stderr )
192
- stdoutMessage := sanitizer .Replace (stdout )
193
-
194
- log .Error ("Failed to prune mirror repository %-v references:\n Stdout: %s\n Stderr: %s\n Err: %v" , m .Repo , stdoutMessage , stderrMessage , pruneErr )
195
- desc := fmt .Sprintf ("Failed to prune mirror repository '%s' references: %s" , repoPath , stderrMessage )
196
- if err := models .CreateRepositoryNotice (desc ); err != nil {
197
- log .Error ("CreateRepositoryNotice: %v" , err )
218
+ pruneErr := pruneBrokenReferences (ctx , m , repoPath , timeout , & stdoutBuilder , & stderrBuilder , sanitizer , false )
219
+ if pruneErr == nil {
220
+ // Successful prune - reattempt mirror
221
+ stderrBuilder .Reset ()
222
+ stdoutBuilder .Reset ()
223
+ if err = git .NewCommandContext (ctx , gitArgs ... ).
224
+ SetDescription (fmt .Sprintf ("Mirror.runSync: %s" , m .Repo .FullName ())).
225
+ RunInDirTimeoutPipeline (timeout , repoPath , & stdoutBuilder , & stderrBuilder ); err != nil {
226
+ stdout := stdoutBuilder .String ()
227
+ stderr := stderrBuilder .String ()
228
+
229
+ // sanitize the output, since it may contain the remote address, which may
230
+ // contain a password
231
+ stderrMessage = sanitizer .Replace (stderr )
232
+ stdoutMessage = sanitizer .Replace (stdout )
198
233
}
199
- // this if will only be reached on a successful prune so try to get the mirror again
200
- } else if err = git .NewCommand (gitArgs ... ).
201
- SetDescription (fmt .Sprintf ("Mirror.runSync: %s" , m .Repo .FullName ())).
202
- RunInDirTimeoutPipeline (timeout , repoPath , & stdoutBuilder , & stderrBuilder ); err != nil {
203
- stdout := stdoutBuilder .String ()
204
- stderr := stderrBuilder .String ()
205
-
206
- // sanitize the output, since it may contain the remote address, which may
207
- // contain a password
208
- stderrMessage = sanitizer .Replace (stderr )
209
- stdoutMessage = sanitizer .Replace (stdout )
210
234
}
211
235
}
212
236
@@ -251,7 +275,7 @@ func runSync(ctx context.Context, m *models.Mirror) ([]*mirrorSyncResult, bool)
251
275
log .Trace ("SyncMirrors [repo: %-v Wiki]: running git remote update..." , m .Repo )
252
276
stderrBuilder .Reset ()
253
277
stdoutBuilder .Reset ()
254
- if err := git .NewCommand ( "remote" , "update" , "--prune" , m .GetRemoteName ()).
278
+ if err := git .NewCommandContext ( ctx , "remote" , "update" , "--prune" , m .GetRemoteName ()).
255
279
SetDescription (fmt .Sprintf ("Mirror.runSync Wiki: %s " , m .Repo .FullName ())).
256
280
RunInDirTimeoutPipeline (timeout , wikiPath , & stdoutBuilder , & stderrBuilder ); err != nil {
257
281
stdout := stdoutBuilder .String ()
@@ -277,30 +301,20 @@ func runSync(ctx context.Context, m *models.Mirror) ([]*mirrorSyncResult, bool)
277
301
err = nil
278
302
279
303
// Attempt prune
280
- stderrBuilder .Reset ()
281
- stdoutBuilder .Reset ()
282
- if err := git .NewCommand ("remote" , "prune" , m .GetRemoteName ()).
283
- SetDescription (fmt .Sprintf ("Mirror.runSync Prune Wiki references: %s " , m .Repo .FullName ())).
284
- RunInDirTimeoutPipeline (timeout , wikiPath , & stdoutBuilder , & stderrBuilder ); err != nil {
285
- stdout := stdoutBuilder .String ()
286
- stderr := stderrBuilder .String ()
287
-
288
- stderrMessage := sanitizer .Replace (stderr )
289
- stdoutMessage := sanitizer .Replace (stdout )
290
-
291
- log .Error ("Failed to prune mirror repository wiki %-v references:\n Stdout: %s\n Stderr: %s\n Err: %v" , m .Repo , stdoutMessage , stderrMessage , err )
292
- desc := fmt .Sprintf ("Failed to prune mirror repository wiki '%s' references: %s" , wikiPath , stderrMessage )
293
- if err = models .CreateRepositoryNotice (desc ); err != nil {
294
- log .Error ("CreateRepositoryNotice: %v" , err )
304
+ pruneErr := pruneBrokenReferences (ctx , m , repoPath , timeout , & stdoutBuilder , & stderrBuilder , sanitizer , true )
305
+ if pruneErr == nil {
306
+ // Successful prune - reattempt mirror
307
+ stderrBuilder .Reset ()
308
+ stdoutBuilder .Reset ()
309
+
310
+ if err = git .NewCommandContext (ctx , "remote" , "update" , "--prune" , m .GetRemoteName ()).
311
+ SetDescription (fmt .Sprintf ("Mirror.runSync Wiki: %s " , m .Repo .FullName ())).
312
+ RunInDirTimeoutPipeline (timeout , wikiPath , & stdoutBuilder , & stderrBuilder ); err != nil {
313
+ stdout := stdoutBuilder .String ()
314
+ stderr := stderrBuilder .String ()
315
+ stderrMessage = sanitizer .Replace (stderr )
316
+ stdoutMessage = sanitizer .Replace (stdout )
295
317
}
296
- // this if will only be reached on a successful prune so try to get the mirror again
297
- } else if err = git .NewCommand ("remote" , "update" , "--prune" , m .GetRemoteName ()).
298
- SetDescription (fmt .Sprintf ("Mirror.runSync Wiki: %s " , m .Repo .FullName ())).
299
- RunInDirTimeoutPipeline (timeout , wikiPath , & stdoutBuilder , & stderrBuilder ); err != nil {
300
- stdout := stdoutBuilder .String ()
301
- stderr := stderrBuilder .String ()
302
- stderrMessage = sanitizer .Replace (stderr )
303
- stdoutMessage = sanitizer .Replace (stdout )
304
318
}
305
319
}
306
320
0 commit comments