diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go index d6b9dddd9d7ba..6ac1af69d0865 100644 --- a/routers/api/v1/repo/pull.go +++ b/routers/api/v1/repo/pull.go @@ -902,6 +902,11 @@ func MergePullRequest(ctx *context.APIContext) { return } + if err := pull_service.RedirectOpenPullsToBaseBranch(ctx, pr, ctx.Doer); err != nil { + ctx.ServerError("RedirectOpenPulls", err) + return + } + var headRepo *git.Repository if ctx.Repo != nil && ctx.Repo.Repository != nil && ctx.Repo.Repository.ID == pr.HeadRepoID && ctx.Repo.GitRepo != nil { headRepo = ctx.Repo.GitRepo diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go index 39f9cefa5c669..b23c123817e40 100644 --- a/routers/web/repo/pull.go +++ b/routers/web/repo/pull.go @@ -1313,6 +1313,11 @@ func MergePullRequest(ctx *context.Context) { return } + if err := pull_service.RedirectOpenPullsToBaseBranch(ctx, pr, ctx.Doer); err != nil { + ctx.ServerError("RedirectOpenPulls", err) + return + } + var headRepo *git.Repository if ctx.Repo != nil && ctx.Repo.Repository != nil && pr.HeadRepoID == ctx.Repo.Repository.ID && ctx.Repo.GitRepo != nil { headRepo = ctx.Repo.GitRepo diff --git a/services/pull/pull.go b/services/pull/pull.go index 6094a4ed31b9e..d63d774cce0cf 100644 --- a/services/pull/pull.go +++ b/services/pull/pull.go @@ -953,3 +953,36 @@ func GetPullCommits(ctx *gitea_context.Context, issue *issues_model.Issue) ([]Co return commits, lastReviewCommitID, nil } + +// RedirectOpenPullsToBaseBranch redirects open pull requests to base branch of specified PR +func RedirectOpenPullsToBaseBranch(ctx context.Context, basePR *issues_model.PullRequest, doer *user_model.User) error { + pullRequestsToHead, err := issues_model.GetUnmergedPullRequestsByBaseInfo(ctx, basePR.HeadRepoID, basePR.HeadBranch) + if err != nil { + return fmt.Errorf("failed to get unmerged pull requests: %w", err) + } + + if err := issues_model.PullRequestList(pullRequestsToHead).LoadAttributes(ctx); err != nil { + return fmt.Errorf("failed to load attributes for pull requests: %w", err) + } + + for _, prToHead := range pullRequestsToHead { + if prToHead.BaseRepoID != basePR.BaseRepoID { + continue + } + + if prToHead.Issue.RepoID == basePR.Issue.RepoID { + prToHead.Issue.Repo = basePR.Issue.Repo + } else { + if err := prToHead.Issue.LoadRepo(ctx); err != nil { + return fmt.Errorf("failed to load repo for issue [%d]: %w", prToHead.IssueID, err) + } + } + + if err := ChangeTargetBranch(ctx, prToHead, doer, basePR.BaseBranch); err != nil && + !issues_model.IsErrPullRequestAlreadyExists(err) { + return fmt.Errorf("failed to change target branch for PR [%d]: %w", prToHead.ID, err) + } + } + + return nil +}