fix(pull): preserve squash message trailers and additional commit messages

When a PR description already ends with git trailers (e.g. Issue: X,
Signed-off-by:), the co-author separator line (---------)  was still
inserted before the Co-authored-by lines, breaking the trailer block.
messageHasTrailers now skips the separator so co-authors are appended
directly into the existing trailer block.

In PR-description mode (PopulateSquashCommentWithCommitMessages=false),
commit messages beyond the oldest were silently dropped. They are now
appended as bullet points after the PR description, consistent with the
commit-message mode format.

The commit-message loop is extracted into formatSquashMergeCommitMessages.
Callers that want to skip the oldest commit pass a trimmed slice
(commits[:max(0, len(commits)-1)]) instead of a skipFirst bool flag.

Co-Authored-By: Nicolas <nicolas@bircks.eu>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Nicolas
2026-05-31 12:12:36 +02:00
co-authored by Nicolas Claude Sonnet 4.6
parent a39b2775ed
commit f5d0e1633d
2 changed files with 63 additions and 31 deletions
+20
View File
@@ -11,7 +11,9 @@ import (
repo_model "gitea.dev/models/repo"
"gitea.dev/models/unit"
"gitea.dev/models/unittest"
"gitea.dev/modules/git"
"gitea.dev/modules/gitrepo"
"gitea.dev/modules/setting"
"github.com/stretchr/testify/assert"
)
@@ -35,6 +37,24 @@ func TestPullRequest_CommitMessageTrailersPattern(t *testing.T) {
assert.True(t, commitMessageTrailersPattern.MatchString("Folded value.\n\nFolded-trailer: This is\n a folded\n trailer value\nOther-Trailer: Value"))
}
func TestPullRequest_FormatSquashMergeCommitMessages(t *testing.T) {
oldest := &git.Commit{CommitMessage: git.CommitMessage{MessageRaw: "commit msg 1"}}
newest := &git.Commit{CommitMessage: git.CommitMessage{MessageRaw: "commit msg 2\n\nCommit description."}}
defer func(old int) { setting.Repository.PullRequest.DefaultMergeMessageSize = old }(
setting.Repository.PullRequest.DefaultMergeMessageSize,
)
setting.Repository.PullRequest.DefaultMergeMessageSize = 0
// all commits
assert.Equal(t, "* commit msg 1\n\n* commit msg 2\n\nCommit description.\n\n",
formatSquashMergeCommitMessages([]*git.Commit{newest, oldest}))
// PR-description mode: pass all-but-oldest so the oldest is not duplicated
assert.Equal(t, "* commit msg 2\n\nCommit description.\n\n",
formatSquashMergeCommitMessages([]*git.Commit{newest}))
}
func TestPullRequest_GetDefaultMergeMessage_InternalTracker(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2})