From bc362ea3c611a94e7920a3cf4691fd108f874ef0 Mon Sep 17 00:00:00 2001
From: 6543 <6543@obermui.de>
Date: Fri, 10 Apr 2020 13:26:37 +0200
Subject: [PATCH] remove package code.gitea.io/gitea/modules/git import out of
 models (#11025)

---
 models/pull.go                              | 200 -------------------
 routers/repo/issue.go                       |   2 +-
 routers/repo/pull.go                        |   1 +
 routers/user/home.go                        |   3 +-
 services/pull/pull.go                       | 202 +++++++++++++++++++-
 templates/repo/issue/view_content/pull.tmpl |   3 +-
 6 files changed, 206 insertions(+), 205 deletions(-)

diff --git a/models/pull.go b/models/pull.go
index 48d2340544..02b5e98c49 100644
--- a/models/pull.go
+++ b/models/pull.go
@@ -10,7 +10,6 @@ import (
 	"io"
 	"strings"
 
-	"code.gitea.io/gitea/modules/git"
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/setting"
 	"code.gitea.io/gitea/modules/timeutil"
@@ -215,143 +214,6 @@ func (pr *PullRequest) GetDefaultMergeMessage() string {
 	return fmt.Sprintf("Merge pull request '%s' (#%d) from %s:%s into %s", pr.Issue.Title, pr.Issue.Index, pr.HeadRepo.FullName(), pr.HeadBranch, pr.BaseBranch)
 }
 
-// GetCommitMessages returns the commit messages between head and merge base (if there is one)
-func (pr *PullRequest) GetCommitMessages() string {
-	if err := pr.LoadIssue(); err != nil {
-		log.Error("Cannot load issue %d for PR id %d: Error: %v", pr.IssueID, pr.ID, err)
-		return ""
-	}
-
-	if err := pr.Issue.LoadPoster(); err != nil {
-		log.Error("Cannot load poster %d for pr id %d, index %d Error: %v", pr.Issue.PosterID, pr.ID, pr.Index, err)
-		return ""
-	}
-
-	if pr.HeadRepo == nil {
-		var err error
-		pr.HeadRepo, err = GetRepositoryByID(pr.HeadRepoID)
-		if err != nil {
-			log.Error("GetRepositoryById[%d]: %v", pr.HeadRepoID, err)
-			return ""
-		}
-	}
-
-	gitRepo, err := git.OpenRepository(pr.HeadRepo.RepoPath())
-	if err != nil {
-		log.Error("Unable to open head repository: Error: %v", err)
-		return ""
-	}
-	defer gitRepo.Close()
-
-	headCommit, err := gitRepo.GetBranchCommit(pr.HeadBranch)
-	if err != nil {
-		log.Error("Unable to get head commit: %s Error: %v", pr.HeadBranch, err)
-		return ""
-	}
-
-	mergeBase, err := gitRepo.GetCommit(pr.MergeBase)
-	if err != nil {
-		log.Error("Unable to get merge base commit: %s Error: %v", pr.MergeBase, err)
-		return ""
-	}
-
-	limit := setting.Repository.PullRequest.DefaultMergeMessageCommitsLimit
-
-	list, err := gitRepo.CommitsBetweenLimit(headCommit, mergeBase, limit, 0)
-	if err != nil {
-		log.Error("Unable to get commits between: %s %s Error: %v", pr.HeadBranch, pr.MergeBase, err)
-		return ""
-	}
-
-	maxSize := setting.Repository.PullRequest.DefaultMergeMessageSize
-
-	posterSig := pr.Issue.Poster.NewGitSig().String()
-
-	authorsMap := map[string]bool{}
-	authors := make([]string, 0, list.Len())
-	stringBuilder := strings.Builder{}
-	element := list.Front()
-	for element != nil {
-		commit := element.Value.(*git.Commit)
-
-		if maxSize < 0 || stringBuilder.Len() < maxSize {
-			toWrite := []byte(commit.CommitMessage)
-			if len(toWrite) > maxSize-stringBuilder.Len() && maxSize > -1 {
-				toWrite = append(toWrite[:maxSize-stringBuilder.Len()], "..."...)
-			}
-			if _, err := stringBuilder.Write(toWrite); err != nil {
-				log.Error("Unable to write commit message Error: %v", err)
-				return ""
-			}
-
-			if _, err := stringBuilder.WriteRune('\n'); err != nil {
-				log.Error("Unable to write commit message Error: %v", err)
-				return ""
-			}
-		}
-
-		authorString := commit.Author.String()
-		if !authorsMap[authorString] && authorString != posterSig {
-			authors = append(authors, authorString)
-			authorsMap[authorString] = true
-		}
-		element = element.Next()
-	}
-
-	// Consider collecting the remaining authors
-	if limit >= 0 && setting.Repository.PullRequest.DefaultMergeMessageAllAuthors {
-		skip := limit
-		limit = 30
-		for {
-			list, err := gitRepo.CommitsBetweenLimit(headCommit, mergeBase, limit, skip)
-			if err != nil {
-				log.Error("Unable to get commits between: %s %s Error: %v", pr.HeadBranch, pr.MergeBase, err)
-				return ""
-
-			}
-			if list.Len() == 0 {
-				break
-			}
-			element := list.Front()
-			for element != nil {
-				commit := element.Value.(*git.Commit)
-
-				authorString := commit.Author.String()
-				if !authorsMap[authorString] && authorString != posterSig {
-					authors = append(authors, authorString)
-					authorsMap[authorString] = true
-				}
-				element = element.Next()
-			}
-
-		}
-	}
-
-	if len(authors) > 0 {
-		if _, err := stringBuilder.WriteRune('\n'); err != nil {
-			log.Error("Unable to write to string builder Error: %v", err)
-			return ""
-		}
-	}
-
-	for _, author := range authors {
-		if _, err := stringBuilder.Write([]byte("Co-authored-by: ")); err != nil {
-			log.Error("Unable to write to string builder Error: %v", err)
-			return ""
-		}
-		if _, err := stringBuilder.Write([]byte(author)); err != nil {
-			log.Error("Unable to write to string builder Error: %v", err)
-			return ""
-		}
-		if _, err := stringBuilder.WriteRune('\n'); err != nil {
-			log.Error("Unable to write to string builder Error: %v", err)
-			return ""
-		}
-	}
-
-	return stringBuilder.String()
-}
-
 // ReviewCount represents a count of Reviews
 type ReviewCount struct {
 	IssueID int64
@@ -465,39 +327,6 @@ func (pr *PullRequest) CanAutoMerge() bool {
 	return pr.Status == PullRequestStatusMergeable
 }
 
-// GetLastCommitStatus returns the last commit status for this pull request.
-func (pr *PullRequest) GetLastCommitStatus() (status *CommitStatus, err error) {
-	if err = pr.LoadHeadRepo(); err != nil {
-		return nil, err
-	}
-
-	if pr.HeadRepo == nil {
-		return nil, ErrPullRequestHeadRepoMissing{pr.ID, pr.HeadRepoID}
-	}
-
-	headGitRepo, err := git.OpenRepository(pr.HeadRepo.RepoPath())
-	if err != nil {
-		return nil, err
-	}
-	defer headGitRepo.Close()
-
-	lastCommitID, err := headGitRepo.GetBranchCommitID(pr.HeadBranch)
-	if err != nil {
-		return nil, err
-	}
-
-	err = pr.LoadBaseRepo()
-	if err != nil {
-		return nil, err
-	}
-
-	statusList, err := GetLatestCommitStatus(pr.BaseRepo, lastCommitID, 0)
-	if err != nil {
-		return nil, err
-	}
-	return CalcCommitStatus(statusList), nil
-}
-
 // MergeStyle represents the approach to merge commits into base branch.
 type MergeStyle string
 
@@ -786,35 +615,6 @@ func (pr *PullRequest) GetWorkInProgressPrefix() string {
 	return ""
 }
 
-// IsHeadEqualWithBranch returns if the commits of branchName are available in pull request head
-func (pr *PullRequest) IsHeadEqualWithBranch(branchName string) (bool, error) {
-	var err error
-	if err = pr.LoadBaseRepo(); err != nil {
-		return false, err
-	}
-	baseGitRepo, err := git.OpenRepository(pr.BaseRepo.RepoPath())
-	if err != nil {
-		return false, err
-	}
-	baseCommit, err := baseGitRepo.GetBranchCommit(branchName)
-	if err != nil {
-		return false, err
-	}
-
-	if err = pr.LoadHeadRepo(); err != nil {
-		return false, err
-	}
-	headGitRepo, err := git.OpenRepository(pr.HeadRepo.RepoPath())
-	if err != nil {
-		return false, err
-	}
-	headCommit, err := headGitRepo.GetBranchCommit(pr.HeadBranch)
-	if err != nil {
-		return false, err
-	}
-	return baseCommit.HasPreviousCommit(headCommit.ID)
-}
-
 // IsSameRepo returns true if base repo and head repo is the same
 func (pr *PullRequest) IsSameRepo() bool {
 	return pr.BaseRepoID == pr.HeadRepoID
diff --git a/routers/repo/issue.go b/routers/repo/issue.go
index 0a059bf789..3655de7ed4 100644
--- a/routers/repo/issue.go
+++ b/routers/repo/issue.go
@@ -240,7 +240,7 @@ func issues(ctx *context.Context, milestoneID int64, isPullOption util.OptionalB
 				return
 			}
 
-			commitStatus[issues[i].PullRequest.ID], _ = issues[i].PullRequest.GetLastCommitStatus()
+			commitStatus[issues[i].PullRequest.ID], _ = pull_service.GetLastCommitStatus(issues[i].PullRequest)
 		}
 	}
 
diff --git a/routers/repo/pull.go b/routers/repo/pull.go
index 55b8bbb42f..ef000208f4 100644
--- a/routers/repo/pull.go
+++ b/routers/repo/pull.go
@@ -433,6 +433,7 @@ func PrepareViewPullInfo(ctx *context.Context, issue *models.Issue) *git.Compare
 			return nil
 		}
 		ctx.Data["Divergence"] = divergence
+		ctx.Data["GetCommitMessages"] = pull_service.GetCommitMessages(pull)
 	}
 
 	sha, err := baseGitRepo.GetRefCommitID(pull.GetGitRefName())
