Performance improvement for list pull requests (#15447)
This commit is contained in:
parent
f44543a1bb
commit
8202dd1311
|
@ -53,6 +53,9 @@ func (issues IssueList) loadRepositories(e Engine) ([]*Repository, error) {
|
||||||
|
|
||||||
for _, issue := range issues {
|
for _, issue := range issues {
|
||||||
issue.Repo = repoMaps[issue.RepoID]
|
issue.Repo = repoMaps[issue.RepoID]
|
||||||
|
if issue.PullRequest != nil {
|
||||||
|
issue.PullRequest.BaseRepo = issue.Repo
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return valuesRepository(repoMaps), nil
|
return valuesRepository(repoMaps), nil
|
||||||
}
|
}
|
||||||
|
@ -516,6 +519,11 @@ func (issues IssueList) LoadDiscussComments() error {
|
||||||
return issues.loadComments(x, builder.Eq{"comment.type": CommentTypeComment})
|
return issues.loadComments(x, builder.Eq{"comment.type": CommentTypeComment})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LoadPullRequests loads pull requests
|
||||||
|
func (issues IssueList) LoadPullRequests() error {
|
||||||
|
return issues.loadPullRequests(x)
|
||||||
|
}
|
||||||
|
|
||||||
// GetApprovalCounts returns a map of issue ID to slice of approval counts
|
// GetApprovalCounts returns a map of issue ID to slice of approval counts
|
||||||
// FIXME: only returns official counts due to double counting of non-official approvals
|
// FIXME: only returns official counts due to double counting of non-official approvals
|
||||||
func (issues IssueList) GetApprovalCounts() (map[int64][]*ReviewCount, error) {
|
func (issues IssueList) GetApprovalCounts() (map[int64][]*ReviewCount, error) {
|
||||||
|
|
|
@ -239,14 +239,13 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
approvalCounts, err := models.IssueList(issues).GetApprovalCounts()
|
var issueList = models.IssueList(issues)
|
||||||
|
approvalCounts, err := issueList.GetApprovalCounts()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ServerError("ApprovalCounts", err)
|
ctx.ServerError("ApprovalCounts", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var commitStatus = make(map[int64]*models.CommitStatus, len(issues))
|
|
||||||
|
|
||||||
// Get posters.
|
// Get posters.
|
||||||
for i := range issues {
|
for i := range issues {
|
||||||
// Check read status
|
// Check read status
|
||||||
|
@ -256,16 +255,12 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti
|
||||||
ctx.ServerError("GetIsRead", err)
|
ctx.ServerError("GetIsRead", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if issues[i].IsPull {
|
commitStatus, err := pull_service.GetIssuesLastCommitStatus(issues)
|
||||||
if err := issues[i].LoadPullRequest(); err != nil {
|
if err != nil {
|
||||||
ctx.ServerError("LoadPullRequest", err)
|
ctx.ServerError("GetIssuesLastCommitStatus", err)
|
||||||
return
|
return
|
||||||
}
|
|
||||||
|
|
||||||
var statuses, _ = pull_service.GetLastCommitStatus(issues[i].PullRequest)
|
|
||||||
commitStatus[issues[i].PullRequest.ID] = models.CalcCommitStatus(statuses)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Data["Issues"] = issues
|
ctx.Data["Issues"] = issues
|
||||||
|
|
|
@ -550,14 +550,14 @@ func buildIssueOverview(ctx *context.Context, unitType models.UnitType) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// maps pull request IDs to their CommitStatus. Will be posted to ctx.Data.
|
// maps pull request IDs to their CommitStatus. Will be posted to ctx.Data.
|
||||||
var commitStatus = make(map[int64]*models.CommitStatus, len(issues))
|
|
||||||
for _, issue := range issues {
|
for _, issue := range issues {
|
||||||
issue.Repo = showReposMap[issue.RepoID]
|
issue.Repo = showReposMap[issue.RepoID]
|
||||||
|
}
|
||||||
|
|
||||||
if isPullList {
|
commitStatus, err := pull_service.GetIssuesLastCommitStatus(issues)
|
||||||
var statuses, _ = pull_service.GetLastCommitStatus(issue.PullRequest)
|
if err != nil {
|
||||||
commitStatus[issue.PullRequest.ID] = models.CalcCommitStatus(statuses)
|
ctx.ServerError("GetIssuesLastCommitStatus", err)
|
||||||
}
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------
|
// -------------------------------
|
||||||
|
|
|
@ -8,7 +8,6 @@ import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -643,33 +642,74 @@ func GetSquashMergeCommitMessages(pr *models.PullRequest) string {
|
||||||
return stringBuilder.String()
|
return stringBuilder.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetLastCommitStatus returns list of commit statuses for latest commit on this pull request.
|
// GetIssuesLastCommitStatus returns a map
|
||||||
func GetLastCommitStatus(pr *models.PullRequest) (status []*models.CommitStatus, err error) {
|
func GetIssuesLastCommitStatus(issues models.IssueList) (map[int64]*models.CommitStatus, error) {
|
||||||
if err = pr.LoadBaseRepo(); err != nil {
|
if err := issues.LoadPullRequests(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if _, err := issues.LoadRepositories(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
gitRepos = make(map[int64]*git.Repository)
|
||||||
|
res = make(map[int64]*models.CommitStatus)
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
defer func() {
|
||||||
|
for _, gitRepo := range gitRepos {
|
||||||
|
gitRepo.Close()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
for _, issue := range issues {
|
||||||
|
if !issue.IsPull {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
gitRepo, ok := gitRepos[issue.RepoID]
|
||||||
|
if !ok {
|
||||||
|
gitRepo, err = git.OpenRepository(issue.Repo.RepoPath())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
gitRepos[issue.RepoID] = gitRepo
|
||||||
|
}
|
||||||
|
|
||||||
|
status, err := getLastCommitStatus(gitRepo, issue.PullRequest)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
res[issue.PullRequest.ID] = status
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetLastCommitStatus returns list of commit statuses for latest commit on this pull request.
|
||||||
|
func GetLastCommitStatus(pr *models.PullRequest) (status *models.CommitStatus, err error) {
|
||||||
|
if err = pr.LoadBaseRepo(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
gitRepo, err := git.OpenRepository(pr.BaseRepo.RepoPath())
|
gitRepo, err := git.OpenRepository(pr.BaseRepo.RepoPath())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer gitRepo.Close()
|
defer gitRepo.Close()
|
||||||
|
|
||||||
compareInfo, err := gitRepo.GetCompareInfo(pr.BaseRepo.RepoPath(), pr.MergeBase, pr.GetGitRefName())
|
return getLastCommitStatus(gitRepo, pr)
|
||||||
|
}
|
||||||
|
|
||||||
|
// getLastCommitStatus get pr's last commit status. PR's last commit status is the head commit id's last commit status
|
||||||
|
func getLastCommitStatus(gitRepo *git.Repository, pr *models.PullRequest) (status *models.CommitStatus, err error) {
|
||||||
|
sha, err := gitRepo.GetRefCommitID(pr.GetGitRefName())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if compareInfo.Commits.Len() == 0 {
|
|
||||||
return nil, errors.New("pull request has no commits")
|
|
||||||
}
|
|
||||||
|
|
||||||
sha := compareInfo.Commits.Front().Value.(*git.Commit).ID.String()
|
|
||||||
statusList, err := models.GetLatestCommitStatus(pr.BaseRepo.ID, sha, models.ListOptions{})
|
statusList, err := models.GetLatestCommitStatus(pr.BaseRepo.ID, sha, models.ListOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return statusList, nil
|
return models.CalcCommitStatus(statusList), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsHeadEqualWithBranch returns if the commits of branchName are available in pull request head
|
// IsHeadEqualWithBranch returns if the commits of branchName are available in pull request head
|
||||||
|
|
|
@ -62,12 +62,12 @@
|
||||||
{{$.i18n.Tr .GetLastEventLabelFake $timeStr (.Poster.GetDisplayName | Escape) | Safe}}
|
{{$.i18n.Tr .GetLastEventLabelFake $timeStr (.Poster.GetDisplayName | Escape) | Safe}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if and .Milestone (ne $.listType "milestone")}}
|
{{if and .Milestone (ne $.listType "milestone")}}
|
||||||
<a class="milestone" {{if $.RepoLink}}href="{{$.RepoLink}}/milestone/{{.Milestone.ID}}"{{else}}href="{{AppSubUrl}}/{{.Repo.Owner.Name}}/{{.Repo.Name}}/milestone/{{.Milestone.ID}}"{{end}}>
|
<a class="milestone" {{if $.RepoLink}}href="{{$.RepoLink}}/milestone/{{.Milestone.ID}}"{{else}}href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/milestone/{{.Milestone.ID}}"{{end}}>
|
||||||
{{svg "octicon-milestone" 14 "mr-2"}}{{.Milestone.Name}}
|
{{svg "octicon-milestone" 14 "mr-2"}}{{.Milestone.Name}}
|
||||||
</a>
|
</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if .Ref}}
|
{{if .Ref}}
|
||||||
<a class="ref" {{if $.RepoLink}}href="{{$.RepoLink}}{{index $.IssueRefURLs .ID}}"{{else}}href="{{AppSubUrl}}/{{.Repo.Owner.Name}}/{{.Repo.Name}}{{index $.IssueRefURLs .ID}}"{{end}}>
|
<a class="ref" {{if $.RepoLink}}href="{{$.RepoLink}}{{index $.IssueRefURLs .ID}}"{{else}}href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{index $.IssueRefURLs .ID}}"{{end}}>
|
||||||
{{svg "octicon-git-branch" 14 "mr-2"}}{{index $.IssueRefEndNames .ID}}
|
{{svg "octicon-git-branch" 14 "mr-2"}}{{index $.IssueRefEndNames .ID}}
|
||||||
</a>
|
</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
Loading…
Reference in a new issue