mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-26 12:27:06 +00:00 
			
		
		
		
	* Fix 500 Error with branch and tag sharing the same name #15592 Fixed 500 error while create Pull request when there are more than one sources (branch, tag) with the same name Fix #15592 Signed-off-by: Viktor Yakovchuk <viktor@yakovchuk.net> * fix logging Co-authored-by: techknowlogick <techknowlogick@gitea.io> Co-authored-by: 6543 <6543@obermui.de>
This commit is contained in:
		| @@ -159,3 +159,20 @@ func (err *ErrPushRejected) GenerateMessage() { | |||||||
| 	} | 	} | ||||||
| 	err.Message = strings.TrimSpace(messageBuilder.String()) | 	err.Message = strings.TrimSpace(messageBuilder.String()) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // ErrMoreThanOne represents an error if pull request fails when there are more than one sources (branch, tag) with the same name | ||||||
|  | type ErrMoreThanOne struct { | ||||||
|  | 	StdOut string | ||||||
|  | 	StdErr string | ||||||
|  | 	Err    error | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // IsErrMoreThanOne checks if an error is a ErrMoreThanOne | ||||||
|  | func IsErrMoreThanOne(err error) bool { | ||||||
|  | 	_, ok := err.(*ErrMoreThanOne) | ||||||
|  | 	return ok | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (err *ErrMoreThanOne) Error() string { | ||||||
|  | 	return fmt.Sprintf("ErrMoreThanOne Error: %v: %s\n%s", err.Err, err.StdErr, err.StdOut) | ||||||
|  | } | ||||||
|   | |||||||
| @@ -225,6 +225,13 @@ func Push(repoPath string, opts PushOptions) error { | |||||||
| 			} | 			} | ||||||
| 			err.GenerateMessage() | 			err.GenerateMessage() | ||||||
| 			return err | 			return err | ||||||
|  | 		} else if strings.Contains(errbuf.String(), "matches more than one") { | ||||||
|  | 			err := &ErrMoreThanOne{ | ||||||
|  | 				StdOut: outbuf.String(), | ||||||
|  | 				StdErr: errbuf.String(), | ||||||
|  | 				Err:    err, | ||||||
|  | 			} | ||||||
|  | 			return err | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -389,6 +389,10 @@ func checkIfPRContentChanged(pr *models.PullRequest, oldCommitID, newCommitID st | |||||||
| // corresponding branches of base repository. | // corresponding branches of base repository. | ||||||
| // FIXME: Only push branches that are actually updates? | // FIXME: Only push branches that are actually updates? | ||||||
| func PushToBaseRepo(pr *models.PullRequest) (err error) { | func PushToBaseRepo(pr *models.PullRequest) (err error) { | ||||||
|  | 	return pushToBaseRepoHelper(pr, "") | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func pushToBaseRepoHelper(pr *models.PullRequest, prefixHeadBranch string) (err error) { | ||||||
| 	log.Trace("PushToBaseRepo[%d]: pushing commits to base repo '%s'", pr.BaseRepoID, pr.GetGitRefName()) | 	log.Trace("PushToBaseRepo[%d]: pushing commits to base repo '%s'", pr.BaseRepoID, pr.GetGitRefName()) | ||||||
|  |  | ||||||
| 	if err := pr.LoadHeadRepo(); err != nil { | 	if err := pr.LoadHeadRepo(); err != nil { | ||||||
| @@ -414,7 +418,7 @@ func PushToBaseRepo(pr *models.PullRequest) (err error) { | |||||||
|  |  | ||||||
| 	if err := git.Push(headRepoPath, git.PushOptions{ | 	if err := git.Push(headRepoPath, git.PushOptions{ | ||||||
| 		Remote: baseRepoPath, | 		Remote: baseRepoPath, | ||||||
| 		Branch: pr.HeadBranch + ":" + gitRefName, | 		Branch: prefixHeadBranch + pr.HeadBranch + ":" + gitRefName, | ||||||
| 		Force:  true, | 		Force:  true, | ||||||
| 		// Use InternalPushingEnvironment here because we know that pre-receive and post-receive do not run on a refs/pulls/... | 		// Use InternalPushingEnvironment here because we know that pre-receive and post-receive do not run on a refs/pulls/... | ||||||
| 		Env: models.InternalPushingEnvironment(pr.Issue.Poster, pr.BaseRepo), | 		Env: models.InternalPushingEnvironment(pr.Issue.Poster, pr.BaseRepo), | ||||||
| @@ -427,6 +431,14 @@ func PushToBaseRepo(pr *models.PullRequest) (err error) { | |||||||
| 			rejectErr := err.(*git.ErrPushRejected) | 			rejectErr := err.(*git.ErrPushRejected) | ||||||
| 			log.Info("Unable to push PR head for %s#%d (%-v:%s) due to rejection:\nStdout: %s\nStderr: %s\nError: %v", pr.BaseRepo.FullName(), pr.Index, pr.BaseRepo, gitRefName, rejectErr.StdOut, rejectErr.StdErr, rejectErr.Err) | 			log.Info("Unable to push PR head for %s#%d (%-v:%s) due to rejection:\nStdout: %s\nStderr: %s\nError: %v", pr.BaseRepo.FullName(), pr.Index, pr.BaseRepo, gitRefName, rejectErr.StdOut, rejectErr.StdErr, rejectErr.Err) | ||||||
| 			return err | 			return err | ||||||
|  | 		} else if git.IsErrMoreThanOne(err) { | ||||||
|  | 			if prefixHeadBranch != "" { | ||||||
|  | 				log.Info("Can't push with %s%s", prefixHeadBranch, pr.HeadBranch) | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  | 			log.Info("Retrying to push with refs/heads/%s", pr.HeadBranch) | ||||||
|  | 			err = pushToBaseRepoHelper(pr, "refs/heads/") | ||||||
|  | 			return err | ||||||
| 		} | 		} | ||||||
| 		log.Error("Unable to push PR head for %s#%d (%-v:%s) due to Error: %v", pr.BaseRepo.FullName(), pr.Index, pr.BaseRepo, gitRefName, err) | 		log.Error("Unable to push PR head for %s#%d (%-v:%s) due to Error: %v", pr.BaseRepo.FullName(), pr.Index, pr.BaseRepo, gitRefName, err) | ||||||
| 		return fmt.Errorf("Push: %s:%s %s:%s %v", pr.HeadRepo.FullName(), pr.HeadBranch, pr.BaseRepo.FullName(), gitRefName, err) | 		return fmt.Errorf("Push: %s:%s %s:%s %v", pr.HeadRepo.FullName(), pr.HeadBranch, pr.BaseRepo.FullName(), gitRefName, err) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Viktor Yakovchuk
					Viktor Yakovchuk