diff --git a/routers/user/home.go b/routers/user/home.go
index 3807025ea5..816968562f 100644
--- a/routers/user/home.go
+++ b/routers/user/home.go
@@ -22,6 +22,7 @@ import (
 	"code.gitea.io/gitea/modules/markup/markdown"
 	"code.gitea.io/gitea/modules/setting"
 	"code.gitea.io/gitea/modules/util"
+	pull_service "code.gitea.io/gitea/services/pull"
 
 	"github.com/keybase/go-crypto/openpgp"
 	"github.com/keybase/go-crypto/openpgp/armor"
@@ -553,7 +554,7 @@ func Issues(ctx *context.Context) {
 		issue.Repo = showReposMap[issue.RepoID]
 
 		if isPullList {
-			commitStatus[issue.PullRequest.ID], _ = issue.PullRequest.GetLastCommitStatus()
+			commitStatus[issue.PullRequest.ID], _ = pull_service.GetLastCommitStatus(issue.PullRequest)
 		}
 	}
 
diff --git a/services/pull/pull.go b/services/pull/pull.go
index ce5c4ff22f..2797294980 100644
--- a/services/pull/pull.go
+++ b/services/pull/pull.go
@@ -19,6 +19,7 @@ import (
 	"code.gitea.io/gitea/modules/graceful"
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/notification"
+	"code.gitea.io/gitea/modules/setting"
 	issue_service "code.gitea.io/gitea/services/issue"
 
 	"github.com/unknwon/com"
@@ -79,7 +80,7 @@ func ChangeTargetBranch(pr *models.PullRequest, doer *models.User, targetBranch
 	}
 
 	// Check if branches are equal
-	branchesEqual, err := pr.IsHeadEqualWithBranch(targetBranch)
+	branchesEqual, err := IsHeadEqualWithBranch(pr, targetBranch)
 	if err != nil {
 		return err
 	}
@@ -454,3 +455,202 @@ func CloseRepoBranchesPulls(doer *models.User, repo *models.Repository) error {
 	}
 	return nil
 }
+
+// GetCommitMessages returns the commit messages between head and merge base (if there is one)
+func GetCommitMessages(pr *models.PullRequest) string {
+	if err := pr.LoadIssue(); err != nil {
+		log.Error("Cannot load issue %d for PR id %d: Error: %v", pr.IssueID, pr.ID, err)
+		return ""
+	}
+
+	if err := pr.Issue.LoadPoster(); err != nil {
+		log.Error("Cannot load poster %d for pr id %d, index %d Error: %v", pr.Issue.PosterID, pr.ID, pr.Index, err)
+		return ""
+	}
+
+	if pr.HeadRepo == nil {
+		var err error
+		pr.HeadRepo, err = models.GetRepositoryByID(pr.HeadRepoID)
+		if err != nil {
+			log.Error("GetRepositoryById[%d]: %v", pr.HeadRepoID, err)
+			return ""
+		}
+	}
+
+	gitRepo, err := git.OpenRepository(pr.HeadRepo.RepoPath())
+	if err != nil {
+		log.Error("Unable to open head repository: Error: %v", err)
+		return ""
+	}
+	defer gitRepo.Close()
+
+	headCommit, err := gitRepo.GetBranchCommit(pr.HeadBranch)
+	if err != nil {
+		log.Error("Unable to get head commit: %s Error: %v", pr.HeadBranch, err)
+		return ""
+	}
+
+	mergeBase, err := gitRepo.GetCommit(pr.MergeBase)
+	if err != nil {
+		log.Error("Unable to get merge base commit: %s Error: %v", pr.MergeBase, err)
+		return ""
+	}
+
+	limit := setting.Repository.PullRequest.DefaultMergeMessageCommitsLimit
+
+	list, err := gitRepo.CommitsBetweenLimit(headCommit, mergeBase, limit, 0)
+	if err != nil {
+		log.Error("Unable to get commits between: %s %s Error: %v", pr.HeadBranch, pr.MergeBase, err)
+		return ""
+	}
+
+	maxSize := setting.Repository.PullRequest.DefaultMergeMessageSize
+
+	posterSig := pr.Issue.Poster.NewGitSig().String()
+
+	authorsMap := map[string]bool{}
+	authors := make([]string, 0, list.Len())
+	stringBuilder := strings.Builder{}
+	element := list.Front()
+	for element != nil {
+		commit := element.Value.(*git.Commit)
+
+		if maxSize < 0 || stringBuilder.Len() < maxSize {
+			toWrite := []byte(commit.CommitMessage)
+			if len(toWrite) > maxSize-stringBuilder.Len() && maxSize > -1 {
+				toWrite = append(toWrite[:maxSize-stringBuilder.Len()], "..."...)
+			}
+			if _, err := stringBuilder.Write(toWrite); err != nil {
+				log.Error("Unable to write commit message Error: %v", err)
+				return ""
+			}
+
+			if _, err := stringBuilder.WriteRune('\n'); err != nil {
+				log.Error("Unable to write commit message Error: %v", err)
+				return ""
+			}
+		}
+
+		authorString := commit.Author.String()
+		if !authorsMap[authorString] && authorString != posterSig {
+			authors = append(authors, authorString)
+			authorsMap[authorString] = true
+		}
+		element = element.Next()
+	}
+
+	// Consider collecting the remaining authors
+	if limit >= 0 && setting.Repository.PullRequest.DefaultMergeMessageAllAuthors {
+		skip := limit
+		limit = 30
+		for {
+			list, err := gitRepo.CommitsBetweenLimit(headCommit, mergeBase, limit, skip)
+			if err != nil {
+				log.Error("Unable to get commits between: %s %s Error: %v", pr.HeadBranch, pr.MergeBase, err)
+				return ""
+
+			}
+			if list.Len() == 0 {
+				break
+			}
+			element := list.Front()
+			for element != nil {
+				commit := element.Value.(*git.Commit)
+
+				authorString := commit.Author.String()
+				if !authorsMap[authorString] && authorString != posterSig {
+					authors = append(authors, authorString)
+					authorsMap[authorString] = true
+				}
+				element = element.Next()
+			}
+
+		}
+	}
+
+	if len(authors) > 0 {
+		if _, err := stringBuilder.WriteRune('\n'); err != nil {
+			log.Error("Unable to write to string builder Error: %v", err)
+			return ""
+		}
+	}
+
+	for _, author := range authors {
+		if _, err := stringBuilder.Write([]byte("Co-authored-by: ")); err != nil {
+			log.Error("Unable to write to string builder Error: %v", err)
+			return ""
+		}
+		if _, err := stringBuilder.Write([]byte(author)); err != nil {
+			log.Error("Unable to write to string builder Error: %v", err)
+			return ""
+		}
+		if _, err := stringBuilder.WriteRune('\n'); err != nil {
+			log.Error("Unable to write to string builder Error: %v", err)
+			return ""
+		}
+	}
+
+	return stringBuilder.String()
+}
+
+// GetLastCommitStatus returns the last commit status for this pull request.
+func GetLastCommitStatus(pr *models.PullRequest) (status *models.CommitStatus, err error) {
+	if err = pr.LoadHeadRepo(); err != nil {
+		return nil, err
+	}
+
+	if pr.HeadRepo == nil {
+		return nil, models.ErrPullRequestHeadRepoMissing{ID: pr.ID, HeadRepoID: pr.HeadRepoID}
+	}
+
+	headGitRepo, err := git.OpenRepository(pr.HeadRepo.RepoPath())
+	if err != nil {
+		return nil, err
+	}
+	defer headGitRepo.Close()
+
+	lastCommitID, err := headGitRepo.GetBranchCommitID(pr.HeadBranch)
+	if err != nil {
+		return nil, err
+	}
+
+	err = pr.LoadBaseRepo()
+	if err != nil {
+		return nil, err
+	}
+
+	statusList, err := models.GetLatestCommitStatus(pr.BaseRepo, lastCommitID, 0)
+	if err != nil {
+		return nil, err
+	}
+	return models.CalcCommitStatus(statusList), nil
+}
+
+// IsHeadEqualWithBranch returns if the commits of branchName are available in pull request head
+func IsHeadEqualWithBranch(pr *models.PullRequest, branchName string) (bool, error) {
+	var err error
+	if err = pr.LoadBaseRepo(); err != nil {
+		return false, err
+	}
+	baseGitRepo, err := git.OpenRepository(pr.BaseRepo.RepoPath())
+	if err != nil {
+		return false, err
+	}
+	baseCommit, err := baseGitRepo.GetBranchCommit(branchName)
+	if err != nil {
+		return false, err
+	}
+
+	if err = pr.LoadHeadRepo(); err != nil {
+		return false, err
+	}
+	headGitRepo, err := git.OpenRepository(pr.HeadRepo.RepoPath())
+	if err != nil {
+		return false, err
+	}
+	headCommit, err := headGitRepo.GetBranchCommit(pr.HeadBranch)
+	if err != nil {
+		return false, err
+	}
+	return baseCommit.HasPreviousCommit(headCommit.ID)
+}
diff --git a/templates/repo/issue/view_content/pull.tmpl b/templates/repo/issue/view_content/pull.tmpl
index 09c7cd1d9f..baad7f864d 100644
--- a/templates/repo/issue/view_content/pull.tmpl
+++ b/templates/repo/issue/view_content/pull.tmpl
@@ -234,7 +234,6 @@
 							</div>
 							{{end}}
 							{{if $prUnit.PullRequestsConfig.AllowSquash}}
-							{{$commitMessages := .Issue.PullRequest.GetCommitMessages}}
 							<div class="ui form squash-fields" style="display: none">
 								<form action="{{.Link}}/merge" method="post">
 									{{.CsrfTokenHtml}}
@@ -242,7 +241,7 @@
 										<input type="text" name="merge_title_field" value="{{.Issue.PullRequest.GetDefaultSquashMessage}}">
 									</div>
 									<div class="field">
-										<textarea name="merge_message_field" rows="5" placeholder="{{$.i18n.Tr "repo.editor.commit_message_desc"}}">{{$commitMessages}}Reviewed-on: {{$.Issue.HTMLURL}}&#13;&#10;{{$approvers}}</textarea>
+										<textarea name="merge_message_field" rows="5" placeholder="{{$.i18n.Tr "repo.editor.commit_message_desc"}}">{{.GetCommitMessages}}Reviewed-on: {{$.Issue.HTMLURL}}&#13;&#10;{{$approvers}}</textarea>
 									</div>
 									<button class="ui green button" type="submit" name="do" value="squash">
 										{{$.i18n.Tr "repo.pulls.squash_merge_pull_request"}}