diff --git a/.github/workflows/pull-db-tests.yml b/.github/workflows/pull-db-tests.yml
index a3fd8ca621..55c2d2bf5e 100644
--- a/.github/workflows/pull-db-tests.yml
+++ b/.github/workflows/pull-db-tests.yml
@@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-latest
services:
pgsql:
- image: postgres:12
+ image: postgres:14
env:
POSTGRES_DB: test
POSTGRES_PASSWORD: postgres
diff --git a/cmd/hook.go b/cmd/hook.go
index 41e3c3ce34..6f0aa5a203 100644
--- a/cmd/hook.go
+++ b/cmd/hook.go
@@ -24,7 +24,7 @@ import (
)
const (
- hookBatchSize = 30
+ hookBatchSize = 500
)
var (
diff --git a/models/repo/release.go b/models/repo/release.go
index 663d310bc0..06cfa37342 100644
--- a/models/repo/release.go
+++ b/models/repo/release.go
@@ -161,6 +161,11 @@ func UpdateRelease(ctx context.Context, rel *Release) error {
return err
}
+func UpdateReleaseNumCommits(ctx context.Context, rel *Release) error {
+ _, err := db.GetEngine(ctx).ID(rel.ID).Cols("num_commits").Update(rel)
+ return err
+}
+
// AddReleaseAttachments adds a release attachments
func AddReleaseAttachments(ctx context.Context, releaseID int64, attachmentUUIDs []string) (err error) {
// Check attachments
@@ -418,8 +423,8 @@ func UpdateReleasesMigrationsByType(ctx context.Context, gitServiceType structs.
return err
}
-// PushUpdateDeleteTagsContext updates a number of delete tags with context
-func PushUpdateDeleteTagsContext(ctx context.Context, repo *Repository, tags []string) error {
+// PushUpdateDeleteTags updates a number of delete tags with context
+func PushUpdateDeleteTags(ctx context.Context, repo *Repository, tags []string) error {
if len(tags) == 0 {
return nil
}
@@ -448,58 +453,6 @@ func PushUpdateDeleteTagsContext(ctx context.Context, repo *Repository, tags []s
return nil
}
-// PushUpdateDeleteTag must be called for any push actions to delete tag
-func PushUpdateDeleteTag(ctx context.Context, repo *Repository, tagName string) error {
- rel, err := GetRelease(ctx, repo.ID, tagName)
- if err != nil {
- if IsErrReleaseNotExist(err) {
- return nil
- }
- return fmt.Errorf("GetRelease: %w", err)
- }
- if rel.IsTag {
- if _, err = db.DeleteByID[Release](ctx, rel.ID); err != nil {
- return fmt.Errorf("Delete: %w", err)
- }
- } else {
- rel.IsDraft = true
- rel.NumCommits = 0
- rel.Sha1 = ""
- if _, err = db.GetEngine(ctx).ID(rel.ID).AllCols().Update(rel); err != nil {
- return fmt.Errorf("Update: %w", err)
- }
- }
-
- return nil
-}
-
-// SaveOrUpdateTag must be called for any push actions to add tag
-func SaveOrUpdateTag(ctx context.Context, repo *Repository, newRel *Release) error {
- rel, err := GetRelease(ctx, repo.ID, newRel.TagName)
- if err != nil && !IsErrReleaseNotExist(err) {
- return fmt.Errorf("GetRelease: %w", err)
- }
-
- if rel == nil {
- rel = newRel
- if _, err = db.GetEngine(ctx).Insert(rel); err != nil {
- return fmt.Errorf("InsertOne: %w", err)
- }
- } else {
- rel.Sha1 = newRel.Sha1
- rel.CreatedUnix = newRel.CreatedUnix
- rel.NumCommits = newRel.NumCommits
- rel.IsDraft = false
- if rel.IsTag && newRel.PublisherID > 0 {
- rel.PublisherID = newRel.PublisherID
- }
- if _, err = db.GetEngine(ctx).ID(rel.ID).AllCols().Update(rel); err != nil {
- return fmt.Errorf("Update: %w", err)
- }
- }
- return nil
-}
-
// RemapExternalUser ExternalUserRemappable interface
func (r *Release) RemapExternalUser(externalName string, externalID, userID int64) error {
r.OriginalAuthor = externalName
diff --git a/modules/repository/repo.go b/modules/repository/repo.go
index bc147a4dd5..ad4a53b858 100644
--- a/modules/repository/repo.go
+++ b/modules/repository/repo.go
@@ -9,13 +9,10 @@ import (
"fmt"
"io"
"strings"
- "time"
"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"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/lfs"
@@ -59,118 +56,6 @@ func SyncRepoTags(ctx context.Context, repoID int64) error {
return SyncReleasesWithTags(ctx, repo, gitRepo)
}
-// SyncReleasesWithTags synchronizes release table with repository tags
-func SyncReleasesWithTags(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository) error {
- log.Debug("SyncReleasesWithTags: in Repo[%d:%s/%s]", repo.ID, repo.OwnerName, repo.Name)
-
- // optimized procedure for pull-mirrors which saves a lot of time (in
- // particular for repos with many tags).
- if repo.IsMirror {
- return pullMirrorReleaseSync(ctx, repo, gitRepo)
- }
-
- existingRelTags := make(container.Set[string])
- opts := repo_model.FindReleasesOptions{
- IncludeDrafts: true,
- IncludeTags: true,
- ListOptions: db.ListOptions{PageSize: 50},
- RepoID: repo.ID,
- }
- for page := 1; ; page++ {
- opts.Page = page
- rels, err := db.Find[repo_model.Release](gitRepo.Ctx, opts)
- if err != nil {
- return fmt.Errorf("unable to GetReleasesByRepoID in Repo[%d:%s/%s]: %w", repo.ID, repo.OwnerName, repo.Name, err)
- }
- if len(rels) == 0 {
- break
- }
- for _, rel := range rels {
- if rel.IsDraft {
- continue
- }
- commitID, err := gitRepo.GetTagCommitID(rel.TagName)
- if err != nil && !git.IsErrNotExist(err) {
- return fmt.Errorf("unable to GetTagCommitID for %q in Repo[%d:%s/%s]: %w", rel.TagName, repo.ID, repo.OwnerName, repo.Name, err)
- }
- if git.IsErrNotExist(err) || commitID != rel.Sha1 {
- if err := repo_model.PushUpdateDeleteTag(ctx, repo, rel.TagName); err != nil {
- return fmt.Errorf("unable to PushUpdateDeleteTag: %q in Repo[%d:%s/%s]: %w", rel.TagName, repo.ID, repo.OwnerName, repo.Name, err)
- }
- } else {
- existingRelTags.Add(strings.ToLower(rel.TagName))
- }
- }
- }
-
- _, err := gitRepo.WalkReferences(git.ObjectTag, 0, 0, func(sha1, refname string) error {
- tagName := strings.TrimPrefix(refname, git.TagPrefix)
- if existingRelTags.Contains(strings.ToLower(tagName)) {
- return nil
- }
-
- if err := PushUpdateAddTag(ctx, repo, gitRepo, tagName, sha1, refname); err != nil {
- // 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
- // this is a tree object, not a tag object which created before git
- log.Error("unable to PushUpdateAddTag: %q to Repo[%d:%s/%s]: %v", tagName, repo.ID, repo.OwnerName, repo.Name, err)
- }
-
- return nil
- })
- return err
-}
-
-// PushUpdateAddTag must be called for any push actions to add tag
-func PushUpdateAddTag(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, tagName, sha1, refname string) error {
- tag, err := gitRepo.GetTagWithID(sha1, tagName)
- if err != nil {
- return fmt.Errorf("unable to GetTag: %w", err)
- }
- commit, err := gitRepo.GetTagCommit(tag.Name)
- if err != nil {
- return fmt.Errorf("unable to get tag Commit: %w", err)
- }
-
- sig := tag.Tagger
- if sig == nil {
- sig = commit.Author
- }
- if sig == nil {
- sig = commit.Committer
- }
-
- var author *user_model.User
- createdAt := time.Unix(1, 0)
-
- if sig != nil {
- author, err = user_model.GetUserByEmail(ctx, sig.Email)
- if err != nil && !user_model.IsErrUserNotExist(err) {
- return fmt.Errorf("unable to GetUserByEmail for %q: %w", sig.Email, err)
- }
- createdAt = sig.When
- }
-
- commitsCount, err := commit.CommitsCount()
- if err != nil {
- return fmt.Errorf("unable to get CommitsCount: %w", err)
- }
-
- rel := repo_model.Release{
- RepoID: repo.ID,
- TagName: tagName,
- LowerTagName: strings.ToLower(tagName),
- Sha1: commit.ID.String(),
- NumCommits: commitsCount,
- CreatedUnix: timeutil.TimeStamp(createdAt.Unix()),
- IsTag: true,
- }
- if author != nil {
- rel.PublisherID = author.ID
- }
-
- return repo_model.SaveOrUpdateTag(ctx, repo, &rel)
-}
-
// StoreMissingLfsObjectsInRepository downloads missing LFS objects
func StoreMissingLfsObjectsInRepository(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, lfsClient lfs.Client) error {
contentStore := lfs.NewContentStore()
@@ -286,18 +171,19 @@ func (shortRelease) TableName() string {
return "release"
}
-// pullMirrorReleaseSync is a pull-mirror specific tag<->release table
+// SyncReleasesWithTags is a tag<->release table
// synchronization which overwrites all Releases from the repository tags. This
// can be relied on since a pull-mirror is always identical to its
-// upstream. Hence, after each sync we want the pull-mirror release set to be
+// upstream. Hence, after each sync we want the release set to be
// identical to the upstream tag set. This is much more efficient for
// repositories like https://github.com/vim/vim (with over 13000 tags).
-func pullMirrorReleaseSync(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository) error {
- log.Trace("pullMirrorReleaseSync: rebuilding releases for pull-mirror Repo[%d:%s/%s]", repo.ID, repo.OwnerName, repo.Name)
- tags, numTags, err := gitRepo.GetTagInfos(0, 0)
+func SyncReleasesWithTags(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository) error {
+ log.Debug("SyncReleasesWithTags: in Repo[%d:%s/%s]", repo.ID, repo.OwnerName, repo.Name)
+ tags, _, err := gitRepo.GetTagInfos(0, 0)
if err != nil {
return fmt.Errorf("unable to GetTagInfos in pull-mirror Repo[%d:%s/%s]: %w", repo.ID, repo.OwnerName, repo.Name, err)
}
+ var added, deleted, updated int
err = db.WithTx(ctx, func(ctx context.Context) error {
dbReleases, err := db.Find[shortRelease](ctx, repo_model.FindReleasesOptions{
RepoID: repo.ID,
@@ -318,9 +204,7 @@ func pullMirrorReleaseSync(ctx context.Context, repo *repo_model.Repository, git
TagName: tag.Name,
LowerTagName: strings.ToLower(tag.Name),
Sha1: tag.Object.String(),
- // NOTE: ignored, since NumCommits are unused
- // for pull-mirrors (only relevant when
- // displaying releases, IsTag: false)
+ // NOTE: ignored, The NumCommits value is calculated and cached on demand when the UI requires it.
NumCommits: -1,
CreatedUnix: timeutil.TimeStamp(tag.Tagger.When.Unix()),
IsTag: true,
@@ -349,13 +233,14 @@ func pullMirrorReleaseSync(ctx context.Context, repo *repo_model.Repository, git
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)
}
}
+ added, deleted, updated = len(deletes), len(updates), len(inserts)
return nil
})
if err != nil {
return fmt.Errorf("unable to rebuild release table for pull-mirror Repo[%d:%s/%s]: %w", repo.ID, repo.OwnerName, repo.Name, err)
}
- log.Trace("pullMirrorReleaseSync: done rebuilding %d releases", numTags)
+ log.Trace("SyncReleasesWithTags: %d tags added, %d tags deleted, %d tags updated", added, deleted, updated)
return nil
}
diff --git a/modules/util/map.go b/modules/util/map.go
new file mode 100644
index 0000000000..f307faad1f
--- /dev/null
+++ b/modules/util/map.go
@@ -0,0 +1,13 @@
+// Copyright 2025 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package util
+
+func GetMapValueOrDefault[T any](m map[string]any, key string, defaultValue T) T {
+ if value, ok := m[key]; ok {
+ if v, ok := value.(T); ok {
+ return v
+ }
+ }
+ return defaultValue
+}
diff --git a/modules/util/map_test.go b/modules/util/map_test.go
new file mode 100644
index 0000000000..1a141cec88
--- /dev/null
+++ b/modules/util/map_test.go
@@ -0,0 +1,26 @@
+// Copyright 2025 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package util
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestGetMapValueOrDefault(t *testing.T) {
+ testMap := map[string]any{
+ "key1": "value1",
+ "key2": 42,
+ "key3": nil,
+ }
+
+ assert.Equal(t, "value1", GetMapValueOrDefault(testMap, "key1", "default"))
+ assert.Equal(t, 42, GetMapValueOrDefault(testMap, "key2", 0))
+
+ assert.Equal(t, "default", GetMapValueOrDefault(testMap, "key4", "default"))
+ assert.Equal(t, 100, GetMapValueOrDefault(testMap, "key5", 100))
+
+ assert.Equal(t, "default", GetMapValueOrDefault(testMap, "key3", "default"))
+}
diff --git a/options/locale/locale_ga-IE.ini b/options/locale/locale_ga-IE.ini
index fac7e15fc4..362ebbd999 100644
--- a/options/locale/locale_ga-IE.ini
+++ b/options/locale/locale_ga-IE.ini
@@ -1228,6 +1228,7 @@ migrate.migrating_issues=Saincheisteanna Imirce
migrate.migrating_pulls=Iarratais Tarraingthe á n-Imirce
migrate.cancel_migrating_title=Cealaigh Imirce
migrate.cancel_migrating_confirm=Ar mhaith leat an imirce seo a chealú?
+migrating_status=Stádas imirce
mirror_from=scáthán de
forked_from=forcailte ó
diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini
index 2a871da6aa..32413023d0 100644
--- a/options/locale/locale_ja-JP.ini
+++ b/options/locale/locale_ja-JP.ini
@@ -3809,6 +3809,9 @@ runs.no_workflows.documentation=Gitea Actions の詳細については、%s %s`
issues.add_project_at=`adicionou esta questão ao planeamento %s %s`
-issues.move_to_column_of_project=`isto foi movido para %s dentro de %s em %s`
+issues.move_to_column_of_project=`moveu isto para %s em %s %s`
issues.change_milestone_at=`modificou a etapa de %s para %s %s`
issues.change_project_at=`modificou o planeamento de %s para %s %s`
issues.remove_milestone_at=`removeu esta questão da etapa %s %s`
diff --git a/options/locale/locale_tr-TR.ini b/options/locale/locale_tr-TR.ini
index d617598057..43ff6495c1 100644
--- a/options/locale/locale_tr-TR.ini
+++ b/options/locale/locale_tr-TR.ini
@@ -113,9 +113,11 @@ copy_type_unsupported=Bu dosya türü kopyalanamaz
write=Yaz
preview=Önizleme
loading=Yükleniyor…
+files=Dosyalar
error=Hata
error404=Ulaşmaya çalıştığınız sayfa mevcut değil veya görüntüleme yetkiniz yok.
+error503=Sunucu isteğinizi gerçekleştiremedi. Lütfen daha sonra tekrar deneyin.
go_back=Geri Git
invalid_data=Geçersiz veri: %v
@@ -128,6 +130,7 @@ pin=Sabitle
unpin=Sabitlemeyi kaldır
artifacts=Yapılar
+expired=Süresi doldu
confirm_delete_artifact=%s yapısını silmek istediğinizden emin misiniz?
archived=Arşivlenmiş
@@ -169,6 +172,10 @@ search=Ara...
type_tooltip=Arama türü
fuzzy=Bulanık
fuzzy_tooltip=Arama terimine benzeyen sonuçları da içer
+words=Kelimeler
+words_tooltip=Sadece arama terimi kelimeleriyle eşleşen sonuçları içer
+regexp=Regexp
+regexp_tooltip=Sadece regexp arama terimiyle tamamen eşleşen sonuçları içer
exact=Tam
exact_tooltip=Sadece arama terimiyle tamamen eşleşen sonuçları içer
repo_kind=Depoları ara...
@@ -235,13 +242,17 @@ network_error=Ağ hatası
[startpage]
app_desc=Zahmetsiz, kendi sunucunuzda barındırabileceğiniz Git servisi
install=Kurulumu kolay
+install_desc=Platformunuz için ikili dosyayı çalıştırın, Docker ile yükleyin veya paket olarak edinin.
platform=Farklı platformlarda çalışablir
+platform_desc=Gitea Go ile derleme yapılabilecek her yerde çalışmaktadır: Windows, macOS, Linux, ARM, vb. Hangisini seviyorsanız onu seçin!
lightweight=Hafif
lightweight_desc=Gitea'nın minimal gereksinimleri çok düşüktür ve ucuz bir Raspberry Pi üzerinde çalışabilmektedir. Makine enerjinizden tasarruf edin!
license=Açık Kaynak
+license_desc=Gidin ve code.gitea.io/gitea'yı edinin! Bu projeyi daha da iyi yapmak için katkıda bulunarak bize katılın. Katkıda bulunmaktan çekinmeyin!
[install]
install=Kurulum
+installing_desc=Şimdi kuruluyor, lütfen bekleyin...
title=Başlangıç Yapılandırması
docker_helper=Eğer Gitea'yı Docker içerisinde çalıştırıyorsanız, lütfen herhangi bir değişiklik yapmadan önce belgeleri okuyun.
require_db_desc=Gitea MySQL, PostgreSQL, MSSQL, SQLite3 veya TiDB (MySQL protokolü) gerektirir.
@@ -352,6 +363,7 @@ enable_update_checker=Güncelleme Denetleyicisini Etkinleştir
enable_update_checker_helper=Düzenli olarak gitea.io'ya bağlanarak yeni yayınlanan sürümleri denetler.
env_config_keys=Ortam Yapılandırma
env_config_keys_prompt=Aşağıdaki ortam değişkenleri de yapılandırma dosyanıza eklenecektir:
+config_write_file_prompt=Bu yapılandırma seçenekleri şuraya yazılacak: %s
[home]
nav_menu=Gezinti Menüsü
@@ -380,6 +392,12 @@ show_only_public=Yalnızca açık olanlar gösteriliyor
issues.in_your_repos=Depolarınızda
+guide_title=Etkinlik yok
+guide_desc=Herhangi bir depo veya kullanıcı takip etmiyorsunuz, bu yüzden görüntülenecek bir içerik yok. Aşağıdaki bağlantıları kullanarak ilgi çekici depo ve kullanıcıları keşfedebilirsiniz.
+explore_repos=Depoları keşfet
+explore_users=Kullanıcıları keşfet
+empty_org=Henüz bir organizasyon yok.
+empty_repo=Henüz bir depo yok.
[explore]
repos=Depolar
@@ -433,6 +451,7 @@ use_scratch_code=Bir çizgi kodu kullanınız
twofa_scratch_used=Geçici kodunuzu kullandınız. İki aşamalı ayarlar sayfasına yönlendirildiniz, burada aygıt kaydınızı kaldırabilir veya yeni bir geçici kod oluşturabilirsiniz.
twofa_passcode_incorrect=Şifreniz yanlış. Aygıtınızı yanlış yerleştirdiyseniz, oturum açmak için çizgi kodunuzu kullanın.
twofa_scratch_token_incorrect=Çizgi kodunuz doğru değildir.
+twofa_required=Depolara erişmek için iki aşama doğrulama kullanmanız veya tekrar oturum açmayı denemeniz gereklidir.
login_userpass=Oturum Aç
login_openid=Açık Kimlik
oauth_signup_tab=Yeni Hesap Oluştur
@@ -441,6 +460,7 @@ oauth_signup_submit=Hesabı Tamamla
oauth_signin_tab=Mevcut Hesaba Bağla
oauth_signin_title=Bağlantılı Hesabı Yetkilendirmek için Giriş Yapın
oauth_signin_submit=Hesabı Bağla
+oauth.signin.error.general=Yetkilendirme isteğini işlerken bir hata oluştu: %s. Eğer hata devam ederse lütfen site yöneticisiyle bağlantıya geçin.
oauth.signin.error.access_denied=Yetkilendirme isteği reddedildi.
oauth.signin.error.temporarily_unavailable=Yetkilendirme sunucusu geçici olarak erişilemez olduğu için yetkilendirme başarısız oldu. Lütfen daha sonra tekrar deneyin.
oauth_callback_unable_auto_reg=Otomatik kayıt etkin ancak OAuth2 Sağlayıcı %[1] eksik sahalar döndürdü: %[2]s, otomatik olarak hesap oluşturulamıyor, lütfen bir hesap oluşturun veya bağlantı verin, veya site yöneticisiyle iletişim kurun.
@@ -457,10 +477,12 @@ authorize_application=Uygulamayı Yetkilendir
authorize_redirect_notice=Bu uygulamayı yetkilendirirseniz %s adresine yönlendirileceksiniz.
authorize_application_created_by=Bu uygulama %s tarafından oluşturuldu.
authorize_application_description=Erişime izin verirseniz, özel depolar ve organizasyonlar da dahil olmak üzere tüm hesap bilgilerinize erişebilir ve yazabilir.
+authorize_application_with_scopes=Kapsamlar: %s
authorize_title=Hesabınıza erişmesi için "%s" yetkilendirilsin mi?
authorization_failed=Yetkilendirme başarısız oldu
authorization_failed_desc=Geçersiz bir istek tespit ettiğimiz için yetkilendirme başarısız oldu. Lütfen izin vermeye çalıştığınız uygulamanın sağlayıcısı ile iletişim kurun.
sspi_auth_failed=SSPI kimlik doğrulaması başarısız oldu
+password_pwned=Seçtiğiniz parola, daha önce herkese açık veri ihlallerinde açığa çıkan bir çalınan parola listesindedir. Lütfen farklı bir parola ile tekrar deneyin ve başka yerlerde de bu parolayı değiştirmeyi düşünün.
password_pwned_err=HaveIBeenPwned'e yapılan istek tamamlanamadı
last_admin=Son yöneticiyi silemezsiniz. En azından bir yönetici olmalıdır.
signin_passkey=Bir parola anahtarı ile oturum aç
@@ -583,6 +605,8 @@ lang_select_error=Listeden bir dil seçin.
username_been_taken=Bu kullanıcı adı daha önce alınmış.
username_change_not_local_user=Yerel olmayan kullanıcılar kendi kullanıcı adlarını değiştiremezler.
+change_username_disabled=Kullanıcı adı değişikliği devre dışıdır.
+change_full_name_disabled=Tam ad değişikliği devre dışıdır.
username_has_not_been_changed=Kullanıcı adı değişmedi
repo_name_been_taken=Depo adı zaten kullanılıyor.
repository_force_private=Gizliyi Zorla devrede: gizli depolar herkese açık yapılamaz.
@@ -632,6 +656,7 @@ org_still_own_repo=Bu organizasyon hala bir veya daha fazla depoya sahip, önce
org_still_own_packages=Bu organizasyon hala bir veya daha fazla pakete sahip, önce onları silin.
target_branch_not_exist=Hedef dal mevcut değil.
+target_ref_not_exist=Hedef referans mevcut değil %s
admin_cannot_delete_self=Yöneticiyken kendinizi silemezsiniz. Lütfen önce yönetici haklarınızı kaldırın.
@@ -698,14 +723,18 @@ applications=Uygulamalar
orgs=Organizasyonları Yönet
repos=Depolar
delete=Hesabı Sil
+twofa=İki Aşamalı Kimlik Doğrulama (TOTP)
account_link=Bağlı Hesaplar
organization=Organizasyonlar
uid=UID
+webauthn=İki-Aşamalı Kimlik Doğrulama (Güvenlik Anahtarları)
public_profile=Herkese Açık Profil
biography_placeholder=Bize kendiniz hakkında birşeyler söyleyin! (Markdown kullanabilirsiniz)
location_placeholder=Yaklaşık konumunuzu başkalarıyla paylaşın
profile_desc=Profilinizin başkalarına nasıl gösterildiğini yönetin. Ana e-posta adresiniz bildirimler, parola kurtarma ve web tabanlı Git işlemleri için kullanılacaktır.
+password_username_disabled=Yerel olmayan kullanıcılara kullanıcı adlarını değiştirme izni verilmemiştir. Daha fazla bilgi edinmek için lütfen site yöneticisi ile iletişime geçiniz.
+password_full_name_disabled=Tam adınızı değiştirme izniniz yoktur. Daha fazla bilgi edinmek için lütfen site yöneticisi ile iletişime geçiniz.
full_name=Ad Soyad
website=Web Sitesi
location=Konum
@@ -755,6 +784,7 @@ uploaded_avatar_not_a_image=Yüklenen dosya bir resim dosyası değil.
uploaded_avatar_is_too_big=Yüklenen dosyanın boyutu (%d KiB), azami boyutu (%d KiB) aşıyor.
update_avatar_success=Profil resminiz değiştirildi.
update_user_avatar_success=Kullanıcının avatarı güncellendi.
+cropper_prompt=Kaydetmeden önce resmi düzenleyebilirsiniz. Düzenlenen resim PNG biçiminde kaydedilecektir.
change_password=Parolayı Güncelle
old_password=Mevcut Parola
@@ -797,6 +827,7 @@ add_email_success=Yeni e-posta adresi eklendi.
email_preference_set_success=E-posta tercihi başarıyla ayarlandı.
add_openid_success=Yeni OpenID adresi eklendi.
keep_email_private=E-posta Adresini Gizle
+keep_email_private_popup=Bu, e-posta adresinizi profilde, değişiklik isteği yaptığınızda veya web arayüzünde dosya düzenlediğinizde gizleyecektir. İtilen işlemeler değişmeyecektir.
openid_desc=OpenID, kimlik doğrulama işlemini harici bir sağlayıcıya devretmenize olanak sağlar.
manage_ssh_keys=SSH Anahtarlarını Yönet
@@ -898,6 +929,9 @@ permission_not_set=Ayarlanmadı
permission_no_access=Erişim Yok
permission_read=Okunmuş
permission_write=Okuma ve Yazma
+permission_anonymous_read=Anonim Okuma
+permission_everyone_read=Herkes Okuyabilir
+permission_everyone_write=Herkes Yazabilir
access_token_desc=Seçili token izinleri, yetkilendirmeyi ilgili API yollarıyla sınırlandıracaktır. Daha fazla bilgi için belgeleri okuyun.
at_least_one_permission=Bir token oluşturmak için en azından bir izin seçmelisiniz
permissions_list=İzinler:
@@ -925,6 +959,7 @@ oauth2_client_secret_hint=Bu sayfadan ayrıldıktan veya yeniledikten sonra gizl
oauth2_application_edit=Düzenle
oauth2_application_create_description=OAuth2 uygulamaları, üçüncü taraf uygulamanıza bu durumda kullanıcı hesaplarına erişim sağlar.
oauth2_application_remove_description=Bir OAuth2 uygulamasının kaldırılması, bu sunucudaki yetkili kullanıcı hesaplarına erişmesini önler. Devam edilsin mi?
+oauth2_application_locked=Gitea kimi OAuth2 uygulamalarının başlangıçta ön kaydını, yapılandırmada etkinleştirilmişse yapabilir. Beklenmeyen davranışı önlemek için bunlar ne düzenlenmeli ne de kaldırılmalı. Daha fazla bilgi için OAuth2 belgesine bakın.
authorized_oauth2_applications=Yetkili OAuth2 Uygulamaları
authorized_oauth2_applications_description=Kişisel Gitea hesabınıza bu üçüncü parti uygulamalara erişim izni verdiniz. Lütfen artık ihtiyaç duyulmayan uygulamalara erişimi iptal edin.
@@ -933,13 +968,17 @@ revoke_oauth2_grant=Erişimi İptal Et
revoke_oauth2_grant_description=Bu üçüncü taraf uygulamasına erişimin iptal edilmesi bu uygulamanın verilerinize erişmesini önleyecektir. Emin misiniz?
revoke_oauth2_grant_success=Erişim başarıyla kaldırıldı.
+twofa_desc=İki aşamalı kimlik doğrulama, hesabınızın güvenliğini artırır.
twofa_recovery_tip=Aygıtınızı kaybetmeniz durumunda, hesabınıza tekrar erişmek için tek kullanımlık kurtarma anahtarını kullanabileceksiniz.
twofa_is_enrolled=Hesabınız şu anda iki faktörlü kimlik doğrulaması içinde kaydedilmiş.
twofa_not_enrolled=Hesabınız şu anda iki faktörlü kimlik doğrulaması içinde kaydedilmemiş.
twofa_disable=İki Aşamalı Doğrulamayı Devre Dışı Bırak
+twofa_scratch_token_regenerate=Geçici Kodu Yeniden Üret
+twofa_scratch_token_regenerated=Geçici kodunuz şimdi %s. Güvenli bir yerde saklayın, tekrar gösterilmeyecektir.
twofa_enroll=İki Faktörlü Kimlik Doğrulamaya Kaydolun
twofa_disable_note=Gerekirse iki faktörlü kimlik doğrulamayı devre dışı bırakabilirsiniz.
twofa_disable_desc=İki faktörlü kimlik doğrulamayı devre dışı bırakmak hesabınızı daha az güvenli hale getirir. Devam edilsin mi?
+regenerate_scratch_token_desc=Geçici kodunuzu kaybettiyseniz veya oturum açmak için kullandıysanız, buradan sıfırlayabilirsiniz.
twofa_disabled=İki faktörlü kimlik doğrulama devre dışı bırakıldı.
scan_this_image=Kim doğrulama uygulamanızla bu görüntüyü tarayın:
or_enter_secret=Veya gizli şeyi girin: %s
@@ -993,6 +1032,8 @@ new_repo_helper=Bir depo, sürüm geçmişi dahil tüm proje dosyalarını içer
owner=Sahibi
owner_helper=Bazı organizasyonlar, en çok depo sayısı sınırı nedeniyle açılır menüde görünmeyebilir.
repo_name=Depo İsmi
+repo_name_profile_public_hint=.profile herkese açık organizasyonunuzun profiline herkesin görüntüleyebileceği bir README.md dosyası eklemek için kullanabileceğiniz özel bir depodur. Başlamak için herkese açık olduğundan ve profile dizininde README ile başladığınızdan emin olun.
+repo_name_profile_private_hint=.profile-private organizasyonunuzun üye profiline sadece organizasyon üyelerinin görüntüleyebileceği bir README.md eklemek için kullanabileceğiniz özel bir depodur. Başlamak için özel olduğundan ve profil dizininde README ile başladığınızdan emin olun.
repo_size=Depo Boyutu
template=Şablon
template_select=Bir şablon seçin.
@@ -1011,6 +1052,8 @@ fork_to_different_account=Başka bir hesaba çatalla
fork_visibility_helper=Çatallanmış bir deponun görünürlüğü değiştirilemez.
fork_branch=Çatala klonlanacak dal
all_branches=Tüm dallar
+view_all_branches=Tüm dalları görüntüle
+view_all_tags=Tüm etiketleri görüntüle
fork_no_valid_owners=Geçerli bir sahibi olmadığı için bu depo çatallanamaz.
fork.blocked_user=Depo çatallanamıyor, depo sahibi tarafından engellenmişsiniz.
use_template=Bu şablonu kullan
@@ -1022,6 +1065,8 @@ generate_repo=Depo Oluştur
generate_from=Şuradan Oluştur
repo_desc=Açıklama
repo_desc_helper=Kısa açıklama girin (isteğe bağlı)
+repo_no_desc=Hiçbir açıklama sağlanmadı
+repo_lang=Dil
repo_gitignore_helper=.gitignore şablonlarını seç.
repo_gitignore_helper_desc=Sık kullanılan diller için bir şablon listesinden hangi dosyaların izlenmeyeceğini seçin. Her dilin oluşturma araçları tarafından oluşturulan tipik yapılar, varsayılan olarak .gitignore dosyasına dahil edilmiştir.
issue_labels=Konu Etiketleri
@@ -1029,6 +1074,7 @@ issue_labels_helper=Bir konu etiket seti seçin.
license=Lisans
license_helper=Bir lisans dosyası seçin.
license_helper_desc=Bir lisans, başkalarının kodunuzla neler yapıp yapamayacağını yönetir. Projeniz için hangisinin doğru olduğundan emin değil misiniz? Lisans seçme konusuna bakın
+multiple_licenses=Çoklu Lisans
object_format=Nesne Biçimi
object_format_helper=Deponun nesne biçimi. Daha sonra değiştirilemez. SHA1 en uyumlu olandır.
readme=README
@@ -1082,15 +1128,20 @@ delete_preexisting_success=%s içindeki kabul edilmeyen dosyalar silindi
blame_prior=Bu değişiklikten önceki suçu görüntüle
blame.ignore_revs=.git-blame-ignore-revs dosyasındaki sürümler yok sayılıyor. Bunun yerine normal sorumlu görüntüsü için buraya tıklayın.
blame.ignore_revs.failed=.git-blame-ignore-revs dosyasındaki sürümler yok sayılamadı.
+user_search_tooltip=En fazla 30 kullanıcı görüntüler
+tree_path_not_found=%[1] yolu, %[2]s deposunda mevcut değil
transfer.accept=Aktarımı Kabul Et
+transfer.accept_desc=`"%s" tarafına aktar`
transfer.reject=Aktarımı Reddet
+transfer.reject_desc=`"%s" tarafına aktarımı iptal et`
transfer.no_permission_to_accept=Bu aktarımı kabul etme izniniz yok.
transfer.no_permission_to_reject=Bu aktarımı reddetme izniniz yok.
desc.private=Özel
desc.public=Genel
+desc.public_access=Herkese Açık Erişim
desc.template=Şablon
desc.internal=Dahili
desc.archived=Arşivlenmiş
@@ -1160,6 +1211,10 @@ migrate.gogs.description=Notabug.org veya diğer Gogs sunucularından veri aktar
migrate.onedev.description=Code.onedev.io ve diğer OneDev sunucularından veri aktar.
migrate.codebase.description=Codebasehq.com sitesinden veri aktar.
migrate.gitbucket.description=GitBucket sunucularından veri aktar.
+migrate.codecommit.aws_access_key_id=AWS Erişim Anahtarı Kimliği
+migrate.codecommit.aws_secret_access_key=AWS Gizli Erişim Anahtarı
+migrate.codecommit.https_git_credentials_username=HTTPS Git Kimliği Kullanıcı Adı
+migrate.codecommit.https_git_credentials_password=HTTPS Git Kimliği Parolası
migrate.migrating_git=Git Verilerini Taşıma
migrate.migrating_topics=Konuları Taşıma
migrate.migrating_milestones=Kilometre Taşlarını Taşıma
@@ -1193,6 +1248,7 @@ create_new_repo_command=Komut satırında yeni bir depo oluşturuluyor
push_exist_repo=Komut satırından mevcut bir depo itiliyor
empty_message=Bu depoda herhangi bir içerik yok.
broken_message=Bu deponun altındaki Git verisi okunamıyor. Bu sunucunun yöneticisiyle bağlantıya geçin veya bu depoyu silin.
+no_branch=Bu deponun hiç bir dalı yok.
code=Kod
code.desc=Kaynak koda, dosyalara, işlemelere ve dallara eriş.
@@ -1302,6 +1358,8 @@ editor.new_branch_name_desc=Yeni dal ismi…
editor.cancel=İptal
editor.filename_cannot_be_empty=Dosya adı boş olamaz.
editor.filename_is_invalid=Dosya adı geçersiz: "%s".
+editor.commit_email=İşleme e-postası
+editor.invalid_commit_email=İşleme e-postası hatalı.
editor.branch_does_not_exist=Bu depoda "%s" dalı yok.
editor.branch_already_exists=Bu depoda "%s" dalı zaten var.
editor.directory_is_a_file=Dizin adı "%s" zaten bu depoda bir dosya adı olarak kullanılmaktadır.
@@ -1350,6 +1408,7 @@ commits.signed_by_untrusted_user_unmatched=İşleyici ile eşleşmeyen güvenilm
commits.gpg_key_id=GPG Anahtar Kimliği
commits.ssh_key_fingerprint=SSH Anahtar Parmak İzi
commits.view_path=Geçmişte bu noktayı görüntüle
+commits.view_file_diff=Bu dosyanın bu işlemedeki değişikliklerini görüntüle
commit.operations=İşlemler
commit.revert=Geri Al
@@ -1410,6 +1469,8 @@ issues.filter_milestones=Kilometre Taşı Süzgeci
issues.filter_projects=Projeyi Süz
issues.filter_labels=Etiket Süzgeci
issues.filter_reviewers=Gözden Geçiren Süzgeci
+issues.filter_no_results=Sonuç yok
+issues.filter_no_results_placeholder=Arama filtrelerinizi ayarlamayı deneyin.
issues.new=Yeni Konu
issues.new.title_empty=Başlık boş olamaz
issues.new.labels=Etiketler
@@ -1427,6 +1488,7 @@ issues.new.clear_milestone=Kilometre Taşlarını Temizle
issues.new.assignees=Atananlar
issues.new.clear_assignees=Atamaları Temizle
issues.new.no_assignees=Atanan Kişi Yok
+issues.new.no_reviewers=Gözden geçiren yok
issues.new.blocked_user=Konu oluşturulamıyor, depo sahibi tarafından engellenmişsiniz.
issues.edit.already_changed=Konuya yapılan değişiklikler kaydedilemiyor. İçerik başka kullanıcı tarafından değiştirilmiş gözüküyor. Diğerlerinin değişikliklerinin üzerine yazmamak için lütfen sayfayı yenileyin ve tekrar düzenlemeye çalışın
issues.edit.blocked_user=İçerik düzenlenemiyor, gönderen veya depo sahibi tarafından engellenmişsiniz.
@@ -1483,6 +1545,7 @@ issues.filter_project=Proje
issues.filter_project_all=Tüm projeler
issues.filter_project_none=Proje yok
issues.filter_assignee=Atanan
+issues.filter_assignee_no_assignee=Hiç kimseye atanmamış
issues.filter_poster=Yazar
issues.filter_type=Tür
issues.filter_type.all_issues=Tüm konular
@@ -2029,6 +2092,7 @@ contributors.contribution_type.deletions=Silmeler
settings=Ayarlar
settings.desc=Ayarlar, deponun ayarlarını yönetebileceğiniz yerdir
settings.options=Depo
+settings.public_access=Herkese Açık Erişim
settings.collaboration=Katkıcılar
settings.collaboration.admin=Yönetici
settings.collaboration.write=Yazma
diff --git a/services/actions/context.go b/services/actions/context.go
index 8f686a688a..b6de429ccf 100644
--- a/services/actions/context.go
+++ b/services/actions/context.go
@@ -15,6 +15,7 @@ import (
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/util"
"github.com/nektos/act/pkg/model"
)
@@ -167,34 +168,34 @@ func mergeTwoOutputs(o1, o2 map[string]string) map[string]string {
func (g *GiteaContext) ToGitHubContext() *model.GithubContext {
return &model.GithubContext{
- Event: (*g)["event"].(map[string]any),
- EventPath: (*g)["event_path"].(string),
- Workflow: (*g)["workflow"].(string),
- RunID: (*g)["run_id"].(string),
- RunNumber: (*g)["run_number"].(string),
- Actor: (*g)["actor"].(string),
- Repository: (*g)["repository"].(string),
- EventName: (*g)["event_name"].(string),
- Sha: (*g)["sha"].(string),
- Ref: (*g)["ref"].(string),
- RefName: (*g)["ref_name"].(string),
- RefType: (*g)["ref_type"].(string),
- HeadRef: (*g)["head_ref"].(string),
- BaseRef: (*g)["base_ref"].(string),
+ Event: util.GetMapValueOrDefault(*g, "event", map[string]any(nil)),
+ EventPath: util.GetMapValueOrDefault(*g, "event_path", ""),
+ Workflow: util.GetMapValueOrDefault(*g, "workflow", ""),
+ RunID: util.GetMapValueOrDefault(*g, "run_id", ""),
+ RunNumber: util.GetMapValueOrDefault(*g, "run_number", ""),
+ Actor: util.GetMapValueOrDefault(*g, "actor", ""),
+ Repository: util.GetMapValueOrDefault(*g, "repository", ""),
+ EventName: util.GetMapValueOrDefault(*g, "event_name", ""),
+ Sha: util.GetMapValueOrDefault(*g, "sha", ""),
+ Ref: util.GetMapValueOrDefault(*g, "ref", ""),
+ RefName: util.GetMapValueOrDefault(*g, "ref_name", ""),
+ RefType: util.GetMapValueOrDefault(*g, "ref_type", ""),
+ HeadRef: util.GetMapValueOrDefault(*g, "head_ref", ""),
+ BaseRef: util.GetMapValueOrDefault(*g, "base_ref", ""),
Token: "", // deliberately omitted for security
- Workspace: (*g)["workspace"].(string),
- Action: (*g)["action"].(string),
- ActionPath: (*g)["action_path"].(string),
- ActionRef: (*g)["action_ref"].(string),
- ActionRepository: (*g)["action_repository"].(string),
- Job: (*g)["job"].(string),
+ Workspace: util.GetMapValueOrDefault(*g, "workspace", ""),
+ Action: util.GetMapValueOrDefault(*g, "action", ""),
+ ActionPath: util.GetMapValueOrDefault(*g, "action_path", ""),
+ ActionRef: util.GetMapValueOrDefault(*g, "action_ref", ""),
+ ActionRepository: util.GetMapValueOrDefault(*g, "action_repository", ""),
+ Job: util.GetMapValueOrDefault(*g, "job", ""),
JobName: "", // not present in GiteaContext
- RepositoryOwner: (*g)["repository_owner"].(string),
- RetentionDays: (*g)["retention_days"].(string),
+ RepositoryOwner: util.GetMapValueOrDefault(*g, "repository_owner", ""),
+ RetentionDays: util.GetMapValueOrDefault(*g, "retention_days", ""),
RunnerPerflog: "", // not present in GiteaContext
RunnerTrackingID: "", // not present in GiteaContext
- ServerURL: (*g)["server_url"].(string),
- APIURL: (*g)["api_url"].(string),
- GraphQLURL: (*g)["graphql_url"].(string),
+ ServerURL: util.GetMapValueOrDefault(*g, "server_url", ""),
+ APIURL: util.GetMapValueOrDefault(*g, "api_url", ""),
+ GraphQLURL: util.GetMapValueOrDefault(*g, "graphql_url", ""),
}
}
diff --git a/services/context/repo.go b/services/context/repo.go
index ea772c508d..61841aa90b 100644
--- a/services/context/repo.go
+++ b/services/context/repo.go
@@ -936,6 +936,15 @@ func RepoRefByType(detectRefType git.RefType) func(*Context) {
ctx.ServerError("GetCommitsCount", err)
return
}
+ if ctx.Repo.RefFullName.IsTag() {
+ rel, err := repo_model.GetRelease(ctx, ctx.Repo.Repository.ID, ctx.Repo.RefFullName.TagName())
+ if err == nil && rel.NumCommits <= 0 {
+ rel.NumCommits = ctx.Repo.CommitsCount
+ if err := repo_model.UpdateReleaseNumCommits(ctx, rel); err != nil {
+ log.Error("UpdateReleaseNumCommits", err)
+ }
+ }
+ }
ctx.Data["CommitsCount"] = ctx.Repo.CommitsCount
ctx.Repo.GitRepo.LastCommitCache = git.NewLastCommitCache(ctx.Repo.CommitsCount, ctx.Repo.Repository.FullName(), ctx.Repo.GitRepo, cache.GetCache())
}
diff --git a/services/repository/migrate.go b/services/repository/migrate.go
index 003be1a9ab..0859158b89 100644
--- a/services/repository/migrate.go
+++ b/services/repository/migrate.go
@@ -149,9 +149,9 @@ func MigrateRepositoryGitData(ctx context.Context, u *user_model.User,
return repo, fmt.Errorf("SyncRepoBranchesWithRepo: %v", err)
}
+ // if releases migration are not requested, we will sync all tags here
+ // otherwise, the releases sync will be done out of this function
if !opts.Releases {
- // note: this will greatly improve release (tag) sync
- // for pull-mirrors with many tags
repo.IsMirror = opts.Mirror
if err = repo_module.SyncReleasesWithTags(ctx, repo, gitRepo); err != nil {
log.Error("Failed to synchronize tags to releases for repository: %v", err)
diff --git a/services/repository/push.go b/services/repository/push.go
index 31794034ba..3735c5f3a4 100644
--- a/services/repository/push.go
+++ b/services/repository/push.go
@@ -344,7 +344,7 @@ func pushDeleteBranch(ctx context.Context, repo *repo_model.Repository, pusher *
// PushUpdateAddDeleteTags updates a number of added and delete tags
func PushUpdateAddDeleteTags(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, addTags, delTags []string) error {
return db.WithTx(ctx, func(ctx context.Context) error {
- if err := repo_model.PushUpdateDeleteTagsContext(ctx, repo, delTags); err != nil {
+ if err := repo_model.PushUpdateDeleteTags(ctx, repo, delTags); err != nil {
return err
}
return pushUpdateAddTags(ctx, repo, gitRepo, addTags)
@@ -415,11 +415,6 @@ func pushUpdateAddTags(ctx context.Context, repo *repo_model.Repository, gitRepo
createdAt = sig.When
}
- commitsCount, err := commit.CommitsCount()
- if err != nil {
- return fmt.Errorf("CommitsCount: %w", err)
- }
-
rel, has := relMap[lowerTag]
parts := strings.SplitN(tag.Message, "\n", 2)
@@ -435,7 +430,7 @@ func pushUpdateAddTags(ctx context.Context, repo *repo_model.Repository, gitRepo
LowerTagName: lowerTag,
Target: "",
Sha1: commit.ID.String(),
- NumCommits: commitsCount,
+ NumCommits: -1, // the commits count will be updated when the UI needs it
Note: note,
IsDraft: false,
IsPrerelease: false,
@@ -450,7 +445,6 @@ func pushUpdateAddTags(ctx context.Context, repo *repo_model.Repository, gitRepo
} else {
rel.Sha1 = commit.ID.String()
rel.CreatedUnix = timeutil.TimeStamp(createdAt.Unix())
- rel.NumCommits = commitsCount
if rel.IsTag {
rel.Title = parts[0]
rel.Note = note
diff --git a/templates/repo/release/list.tmpl b/templates/repo/release/list.tmpl
index 01ec0ff188..1a7d911acb 100644
--- a/templates/repo/release/list.tmpl
+++ b/templates/repo/release/list.tmpl
@@ -61,7 +61,7 @@
{{if $release.CreatedUnix}}
{{DateUtils.TimeSince $release.CreatedUnix}}
{{end}}
- {{if and (not $release.IsDraft) ($.Permission.CanRead ctx.Consts.RepoUnitTypeCode)}}
+ {{if and (gt $release.NumCommits 0) (not $release.IsDraft) ($.Permission.CanRead ctx.Consts.RepoUnitTypeCode)}}
| {{ctx.Locale.Tr "repo.release.ahead.commits" $release.NumCommitsBehind}} {{ctx.Locale.Tr "repo.release.ahead.target" $release.TargetBehind}}
{{end}}