@@ -180,8 +180,10 @@ func (r Repo) fetchGitRepo(arch string, entry *manifest.Manifest2822Entry) (stri
180
180
}
181
181
}
182
182
183
- fetchString := entry .ArchGitFetch (arch ) + ":"
184
- if entry .ArchGitCommit (arch ) == "FETCH_HEAD" {
183
+ fetchStrings := []string {
184
+ entry .ArchGitFetch (arch ) + ":" ,
185
+ }
186
+ if entryArchGitCommit := entry .ArchGitCommit (arch ); entryArchGitCommit == "FETCH_HEAD" {
185
187
// fetch remote tag references to a local tag ref so that we can cache them and not re-fetch every time
186
188
localRef := "refs/tags/" + gitNormalizeForTagUsage (cacheKey )
187
189
commit , err := getGitCommit (localRef )
@@ -190,7 +192,7 @@ func (r Repo) fetchGitRepo(arch string, entry *manifest.Manifest2822Entry) (stri
190
192
entry .SetGitCommit (arch , commit )
191
193
return commit , nil
192
194
}
193
- fetchString += localRef
195
+ fetchStrings [ 0 ] += localRef
194
196
} else {
195
197
// we create a temporary remote dir so that we can clean it up completely afterwards
196
198
refBase := "refs/remotes"
@@ -210,10 +212,19 @@ func (r Repo) fetchGitRepo(arch string, entry *manifest.Manifest2822Entry) (stri
210
212
tempRef := path .Join (refBase , filepath .Base (tempRefDir ))
211
213
if entry .ArchGitFetch (arch ) == manifest .DefaultLineBasedFetch {
212
214
// backwards compat (see manifest/line-based.go in go-dockerlibrary)
213
- fetchString += tempRef + "/*"
215
+ fetchStrings [ 0 ] += tempRef + "/*"
214
216
} else {
215
- fetchString += tempRef + "/temp"
217
+ fetchStrings [ 0 ] += tempRef + "/temp"
216
218
}
219
+
220
+ fetchStrings = append ([]string {
221
+ // Git (and more recently, GitHub) support "git fetch"ing a specific commit directly!
222
+ // (The "actions/checkout@v2" GitHub action uses this to fetch commits for running workflows even after branches are deleted!)
223
+ // https://github.com/git/git/commit/f8edeaa05d8623a9f6dad408237496c51101aad8
224
+ // https://github.com/go-git/go-git/pull/58
225
+ // If that works, we want to prefer it (since it'll be much more efficient at getting us the commit we care about), so we prepend it to our list of "things to try fetching"
226
+ entryArchGitCommit + ":" + tempRef + "/temp" ,
227
+ }, fetchStrings ... )
217
228
}
218
229
219
230
if strings .HasPrefix (entry .ArchGitRepo (arch ), "git://github.com/" ) {
@@ -229,27 +240,32 @@ func (r Repo) fetchGitRepo(arch string, entry *manifest.Manifest2822Entry) (stri
229
240
return "" , err
230
241
}
231
242
232
- err = gitRemote .Fetch (& goGit.FetchOptions {
233
- RefSpecs : []goGitConfig.RefSpec {goGitConfig .RefSpec (fetchString )},
234
- Tags : goGit .NoTags ,
243
+ var commit string
244
+ fetchErrors := []error {}
245
+ for _ , fetchString := range fetchStrings {
246
+ err := gitRemote .Fetch (& goGit.FetchOptions {
247
+ RefSpecs : []goGitConfig.RefSpec {goGitConfig .RefSpec (fetchString )},
248
+ Tags : goGit .NoTags ,
235
249
236
- //Progress: os.Stdout,
237
- })
238
- if err != nil {
239
- if fetchErr := fetchGitCommit ( arch , entry , gitRemote . Config (). URLs [ 0 ], fetchString ); fetchErr != nil {
240
- return "" , cli . NewMultiError ( err , fetchErr )
250
+ //Progress: os.Stdout,
251
+ })
252
+ if err != nil {
253
+ fetchErrors = append ( fetchErrors , err )
254
+ continue
241
255
}
242
- }
243
256
244
- commit , err := getGitCommit (entry .ArchGitCommit (arch ))
245
- if err != nil {
246
- if fetchErr := fetchGitCommit (arch , entry , gitRemote .Config ().URLs [0 ], fetchString ); fetchErr != nil {
247
- return "" , cli .NewMultiError (err , fetchErr )
248
- }
249
257
commit , err = getGitCommit (entry .ArchGitCommit (arch ))
250
258
if err != nil {
251
- return "" , err
259
+ fetchErrors = append (fetchErrors , err )
260
+ continue
252
261
}
262
+
263
+ fetchErrors = nil
264
+ break
265
+ }
266
+
267
+ if len (fetchErrors ) > 0 {
268
+ return "" , cli .NewMultiError (fetchErrors ... )
253
269
}
254
270
255
271
gitTag := gitNormalizeForTagUsage (path .Join (arch , namespace , r .RepoName , entry .Tags [0 ]))
@@ -263,20 +279,3 @@ func (r Repo) fetchGitRepo(arch string, entry *manifest.Manifest2822Entry) (stri
263
279
entry .SetGitCommit (arch , commit )
264
280
return commit , nil
265
281
}
266
-
267
- // this is used as a fallback if using github.com/go-git/go-git/v5 to fetch the branch fails to find the commit
268
- // Git (and more recently, GitHub) support "git fetch"ing a specific commit directly!
269
- // (The "actions/checkout@v2" GitHub action uses this to fetch commits for running workflows even after branches are deleted!)
270
- // https://github.com/git/git/commit/f8edeaa05d8623a9f6dad408237496c51101aad8
271
- // (Unfortunately, github.com/go-git/go-git/v5 does not support fetching a commit like this from what I can figure [https://github.com/go-git/go-git/issues/56], so we have to shell out.)
272
- func fetchGitCommit (arch string , entry * manifest.Manifest2822Entry , gitRemote , fetchString string ) error {
273
- commit := entry .ArchGitCommit (arch )
274
- if commit == "FETCH_HEAD" {
275
- return fmt .Errorf ("cannot fetch line-based entry commit when fetching by tag" )
276
- }
277
-
278
- fetchString = "+" + commit + ":" + strings .SplitN (fetchString , ":" , 2 )[1 ]
279
-
280
- _ , err := git (`fetch` , `--quiet` , gitRemote , fetchString )
281
- return err
282
- }
0 commit comments