From 741b53eb30e8e0ebdcff6bfb157cf61aa7691b8a Mon Sep 17 00:00:00 2001
From: Kerwin Bryant
Date: Tue, 1 Apr 2025 02:39:08 +0800
Subject: [PATCH 01/62] [Fix] Resolve the problem of commit_statuses not being
loaded at the top - right when switching files from the file tree (#34079)
Co-authored-by: wxiaoguang
---
templates/repo/commit_statuses.tmpl | 4 ++--
tests/integration/repo_commits_test.go | 4 ++--
web_src/js/features/repo-commit.ts | 16 ++++++++--------
3 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/templates/repo/commit_statuses.tmpl b/templates/repo/commit_statuses.tmpl
index a6f75584a3..1bbfb33105 100644
--- a/templates/repo/commit_statuses.tmpl
+++ b/templates/repo/commit_statuses.tmpl
@@ -1,10 +1,10 @@
{{if .Statuses}}
{{if and (eq (len .Statuses) 1) .Status.TargetURL}}
-
+
{{template "repo/commit_status" .Status}}
{{else}}
-
+
{{template "repo/commit_status" .Status}}
{{end}}
diff --git a/tests/integration/repo_commits_test.go b/tests/integration/repo_commits_test.go
index 139f08075c..dee0aa6176 100644
--- a/tests/integration/repo_commits_test.go
+++ b/tests/integration/repo_commits_test.go
@@ -240,7 +240,7 @@ func TestRepoCommitsStatusMultiple(t *testing.T) {
resp = session.MakeRequest(t, req, http.StatusOK)
doc = NewHTMLParser(t, resp.Body)
- // Check that the data-tippy="commit-statuses" (for trigger) and commit-status (svg) are present
- sel := doc.doc.Find("#commits-table .message [data-tippy=\"commit-statuses\"] .commit-status")
+ // Check that the data-global-init="initCommitStatuses" (for trigger) and commit-status (svg) are present
+ sel := doc.doc.Find(`#commits-table .message [data-global-init="initCommitStatuses"] .commit-status`)
assert.Equal(t, 1, sel.Length())
}
diff --git a/web_src/js/features/repo-commit.ts b/web_src/js/features/repo-commit.ts
index e6d1112778..98ec2328ec 100644
--- a/web_src/js/features/repo-commit.ts
+++ b/web_src/js/features/repo-commit.ts
@@ -1,6 +1,6 @@
import {createTippy} from '../modules/tippy.ts';
import {toggleElem} from '../utils/dom.ts';
-import {registerGlobalEventFunc} from '../modules/observer.ts';
+import {registerGlobalEventFunc, registerGlobalInitFunc} from '../modules/observer.ts';
export function initRepoEllipsisButton() {
registerGlobalEventFunc('click', 'onRepoEllipsisButtonClick', async (el: HTMLInputElement, e: Event) => {
@@ -12,15 +12,15 @@ export function initRepoEllipsisButton() {
}
export function initCommitStatuses() {
- for (const element of document.querySelectorAll('[data-tippy="commit-statuses"]')) {
- const top = document.querySelector('.repository.file.list') || document.querySelector('.repository.diff');
-
- createTippy(element, {
- content: element.nextElementSibling,
- placement: top ? 'top-start' : 'bottom-start',
+ registerGlobalInitFunc('initCommitStatuses', (el: HTMLElement) => {
+ const nextEl = el.nextElementSibling;
+ if (!nextEl.matches('.tippy-target')) throw new Error('Expected next element to be a tippy target');
+ createTippy(el, {
+ content: nextEl,
+ placement: 'bottom-start',
interactive: true,
role: 'dialog',
theme: 'box-with-header',
});
- }
+ });
}
From 342432e52a13c37575cf443286ba1d01bdd67cce Mon Sep 17 00:00:00 2001
From: Simon Priet <105607989+SimonPistache@users.noreply.github.com>
Date: Mon, 31 Mar 2025 21:11:15 +0200
Subject: [PATCH 02/62] fix(#34076):replace assgniee translation key (#34077)
Fix the typo on the `filter_assginee_no_assigne` key used in
translations.
The typo itself doesn't produce a bug (as it's there both on the code
and on the locales)
Side Note: Github UI is not the best to bulk change this :/ Squashing
commits on the PR should be adequate.
Closes #34076 .
---------
Co-authored-by: Lunny Xiao
---
options/locale/locale_en-US.ini | 2 +-
templates/projects/view.tmpl | 2 +-
templates/repo/issue/filter_list.tmpl | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index 8ce469359c..91bfdefb4b 100644
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -1551,7 +1551,7 @@ issues.filter_project = Project
issues.filter_project_all = All projects
issues.filter_project_none = No project
issues.filter_assignee = Assignee
-issues.filter_assginee_no_assignee = Assigned to nobody
+issues.filter_assignee_no_assignee = Assigned to nobody
issues.filter_assignee_any_assignee = Assigned to anybody
issues.filter_poster = Author
issues.filter_user_placeholder = Search users
diff --git a/templates/projects/view.tmpl b/templates/projects/view.tmpl
index 79925e69cc..d6a335ef4b 100644
--- a/templates/projects/view.tmpl
+++ b/templates/projects/view.tmpl
@@ -13,7 +13,7 @@
"UserSearchList" $.Assignees
"SelectedUserId" $.AssigneeID
"TextFilterTitle" (ctx.Locale.Tr "repo.issues.filter_assignee")
- "TextFilterMatchNone" (ctx.Locale.Tr "repo.issues.filter_assginee_no_assignee")
+ "TextFilterMatchNone" (ctx.Locale.Tr "repo.issues.filter_assignee_no_assignee")
"TextFilterMatchAny" (ctx.Locale.Tr "repo.issues.filter_assignee_any_assignee")
}}
diff --git a/templates/repo/issue/filter_list.tmpl b/templates/repo/issue/filter_list.tmpl
index 58ca4a7c00..cd04f1c317 100644
--- a/templates/repo/issue/filter_list.tmpl
+++ b/templates/repo/issue/filter_list.tmpl
@@ -94,7 +94,7 @@
"UserSearchList" $.Assignees
"SelectedUserId" $.AssigneeID
"TextFilterTitle" (ctx.Locale.Tr "repo.issues.filter_assignee")
- "TextFilterMatchNone" (ctx.Locale.Tr "repo.issues.filter_assginee_no_assignee")
+ "TextFilterMatchNone" (ctx.Locale.Tr "repo.issues.filter_assignee_no_assignee")
"TextFilterMatchAny" (ctx.Locale.Tr "repo.issues.filter_assignee_any_assignee")
}}
From a2e8a289b2dbd7d28aa91fbf67eee4439ad9d854 Mon Sep 17 00:00:00 2001
From: Lunny Xiao
Date: Mon, 31 Mar 2025 12:54:31 -0700
Subject: [PATCH 03/62] Improve pull request list api (#34052)
The pull request list API is slow, for every pull request, it needs to
open a git repository. Assume it has 30 records, there will be 30 sub
processes back because every repository will open a git cat-file --batch
sub process. This PR use base git repository to get the head commit id
rather than read it from head repository to avoid open any head git
repository.
---
models/git/branch.go | 12 ++++++
services/convert/pull.go | 83 +++++++++++++---------------------------
2 files changed, 39 insertions(+), 56 deletions(-)
diff --git a/models/git/branch.go b/models/git/branch.go
index d1caa35947..9ac6c45578 100644
--- a/models/git/branch.go
+++ b/models/git/branch.go
@@ -173,6 +173,18 @@ func GetBranch(ctx context.Context, repoID int64, branchName string) (*Branch, e
return &branch, nil
}
+// IsBranchExist returns true if the branch exists in the repository.
+func IsBranchExist(ctx context.Context, repoID int64, branchName string) (bool, error) {
+ var branch Branch
+ has, err := db.GetEngine(ctx).Where("repo_id=?", repoID).And("name=?", branchName).Get(&branch)
+ if err != nil {
+ return false, err
+ } else if !has {
+ return false, nil
+ }
+ return !branch.IsDeleted, nil
+}
+
func GetBranches(ctx context.Context, repoID int64, branchNames []string, includeDeleted bool) ([]*Branch, error) {
branches := make([]*Branch, 0, len(branchNames))
diff --git a/services/convert/pull.go b/services/convert/pull.go
index 928534ce5e..c22b5282c8 100644
--- a/services/convert/pull.go
+++ b/services/convert/pull.go
@@ -389,7 +389,7 @@ func ToAPIPullRequests(ctx context.Context, baseRepo *repo_model.Repository, prs
},
Head: &api.PRBranchInfo{
Name: pr.HeadBranch,
- Ref: fmt.Sprintf("%s%d/head", git.PullPrefix, pr.Index),
+ Ref: pr.GetGitRefName(),
RepoID: -1,
},
}
@@ -422,72 +422,43 @@ func ToAPIPullRequests(ctx context.Context, baseRepo *repo_model.Repository, prs
return nil, err
}
}
-
if baseBranch != nil {
apiPullRequest.Base.Sha = baseBranch.CommitID
}
- if pr.Flow == issues_model.PullRequestFlowAGit {
- apiPullRequest.Head.Sha, err = gitRepo.GetRefCommitID(pr.GetGitRefName())
+ // pull request head branch, both repository and branch could not exist
+ if pr.HeadRepo != nil {
+ apiPullRequest.Head.RepoID = pr.HeadRepo.ID
+ exist, err := git_model.IsBranchExist(ctx, pr.HeadRepo.ID, pr.HeadBranch)
if err != nil {
- log.Error("GetRefCommitID[%s]: %v", pr.GetGitRefName(), err)
+ log.Error("IsBranchExist[%d]: %v", pr.HeadRepo.ID, err)
return nil, err
}
- apiPullRequest.Head.RepoID = pr.BaseRepoID
- apiPullRequest.Head.Repository = apiPullRequest.Base.Repository
- apiPullRequest.Head.Name = ""
+ if exist {
+ apiPullRequest.Head.Ref = pr.HeadBranch
+ }
+ }
+ if apiPullRequest.Head.Ref == "" {
+ apiPullRequest.Head.Ref = pr.GetGitRefName()
}
- var headGitRepo *git.Repository
- if pr.HeadRepo != nil && pr.Flow == issues_model.PullRequestFlowGithub {
- if pr.HeadRepoID == pr.BaseRepoID {
- apiPullRequest.Head.RepoID = pr.HeadRepo.ID
- apiPullRequest.Head.Repository = apiRepo
- headGitRepo = gitRepo
- } else {
- p, err := access_model.GetUserRepoPermission(ctx, pr.HeadRepo, doer)
- if err != nil {
- log.Error("GetUserRepoPermission[%d]: %v", pr.HeadRepoID, err)
- p.AccessMode = perm.AccessModeNone
- }
-
- apiPullRequest.Head.RepoID = pr.HeadRepo.ID
- apiPullRequest.Head.Repository = ToRepo(ctx, pr.HeadRepo, p)
-
- headGitRepo, err = gitrepo.OpenRepository(ctx, pr.HeadRepo)
- if err != nil {
- log.Error("OpenRepository[%s]: %v", pr.HeadRepo.RepoPath(), err)
- return nil, err
- }
- defer headGitRepo.Close()
+ if pr.HeadRepoID == pr.BaseRepoID {
+ apiPullRequest.Head.Repository = apiPullRequest.Base.Repository
+ } else {
+ p, err := access_model.GetUserRepoPermission(ctx, pr.HeadRepo, doer)
+ if err != nil {
+ log.Error("GetUserRepoPermission[%d]: %v", pr.HeadRepoID, err)
+ p.AccessMode = perm.AccessModeNone
}
+ apiPullRequest.Head.Repository = ToRepo(ctx, pr.HeadRepo, p)
+ }
- headBranch, err := headGitRepo.GetBranch(pr.HeadBranch)
- if err != nil && !git.IsErrBranchNotExist(err) {
- log.Error("GetBranch[%s]: %v", pr.HeadBranch, err)
- return nil, err
- }
-
- if git.IsErrBranchNotExist(err) {
- headCommitID, err := headGitRepo.GetRefCommitID(apiPullRequest.Head.Ref)
- if err != nil && !git.IsErrNotExist(err) {
- log.Error("GetCommit[%s]: %v", pr.HeadBranch, err)
- return nil, err
- }
- if err == nil {
- apiPullRequest.Head.Sha = headCommitID
- }
- } else {
- commit, err := headBranch.GetCommit()
- if err != nil && !git.IsErrNotExist(err) {
- log.Error("GetCommit[%s]: %v", headBranch.Name, err)
- return nil, err
- }
- if err == nil {
- apiPullRequest.Head.Ref = pr.HeadBranch
- apiPullRequest.Head.Sha = commit.ID.String()
- }
- }
+ if pr.Flow == issues_model.PullRequestFlowAGit {
+ apiPullRequest.Head.Name = ""
+ }
+ apiPullRequest.Head.Sha, err = gitRepo.GetRefCommitID(pr.GetGitRefName())
+ if err != nil {
+ log.Error("GetRefCommitID[%s]: %v", pr.GetGitRefName(), err)
}
if len(apiPullRequest.Head.Sha) == 0 && len(apiPullRequest.Head.Ref) != 0 {
From 4d2323183d05f73c00f9f3be3171b3f755f551c4 Mon Sep 17 00:00:00 2001
From: TheFox0x7
Date: Mon, 31 Mar 2025 22:19:32 +0200
Subject: [PATCH 04/62] fix users being able bypass limits with repo transfers
(#34031)
prevent user from being able to transfer repo to user who cannot have
more repositories
---
models/fixtures/repo_transfer.yml | 8 ++++++
routers/api/v1/repo/transfer.go | 23 ++++++++-------
routers/web/repo/repo.go | 10 +++++--
routers/web/repo/setting/setting.go | 3 ++
services/repository/transfer.go | 22 +++++++++++++++
services/repository/transfer_test.go | 42 +++++++++++++++++++++++++++-
6 files changed, 92 insertions(+), 16 deletions(-)
diff --git a/models/fixtures/repo_transfer.yml b/models/fixtures/repo_transfer.yml
index db92c95248..b12e6b207f 100644
--- a/models/fixtures/repo_transfer.yml
+++ b/models/fixtures/repo_transfer.yml
@@ -21,3 +21,11 @@
repo_id: 32
created_unix: 1553610671
updated_unix: 1553610671
+
+-
+ id: 4
+ doer_id: 3
+ recipient_id: 1
+ repo_id: 5
+ created_unix: 1553610671
+ updated_unix: 1553610671
diff --git a/routers/api/v1/repo/transfer.go b/routers/api/v1/repo/transfer.go
index 7b890c9e5c..8643d0c2ca 100644
--- a/routers/api/v1/repo/transfer.go
+++ b/routers/api/v1/repo/transfer.go
@@ -108,22 +108,19 @@ func Transfer(ctx *context.APIContext) {
oldFullname := ctx.Repo.Repository.FullName()
if err := repo_service.StartRepositoryTransfer(ctx, ctx.Doer, newOwner, ctx.Repo.Repository, teams); err != nil {
- if repo_model.IsErrRepoTransferInProgress(err) {
+ switch {
+ case repo_model.IsErrRepoTransferInProgress(err):
ctx.APIError(http.StatusConflict, err)
- return
- }
-
- if repo_model.IsErrRepoAlreadyExist(err) {
+ case repo_model.IsErrRepoAlreadyExist(err):
ctx.APIError(http.StatusUnprocessableEntity, err)
+ case repo_service.IsRepositoryLimitReached(err):
+ ctx.APIError(http.StatusForbidden, err)
+ case errors.Is(err, user_model.ErrBlockedUser):
+ ctx.APIError(http.StatusForbidden, err)
+ default:
+ ctx.APIErrorInternal(err)
return
}
-
- if errors.Is(err, user_model.ErrBlockedUser) {
- ctx.APIError(http.StatusForbidden, err)
- } else {
- ctx.APIErrorInternal(err)
- }
- return
}
if ctx.Repo.Repository.Status == repo_model.RepositoryPendingTransfer {
@@ -169,6 +166,8 @@ func AcceptTransfer(ctx *context.APIContext) {
ctx.APIError(http.StatusNotFound, err)
case errors.Is(err, util.ErrPermissionDenied):
ctx.APIError(http.StatusForbidden, err)
+ case repo_service.IsRepositoryLimitReached(err):
+ ctx.APIError(http.StatusForbidden, err)
default:
ctx.APIErrorInternal(err)
}
diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go
index 54b7448a89..e260ea36dd 100644
--- a/routers/web/repo/repo.go
+++ b/routers/web/repo/repo.go
@@ -305,11 +305,15 @@ func CreatePost(ctx *context.Context) {
}
func handleActionError(ctx *context.Context, err error) {
- if errors.Is(err, user_model.ErrBlockedUser) {
+ switch {
+ case errors.Is(err, user_model.ErrBlockedUser):
ctx.Flash.Error(ctx.Tr("repo.action.blocked_user"))
- } else if errors.Is(err, util.ErrPermissionDenied) {
+ case repo_service.IsRepositoryLimitReached(err):
+ limit := err.(repo_service.LimitReachedError).Limit
+ ctx.Flash.Error(ctx.TrN(limit, "repo.form.reach_limit_of_creation_1", "repo.form.reach_limit_of_creation_n", limit))
+ case errors.Is(err, util.ErrPermissionDenied):
ctx.HTTPError(http.StatusNotFound)
- } else {
+ default:
ctx.ServerError(fmt.Sprintf("Action (%s)", ctx.PathParam("action")), err)
}
}
diff --git a/routers/web/repo/setting/setting.go b/routers/web/repo/setting/setting.go
index a0edb1e11a..e30986e86e 100644
--- a/routers/web/repo/setting/setting.go
+++ b/routers/web/repo/setting/setting.go
@@ -848,6 +848,9 @@ func handleSettingsPostTransfer(ctx *context.Context) {
ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), tplSettingsOptions, nil)
} else if repo_model.IsErrRepoTransferInProgress(err) {
ctx.RenderWithErr(ctx.Tr("repo.settings.transfer_in_progress"), tplSettingsOptions, nil)
+ } else if repo_service.IsRepositoryLimitReached(err) {
+ limit := err.(repo_service.LimitReachedError).Limit
+ ctx.RenderWithErr(ctx.TrN(limit, "repo.form.reach_limit_of_creation_1", "repo.form.reach_limit_of_creation_n", limit), tplSettingsOptions, nil)
} else if errors.Is(err, user_model.ErrBlockedUser) {
ctx.RenderWithErr(ctx.Tr("repo.settings.transfer.blocked_user"), tplSettingsOptions, nil)
} else {
diff --git a/services/repository/transfer.go b/services/repository/transfer.go
index a589bc469d..4e44b90df2 100644
--- a/services/repository/transfer.go
+++ b/services/repository/transfer.go
@@ -20,10 +20,22 @@ import (
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/globallock"
"code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
notify_service "code.gitea.io/gitea/services/notify"
)
+type LimitReachedError struct{ Limit int }
+
+func (LimitReachedError) Error() string {
+ return "Repository limit has been reached"
+}
+
+func IsRepositoryLimitReached(err error) bool {
+ _, ok := err.(LimitReachedError)
+ return ok
+}
+
func getRepoWorkingLockKey(repoID int64) string {
return fmt.Sprintf("repo_working_%d", repoID)
}
@@ -49,6 +61,11 @@ func AcceptTransferOwnership(ctx context.Context, repo *repo_model.Repository, d
return err
}
+ if !doer.IsAdmin && !repoTransfer.Recipient.CanCreateRepo() {
+ limit := util.Iif(repoTransfer.Recipient.MaxRepoCreation >= 0, repoTransfer.Recipient.MaxRepoCreation, setting.Repository.MaxCreationLimit)
+ return LimitReachedError{Limit: limit}
+ }
+
if !repoTransfer.CanUserAcceptOrRejectTransfer(ctx, doer) {
return util.ErrPermissionDenied
}
@@ -399,6 +416,11 @@ func StartRepositoryTransfer(ctx context.Context, doer, newOwner *user_model.Use
return err
}
+ if !doer.IsAdmin && !newOwner.CanCreateRepo() {
+ limit := util.Iif(newOwner.MaxRepoCreation >= 0, newOwner.MaxRepoCreation, setting.Repository.MaxCreationLimit)
+ return LimitReachedError{Limit: limit}
+ }
+
var isDirectTransfer bool
oldOwnerName := repo.OwnerName
diff --git a/services/repository/transfer_test.go b/services/repository/transfer_test.go
index 16a8fb6e1e..bf71c7ca2e 100644
--- a/services/repository/transfer_test.go
+++ b/services/repository/transfer_test.go
@@ -1,4 +1,4 @@
-// Copyright 2019 The Gitea Authors. All rights reserved.
+// Copyright 2025 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package repository
@@ -14,11 +14,14 @@ import (
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/test"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/services/feed"
notify_service "code.gitea.io/gitea/services/notify"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
var notifySync sync.Once
@@ -125,3 +128,40 @@ func TestRepositoryTransfer(t *testing.T) {
err = RejectRepositoryTransfer(db.DefaultContext, repo2, doer)
assert.True(t, repo_model.IsErrNoPendingTransfer(err))
}
+
+// Test transfer rejections
+func TestRepositoryTransferRejection(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+ // Set limit to 0 repositories so no repositories can be transferred
+ defer test.MockVariableValue(&setting.Repository.MaxCreationLimit, 0)()
+
+ // Admin case
+ doerAdmin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 5})
+
+ transfer, err := repo_model.GetPendingRepositoryTransfer(db.DefaultContext, repo)
+ require.NoError(t, err)
+ require.NotNil(t, transfer)
+ require.NoError(t, transfer.LoadRecipient(db.DefaultContext))
+
+ require.True(t, transfer.Recipient.CanCreateRepo()) // admin is not subject to limits
+
+ // Administrator should not be affected by the limits so transfer should be successful
+ assert.NoError(t, AcceptTransferOwnership(db.DefaultContext, repo, doerAdmin))
+
+ // Non admin user case
+ doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 10})
+ repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 21})
+
+ transfer, err = repo_model.GetPendingRepositoryTransfer(db.DefaultContext, repo)
+ require.NoError(t, err)
+ require.NotNil(t, transfer)
+ require.NoError(t, transfer.LoadRecipient(db.DefaultContext))
+
+ require.False(t, transfer.Recipient.CanCreateRepo()) // regular user is subject to limits
+
+ // Cannot accept because of the limit
+ err = AcceptTransferOwnership(db.DefaultContext, repo, doer)
+ assert.Error(t, err)
+ assert.True(t, IsRepositoryLimitReached(err))
+}
From d54418a7d3611465332d4b86ed3bd5579bda3766 Mon Sep 17 00:00:00 2001
From: GiteaBot
Date: Tue, 1 Apr 2025 00:39:56 +0000
Subject: [PATCH 05/62] [skip ci] Updated translations via Crowdin
---
options/locale/locale_cs-CZ.ini | 1 -
options/locale/locale_de-DE.ini | 1 -
options/locale/locale_el-GR.ini | 1 -
options/locale/locale_es-ES.ini | 1 -
options/locale/locale_fa-IR.ini | 1 -
options/locale/locale_ga-IE.ini | 11 ++++++++++-
options/locale/locale_it-IT.ini | 1 -
options/locale/locale_ja-JP.ini | 1 -
options/locale/locale_ko-KR.ini | 1 -
options/locale/locale_lv-LV.ini | 1 -
options/locale/locale_nl-NL.ini | 1 -
options/locale/locale_pl-PL.ini | 1 -
options/locale/locale_pt-PT.ini | 1 -
options/locale/locale_ru-RU.ini | 1 -
options/locale/locale_si-LK.ini | 1 -
options/locale/locale_sv-SE.ini | 1 -
options/locale/locale_tr-TR.ini | 1 -
options/locale/locale_uk-UA.ini | 1 -
options/locale/locale_zh-HK.ini | 1 -
19 files changed, 10 insertions(+), 19 deletions(-)
diff --git a/options/locale/locale_cs-CZ.ini b/options/locale/locale_cs-CZ.ini
index a021837002..efbfef984f 100644
--- a/options/locale/locale_cs-CZ.ini
+++ b/options/locale/locale_cs-CZ.ini
@@ -1529,7 +1529,6 @@ issues.filter_project=Projekt
issues.filter_project_all=Všechny projekty
issues.filter_project_none=Žádný projekt
issues.filter_assignee=Zpracovatel
-issues.filter_assginee_no_assignee=Bez zpracovatele
issues.filter_poster=Autor
issues.filter_user_placeholder=Hledat uživatele
issues.filter_user_no_select=Všichni uživatelé
diff --git a/options/locale/locale_de-DE.ini b/options/locale/locale_de-DE.ini
index 0b0544b89c..1840cd312d 100644
--- a/options/locale/locale_de-DE.ini
+++ b/options/locale/locale_de-DE.ini
@@ -1530,7 +1530,6 @@ issues.filter_project=Projekt
issues.filter_project_all=Alle Projekte
issues.filter_project_none=Kein Projekt
issues.filter_assignee=Zuständig
-issues.filter_assginee_no_assignee=Niemand zuständig
issues.filter_poster=Autor
issues.filter_user_placeholder=Benutzer suchen
issues.filter_user_no_select=Alle Benutzer
diff --git a/options/locale/locale_el-GR.ini b/options/locale/locale_el-GR.ini
index f430c0506c..960e3b1581 100644
--- a/options/locale/locale_el-GR.ini
+++ b/options/locale/locale_el-GR.ini
@@ -1377,7 +1377,6 @@ issues.filter_project=Έργο
issues.filter_project_all=Όλα τα έργα
issues.filter_project_none=Χωρίς έργα
issues.filter_assignee=Αποδέκτης
-issues.filter_assginee_no_assignee=Κανένας Αποδέκτης
issues.filter_poster=Συγγραφέας
issues.filter_type=Τύπος
issues.filter_type.all_issues=Όλα τα ζητήματα
diff --git a/options/locale/locale_es-ES.ini b/options/locale/locale_es-ES.ini
index debf9a6f5d..280c735c79 100644
--- a/options/locale/locale_es-ES.ini
+++ b/options/locale/locale_es-ES.ini
@@ -1367,7 +1367,6 @@ issues.filter_project=Proyecto
issues.filter_project_all=Todos los proyectos
issues.filter_project_none=Ningún proyecto
issues.filter_assignee=Asignada a
-issues.filter_assginee_no_assignee=Sin asignado
issues.filter_poster=Autor
issues.filter_type=Tipo
issues.filter_type.all_issues=Todas las incidencias
diff --git a/options/locale/locale_fa-IR.ini b/options/locale/locale_fa-IR.ini
index 5c96cea8f6..c7bef6e6dc 100644
--- a/options/locale/locale_fa-IR.ini
+++ b/options/locale/locale_fa-IR.ini
@@ -1059,7 +1059,6 @@ issues.filter_label_no_select=تمامی برچسبها
issues.filter_milestone=نقطه عطف
issues.filter_project_none=هیچ پروژه ثبت نشده
issues.filter_assignee=مسئول رسیدگی
-issues.filter_assginee_no_assignee=بدون مسئول رسیدگی
issues.filter_type=نوع
issues.filter_type.all_issues=همه مسائل
issues.filter_type.assigned_to_you=به شما محول شده
diff --git a/options/locale/locale_ga-IE.ini b/options/locale/locale_ga-IE.ini
index bb2bf6f15f..a63c097cd0 100644
--- a/options/locale/locale_ga-IE.ini
+++ b/options/locale/locale_ga-IE.ini
@@ -926,6 +926,9 @@ permission_not_set=Níl leagtha
permission_no_access=Gan rochtain
permission_read=Léigh
permission_write=Léigh agus Scríobh
+permission_anonymous_read=Léamh gan Ainm
+permission_everyone_read=Léigh gach duine
+permission_everyone_write=Scríobh gach duine
access_token_desc=Ní chuireann ceadchomharthaí roghnaithe ach teorainn leis an údarú do na bealaí API comhfhreagracha. Léigh doiciméadúchán chun tuilleadh eolais a fháil.
at_least_one_permission=Ní mór duit cead amháin ar a laghad a roghnú chun comhartha a chruthú
permissions_list=Ceadanna:
@@ -1138,6 +1141,7 @@ transfer.no_permission_to_reject=Níl cead agat an aistriú seo a dhiúltú.
desc.private=Príobháideach
desc.public=Poiblí
+desc.public_access=Rochtain Phoiblí
desc.template=Teimpléad
desc.internal=Inmheánach
desc.archived=Cartlannaithe
@@ -1546,7 +1550,6 @@ issues.filter_project=Tionscadal
issues.filter_project_all=Gach tionscadal
issues.filter_project_none=Gan aon tionscadal
issues.filter_assignee=Sannaitheoir
-issues.filter_assginee_no_assignee=Sannta do dhuine ar bith
issues.filter_assignee_any_assignee=Sannta do dhuine ar bith
issues.filter_poster=Údar
issues.filter_user_placeholder=Cuardaigh úsáideoirí
@@ -2132,6 +2135,12 @@ contributors.contribution_type.deletions=Scriosadh
settings=Socruithe
settings.desc=Is é socruithe an áit ar féidir leat na socruithe don stóras a bhainistiú
settings.options=Stóras
+settings.public_access=Rochtain Phoiblí
+settings.public_access_desc=Cumraigh ceadanna rochtana an chuairteora phoiblí chun réamhshocruithe an stóras seo a shárú.
+settings.public_access.docs.not_set=Gan Socrú: níl cead rochtana poiblí breise ar bith. Leanann cead an chuairteora infheictheacht an stór agus ceadanna na mball.
+settings.public_access.docs.anonymous_read=Léamh gan Ainm: is féidir le húsáideoirí nach bhfuil logáilte isteach rochtain a fháil ar an aonad le cead léite.
+settings.public_access.docs.everyone_read=Léamh ag Gach Duine: is féidir le gach úsáideoir logáilte isteach rochtain a fháil ar an aonad le cead léite. Ciallaíonn cead léite na n-aonad eisiúna/iarrataí tarraingthe freisin gur féidir le húsáideoirí saincheisteanna nua/iarratais tarraingthe a chruthú.
+settings.public_access.docs.everyone_write=Scríobh Gach Duine: tá cead scríofa ag gach úsáideoir logáilte isteach don aonad. Ní thacaíonn ach aonad Vicí leis an gcead seo.
settings.collaboration=Comhoibritheoirí
settings.collaboration.admin=Riarthóir
settings.collaboration.write=Scríobh
diff --git a/options/locale/locale_it-IT.ini b/options/locale/locale_it-IT.ini
index 3ce5a6770f..810f1040f5 100644
--- a/options/locale/locale_it-IT.ini
+++ b/options/locale/locale_it-IT.ini
@@ -1143,7 +1143,6 @@ issues.filter_milestone=Traguardo
issues.filter_project=Progetto
issues.filter_project_none=Nessun progetto
issues.filter_assignee=Assegnatario
-issues.filter_assginee_no_assignee=Nessun assegnatario
issues.filter_poster=Autore
issues.filter_type=Tipo
issues.filter_type.all_issues=Tutti i problemi
diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini
index 7fe0f4332d..df987fa3b9 100644
--- a/options/locale/locale_ja-JP.ini
+++ b/options/locale/locale_ja-JP.ini
@@ -1546,7 +1546,6 @@ issues.filter_project=プロジェクト
issues.filter_project_all=すべてのプロジェクト
issues.filter_project_none=プロジェクトなし
issues.filter_assignee=担当者
-issues.filter_assginee_no_assignee=担当者なし
issues.filter_assignee_any_assignee=担当者あり
issues.filter_poster=作成者
issues.filter_user_placeholder=ユーザーを検索
diff --git a/options/locale/locale_ko-KR.ini b/options/locale/locale_ko-KR.ini
index 697371c2c9..ddb80dde1d 100644
--- a/options/locale/locale_ko-KR.ini
+++ b/options/locale/locale_ko-KR.ini
@@ -707,7 +707,6 @@ issues.filter_label=레이블
issues.filter_label_no_select=모든 레이블
issues.filter_milestone=마일스톤
issues.filter_assignee=담당자
-issues.filter_assginee_no_assignee=담당자 없음
issues.filter_type=유형
issues.filter_type.all_issues=모든 이슈
issues.filter_type.assigned_to_you=나에게 할당됨
diff --git a/options/locale/locale_lv-LV.ini b/options/locale/locale_lv-LV.ini
index 4439537fd7..42c12def23 100644
--- a/options/locale/locale_lv-LV.ini
+++ b/options/locale/locale_lv-LV.ini
@@ -1383,7 +1383,6 @@ issues.filter_project=Projekts
issues.filter_project_all=Visi projekti
issues.filter_project_none=Nav projekta
issues.filter_assignee=Atbildīgais
-issues.filter_assginee_no_assignee=Nav atbildīgā
issues.filter_poster=Autors
issues.filter_type=Veids
issues.filter_type.all_issues=Visas problēmas
diff --git a/options/locale/locale_nl-NL.ini b/options/locale/locale_nl-NL.ini
index 77bf2d2d59..0ad14807d6 100644
--- a/options/locale/locale_nl-NL.ini
+++ b/options/locale/locale_nl-NL.ini
@@ -1141,7 +1141,6 @@ issues.filter_milestone=Mijlpaal
issues.filter_project=Project
issues.filter_project_none=Geen project
issues.filter_assignee=Aangewezene
-issues.filter_assginee_no_assignee=Geen verantwoordelijke
issues.filter_poster=Auteur
issues.filter_type=Type
issues.filter_type.all_issues=Alle kwesties
diff --git a/options/locale/locale_pl-PL.ini b/options/locale/locale_pl-PL.ini
index f64b8771ac..9673db2a71 100644
--- a/options/locale/locale_pl-PL.ini
+++ b/options/locale/locale_pl-PL.ini
@@ -1054,7 +1054,6 @@ issues.filter_label_no_select=Wszystkie etykiety
issues.filter_milestone=Kamień milowy
issues.filter_project_none=Brak projektu
issues.filter_assignee=Przypisany
-issues.filter_assginee_no_assignee=Brak przypisania
issues.filter_type=Typ
issues.filter_type.all_issues=Wszystkie zgłoszenia
issues.filter_type.assigned_to_you=Przypisane do Ciebie
diff --git a/options/locale/locale_pt-PT.ini b/options/locale/locale_pt-PT.ini
index 0b0ddbee56..fdb7389b51 100644
--- a/options/locale/locale_pt-PT.ini
+++ b/options/locale/locale_pt-PT.ini
@@ -1550,7 +1550,6 @@ issues.filter_project=Planeamento
issues.filter_project_all=Todos os planeamentos
issues.filter_project_none=Nenhum planeamento
issues.filter_assignee=Encarregado
-issues.filter_assginee_no_assignee=Sem encarregado
issues.filter_assignee_any_assignee=Atribuído a qualquer pessoa
issues.filter_poster=Autor(a)
issues.filter_user_placeholder=Procurar utilizadores
diff --git a/options/locale/locale_ru-RU.ini b/options/locale/locale_ru-RU.ini
index fe52165837..68246ff751 100644
--- a/options/locale/locale_ru-RU.ini
+++ b/options/locale/locale_ru-RU.ini
@@ -1355,7 +1355,6 @@ issues.filter_project=Проект
issues.filter_project_all=Все проекты
issues.filter_project_none=Нет проекта
issues.filter_assignee=Назначено
-issues.filter_assginee_no_assignee=Нет ответственного
issues.filter_poster=Автор
issues.filter_type=Тип
issues.filter_type.all_issues=Все задачи
diff --git a/options/locale/locale_si-LK.ini b/options/locale/locale_si-LK.ini
index 2cd7fb29b9..7c95b254e8 100644
--- a/options/locale/locale_si-LK.ini
+++ b/options/locale/locale_si-LK.ini
@@ -1025,7 +1025,6 @@ issues.filter_label_no_select=සියලු ලේබල
issues.filter_milestone=සන්ධිස්ථානය
issues.filter_project_none=ව්යාපෘති නැත
issues.filter_assignee=අස්ගිනී
-issues.filter_assginee_no_assignee=කිසිදු අස්වැද්දුමක්
issues.filter_type=වර්ගය
issues.filter_type.all_issues=සියලු ගැටළු
issues.filter_type.assigned_to_you=ඔබට පවරා ඇත
diff --git a/options/locale/locale_sv-SE.ini b/options/locale/locale_sv-SE.ini
index dbe53aaadf..92917c103a 100644
--- a/options/locale/locale_sv-SE.ini
+++ b/options/locale/locale_sv-SE.ini
@@ -873,7 +873,6 @@ issues.filter_label_no_select=Alla etiketter
issues.filter_milestone=Milsten
issues.filter_project_none=Inget projekt
issues.filter_assignee=Förvärvare
-issues.filter_assginee_no_assignee=Ingen tilldelad
issues.filter_type=Typ
issues.filter_type.all_issues=Alla ärenden
issues.filter_type.assigned_to_you=Tilldelad dig
diff --git a/options/locale/locale_tr-TR.ini b/options/locale/locale_tr-TR.ini
index 1a044fca83..faf442431b 100644
--- a/options/locale/locale_tr-TR.ini
+++ b/options/locale/locale_tr-TR.ini
@@ -1484,7 +1484,6 @@ issues.filter_project=Proje
issues.filter_project_all=Tüm projeler
issues.filter_project_none=Proje yok
issues.filter_assignee=Atanan
-issues.filter_assginee_no_assignee=Atanan yok
issues.filter_poster=Yazar
issues.filter_type=Tür
issues.filter_type.all_issues=Tüm konular
diff --git a/options/locale/locale_uk-UA.ini b/options/locale/locale_uk-UA.ini
index 8c8911ceb6..995de50b61 100644
--- a/options/locale/locale_uk-UA.ini
+++ b/options/locale/locale_uk-UA.ini
@@ -1071,7 +1071,6 @@ issues.filter_milestone=Етап
issues.filter_project=Проєкт
issues.filter_project_none=Проєкт відсутній
issues.filter_assignee=Виконавець
-issues.filter_assginee_no_assignee=Немає виконавця
issues.filter_type=Тип
issues.filter_type.all_issues=Всі задачі
issues.filter_type.assigned_to_you=Призначене вам
diff --git a/options/locale/locale_zh-HK.ini b/options/locale/locale_zh-HK.ini
index b924faba09..ae6c6c3552 100644
--- a/options/locale/locale_zh-HK.ini
+++ b/options/locale/locale_zh-HK.ini
@@ -416,7 +416,6 @@ issues.delete_branch_at=`刪除分支 %s %s`
issues.filter_label=標籤篩選
issues.filter_milestone=里程碑篩選
issues.filter_assignee=指派人篩選
-issues.filter_assginee_no_assignee=無負責人
issues.filter_type=類型篩選
issues.filter_type.all_issues=所有問題
issues.filter_type.assigned_to_you=指派給您的
From 86c1a33369e0458748d30d0084d3199e7f736855 Mon Sep 17 00:00:00 2001
From: wxiaoguang
Date: Tue, 1 Apr 2025 15:02:30 +0800
Subject: [PATCH 06/62] Fix some UI bugs and clean up unused tests (#34088)
1. Make the material icon falls back to basic theme correctly
2. Remove `TestAttributeReader`, the problem has been resolved.
3. Fix `toggleElem` bug and add tests
---
modules/fileicon/material.go | 12 +++---
modules/git/repo_attribute_test.go | 60 ------------------------------
web_src/js/utils/dom.test.ts | 18 ++++++++-
web_src/js/utils/dom.ts | 2 +-
4 files changed, 23 insertions(+), 69 deletions(-)
diff --git a/modules/fileicon/material.go b/modules/fileicon/material.go
index aa31cd8d7c..cbdb962ee3 100644
--- a/modules/fileicon/material.go
+++ b/modules/fileicon/material.go
@@ -99,12 +99,9 @@ func (m *MaterialIconProvider) FileIcon(ctx reqctx.RequestContext, entry *git.Tr
}
name := m.findIconNameByGit(entry)
- if name == "folder" {
- // the material icon pack's "folder" icon doesn't look good, so use our built-in one
- // keep the old "octicon-xxx" class name to make some "theme plugin selector" could still work
- return svg.RenderHTML("material-folder-generic", 16, "octicon-file-directory-fill")
- }
- if iconSVG, ok := m.svgs[name]; ok && iconSVG != "" {
+ // the material icon pack's "folder" icon doesn't look good, so use our built-in one
+ // keep the old "octicon-xxx" class name to make some "theme plugin selector" could still work
+ if iconSVG, ok := m.svgs[name]; ok && name != "folder" && iconSVG != "" {
// keep the old "octicon-xxx" class name to make some "theme plugin selector" could still work
extraClass := "octicon-file"
switch {
@@ -115,7 +112,8 @@ func (m *MaterialIconProvider) FileIcon(ctx reqctx.RequestContext, entry *git.Tr
}
return m.renderFileIconSVG(ctx, name, iconSVG, extraClass)
}
- return svg.RenderHTML("octicon-file")
+ // TODO: use an interface or wrapper for git.Entry to make the code testable.
+ return BasicThemeIcon(entry)
}
func (m *MaterialIconProvider) findIconNameWithLangID(s string) string {
diff --git a/modules/git/repo_attribute_test.go b/modules/git/repo_attribute_test.go
index c4f5bac46d..d8fd9f0e8d 100644
--- a/modules/git/repo_attribute_test.go
+++ b/modules/git/repo_attribute_test.go
@@ -4,16 +4,10 @@
package git
import (
- "context"
- mathRand "math/rand/v2"
- "path/filepath"
- "slices"
- "sync"
"testing"
"time"
"github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
)
func Test_nulSeparatedAttributeWriter_ReadAttribute(t *testing.T) {
@@ -101,57 +95,3 @@ func Test_nulSeparatedAttributeWriter_ReadAttribute(t *testing.T) {
Value: "unspecified",
}, attr)
}
-
-func TestAttributeReader(t *testing.T) {
- t.Skip() // for debug purpose only, do not run in CI
-
- ctx := t.Context()
-
- timeout := 1 * time.Second
- repoPath := filepath.Join(testReposDir, "language_stats_repo")
- commitRef := "HEAD"
-
- oneRound := func(t *testing.T, roundIdx int) {
- ctx, cancel := context.WithTimeout(ctx, timeout)
- _ = cancel
- gitRepo, err := OpenRepository(ctx, repoPath)
- require.NoError(t, err)
- defer gitRepo.Close()
-
- commit, err := gitRepo.GetCommit(commitRef)
- require.NoError(t, err)
-
- files, err := gitRepo.LsFiles()
- require.NoError(t, err)
-
- randomFiles := slices.Clone(files)
- randomFiles = append(randomFiles, "any-file-1", "any-file-2")
-
- t.Logf("Round %v with %d files", roundIdx, len(randomFiles))
-
- attrReader, deferrable := gitRepo.CheckAttributeReader(commit.ID.String())
- defer deferrable()
-
- wg := sync.WaitGroup{}
- wg.Add(1)
-
- go func() {
- for {
- file := randomFiles[mathRand.IntN(len(randomFiles))]
- _, err := attrReader.CheckPath(file)
- if err != nil {
- for i := 0; i < 10; i++ {
- _, _ = attrReader.CheckPath(file)
- }
- break
- }
- }
- wg.Done()
- }()
- wg.Wait()
- }
-
- for i := 0; i < 100; i++ {
- oneRound(t, i)
- }
-}
diff --git a/web_src/js/utils/dom.test.ts b/web_src/js/utils/dom.test.ts
index 6e71596850..6a3af91556 100644
--- a/web_src/js/utils/dom.test.ts
+++ b/web_src/js/utils/dom.test.ts
@@ -1,4 +1,10 @@
-import {createElementFromAttrs, createElementFromHTML, queryElemChildren, querySingleVisibleElem} from './dom.ts';
+import {
+ createElementFromAttrs,
+ createElementFromHTML,
+ queryElemChildren,
+ querySingleVisibleElem,
+ toggleElem,
+} from './dom.ts';
test('createElementFromHTML', () => {
expect(createElementFromHTML('foobar').outerHTML).toEqual('foobar');
@@ -32,3 +38,13 @@ test('queryElemChildren', () => {
const children = queryElemChildren(el, '.a');
expect(children.length).toEqual(1);
});
+
+test('toggleElem', () => {
+ const el = createElementFromHTML('a
b
');
+ toggleElem(el.children);
+ expect(el.outerHTML).toEqual('a
b
');
+ toggleElem(el.children, false);
+ expect(el.outerHTML).toEqual('a
b
');
+ toggleElem(el.children, true);
+ expect(el.outerHTML).toEqual('a
b
');
+});
diff --git a/web_src/js/utils/dom.ts b/web_src/js/utils/dom.ts
index 6d38ffa8cd..b3debfde9e 100644
--- a/web_src/js/utils/dom.ts
+++ b/web_src/js/utils/dom.ts
@@ -44,7 +44,7 @@ export function toggleClass(el: ElementArg, className: string, force?: boolean)
* @param force force=true to show or force=false to hide, undefined to toggle
*/
export function toggleElem(el: ElementArg, force?: boolean) {
- toggleClass(el, 'tw-hidden', !force);
+ toggleClass(el, 'tw-hidden', force === undefined ? force : !force);
}
export function showElem(el: ElementArg) {
From 56e42be36dd6daf86073732188da43316ccad608 Mon Sep 17 00:00:00 2001
From: bytedream <63594396+bytedream@users.noreply.github.com>
Date: Tue, 1 Apr 2025 11:42:10 +0200
Subject: [PATCH 07/62] Add flat-square action badge style (#34062)
Adds the `flat-square` style to action badges. Styles can be selected by
adding `?style=${svg}