Skip to content

Commit 1c7f33a

Browse files
authored
Don't fail on repositories with one branch (#8)
1 parent f8b889b commit 1c7f33a

File tree

2 files changed

+34
-24
lines changed

2 files changed

+34
-24
lines changed

.golangci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ linters-settings:
2222
# default is false: such cases aren't reported by default.
2323
check-blank: true
2424
govet:
25-
# report about shadowed variables
26-
check-shadowing: true
25+
enable:
26+
- shadow
2727
gocyclo:
2828
# minimal code complexity to report, 30 by default
2929
min-complexity: 15

cmd/mirror.go

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -88,18 +88,18 @@ func ValidateRepositories(repositories []RepositoryPair) {
8888
}
8989
}
9090

91-
func ListRemote(remote *git.Remote, listOptions *git.ListOptions) ([]*gitplumbing.Reference, error) {
91+
func ListRemote(remote *git.Remote, listOptions *git.ListOptions, repository string) ([]*gitplumbing.Reference, error) {
9292
refList, err := remote.List(listOptions)
9393
if err == gittransport.ErrAuthenticationRequired {
9494
return nil, backoff.Permanent(err)
9595
} else if err != nil {
96-
log.Warn("Retrying listing remote...")
96+
log.Warn("[", repository, "] Retrying listing remote because the following error occurred: ", err)
9797
}
9898
return refList, err
9999
}
100100

101101
// GetBranchesAndTagsFromRemote returns list of branches and tags present in remoteName of repository.
102-
func GetBranchesAndTagsFromRemote(repository *git.Repository, remoteName string, listOptions *git.ListOptions) ([]string, []string, error) {
102+
func GetBranchesAndTagsFromRemote(repository *git.Repository, remoteName string, listOptions *git.ListOptions, sourceRepository string) ([]string, []string, error) {
103103
var branchList []string
104104
var tagList []string
105105
var err error
@@ -112,7 +112,7 @@ func GetBranchesAndTagsFromRemote(repository *git.Repository, remoteName string,
112112
listRemoteBackoff := backoff.NewExponentialBackOff()
113113
listRemoteBackoff.MaxElapsedTime = time.Minute
114114
refList, err := backoff.RetryWithData(
115-
func() ([]*gitplumbing.Reference, error) { return ListRemote(remote, listOptions) },
115+
func() ([]*gitplumbing.Reference, error) { return ListRemote(remote, listOptions, sourceRepository) },
116116
listRemoteBackoff,
117117
)
118118
if err != nil {
@@ -229,32 +229,40 @@ func GetDestinationAuth(destAuth Authentication) *githttp.BasicAuth {
229229
}
230230

231231
// GitPlainClone clones git repository and is retried in case of error.
232-
func GitPlainClone(gitDirectory string, cloneOptions *git.CloneOptions) (*git.Repository, error) {
232+
func GitPlainClone(gitDirectory string, cloneOptions *git.CloneOptions, repositoryName string) (*git.Repository, error) {
233233
repository, err := git.PlainClone(gitDirectory, false, cloneOptions)
234234
if err == gittransport.ErrAuthenticationRequired {
235235
// Terminate backoff.
236236
return nil, backoff.Permanent(err)
237237
} else if err != nil {
238-
log.Warn("Retrying cloning repository...")
238+
log.Warn("[", repositoryName, "] Retrying cloning repository because the following error occurred: ", err)
239239
}
240240
return repository, err
241241
}
242242

243243
// GitFetchBranches fetches all branches and is retried in case of error.
244-
func GitFetchBranches(sourceRemote *git.Remote, sourceAuthentication Authentication) error {
244+
func GitFetchBranches(sourceRemote *git.Remote, sourceAuthentication Authentication, repositoryName string) error {
245245
gitFetchOptions := GetFetchOptions("refs/heads/*:refs/heads/*", sourceAuthentication)
246246
err := sourceRemote.Fetch(gitFetchOptions)
247-
if err == gittransport.ErrAuthenticationRequired {
248-
// Terminate backoff.
247+
switch err {
248+
case gittransport.ErrAuthenticationRequired:
249+
log.Error("[", repositoryName, "] Authentication required.")
249250
return backoff.Permanent(err)
250-
} else if err != nil {
251-
log.Warn("Retrying fetching branches...")
251+
case git.NoErrAlreadyUpToDate:
252+
// Terminate backoff with no error in case the branch is already up-to-date.
253+
// This can occur if source or destination repository has only one branch.
254+
log.Info("[", repositoryName, "] Repository up-to-date.")
255+
return nil
256+
default:
257+
if err != nil {
258+
log.Warn("[", repositoryName, "] Retrying fetching branches because the following error occurred: ", err)
259+
}
260+
return err
252261
}
253-
return err
254262
}
255263

256264
// PushRefs pushes refs defined in refSpecString to destination remote and is retried in case of error.
257-
func PushRefs(repository *git.Repository, auth *githttp.BasicAuth, refSpecString string) error {
265+
func PushRefs(repository *git.Repository, auth *githttp.BasicAuth, refSpecString string, repositoryName string) error {
258266
err := repository.Push(&git.PushOptions{
259267
RemoteName: "destination",
260268
RefSpecs: []gitconfig.RefSpec{gitconfig.RefSpec(refSpecString)},
@@ -264,7 +272,7 @@ func PushRefs(repository *git.Repository, auth *githttp.BasicAuth, refSpecString
264272
// Terminate backoff.
265273
return backoff.Permanent(err)
266274
} else if err != nil {
267-
log.Warn("Retrying pushing refs...")
275+
log.Warn("[", repositoryName, "] Retrying pushing refs because the following error occurred: ", err)
268276
}
269277
return err
270278
}
@@ -283,7 +291,7 @@ func MirrorRepository(messages chan MirrorStatus, source, destination string, so
283291
cloneBackoff := backoff.NewExponentialBackOff()
284292
cloneBackoff.MaxElapsedTime = 2 * time.Minute
285293
repository, err := backoff.RetryWithData(
286-
func() (*git.Repository, error) { return GitPlainClone(gitDirectory, gitCloneOptions) },
294+
func() (*git.Repository, error) { return GitPlainClone(gitDirectory, gitCloneOptions, source) },
287295
cloneBackoff,
288296
)
289297
if err != nil {
@@ -293,7 +301,7 @@ func MirrorRepository(messages chan MirrorStatus, source, destination string, so
293301
}
294302

295303
gitListOptions := GetListOptions(sourceAuthentication)
296-
sourceBranchList, sourceTagList, err := GetBranchesAndTagsFromRemote(repository, "origin", gitListOptions)
304+
sourceBranchList, sourceTagList, err := GetBranchesAndTagsFromRemote(repository, "origin", gitListOptions, source)
297305
if err != nil {
298306
ProcessError(err, "getting branches and tags from ", source, &allErrors)
299307
messages <- MirrorStatus{allErrors, time.Now(), 0, 0}
@@ -313,7 +321,7 @@ func MirrorRepository(messages chan MirrorStatus, source, destination string, so
313321
fetchBranchesBackoff := backoff.NewExponentialBackOff()
314322
fetchBranchesBackoff.MaxElapsedTime = time.Minute
315323
err = backoff.Retry(
316-
func() error { return GitFetchBranches(sourceRemote, sourceAuthentication) },
324+
func() error { return GitFetchBranches(sourceRemote, sourceAuthentication, source) },
317325
fetchBranchesBackoff,
318326
)
319327
if err != nil {
@@ -337,7 +345,7 @@ func MirrorRepository(messages chan MirrorStatus, source, destination string, so
337345

338346
destinationAuth := GetDestinationAuth(destinationAuthentication)
339347

340-
destinationBranchList, destinationTagList, err := GetBranchesAndTagsFromRemote(repository, "destination", &git.ListOptions{Auth: destinationAuth})
348+
destinationBranchList, destinationTagList, err := GetBranchesAndTagsFromRemote(repository, "destination", &git.ListOptions{Auth: destinationAuth}, destination)
341349
if err != nil {
342350
ProcessError(err, "getting branches and tags from ", destination, &allErrors)
343351
}
@@ -351,7 +359,7 @@ func MirrorRepository(messages chan MirrorStatus, source, destination string, so
351359
pushBranchesBackoff.MaxElapsedTime = 2 * time.Minute
352360
err = backoff.Retry(
353361
func() error {
354-
return PushRefs(repository, destinationAuth, "+"+refBranchPrefix+branch+":"+refBranchPrefix+branch)
362+
return PushRefs(repository, destinationAuth, "+"+refBranchPrefix+branch+":"+refBranchPrefix+branch, destination)
355363
},
356364
pushBranchesBackoff,
357365
)
@@ -365,7 +373,7 @@ func MirrorRepository(messages chan MirrorStatus, source, destination string, so
365373
removeBranchesBackoff := backoff.NewExponentialBackOff()
366374
removeBranchesBackoff.MaxElapsedTime = time.Minute
367375
err = backoff.Retry(
368-
func() error { return PushRefs(repository, destinationAuth, ":"+refBranchPrefix+branch) },
376+
func() error { return PushRefs(repository, destinationAuth, ":"+refBranchPrefix+branch, destination) },
369377
removeBranchesBackoff,
370378
)
371379
ProcessError(err, "removing branch "+branch+" from ", destination, &allErrors)
@@ -376,7 +384,9 @@ func MirrorRepository(messages chan MirrorStatus, source, destination string, so
376384
pushTagsBackoff := backoff.NewExponentialBackOff()
377385
pushTagsBackoff.MaxElapsedTime = time.Minute
378386
err = backoff.Retry(
379-
func() error { return PushRefs(repository, destinationAuth, "+"+refTagPrefix+"*:"+refTagPrefix+"*") },
387+
func() error {
388+
return PushRefs(repository, destinationAuth, "+"+refTagPrefix+"*:"+refTagPrefix+"*", destination)
389+
},
380390
pushTagsBackoff,
381391
)
382392
ProcessError(err, "pushing all tags to ", destination, &allErrors)
@@ -388,7 +398,7 @@ func MirrorRepository(messages chan MirrorStatus, source, destination string, so
388398
removeTagsBackoff := backoff.NewExponentialBackOff()
389399
removeTagsBackoff.MaxElapsedTime = time.Minute
390400
err = backoff.Retry(
391-
func() error { return PushRefs(repository, destinationAuth, ":"+refTagPrefix+tag) },
401+
func() error { return PushRefs(repository, destinationAuth, ":"+refTagPrefix+tag, destination) },
392402
removeTagsBackoff,
393403
)
394404
ProcessError(err, "removing tag "+tag+" from ", destination, &allErrors)

0 commit comments

Comments
 (0)