diff --git a/models/pull.go b/models/pull.go index 5f4a6e205..a8b054350 100644 --- a/models/pull.go +++ b/models/pull.go @@ -60,15 +60,15 @@ type PullRequest struct { Issue *Issue `xorm:"-"` Index int64 - HeadRepoID int64 `xorm:"INDEX"` - HeadRepo *Repository `xorm:"-"` - BaseRepoID int64 `xorm:"INDEX"` - BaseRepo *Repository `xorm:"-"` - HeadUserName string - HeadBranch string - BaseBranch string - MergeBase string `xorm:"VARCHAR(40)"` - + HeadRepoID int64 `xorm:"INDEX"` + HeadRepo *Repository `xorm:"-"` + BaseRepoID int64 `xorm:"INDEX"` + BaseRepo *Repository `xorm:"-"` + HeadUserName string + HeadBranch string + BaseBranch string + MergeBase string `xorm:"VARCHAR(40)"` + LastCommitID string `xorm:"-"` HasMerged bool `xorm:"INDEX"` MergedCommitID string `xorm:"VARCHAR(40)"` MergerID int64 `xorm:"INDEX"` diff --git a/models/status.go b/models/status.go index 0e30979dc..791d9e488 100644 --- a/models/status.go +++ b/models/status.go @@ -158,21 +158,42 @@ func GetLatestCommitStatus(repo *Repository, sha string, page int) ([]*CommitSta return statuses, x.In("id", ids).Find(&statuses) } -// GetLatestCommitStatuses returns all statuses with given repoIDs and shas -func GetLatestCommitStatuses(repoSHAs []struct { - RepoID int64 - SHA string -}) ([][]*CommitStatus, error) { +// GetIssuesLatestCommitStatuses returns all statuses with given repoIDs and shas +func GetIssuesLatestCommitStatuses(issues []*Issue) ([][]*CommitStatus, error) { var cond = builder.NewCond() - for i := 0; i < len(repoSHAs); i++ { + var repoCache = make(map[int64]*git.Repository) + var err error + for i := 0; i < len(issues); i++ { + var gitRepo *git.Repository + var ok bool + if gitRepo, ok = repoCache[issues[i].PullRequest.HeadRepoID]; !ok { + if err := issues[i].PullRequest.GetHeadRepo(); err != nil { + log.Error(4, "GetHeadRepo[%d, %d]: %v", issues[i].PullRequest.ID, issues[i].PullRequest.HeadRepoID, err) + continue + } + + gitRepo, err = git.OpenRepository(issues[i].PullRequest.HeadRepo.RepoPath()) + if err != nil { + log.Error(4, "OpenRepository[%d, %s]: %v", issues[i].PullRequest.ID, issues[i].PullRequest.HeadRepo.RepoPath(), err) + continue + } + repoCache[issues[i].PullRequest.HeadRepoID] = gitRepo + } + + issues[i].PullRequest.LastCommitID, err = gitRepo.GetBranchCommitID(issues[i].PullRequest.HeadBranch) + if err != nil { + log.Error(4, "GetBranchCommitID[%d, %s]: %v", issues[i].PullRequest.ID, issues[i].PullRequest.HeadBranch, err) + continue + } + cond = cond.Or(builder.Eq{ - "repo_id": repoSHAs[i].RepoID, - "sha": repoSHAs[i].SHA, + "repo_id": issues[i].RepoID, + "sha": issues[i].PullRequest.LastCommitID, }) } - var ids = make([]int64, 0, len(repoSHAs)) - err := x.Table("commit_status"). + var ids = make([]int64, 0, len(issues)) + err = x.Table("commit_status"). Where(cond). Select("max( id ) as id"). GroupBy("repo_id, sha, context"). @@ -182,7 +203,7 @@ func GetLatestCommitStatuses(repoSHAs []struct { return nil, err } - var returns = make([][]*CommitStatus, len(repoSHAs)) + var returns = make([][]*CommitStatus, len(issues)) if len(ids) == 0 { return returns, nil } @@ -193,14 +214,15 @@ func GetLatestCommitStatuses(repoSHAs []struct { return nil, err } - var repoIDsMap = make(map[string][]int64, len(repoSHAs)) + var repoIDsMap = make(map[string][]int64, len(issues)) for _, status := range statuses { key := fmt.Sprintf("%d-%s", status.RepoID, status.SHA) repoIDsMap[key] = append(repoIDsMap[key], status.ID) } - for i := 0; i < len(repoSHAs); i++ { - for _, id := range repoIDsMap[fmt.Sprintf("%d-%s", repoSHAs[i].RepoID, repoSHAs[i].SHA)] { + for i := 0; i < len(issues); i++ { + key := fmt.Sprintf("%d-%s", issues[i].RepoID, issues[i].PullRequest.LastCommitID) + for _, id := range repoIDsMap[key] { returns[i] = append(returns[i], statuses[id]) } } diff --git a/routers/repo/issue.go b/routers/repo/issue.go index af2e596d0..3563cbd79 100644 --- a/routers/repo/issue.go +++ b/routers/repo/issue.go @@ -209,83 +209,29 @@ func Issues(ctx *context.Context) { } } - if !isPullList { - // Get posters. - for i := 0; i < len(issues); i++ { - // Check read status - if !ctx.IsSigned { - issues[i].IsRead = true - } else if err = issues[i].GetIsRead(ctx.User.ID); err != nil { - ctx.ServerError("GetIsRead", err) - return - } + // Get posters. + for i := 0; i < len(issues); i++ { + // Check read status + if !ctx.IsSigned { + issues[i].IsRead = true + } else if err = issues[i].GetIsRead(ctx.User.ID); err != nil { + ctx.ServerError("GetIsRead", err) + return } - } else { - var repoSHAs = make([]struct { - RepoID int64 - SHA string - }, 0, len(issues)) - var pullIDs = make([]int64, 0, len(issues)) - var repoCache = make(map[int64]*git.Repository) + } - // Get posters. - for i, issue := range issues { - // Check read status - if !ctx.IsSigned { - issues[i].IsRead = true - } else if err = issues[i].GetIsRead(ctx.User.ID); err != nil { - ctx.ServerError("GetIsRead", err) - return - } - - if err := issue.LoadAttributes(); err != nil { - ctx.ServerError("LoadAttributes", err) - return - } - - var gitRepo *git.Repository - var ok bool - if gitRepo, ok = repoCache[issue.PullRequest.HeadRepoID]; !ok { - if err := issue.PullRequest.GetHeadRepo(); err != nil { - ctx.ServerError("GetHeadRepo", err) - return - } - - gitRepo, err = git.OpenRepository(issue.PullRequest.HeadRepo.RepoPath()) - if err != nil { - ctx.ServerError("OpenRepository", err) - return - } - repoCache[issue.PullRequest.HeadRepoID] = gitRepo - } - - sha, err := gitRepo.GetBranchCommitID(issue.PullRequest.HeadBranch) - if err != nil { - log.Error(4, "GetBranchCommitID: %v", err) - } else { - repoSHAs = append(repoSHAs, struct { - RepoID int64 - SHA string - }{ - RepoID: issue.RepoID, - SHA: sha, - }) - pullIDs = append(pullIDs, issue.ID) - } + if isPullList && len(issues) > 0 { + commitStatuses, err := models.GetIssuesLatestCommitStatuses(issues) + if err != nil { + ctx.ServerError("GetIssuesLatestCommitStatuses", err) + return } var issuesStates = make(map[int64]*models.CommitStatus, len(issues)) - if len(repoSHAs) > 0 { - commitStatuses, err := models.GetLatestCommitStatuses(repoSHAs) - if err != nil { - ctx.ServerError("GetLatestCommitStatuses", err) - return - } - - for i, statuses := range commitStatuses { - issuesStates[pullIDs[i]] = models.CalcCommitStatus(statuses) - } + for i, statuses := range commitStatuses { + issuesStates[issues[i].PullRequest.ID] = models.CalcCommitStatus(statuses) } + ctx.Data["IssuesStates"] = issuesStates } diff --git a/routers/user/home.go b/routers/user/home.go index 553049791..5fb35e62f 100644 --- a/routers/user/home.go +++ b/routers/user/home.go @@ -9,11 +9,9 @@ import ( "fmt" "sort" - "code.gitea.io/git" "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" @@ -293,69 +291,21 @@ func Issues(ctx *context.Context) { return } - if !isPullList { - for _, issue := range issues { - issue.Repo = showReposMap[issue.RepoID] - } - } else { - var repoSHAs = make([]struct { - RepoID int64 - SHA string - }, 0, len(issues)) - var pullIDs = make([]int64, 0, len(issues)) - var repoCache = make(map[int64]*git.Repository) - - for _, issue := range issues { - issue.Repo = showReposMap[issue.RepoID] - - if err := issue.LoadAttributes(); err != nil { - ctx.ServerError("LoadAttributes", fmt.Errorf("%v", err)) - return - } - - var gitRepo *git.Repository - var ok bool - if gitRepo, ok = repoCache[issue.PullRequest.HeadRepoID]; !ok { - if err := issue.PullRequest.GetHeadRepo(); err != nil { - ctx.ServerError("GetHeadRepo", err) - return - } - - gitRepo, err = git.OpenRepository(issue.PullRequest.HeadRepo.RepoPath()) - if err != nil { - ctx.ServerError("OpenRepository", err) - return - } - repoCache[issue.PullRequest.HeadRepoID] = gitRepo - } - - sha, err := gitRepo.GetBranchCommitID(issue.PullRequest.HeadBranch) - if err != nil { - log.Error(4, "GetBranchCommitID: %v", err) - } else { - repoSHAs = append(repoSHAs, struct { - RepoID int64 - SHA string - }{ - RepoID: issue.RepoID, - SHA: sha, - }) - pullIDs = append(pullIDs, issue.ID) - } + for _, issue := range issues { + issue.Repo = showReposMap[issue.RepoID] + } + if isPullList && len(issues) > 0 { + commitStatuses, err := models.GetIssuesLatestCommitStatuses(issues) + if err != nil { + ctx.ServerError("GetIssuesLatestCommitStatuses", err) + return } var issuesStates = make(map[int64]*models.CommitStatus, len(issues)) - if len(repoSHAs) > 0 { - commitStatuses, err := models.GetLatestCommitStatuses(repoSHAs) - if err != nil { - ctx.ServerError("GetLatestCommitStatuses", err) - return - } - - for i, statuses := range commitStatuses { - issuesStates[pullIDs[i]] = models.CalcCommitStatus(statuses) - } + for i, statuses := range commitStatuses { + issuesStates[issues[i].PullRequest.ID] = models.CalcCommitStatus(statuses) } + ctx.Data["IssuesStates"] = issuesStates }