Provide Default messages for merges (#9393)
Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com>
This commit is contained in:
parent
b983ff4473
commit
0c07f1de5b
7 changed files with 276 additions and 15 deletions
|
@ -76,6 +76,16 @@ WORK_IN_PROGRESS_PREFIXES=WIP:,[WIP]
|
||||||
CLOSE_KEYWORDS=close,closes,closed,fix,fixes,fixed,resolve,resolves,resolved
|
CLOSE_KEYWORDS=close,closes,closed,fix,fixes,fixed,resolve,resolves,resolved
|
||||||
; List of keywords used in Pull Request comments to automatically reopen a related issue
|
; List of keywords used in Pull Request comments to automatically reopen a related issue
|
||||||
REOPEN_KEYWORDS=reopen,reopens,reopened
|
REOPEN_KEYWORDS=reopen,reopens,reopened
|
||||||
|
; In the default merge message for squash commits include at most this many commits
|
||||||
|
DEFAULT_MERGE_MESSAGE_COMMITS_LIMIT=50
|
||||||
|
; In the default merge message for squash commits limit the size of the commit messages to this
|
||||||
|
DEFAULT_MERGE_MESSAGE_SIZE=5120
|
||||||
|
; In the default merge message for squash commits walk all commits to include all authors in the Co-authored-by otherwise just use those in the limited list
|
||||||
|
DEFAULT_MERGE_MESSAGE_ALL_AUTHORS=false
|
||||||
|
; In default merge messages limit the number of approvers listed as Reviewed-by: to this many
|
||||||
|
DEFAULT_MERGE_MESSAGE_MAX_APPROVERS=10
|
||||||
|
; In default merge messages only include approvers who are official
|
||||||
|
DEFAULT_MERGE_MESSAGE_OFFICIAL_APPROVERS_ONLY=true
|
||||||
|
|
||||||
[repository.issue]
|
[repository.issue]
|
||||||
; List of reasons why a Pull Request or Issue can be locked
|
; List of reasons why a Pull Request or Issue can be locked
|
||||||
|
|
|
@ -77,6 +77,11 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
|
||||||
keywords used in Pull Request comments to automatically close a related issue
|
keywords used in Pull Request comments to automatically close a related issue
|
||||||
- `REOPEN_KEYWORDS`: **reopen**, **reopens**, **reopened**: List of keywords used in Pull Request comments to automatically reopen
|
- `REOPEN_KEYWORDS`: **reopen**, **reopens**, **reopened**: List of keywords used in Pull Request comments to automatically reopen
|
||||||
a related issue
|
a related issue
|
||||||
|
- `DEFAULT_MERGE_MESSAGE_COMMITS_LIMIT`: **50**: In the default merge message for squash commits include at most this many commits. Set to `-1` to include all commits
|
||||||
|
- `DEFAULT_MERGE_MESSAGE_SIZE`: **5120**: In the default merge message for squash commits limit the size of the commit messages. Set to `-1` to have no limit.
|
||||||
|
- `DEFAULT_MERGE_MESSAGE_ALL_AUTHORS`: **false**: In the default merge message for squash commits walk all commits to include all authors in the Co-authored-by otherwise just use those in the limited list
|
||||||
|
- `DEFAULT_MERGE_MESSAGE_MAX_APPROVERS`: **10**: In default merge messages limit the number of approvers listed as `Reviewed-by:`. Set to `-1` to include all.
|
||||||
|
- `DEFAULT_MERGE_MESSAGE_OFFICIAL_APPROVERS_ONLY`: **true**: In default merge messages only include approvers who are officially allowed to review.
|
||||||
|
|
||||||
### Repository - Issue (`repository.issue`)
|
### Repository - Issue (`repository.issue`)
|
||||||
|
|
||||||
|
|
201
models/pull.go
201
models/pull.go
|
@ -7,6 +7,7 @@ package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
|
@ -177,6 +178,206 @@ 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)
|
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 ""
|
||||||
|
}
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 {
|
||||||
|
maxReviewers := setting.Repository.PullRequest.DefaultMergeMessageMaxApprovers
|
||||||
|
|
||||||
|
if maxReviewers == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
sess := x.NewSession()
|
||||||
|
defer sess.Close()
|
||||||
|
if err := sess.Begin(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: This doesn't page as we only expect a very limited number of reviews
|
||||||
|
reviews, err := findReviews(sess, FindReviewOptions{
|
||||||
|
Type: ReviewTypeApprove,
|
||||||
|
IssueID: pr.IssueID,
|
||||||
|
OfficialOnly: setting.Repository.PullRequest.DefaultMergeMessageOfficialApproversOnly,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Unable to FindReviews for PR ID %d: %v", pr.ID, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
reviewersWritten := 0
|
||||||
|
|
||||||
|
for _, review := range reviews {
|
||||||
|
if maxReviewers > 0 && reviewersWritten > maxReviewers {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := review.loadReviewer(sess); err != nil && !IsErrUserNotExist(err) {
|
||||||
|
log.Error("Unable to LoadReviewer[%d] for PR ID %d : %v", review.ReviewerID, pr.ID, err)
|
||||||
|
return err
|
||||||
|
} else if review.Reviewer == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
reviewersWritten++
|
||||||
|
}
|
||||||
|
return sess.Commit()
|
||||||
|
}
|
||||||
|
|
||||||
// GetDefaultSquashMessage returns default message used when squash and merging pull request
|
// GetDefaultSquashMessage returns default message used when squash and merging pull request
|
||||||
func (pr *PullRequest) GetDefaultSquashMessage() string {
|
func (pr *PullRequest) GetDefaultSquashMessage() string {
|
||||||
if err := pr.LoadIssue(); err != nil {
|
if err := pr.LoadIssue(); err != nil {
|
||||||
|
|
|
@ -125,9 +125,10 @@ func GetReviewByID(id int64) (*Review, error) {
|
||||||
|
|
||||||
// FindReviewOptions represent possible filters to find reviews
|
// FindReviewOptions represent possible filters to find reviews
|
||||||
type FindReviewOptions struct {
|
type FindReviewOptions struct {
|
||||||
Type ReviewType
|
Type ReviewType
|
||||||
IssueID int64
|
IssueID int64
|
||||||
ReviewerID int64
|
ReviewerID int64
|
||||||
|
OfficialOnly bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (opts *FindReviewOptions) toCond() builder.Cond {
|
func (opts *FindReviewOptions) toCond() builder.Cond {
|
||||||
|
@ -141,6 +142,9 @@ func (opts *FindReviewOptions) toCond() builder.Cond {
|
||||||
if opts.Type != ReviewTypeUnknown {
|
if opts.Type != ReviewTypeUnknown {
|
||||||
cond = cond.And(builder.Eq{"type": opts.Type})
|
cond = cond.And(builder.Eq{"type": opts.Type})
|
||||||
}
|
}
|
||||||
|
if opts.OfficialOnly {
|
||||||
|
cond = cond.And(builder.Eq{"official": true})
|
||||||
|
}
|
||||||
return cond
|
return cond
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -315,7 +315,28 @@ func (repo *Repository) FilesCountBetween(startCommitID, endCommitID string) (in
|
||||||
|
|
||||||
// CommitsBetween returns a list that contains commits between [last, before).
|
// CommitsBetween returns a list that contains commits between [last, before).
|
||||||
func (repo *Repository) CommitsBetween(last *Commit, before *Commit) (*list.List, error) {
|
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
|
||||||
|
}
|
||||||
|
return repo.parsePrettyFormatLogToList(bytes.TrimSpace(stdout))
|
||||||
|
}
|
||||||
|
|
||||||
|
// CommitsBetweenLimit returns a list that contains at most limit commits skipping the first skip commits between [last, before)
|
||||||
|
func (repo *Repository) CommitsBetweenLimit(last *Commit, before *Commit, limit, skip int) (*list.List, error) {
|
||||||
|
var stdout []byte
|
||||||
|
var err error
|
||||||
|
if before == nil {
|
||||||
|
stdout, err = NewCommand("rev-list", "--max-count", strconv.Itoa(limit), "--skip", strconv.Itoa(skip), last.ID.String()).RunInDirBytes(repo.Path)
|
||||||
|
} else {
|
||||||
|
stdout, err = NewCommand("rev-list", "--max-count", strconv.Itoa(limit), "--skip", strconv.Itoa(skip), before.ID.String()+"..."+last.ID.String()).RunInDirBytes(repo.Path)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -328,6 +349,9 @@ func (repo *Repository) CommitsBetweenIDs(last, before string) (*list.List, erro
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if before == "" {
|
||||||
|
return repo.CommitsBetween(lastCommit, nil)
|
||||||
|
}
|
||||||
beforeCommit, err := repo.GetCommit(before)
|
beforeCommit, err := repo.GetCommit(before)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -60,9 +60,14 @@ var (
|
||||||
|
|
||||||
// Pull request settings
|
// Pull request settings
|
||||||
PullRequest struct {
|
PullRequest struct {
|
||||||
WorkInProgressPrefixes []string
|
WorkInProgressPrefixes []string
|
||||||
CloseKeywords []string
|
CloseKeywords []string
|
||||||
ReopenKeywords []string
|
ReopenKeywords []string
|
||||||
|
DefaultMergeMessageCommitsLimit int
|
||||||
|
DefaultMergeMessageSize int
|
||||||
|
DefaultMergeMessageAllAuthors bool
|
||||||
|
DefaultMergeMessageMaxApprovers int
|
||||||
|
DefaultMergeMessageOfficialApproversOnly bool
|
||||||
} `ini:"repository.pull-request"`
|
} `ini:"repository.pull-request"`
|
||||||
|
|
||||||
// Issue Setting
|
// Issue Setting
|
||||||
|
@ -127,15 +132,25 @@ var (
|
||||||
|
|
||||||
// Pull request settings
|
// Pull request settings
|
||||||
PullRequest: struct {
|
PullRequest: struct {
|
||||||
WorkInProgressPrefixes []string
|
WorkInProgressPrefixes []string
|
||||||
CloseKeywords []string
|
CloseKeywords []string
|
||||||
ReopenKeywords []string
|
ReopenKeywords []string
|
||||||
|
DefaultMergeMessageCommitsLimit int
|
||||||
|
DefaultMergeMessageSize int
|
||||||
|
DefaultMergeMessageAllAuthors bool
|
||||||
|
DefaultMergeMessageMaxApprovers int
|
||||||
|
DefaultMergeMessageOfficialApproversOnly bool
|
||||||
}{
|
}{
|
||||||
WorkInProgressPrefixes: []string{"WIP:", "[WIP]"},
|
WorkInProgressPrefixes: []string{"WIP:", "[WIP]"},
|
||||||
// Same as GitHub. See
|
// Same as GitHub. See
|
||||||
// https://help.github.com/articles/closing-issues-via-commit-messages
|
// https://help.github.com/articles/closing-issues-via-commit-messages
|
||||||
CloseKeywords: strings.Split("close,closes,closed,fix,fixes,fixed,resolve,resolves,resolved", ","),
|
CloseKeywords: strings.Split("close,closes,closed,fix,fixes,fixed,resolve,resolves,resolved", ","),
|
||||||
ReopenKeywords: strings.Split("reopen,reopens,reopened", ","),
|
ReopenKeywords: strings.Split("reopen,reopens,reopened", ","),
|
||||||
|
DefaultMergeMessageCommitsLimit: 50,
|
||||||
|
DefaultMergeMessageSize: 5 * 1024,
|
||||||
|
DefaultMergeMessageAllAuthors: false,
|
||||||
|
DefaultMergeMessageMaxApprovers: 10,
|
||||||
|
DefaultMergeMessageOfficialApproversOnly: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
// Issue settings
|
// Issue settings
|
||||||
|
|
|
@ -131,6 +131,7 @@
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if .AllowMerge}}
|
{{if .AllowMerge}}
|
||||||
{{$prUnit := .Repository.MustGetUnit $.UnitTypePullRequests}}
|
{{$prUnit := .Repository.MustGetUnit $.UnitTypePullRequests}}
|
||||||
|
{{$approvers := .Issue.PullRequest.GetApprovers}}
|
||||||
{{if or $prUnit.PullRequestsConfig.AllowMerge $prUnit.PullRequestsConfig.AllowRebase $prUnit.PullRequestsConfig.AllowRebaseMerge $prUnit.PullRequestsConfig.AllowSquash}}
|
{{if or $prUnit.PullRequestsConfig.AllowMerge $prUnit.PullRequestsConfig.AllowRebase $prUnit.PullRequestsConfig.AllowRebaseMerge $prUnit.PullRequestsConfig.AllowSquash}}
|
||||||
<div class="ui divider"></div>
|
<div class="ui divider"></div>
|
||||||
{{if $prUnit.PullRequestsConfig.AllowMerge}}
|
{{if $prUnit.PullRequestsConfig.AllowMerge}}
|
||||||
|
@ -141,7 +142,7 @@
|
||||||
<input type="text" name="merge_title_field" value="{{.Issue.PullRequest.GetDefaultMergeMessage}}">
|
<input type="text" name="merge_title_field" value="{{.Issue.PullRequest.GetDefaultMergeMessage}}">
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<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>
|
</div>
|
||||||
<button class="ui green button" type="submit" name="do" value="merge">
|
<button class="ui green button" type="submit" name="do" value="merge">
|
||||||
{{$.i18n.Tr "repo.pulls.merge_pull_request"}}
|
{{$.i18n.Tr "repo.pulls.merge_pull_request"}}
|
||||||
|
@ -173,7 +174,7 @@
|
||||||
<input type="text" name="merge_title_field" value="{{.Issue.PullRequest.GetDefaultMergeMessage}}">
|
<input type="text" name="merge_title_field" value="{{.Issue.PullRequest.GetDefaultMergeMessage}}">
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<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>
|
</div>
|
||||||
<button class="ui green button" type="submit" name="do" value="rebase-merge">
|
<button class="ui green button" type="submit" name="do" value="rebase-merge">
|
||||||
{{$.i18n.Tr "repo.pulls.rebase_merge_commit_pull_request"}}
|
{{$.i18n.Tr "repo.pulls.rebase_merge_commit_pull_request"}}
|
||||||
|
@ -185,6 +186,7 @@
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if $prUnit.PullRequestsConfig.AllowSquash}}
|
{{if $prUnit.PullRequestsConfig.AllowSquash}}
|
||||||
|
{{$commitMessages := .Issue.PullRequest.GetCommitMessages}}
|
||||||
<div class="ui form squash-fields" style="display: none">
|
<div class="ui form squash-fields" style="display: none">
|
||||||
<form action="{{.Link}}/merge" method="post">
|
<form action="{{.Link}}/merge" method="post">
|
||||||
{{.CsrfTokenHtml}}
|
{{.CsrfTokenHtml}}
|
||||||
|
@ -192,7 +194,7 @@
|
||||||
<input type="text" name="merge_title_field" value="{{.Issue.PullRequest.GetDefaultSquashMessage}}">
|
<input type="text" name="merge_title_field" value="{{.Issue.PullRequest.GetDefaultSquashMessage}}">
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<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>
|
</div>
|
||||||
<button class="ui green button" type="submit" name="do" value="squash">
|
<button class="ui green button" type="submit" name="do" value="squash">
|
||||||
{{$.i18n.Tr "repo.pulls.squash_merge_pull_request"}}
|
{{$.i18n.Tr "repo.pulls.squash_merge_pull_request"}}
|
||||||
|
|
Reference in a new issue