From f99aa56c4ff491913787e016a9c8f4c98376a093 Mon Sep 17 00:00:00 2001 From: Nicolas Date: Sun, 31 May 2026 12:57:52 +0200 Subject: [PATCH] fix --- services/pull/pull.go | 22 ++++++++++------------ services/pull/pull_test.go | 6 ++---- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/services/pull/pull.go b/services/pull/pull.go index 35f9823e2f..8a2410d875 100644 --- a/services/pull/pull.go +++ b/services/pull/pull.go @@ -12,7 +12,6 @@ import ( "slices" "strings" "time" - "unicode/utf8" "gitea.dev/models/db" git_model "gitea.dev/models/git" @@ -831,11 +830,13 @@ func GetSquashMergeCommitMessages(ctx context.Context, pr *issues_model.PullRequ authors := make([]string, 0, len(commits)) stringBuilder := strings.Builder{} - messageHasTrailers := false + // trailerBlockAtEnd tracks whether the message currently ends with a Git trailer block. + // When true, we skip the "---------" separator so Co-authored-by lines stay contiguous with it. + trailerBlockAtEnd := false if !setting.Repository.PullRequest.PopulateSquashCommentWithCommitMessages { // use PR's title and description as squash commit message message := strings.TrimSpace(pr.Issue.Content) - messageHasTrailers = commitMessageTrailersPattern.MatchString(message) + messageHasTrailers := commitMessageTrailersPattern.MatchString(message) stringBuilder.WriteString(message) additionalCommitMessages := formatSquashMergeCommitMessages(commits[:max(0, len(commits)-1)]) if additionalCommitMessages != "" { @@ -843,11 +844,13 @@ func GetSquashMergeCommitMessages(ctx context.Context, pr *issues_model.PullRequ stringBuilder.WriteString("\n\n") } stringBuilder.WriteString(additionalCommitMessages) + // appended bullets push the PR-description trailers (if any) out of the trailer-block position } else if stringBuilder.Len() > 0 { stringBuilder.WriteRune('\n') if !messageHasTrailers { stringBuilder.WriteRune('\n') } + trailerBlockAtEnd = messageHasTrailers } } else { // use PR's commit messages as squash commit message @@ -893,7 +896,7 @@ func GetSquashMergeCommitMessages(ctx context.Context, pr *issues_model.PullRequ } } - if stringBuilder.Len() > 0 && len(authors) > 0 && !messageHasTrailers { + if stringBuilder.Len() > 0 && len(authors) > 0 && !trailerBlockAtEnd { stringBuilder.WriteString("---------\n\n") } @@ -921,14 +924,9 @@ func formatSquashMergeCommitMessages(commits []*git.Commit) string { // Maybe, ideally, we should indent those lines too. _, _ = fmt.Fprintf(&stringBuilder, "* %s\n\n", msg) if maxMsgSize > 0 && stringBuilder.Len() >= maxMsgSize { - tmp := stringBuilder.String() - wasValidUtf8 := utf8.ValidString(tmp) - tmp = tmp[:maxMsgSize] + "..." - if wasValidUtf8 { - // If the message was valid UTF-8 before truncation, ensure it remains valid after truncation - // For non-utf8 messages, we can't do much about it, end users should use utf-8 as much as possible - tmp = strings.ToValidUTF8(tmp, "") - } + // MessageUTF8 already guarantees valid UTF-8, but the byte-offset truncation + // can split a multi-byte rune, so trim any resulting invalid trailing bytes. + tmp := strings.ToValidUTF8(stringBuilder.String()[:maxMsgSize], "") + "..." stringBuilder.Reset() stringBuilder.WriteString(tmp) break diff --git a/services/pull/pull_test.go b/services/pull/pull_test.go index ec3116ef61..16ced40631 100644 --- a/services/pull/pull_test.go +++ b/services/pull/pull_test.go @@ -14,6 +14,7 @@ import ( "gitea.dev/modules/git" "gitea.dev/modules/gitrepo" "gitea.dev/modules/setting" + "gitea.dev/modules/test" "github.com/stretchr/testify/assert" ) @@ -41,10 +42,7 @@ 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 + defer test.MockVariableValue(&setting.Repository.PullRequest.DefaultMergeMessageSize, 0)() // all commits assert.Equal(t, "* commit msg 1\n\n* commit msg 2\n\nCommit description.\n\n",