mirror of
https://github.com/go-gitea/gitea.git
synced 2026-08-01 16:24:21 +00:00
43390e802c
Show only author and co-authors without committer, and deduplicate the same user with multiple email addresses. The commit list "Author" column should not show the committer. This is somewhat misleading, and arguably showing it on the individual commit page is sufficient and consistent with other forges. The same user with multiple email addresses often happens when DEFAULT_KEEP_EMAIL_PRIVATE is enabled and Gitea does not use an actual email address by default for edits. Showing the same avatar and name twice is not helpful then. Ref #37594 Fix #38488 --- Before <img width="4088" height="2138" alt="before" src="https://github.com/user-attachments/assets/a9e919f4-72d0-495f-a0b5-ec094f148f5a" /> After <img width="4124" height="2142" alt="after" src="https://github.com/user-attachments/assets/7212e527-ab83-440a-a8a4-95b5a79b3580" /> --------- Co-authored-by: bircni <bircni@icloud.com> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
64 lines
2.1 KiB
Go
64 lines
2.1 KiB
Go
// Copyright 2026 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package gituser
|
|
|
|
import (
|
|
"context"
|
|
"net/url"
|
|
|
|
"gitea.dev/models/user"
|
|
"gitea.dev/modules/container"
|
|
"gitea.dev/modules/git"
|
|
)
|
|
|
|
// CommitParticipant is one participant of a commit (its author or a co-author):
|
|
// a git identity, optionally matched to a Gitea user.
|
|
type CommitParticipant struct {
|
|
GitIdentity *git.CommitIdentity // git identity (name/email), never nil
|
|
GiteaUser *user.User // matched Gitea user, nil if unmatched
|
|
}
|
|
|
|
// UserCommit represents a commit with matched of database "author" user.
|
|
type UserCommit struct {
|
|
GitCommit *git.Commit
|
|
AuthorUser *user.User
|
|
AvatarStackData *AvatarStackData
|
|
}
|
|
|
|
func RepoCommitSearchByEmailLink(repoLink string, ref git.RefName) string {
|
|
if curRefWebLinkPath := ref.RefWebLinkPath(); curRefWebLinkPath != "" {
|
|
return repoLink + "/commits/" + curRefWebLinkPath + "/search?q=" + url.QueryEscape("author:") + "{email}"
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// GetUserCommitsByGitCommits checks if authors' e-mails of commits are corresponding to users.
|
|
func GetUserCommitsByGitCommits(ctx context.Context, gitCommits []*git.Commit, repoLink string, currentRef git.RefName) ([]*UserCommit, error) {
|
|
userCommits := make([]*UserCommit, 0, len(gitCommits))
|
|
emailSet := make(container.Set[string])
|
|
for _, c := range gitCommits {
|
|
emailSet.Add(c.Author.Email)
|
|
for _, p := range c.AllAuthorIdentities() {
|
|
emailSet.Add(p.Email)
|
|
}
|
|
}
|
|
|
|
emailUserMap, err := user.GetUsersByEmails(ctx, emailSet.Values())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
searchByEmailLink := RepoCommitSearchByEmailLink(repoLink, currentRef)
|
|
for _, c := range gitCommits {
|
|
uc := &UserCommit{
|
|
AuthorUser: emailUserMap.GetByEmail(c.Author.Email), // FIXME: why GetUserCommitsByGitCommits uses "Author", but ParseCommitsWithSignature uses "Committer"?
|
|
GitCommit: c,
|
|
AvatarStackData: BuildAvatarStackData(ctx, c.AllAuthorIdentities(), emailUserMap),
|
|
}
|
|
uc.AvatarStackData.SearchByEmailLink = searchByEmailLink
|
|
userCommits = append(userCommits, uc)
|
|
}
|
|
return userCommits, nil
|
|
}
|