diff options
| author | Aleksandr Nogikh <nogikh@google.com> | 2023-08-29 17:41:10 +0200 |
|---|---|---|
| committer | Aleksandr Nogikh <nogikh@google.com> | 2023-08-30 09:27:19 +0000 |
| commit | a4e766bb01114f0055eb04c39d8f0923b9cb4d6e (patch) | |
| tree | 90e5e9b8d8213e51350519eb3bfec44cd4bd8ddf /pkg/vcs | |
| parent | b42ca3a7c82c932ad7ee2ae2a89ae7dfe1e583a5 (diff) | |
pkg/vcs: circumvent ref conflicts during fetch
If the remote repo's tags conflict with the local ones, `git fetch` may
fail with `error: cannot lock ref %: % exists`.
It seems that the only way to restore the repository in this case is to
do `git fetch` with `--prune --prune-tags`. Since this also forces the
repository to forget all tags not present in the remote, let's do it
only when we got the error message.
Diffstat (limited to 'pkg/vcs')
| -rw-r--r-- | pkg/vcs/git.go | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/pkg/vcs/git.go b/pkg/vcs/git.go index e1682afb0..b3e9a7ace 100644 --- a/pkg/vcs/git.go +++ b/pkg/vcs/git.go @@ -6,6 +6,7 @@ package vcs import ( "bufio" "bytes" + "errors" "fmt" "net/mail" "os" @@ -144,6 +145,18 @@ func (git *git) fetchRemote(repo string) error { // Ignore error as we can double add the same remote and that will fail. git.git("remote", "add", repoHash, repo) _, err := git.git("fetch", "--force", "--tags", repoHash) + if err != nil { + var verbose *osutil.VerboseError + if errors.As(err, &verbose) && + bytes.Contains(verbose.Output, []byte("error: cannot lock ref")) { + // It can happen that the fetched repo has tags names that conflict + // with the ones already present in the repository. + // Try to fetch more, but this time prune tags, it should help. + // The --prune-tags option will remove all tags that are not present + // in this remote repo, so don't do it always. Only when necessary. + _, err = git.git("fetch", "--force", "--tags", "--prune", "--prune-tags", repoHash) + } + } return err } |
