Skip to content

Commit 0ed7237

Browse files
wetnebtclin914
authored andcommitted
[gitea] Always use an empty line to separate the commit message and trailer (#8041)
This is a port of a gitea PR: go-gitea/gitea#34512. I have added some copy-editing commits on top for cleanliness. I haven't tested the changes manually and only relied on the existing automated test. ## Checklist ### Tests - I added test coverage for Go changes... - [x] in their respective `*_test.go` for unit tests. - [ ] in the `tests/integration` directory if it involves interactions with a live Forgejo server. ### Documentation - [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change. - [x] I did not document these changes and I do not expect someone else to do it. ### Release notes - [x] I do not want this change to show in the release notes. - [ ] I want the title to show in the release notes with a link to this pull request. - [ ] I want the content of the `release-notes/<pull request number>.md` to be be used for the release notes instead of the title. Co-authored-by: Jim Lin <[email protected]> Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/8041 Reviewed-by: Earl Warren <[email protected]> Co-authored-by: Antonin Delpeuch <[email protected]> Co-committed-by: Antonin Delpeuch <[email protected]>
1 parent fc35915 commit 0ed7237

File tree

3 files changed

+63
-5
lines changed

3 files changed

+63
-5
lines changed

services/pull/merge.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"regexp"
1515
"strconv"
1616
"strings"
17+
"unicode"
1718

1819
"forgejo.org/models"
1920
"forgejo.org/models/db"
@@ -169,6 +170,41 @@ func GetDefaultMergeMessage(ctx context.Context, baseGitRepo *git.Repository, pr
169170
return getMergeMessage(ctx, baseGitRepo, pr, mergeStyle, nil)
170171
}
171172

173+
func AddCommitMessageTrailer(message, tailerKey, tailerValue string) string {
174+
trailerLine := tailerKey + ": " + tailerValue
175+
message = strings.ReplaceAll(message, "\r\n", "\n")
176+
message = strings.ReplaceAll(message, "\r", "\n")
177+
if strings.Contains(message, "\n"+trailerLine+"\n") || strings.HasSuffix(message, "\n"+trailerLine) {
178+
return message
179+
}
180+
181+
if !strings.HasSuffix(message, "\n") {
182+
message += "\n"
183+
}
184+
lastNewLine := strings.LastIndexByte(message[:len(message)-1], '\n')
185+
keyEnd := -1
186+
if lastNewLine != -1 {
187+
keyEnd = strings.IndexByte(message[lastNewLine:], ':')
188+
if keyEnd != -1 {
189+
keyEnd += lastNewLine
190+
}
191+
}
192+
var lastLineKey string
193+
if lastNewLine != -1 && keyEnd != -1 {
194+
lastLineKey = message[lastNewLine+1 : keyEnd]
195+
}
196+
197+
isLikelyTrailerLine := lastLineKey != "" && unicode.IsUpper(rune(lastLineKey[0])) && strings.Contains(message, "-")
198+
for i := 0; isLikelyTrailerLine && i < len(lastLineKey); i++ {
199+
r := rune(lastLineKey[i])
200+
isLikelyTrailerLine = unicode.IsLetter(r) || unicode.IsDigit(r) || r == '-'
201+
}
202+
if !strings.HasSuffix(message, "\n\n") && !isLikelyTrailerLine {
203+
message += "\n"
204+
}
205+
return message + trailerLine
206+
}
207+
172208
// Merge merges pull request to base repository.
173209
// Caller should check PR is ready to be merged (review and status checks)
174210
func Merge(ctx context.Context, pr *issues_model.PullRequest, doer *user_model.User, baseGitRepo *git.Repository, mergeStyle repo_model.MergeStyle, expectedHeadCommitID, message string, wasAutoMerged bool) error {

services/pull/merge_squash.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ package pull
55

66
import (
77
"fmt"
8-
"strings"
98

109
repo_model "forgejo.org/models/repo"
1110
user_model "forgejo.org/models/user"
@@ -67,10 +66,8 @@ func doMergeStyleSquash(ctx *mergeContext, message string) error {
6766

6867
if setting.Repository.PullRequest.AddCoCommitterTrailers && ctx.committer.String() != sig.String() {
6968
// add trailer
70-
if !strings.Contains(message, fmt.Sprintf("Co-authored-by: %s", sig.String())) {
71-
message += fmt.Sprintf("\nCo-authored-by: %s", sig.String())
72-
}
73-
message += fmt.Sprintf("\nCo-committed-by: %s\n", sig.String())
69+
message = AddCommitMessageTrailer(message, "Co-authored-by", sig.String())
70+
message = AddCommitMessageTrailer(message, "Co-committed-by", sig.String()) // FIXME: this one should be removed, it is not really used or widely used
7471
}
7572
cmdCommit := git.NewCommand(ctx, "commit").
7673
AddOptionFormat("--author='%s <%s>'", sig.Name, sig.Email).

services/pull/merge_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,28 @@ func Test_expandDefaultMergeMessage(t *testing.T) {
6565
})
6666
}
6767
}
68+
69+
func TestAddCommitMessageTailer(t *testing.T) {
70+
// add tailer for empty message
71+
assert.Equal(t, "\n\nTest-tailer: TestValue", AddCommitMessageTrailer("", "Test-tailer", "TestValue"))
72+
73+
// add tailer for message without newlines
74+
assert.Equal(t, "title\n\nTest-tailer: TestValue", AddCommitMessageTrailer("title", "Test-tailer", "TestValue"))
75+
assert.Equal(t, "title\n\nNot tailer: xxx\n\nTest-tailer: TestValue", AddCommitMessageTrailer("title\n\nNot tailer: xxx", "Test-tailer", "TestValue"))
76+
assert.Equal(t, "title\n\nNotTailer: xxx\n\nTest-tailer: TestValue", AddCommitMessageTrailer("title\n\nNotTailer: xxx", "Test-tailer", "TestValue"))
77+
assert.Equal(t, "title\n\nnot-tailer: xxx\n\nTest-tailer: TestValue", AddCommitMessageTrailer("title\n\nnot-tailer: xxx", "Test-tailer", "TestValue"))
78+
79+
// add tailer for message with one EOL
80+
assert.Equal(t, "title\n\nTest-tailer: TestValue", AddCommitMessageTrailer("title\n", "Test-tailer", "TestValue"))
81+
82+
// add tailer for message with two EOLs
83+
assert.Equal(t, "title\n\nTest-tailer: TestValue", AddCommitMessageTrailer("title\n\n", "Test-tailer", "TestValue"))
84+
85+
// add tailer for message with existing tailer (won't duplicate)
86+
assert.Equal(t, "title\n\nTest-tailer: TestValue", AddCommitMessageTrailer("title\n\nTest-tailer: TestValue", "Test-tailer", "TestValue"))
87+
assert.Equal(t, "title\n\nTest-tailer: TestValue\n", AddCommitMessageTrailer("title\n\nTest-tailer: TestValue\n", "Test-tailer", "TestValue"))
88+
89+
// add tailer for message with existing tailer and different value (will append)
90+
assert.Equal(t, "title\n\nTest-tailer: v1\nTest-tailer: v2", AddCommitMessageTrailer("title\n\nTest-tailer: v1", "Test-tailer", "v2"))
91+
assert.Equal(t, "title\n\nTest-tailer: v1\nTest-tailer: v2", AddCommitMessageTrailer("title\n\nTest-tailer: v1\n", "Test-tailer", "v2"))
92+
}

0 commit comments

Comments
 (0)