aboutsummaryrefslogtreecommitdiffstats
path: root/services/git/commit.go
diff options
context:
space:
mode:
Diffstat (limited to 'services/git/commit.go')
-rw-r--r--services/git/commit.go95
1 files changed, 95 insertions, 0 deletions
diff --git a/services/git/commit.go b/services/git/commit.go
new file mode 100644
index 0000000000..8ab8f3d369
--- /dev/null
+++ b/services/git/commit.go
@@ -0,0 +1,95 @@
+// Copyright 2025 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package git
+
+import (
+ "context"
+
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
+ "code.gitea.io/gitea/models/db"
+ git_model "code.gitea.io/gitea/models/git"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/container"
+ "code.gitea.io/gitea/modules/git"
+ asymkey_service "code.gitea.io/gitea/services/asymkey"
+)
+
+// ParseCommitsWithSignature checks if signaute of commits are corresponding to users gpg keys.
+func ParseCommitsWithSignature(ctx context.Context, oldCommits []*user_model.UserCommit, repoTrustModel repo_model.TrustModelType, isOwnerMemberCollaborator func(*user_model.User) (bool, error)) ([]*asymkey_model.SignCommit, error) {
+ newCommits := make([]*asymkey_model.SignCommit, 0, len(oldCommits))
+ keyMap := map[string]bool{}
+
+ emails := make(container.Set[string])
+ for _, c := range oldCommits {
+ if c.Committer != nil {
+ emails.Add(c.Committer.Email)
+ }
+ }
+
+ emailUsers, err := user_model.GetUsersByEmails(ctx, emails.Values())
+ if err != nil {
+ return nil, err
+ }
+
+ for _, c := range oldCommits {
+ committer, ok := emailUsers[c.Committer.Email]
+ if !ok && c.Committer != nil {
+ committer = &user_model.User{
+ Name: c.Committer.Name,
+ Email: c.Committer.Email,
+ }
+ }
+
+ signCommit := &asymkey_model.SignCommit{
+ UserCommit: c,
+ Verification: asymkey_service.ParseCommitWithSignatureCommitter(ctx, c.Commit, committer),
+ }
+
+ _ = asymkey_model.CalculateTrustStatus(signCommit.Verification, repoTrustModel, isOwnerMemberCollaborator, &keyMap)
+
+ newCommits = append(newCommits, signCommit)
+ }
+ return newCommits, nil
+}
+
+// ConvertFromGitCommit converts git commits into SignCommitWithStatuses
+func ConvertFromGitCommit(ctx context.Context, commits []*git.Commit, repo *repo_model.Repository) ([]*git_model.SignCommitWithStatuses, error) {
+ validatedCommits, err := user_model.ValidateCommitsWithEmails(ctx, commits)
+ if err != nil {
+ return nil, err
+ }
+ signedCommits, err := ParseCommitsWithSignature(
+ ctx,
+ validatedCommits,
+ repo.GetTrustModel(),
+ func(user *user_model.User) (bool, error) {
+ return repo_model.IsOwnerMemberCollaborator(ctx, repo, user.ID)
+ },
+ )
+ if err != nil {
+ return nil, err
+ }
+ return ParseCommitsWithStatus(ctx, signedCommits, repo)
+}
+
+// ParseCommitsWithStatus checks commits latest statuses and calculates its worst status state
+func ParseCommitsWithStatus(ctx context.Context, oldCommits []*asymkey_model.SignCommit, repo *repo_model.Repository) ([]*git_model.SignCommitWithStatuses, error) {
+ newCommits := make([]*git_model.SignCommitWithStatuses, 0, len(oldCommits))
+
+ for _, c := range oldCommits {
+ commit := &git_model.SignCommitWithStatuses{
+ SignCommit: c,
+ }
+ statuses, _, err := git_model.GetLatestCommitStatus(ctx, repo.ID, commit.ID.String(), db.ListOptions{})
+ if err != nil {
+ return nil, err
+ }
+
+ commit.Statuses = statuses
+ commit.Status = git_model.CalcCommitStatus(statuses)
+ newCommits = append(newCommits, commit)
+ }
+ return newCommits, nil
+}