Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide Default messages for merges #9393

Merged
merged 10 commits into from
Dec 30, 2019
142 changes: 142 additions & 0 deletions models/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package models

import (
"fmt"
"io"
"strings"

"code.gitea.io/gitea/modules/git"
Expand Down Expand Up @@ -177,6 +178,147 @@ func (pr *PullRequest) GetDefaultMergeMessage() string {
return fmt.Sprintf("Merge branch '%s' of %s/%s into %s", pr.HeadBranch, pr.MustHeadUserName(), pr.HeadRepo.Name, 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 ""
}
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 ""
}

list, err := gitRepo.CommitsBetween(headCommit, mergeBase)
if err != nil {
log.Error("Unable to get commits between: %s %s Error: %v", pr.HeadBranch, pr.MergeBase, err)
return ""
}

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 _, err := stringBuilder.Write([]byte(commit.CommitMessage)); err != nil {
log.Error("Unable to write commit message Error: %v", err)
return ""
}

if _, err := stringBuilder.Write([]byte{'\n'}); err != nil {
zeripath marked this conversation as resolved.
Show resolved Hide resolved
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()
}

if len(authors) > 0 {
if _, err := stringBuilder.Write([]byte{'\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.Write([]byte{'\n'}); err != nil {
log.Error("Unable to write to string builder Error: %v", err)
return ""
}
}

return stringBuilder.String()
}

// GetApprovers returns the approvers of the pull request
func (pr *PullRequest) GetApprovers() string {

stringBuilder := strings.Builder{}
if err := pr.getReviewedByLines(&stringBuilder); err != nil {
log.Error("Unable to getReviewedByLines: Error: %v", err)
return ""
}

return stringBuilder.String()
}

func (pr *PullRequest) getReviewedByLines(writer io.Writer) error {
sess := x.NewSession()
defer sess.Close()
if err := sess.Begin(); err != nil {
return err
}

reviews, err := findReviews(sess, FindReviewOptions{
Type: ReviewTypeApprove,
IssueID: pr.IssueID,
})
if err != nil {
log.Error("Unable to FindReviews for PR ID %d: %v", pr.ID, err)
return err
}
for _, review := range reviews {
if err := review.loadReviewer(sess); err != nil {
zeripath marked this conversation as resolved.
Show resolved Hide resolved
log.Error("Unable to LoadReviewer[%d] for PR ID %d : %v", review.ReviewerID, pr.ID, err)
return err
}
if _, err := writer.Write([]byte("Reviewed-by: ")); err != nil {
return err
}
if _, err := writer.Write([]byte(review.Reviewer.NewGitSig().String())); err != nil {
return err
}
if _, err := writer.Write([]byte{'\n'}); err != nil {
return err
}
}
return sess.Commit()
}

// GetDefaultSquashMessage returns default message used when squash and merging pull request
func (pr *PullRequest) GetDefaultSquashMessage() string {
if err := pr.LoadIssue(); err != nil {
Expand Down
11 changes: 10 additions & 1 deletion modules/git/repo_commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,13 @@ func (repo *Repository) FilesCountBetween(startCommitID, endCommitID string) (in

// CommitsBetween returns a list that contains commits between [last, before).
func (repo *Repository) CommitsBetween(last *Commit, before *Commit) (*list.List, error) {
stdout, err := NewCommand("rev-list", before.ID.String()+"..."+last.ID.String()).RunInDirBytes(repo.Path)
var stdout []byte
var err error
if before == nil {
stdout, err = NewCommand("rev-list", before.ID.String()).RunInDirBytes(repo.Path)
} else {
stdout, err = NewCommand("rev-list", before.ID.String()+"..."+last.ID.String()).RunInDirBytes(repo.Path)
}
if err != nil {
return nil, err
}
Expand All @@ -328,6 +334,9 @@ func (repo *Repository) CommitsBetweenIDs(last, before string) (*list.List, erro
if err != nil {
return nil, err
}
if before == "" {
return repo.CommitsBetween(lastCommit, nil)
}
beforeCommit, err := repo.GetCommit(before)
if err != nil {
return nil, err
Expand Down
8 changes: 5 additions & 3 deletions templates/repo/issue/view_content/pull.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@
{{end}}
{{if .AllowMerge}}
{{$prUnit := .Repository.MustGetUnit $.UnitTypePullRequests}}
{{$commitMessages := .Issue.PullRequest.GetCommitMessages}}
{{$approvers := .Issue.PullRequest.GetApprovers}}
{{if or $prUnit.PullRequestsConfig.AllowMerge $prUnit.PullRequestsConfig.AllowRebase $prUnit.PullRequestsConfig.AllowRebaseMerge $prUnit.PullRequestsConfig.AllowSquash}}
<div class="ui divider"></div>
{{if $prUnit.PullRequestsConfig.AllowMerge}}
Expand All @@ -141,7 +143,7 @@
<input type="text" name="merge_title_field" value="{{.Issue.PullRequest.GetDefaultMergeMessage}}">
</div>
<div class="field">
<textarea name="merge_message_field" rows="5" placeholder="{{$.i18n.Tr "repo.editor.commit_message_desc"}}"></textarea>
<textarea name="merge_message_field" rows="5" placeholder="{{$.i18n.Tr "repo.editor.commit_message_desc"}}">{{$approvers}}</textarea>
</div>
<button class="ui green button" type="submit" name="do" value="merge">
{{$.i18n.Tr "repo.pulls.merge_pull_request"}}
Expand Down Expand Up @@ -173,7 +175,7 @@
<input type="text" name="merge_title_field" value="{{.Issue.PullRequest.GetDefaultMergeMessage}}">
</div>
<div class="field">
<textarea name="merge_message_field" rows="5" placeholder="{{$.i18n.Tr "repo.editor.commit_message_desc"}}"></textarea>
<textarea name="merge_message_field" rows="5" placeholder="{{$.i18n.Tr "repo.editor.commit_message_desc"}}">{{$approvers}}</textarea>
</div>
<button class="ui green button" type="submit" name="do" value="rebase-merge">
{{$.i18n.Tr "repo.pulls.rebase_merge_commit_pull_request"}}
Expand All @@ -192,7 +194,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"}}"></textarea>
<textarea name="merge_message_field" rows="5" placeholder="{{$.i18n.Tr "repo.editor.commit_message_desc"}}">{{$commitMessages}}{{$approvers}}</textarea>
</div>
<button class="ui green button" type="submit" name="do" value="squash">
{{$.i18n.Tr "repo.pulls.squash_merge_pull_request"}}
Expand Down