diff --git a/models/git/branch.go b/models/git/branch.go index 698c43f147..db53ca0ac7 100644 --- a/models/git/branch.go +++ b/models/git/branch.go @@ -261,7 +261,7 @@ func UpdateBranch(ctx context.Context, repoID, pusherID int64, branchName string Cols("commit_id, commit_message, pusher_id, commit_time, is_deleted, updated_unix"). Update(&Branch{ CommitID: commit.ID.String(), - CommitMessage: commit.Summary(), + CommitMessage: commit.MessageTitle(), PusherID: pusherID, CommitTime: timeutil.TimeStamp(commit.Committer.When.Unix()), IsDeleted: false, diff --git a/models/git/branch_test.go b/models/git/branch_test.go index 3832df9350..be67439285 100644 --- a/models/git/branch_test.go +++ b/models/git/branch_test.go @@ -36,7 +36,7 @@ func TestAddDeletedBranch(t *testing.T) { commit := &git.Commit{ ID: git.MustIDFromString(secondBranch.CommitID), - CommitMessage: secondBranch.CommitMessage, + CommitMessage: git.CommitMessage{MessageRaw: secondBranch.CommitMessage}, Committer: &git.Signature{ When: secondBranch.CommitTime.AsLocalTime(), }, diff --git a/modules/charset/charset.go b/modules/charset/charset.go index 96de1c9fcc..e5df55c9b6 100644 --- a/modules/charset/charset.go +++ b/modules/charset/charset.go @@ -89,7 +89,10 @@ func ToUTF8(content []byte, opts ConvertOpts) []byte { encoding, _ := charset.Lookup(charsetLabel) if encoding == nil { setting.PanicInDevOrTesting("unsupported detected charset %q, it shouldn't happen", charsetLabel) - return content + if opts.ErrorReturnOrigin { + return content + } + return bytes.ToValidUTF8(content, opts.ErrorReplacement) } var decoded []byte diff --git a/modules/git/commit.go b/modules/git/commit.go index c3d23d6878..b576451db8 100644 --- a/modules/git/commit.go +++ b/modules/git/commit.go @@ -11,19 +11,28 @@ import ( "os/exec" "strings" + "code.gitea.io/gitea/modules/charset" "code.gitea.io/gitea/modules/git/gitcmd" "code.gitea.io/gitea/modules/util" ) +type CommitMessage struct { + MessageRaw string + messageUTF8 *string + messageTitle *string + messageBody *string +} + // Commit represents a git commit. type Commit struct { Tree // FIXME: bad design, this field can be nil if the commit is from "last commit cache" - ID ObjectID - Author *Signature // never nil - Committer *Signature // never nil - CommitMessage string - Signature *CommitSignature + CommitMessage + + ID ObjectID + Author *Signature // never nil + Committer *Signature // never nil + Signature *CommitSignature Parents []ObjectID // ID strings submoduleCache *ObjectCache[*SubModule] @@ -35,19 +44,28 @@ type CommitSignature struct { Payload string } -// Message returns the commit message. Same as retrieving CommitMessage directly. -func (c *Commit) Message() string { - // FIXME: GIT-COMMIT-MESSAGE-ENCODING: this logic is not right - // * When need to use commit message in templates/database, it should be valid UTF-8 - // * When need to get the original commit message, it should just use "c.CommitMessage" - // It's not easy to refactor at the moment, many templates need to be updated and tested - return c.CommitMessage +func (c *CommitMessage) MessageUTF8() string { + if c.messageUTF8 == nil { + bs := charset.ToUTF8(util.UnsafeStringToBytes(c.MessageRaw), charset.ConvertOpts{ErrorReplacement: []byte{'?'}}) + c.messageUTF8 = new(util.UnsafeBytesToString(bs)) + } + return *c.messageUTF8 } -// Summary returns first line of commit message. -// The string is forced to be valid UTF8 -func (c *Commit) Summary() string { - return strings.ToValidUTF8(strings.Split(strings.TrimSpace(c.CommitMessage), "\n")[0], "?") +func (c *CommitMessage) MessageTitle() string { + if c.messageTitle == nil { + s, _, _ := strings.Cut(strings.TrimSpace(c.MessageUTF8()), "\n") + c.messageTitle = new(strings.TrimSpace(s)) + } + return *c.messageTitle +} + +func (c *CommitMessage) MessageBody() string { + if c.messageBody == nil { + _, s, _ := strings.Cut(strings.TrimSpace(c.MessageUTF8()), "\n") + c.messageBody = new(strings.TrimSpace(s)) + } + return *c.messageBody } // ParentID returns oid of n-th parent (0-based index). diff --git a/modules/git/commit_convert_gogit.go b/modules/git/commit_convert_gogit.go index d7b945ed6b..92ad1d21fd 100644 --- a/modules/git/commit_convert_gogit.go +++ b/modules/git/commit_convert_gogit.go @@ -66,7 +66,7 @@ func convertPGPSignature(c *object.Commit) *CommitSignature { func convertCommit(c *object.Commit) *Commit { return &Commit{ ID: ParseGogitHash(c.Hash), - CommitMessage: c.Message, + CommitMessage: CommitMessage{MessageRaw: c.Message}, Committer: &c.Committer, Author: &c.Author, Signature: convertPGPSignature(c), diff --git a/modules/git/commit_reader.go b/modules/git/commit_reader.go index eb8f4c6322..ce48d6f319 100644 --- a/modules/git/commit_reader.go +++ b/modules/git/commit_reader.go @@ -92,7 +92,7 @@ func CommitFromReader(gitRepo *Repository, objectID ObjectID, reader io.Reader) } } - commit.CommitMessage = messageSB.String() + commit.MessageRaw = messageSB.String() if commit.Signature != nil { commit.Signature.Payload = payloadSB.String() } diff --git a/modules/git/commit_sha256_test.go b/modules/git/commit_sha256_test.go index 0aefb30c95..9fb1539dc9 100644 --- a/modules/git/commit_sha256_test.go +++ b/modules/git/commit_sha256_test.go @@ -95,7 +95,7 @@ signed commit`, commitFromReader.Signature.Payload) commitFromReader2, err := CommitFromReader(gitRepo, sha, strings.NewReader(commitString+"\n\n")) assert.NoError(t, err) - commitFromReader.CommitMessage += "\n\n" + commitFromReader.CommitMessage.MessageRaw += "\n\n" commitFromReader.Signature.Payload += "\n\n" assert.Equal(t, commitFromReader, commitFromReader2) } diff --git a/modules/git/commit_test.go b/modules/git/commit_test.go index de7b7455eb..a7668e4deb 100644 --- a/modules/git/commit_test.go +++ b/modules/git/commit_test.go @@ -91,7 +91,7 @@ empty commit`, commitFromReader.Signature.Payload) commitFromReader2, err := CommitFromReader(gitRepo, sha, strings.NewReader(commitString+"\n\n")) assert.NoError(t, err) - commitFromReader.CommitMessage += "\n\n" + commitFromReader.CommitMessage.MessageRaw += "\n\n" commitFromReader.Signature.Payload += "\n\n" assert.Equal(t, commitFromReader, commitFromReader2) } @@ -154,11 +154,20 @@ ISO-8859-1`, commitFromReader.Signature.Payload) commitFromReader2, err := CommitFromReader(gitRepo, sha, strings.NewReader(commitString+"\n\n")) assert.NoError(t, err) - commitFromReader.CommitMessage += "\n\n" + commitFromReader.CommitMessage.MessageRaw += "\n\n" commitFromReader.Signature.Payload += "\n\n" assert.Equal(t, commitFromReader, commitFromReader2) } +func TestCommitMessageSanitizesInvalidUTF8(t *testing.T) { + commit := &Commit{ + CommitMessage: CommitMessage{MessageRaw: "title \xff\n\n\n\nbody \xff\n\n\n"}, + } + assert.Equal(t, "title ÿ", commit.MessageTitle()) + assert.Equal(t, "body ÿ", commit.MessageBody()) + assert.Equal(t, "title ÿ\n\n\n\nbody ÿ\n\n\n", commit.MessageUTF8()) +} + func TestHasPreviousCommit(t *testing.T) { bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") diff --git a/modules/git/foreachref/parser.go b/modules/git/foreachref/parser.go index 91868076b4..874b3744c3 100644 --- a/modules/git/foreachref/parser.go +++ b/modules/git/foreachref/parser.go @@ -111,8 +111,6 @@ func (p *Parser) parseRef(refBlock string) (map[string]string, error) { len(fields), len(p.format.fieldNames)) } for i, field := range fields { - field = strings.TrimSpace(field) - var fieldKey string var fieldVal string before, after, ok := strings.Cut(field, " ") diff --git a/modules/git/foreachref/parser_test.go b/modules/git/foreachref/parser_test.go index 7a37ced356..fc1c8e7cf6 100644 --- a/modules/git/foreachref/parser_test.go +++ b/modules/git/foreachref/parser_test.go @@ -116,12 +116,12 @@ func TestParser(t *testing.T) { }, { "refname:short": "v0.0.2", - "contents": "Update CI config (#651)", + "contents": "Update CI config (#651)\n\n", "author": "John Doe 1521643174 +0000", }, { "refname:short": "v0.0.3", - "contents": "Fixed code sample for bash completion (#687)", + "contents": "Fixed code sample for bash completion (#687)\n\n", "author": "Foo Baz 1524836750 +0200", }, }, diff --git a/modules/git/pipeline/lfs_nogogit.go b/modules/git/pipeline/lfs_nogogit.go index 9a49dc81a2..b4a4aff4ed 100644 --- a/modules/git/pipeline/lfs_nogogit.go +++ b/modules/git/pipeline/lfs_nogogit.go @@ -10,7 +10,6 @@ import ( "bytes" "io" "sort" - "strings" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git/gitcmd" @@ -97,7 +96,7 @@ func findLFSFileFunc(repo *git.Repository, objectID git.ObjectID, revListReader result := LFSResult{ Name: curPath + fname, SHA: curCommit.ID.String(), - Summary: strings.Split(strings.TrimSpace(curCommit.CommitMessage), "\n")[0], + Summary: curCommit.MessageTitle(), When: curCommit.Author.When, ParentHashes: curCommit.Parents, } diff --git a/modules/git/repo_commit_test.go b/modules/git/repo_commit_test.go index 3f7883ab14..ea56a1375d 100644 --- a/modules/git/repo_commit_test.go +++ b/modules/git/repo_commit_test.go @@ -54,7 +54,7 @@ func TestGetTagCommitWithSignature(t *testing.T) { assert.NotNil(t, commit) assert.NotNil(t, commit.Signature) // test that signature is not in message - assert.Equal(t, "signed-commit\n", commit.CommitMessage) + assert.Equal(t, "signed-commit\n", commit.CommitMessage.MessageRaw) } func TestGetCommitWithBadCommitID(t *testing.T) { diff --git a/modules/git/repo_tag.go b/modules/git/repo_tag.go index 2599236ae0..862b370890 100644 --- a/modules/git/repo_tag.go +++ b/modules/git/repo_tag.go @@ -176,15 +176,14 @@ func parseTagRef(ref map[string]string) (tag *Tag, err error) { } tag.Tagger = parseSignatureFromCommitLine(ref["creator"]) - tag.Message = ref["contents"] + tag.MessageRaw = ref["contents"] // strip any signature if present in contents field - _, tag.Message, _ = parsePayloadSignature(util.UnsafeStringToBytes(tag.Message), 0) + _, tag.MessageRaw, _ = parsePayloadSignature(util.UnsafeStringToBytes(tag.MessageRaw), 0) // annotated tag with GPG signature if tag.Type == "tag" && ref["contents:signature"] != "" { - payload := fmt.Sprintf("object %s\ntype commit\ntag %s\ntagger %s\n\n%s\n", - tag.Object, tag.Name, ref["creator"], strings.TrimSpace(tag.Message)) + payload := fmt.Sprintf("object %s\ntype commit\ntag %s\ntagger %s\n\n%s", tag.Object, tag.Name, ref["creator"], tag.MessageRaw) tag.Signature = &CommitSignature{ Signature: ref["contents:signature"], Payload: payload, diff --git a/modules/git/repo_tag_gogit.go b/modules/git/repo_tag_gogit.go index 878ab55bf2..a3e25f3899 100644 --- a/modules/git/repo_tag_gogit.go +++ b/modules/git/repo_tag_gogit.go @@ -64,12 +64,12 @@ func (repo *Repository) getTag(tagID ObjectID, name string) (*Tag, error) { return nil, err } tag := &Tag{ - Name: name, - ID: tagID, - Object: commitID, - Type: tp, - Tagger: commit.Committer, - Message: commit.Message(), + Name: name, + ID: tagID, + Object: commitID, + Type: tp, + Tagger: commit.Committer, + CommitMessage: CommitMessage{MessageRaw: commit.CommitMessage.MessageRaw}, } repo.tagCache.Set(tagID.String(), tag) @@ -86,12 +86,12 @@ func (repo *Repository) getTag(tagID ObjectID, name string) (*Tag, error) { } tag := &Tag{ - Name: name, - ID: tagID, - Object: commitID.Type().MustID(gogitTag.Target[:]), - Type: tp, - Tagger: &gogitTag.Tagger, - Message: gogitTag.Message, + Name: name, + ID: tagID, + Object: commitID.Type().MustID(gogitTag.Target[:]), + Type: tp, + Tagger: &gogitTag.Tagger, + CommitMessage: CommitMessage{MessageRaw: gogitTag.Message}, } repo.tagCache.Set(tagID.String(), tag) diff --git a/modules/git/repo_tag_nogogit.go b/modules/git/repo_tag_nogogit.go index a9ac040821..053c633662 100644 --- a/modules/git/repo_tag_nogogit.go +++ b/modules/git/repo_tag_nogogit.go @@ -71,12 +71,12 @@ func (repo *Repository) getTag(tagID ObjectID, name string) (*Tag, error) { return nil, err } tag := &Tag{ - Name: name, - ID: tagID, - Object: commitID, - Type: tp, - Tagger: commit.Committer, - Message: commit.Message(), + Name: name, + ID: tagID, + Object: commitID, + Type: tp, + Tagger: commit.Committer, + CommitMessage: commit.CommitMessage, } repo.tagCache.Set(tagID.String(), tag) diff --git a/modules/git/repo_tag_test.go b/modules/git/repo_tag_test.go index e6f8e75a0e..50c6ab5036 100644 --- a/modules/git/repo_tag_test.go +++ b/modules/git/repo_tag_test.go @@ -211,13 +211,13 @@ func TestRepository_parseTagRef(t *testing.T) { }, want: &Tag{ - Name: "v1.9.1", - ID: MustIDFromString("ab23e4b7f4cd0caafe0174c0e7ef6d651ba72889"), - Object: MustIDFromString("ab23e4b7f4cd0caafe0174c0e7ef6d651ba72889"), - Type: "commit", - Tagger: parseSignatureFromCommitLine("Foo Bar 1565789218 +0300"), - Message: "Add changelog of v1.9.1 (#7859)\n\n* add changelog of v1.9.1\n* Update CHANGELOG.md\n", - Signature: nil, + Name: "v1.9.1", + ID: MustIDFromString("ab23e4b7f4cd0caafe0174c0e7ef6d651ba72889"), + Object: MustIDFromString("ab23e4b7f4cd0caafe0174c0e7ef6d651ba72889"), + Type: "commit", + Tagger: parseSignatureFromCommitLine("Foo Bar 1565789218 +0300"), + CommitMessage: CommitMessage{MessageRaw: "Add changelog of v1.9.1 (#7859)\n\n* add changelog of v1.9.1\n* Update CHANGELOG.md\n"}, + Signature: nil, }, }, @@ -240,13 +240,13 @@ func TestRepository_parseTagRef(t *testing.T) { }, want: &Tag{ - Name: "v0.0.1", - ID: MustIDFromString("8c68a1f06fc59c655b7e3905b159d761e91c53c9"), - Object: MustIDFromString("3325fd8a973321fd59455492976c042dde3fd1ca"), - Type: "tag", - Tagger: parseSignatureFromCommitLine("Foo Bar 1565789218 +0300"), - Message: "Add changelog of v1.9.1 (#7859)\n\n* add changelog of v1.9.1\n* Update CHANGELOG.md\n", - Signature: nil, + Name: "v0.0.1", + ID: MustIDFromString("8c68a1f06fc59c655b7e3905b159d761e91c53c9"), + Object: MustIDFromString("3325fd8a973321fd59455492976c042dde3fd1ca"), + Type: "tag", + Tagger: parseSignatureFromCommitLine("Foo Bar 1565789218 +0300"), + CommitMessage: CommitMessage{MessageRaw: "Add changelog of v1.9.1 (#7859)\n\n* add changelog of v1.9.1\n* Update CHANGELOG.md\n"}, + Signature: nil, }, }, @@ -263,6 +263,7 @@ func TestRepository_parseTagRef(t *testing.T) { * add changelog of v1.9.1 * Update CHANGELOG.md + -----BEGIN PGP SIGNATURE----- aBCGzBAABCgAdFiEEyWRwv/q1Q6IjSv+D4IPOwzt33PoFAmI8jbIACgkQ4IPOwzt3 @@ -298,12 +299,12 @@ qbHDASXl }, want: &Tag{ - Name: "v0.0.1", - ID: MustIDFromString("8c68a1f06fc59c655b7e3905b159d761e91c53c9"), - Object: MustIDFromString("3325fd8a973321fd59455492976c042dde3fd1ca"), - Type: "tag", - Tagger: parseSignatureFromCommitLine("Foo Bar 1565789218 +0300"), - Message: "Add changelog of v1.9.1 (#7859)\n\n* add changelog of v1.9.1\n* Update CHANGELOG.md", + Name: "v0.0.1", + ID: MustIDFromString("8c68a1f06fc59c655b7e3905b159d761e91c53c9"), + Object: MustIDFromString("3325fd8a973321fd59455492976c042dde3fd1ca"), + Type: "tag", + Tagger: parseSignatureFromCommitLine("Foo Bar 1565789218 +0300"), + CommitMessage: CommitMessage{MessageRaw: "Add changelog of v1.9.1 (#7859)\n\n* add changelog of v1.9.1\n* Update CHANGELOG.md\n"}, Signature: &CommitSignature{ Signature: `-----BEGIN PGP SIGNATURE----- diff --git a/modules/git/tag.go b/modules/git/tag.go index 8bf3658d62..232dda7fd9 100644 --- a/modules/git/tag.go +++ b/modules/git/tag.go @@ -12,12 +12,13 @@ import ( // Tag represents a Git tag. type Tag struct { + CommitMessage + Name string ID ObjectID Object ObjectID // The id of this commit object Type string Tagger *Signature - Message string Signature *CommitSignature } @@ -87,7 +88,7 @@ func parseTagData(objectFormat ObjectFormat, data []byte) (*Tag, error) { pos += eol + 1 } payload, msg, sign := parsePayloadSignature(data, pos) - tag.Message = msg + tag.MessageRaw = msg if len(sign) > 0 { tag.Signature = &CommitSignature{Signature: sign, Payload: payload} } diff --git a/modules/git/tag_test.go b/modules/git/tag_test.go index ba02c28946..6a65e359a2 100644 --- a/modules/git/tag_test.go +++ b/modules/git/tag_test.go @@ -28,7 +28,6 @@ tagger Lucas Michot 1484491741 +0100 Object: MustIDFromString("3b114ab800c6432ad42387ccf6bc8d4388a2885a"), Type: "commit", Tagger: &Signature{Name: "Lucas Michot", Email: "lucas@semalead.com", When: time.Unix(1484491741, 0).In(time.FixedZone("", 3600))}, - Message: "", Signature: nil, }, }, @@ -43,13 +42,13 @@ o ono`, expected: Tag{ - Name: "", - ID: Sha1ObjectFormat.EmptyObjectID(), - Object: MustIDFromString("7cdf42c0b1cc763ab7e4c33c47a24e27c66bfccc"), - Type: "commit", - Tagger: &Signature{Name: "Lucas Michot", Email: "lucas@semalead.com", When: time.Unix(1484553735, 0).In(time.FixedZone("", 3600))}, - Message: "test message\no\n\nono", - Signature: nil, + Name: "", + ID: Sha1ObjectFormat.EmptyObjectID(), + Object: MustIDFromString("7cdf42c0b1cc763ab7e4c33c47a24e27c66bfccc"), + Type: "commit", + Tagger: &Signature{Name: "Lucas Michot", Email: "lucas@semalead.com", When: time.Unix(1484553735, 0).In(time.FixedZone("", 3600))}, + CommitMessage: CommitMessage{MessageRaw: "test message\no\n\nono"}, + Signature: nil, }, }, { @@ -64,12 +63,12 @@ dummy signature -----END SSH SIGNATURE----- `, expected: Tag{ - Name: "", - ID: Sha1ObjectFormat.EmptyObjectID(), - Object: MustIDFromString("7cdf42c0b1cc763ab7e4c33c47a24e27c66bfaaa"), - Type: "commit", - Tagger: &Signature{Name: "dummy user", Email: "dummy-email@example.com", When: time.Unix(1484491741, 0).In(time.FixedZone("", 3600))}, - Message: "dummy message", + Name: "", + ID: Sha1ObjectFormat.EmptyObjectID(), + Object: MustIDFromString("7cdf42c0b1cc763ab7e4c33c47a24e27c66bfaaa"), + Type: "commit", + Tagger: &Signature{Name: "dummy user", Email: "dummy-email@example.com", When: time.Unix(1484491741, 0).In(time.FixedZone("", 3600))}, + CommitMessage: CommitMessage{MessageRaw: "dummy message"}, Signature: &CommitSignature{ Signature: `-----BEGIN SSH SIGNATURE----- dummy signature @@ -93,5 +92,5 @@ dummy message`, tag, err := parseTagData(Sha1ObjectFormat, []byte("type commit\n\nfoo\n-----BEGIN SSH SIGNATURE-----\ncorrupted...")) assert.NoError(t, err) - assert.Equal(t, "foo\n-----BEGIN SSH SIGNATURE-----\ncorrupted...", tag.Message) + assert.Equal(t, "foo\n-----BEGIN SSH SIGNATURE-----\ncorrupted...", tag.CommitMessage.MessageRaw) } diff --git a/modules/repository/branch.go b/modules/repository/branch.go index 0a8f7cc464..8dda3f82d7 100644 --- a/modules/repository/branch.go +++ b/modules/repository/branch.go @@ -97,7 +97,7 @@ func SyncRepoBranchesWithRepo(ctx context.Context, repo *repo_model.Repository, RepoID: repo.ID, Name: branch, CommitID: commit.ID.String(), - CommitMessage: commit.Summary(), + CommitMessage: commit.MessageTitle(), PusherID: doerID, CommitTime: timeutil.TimeStamp(commit.Committer.When.Unix()), }) @@ -112,7 +112,7 @@ func SyncRepoBranchesWithRepo(ctx context.Context, repo *repo_model.Repository, RepoID: repo.ID, Name: branch, CommitID: commit.ID.String(), - CommitMessage: commit.Summary(), + CommitMessage: commit.MessageTitle(), PusherID: doerID, CommitTime: timeutil.TimeStamp(commit.Committer.When.Unix()), }) diff --git a/modules/repository/commits.go b/modules/repository/commits.go index a3e253e998..32550a9f03 100644 --- a/modules/repository/commits.go +++ b/modules/repository/commits.go @@ -152,7 +152,7 @@ func (pc *PushCommits) AvatarLink(ctx context.Context, email string) string { func CommitToPushCommit(commit *git.Commit) *PushCommit { return &PushCommit{ Sha1: commit.ID.String(), - Message: commit.Message(), + Message: commit.MessageUTF8(), AuthorEmail: commit.Author.Email, AuthorName: commit.Author.Name, CommitterEmail: commit.Committer.Email, diff --git a/modules/repository/commits_test.go b/modules/repository/commits_test.go index 04c0711828..46db7b028b 100644 --- a/modules/repository/commits_test.go +++ b/modules/repository/commits_test.go @@ -145,7 +145,7 @@ func TestCommitToPushCommit(t *testing.T) { ID: sha1, Author: sig, Committer: sig, - CommitMessage: "Commit Message", + CommitMessage: git.CommitMessage{MessageRaw: "Commit Message"}, }) assert.Equal(t, hexString, pushCommit.Sha1) assert.Equal(t, "Commit Message", pushCommit.Message) @@ -176,13 +176,13 @@ func TestListToPushCommits(t *testing.T) { ID: hash1, Author: sig, Committer: sig, - CommitMessage: "Message1", + CommitMessage: git.CommitMessage{MessageRaw: "Message1"}, }, { ID: hash2, Author: sig, Committer: sig, - CommitMessage: "Message2", + CommitMessage: git.CommitMessage{MessageRaw: "Message2"}, }, } diff --git a/modules/templates/helper.go b/modules/templates/helper.go index 4cd6269eaf..aebbfc7407 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -132,10 +132,9 @@ func newFuncMapWebPage() template.FuncMap { // ----------------------------------------------------------------- // misc (TODO: move them to MiscUtils to avoid bloating the main func map) - "ActionContent2Commits": ActionContent2Commits, - "IsMultilineCommitMessage": isMultilineCommitMessage, - "CommentMustAsDiff": gitdiff.CommentMustAsDiff, - "MirrorRemoteAddress": mirrorRemoteAddress, + "ActionContent2Commits": ActionContent2Commits, + "CommentMustAsDiff": gitdiff.CommentMustAsDiff, + "MirrorRemoteAddress": mirrorRemoteAddress, "FilenameIsImage": filenameIsImage, "TabSizeClass": tabSizeClass, diff --git a/modules/templates/util_misc.go b/modules/templates/util_misc.go index fb523fd53a..ac179e7178 100644 --- a/modules/templates/util_misc.go +++ b/modules/templates/util_misc.go @@ -52,11 +52,6 @@ func sortArrow(normSort, revSort, urlSort string, isDefault bool) template.HTML return "" } -// isMultilineCommitMessage checks to see if a commit message contains multiple lines. -func isMultilineCommitMessage(msg string) bool { - return strings.Count(strings.TrimSpace(msg), "\n") >= 1 -} - // Actioner describes an action type Actioner interface { GetOpType() activities_model.ActionType diff --git a/modules/templates/util_render.go b/modules/templates/util_render.go index 6641ee7959..da186f87f2 100644 --- a/modules/templates/util_render.go +++ b/modules/templates/util_render.go @@ -79,20 +79,14 @@ func (ut *RenderUtils) RenderCommitMessageLinkSubject(msg, urlDefault string, re // RenderCommitBody extracts the body of a commit message without its title. func (ut *RenderUtils) RenderCommitBody(msg string, repo *repo.Repository) template.HTML { - msgLine := strings.TrimSpace(msg) - lineEnd := strings.IndexByte(msgLine, '\n') - if lineEnd > 0 { - msgLine = msgLine[lineEnd+1:] - } else { - return "" - } - msgLine = strings.TrimLeftFunc(msgLine, unicode.IsSpace) - if len(msgLine) == 0 { + _, body, _ := strings.Cut(strings.TrimSpace(msg), "\n") + body = strings.TrimFunc(body, unicode.IsSpace) + if body == "" { return "" } rctx := renderhelper.NewRenderContextRepoComment(ut.ctx, repo) - htmlContent := template.HTML(template.HTMLEscapeString(msgLine)) + htmlContent := template.HTML(template.HTMLEscapeString(body)) renderedMessage, err := markup.PostProcessCommitMessage(rctx, htmlContent) if err != nil { log.Error("PostProcessCommitMessage: %v", err) diff --git a/routers/web/feed/branch.go b/routers/web/feed/branch.go index eb7f6dc5bc..5818f509fe 100644 --- a/routers/web/feed/branch.go +++ b/routers/web/feed/branch.go @@ -4,7 +4,6 @@ package feed import ( - "strings" "time" "code.gitea.io/gitea/models/repo" @@ -39,14 +38,14 @@ func ShowBranchFeed(ctx *context.Context, repo *repo.Repository, formatType stri for _, commit := range commits { feed.Items = append(feed.Items, &feeds.Item{ Id: commit.ID.String(), - Title: strings.TrimSpace(strings.Split(commit.Message(), "\n")[0]), + Title: commit.MessageTitle(), Link: &feeds.Link{Href: repo.HTMLURL() + "/commit/" + commit.ID.String()}, Author: &feeds.Author{ Name: commit.Author.Name, Email: commit.Author.Email, }, - Description: commit.Message(), - Content: commit.Message(), + Description: commit.MessageUTF8(), // TODO: description can be shorten content + Content: commit.MessageUTF8(), Created: commit.Committer.When, }) } diff --git a/routers/web/feed/file.go b/routers/web/feed/file.go index 026c15c43a..2888f4e61f 100644 --- a/routers/web/feed/file.go +++ b/routers/web/feed/file.go @@ -4,7 +4,6 @@ package feed import ( - "strings" "time" "code.gitea.io/gitea/models/repo" @@ -46,14 +45,14 @@ func ShowFileFeed(ctx *context.Context, repo *repo.Repository, formatType string for _, commit := range commits { feed.Items = append(feed.Items, &feeds.Item{ Id: commit.ID.String(), - Title: strings.TrimSpace(strings.Split(commit.Message(), "\n")[0]), + Title: commit.MessageTitle(), Link: &feeds.Link{Href: repo.HTMLURL() + "/commit/" + commit.ID.String()}, Author: &feeds.Author{ Name: commit.Author.Name, Email: commit.Author.Email, }, - Description: commit.Message(), - Content: commit.Message(), + Description: commit.MessageUTF8(), // TODO: description can be shorten content + Content: commit.MessageUTF8(), Created: commit.Committer.When, }) } diff --git a/routers/web/repo/blame.go b/routers/web/repo/blame.go index 4fb61bee6d..803397f33f 100644 --- a/routers/web/repo/blame.go +++ b/routers/web/repo/blame.go @@ -231,7 +231,7 @@ func renderBlameFillFirstBlameRow(repoLink string, avatarUtils *templates.Avatar br.PreviousSha = part.PreviousSha br.PreviousShaURL = fmt.Sprintf("%s/blame/commit/%s/%s", repoLink, url.PathEscape(part.PreviousSha), util.PathEscapeSegments(part.PreviousPath)) br.CommitURL = fmt.Sprintf("%s/commit/%s", repoLink, url.PathEscape(part.Sha)) - br.CommitMessage = commit.CommitMessage + br.CommitMessage = commit.MessageUTF8() br.CommitSince = templates.TimeSince(commit.Author.When) } diff --git a/routers/web/repo/commit.go b/routers/web/repo/commit.go index 84b51bba5f..6c973696ff 100644 --- a/routers/web/repo/commit.go +++ b/routers/web/repo/commit.go @@ -349,7 +349,7 @@ func Diff(ctx *context.Context) { parentCommitID = parentCommit.ID.String() } setCompareContext(ctx, parentCommit, commit, userName, repoName) - ctx.Data["Title"] = commit.Summary() + " · " + base.ShortSha(commitID) + ctx.Data["Title"] = commit.MessageTitle() + " · " + base.ShortSha(commitID) ctx.Data["Commit"] = commit ctx.Data["Diff"] = diff ctx.Data["DiffBlobExcerptData"] = diffBlobExcerptData diff --git a/routers/web/repo/compare.go b/routers/web/repo/compare.go index 2797b0b26d..46867e80bb 100644 --- a/routers/web/repo/compare.go +++ b/routers/web/repo/compare.go @@ -391,17 +391,14 @@ func prepareNewPullRequestTitleContent(ci *git_service.CompareInfo, commits []*g if useFirstCommitAsTitle { // the "commits" are from "ShowPrettyFormatLogToList", which is ordered from newest to oldest, here take the oldest one c := commits[len(commits)-1] - title = strings.TrimSpace(c.UserCommit.Summary()) + title = c.UserCommit.MessageTitle() } else { title = autoTitleFromBranchName(ci.HeadRef.ShortName()) } if len(commits) == 1 { - // FIXME: GIT-COMMIT-MESSAGE-ENCODING: try to convert the encoding for commit message explicitly, ideally it should be done by a git commit struct method c := commits[0] - _, content, _ = strings.Cut(strings.TrimSpace(c.UserCommit.CommitMessage), "\n") - content = strings.TrimSpace(content) - content = string(charset.ToUTF8([]byte(content), charset.ConvertOpts{})) + content = c.MessageBody() } var titleTrailer string diff --git a/routers/web/repo/compare_test.go b/routers/web/repo/compare_test.go index 63b0f287e5..da5b2c84b3 100644 --- a/routers/web/repo/compare_test.go +++ b/routers/web/repo/compare_test.go @@ -6,7 +6,6 @@ package repo import ( "strings" "testing" - "unicode/utf8" asymkey_model "code.gitea.io/gitea/models/asymkey" git_model "code.gitea.io/gitea/models/git" @@ -55,7 +54,7 @@ func TestNewPullRequestTitleContent(t *testing.T) { SignCommit: &asymkey_model.SignCommit{ UserCommit: &user_model.UserCommit{ Commit: &git.Commit{ - CommitMessage: msg, + CommitMessage: git.CommitMessage{MessageRaw: msg}, }, }, }, @@ -99,9 +98,9 @@ func TestNewPullRequestTitleContent(t *testing.T) { assert.Equal(t, "title-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa…", title) assert.Equal(t, "…aaaaaaaaa\n", content) - title, content = prepareNewPullRequestTitleContent(ci, []*git_model.SignCommitWithStatuses{mockCommit("a\xf0\xf0\xf0\nb\xf0\xf0\xf0")}, setting.RepoPRTitleSourceFirstCommit) - assert.Equal(t, "a?", title) // FIXME: GIT-COMMIT-MESSAGE-ENCODING: "title" doesn't use the same charset converting logic as "content" - assert.Equal(t, "b"+string(utf8.RuneError)+string(utf8.RuneError), content) + title, content = prepareNewPullRequestTitleContent(ci, []*git_model.SignCommitWithStatuses{mockCommit("title \xf0\nbody \xf0")}, setting.RepoPRTitleSourceFirstCommit) + assert.Equal(t, "title ð", title) + assert.Equal(t, "body ð", content) } func TestAutoTitleFromBranchName(t *testing.T) { diff --git a/routers/web/repo/editor_cherry_pick.go b/routers/web/repo/editor_cherry_pick.go index 605a35b100..f3cbc09827 100644 --- a/routers/web/repo/editor_cherry_pick.go +++ b/routers/web/repo/editor_cherry_pick.go @@ -6,7 +6,6 @@ package repo import ( "bytes" "net/http" - "strings" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo" @@ -33,10 +32,10 @@ func CherryPick(ctx *context.Context) { if ctx.FormString("cherry-pick-type") == "revert" { ctx.Data["CherryPickType"] = "revert" ctx.Data["commit_summary"] = "revert " + ctx.PathParam("sha") - ctx.Data["commit_message"] = "revert " + cherryPickCommit.Message() + ctx.Data["commit_message"] = "revert " + cherryPickCommit.MessageUTF8() } else { ctx.Data["CherryPickType"] = "cherry-pick" - ctx.Data["commit_summary"], ctx.Data["commit_message"], _ = strings.Cut(cherryPickCommit.Message(), "\n") + ctx.Data["commit_summary"], ctx.Data["commit_message"] = cherryPickCommit.MessageTitle(), cherryPickCommit.MessageBody() } ctx.HTML(http.StatusOK, tplCherryPick) diff --git a/routers/web/repo/setting/webhook.go b/routers/web/repo/setting/webhook.go index 8c57a68b25..a7c0b863cc 100644 --- a/routers/web/repo/setting/webhook.go +++ b/routers/web/repo/setting/webhook.go @@ -675,7 +675,7 @@ func TestWebhook(ctx *context.Context) { ID: objectFormat.EmptyObjectID(), Author: ghost.NewGitSig(), Committer: ghost.NewGitSig(), - CommitMessage: "This is a fake commit", + CommitMessage: git.CommitMessage{MessageRaw: "This is a fake commit"}, } } @@ -683,7 +683,7 @@ func TestWebhook(ctx *context.Context) { apiCommit := &api.PayloadCommit{ ID: commit.ID.String(), - Message: commit.Message(), + Message: commit.MessageUTF8(), URL: ctx.Repo.Repository.HTMLURL() + "/commit/" + url.PathEscape(commit.ID.String()), Author: &api.PayloadUser{ Name: commit.Author.Name, diff --git a/services/actions/notifier_helper.go b/services/actions/notifier_helper.go index 3021f5bd0e..05f7f918df 100644 --- a/services/actions/notifier_helper.go +++ b/services/actions/notifier_helper.go @@ -256,7 +256,7 @@ func skipWorkflows(ctx context.Context, input *notifyInput, commit *git.Commit) log.Debug("repo %s: skipped run for pr %v because of %s string", input.Repo.RelativePath(), input.PullRequest.Issue.ID, s) return true } - if strings.Contains(commit.CommitMessage, s) { + if strings.Contains(commit.MessageRaw, s) { log.Debug("repo %s with commit %s: skipped run because of %s string", input.Repo.RelativePath(), commit.ID, s) return true } @@ -320,7 +320,7 @@ func handleWorkflows( for _, dwf := range detectedWorkflows { run := &actions_model.ActionRun{ - Title: strings.SplitN(commit.CommitMessage, "\n", 2)[0], + Title: commit.MessageTitle(), RepoID: input.Repo.ID, Repo: input.Repo, OwnerID: input.Repo.OwnerID, @@ -483,7 +483,7 @@ func handleSchedules( } run := &actions_model.ActionSchedule{ - Title: strings.SplitN(commit.CommitMessage, "\n", 2)[0], + Title: commit.MessageTitle(), RepoID: input.Repo.ID, Repo: input.Repo, OwnerID: input.Repo.OwnerID, diff --git a/services/actions/workflow.go b/services/actions/workflow.go index 44dad71c4a..e60ae1ec2e 100644 --- a/services/actions/workflow.go +++ b/services/actions/workflow.go @@ -5,7 +5,6 @@ package actions import ( "fmt" - "strings" actions_model "code.gitea.io/gitea/models/actions" "code.gitea.io/gitea/models/perm" @@ -98,7 +97,7 @@ func DispatchActionWorkflow(ctx reqctx.RequestContext, doer *user_model.User, re var entry *git.TreeEntry run := &actions_model.ActionRun{ - Title: strings.SplitN(runTargetCommit.CommitMessage, "\n", 2)[0], + Title: runTargetCommit.MessageTitle(), RepoID: repo.ID, Repo: repo, OwnerID: repo.OwnerID, diff --git a/services/agit/agit.go b/services/agit/agit.go index 55b98a65ae..c7c46651c0 100644 --- a/services/agit/agit.go +++ b/services/agit/agit.go @@ -150,17 +150,13 @@ func ProcReceive(ctx context.Context, repo *repo_model.Repository, gitRepo *git. if err != nil { return nil, fmt.Errorf("failed to get commit %s in repository: %s Error: %w", opts.NewCommitIDs[i], repo.FullName(), err) } - } - - // create a new pull request - if title == "" { - title = strings.Split(commit.CommitMessage, "\n")[0] - } - if description == "" { - _, description, _ = strings.Cut(commit.CommitMessage, "\n\n") - } - if description == "" { - description = title + // create a new pull request + if title == "" { + title = commit.MessageTitle() + } + if description == "" { + description = commit.MessageBody() + } } prIssue := &issues_model.Issue{ diff --git a/services/convert/convert.go b/services/convert/convert.go index dc1692b6ca..21fd1cadb4 100644 --- a/services/convert/convert.go +++ b/services/convert/convert.go @@ -11,7 +11,6 @@ import ( "net/url" "path" "strconv" - "strings" "time" actions_model "code.gitea.io/gitea/models/actions" @@ -215,7 +214,7 @@ func ToTag(repo *repo_model.Repository, t *git.Tag) *api.Tag { return &api.Tag{ Name: t.Name, - Message: strings.TrimSpace(t.Message), + Message: t.MessageUTF8(), ID: t.ID.String(), Commit: ToCommitMeta(repo, t), ZipballURL: zipballURL, @@ -769,7 +768,7 @@ func ToAnnotatedTag(ctx context.Context, repo *repo_model.Repository, t *git.Tag Tag: t.Name, SHA: t.ID.String(), Object: ToAnnotatedTagObject(repo, c), - Message: t.Message, + Message: t.MessageUTF8(), URL: repo.APIURL() + "/git/tags/" + t.ID.String(), Tagger: ToCommitUser(t.Tagger), Verification: ToVerification(ctx, c), diff --git a/services/convert/git_commit.go b/services/convert/git_commit.go index d809e3778d..9daad1843e 100644 --- a/services/convert/git_commit.go +++ b/services/convert/git_commit.go @@ -56,7 +56,7 @@ func ToPayloadCommit(ctx context.Context, repo *repo_model.Repository, c *git.Co return &api.PayloadCommit{ ID: c.ID.String(), - Message: c.Message(), + Message: c.MessageUTF8(), URL: repo.HTMLURL() + "/commit/" + c.ID.String(), Author: &api.PayloadUser{ Name: c.Author.Name, @@ -171,7 +171,7 @@ func ToCommit(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Rep }, Date: commit.Committer.When.Format(time.RFC3339), }, - Message: commit.Message(), + Message: commit.MessageUTF8(), Tree: &api.CommitMeta{ URL: repo.APIURL() + "/git/trees/" + url.PathEscape(commit.ID.String()), SHA: commit.ID.String(), diff --git a/services/convert/git_commit_test.go b/services/convert/git_commit_test.go index 66a427fadf..4aa1e6cac0 100644 --- a/services/convert/git_commit_test.go +++ b/services/convert/git_commit_test.go @@ -21,12 +21,12 @@ func TestToCommitMeta(t *testing.T) { sha1 := git.Sha1ObjectFormat signature := &git.Signature{Name: "Test Signature", Email: "test@email.com", When: time.Unix(0, 0)} tag := &git.Tag{ - Name: "Test Tag", - ID: sha1.EmptyObjectID(), - Object: sha1.EmptyObjectID(), - Type: "Test Type", - Tagger: signature, - Message: "Test Message", + Name: "Test Tag", + ID: sha1.EmptyObjectID(), + Object: sha1.EmptyObjectID(), + Type: "Test Type", + Tagger: signature, + CommitMessage: git.CommitMessage{MessageRaw: "Test Message"}, } commitMeta := ToCommitMeta(headRepo, tag) diff --git a/services/convert/wiki.go b/services/convert/wiki.go index 767bfdb88d..b82b8c31e7 100644 --- a/services/convert/wiki.go +++ b/services/convert/wiki.go @@ -28,7 +28,7 @@ func ToWikiCommit(commit *git.Commit) *api.WikiCommit { }, Date: commit.Committer.When.UTC().Format(time.RFC3339), }, - Message: commit.CommitMessage, + Message: commit.MessageUTF8(), } } diff --git a/services/pull/pull.go b/services/pull/pull.go index b852dc2ed1..3524b4d9bf 100644 --- a/services/pull/pull.go +++ b/services/pull/pull.go @@ -847,7 +847,7 @@ func GetSquashMergeCommitMessages(ctx context.Context, pr *issues_model.PullRequ maxMsgSize := setting.Repository.PullRequest.DefaultMergeMessageSize for i := len(commits) - 1; i >= 0; i-- { commit := commits[i] - msg := strings.TrimSpace(commit.CommitMessage) + msg := strings.TrimSpace(commit.MessageUTF8()) if msg == "" { continue } @@ -1074,7 +1074,7 @@ func GetPullCommits(ctx context.Context, baseGitRepo *git.Repository, doer *user } commits = append(commits, CommitInfo{ - Summary: commit.Summary(), + Summary: commit.MessageTitle(), CommitterOrAuthorName: committerOrAuthorName, ID: commit.ID.String(), ShortSha: base.ShortSha(commit.ID.String()), diff --git a/services/repository/branch.go b/services/repository/branch.go index dc17e4f2fe..a0572f59c5 100644 --- a/services/repository/branch.go +++ b/services/repository/branch.go @@ -359,7 +359,7 @@ func SyncBranchesToDB(ctx context.Context, repoID, pusherID int64, branchNames, RepoID: repoID, Name: branchName, CommitID: commit.ID.String(), - CommitMessage: commit.Summary(), + CommitMessage: commit.MessageTitle(), PusherID: pusherID, CommitTime: timeutil.TimeStamp(commit.Committer.When.Unix()), }) diff --git a/services/repository/files/content.go b/services/repository/files/content.go index 9b042f9e67..519785ff72 100644 --- a/services/repository/files/content.go +++ b/services/repository/files/content.go @@ -179,7 +179,7 @@ func getFileContentsByEntryInternal(ctx context.Context, repo *repo_model.Reposi } } if opts.IncludeCommitMessage { - contentsResponse.LastCommitMessage = new(lastCommit.Message()) + contentsResponse.LastCommitMessage = new(lastCommit.MessageUTF8()) } } diff --git a/services/repository/files/file.go b/services/repository/files/file.go index f48e32b427..41302b2637 100644 --- a/services/repository/files/file.go +++ b/services/repository/files/file.go @@ -110,7 +110,7 @@ func GetFileCommitResponse(repo *repo_model.Repository, commit *git.Commit) (*ap }, Date: commit.Committer.When.UTC().Format(time.RFC3339), }, - Message: commit.Message(), + Message: commit.MessageUTF8(), Tree: &api.CommitMeta{ URL: commitTreeURL.String(), SHA: commit.Tree.ID.String(), diff --git a/services/repository/push.go b/services/repository/push.go index 7c68a7f176..3c9a070746 100644 --- a/services/repository/push.go +++ b/services/repository/push.go @@ -402,7 +402,7 @@ func pushUpdateAddTags(ctx context.Context, repo *repo_model.Repository, gitRepo } rel, has := relMap[lowerTag] - title, note := git.SplitCommitTitleBody(tag.Message, 255) + title, note := git.SplitCommitTitleBody(tag.MessageUTF8(), 255) if !has { rel = &repo_model.Release{ RepoID: repo.ID, diff --git a/templates/base/head_opengraph.tmpl b/templates/base/head_opengraph.tmpl index 93624ea4b0..3de262f59f 100644 --- a/templates/base/head_opengraph.tmpl +++ b/templates/base/head_opengraph.tmpl @@ -18,8 +18,7 @@ {{if and .PageIsDiff .Commit}} - {{- $commitMessageParts := StringUtils.Cut .Commit.Message "\n" -}} - {{- $commitMessageBody := index $commitMessageParts 1 -}} + {{- $commitMessageBody := .Commit.MessageBody -}} {{- if $commitMessageBody -}} {{- end -}} diff --git a/templates/mail/repo/issue/default.tmpl b/templates/mail/repo/issue/default.tmpl index 6e70cb83cd..44cdc563ad 100644 --- a/templates/mail/repo/issue/default.tmpl +++ b/templates/mail/repo/issue/default.tmpl @@ -65,11 +65,12 @@ {{end -}} {{if eq .ActionName "push"}} diff --git a/templates/repo/commit_page.tmpl b/templates/repo/commit_page.tmpl index 8451a6f3cf..975cd303ec 100644 --- a/templates/repo/commit_page.tmpl +++ b/templates/repo/commit_page.tmpl @@ -5,7 +5,7 @@
-

{{ctx.RenderUtils.RenderCommitMessage .Commit.Message $.Repository}}{{template "repo/commit_statuses" dict "Status" .CommitStatus "Statuses" .CommitStatuses "AdditionalClasses" "tw-inline"}}

+

{{ctx.RenderUtils.RenderCommitMessage .Commit.MessageUTF8 $.Repository}}{{template "repo/commit_statuses" dict "Status" .CommitStatus "Statuses" .CommitStatuses "AdditionalClasses" "tw-inline"}}

{{if not $.PageIsWiki}} {{end}}
- {{if IsMultilineCommitMessage .Commit.Message}} -
{{ctx.RenderUtils.RenderCommitBody .Commit.Message $.Repository}}
+ {{if .Commit.MessageBody}} +
{{ctx.RenderUtils.RenderCommitBody .Commit.MessageUTF8 $.Repository}}
{{end}} {{template "repo/commit_load_branches_and_tags" .}}
diff --git a/templates/repo/commits_list.tmpl b/templates/repo/commits_list.tmpl index d520c0fbcf..e79d189b8d 100644 --- a/templates/repo/commits_list.tmpl +++ b/templates/repo/commits_list.tmpl @@ -11,7 +11,7 @@ {{$commitRepoLink := $.RepoLink}}{{if $.CommitRepoLink}}{{$commitRepoLink = $.CommitRepoLink}}{{end}} - {{range .Commits}} + {{range $commit := .Commits}} @@ -38,18 +38,22 @@ {{if $.PageIsWiki}} - {{.Summary | ctx.RenderUtils.RenderEmoji}} + + {{$commit.MessageTitle | ctx.RenderUtils.RenderEmoji}} + {{else}} - {{$commitLink:= printf "%s/commit/%s" $commitRepoLink (PathEscape .ID.String)}} - {{ctx.RenderUtils.RenderCommitMessageLinkSubject .Message $commitLink $.Repository}} + {{$commitLink:= printf "%s/commit/%s" $commitRepoLink (PathEscape $commit.ID.String)}} + + {{ctx.RenderUtils.RenderCommitMessageLinkSubject $commit.MessageUTF8 $commitLink $.Repository}} + {{end}} - {{if IsMultilineCommitMessage .Message}} + {{if $commit.MessageBody}} {{end}} {{template "repo/commit_statuses" dict "Status" .Status "Statuses" .Statuses}} - {{if IsMultilineCommitMessage .Message}} -
{{ctx.RenderUtils.RenderCommitBody .Message $.Repository}}
+ {{if $commit.MessageBody}} +
{{ctx.RenderUtils.RenderCommitBody $commit.MessageUTF8 $.Repository}}
{{end}} {{if $.CommitsTagsMap}} {{range (index $.CommitsTagsMap .ID.String)}} diff --git a/templates/repo/commits_list_small.tmpl b/templates/repo/commits_list_small.tmpl index 0470d1e9f5..c5f0d5b590 100644 --- a/templates/repo/commits_list_small.tmpl +++ b/templates/repo/commits_list_small.tmpl @@ -1,6 +1,6 @@ {{$index := 0}}
-{{range .comment.Commits}} +{{range $commit := .comment.Commits}} {{$tag := printf "%s-%d" $.comment.HashTag $index}} {{$index = Eval $index "+" 1}}
{{/*singular-commit*/}} @@ -14,11 +14,11 @@ {{$commitBaseLink := printf "%s/commit" $.comment.Issue.PullRequest.BaseRepo.Link}} {{$commitLink:= printf "%s/%s" $commitBaseLink (PathEscape .ID.String)}} - - {{- ctx.RenderUtils.RenderCommitMessageLinkSubject .Message $commitLink $.comment.Issue.PullRequest.BaseRepo -}} + + {{- ctx.RenderUtils.RenderCommitMessageLinkSubject $commit.MessageUTF8 $commitLink $.comment.Issue.PullRequest.BaseRepo -}} - {{if IsMultilineCommitMessage .Message}} + {{if $commit.MessageBody}} {{end}} @@ -27,9 +27,9 @@ {{template "repo/commit_sign_badge" dict "Commit" . "CommitBaseLink" $commitBaseLink "CommitSignVerification" .Verification}}
- {{if IsMultilineCommitMessage .Message}} + {{if $commit.MessageBody}}
-		{{- ctx.RenderUtils.RenderCommitBody .Message $.comment.Issue.PullRequest.BaseRepo -}}
+		{{- ctx.RenderUtils.RenderCommitBody $commit.MessageUTF8 $.comment.Issue.PullRequest.BaseRepo -}}
 	
{{end}} {{end}} diff --git a/templates/repo/latest_commit.tmpl b/templates/repo/latest_commit.tmpl index c8f1ad5492..c0518189b8 100644 --- a/templates/repo/latest_commit.tmpl +++ b/templates/repo/latest_commit.tmpl @@ -17,10 +17,11 @@ {{template "repo/commit_statuses" dict "Status" .LatestCommitStatus "Statuses" .LatestCommitStatuses}} {{$commitLink:= printf "%s/commit/%s" .RepoLink (PathEscape .LatestCommit.ID.String)}} - {{ctx.RenderUtils.RenderCommitMessageLinkSubject .LatestCommit.Message $commitLink $.Repository}} - {{if IsMultilineCommitMessage .LatestCommit.Message}} + + {{ctx.RenderUtils.RenderCommitMessageLinkSubject .LatestCommit.MessageUTF8 $commitLink $.Repository}} + {{if .LatestCommit.MessageBody}} -
{{ctx.RenderUtils.RenderCommitBody .LatestCommit.Message $.Repository}}
+
{{ctx.RenderUtils.RenderCommitBody .LatestCommit.MessageUTF8 $.Repository}}
{{end}}
{{end}} diff --git a/templates/repo/settings/lfs_file_find.tmpl b/templates/repo/settings/lfs_file_find.tmpl index 1e89b5012e..ddf98783db 100644 --- a/templates/repo/settings/lfs_file_find.tmpl +++ b/templates/repo/settings/lfs_file_find.tmpl @@ -6,7 +6,7 @@ - {{range .Results}} + {{range $lfsItem := .Results}} diff --git a/templates/repo/view_list.tmpl b/templates/repo/view_list.tmpl index 317c67611e..e79eac1dd1 100644 --- a/templates/repo/view_list.tmpl +++ b/templates/repo/view_list.tmpl @@ -56,7 +56,7 @@
{{if $commit}} {{$commitLink := printf "%s/commit/%s" $.RepoLink (PathEscape $commit.ID.String)}} - {{ctx.RenderUtils.RenderCommitMessageLinkSubject $commit.Message $commitLink $.Repository}} + {{ctx.RenderUtils.RenderCommitMessageLinkSubject $commit.MessageUTF8 $commitLink $.Repository}} {{else}} … {{/* will be loaded again by LastCommitLoaderURL */}} {{end}} diff --git a/templates/user/dashboard/feeds.tmpl b/templates/user/dashboard/feeds.tmpl index 03f03b176d..baf077863c 100644 --- a/templates/user/dashboard/feeds.tmpl +++ b/templates/user/dashboard/feeds.tmpl @@ -88,13 +88,13 @@ {{$repoLink := (.GetRepoLink ctx)}} {{$repo := .Repo}}
- {{range $push.Commits}} + {{range $pushCommit := $push.Commits}} {{$commitLink := printf "%s/commit/%s" $repoLink .Sha1}}
{{ShortSha .Sha1}} - {{ctx.RenderUtils.RenderCommitMessage .Message $repo}} + {{ctx.RenderUtils.RenderCommitMessage $pushCommit.Message $repo}}
{{end}} diff --git a/tests/integration/api_repo_tags_test.go b/tests/integration/api_repo_tags_test.go index 03dafafb2d..13718040ce 100644 --- a/tests/integration/api_repo_tags_test.go +++ b/tests/integration/api_repo_tags_test.go @@ -16,6 +16,7 @@ import ( "code.gitea.io/gitea/tests" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestAPIRepoTags(t *testing.T) { @@ -35,24 +36,22 @@ func TestAPIRepoTags(t *testing.T) { assert.Len(t, tags, 1) assert.Equal(t, "v1.1", tags[0].Name) - assert.Equal(t, "Initial commit", tags[0].Message) + assert.Equal(t, "Initial commit\n", tags[0].Message) assert.Equal(t, "65f1bf27bc3bf70f64657658635e66094edbcb4d", tags[0].Commit.SHA) assert.Equal(t, setting.AppURL+"api/v1/repos/user2/repo1/git/commits/65f1bf27bc3bf70f64657658635e66094edbcb4d", tags[0].Commit.URL) assert.Equal(t, setting.AppURL+"user2/repo1/archive/v1.1.zip", tags[0].ZipballURL) assert.Equal(t, setting.AppURL+"user2/repo1/archive/v1.1.tar.gz", tags[0].TarballURL) newTag := createNewTagUsingAPI(t, token, user.Name, repoName, "gitea/22", "", "nice!\nand some text") + assert.Equal(t, "nice!\nand some text\n", newTag.Message) // git message standard: there will always be a newline at the end of the message + resp = MakeRequest(t, req, http.StatusOK) tags = DecodeJSON(t, resp, []*api.Tag{}) - assert.Len(t, tags, 2) - for _, tag := range tags { - if tag.Name != "v1.1" { - assert.Equal(t, newTag.Name, tag.Name) - assert.Equal(t, newTag.Message, tag.Message) - assert.Equal(t, "nice!\nand some text", tag.Message) - assert.Equal(t, newTag.Commit.SHA, tag.Commit.SHA) - } - } + require.Len(t, tags, 2) + respTag := tags[0] + assert.Equal(t, newTag.Name, respTag.Name) + assert.Equal(t, newTag.Message, respTag.Message) + assert.Equal(t, newTag.Commit.SHA, respTag.Commit.SHA) // get created tag req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/tags/%s", user.Name, repoName, newTag.Name).
{{svg "octicon-file"}} @@ -14,8 +14,8 @@ - - {{.Summary | ctx.RenderUtils.RenderEmoji}} + + {{$lfsItem.Summary | ctx.RenderUtils.RenderEmoji}}