···5566import (
77 "context"
88+ "strings"
89910 giturl "code.gitea.io/gitea/modules/git/url"
1011)
···3738 }
3839 return giturl.Parse(addr)
3940}
4141+4242+// IsRemoteNotExistError checks the prefix of the error message to see whether a remote does not exist.
4343+func IsRemoteNotExistError(err error) bool {
4444+ // see: https://github.com/go-gitea/gitea/issues/32889#issuecomment-2571848216
4545+ // Should not add space in the end, sometimes git will add a `:`
4646+ prefix1 := "exit status 128 - fatal: No such remote" // git < 2.30
4747+ prefix2 := "exit status 2 - error: No such remote" // git >= 2.30
4848+ return strings.HasPrefix(err.Error(), prefix1) || strings.HasPrefix(err.Error(), prefix2)
4949+}
+4-4
services/mirror/mirror_pull.go
···4040 repoPath := m.GetRepository(ctx).RepoPath()
4141 // Remove old remote
4242 _, _, err = git.NewCommand(ctx, "remote", "rm").AddDynamicArguments(remoteName).RunStdString(&git.RunOpts{Dir: repoPath})
4343- if err != nil && !strings.HasPrefix(err.Error(), "exit status 128 - fatal: No such remote ") {
4343+ if err != nil && !git.IsRemoteNotExistError(err) {
4444 return err
4545 }
4646···5151 cmd.SetDescription(fmt.Sprintf("remote add %s --mirror=fetch %s [repo_path: %s]", remoteName, addr, repoPath))
5252 }
5353 _, _, err = cmd.RunStdString(&git.RunOpts{Dir: repoPath})
5454- if err != nil && !strings.HasPrefix(err.Error(), "exit status 128 - fatal: No such remote ") {
5454+ if err != nil && !git.IsRemoteNotExistError(err) {
5555 return err
5656 }
5757···6060 wikiRemotePath := repo_module.WikiRemoteURL(ctx, addr)
6161 // Remove old remote of wiki
6262 _, _, err = git.NewCommand(ctx, "remote", "rm").AddDynamicArguments(remoteName).RunStdString(&git.RunOpts{Dir: wikiPath})
6363- if err != nil && !strings.HasPrefix(err.Error(), "exit status 128 - fatal: No such remote ") {
6363+ if err != nil && !git.IsRemoteNotExistError(err) {
6464 return err
6565 }
6666···7171 cmd.SetDescription(fmt.Sprintf("remote add %s --mirror=fetch %s [repo_path: %s]", remoteName, wikiRemotePath, wikiPath))
7272 }
7373 _, _, err = cmd.RunStdString(&git.RunOpts{Dir: wikiPath})
7474- if err != nil && !strings.HasPrefix(err.Error(), "exit status 128 - fatal: No such remote ") {
7474+ if err != nil && !git.IsRemoteNotExistError(err) {
7575 return err
7676 }
7777 }
+3-4
services/repository/migrate.go
···88 "errors"
99 "fmt"
1010 "net/http"
1111- "strings"
1211 "time"
13121413 "code.gitea.io/gitea/models/db"
···253252func cleanUpMigrateGitConfig(ctx context.Context, repoPath string) error {
254253 cmd := git.NewCommand(ctx, "remote", "rm", "origin")
255254 // if the origin does not exist
256256- _, stderr, err := cmd.RunStdString(&git.RunOpts{
255255+ _, _, err := cmd.RunStdString(&git.RunOpts{
257256 Dir: repoPath,
258257 })
259259- if err != nil && !strings.HasPrefix(stderr, "fatal: No such remote") {
258258+ if err != nil && !git.IsRemoteNotExistError(err) {
260259 return err
261260 }
262261 return nil
···275274 }
276275277276 _, _, err := git.NewCommand(ctx, "remote", "rm", "origin").RunStdString(&git.RunOpts{Dir: repoPath})
278278- if err != nil && !strings.HasPrefix(err.Error(), "exit status 128 - fatal: No such remote ") {
277277+ if err != nil && !git.IsRemoteNotExistError(err) {
279278 return repo, fmt.Errorf("CleanUpMigrateInfo: %w", err)
280279 }
281280