Skip to content

Commit f4dc344

Browse files
committed
Merge remote-tracking branch 'giteaofficial/main'
* giteaofficial/main: [skip ci] Updated translations via Crowdin Performance optimization for tags synchronization (go-gitea#34355) Fix possible panic (go-gitea#34508) [skip ci] Updated translations via Crowdin
2 parents 2549ad6 + 4dd833c commit f4dc344

File tree

13 files changed

+101
-216
lines changed

13 files changed

+101
-216
lines changed

cmd/hook.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import (
2424
)
2525

2626
const (
27-
hookBatchSize = 30
27+
hookBatchSize = 500
2828
)
2929

3030
var (

models/repo/release.go

Lines changed: 7 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,11 @@ func UpdateRelease(ctx context.Context, rel *Release) error {
161161
return err
162162
}
163163

164+
func UpdateReleaseNumCommits(ctx context.Context, rel *Release) error {
165+
_, err := db.GetEngine(ctx).ID(rel.ID).Cols("num_commits").Update(rel)
166+
return err
167+
}
168+
164169
// AddReleaseAttachments adds a release attachments
165170
func AddReleaseAttachments(ctx context.Context, releaseID int64, attachmentUUIDs []string) (err error) {
166171
// Check attachments
@@ -418,8 +423,8 @@ func UpdateReleasesMigrationsByType(ctx context.Context, gitServiceType structs.
418423
return err
419424
}
420425

421-
// PushUpdateDeleteTagsContext updates a number of delete tags with context
422-
func PushUpdateDeleteTagsContext(ctx context.Context, repo *Repository, tags []string) error {
426+
// PushUpdateDeleteTags updates a number of delete tags with context
427+
func PushUpdateDeleteTags(ctx context.Context, repo *Repository, tags []string) error {
423428
if len(tags) == 0 {
424429
return nil
425430
}
@@ -448,58 +453,6 @@ func PushUpdateDeleteTagsContext(ctx context.Context, repo *Repository, tags []s
448453
return nil
449454
}
450455

451-
// PushUpdateDeleteTag must be called for any push actions to delete tag
452-
func PushUpdateDeleteTag(ctx context.Context, repo *Repository, tagName string) error {
453-
rel, err := GetRelease(ctx, repo.ID, tagName)
454-
if err != nil {
455-
if IsErrReleaseNotExist(err) {
456-
return nil
457-
}
458-
return fmt.Errorf("GetRelease: %w", err)
459-
}
460-
if rel.IsTag {
461-
if _, err = db.DeleteByID[Release](ctx, rel.ID); err != nil {
462-
return fmt.Errorf("Delete: %w", err)
463-
}
464-
} else {
465-
rel.IsDraft = true
466-
rel.NumCommits = 0
467-
rel.Sha1 = ""
468-
if _, err = db.GetEngine(ctx).ID(rel.ID).AllCols().Update(rel); err != nil {
469-
return fmt.Errorf("Update: %w", err)
470-
}
471-
}
472-
473-
return nil
474-
}
475-
476-
// SaveOrUpdateTag must be called for any push actions to add tag
477-
func SaveOrUpdateTag(ctx context.Context, repo *Repository, newRel *Release) error {
478-
rel, err := GetRelease(ctx, repo.ID, newRel.TagName)
479-
if err != nil && !IsErrReleaseNotExist(err) {
480-
return fmt.Errorf("GetRelease: %w", err)
481-
}
482-
483-
if rel == nil {
484-
rel = newRel
485-
if _, err = db.GetEngine(ctx).Insert(rel); err != nil {
486-
return fmt.Errorf("InsertOne: %w", err)
487-
}
488-
} else {
489-
rel.Sha1 = newRel.Sha1
490-
rel.CreatedUnix = newRel.CreatedUnix
491-
rel.NumCommits = newRel.NumCommits
492-
rel.IsDraft = false
493-
if rel.IsTag && newRel.PublisherID > 0 {
494-
rel.PublisherID = newRel.PublisherID
495-
}
496-
if _, err = db.GetEngine(ctx).ID(rel.ID).AllCols().Update(rel); err != nil {
497-
return fmt.Errorf("Update: %w", err)
498-
}
499-
}
500-
return nil
501-
}
502-
503456
// RemapExternalUser ExternalUserRemappable interface
504457
func (r *Release) RemapExternalUser(externalName string, externalID, userID int64) error {
505458
r.OriginalAuthor = externalName

modules/repository/repo.go

Lines changed: 9 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,10 @@ import (
99
"fmt"
1010
"io"
1111
"strings"
12-
"time"
1312

1413
"code.gitea.io/gitea/models/db"
1514
git_model "code.gitea.io/gitea/models/git"
1615
repo_model "code.gitea.io/gitea/models/repo"
17-
user_model "code.gitea.io/gitea/models/user"
18-
"code.gitea.io/gitea/modules/container"
1916
"code.gitea.io/gitea/modules/git"
2017
"code.gitea.io/gitea/modules/gitrepo"
2118
"code.gitea.io/gitea/modules/lfs"
@@ -59,118 +56,6 @@ func SyncRepoTags(ctx context.Context, repoID int64) error {
5956
return SyncReleasesWithTags(ctx, repo, gitRepo)
6057
}
6158

62-
// SyncReleasesWithTags synchronizes release table with repository tags
63-
func SyncReleasesWithTags(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository) error {
64-
log.Debug("SyncReleasesWithTags: in Repo[%d:%s/%s]", repo.ID, repo.OwnerName, repo.Name)
65-
66-
// optimized procedure for pull-mirrors which saves a lot of time (in
67-
// particular for repos with many tags).
68-
if repo.IsMirror {
69-
return pullMirrorReleaseSync(ctx, repo, gitRepo)
70-
}
71-
72-
existingRelTags := make(container.Set[string])
73-
opts := repo_model.FindReleasesOptions{
74-
IncludeDrafts: true,
75-
IncludeTags: true,
76-
ListOptions: db.ListOptions{PageSize: 50},
77-
RepoID: repo.ID,
78-
}
79-
for page := 1; ; page++ {
80-
opts.Page = page
81-
rels, err := db.Find[repo_model.Release](gitRepo.Ctx, opts)
82-
if err != nil {
83-
return fmt.Errorf("unable to GetReleasesByRepoID in Repo[%d:%s/%s]: %w", repo.ID, repo.OwnerName, repo.Name, err)
84-
}
85-
if len(rels) == 0 {
86-
break
87-
}
88-
for _, rel := range rels {
89-
if rel.IsDraft {
90-
continue
91-
}
92-
commitID, err := gitRepo.GetTagCommitID(rel.TagName)
93-
if err != nil && !git.IsErrNotExist(err) {
94-
return fmt.Errorf("unable to GetTagCommitID for %q in Repo[%d:%s/%s]: %w", rel.TagName, repo.ID, repo.OwnerName, repo.Name, err)
95-
}
96-
if git.IsErrNotExist(err) || commitID != rel.Sha1 {
97-
if err := repo_model.PushUpdateDeleteTag(ctx, repo, rel.TagName); err != nil {
98-
return fmt.Errorf("unable to PushUpdateDeleteTag: %q in Repo[%d:%s/%s]: %w", rel.TagName, repo.ID, repo.OwnerName, repo.Name, err)
99-
}
100-
} else {
101-
existingRelTags.Add(strings.ToLower(rel.TagName))
102-
}
103-
}
104-
}
105-
106-
_, err := gitRepo.WalkReferences(git.ObjectTag, 0, 0, func(sha1, refname string) error {
107-
tagName := strings.TrimPrefix(refname, git.TagPrefix)
108-
if existingRelTags.Contains(strings.ToLower(tagName)) {
109-
return nil
110-
}
111-
112-
if err := PushUpdateAddTag(ctx, repo, gitRepo, tagName, sha1, refname); err != nil {
113-
// sometimes, some tags will be sync failed. i.e. https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tag/?h=v2.6.11
114-
// this is a tree object, not a tag object which created before git
115-
log.Error("unable to PushUpdateAddTag: %q to Repo[%d:%s/%s]: %v", tagName, repo.ID, repo.OwnerName, repo.Name, err)
116-
}
117-
118-
return nil
119-
})
120-
return err
121-
}
122-
123-
// PushUpdateAddTag must be called for any push actions to add tag
124-
func PushUpdateAddTag(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, tagName, sha1, refname string) error {
125-
tag, err := gitRepo.GetTagWithID(sha1, tagName)
126-
if err != nil {
127-
return fmt.Errorf("unable to GetTag: %w", err)
128-
}
129-
commit, err := gitRepo.GetTagCommit(tag.Name)
130-
if err != nil {
131-
return fmt.Errorf("unable to get tag Commit: %w", err)
132-
}
133-
134-
sig := tag.Tagger
135-
if sig == nil {
136-
sig = commit.Author
137-
}
138-
if sig == nil {
139-
sig = commit.Committer
140-
}
141-
142-
var author *user_model.User
143-
createdAt := time.Unix(1, 0)
144-
145-
if sig != nil {
146-
author, err = user_model.GetUserByEmail(ctx, sig.Email)
147-
if err != nil && !user_model.IsErrUserNotExist(err) {
148-
return fmt.Errorf("unable to GetUserByEmail for %q: %w", sig.Email, err)
149-
}
150-
createdAt = sig.When
151-
}
152-
153-
commitsCount, err := commit.CommitsCount()
154-
if err != nil {
155-
return fmt.Errorf("unable to get CommitsCount: %w", err)
156-
}
157-
158-
rel := repo_model.Release{
159-
RepoID: repo.ID,
160-
TagName: tagName,
161-
LowerTagName: strings.ToLower(tagName),
162-
Sha1: commit.ID.String(),
163-
NumCommits: commitsCount,
164-
CreatedUnix: timeutil.TimeStamp(createdAt.Unix()),
165-
IsTag: true,
166-
}
167-
if author != nil {
168-
rel.PublisherID = author.ID
169-
}
170-
171-
return repo_model.SaveOrUpdateTag(ctx, repo, &rel)
172-
}
173-
17459
// StoreMissingLfsObjectsInRepository downloads missing LFS objects
17560
func StoreMissingLfsObjectsInRepository(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, lfsClient lfs.Client) error {
17661
contentStore := lfs.NewContentStore()
@@ -286,18 +171,19 @@ func (shortRelease) TableName() string {
286171
return "release"
287172
}
288173

289-
// pullMirrorReleaseSync is a pull-mirror specific tag<->release table
174+
// SyncReleasesWithTags is a tag<->release table
290175
// synchronization which overwrites all Releases from the repository tags. This
291176
// can be relied on since a pull-mirror is always identical to its
292-
// upstream. Hence, after each sync we want the pull-mirror release set to be
177+
// upstream. Hence, after each sync we want the release set to be
293178
// identical to the upstream tag set. This is much more efficient for
294179
// repositories like https://github.com/vim/vim (with over 13000 tags).
295-
func pullMirrorReleaseSync(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository) error {
296-
log.Trace("pullMirrorReleaseSync: rebuilding releases for pull-mirror Repo[%d:%s/%s]", repo.ID, repo.OwnerName, repo.Name)
297-
tags, numTags, err := gitRepo.GetTagInfos(0, 0)
180+
func SyncReleasesWithTags(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository) error {
181+
log.Debug("SyncReleasesWithTags: in Repo[%d:%s/%s]", repo.ID, repo.OwnerName, repo.Name)
182+
tags, _, err := gitRepo.GetTagInfos(0, 0)
298183
if err != nil {
299184
return fmt.Errorf("unable to GetTagInfos in pull-mirror Repo[%d:%s/%s]: %w", repo.ID, repo.OwnerName, repo.Name, err)
300185
}
186+
var added, deleted, updated int
301187
err = db.WithTx(ctx, func(ctx context.Context) error {
302188
dbReleases, err := db.Find[shortRelease](ctx, repo_model.FindReleasesOptions{
303189
RepoID: repo.ID,
@@ -318,9 +204,7 @@ func pullMirrorReleaseSync(ctx context.Context, repo *repo_model.Repository, git
318204
TagName: tag.Name,
319205
LowerTagName: strings.ToLower(tag.Name),
320206
Sha1: tag.Object.String(),
321-
// NOTE: ignored, since NumCommits are unused
322-
// for pull-mirrors (only relevant when
323-
// displaying releases, IsTag: false)
207+
// NOTE: ignored, The NumCommits value is calculated and cached on demand when the UI requires it.
324208
NumCommits: -1,
325209
CreatedUnix: timeutil.TimeStamp(tag.Tagger.When.Unix()),
326210
IsTag: true,
@@ -349,13 +233,14 @@ func pullMirrorReleaseSync(ctx context.Context, repo *repo_model.Repository, git
349233
return fmt.Errorf("unable to update tag %s for pull-mirror Repo[%d:%s/%s]: %w", tag.Name, repo.ID, repo.OwnerName, repo.Name, err)
350234
}
351235
}
236+
added, deleted, updated = len(deletes), len(updates), len(inserts)
352237
return nil
353238
})
354239
if err != nil {
355240
return fmt.Errorf("unable to rebuild release table for pull-mirror Repo[%d:%s/%s]: %w", repo.ID, repo.OwnerName, repo.Name, err)
356241
}
357242

358-
log.Trace("pullMirrorReleaseSync: done rebuilding %d releases", numTags)
243+
log.Trace("SyncReleasesWithTags: %d tags added, %d tags deleted, %d tags updated", added, deleted, updated)
359244
return nil
360245
}
361246

modules/util/map.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright 2025 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package util
5+
6+
func GetMapValueOrDefault[T any](m map[string]any, key string, defaultValue T) T {
7+
if value, ok := m[key]; ok {
8+
if v, ok := value.(T); ok {
9+
return v
10+
}
11+
}
12+
return defaultValue
13+
}

modules/util/map_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright 2025 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package util
5+
6+
import (
7+
"testing"
8+
9+
"github.com/stretchr/testify/assert"
10+
)
11+
12+
func TestGetMapValueOrDefault(t *testing.T) {
13+
testMap := map[string]any{
14+
"key1": "value1",
15+
"key2": 42,
16+
"key3": nil,
17+
}
18+
19+
assert.Equal(t, "value1", GetMapValueOrDefault(testMap, "key1", "default"))
20+
assert.Equal(t, 42, GetMapValueOrDefault(testMap, "key2", 0))
21+
22+
assert.Equal(t, "default", GetMapValueOrDefault(testMap, "key4", "default"))
23+
assert.Equal(t, 100, GetMapValueOrDefault(testMap, "key5", 100))
24+
25+
assert.Equal(t, "default", GetMapValueOrDefault(testMap, "key3", "default"))
26+
}

options/locale/locale_ga-IE.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1228,6 +1228,7 @@ migrate.migrating_issues=Saincheisteanna Imirce
12281228
migrate.migrating_pulls=Iarratais Tarraingthe á n-Imirce
12291229
migrate.cancel_migrating_title=Cealaigh Imirce
12301230
migrate.cancel_migrating_confirm=Ar mhaith leat an imirce seo a chealú?
1231+
migrating_status=Stádas imirce
12311232

12321233
mirror_from=scáthán de
12331234
forked_from=forcailte ó

options/locale/locale_ja-JP.ini

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3809,6 +3809,9 @@ runs.no_workflows.documentation=Gitea Actions の詳細については、<a targ
38093809
runs.no_runs=ワークフローはまだ実行されていません。
38103810
runs.empty_commit_message=(空のコミットメッセージ)
38113811
runs.expire_log_message=ログは古すぎるため消去されています。
3812+
runs.delete=ワークフローの実行を削除
3813+
runs.delete.description=このワークフローを完全に削除してもよろしいですか?この操作は元に戻せません。
3814+
runs.not_done=このワークフローの実行は完了していません。
38123815

38133816
workflow.disable=ワークフローを無効にする
38143817
workflow.disable_success=ワークフロー '%s' が無効になりました。

options/locale/locale_pt-PT.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1523,7 +1523,7 @@ issues.remove_labels=removeu os rótulos %s %s
15231523
issues.add_remove_labels=adicionou o(s) rótulo(s) %s e removeu %s %s
15241524
issues.add_milestone_at=`adicionou esta questão à etapa <b>%s</b> %s`
15251525
issues.add_project_at=`adicionou esta questão ao planeamento <b>%s</b> %s`
1526-
issues.move_to_column_of_project=`isto foi movido para %s dentro de %s em %s`
1526+
issues.move_to_column_of_project=`moveu isto para %s em %s %s`
15271527
issues.change_milestone_at=`modificou a etapa de <b>%s</b> para <b>%s</b> %s`
15281528
issues.change_project_at=`modificou o planeamento de <b>%s</b> para <b>%s</b> %s`
15291529
issues.remove_milestone_at=`removeu esta questão da etapa <b>%s</b> %s`

0 commit comments

Comments
 (0)