Skip to content

Commit 4d64461

Browse files
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>
1 parent cbf3083 commit 4d64461

File tree

3 files changed

+37
-1
lines changed

3 files changed

+37
-1
lines changed

modules/git/error.go

+17
Original file line numberDiff line numberDiff line change
@@ -159,3 +159,20 @@ func (err *ErrPushRejected) GenerateMessage() {
159159
}
160160
err.Message = strings.TrimSpace(messageBuilder.String())
161161
}
162+
163+
// ErrMoreThanOne represents an error if pull request fails when there are more than one sources (branch, tag) with the same name
164+
type ErrMoreThanOne struct {
165+
StdOut string
166+
StdErr string
167+
Err error
168+
}
169+
170+
// IsErrMoreThanOne checks if an error is a ErrMoreThanOne
171+
func IsErrMoreThanOne(err error) bool {
172+
_, ok := err.(*ErrMoreThanOne)
173+
return ok
174+
}
175+
176+
func (err *ErrMoreThanOne) Error() string {
177+
return fmt.Sprintf("ErrMoreThanOne Error: %v: %s\n%s", err.Err, err.StdErr, err.StdOut)
178+
}

modules/git/repo.go

+7
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,13 @@ func Push(repoPath string, opts PushOptions) error {
213213
}
214214
err.GenerateMessage()
215215
return err
216+
} else if strings.Contains(errbuf.String(), "matches more than one") {
217+
err := &ErrMoreThanOne{
218+
StdOut: outbuf.String(),
219+
StdErr: errbuf.String(),
220+
Err: err,
221+
}
222+
return err
216223
}
217224
}
218225

services/pull/pull.go

+13-1
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,10 @@ func checkIfPRContentChanged(pr *models.PullRequest, oldCommitID, newCommitID st
389389
// corresponding branches of base repository.
390390
// FIXME: Only push branches that are actually updates?
391391
func PushToBaseRepo(pr *models.PullRequest) (err error) {
392+
return pushToBaseRepoHelper(pr, "")
393+
}
394+
395+
func pushToBaseRepoHelper(pr *models.PullRequest, prefixHeadBranch string) (err error) {
392396
log.Trace("PushToBaseRepo[%d]: pushing commits to base repo '%s'", pr.BaseRepoID, pr.GetGitRefName())
393397

394398
if err := pr.LoadHeadRepo(); err != nil {
@@ -414,7 +418,7 @@ func PushToBaseRepo(pr *models.PullRequest) (err error) {
414418

415419
if err := git.Push(headRepoPath, git.PushOptions{
416420
Remote: baseRepoPath,
417-
Branch: pr.HeadBranch + ":" + gitRefName,
421+
Branch: prefixHeadBranch + pr.HeadBranch + ":" + gitRefName,
418422
Force: true,
419423
// Use InternalPushingEnvironment here because we know that pre-receive and post-receive do not run on a refs/pulls/...
420424
Env: models.InternalPushingEnvironment(pr.Issue.Poster, pr.BaseRepo),
@@ -427,6 +431,14 @@ func PushToBaseRepo(pr *models.PullRequest) (err error) {
427431
rejectErr := err.(*git.ErrPushRejected)
428432
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)
429433
return err
434+
} else if git.IsErrMoreThanOne(err) {
435+
log.Info("Retrying to push with refs/heads/%s", pr.HeadBranch)
436+
if prefixHeadBranch != "" {
437+
log.Info("Can't push with refs/heads/%s", pr.HeadBranch)
438+
return err
439+
}
440+
err = pushToBaseRepoHelper(pr, "refs/heads/")
441+
return err
430442
}
431443
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)
432444
return fmt.Errorf("Push: %s:%s %s:%s %v", pr.HeadRepo.FullName(), pr.HeadBranch, pr.BaseRepo.FullName(), gitRefName, err)

0 commit comments

Comments
 (0)