"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/repofiles"
"code.gitea.io/gitea/modules/util"
+ "gopkg.in/src-d/go-git.v4/plumbing"
)
const (
CommitsAhead int
CommitsBehind int
LatestPullRequest *models.PullRequest
+ MergeMovedOn bool
}
// Branches render repository branch page
return nil
}
+ repoIDToRepo := map[int64]*models.Repository{}
+ repoIDToRepo[ctx.Repo.Repository.ID] = ctx.Repo.Repository
+
+ repoIDToGitRepo := map[int64]*git.Repository{}
+ repoIDToGitRepo[ctx.Repo.Repository.ID] = ctx.Repo.GitRepo
+
branches := make([]*Branch, len(rawBranches))
for i := range rawBranches {
commit, err := rawBranches[i].GetCommit()
ctx.ServerError("GetLatestPullRequestByHeadInfo", err)
return nil
}
+ headCommit := commit.ID.String()
+
+ mergeMovedOn := false
if pr != nil {
+ pr.HeadRepo = ctx.Repo.Repository
if err := pr.LoadIssue(); err != nil {
ctx.ServerError("pr.LoadIssue", err)
return nil
}
+ if repo, ok := repoIDToRepo[pr.BaseRepoID]; ok {
+ pr.BaseRepo = repo
+ } else if err := pr.LoadBaseRepo(); err != nil {
+ ctx.ServerError("pr.LoadBaseRepo", err)
+ return nil
+ } else {
+ repoIDToRepo[pr.BaseRepoID] = pr.BaseRepo
+ }
+
+ if pr.HasMerged {
+ baseGitRepo, ok := repoIDToGitRepo[pr.BaseRepoID]
+ if !ok {
+ baseGitRepo, err = git.OpenRepository(pr.BaseRepo.RepoPath())
+ if err != nil {
+ ctx.ServerError("OpenRepository", err)
+ return nil
+ }
+ defer baseGitRepo.Close()
+ repoIDToGitRepo[pr.BaseRepoID] = baseGitRepo
+ }
+ pullCommit, err := baseGitRepo.GetRefCommitID(pr.GetGitRefName())
+ if err != nil && err != plumbing.ErrReferenceNotFound {
+ ctx.ServerError("GetBranchCommitID", err)
+ return nil
+ }
+ if err == nil && headCommit != pullCommit {
+ // the head has moved on from the merge - we shouldn't delete
+ mergeMovedOn = true
+ }
+ }
+
}
isIncluded := divergence.Ahead == 0 && ctx.Repo.Repository.DefaultBranch != branchName
CommitsAhead: divergence.Ahead,
CommitsBehind: divergence.Behind,
LatestPullRequest: pr,
+ MergeMovedOn: mergeMovedOn,
}
}
repo := ctx.Repo.Repository
pull := issue.PullRequest
- var err error
- if err = pull.GetHeadRepo(); err != nil {
+ if err := pull.GetHeadRepo(); err != nil {
ctx.ServerError("GetHeadRepo", err)
return nil
}
+ if err := pull.GetBaseRepo(); err != nil {
+ ctx.ServerError("GetBaseRepo", err)
+ return nil
+ }
+
setMergeTarget(ctx, pull)
- if err = pull.LoadProtectedBranch(); err != nil {
+ if err := pull.LoadProtectedBranch(); err != nil {
ctx.ServerError("GetLatestCommitStatus", err)
return nil
}
ctx.Data["EnableStatusCheck"] = pull.ProtectedBranch != nil && pull.ProtectedBranch.EnableStatusCheck
- var headGitRepo *git.Repository
+ baseGitRepo, err := git.OpenRepository(pull.BaseRepo.RepoPath())
+ if err != nil {
+ ctx.ServerError("OpenRepository", err)
+ return nil
+ }
+ defer baseGitRepo.Close()
var headBranchExist bool
+ var headBranchSha string
// HeadRepo may be missing
if pull.HeadRepo != nil {
- headGitRepo, err = git.OpenRepository(pull.HeadRepo.RepoPath())
+ var err error
+
+ headGitRepo, err := git.OpenRepository(pull.HeadRepo.RepoPath())
if err != nil {
ctx.ServerError("OpenRepository", err)
return nil
headBranchExist = headGitRepo.IsBranchExist(pull.HeadBranch)
if headBranchExist {
- sha, err := headGitRepo.GetBranchCommitID(pull.HeadBranch)
+ headBranchSha, err = headGitRepo.GetBranchCommitID(pull.HeadBranch)
if err != nil {
ctx.ServerError("GetBranchCommitID", err)
return nil
}
+ }
+ }
- commitStatuses, err := models.GetLatestCommitStatus(repo, sha, 0)
- if err != nil {
- ctx.ServerError("GetLatestCommitStatus", err)
- return nil
- }
- if len(commitStatuses) > 0 {
- ctx.Data["LatestCommitStatuses"] = commitStatuses
- ctx.Data["LatestCommitStatus"] = models.CalcCommitStatus(commitStatuses)
- }
+ sha, err := baseGitRepo.GetRefCommitID(pull.GetGitRefName())
+ if err != nil {
+ ctx.ServerError(fmt.Sprintf("GetRefCommitID(%s)", pull.GetGitRefName()), err)
+ return nil
+ }
- if pull.ProtectedBranch != nil && pull.ProtectedBranch.EnableStatusCheck {
- ctx.Data["is_context_required"] = func(context string) bool {
- for _, c := range pull.ProtectedBranch.StatusCheckContexts {
- if c == context {
- return true
- }
- }
- return false
+ commitStatuses, err := models.GetLatestCommitStatus(repo, sha, 0)
+ if err != nil {
+ ctx.ServerError("GetLatestCommitStatus", err)
+ return nil
+ }
+ if len(commitStatuses) > 0 {
+ ctx.Data["LatestCommitStatuses"] = commitStatuses
+ ctx.Data["LatestCommitStatus"] = models.CalcCommitStatus(commitStatuses)
+ }
+
+ if pull.ProtectedBranch != nil && pull.ProtectedBranch.EnableStatusCheck {
+ ctx.Data["is_context_required"] = func(context string) bool {
+ for _, c := range pull.ProtectedBranch.StatusCheckContexts {
+ if c == context {
+ return true
}
- ctx.Data["IsRequiredStatusCheckSuccess"] = pull_service.IsCommitStatusContextSuccess(commitStatuses, pull.ProtectedBranch.StatusCheckContexts)
}
+ return false
}
+ ctx.Data["IsRequiredStatusCheckSuccess"] = pull_service.IsCommitStatusContextSuccess(commitStatuses, pull.ProtectedBranch.StatusCheckContexts)
}
- if pull.HeadRepo == nil || !headBranchExist {
+ ctx.Data["HeadBranchMovedOn"] = headBranchSha != sha
+ ctx.Data["HeadBranchCommitID"] = headBranchSha
+ ctx.Data["PullHeadCommitID"] = sha
+
+ if pull.HeadRepo == nil || !headBranchExist || headBranchSha != sha {
ctx.Data["IsPullRequestBroken"] = true
ctx.Data["HeadTarget"] = "deleted"
- ctx.Data["NumCommits"] = 0
- ctx.Data["NumFiles"] = 0
- return nil
}
- compareInfo, err := headGitRepo.GetCompareInfo(models.RepoPath(repo.Owner.Name, repo.Name),
- pull.BaseBranch, pull.HeadBranch)
+ compareInfo, err := baseGitRepo.GetCompareInfo(pull.BaseRepo.RepoPath(),
+ pull.BaseBranch, pull.GetGitRefName())
if err != nil {
if strings.Contains(err.Error(), "fatal: Not a valid object name") {
ctx.Data["IsPullRequestBroken"] = true