Skip to content

Commit 09f7d84

Browse files
authored
Ensure rejected push to refs/pull/index/head fails nicely (#11724)
A pre-receive hook that rejects pushes to refs/pull/index/head will cause a broken PR which causes an internal server error whenever it is viewed. This PR handles prevents the internal server error by handling non-existent pr heads and sends a flash error informing the creator there was a problem. Signed-off-by: Andrew Thornton <[email protected]>
1 parent 5814079 commit 09f7d84

File tree

2 files changed

+37
-5
lines changed

2 files changed

+37
-5
lines changed

routers/repo/pull.go

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,20 @@ func PrepareViewPullInfo(ctx *context.Context, issue *models.Issue) *git.Compare
430430

431431
sha, err := baseGitRepo.GetRefCommitID(pull.GetGitRefName())
432432
if err != nil {
433+
if git.IsErrNotExist(err) {
434+
ctx.Data["IsPullRequestBroken"] = true
435+
if pull.IsSameRepo() {
436+
ctx.Data["HeadTarget"] = pull.HeadBranch
437+
} else if pull.HeadRepo == nil {
438+
ctx.Data["HeadTarget"] = "<deleted>:" + pull.HeadBranch
439+
} else {
440+
ctx.Data["HeadTarget"] = pull.HeadRepo.OwnerName + ":" + pull.HeadBranch
441+
}
442+
ctx.Data["BaseTarget"] = pull.BaseBranch
443+
ctx.Data["NumCommits"] = 0
444+
ctx.Data["NumFiles"] = 0
445+
return nil
446+
}
433447
ctx.ServerError(fmt.Sprintf("GetRefCommitID(%s)", pull.GetGitRefName()), err)
434448
return nil
435449
}
@@ -464,12 +478,10 @@ func PrepareViewPullInfo(ctx *context.Context, issue *models.Issue) *git.Compare
464478
ctx.Data["IsPullRequestBroken"] = true
465479
if pull.IsSameRepo() {
466480
ctx.Data["HeadTarget"] = pull.HeadBranch
481+
} else if pull.HeadRepo == nil {
482+
ctx.Data["HeadTarget"] = "<deleted>:" + pull.HeadBranch
467483
} else {
468-
if pull.HeadRepo == nil {
469-
ctx.Data["HeadTarget"] = "<deleted>:" + pull.HeadBranch
470-
} else {
471-
ctx.Data["HeadTarget"] = pull.HeadRepo.OwnerName + ":" + pull.HeadBranch
472-
}
484+
ctx.Data["HeadTarget"] = pull.HeadRepo.OwnerName + ":" + pull.HeadBranch
473485
}
474486
}
475487

@@ -952,6 +964,16 @@ func CompareAndPullRequestPost(ctx *context.Context, form auth.CreateIssueForm)
952964
if models.IsErrUserDoesNotHaveAccessToRepo(err) {
953965
ctx.Error(400, "UserDoesNotHaveAccessToRepo", err.Error())
954966
return
967+
} else if git.IsErrPushRejected(err) {
968+
pushrejErr := err.(*git.ErrPushRejected)
969+
message := pushrejErr.Message
970+
if len(message) == 0 {
971+
ctx.Flash.Error(ctx.Tr("repo.pulls.push_rejected_no_message"))
972+
} else {
973+
ctx.Flash.Error(ctx.Tr("repo.pulls.push_rejected", utils.SanitizeFlashErrorString(pushrejErr.Message)))
974+
}
975+
ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + com.ToStr(pullIssue.Index))
976+
return
955977
}
956978
ctx.ServerError("NewPullRequest", err)
957979
return

services/pull/pull.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,16 @@ func PushToBaseRepo(pr *models.PullRequest) (err error) {
443443
// Use InternalPushingEnvironment here because we know that pre-receive and post-receive do not run on a refs/pulls/...
444444
Env: models.InternalPushingEnvironment(pr.Issue.Poster, pr.BaseRepo),
445445
}); err != nil {
446+
if git.IsErrPushOutOfDate(err) {
447+
// This should not happen as we're using force!
448+
log.Error("Unable to push PR head for %s#%d (%-v:%s) due to ErrPushOfDate: %v", pr.BaseRepo.FullName(), pr.Index, pr.BaseRepo, headFile, err)
449+
return err
450+
} else if git.IsErrPushRejected(err) {
451+
rejectErr := err.(*git.ErrPushRejected)
452+
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, headFile, rejectErr.StdOut, rejectErr.StdErr, rejectErr.Err)
453+
return err
454+
}
455+
log.Error("Unable to push PR head for %s#%d (%-v:%s) due to Error: %v", pr.BaseRepo.FullName(), pr.Index, pr.BaseRepo, headFile, err)
446456
return fmt.Errorf("Push: %s:%s %s:%s %v", pr.HeadRepo.FullName(), pr.HeadBranch, pr.BaseRepo.FullName(), headFile, err)
447457
}
448458

0 commit comments

Comments
 (0)