mirror of https://github.com/go-gitea/gitea
Merge branch 'main' into fix-package-performance-28255
This commit is contained in:
commit
4f7f08a5ed
|
@ -38,6 +38,8 @@ jobs:
|
|||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
cache: npm
|
||||
cache-dependency-path: package-lock.json
|
||||
- run: pip install poetry
|
||||
- run: make deps-py
|
||||
- run: make deps-frontend
|
||||
|
@ -65,6 +67,8 @@ jobs:
|
|||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
cache: npm
|
||||
cache-dependency-path: package-lock.json
|
||||
- run: make deps-frontend
|
||||
- run: make lint-swagger
|
||||
|
||||
|
@ -134,6 +138,8 @@ jobs:
|
|||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
cache: npm
|
||||
cache-dependency-path: package-lock.json
|
||||
- run: make deps-frontend
|
||||
- run: make lint-frontend
|
||||
- run: make checks-frontend
|
||||
|
@ -181,6 +187,8 @@ jobs:
|
|||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
cache: npm
|
||||
cache-dependency-path: package-lock.json
|
||||
- run: make deps-frontend
|
||||
- run: make lint-md
|
||||
- run: make docs
|
||||
|
|
|
@ -24,6 +24,8 @@ jobs:
|
|||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
cache: npm
|
||||
cache-dependency-path: package-lock.json
|
||||
- run: make deps-frontend frontend deps-backend
|
||||
- run: npx playwright install --with-deps
|
||||
- run: make test-e2e-sqlite
|
||||
|
|
|
@ -25,6 +25,8 @@ jobs:
|
|||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
cache: npm
|
||||
cache-dependency-path: package-lock.json
|
||||
- run: make deps-frontend deps-backend
|
||||
# xgo build
|
||||
- run: make release
|
||||
|
|
|
@ -24,6 +24,8 @@ jobs:
|
|||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
cache: npm
|
||||
cache-dependency-path: package-lock.json
|
||||
- run: make deps-frontend deps-backend
|
||||
# xgo build
|
||||
- run: make release
|
||||
|
|
|
@ -26,6 +26,8 @@ jobs:
|
|||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
cache: npm
|
||||
cache-dependency-path: package-lock.json
|
||||
- run: make deps-frontend deps-backend
|
||||
# xgo build
|
||||
- run: make release
|
||||
|
|
File diff suppressed because it is too large
Load Diff
5382
CHANGELOG.md
5382
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
9
Makefile
9
Makefile
|
@ -110,7 +110,6 @@ LDFLAGS := $(LDFLAGS) -X "main.MakeVersion=$(MAKE_VERSION)" -X "main.Version=$(G
|
|||
|
||||
LINUX_ARCHS ?= linux/amd64,linux/386,linux/arm-5,linux/arm-6,linux/arm64
|
||||
|
||||
GO_PACKAGES ?= $(filter-out code.gitea.io/gitea/tests/integration/migration-test code.gitea.io/gitea/tests code.gitea.io/gitea/tests/integration code.gitea.io/gitea/tests/e2e,$(shell $(GO) list ./... | grep -v /vendor/))
|
||||
GO_TEST_PACKAGES ?= $(filter-out $(shell $(GO) list code.gitea.io/gitea/models/migrations/...) code.gitea.io/gitea/tests/integration/migration-test code.gitea.io/gitea/tests code.gitea.io/gitea/tests/integration code.gitea.io/gitea/tests/e2e,$(shell $(GO) list ./... | grep -v /vendor/))
|
||||
MIGRATE_TEST_PACKAGES ?= $(shell $(GO) list code.gitea.io/gitea/models/migrations/...)
|
||||
|
||||
|
@ -144,9 +143,9 @@ TAR_EXCLUDES := .git data indexers queues log node_modules $(EXECUTABLE) $(FOMAN
|
|||
GO_DIRS := build cmd models modules routers services tests
|
||||
WEB_DIRS := web_src/js web_src/css
|
||||
|
||||
ESLINT_FILES := web_src/js tools *.config.js tests/e2e
|
||||
ESLINT_FILES := web_src/js tools *.js tests/e2e
|
||||
STYLELINT_FILES := web_src/css web_src/js/components/*.vue
|
||||
SPELLCHECK_FILES := $(GO_DIRS) $(WEB_DIRS) docs/content templates options/locale/locale_en-US.ini .github
|
||||
SPELLCHECK_FILES := $(GO_DIRS) $(WEB_DIRS) docs/content templates options/locale/locale_en-US.ini .github $(filter-out CHANGELOG.md, $(wildcard *.go *.js *.md *.yml *.yaml *.toml))
|
||||
EDITORCONFIG_FILES := templates .github/workflows options/locale/locale_en-US.ini
|
||||
|
||||
GO_SOURCES := $(wildcard *.go)
|
||||
|
@ -423,7 +422,7 @@ lint-go-windows:
|
|||
lint-go-vet:
|
||||
@echo "Running go vet..."
|
||||
@GOOS= GOARCH= $(GO) build code.gitea.io/gitea-vet
|
||||
@$(GO) vet -vettool=gitea-vet $(GO_PACKAGES)
|
||||
@$(GO) vet -vettool=gitea-vet ./...
|
||||
|
||||
.PHONY: lint-editorconfig
|
||||
lint-editorconfig:
|
||||
|
@ -779,7 +778,7 @@ generate-backend: $(TAGS_PREREQ) generate-go
|
|||
.PHONY: generate-go
|
||||
generate-go: $(TAGS_PREREQ)
|
||||
@echo "Running go generate..."
|
||||
@CC= GOOS= GOARCH= $(GO) generate -tags '$(TAGS)' $(GO_PACKAGES)
|
||||
@CC= GOOS= GOARCH= $(GO) generate -tags '$(TAGS)' ./...
|
||||
|
||||
.PHONY: security-check
|
||||
security-check:
|
||||
|
|
|
@ -2377,22 +2377,6 @@ LEVEL = Info
|
|||
;; Enable issue by repository metrics; default is false
|
||||
;ENABLED_ISSUE_BY_REPOSITORY = false
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;[task]
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;
|
||||
;; Task queue type, could be `channel` or `redis`.
|
||||
;QUEUE_TYPE = channel
|
||||
;;
|
||||
;; Task queue length, available only when `QUEUE_TYPE` is `channel`.
|
||||
;QUEUE_LENGTH = 1000
|
||||
;;
|
||||
;; Task queue connection string, available only when `QUEUE_TYPE` is `redis`.
|
||||
;; If there is a password of redis, use `redis://127.0.0.1:6379/0?pool_size=100&idle_timeout=180s` or `redis+cluster://127.0.0.1:6379/0?pool_size=100&idle_timeout=180s` for `redis-clsuter`.
|
||||
;QUEUE_CONN_STR = "redis://127.0.0.1:6379/0?pool_size=100&idle_timeout=180s"
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;[migrations]
|
||||
|
|
|
@ -1198,14 +1198,6 @@ in this mapping or the filetype using heuristics.
|
|||
|
||||
- `DEFAULT_UI_LOCATION`: Default location of time on the UI, so that we can display correct user's time on UI. i.e. Asia/Shanghai
|
||||
|
||||
## Task (`task`)
|
||||
|
||||
Task queue configuration has been moved to `queue.task`. However, the below configuration values are kept for backwards compatibility:
|
||||
|
||||
- `QUEUE_TYPE`: **channel**: Task queue type, could be `channel` or `redis`.
|
||||
- `QUEUE_LENGTH`: **1000**: Task queue length, available only when `QUEUE_TYPE` is `channel`.
|
||||
- `QUEUE_CONN_STR`: **redis://127.0.0.1:6379/0**: Task queue connection string, available only when `QUEUE_TYPE` is `redis`. If redis needs a password, use `redis://123@127.0.0.1:6379/0` or `redis+cluster://123@127.0.0.1:6379/0`.
|
||||
|
||||
## Migrations (`migrations`)
|
||||
|
||||
- `MAX_ATTEMPTS`: **3**: Max attempts per http/https request on migrations.
|
||||
|
|
|
@ -1128,15 +1128,6 @@ ALLOW_DATA_URI_IMAGES = true
|
|||
|
||||
- `DEFAULT_UI_LOCATION`:在 UI 上的默认时间位置,以便我们可以在 UI 上显示正确的用户时间。例如:Asia/Shanghai
|
||||
|
||||
## 任务 (`task`)
|
||||
|
||||
任务队列配置已移动到 `queue.task`。然而,以下配置值仍保留以确保向后兼容:
|
||||
|
||||
- `QUEUE_TYPE`:**channel**:任务队列类型,可以是 `channel` 或 `redis`。
|
||||
- `QUEUE_LENGTH`:**1000**:任务队列长度,仅在 `QUEUE_TYPE` 为 `channel` 时可用。
|
||||
- `QUEUE_CONN_STR`:**redis://127.0.0.1:6379/0**:任务队列连接字符串,仅在 `QUEUE_TYPE` 为 `redis` 时可用。
|
||||
如果 redis 需要密码,使用 `redis://123@127.0.0.1:6379/0` 或 `redis+cluster://123@127.0.0.1:6379/0`。
|
||||
|
||||
## 迁移 (`migrations`)
|
||||
|
||||
- `MAX_ATTEMPTS`:**3**:每次 http/https 请求的最大尝试次数(用于迁移)。
|
||||
|
|
|
@ -83,6 +83,9 @@ func (actions ActionList) loadRepoOwner(ctx context.Context, userMap map[int64]*
|
|||
_, alreadyLoaded := userMap[action.Repo.OwnerID]
|
||||
return action.Repo.OwnerID, !alreadyLoaded
|
||||
})
|
||||
if len(missingUserIDs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := db.GetEngine(ctx).
|
||||
In("id", missingUserIDs).
|
||||
|
@ -129,6 +132,9 @@ func (actions ActionList) LoadComments(ctx context.Context) error {
|
|||
commentIDs = append(commentIDs, action.CommentID)
|
||||
}
|
||||
}
|
||||
if len(commentIDs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
commentsMap := make(map[int64]*issues_model.Comment, len(commentIDs))
|
||||
if err := db.GetEngine(ctx).In("id", commentIDs).Find(&commentsMap); err != nil {
|
||||
|
|
|
@ -62,11 +62,13 @@ func CanMaintainerWriteToBranch(ctx context.Context, p access_model.Permission,
|
|||
return true
|
||||
}
|
||||
|
||||
if len(p.Units) < 1 {
|
||||
// the code below depends on units to get the repository ID, not ideal but just keep it for now
|
||||
firstUnitRepoID := p.GetFirstUnitRepoID()
|
||||
if firstUnitRepoID == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
prs, err := GetUnmergedPullRequestsByHeadInfo(ctx, p.Units[0].RepoID, branch)
|
||||
prs, err := GetUnmergedPullRequestsByHeadInfo(ctx, firstUnitRepoID, branch)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -582,6 +582,8 @@ var migrations = []Migration{
|
|||
NewMigration("Add commit status summary table", v1_23.AddCommitStatusSummary),
|
||||
// v296 -> v297
|
||||
NewMigration("Add missing field of commit status summary table", v1_23.AddCommitStatusSummary2),
|
||||
// v297 -> v298
|
||||
NewMigration("Add everyone_access_mode for repo_unit", v1_23.AddRepoUnitEveryoneAccessMode),
|
||||
}
|
||||
|
||||
// GetCurrentDBVersion returns the current db version
|
||||
|
|
|
@ -336,7 +336,7 @@ func AddBranchProtectionCanPushAndEnableWhitelist(x *xorm.Engine) error {
|
|||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if perm.UnitsMode == nil {
|
||||
if len(perm.UnitsMode) == 0 {
|
||||
for _, u := range perm.Units {
|
||||
if u.Type == UnitTypeCode {
|
||||
return AccessModeWrite <= perm.AccessMode, nil
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v1_23 //nolint
|
||||
|
||||
import (
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func AddRepoUnitEveryoneAccessMode(x *xorm.Engine) error {
|
||||
type RepoUnit struct { //revive:disable-line:exported
|
||||
EveryoneAccessMode perm.AccessMode `xorm:"NOT NULL DEFAULT 0"`
|
||||
}
|
||||
return x.Sync(&RepoUnit{})
|
||||
}
|
|
@ -130,11 +130,11 @@ func (t *Team) GetUnitsMap() map[string]string {
|
|||
m := make(map[string]string)
|
||||
if t.AccessMode >= perm.AccessModeAdmin {
|
||||
for _, u := range unit.Units {
|
||||
m[u.NameKey] = t.AccessMode.String()
|
||||
m[u.NameKey] = t.AccessMode.ToString()
|
||||
}
|
||||
} else {
|
||||
for _, u := range t.Units {
|
||||
m[u.Unit().NameKey] = u.AccessMode.String()
|
||||
m[u.Unit().NameKey] = u.AccessMode.ToString()
|
||||
}
|
||||
}
|
||||
return m
|
||||
|
@ -174,23 +174,27 @@ func (t *Team) LoadMembers(ctx context.Context) (err error) {
|
|||
return err
|
||||
}
|
||||
|
||||
// UnitEnabled returns if the team has the given unit type enabled
|
||||
// UnitEnabled returns true if the team has the given unit type enabled
|
||||
func (t *Team) UnitEnabled(ctx context.Context, tp unit.Type) bool {
|
||||
return t.UnitAccessMode(ctx, tp) > perm.AccessModeNone
|
||||
}
|
||||
|
||||
// UnitAccessMode returns if the team has the given unit type enabled
|
||||
// UnitAccessMode returns the access mode for the given unit type, "none" for non-existent units
|
||||
func (t *Team) UnitAccessMode(ctx context.Context, tp unit.Type) perm.AccessMode {
|
||||
accessMode, _ := t.UnitAccessModeEx(ctx, tp)
|
||||
return accessMode
|
||||
}
|
||||
|
||||
func (t *Team) UnitAccessModeEx(ctx context.Context, tp unit.Type) (accessMode perm.AccessMode, exist bool) {
|
||||
if err := t.LoadUnits(ctx); err != nil {
|
||||
log.Warn("Error loading team (ID: %d) units: %s", t.ID, err.Error())
|
||||
}
|
||||
|
||||
for _, unit := range t.Units {
|
||||
if unit.Type == tp {
|
||||
return unit.AccessMode
|
||||
for _, u := range t.Units {
|
||||
if u.Type == tp {
|
||||
return u.AccessMode, true
|
||||
}
|
||||
}
|
||||
return perm.AccessModeNone
|
||||
return perm.AccessModeNone, false
|
||||
}
|
||||
|
||||
// IsUsableTeamName tests if a name could be as team name
|
||||
|
|
|
@ -63,13 +63,11 @@ func accessLevel(ctx context.Context, user *user_model.User, repo *repo_model.Re
|
|||
}
|
||||
|
||||
func maxAccessMode(modes ...perm.AccessMode) perm.AccessMode {
|
||||
max := perm.AccessModeNone
|
||||
maxMode := perm.AccessModeNone
|
||||
for _, mode := range modes {
|
||||
if mode > max {
|
||||
max = mode
|
||||
}
|
||||
maxMode = max(maxMode, mode)
|
||||
}
|
||||
return max
|
||||
return maxMode
|
||||
}
|
||||
|
||||
type userAccess struct {
|
||||
|
|
|
@ -6,6 +6,7 @@ package access
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"slices"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/organization"
|
||||
|
@ -14,13 +15,15 @@ import (
|
|||
"code.gitea.io/gitea/models/unit"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
)
|
||||
|
||||
// Permission contains all the permissions related variables to a repository for a user
|
||||
type Permission struct {
|
||||
AccessMode perm_model.AccessMode
|
||||
Units []*repo_model.RepoUnit
|
||||
UnitsMode map[unit.Type]perm_model.AccessMode
|
||||
|
||||
units []*repo_model.RepoUnit
|
||||
unitsMode map[unit.Type]perm_model.AccessMode
|
||||
}
|
||||
|
||||
// IsOwner returns true if current user is the owner of repository.
|
||||
|
@ -33,25 +36,44 @@ func (p *Permission) IsAdmin() bool {
|
|||
return p.AccessMode >= perm_model.AccessModeAdmin
|
||||
}
|
||||
|
||||
// HasAccess returns true if the current user has at least read access to any unit of this repository
|
||||
// HasAccess returns true if the current user might have at least read access to any unit of this repository
|
||||
func (p *Permission) HasAccess() bool {
|
||||
if p.UnitsMode == nil {
|
||||
return p.AccessMode >= perm_model.AccessModeRead
|
||||
}
|
||||
return len(p.UnitsMode) > 0
|
||||
return len(p.unitsMode) > 0 || p.AccessMode >= perm_model.AccessModeRead
|
||||
}
|
||||
|
||||
// UnitAccessMode returns current user accessmode to the specify unit of the repository
|
||||
func (p *Permission) UnitAccessMode(unitType unit.Type) perm_model.AccessMode {
|
||||
if p.UnitsMode == nil {
|
||||
for _, u := range p.Units {
|
||||
if u.Type == unitType {
|
||||
return p.AccessMode
|
||||
}
|
||||
}
|
||||
return perm_model.AccessModeNone
|
||||
// HasUnits returns true if the permission contains attached units
|
||||
func (p *Permission) HasUnits() bool {
|
||||
return len(p.units) > 0
|
||||
}
|
||||
|
||||
// GetFirstUnitRepoID returns the repo ID of the first unit, it is a fragile design and should NOT be used anymore
|
||||
// deprecated
|
||||
func (p *Permission) GetFirstUnitRepoID() int64 {
|
||||
if len(p.units) > 0 {
|
||||
return p.units[0].RepoID
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// UnitAccessMode returns current user access mode to the specify unit of the repository
|
||||
func (p *Permission) UnitAccessMode(unitType unit.Type) perm_model.AccessMode {
|
||||
if p.unitsMode != nil {
|
||||
// if the units map contains the access mode, use it, but admin/owner mode could override it
|
||||
if m, ok := p.unitsMode[unitType]; ok {
|
||||
return util.Iif(p.AccessMode >= perm_model.AccessModeAdmin, p.AccessMode, m)
|
||||
}
|
||||
}
|
||||
// if the units map does not contain the access mode, return the default access mode if the unit exists
|
||||
hasUnit := slices.ContainsFunc(p.units, func(u *repo_model.RepoUnit) bool { return u.Type == unitType })
|
||||
return util.Iif(hasUnit, p.AccessMode, perm_model.AccessModeNone)
|
||||
}
|
||||
|
||||
func (p *Permission) SetUnitsWithDefaultAccessMode(units []*repo_model.RepoUnit, mode perm_model.AccessMode) {
|
||||
p.units = units
|
||||
p.unitsMode = make(map[unit.Type]perm_model.AccessMode)
|
||||
for _, u := range p.units {
|
||||
p.unitsMode[u.Type] = mode
|
||||
}
|
||||
return p.UnitsMode[unitType]
|
||||
}
|
||||
|
||||
// CanAccess returns true if user has mode access to the unit of the repository
|
||||
|
@ -102,23 +124,33 @@ func (p *Permission) CanWriteIssuesOrPulls(isPull bool) bool {
|
|||
return p.CanWrite(unit.TypeIssues)
|
||||
}
|
||||
|
||||
func (p *Permission) ReadableUnitTypes() []unit.Type {
|
||||
types := make([]unit.Type, 0, len(p.units))
|
||||
for _, u := range p.units {
|
||||
if p.CanRead(u.Type) {
|
||||
types = append(types, u.Type)
|
||||
}
|
||||
}
|
||||
return types
|
||||
}
|
||||
|
||||
func (p *Permission) LogString() string {
|
||||
format := "<Permission AccessMode=%s, %d Units, %d UnitsMode(s): [ "
|
||||
args := []any{p.AccessMode.String(), len(p.Units), len(p.UnitsMode)}
|
||||
args := []any{p.AccessMode.ToString(), len(p.units), len(p.unitsMode)}
|
||||
|
||||
for i, unit := range p.Units {
|
||||
for i, u := range p.units {
|
||||
config := ""
|
||||
if unit.Config != nil {
|
||||
configBytes, err := unit.Config.ToDB()
|
||||
if u.Config != nil {
|
||||
configBytes, err := u.Config.ToDB()
|
||||
config = string(configBytes)
|
||||
if err != nil {
|
||||
config = err.Error()
|
||||
}
|
||||
}
|
||||
format += "\nUnits[%d]: ID: %d RepoID: %d Type: %s Config: %s"
|
||||
args = append(args, i, unit.ID, unit.RepoID, unit.Type.LogString(), config)
|
||||
args = append(args, i, u.ID, u.RepoID, u.Type.LogString(), config)
|
||||
}
|
||||
for key, value := range p.UnitsMode {
|
||||
for key, value := range p.unitsMode {
|
||||
format += "\nUnitMode[%-v]: %-v"
|
||||
args = append(args, key.LogString(), value.LogString())
|
||||
}
|
||||
|
@ -126,23 +158,34 @@ func (p *Permission) LogString() string {
|
|||
return fmt.Sprintf(format, args...)
|
||||
}
|
||||
|
||||
// GetUserRepoPermission returns the user permissions to the repository
|
||||
func GetUserRepoPermission(ctx context.Context, repo *repo_model.Repository, user *user_model.User) (Permission, error) {
|
||||
var perm Permission
|
||||
if log.IsTrace() {
|
||||
defer func() {
|
||||
if user == nil {
|
||||
log.Trace("Permission Loaded for anonymous user in %-v:\nPermissions: %-+v",
|
||||
repo,
|
||||
perm)
|
||||
return
|
||||
func applyEveryoneRepoPermission(user *user_model.User, perm *Permission) {
|
||||
if user != nil && user.ID > 0 {
|
||||
for _, u := range perm.units {
|
||||
if perm.unitsMode == nil {
|
||||
perm.unitsMode = make(map[unit.Type]perm_model.AccessMode)
|
||||
}
|
||||
log.Trace("Permission Loaded for %-v in %-v:\nPermissions: %-+v",
|
||||
user,
|
||||
repo,
|
||||
perm)
|
||||
}()
|
||||
if u.EveryoneAccessMode >= perm_model.AccessModeRead && u.EveryoneAccessMode > perm.unitsMode[u.Type] {
|
||||
perm.unitsMode[u.Type] = u.EveryoneAccessMode
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GetUserRepoPermission returns the user permissions to the repository
|
||||
func GetUserRepoPermission(ctx context.Context, repo *repo_model.Repository, user *user_model.User) (perm Permission, err error) {
|
||||
defer func() {
|
||||
if err == nil {
|
||||
applyEveryoneRepoPermission(user, &perm)
|
||||
}
|
||||
if log.IsTrace() {
|
||||
log.Trace("Permission Loaded for user %-v in repo %-v, permissions: %-+v", user, repo, perm)
|
||||
}
|
||||
}()
|
||||
|
||||
if err = repo.LoadUnits(ctx); err != nil {
|
||||
return perm, err
|
||||
}
|
||||
perm.units = repo.Units
|
||||
|
||||
// anonymous user visit private repo.
|
||||
// TODO: anonymous user visit public unit of private repo???
|
||||
|
@ -152,7 +195,6 @@ func GetUserRepoPermission(ctx context.Context, repo *repo_model.Repository, use
|
|||
}
|
||||
|
||||
var isCollaborator bool
|
||||
var err error
|
||||
if user != nil {
|
||||
isCollaborator, err = repo_model.IsCollaborator(ctx, repo.ID, user.ID)
|
||||
if err != nil {
|
||||
|
@ -160,7 +202,7 @@ func GetUserRepoPermission(ctx context.Context, repo *repo_model.Repository, use
|
|||
}
|
||||
}
|
||||
|
||||
if err := repo.LoadOwner(ctx); err != nil {
|
||||
if err = repo.LoadOwner(ctx); err != nil {
|
||||
return perm, err
|
||||
}
|
||||
|
||||
|
@ -171,12 +213,6 @@ func GetUserRepoPermission(ctx context.Context, repo *repo_model.Repository, use
|
|||
return perm, nil
|
||||
}
|
||||
|
||||
if err := repo.LoadUnits(ctx); err != nil {
|
||||
return perm, err
|
||||
}
|
||||
|
||||
perm.Units = repo.Units
|
||||
|
||||
// anonymous visit public repo
|
||||
if user == nil {
|
||||
perm.AccessMode = perm_model.AccessModeRead
|
||||
|
@ -195,19 +231,16 @@ func GetUserRepoPermission(ctx context.Context, repo *repo_model.Repository, use
|
|||
return perm, err
|
||||
}
|
||||
|
||||
if err := repo.LoadOwner(ctx); err != nil {
|
||||
return perm, err
|
||||
}
|
||||
if !repo.Owner.IsOrganization() {
|
||||
return perm, nil
|
||||
}
|
||||
|
||||
perm.UnitsMode = make(map[unit.Type]perm_model.AccessMode)
|
||||
perm.unitsMode = make(map[unit.Type]perm_model.AccessMode)
|
||||
|
||||
// Collaborators on organization
|
||||
if isCollaborator {
|
||||
for _, u := range repo.Units {
|
||||
perm.UnitsMode[u.Type] = perm.AccessMode
|
||||
perm.unitsMode[u.Type] = perm.AccessMode
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -221,7 +254,7 @@ func GetUserRepoPermission(ctx context.Context, repo *repo_model.Repository, use
|
|||
for _, team := range teams {
|
||||
if team.AccessMode >= perm_model.AccessModeAdmin {
|
||||
perm.AccessMode = perm_model.AccessModeOwner
|
||||
perm.UnitsMode = nil
|
||||
perm.unitsMode = nil
|
||||
return perm, nil
|
||||
}
|
||||
}
|
||||
|
@ -229,30 +262,26 @@ func GetUserRepoPermission(ctx context.Context, repo *repo_model.Repository, use
|
|||
for _, u := range repo.Units {
|
||||
var found bool
|
||||
for _, team := range teams {
|
||||
teamMode := team.UnitAccessMode(ctx, u.Type)
|
||||
if teamMode > perm_model.AccessModeNone {
|
||||
m := perm.UnitsMode[u.Type]
|
||||
if m < teamMode {
|
||||
perm.UnitsMode[u.Type] = teamMode
|
||||
}
|
||||
if teamMode, exist := team.UnitAccessModeEx(ctx, u.Type); exist {
|
||||
perm.unitsMode[u.Type] = max(perm.unitsMode[u.Type], teamMode)
|
||||
found = true
|
||||
}
|
||||
}
|
||||
|
||||
// for a public repo on an organization, a non-restricted user has read permission on non-team defined units.
|
||||
if !found && !repo.IsPrivate && !user.IsRestricted {
|
||||
if _, ok := perm.UnitsMode[u.Type]; !ok {
|
||||
perm.UnitsMode[u.Type] = perm_model.AccessModeRead
|
||||
if _, ok := perm.unitsMode[u.Type]; !ok {
|
||||
perm.unitsMode[u.Type] = perm_model.AccessModeRead
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove no permission units
|
||||
perm.Units = make([]*repo_model.RepoUnit, 0, len(repo.Units))
|
||||
for t := range perm.UnitsMode {
|
||||
perm.units = make([]*repo_model.RepoUnit, 0, len(repo.Units))
|
||||
for t := range perm.unitsMode {
|
||||
for _, u := range repo.Units {
|
||||
if u.Type == t {
|
||||
perm.Units = append(perm.Units, u)
|
||||
perm.units = append(perm.units, u)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -334,7 +363,7 @@ func HasAccessUnit(ctx context.Context, user *user_model.User, repo *repo_model.
|
|||
// Currently any write access (code, issues or pr's) is assignable, to match assignee list in user interface.
|
||||
func CanBeAssigned(ctx context.Context, user *user_model.User, repo *repo_model.Repository, _ bool) (bool, error) {
|
||||
if user.IsOrganization() {
|
||||
return false, fmt.Errorf("Organization can't be added as assignee [user_id: %d, repo_id: %d]", user.ID, repo.ID)
|
||||
return false, fmt.Errorf("organization can't be added as assignee [user_id: %d, repo_id: %d]", user.ID, repo.ID)
|
||||
}
|
||||
perm, err := GetUserRepoPermission(ctx, repo, user)
|
||||
if err != nil {
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package access
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
perm_model "code.gitea.io/gitea/models/perm"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestApplyEveryoneRepoPermission(t *testing.T) {
|
||||
perm := Permission{
|
||||
AccessMode: perm_model.AccessModeNone,
|
||||
units: []*repo_model.RepoUnit{
|
||||
{Type: unit.TypeWiki, EveryoneAccessMode: perm_model.AccessModeNone},
|
||||
},
|
||||
}
|
||||
applyEveryoneRepoPermission(nil, &perm)
|
||||
assert.False(t, perm.CanRead(unit.TypeWiki))
|
||||
|
||||
perm = Permission{
|
||||
AccessMode: perm_model.AccessModeNone,
|
||||
units: []*repo_model.RepoUnit{
|
||||
{Type: unit.TypeWiki, EveryoneAccessMode: perm_model.AccessModeRead},
|
||||
},
|
||||
}
|
||||
applyEveryoneRepoPermission(&user_model.User{ID: 1}, &perm)
|
||||
assert.True(t, perm.CanRead(unit.TypeWiki))
|
||||
|
||||
perm = Permission{
|
||||
AccessMode: perm_model.AccessModeWrite,
|
||||
units: []*repo_model.RepoUnit{
|
||||
{Type: unit.TypeWiki, EveryoneAccessMode: perm_model.AccessModeRead},
|
||||
},
|
||||
}
|
||||
applyEveryoneRepoPermission(&user_model.User{ID: 1}, &perm)
|
||||
assert.True(t, perm.CanRead(unit.TypeWiki))
|
||||
assert.False(t, perm.CanWrite(unit.TypeWiki)) // because there is no unit mode, so the everyone-mode is used as the unit's access mode
|
||||
|
||||
perm = Permission{
|
||||
units: []*repo_model.RepoUnit{
|
||||
{Type: unit.TypeWiki, EveryoneAccessMode: perm_model.AccessModeRead},
|
||||
},
|
||||
unitsMode: map[unit.Type]perm_model.AccessMode{
|
||||
unit.TypeWiki: perm_model.AccessModeWrite,
|
||||
},
|
||||
}
|
||||
applyEveryoneRepoPermission(&user_model.User{ID: 1}, &perm)
|
||||
assert.True(t, perm.CanWrite(unit.TypeWiki))
|
||||
}
|
||||
|
||||
func TestUnitAccessMode(t *testing.T) {
|
||||
perm := Permission{
|
||||
AccessMode: perm_model.AccessModeNone,
|
||||
}
|
||||
assert.Equal(t, perm_model.AccessModeNone, perm.UnitAccessMode(unit.TypeWiki), "no unit, no map, use AccessMode")
|
||||
|
||||
perm = Permission{
|
||||
AccessMode: perm_model.AccessModeRead,
|
||||
units: []*repo_model.RepoUnit{
|
||||
{Type: unit.TypeWiki},
|
||||
},
|
||||
}
|
||||
assert.Equal(t, perm_model.AccessModeRead, perm.UnitAccessMode(unit.TypeWiki), "only unit, no map, use AccessMode")
|
||||
|
||||
perm = Permission{
|
||||
AccessMode: perm_model.AccessModeAdmin,
|
||||
unitsMode: map[unit.Type]perm_model.AccessMode{
|
||||
unit.TypeWiki: perm_model.AccessModeRead,
|
||||
},
|
||||
}
|
||||
assert.Equal(t, perm_model.AccessModeAdmin, perm.UnitAccessMode(unit.TypeWiki), "no unit, only map, admin overrides map")
|
||||
|
||||
perm = Permission{
|
||||
AccessMode: perm_model.AccessModeNone,
|
||||
unitsMode: map[unit.Type]perm_model.AccessMode{
|
||||
unit.TypeWiki: perm_model.AccessModeRead,
|
||||
},
|
||||
}
|
||||
assert.Equal(t, perm_model.AccessModeRead, perm.UnitAccessMode(unit.TypeWiki), "no unit, only map, use map")
|
||||
|
||||
perm = Permission{
|
||||
AccessMode: perm_model.AccessModeNone,
|
||||
units: []*repo_model.RepoUnit{
|
||||
{Type: unit.TypeWiki},
|
||||
},
|
||||
unitsMode: map[unit.Type]perm_model.AccessMode{
|
||||
unit.TypeWiki: perm_model.AccessModeRead,
|
||||
},
|
||||
}
|
||||
assert.Equal(t, perm_model.AccessModeRead, perm.UnitAccessMode(unit.TypeWiki), "has unit, and map, use map")
|
||||
}
|
|
@ -5,25 +5,25 @@ package perm
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"slices"
|
||||
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
)
|
||||
|
||||
// AccessMode specifies the users access mode
|
||||
type AccessMode int
|
||||
|
||||
const (
|
||||
// AccessModeNone no access
|
||||
AccessModeNone AccessMode = iota // 0
|
||||
// AccessModeRead read access
|
||||
AccessModeRead // 1
|
||||
// AccessModeWrite write access
|
||||
AccessModeWrite // 2
|
||||
// AccessModeAdmin admin access
|
||||
AccessModeAdmin // 3
|
||||
// AccessModeOwner owner access
|
||||
AccessModeOwner // 4
|
||||
AccessModeNone AccessMode = iota // 0: no access
|
||||
|
||||
AccessModeRead // 1: read access
|
||||
AccessModeWrite // 2: write access
|
||||
AccessModeAdmin // 3: admin access
|
||||
AccessModeOwner // 4: owner access
|
||||
)
|
||||
|
||||
func (mode AccessMode) String() string {
|
||||
// ToString returns the string representation of the access mode, do not make it a Stringer, otherwise it's difficult to render in templates
|
||||
func (mode AccessMode) ToString() string {
|
||||
switch mode {
|
||||
case AccessModeRead:
|
||||
return "read"
|
||||
|
@ -39,19 +39,24 @@ func (mode AccessMode) String() string {
|
|||
}
|
||||
|
||||
func (mode AccessMode) LogString() string {
|
||||
return fmt.Sprintf("<AccessMode:%d:%s>", mode, mode.String())
|
||||
return fmt.Sprintf("<AccessMode:%d:%s>", mode, mode.ToString())
|
||||
}
|
||||
|
||||
// ParseAccessMode returns corresponding access mode to given permission string.
|
||||
func ParseAccessMode(permission string) AccessMode {
|
||||
func ParseAccessMode(permission string, allowed ...AccessMode) AccessMode {
|
||||
m := AccessModeNone
|
||||
switch permission {
|
||||
case "read":
|
||||
return AccessModeRead
|
||||
m = AccessModeRead
|
||||
case "write":
|
||||
return AccessModeWrite
|
||||
m = AccessModeWrite
|
||||
case "admin":
|
||||
return AccessModeAdmin
|
||||
m = AccessModeAdmin
|
||||
default:
|
||||
return AccessModeNone
|
||||
// the "owner" access is not really used for user input, it's mainly for checking access level in code, so don't parse it
|
||||
}
|
||||
if len(allowed) == 0 {
|
||||
return m
|
||||
}
|
||||
return util.Iif(slices.Contains(allowed, m), m, AccessModeNone)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package perm
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestAccessMode(t *testing.T) {
|
||||
names := []string{"none", "read", "write", "admin"}
|
||||
for i, name := range names {
|
||||
m := ParseAccessMode(name)
|
||||
assert.Equal(t, AccessMode(i), m)
|
||||
}
|
||||
assert.Equal(t, AccessMode(4), AccessModeOwner)
|
||||
assert.Equal(t, "owner", AccessModeOwner.ToString())
|
||||
assert.Equal(t, AccessModeNone, ParseAccessMode("owner"))
|
||||
assert.Equal(t, AccessModeNone, ParseAccessMode("invalid"))
|
||||
}
|
|
@ -10,6 +10,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
"code.gitea.io/gitea/modules/json"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
@ -41,11 +42,12 @@ func (err ErrUnitTypeNotExist) Unwrap() error {
|
|||
|
||||
// RepoUnit describes all units of a repository
|
||||
type RepoUnit struct { //revive:disable-line:exported
|
||||
ID int64
|
||||
RepoID int64 `xorm:"INDEX(s)"`
|
||||
Type unit.Type `xorm:"INDEX(s)"`
|
||||
Config convert.Conversion `xorm:"TEXT"`
|
||||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX CREATED"`
|
||||
ID int64
|
||||
RepoID int64 `xorm:"INDEX(s)"`
|
||||
Type unit.Type `xorm:"INDEX(s)"`
|
||||
Config convert.Conversion `xorm:"TEXT"`
|
||||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX CREATED"`
|
||||
EveryoneAccessMode perm.AccessMode `xorm:"NOT NULL DEFAULT 0"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
|
@ -191,16 +191,13 @@ type Unit struct {
|
|||
NameKey string
|
||||
URI string
|
||||
DescKey string
|
||||
Idx int
|
||||
Priority int
|
||||
MaxAccessMode perm.AccessMode // The max access mode of the unit. i.e. Read means this unit can only be read.
|
||||
}
|
||||
|
||||
// IsLessThan compares order of two units
|
||||
func (u Unit) IsLessThan(unit Unit) bool {
|
||||
if (u.Type == TypeExternalTracker || u.Type == TypeExternalWiki) && unit.Type != TypeExternalTracker && unit.Type != TypeExternalWiki {
|
||||
return false
|
||||
}
|
||||
return u.Idx < unit.Idx
|
||||
return u.Priority < unit.Priority
|
||||
}
|
||||
|
||||
// MaxPerm returns the max perms of this unit
|
||||
|
@ -236,7 +233,7 @@ var (
|
|||
"repo.ext_issues",
|
||||
"/issues",
|
||||
"repo.ext_issues.desc",
|
||||
1,
|
||||
101,
|
||||
perm.AccessModeRead,
|
||||
}
|
||||
|
||||
|
@ -272,7 +269,7 @@ var (
|
|||
"repo.ext_wiki",
|
||||
"/wiki",
|
||||
"repo.ext_wiki.desc",
|
||||
4,
|
||||
102,
|
||||
perm.AccessModeRead,
|
||||
}
|
||||
|
||||
|
|
|
@ -468,7 +468,7 @@ func parseCommitFileStatus(fileStatus *CommitFileStatus, stdout io.Reader) {
|
|||
_, _ = rd.Discard(1)
|
||||
}
|
||||
for {
|
||||
modifier, err := rd.ReadSlice('\x00')
|
||||
modifier, err := rd.ReadString('\x00')
|
||||
if err != nil {
|
||||
if err != io.EOF {
|
||||
log.Error("Unexpected error whilst reading from git log --name-status. Error: %v", err)
|
||||
|
|
|
@ -48,10 +48,11 @@ const maxNuspecFileSize = 3 * 1024 * 1024
|
|||
|
||||
// Package represents a Nuget package
|
||||
type Package struct {
|
||||
PackageType PackageType
|
||||
ID string
|
||||
Version string
|
||||
Metadata *Metadata
|
||||
PackageType PackageType
|
||||
ID string
|
||||
Version string
|
||||
Metadata *Metadata
|
||||
NuspecContent *bytes.Buffer
|
||||
}
|
||||
|
||||
// Metadata represents the metadata of a Nuget package
|
||||
|
@ -138,8 +139,9 @@ func ParsePackageMetaData(r io.ReaderAt, size int64) (*Package, error) {
|
|||
|
||||
// ParseNuspecMetaData parses a Nuspec file to retrieve the metadata of a Nuget package
|
||||
func ParseNuspecMetaData(archive *zip.Reader, r io.Reader) (*Package, error) {
|
||||
var nuspecBuf bytes.Buffer
|
||||
var p nuspecPackage
|
||||
if err := xml.NewDecoder(r).Decode(&p); err != nil {
|
||||
if err := xml.NewDecoder(io.TeeReader(r, &nuspecBuf)).Decode(&p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
@ -212,10 +214,11 @@ func ParseNuspecMetaData(archive *zip.Reader, r io.Reader) (*Package, error) {
|
|||
}
|
||||
}
|
||||
return &Package{
|
||||
PackageType: packageType,
|
||||
ID: p.Metadata.ID,
|
||||
Version: toNormalizedVersion(v),
|
||||
Metadata: m,
|
||||
PackageType: packageType,
|
||||
ID: p.Metadata.ID,
|
||||
Version: toNormalizedVersion(v),
|
||||
Metadata: m,
|
||||
NuspecContent: &nuspecBuf,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
var (
|
||||
backoffBegin = 50 * time.Millisecond
|
||||
backoffUpper = 2 * time.Second
|
||||
)
|
||||
|
@ -18,6 +18,14 @@ type (
|
|||
backoffFuncErr func() (retry bool, err error)
|
||||
)
|
||||
|
||||
func mockBackoffDuration(d time.Duration) func() {
|
||||
oldBegin, oldUpper := backoffBegin, backoffUpper
|
||||
backoffBegin, backoffUpper = d, d
|
||||
return func() {
|
||||
backoffBegin, backoffUpper = oldBegin, oldUpper
|
||||
}
|
||||
}
|
||||
|
||||
func backoffRetErr[T any](ctx context.Context, begin, upper time.Duration, end <-chan time.Time, fn backoffFuncRetErr[T]) (ret T, err error) {
|
||||
d := begin
|
||||
for {
|
||||
|
|
|
@ -250,6 +250,7 @@ func TestWorkerPoolQueueShutdown(t *testing.T) {
|
|||
|
||||
func TestWorkerPoolQueueWorkerIdleReset(t *testing.T) {
|
||||
defer test.MockVariableValue(&workerIdleDuration, 10*time.Millisecond)()
|
||||
defer mockBackoffDuration(10 * time.Millisecond)()
|
||||
|
||||
handler := func(items ...int) (unhandled []int) {
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
|
|
|
@ -6,9 +6,6 @@ package session
|
|||
import (
|
||||
"net/http"
|
||||
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/web/middleware"
|
||||
|
||||
"gitea.com/go-chi/session"
|
||||
)
|
||||
|
||||
|
@ -21,10 +18,12 @@ type Store interface {
|
|||
|
||||
// RegenerateSession regenerates the underlying session and returns the new store
|
||||
func RegenerateSession(resp http.ResponseWriter, req *http.Request) (Store, error) {
|
||||
// Ensure that a cookie with a trailing slash does not take precedence over
|
||||
// the cookie written by the middleware.
|
||||
middleware.DeleteLegacySiteCookie(resp, setting.SessionConfig.CookieName)
|
||||
|
||||
for _, f := range BeforeRegenerateSession {
|
||||
f(resp, req)
|
||||
}
|
||||
s, err := session.RegenerateSession(resp, req)
|
||||
return s, err
|
||||
}
|
||||
|
||||
// BeforeRegenerateSession is a list of functions that are called before a session is regenerated.
|
||||
var BeforeRegenerateSession []func(http.ResponseWriter, *http.Request)
|
||||
|
|
|
@ -34,6 +34,7 @@ func NewFuncMap() template.FuncMap {
|
|||
// -----------------------------------------------------------------
|
||||
// html/template related functions
|
||||
"dict": dict, // it's lowercase because this name has been widely used. Our other functions should have uppercase names.
|
||||
"Iif": Iif,
|
||||
"Eval": Eval,
|
||||
"SafeHTML": SafeHTML,
|
||||
"HTMLFormat": HTMLFormat,
|
||||
|
@ -238,6 +239,17 @@ func DotEscape(raw string) string {
|
|||
return strings.ReplaceAll(raw, ".", "\u200d.\u200d")
|
||||
}
|
||||
|
||||
// Iif is an "inline-if", similar util.Iif[T] but templates need the non-generic version,
|
||||
// and it could be simply used as "{{Iif expr trueVal}}" (omit the falseVal).
|
||||
func Iif(condition bool, vals ...any) any {
|
||||
if condition {
|
||||
return vals[0]
|
||||
} else if len(vals) > 1 {
|
||||
return vals[1]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Eval the expression and return the result, see the comment of eval.Expr for details.
|
||||
// To use this helper function in templates, pass each token as a separate parameter.
|
||||
//
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"net/url"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/modules/session"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
)
|
||||
|
||||
|
@ -48,12 +49,12 @@ func SetSiteCookie(resp http.ResponseWriter, name, value string, maxAge int) {
|
|||
// Previous versions would use a cookie path with a trailing /.
|
||||
// These are more specific than cookies without a trailing /, so
|
||||
// we need to delete these if they exist.
|
||||
DeleteLegacySiteCookie(resp, name)
|
||||
deleteLegacySiteCookie(resp, name)
|
||||
}
|
||||
|
||||
// DeleteLegacySiteCookie deletes the cookie with the given name at the cookie
|
||||
// deleteLegacySiteCookie deletes the cookie with the given name at the cookie
|
||||
// path with a trailing /, which would unintentionally override the cookie.
|
||||
func DeleteLegacySiteCookie(resp http.ResponseWriter, name string) {
|
||||
func deleteLegacySiteCookie(resp http.ResponseWriter, name string) {
|
||||
if setting.SessionConfig.CookiePath == "" || strings.HasSuffix(setting.SessionConfig.CookiePath, "/") {
|
||||
// If the cookie path ends with /, no legacy cookies will take
|
||||
// precedence, so do nothing. The exception is that cookies with no
|
||||
|
@ -74,3 +75,11 @@ func DeleteLegacySiteCookie(resp http.ResponseWriter, name string) {
|
|||
}
|
||||
resp.Header().Add("Set-Cookie", cookie.String())
|
||||
}
|
||||
|
||||
func init() {
|
||||
session.BeforeRegenerateSession = append(session.BeforeRegenerateSession, func(resp http.ResponseWriter, _ *http.Request) {
|
||||
// Ensure that a cookie with a trailing slash does not take precedence over
|
||||
// the cookie written by the middleware.
|
||||
deleteLegacySiteCookie(resp, setting.SessionConfig.CookieName)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -164,8 +164,6 @@ search=Hledat...
|
|||
type_tooltip=Druh vyhledávání
|
||||
fuzzy=Fuzzy
|
||||
fuzzy_tooltip=Zahrnout výsledky, které také úzce odpovídají hledanému výrazu
|
||||
match=Shoda
|
||||
match_tooltip=Zahrnout pouze výsledky, které odpovídají přesnému hledanému výrazu
|
||||
repo_kind=Hledat repozitáře...
|
||||
user_kind=Hledat uživatele...
|
||||
org_kind=Hledat organizace...
|
||||
|
@ -714,7 +712,6 @@ cancel=Zrušit
|
|||
language=Jazyk
|
||||
ui=Motiv vzhledu
|
||||
hidden_comment_types=Skryté typy komentářů
|
||||
hidden_comment_types_description=Zde zkontrolované typy komentářů nebudou zobrazeny na stránkách problémů. Zaškrtnutí „Štítek“ například odstraní všechny komentáře „<user> přidal/odstranil <label>“.
|
||||
hidden_comment_types.ref_tooltip=Komentáře, na které se odkazovalo z jiného úkolu/commitu/…
|
||||
hidden_comment_types.issue_ref_tooltip=Komentáře, kde uživatel změní větev/značku spojenou s problémem
|
||||
comment_type_group_reference=Reference
|
||||
|
@ -1286,7 +1283,6 @@ editor.or=nebo
|
|||
editor.cancel_lower=Zrušit
|
||||
editor.commit_signed_changes=Odevzdat podepsané změny
|
||||
editor.commit_changes=Odevzdat změny
|
||||
editor.add_tmpl=Přidán „<nazev_souboru>“
|
||||
editor.add=Přidat %s
|
||||
editor.update=Aktualizovat %s
|
||||
editor.delete=Odstranit %s
|
||||
|
@ -3075,14 +3071,12 @@ auths.tips=Tipy
|
|||
auths.tips.oauth2.general=Ověřování OAuth2
|
||||
auths.tips.oauth2.general.tip=Při registraci nové OAuth2 autentizace by URL callbacku/přesměrování měla být:
|
||||
auths.tip.oauth2_provider=Poskytovatel OAuth2
|
||||
auths.tip.bitbucket=Vytvořte nového OAuth konzumenta na https://bitbucket.org/account/user/<vase-uzivatelske-jmeno>/oauth-consumers/new a přidejte oprávnění „Account“ - „Read“
|
||||
auths.tip.nextcloud=Zaregistrujte nového OAuth konzumenta na vaší instanci pomocí následujícího menu „Nastavení -> Zabezpečení -> OAuth 2.0 klient“
|
||||
auths.tip.dropbox=Vytvořte novou aplikaci na https://www.dropbox.com/developers/apps
|
||||
auths.tip.facebook=Registrujte novou aplikaci na https://developers.facebook.com/apps a přidejte produkt „Facebook Login“
|
||||
auths.tip.github=Registrujte novou OAuth aplikaci na https://github.com/settings/applications/new
|
||||
auths.tip.gitlab_new=Zaregistrujte novou aplikaci na https://gitlab.com/-/profile/applications
|
||||
auths.tip.google_plus=Získejte klientské pověření OAuth2 z Google API konzole na https://console.developers.google.com/
|
||||
auths.tip.openid_connect=Použijte OpenID URL pro objevování spojení (<server>/.well-known/openid-configuration) k nastavení koncových bodů
|
||||
auths.tip.twitter=Jděte na https://dev.twitter.com/apps, vytvořte aplikaci a ujistěte se, že volba „Allow this application to be used to Sign in with Twitter“ je povolená
|
||||
auths.tip.discord=Registrujte novou aplikaci na https://discordapp.com/developers/applications/me
|
||||
auths.tip.gitea=Registrovat novou Oauth2 aplikaci. Návod naleznete na https://docs.gitea.com/development/oauth2-provider
|
||||
|
|
|
@ -164,8 +164,6 @@ search=Suche ...
|
|||
type_tooltip=Suchmodus
|
||||
fuzzy=Ähnlich
|
||||
fuzzy_tooltip=Ergebnisse einbeziehen, die dem Suchbegriff ähnlich sind
|
||||
match=Genau
|
||||
match_tooltip=Nur genau zum Suchbegriff passende Ergebnisse einbeziehen
|
||||
repo_kind=Repositories durchsuchen ...
|
||||
user_kind=Benutzer durchsuchen ...
|
||||
org_kind=Organisationen durchsuchen ...
|
||||
|
@ -714,7 +712,6 @@ cancel=Abbrechen
|
|||
language=Sprache
|
||||
ui=Theme
|
||||
hidden_comment_types=Ausgeblendeter Kommentartypen
|
||||
hidden_comment_types_description=Die hier markierten Kommentartypen werden nicht innerhalb der Issue-Seiten angezeigt. Das Überprüfen von "Label" entfernt beispielsweise alle "<user> hinzugefügt/entfernt <label>" Kommentare.
|
||||
hidden_comment_types.ref_tooltip=Kommentare, in denen dieses Issue von einem anderen Issue/Commit referenziert wurde
|
||||
hidden_comment_types.issue_ref_tooltip=Kommentare, bei denen der Benutzer den Branch/Tag des Issues ändert
|
||||
comment_type_group_reference=Verweis auf Mitglieder
|
||||
|
@ -1287,7 +1284,6 @@ editor.or=oder
|
|||
editor.cancel_lower=Abbrechen
|
||||
editor.commit_signed_changes=Committe signierte Änderungen
|
||||
editor.commit_changes=Änderungen committen
|
||||
editor.add_tmpl='<filename>' hinzufügen
|
||||
editor.add=%s hinzugefügt
|
||||
editor.update=%s aktualisiert
|
||||
editor.delete=%s gelöscht
|
||||
|
@ -3083,14 +3079,12 @@ auths.tips=Tipps
|
|||
auths.tips.oauth2.general=OAuth2-Authentifizierung
|
||||
auths.tips.oauth2.general.tip=Beim Registrieren einer OAuth2-Anwendung sollte die Callback-URL folgendermaßen lauten:
|
||||
auths.tip.oauth2_provider=OAuth2-Anbieter
|
||||
auths.tip.bitbucket=Registriere einen neuen OAuth-Consumer unter https://bitbucket.org/account/user/<dein-benutzername>/oauth-consumers/new und füge die Berechtigung „Account“ – „Read“ hinzu.
|
||||
auths.tip.nextcloud=Registriere über das "Settings -> Security -> OAuth 2.0 client"-Menü einen neuen "OAuth consumer" auf der Nextcloud-Instanz
|
||||
auths.tip.dropbox=Erstelle eine neue App auf https://www.dropbox.com/developers/apps.
|
||||
auths.tip.facebook=Erstelle eine neue Anwendung auf https://developers.facebook.com/apps und füge das Produkt „Facebook Login“ hinzu.
|
||||
auths.tip.github=Erstelle unter https://github.com/settings/applications/new eine neue OAuth-Anwendung.
|
||||
auths.tip.gitlab_new=Erstelle eine neue Anwendung unter https://gitlab.com/-/profile/applications
|
||||
auths.tip.google_plus=Du erhältst die OAuth2-Client-Zugangsdaten in der Google-API-Konsole unter https://console.developers.google.com/
|
||||
auths.tip.openid_connect=Benutze die OpenID-Connect-Discovery-URL (<server>/.well-known/openid-configuration), um die Endpunkte zu spezifizieren
|
||||
auths.tip.twitter=Gehe auf https://dev.twitter.com/apps, erstelle eine Anwendung und stelle sicher, dass die Option „Allow this application to be used to Sign in with Twitter“ aktiviert ist
|
||||
auths.tip.discord=Erstelle unter https://discordapp.com/developers/applications/me eine neue Anwendung.
|
||||
auths.tip.gitea=Registriere eine neue OAuth2-Anwendung. Eine Anleitung findest du unter https://docs.gitea.com/development/oauth2-provider/
|
||||
|
|
|
@ -651,7 +651,6 @@ cancel=Ακύρωση
|
|||
language=Γλώσσα
|
||||
ui=Θέμα Διεπαφής
|
||||
hidden_comment_types=Κρυμμένοι τύποι σχολίων
|
||||
hidden_comment_types_description=Οι τύποι σχολίων που επιλέγονται εδώ δε θα εμφανίζονται μέσα στις σελίδες ζητημάτων. Επιλέγοντας π.χ το "Σήματα", θα αφαιρεθούν όλα τα σχόλια σαν το "<user> πρόσθεσε/αφαίρεσε τα σήματα <label>".
|
||||
hidden_comment_types.ref_tooltip=Σχόλια όπου αυτό το ζήτημα αναφέρθηκε από άλλο ζήτημα/υποβολή/…
|
||||
hidden_comment_types.issue_ref_tooltip=Σχόλια όπου ο χρήστης αλλάζει τον κλάδο/ετικέτα που σχετίζεται με το ζήτημα
|
||||
comment_type_group_reference=Αναφορά
|
||||
|
@ -1214,7 +1213,6 @@ editor.or=ή
|
|||
editor.cancel_lower=Ακύρωση
|
||||
editor.commit_signed_changes=Υποβολή Υπογεγραμμένων Αλλαγών
|
||||
editor.commit_changes=Υποβολή Αλλαγών
|
||||
editor.add_tmpl=Προσθήκη '<filename>'
|
||||
editor.add=Προσθήκη %s
|
||||
editor.update=Ενημέρωση %s
|
||||
editor.delete=Διαγραφή %s
|
||||
|
@ -2970,13 +2968,11 @@ auths.tips=Συμβουλές
|
|||
auths.tips.oauth2.general=Ταυτοποίηση OAuth2
|
||||
auths.tips.oauth2.general.tip=Κατά την εγγραφή μιας νέας ταυτοποίησης OAuth2, το URL κλήσης/ανακατεύθυνσης πρέπει να είναι:
|
||||
auths.tip.oauth2_provider=Πάροχος OAuth2
|
||||
auths.tip.bitbucket=Καταχωρήστε ένα νέο καταναλωτή OAuth στο https://bitbucket.org/account/user/<your username>/oauth-consumers/new και προσθέστε το δικαίωμα 'Account' - 'Read'
|
||||
auths.tip.nextcloud=`Καταχωρήστε ένα νέο καταναλωτή OAuth στην υπηρεσία σας χρησιμοποιώντας το παρακάτω μενού "Settings -> Security -> OAuth 2.0 client"`
|
||||
auths.tip.dropbox=Δημιουργήστε μια νέα εφαρμογή στο https://www.dropbox.com/developers/apps
|
||||
auths.tip.facebook=`Καταχωρήστε μια νέα εφαρμογή στο https://developers.facebook.com/apps και προσθέστε το προϊόν "Facebook Login"`
|
||||
auths.tip.github=Καταχωρήστε μια νέα εφαρμογή OAuth στο https://github.com/settings/applications/new
|
||||
auths.tip.google_plus=Αποκτήστε τα διαπιστευτήρια πελάτη OAuth2 από την κονσόλα API της Google στο https://console.developers.google.com/
|
||||
auths.tip.openid_connect=Χρησιμοποιήστε το OpenID Connect Discovery URL (<server>/.well known/openid-configuration) για να καθορίσετε τα τελικά σημεία
|
||||
auths.tip.twitter=Πηγαίνετε στο https://dev.twitter.com/apps, δημιουργήστε μια εφαρμογή και βεβαιωθείτε ότι η επιλογή “Allow this application to be used to Sign in with Twitter” είναι ενεργοποιημένη
|
||||
auths.tip.discord=Καταχωρήστε μια νέα εφαρμογή στο https://discordapp.com/developers/applications/me
|
||||
auths.tip.gitea=Καταχωρήστε μια νέα εφαρμογή OAuth2. Μπορείτε να βρείτε τον οδηγό στο https://docs.gitea.com/development/oauth2-provider
|
||||
|
|
|
@ -164,8 +164,8 @@ search = Search...
|
|||
type_tooltip = Search type
|
||||
fuzzy = Fuzzy
|
||||
fuzzy_tooltip = Include results that also match the search term closely
|
||||
match = Match
|
||||
match_tooltip = Include only results that match the exact search term
|
||||
exact = Exact
|
||||
exact_tooltip = Include only results that match the exact search term
|
||||
repo_kind = Search repos...
|
||||
user_kind = Search users...
|
||||
org_kind = Search orgs...
|
||||
|
@ -179,6 +179,8 @@ branch_kind = Search branches...
|
|||
commit_kind = Search commits...
|
||||
runner_kind = Search runners...
|
||||
no_results = No matching results found.
|
||||
issue_kind = Search issues...
|
||||
pull_kind = Search pulls...
|
||||
keyword_search_unavailable = Searching by keyword is currently not available. Please contact the site administrator.
|
||||
|
||||
[aria]
|
||||
|
@ -714,7 +716,7 @@ cancel = Cancel
|
|||
language = Language
|
||||
ui = Theme
|
||||
hidden_comment_types = Hidden comment types
|
||||
hidden_comment_types_description = Comment types checked here will not be shown inside issue pages. Checking "Label" for example removes all "<user> added/removed <label>" comments.
|
||||
hidden_comment_types_description = Comment types checked here will not be shown inside issue pages. Checking "Label" for example removes all "{user} added/removed {label}" comments.
|
||||
hidden_comment_types.ref_tooltip = Comments where this issue was referenced from another issue/commit/…
|
||||
hidden_comment_types.issue_ref_tooltip = Comments where the user changes the branch/tag associated with the issue
|
||||
comment_type_group_reference = Reference
|
||||
|
@ -885,6 +887,7 @@ repo_and_org_access = Repository and Organization Access
|
|||
permissions_public_only = Public only
|
||||
permissions_access_all = All (public, private, and limited)
|
||||
select_permissions = Select permissions
|
||||
permission_not_set = Not set
|
||||
permission_no_access = No Access
|
||||
permission_read = Read
|
||||
permission_write = Read and Write
|
||||
|
@ -1289,7 +1292,7 @@ editor.or = or
|
|||
editor.cancel_lower = Cancel
|
||||
editor.commit_signed_changes = Commit Signed Changes
|
||||
editor.commit_changes = Commit Changes
|
||||
editor.add_tmpl = Add '<filename>'
|
||||
editor.add_tmpl = Add '{filename}'
|
||||
editor.add = Add %s
|
||||
editor.update = Update %s
|
||||
editor.delete = Delete %s
|
||||
|
@ -2096,6 +2099,7 @@ settings.advanced_settings = Advanced Settings
|
|||
settings.wiki_desc = Enable Repository Wiki
|
||||
settings.use_internal_wiki = Use Built-In Wiki
|
||||
settings.default_wiki_branch_name = Default Wiki Branch Name
|
||||
settings.default_wiki_everyone_access = Default Access Permission for signed-in users:
|
||||
settings.failed_to_change_default_wiki_branch = Failed to change the default wiki branch.
|
||||
settings.use_external_wiki = Use External Wiki
|
||||
settings.external_wiki_url = External Wiki URL
|
||||
|
@ -3087,14 +3091,14 @@ auths.tips = Tips
|
|||
auths.tips.oauth2.general = OAuth2 Authentication
|
||||
auths.tips.oauth2.general.tip = When registering a new OAuth2 authentication, the callback/redirect URL should be:
|
||||
auths.tip.oauth2_provider = OAuth2 Provider
|
||||
auths.tip.bitbucket = Register a new OAuth consumer on https://bitbucket.org/account/user/<your username>/oauth-consumers/new and add the permission 'Account' - 'Read'
|
||||
auths.tip.bitbucket = Register a new OAuth consumer on https://bitbucket.org/account/user/{your-username}/oauth-consumers/new and add the permission 'Account' - 'Read'
|
||||
auths.tip.nextcloud = Register a new OAuth consumer on your instance using the following menu "Settings -> Security -> OAuth 2.0 client"
|
||||
auths.tip.dropbox = Create a new application at https://www.dropbox.com/developers/apps
|
||||
auths.tip.facebook = Register a new application at https://developers.facebook.com/apps and add the product "Facebook Login"
|
||||
auths.tip.github = Register a new OAuth application on https://github.com/settings/applications/new
|
||||
auths.tip.gitlab_new = Register a new application on https://gitlab.com/-/profile/applications
|
||||
auths.tip.google_plus = Obtain OAuth2 client credentials from the Google API console at https://console.developers.google.com/
|
||||
auths.tip.openid_connect = Use the OpenID Connect Discovery URL (<server>/.well-known/openid-configuration) to specify the endpoints
|
||||
auths.tip.openid_connect = Use the OpenID Connect Discovery URL "https://{server}/.well-known/openid-configuration" to specify the endpoints
|
||||
auths.tip.twitter = Go to https://dev.twitter.com/apps, create an application and ensure that the “Allow this application to be used to Sign in with Twitter” option is enabled
|
||||
auths.tip.discord = Register a new application on https://discordapp.com/developers/applications/me
|
||||
auths.tip.gitea = Register a new OAuth2 application. Guide can be found at https://docs.gitea.com/development/oauth2-provider
|
||||
|
|
|
@ -648,7 +648,6 @@ cancel=Cancelar
|
|||
language=Idioma
|
||||
ui=Tema
|
||||
hidden_comment_types=Tipos de comentarios ocultos
|
||||
hidden_comment_types_description=Los tipos de comentarios marcados aquí no se mostrarán dentro de las páginas de incidencia. Marcar "Etiqueta" por ejemplo elimina todos los comentarios "<user> añadidos/eliminados <label>".
|
||||
hidden_comment_types.ref_tooltip=Comentarios donde esta incidencia fue referenciada desde otra incidencia/commit/…
|
||||
hidden_comment_types.issue_ref_tooltip=Comentarios donde el usuario cambia la rama/etiqueta asociada a la incidencia
|
||||
comment_type_group_reference=Referencia
|
||||
|
@ -1207,7 +1206,6 @@ editor.or=o
|
|||
editor.cancel_lower=Cancelar
|
||||
editor.commit_signed_changes=Crear commit firmado de los cambios
|
||||
editor.commit_changes=Crear commit de los cambios
|
||||
editor.add_tmpl=Añadir '<filename>'
|
||||
editor.add=Añadir %s
|
||||
editor.update=Actualizar %s
|
||||
editor.delete=Eliminar %s
|
||||
|
@ -2953,13 +2951,11 @@ auths.tips=Consejos
|
|||
auths.tips.oauth2.general=Autenticación OAuth2
|
||||
auths.tips.oauth2.general.tip=Al registrar una nueva autenticación de OAuth2, la URL de devolución de llamada/redirección debe ser:
|
||||
auths.tip.oauth2_provider=Proveedor OAuth2
|
||||
auths.tip.bitbucket=Registrar un nuevo usuario de OAuth en https://bitbucket.org/account/user/<your username>/oauth-consumers/new y agregar el permiso 'Cuenta' - 'Lectura'
|
||||
auths.tip.nextcloud=`Registre un nuevo consumidor OAuth en su instancia usando el siguiente menú "Configuración-> Seguridad-> cliente OAuth 2.0"`
|
||||
auths.tip.dropbox=Crear nueva aplicación en https://www.dropbox.com/developers/apps
|
||||
auths.tip.facebook=`Registre una nueva aplicación en https://developers.facebook.com/apps y agregue el producto "Facebook Login"`
|
||||
auths.tip.github=Registre una nueva aplicación OAuth en https://github.com/settings/applications/new
|
||||
auths.tip.google_plus=Obtener credenciales de cliente OAuth2 desde la consola API de Google en https://console.developers.google.com/
|
||||
auths.tip.openid_connect=Use el OpenID Connect Discovery URL (<server>/.well-known/openid-configuration) para especificar los puntos finales
|
||||
auths.tip.twitter=Ir a https://dev.twitter.com/apps, crear una aplicación y asegurarse de que la opción "Permitir que esta aplicación sea usada para iniciar sesión con Twitter" está activada
|
||||
auths.tip.discord=Registrar una nueva aplicación en https://discordapp.com/developers/applications/me
|
||||
auths.tip.gitea=Registrar una nueva aplicación OAuth2. Puede encontrar la guía en https://docs.gitea.com/development/oauth2-provider
|
||||
|
|
|
@ -947,7 +947,6 @@ editor.or=یا
|
|||
editor.cancel_lower=انصراف
|
||||
editor.commit_signed_changes=اعمال تغییرات امضا شده
|
||||
editor.commit_changes=تغییرات کامیت
|
||||
editor.add_tmpl=افزودن '<filename>'
|
||||
editor.commit_message_desc=توضیحی تخصصی به دلخواه اضافه نمایید…
|
||||
editor.signoff_desc=یک تریلر Signed-off-by توسط committer در انتهای پیام گزارش commit اضافه کنید.
|
||||
editor.commit_directly_to_this_branch=ثبت کامیت به صورت مستقیم در انشعاب <strong class="branch-name">%s</strong>.
|
||||
|
@ -2297,13 +2296,11 @@ auths.sspi_default_language_helper=زبان پیش فرض برای کاربرا
|
|||
auths.tips=ﻧﮑﺎﺕ
|
||||
auths.tips.oauth2.general=احراز هویت OAuth2
|
||||
auths.tip.oauth2_provider=تامین کننده OAuth2
|
||||
auths.tip.bitbucket=ثبت یک OAuth جدید مصرف کننده بر https://bitbucket.org/account/user/<your username>/oauth-consumers/new و افزودن مجوز 'Account' - 'Read'
|
||||
auths.tip.nextcloud=با استفاده از منوی زیر "تنظیمات -> امنیت -> مشتری OAuth 2.0" مصرف کننده OAuth جدیدی را در نمونه خود ثبت کنید
|
||||
auths.tip.dropbox=یک برنامه جدید در https://www.dropbox.com/developers/apps بسازید
|
||||
auths.tip.facebook=`یک برنامه جدید در https://developers.facebook.com/apps بسازید برای ورود از طریق فیس بوک قسمت محصولات "Facebook Login"`
|
||||
auths.tip.github=یک برنامه OAuth جدید در https://github.com/settings/applications/new ثبت کنید
|
||||
auths.tip.google_plus=اطلاعات مربوط به مشتری OAuth2 را از کلاینت API Google در https://console.developers.google.com/
|
||||
auths.tip.openid_connect=برای مشخص کردن نقاط پایانی از آدرس OpenID Connect Discovery URL (<server> /.well-known/openid-configuration) استفاده کنید.
|
||||
auths.tip.twitter=به https://dev.twitter.com/apps بروید ، برنامه ای ایجاد کنید و اطمینان حاصل کنید که گزینه "اجازه استفاده از این برنامه برای ورود به سیستم با Twitter" را فعال کنید
|
||||
auths.tip.discord=یک برنامه جدید را در https://discordapp.com/developers/applications/me ثبت کنید
|
||||
auths.tip.yandex=`یک برنامه جدید در https://oauth.yandex.com/client/new ایجاد کنید. مجوزهای زیر را از بخش "Yandex.Passport API" انتخاب کنید: "دسترسی به آدرس ایمیل"، "دسترسی به آواتار کاربر" و "دسترسی به نام کاربری، نام و نام خانوادگی، جنسیت"`
|
||||
|
|
|
@ -767,7 +767,6 @@ editor.or=tai
|
|||
editor.cancel_lower=Peru
|
||||
editor.commit_signed_changes=Commitoi vahvistetut muutokset
|
||||
editor.commit_changes=Commitoi muutokset
|
||||
editor.add_tmpl=Lisää '<filename>'
|
||||
editor.commit_directly_to_this_branch=Commitoi suoraan <strong class="branch-name">%s</strong> haaraan.
|
||||
editor.create_new_branch=Luo <strong>uusi haara</strong> tälle commitille ja aloita vetopyyntö.
|
||||
editor.create_new_branch_np=Luo <strong>uusi haara</strong> tälle commitille.
|
||||
|
|
|
@ -150,6 +150,10 @@ filter.private=Privé
|
|||
|
||||
|
||||
[search]
|
||||
exact=Exact
|
||||
exact_tooltip=Inclure uniquement les résultats qui correspondent exactement au terme de recherche
|
||||
issue_kind=Recherche de tickets…
|
||||
pull_kind=Recherche de demandes d’ajouts…
|
||||
|
||||
[aria]
|
||||
navbar=Barre de navigation
|
||||
|
@ -654,7 +658,6 @@ cancel=Annuler
|
|||
language=Langue
|
||||
ui=Thème
|
||||
hidden_comment_types=Catégories de commentaires masqués
|
||||
hidden_comment_types_description=Cochez les catégories suivantes pour masquer les commentaires correspondants des fils d'activité. Par exemple, « Label » cache les commentaires du genre « Cerise a attribué le label Bug il y a 2 heures. »
|
||||
hidden_comment_types.ref_tooltip=Commentaires où ce ticket a été référencé sur un autre ticket, révision, etc.
|
||||
hidden_comment_types.issue_ref_tooltip=Commentaires où l’utilisateur change la branche/étiquette associée au ticket
|
||||
comment_type_group_reference=Référence
|
||||
|
@ -825,6 +828,7 @@ repo_and_org_access=Accès aux Organisations et Dépôts
|
|||
permissions_public_only=Publique uniquement
|
||||
permissions_access_all=Tout (public, privé et limité)
|
||||
select_permissions=Sélectionner les autorisations
|
||||
permission_not_set=Non défini
|
||||
permission_no_access=Aucun accès
|
||||
permission_read=Lecture
|
||||
permission_write=Lecture et écriture
|
||||
|
@ -1223,7 +1227,6 @@ editor.or=ou
|
|||
editor.cancel_lower=Annuler
|
||||
editor.commit_signed_changes=Réviser les changements (signé)
|
||||
editor.commit_changes=Réviser les changements
|
||||
editor.add_tmpl=Ajouter '<filename>'
|
||||
editor.add=Ajouter %s
|
||||
editor.update=Actualiser %s
|
||||
editor.delete=Supprimer %s
|
||||
|
@ -2018,6 +2021,7 @@ settings.branches.add_new_rule=Ajouter une nouvelle règle
|
|||
settings.advanced_settings=Paramètres avancés
|
||||
settings.wiki_desc=Activer le wiki du dépôt
|
||||
settings.use_internal_wiki=Utiliser le wiki interne
|
||||
settings.default_wiki_everyone_access=Autorisation d’accès par défaut pour les utilisateurs connectés :
|
||||
settings.use_external_wiki=Utiliser un wiki externe
|
||||
settings.external_wiki_url=URL Wiki externe
|
||||
settings.external_wiki_url_error=L’URL du wiki externe n’est pas une URL valide.
|
||||
|
@ -2997,13 +3001,11 @@ auths.tips=Conseils
|
|||
auths.tips.oauth2.general=Authentification OAuth2
|
||||
auths.tips.oauth2.general.tip=Lors de l'enregistrement d'une nouvelle authentification OAuth2, l'URL de rappel/redirection doit être :
|
||||
auths.tip.oauth2_provider=Fournisseur OAuth2
|
||||
auths.tip.bitbucket=`Créez un nouveau jeton OAuth sur https://bitbucket.org/account/user/<your username>/oauth-consumers/new et ajoutez la permission "Compte"-"Lecture"`
|
||||
auths.tip.nextcloud=`Enregistrez un nouveau consommateur OAuth sur votre instance en utilisant le menu "Paramètres -> Sécurité -> Client OAuth 2.0"`
|
||||
auths.tip.dropbox=Créez une nouvelle application sur https://www.dropbox.com/developers/apps
|
||||
auths.tip.facebook=`Enregistrez une nouvelle application sur https://developers.facebook.com/apps et ajoutez le produit "Facebook Login"`
|
||||
auths.tip.github=Créez une nouvelle application OAuth sur https://github.com/settings/applications/new
|
||||
auths.tip.google_plus=Obtenez des identifiants OAuth2 sur la console API de Google (https://console.developers.google.com/)
|
||||
auths.tip.openid_connect=Utilisez l'URL de découvert OpenID (<server>/.well-known/openid-configuration) pour spécifier les points d'accès
|
||||
auths.tip.twitter=Rendez-vous sur https://dev.twitter.com/apps, créez une application et assurez-vous que l'option "Autoriser l'application à être utilisée avec Twitter Connect" est activée
|
||||
auths.tip.discord=Enregistrer une nouvelle application sur https://discordapp.com/developers/applications/me
|
||||
auths.tip.gitea=Enregistrez une nouvelle application OAuth2. Le guide peut être trouvé sur https://docs.gitea.com/development/oauth2-provider
|
||||
|
|
|
@ -711,7 +711,6 @@ editor.name_your_file=Fájl elnevezése…
|
|||
editor.or=vagy
|
||||
editor.cancel_lower=Mégse
|
||||
editor.commit_changes=Változások Véglegesítése
|
||||
editor.add_tmpl='<filename>' hozzáadása
|
||||
editor.commit_message_desc=Opcionális hosszabb leírás hozzáadása…
|
||||
editor.commit_directly_to_this_branch=Mentés egyenesen a(z) <strong class="branch-name">%s</strong> ágba.
|
||||
editor.create_new_branch=Hozzon létre egy <strong>új ágat</strong> ennek a commit-nak és indíts egy egyesítési kérést.
|
||||
|
@ -1401,12 +1400,10 @@ auths.enable_auto_register=Automatikus regisztráció engedélyezése
|
|||
auths.tips=Tippek
|
||||
auths.tips.oauth2.general=OAuth2 hitelesítés
|
||||
auths.tip.oauth2_provider=OAuth2 szolgáltató
|
||||
auths.tip.bitbucket=Igényeljen egy új OAuth jogosultságot itt: https://bitbucket.org/account/user/<felhasználóneved>/oauth-consumers/new és adja hozzá jogosultságot a "Fiókok"-"Olvasás" alá
|
||||
auths.tip.dropbox=Vegyen fel új alkalmazást itt: https://www.dropbox.com/developers/apps
|
||||
auths.tip.facebook=Vegyen fel új alkalmazást itt: https://developers.facebook.com/apps majd adja hozzá a "Facebook Login"-t
|
||||
auths.tip.github=Vegyen fel új OAuth alkalmazást itt: https://github.com/settings/applications/new
|
||||
auths.tip.google_plus=Szerezzen OAuth2 kliens hitelesítési adatokat a Google API konzolban (https://console.developers.google.com/)
|
||||
auths.tip.openid_connect=Használja az OpenID kapcsolódás felfedező URL-t (<kiszolgáló>/.well-known/openid-configuration) a végpontok beállításához
|
||||
auths.tip.twitter=Menyjen ide: https://dev.twitter.com/apps, hozzon létre egy alkalmazást és győződjön meg róla, hogy az “Allow this application to be used to Sign in with Twitter” opció be van kapcsolva
|
||||
auths.tip.discord=Vegyen fel új alkalmazást itt:
|
||||
https://discordapp.com/developers/applications/me
|
||||
|
|
|
@ -620,7 +620,6 @@ editor.filename_help=Tambahkan direktori dengan mengetikkan nama direktori diiku
|
|||
editor.or=atau
|
||||
editor.cancel_lower=Batalkan
|
||||
editor.commit_changes=Perubahan komitmen
|
||||
editor.add_tmpl=Tambahkan '<filename>'
|
||||
editor.commit_message_desc=Tambahkan deskripsi opsional yang panjang…
|
||||
editor.commit_directly_to_this_branch=Komitmen langsung ke <strong class="branch-name">%s</strong> cabang.
|
||||
editor.create_new_branch=Membuat <strong>new branch</strong> untuk tarik komit ini mulai permintaan.
|
||||
|
@ -1118,7 +1117,6 @@ auths.tip.oauth2_provider=Penyediaan OAuth2
|
|||
auths.tip.dropbox=Membuat aplikasi baru di https://www.dropbox.com/developers/apps
|
||||
auths.tip.facebook=`Daftarkan sebuah aplikasi baru di https://developers.facebook.com/apps dan tambakan produk "Facebook Masuk"`
|
||||
auths.tip.github=Mendaftar aplikasi OAuth baru di https://github.com/settings/applications/new
|
||||
auths.tip.openid_connect=Gunakan membuka ID yang terhubung ke jelajah URL (<server>/.well-known/openid-configuration) untuk menentukan titik akhir
|
||||
auths.delete=Menghapus Otentikasi Sumber
|
||||
auths.delete_auth_title=Menghapus Otentikasi Sumber
|
||||
|
||||
|
|
|
@ -697,7 +697,6 @@ editor.delete_this_file=Eyða Skrá
|
|||
editor.name_your_file=Nefndu skrána þína…
|
||||
editor.or=eða
|
||||
editor.cancel_lower=Hætta við
|
||||
editor.add_tmpl=Bæta við „<filename>“
|
||||
editor.create_new_branch=Búðu til <strong>nýja grein</strong> og sameiningarbeiðni fyrir þetta framlag.
|
||||
editor.create_new_branch_np=Búðu til <strong>nýja grein</strong> fyrir þetta framlag.
|
||||
editor.new_branch_name_desc=Heiti nýjar greinar…
|
||||
|
|
|
@ -1018,7 +1018,6 @@ editor.or=o
|
|||
editor.cancel_lower=Annulla
|
||||
editor.commit_signed_changes=Conferma modifiche firmate
|
||||
editor.commit_changes=Apporta le modifiche
|
||||
editor.add_tmpl=Aggiungi '<filename>'
|
||||
editor.patch=Applica Patch
|
||||
editor.patching=Patching:
|
||||
editor.new_patch=Nuova Patch
|
||||
|
@ -2489,13 +2488,11 @@ auths.sspi_default_language_helper=Lingua predefinita per gli utenti creati auto
|
|||
auths.tips=Consigli
|
||||
auths.tips.oauth2.general=Autenticazione OAuth2
|
||||
auths.tip.oauth2_provider=OAuth2 Provider
|
||||
auths.tip.bitbucket=Registra un nuovo cliente OAuth su https://bitbucket.org/account/user/<your username>/oauth-consumers/new e aggiungi il permesso 'Account' - 'Read'
|
||||
auths.tip.nextcloud=`Registra un nuovo OAuth sulla tua istanza utilizzando il seguente menu "Impostazioni -> Sicurezza -> OAuth 2.0 client"`
|
||||
auths.tip.dropbox=Crea una nuova applicazione su https://www.dropbox.com/developers/apps
|
||||
auths.tip.facebook=`Registra una nuova applicazione su https://developers.facebook.com/apps e aggiungi il prodotto "Facebook Login"`
|
||||
auths.tip.github=Registra una nuova applicazione OAuth su https://github.com/settings/applications/new
|
||||
auths.tip.google_plus=Ottieni le credenziali del client OAuth2 dalla console API di Google su https://console.developers.google.com/
|
||||
auths.tip.openid_connect=Utilizza l'OpenID Connect Discovery URL (<server>/.well-known/openid-configuration) per specificare gli endpoint
|
||||
auths.tip.twitter=Vai su https://dev.twitter.com/apps, crea una applicazione e assicurati che l'opzione "Allow this application to be used to Sign In with Twitter" sia abilitata
|
||||
auths.tip.discord=Registra una nuova applicazione su https://discordapp.com/developers/applications/me
|
||||
auths.tip.yandex=`Crea una nuova applicazione su https://oauth.yandex.com/client/new. Seleziona i seguenti permessi da "Yandex. assport API": "Access to email address", "Access to user avatar" e "Access to username, name and surname, gender"`
|
||||
|
|
|
@ -164,8 +164,6 @@ search=検索…
|
|||
type_tooltip=検索タイプ
|
||||
fuzzy=あいまい
|
||||
fuzzy_tooltip=検索ワードに近い結果も含めます
|
||||
match=一致
|
||||
match_tooltip=検索ワードと完全に一致する結果のみ含めます
|
||||
repo_kind=リポジトリを検索...
|
||||
user_kind=ユーザーを検索...
|
||||
org_kind=組織を検索...
|
||||
|
@ -709,7 +707,6 @@ cancel=キャンセル
|
|||
language=言語
|
||||
ui=テーマ
|
||||
hidden_comment_types=非表示にするコメントの種類
|
||||
hidden_comment_types_description=ここでチェックを入れたコメントの種類は、イシューのページには表示されません。 たとえば「ラベル」にチェックを入れると、「<ユーザー> が <ラベル> を追加/削除」といったコメントはすべて除去されます。
|
||||
hidden_comment_types.ref_tooltip=このイシューが別のイシューやコミット等から参照された、というコメント
|
||||
hidden_comment_types.issue_ref_tooltip=このイシューのブランチやタグへの関連付けをユーザーが変更した、というコメント
|
||||
comment_type_group_reference=参照
|
||||
|
@ -1282,7 +1279,6 @@ editor.or=または
|
|||
editor.cancel_lower=キャンセル
|
||||
editor.commit_signed_changes=署名した変更をコミット
|
||||
editor.commit_changes=変更をコミット
|
||||
editor.add_tmpl='<ファイル名>' を追加
|
||||
editor.add=%s を追加
|
||||
editor.update=%s を更新
|
||||
editor.delete=%s を削除
|
||||
|
@ -3080,14 +3076,12 @@ auths.tips=ヒント
|
|||
auths.tips.oauth2.general=OAuth2認証
|
||||
auths.tips.oauth2.general.tip=新しいOAuth2認証を登録するときは、コールバック/リダイレクトURLは以下になります:
|
||||
auths.tip.oauth2_provider=OAuth2プロバイダー
|
||||
auths.tip.bitbucket=新しいOAuthコンシューマーを https://bitbucket.org/account/user/<あなたのユーザー名>/oauth-consumers/new から登録し、"アカウント" に "読み取り" 権限を追加してください。
|
||||
auths.tip.nextcloud=新しいOAuthコンシューマーを、インスタンスのメニュー "Settings -> Security -> OAuth 2.0 client" から登録してください。
|
||||
auths.tip.dropbox=新しいアプリケーションを https://www.dropbox.com/developers/apps から登録してください。
|
||||
auths.tip.facebook=新しいアプリケーションを https://developers.facebook.com/apps で登録し、"Facebook Login"を追加してください。
|
||||
auths.tip.github=新しいOAuthアプリケーションを https://github.com/settings/applications/new から登録してください。
|
||||
auths.tip.gitlab_new=新しいアプリケーションを https://gitlab.com/-/profile/applications から登録してください。
|
||||
auths.tip.google_plus=OAuth2クライアント資格情報を、Google APIコンソール https://console.developers.google.com/ から取得してください。
|
||||
auths.tip.openid_connect=OpenID Connect DiscoveryのURL (<server>/.well-known/openid-configuration) をエンドポイントとして指定してください
|
||||
auths.tip.twitter=https://dev.twitter.com/apps へアクセスしてアプリケーションを作成し、“Allow this application to be used to Sign in with Twitter”オプションを有効にしてください。
|
||||
auths.tip.discord=新しいアプリケーションを https://discordapp.com/developers/applications/me から登録してください。
|
||||
auths.tip.gitea=新しいOAuthアプリケーションを登録してください。 利用ガイドは https://docs.gitea.com/development/oauth2-provider にあります
|
||||
|
|
|
@ -651,7 +651,6 @@ cancel=Atcelt
|
|||
language=Valoda
|
||||
ui=Motīvs
|
||||
hidden_comment_types=Attēlojot paslēpt šauds komentārus:
|
||||
hidden_comment_types_description=Komentāru veidi, kas atzīmēti, netiks rādīti problēmas lapā. Piemēram, atzīmējot "Etiķetes" netiks rādīti komentāri "<lietotājs> pievienoja/noņēma <etiķete>".
|
||||
hidden_comment_types.ref_tooltip=Komentāri, kad problēmai tiek pievienota atsauce uz citu probēmu, komentāru, …
|
||||
hidden_comment_types.issue_ref_tooltip=Komentāri par lietotāja izmaiņām ar problēmas saistīto atzaru/tagu
|
||||
comment_type_group_reference=Atsauces
|
||||
|
@ -1215,7 +1214,6 @@ editor.or=vai
|
|||
editor.cancel_lower=Atcelt
|
||||
editor.commit_signed_changes=Apstiprināt parakstītu revīziju
|
||||
editor.commit_changes=Pabeigt revīziju
|
||||
editor.add_tmpl=Pievienot '<fails>'
|
||||
editor.add=Pievienot %s
|
||||
editor.update=Atjaunot %s
|
||||
editor.delete=Dzēst %s
|
||||
|
@ -2976,13 +2974,11 @@ auths.tips=Padomi
|
|||
auths.tips.oauth2.general=OAuth2 autentifikācija
|
||||
auths.tips.oauth2.general.tip=Kad tiek reģistrēta jauna OAuth2 autentifikācija, atzvanīšanas/pārvirzīšanas URL vajadzētu būt:
|
||||
auths.tip.oauth2_provider=OAuth2 pakalpojuma sniedzējs
|
||||
auths.tip.bitbucket=Reģistrējiet jaunu OAuth klientu adresē https://bitbucket.org/account/user/<jūsu lietotājvārds>/oauth-consumers/new un piešķiriet tam "Account" - "Read" tiesības
|
||||
auths.tip.nextcloud=`Reģistrējiet jaunu OAuth klientu jūsu instances sadāļā "Settings -> Security -> OAuth 2.0 client"`
|
||||
auths.tip.dropbox=Izveidojiet jaunu aplikāciju adresē https://www.dropbox.com/developers/apps
|
||||
auths.tip.facebook=`Reģistrējiet jaunu aplikāciju adresē https://developers.facebook.com/apps un pievienojiet produktu "Facebook Login"`
|
||||
auths.tip.github=Reģistrējiet jaunu aplikāciju adresē https://github.com/settings/applications/new
|
||||
auths.tip.google_plus=Iegūstiet OAuth2 klienta pilnvaru no Google API konsoles adresē https://console.developers.google.com/
|
||||
auths.tip.openid_connect=Izmantojiet OpenID pieslēgšanās atklāšanas URL (<serveris>/.well-known/openid-configuration), lai norādītu galapunktus
|
||||
auths.tip.twitter=Dodieties uz adresi https://dev.twitter.com/apps, izveidojiet lietotni un pārliecinieties, ka ir atzīmēts “Allow this application to be used to Sign in with Twitter”
|
||||
auths.tip.discord=Reģistrējiet jaunu aplikāciju adresē https://discordapp.com/developers/applications/me
|
||||
auths.tip.gitea=Pievienot jaunu OAuth2 lietojumprogrammu. Dokumentācija ir pieejama https://docs.gitea.com/development/oauth2-provider
|
||||
|
|
|
@ -1016,7 +1016,6 @@ editor.or=of
|
|||
editor.cancel_lower=Annuleer
|
||||
editor.commit_signed_changes=Commit Ondertekende Wijzigingen
|
||||
editor.commit_changes=Wijzigingen doorvoeren
|
||||
editor.add_tmpl='<filename>' toevoegen
|
||||
editor.patch=Patch toepassen
|
||||
editor.patching=Patchen:
|
||||
editor.new_patch=Nieuwe Patch
|
||||
|
@ -2345,7 +2344,6 @@ auths.tip.dropbox=Maak een nieuwe applicatie aan op https://www.dropbox.com/deve
|
|||
auths.tip.facebook=Registreer een nieuwe applicatie op https://developers.facebook.com/apps en voeg het product "Facebook Login" toe
|
||||
auths.tip.github=Registreer een nieuwe OAuth toepassing op https://github.com/settings/applications/new
|
||||
auths.tip.google_plus=Verkrijg OAuth2 client referenties van de Google API console op https://console.developers.google.com/
|
||||
auths.tip.openid_connect=Gebruik de OpenID Connect Discovery URL (<server>/.well-known/openid-configuration) om de eindpunten op te geven
|
||||
auths.tip.yandex=`Maak een nieuwe applicatie aan op https://oauth.yandex.com/client/new. Selecteer de volgende machtigingen van de "Yandex". assport API sectie: "Toegang tot e-mailadres", "Toegang tot avatar" en "Toegang tot gebruikersnaam, voornaam en achternaam, geslacht"`
|
||||
auths.edit=Authenticatiebron bewerken
|
||||
auths.activated=Deze authenticatiebron is geactiveerd
|
||||
|
|
|
@ -950,7 +950,6 @@ editor.or=lub
|
|||
editor.cancel_lower=Anuluj
|
||||
editor.commit_signed_changes=Zatwierdź podpisane zmiany
|
||||
editor.commit_changes=Zatwierdź zmiany
|
||||
editor.add_tmpl=Dodanie '<filename>'
|
||||
editor.commit_message_desc=Dodaj dodatkowy rozszerzony opis…
|
||||
editor.commit_directly_to_this_branch=Zmieniaj bezpośrednio gałąź <strong class="branch-name">%s</strong>.
|
||||
editor.create_new_branch=Stwórz <strong>nową gałąź</strong> dla tego commita i rozpocznij Pull Request.
|
||||
|
@ -2223,13 +2222,11 @@ auths.sspi_default_language_helper=Domyślny język dla użytkowników automatyc
|
|||
auths.tips=Wskazówki
|
||||
auths.tips.oauth2.general=Uwierzytelnianie OAuth2
|
||||
auths.tip.oauth2_provider=Dostawca OAuth2
|
||||
auths.tip.bitbucket=`Zarejestruj nowego konsumenta OAuth na https://bitbucket.org/account/user/<twoja nazwa użytkownika>/oauth-consumers/new i dodaj uprawnienie "Account" - "Read"`
|
||||
auths.tip.nextcloud=`Zarejestruj nowego klienta OAuth w swojej instancji za pomocą menu "Ustawienia -> Bezpieczeństwo -> Klient OAuth 2.0"`
|
||||
auths.tip.dropbox=Stwórz nową aplikację na https://www.dropbox.com/developers/apps
|
||||
auths.tip.facebook=`Zarejestruj nową aplikację na https://developers.facebook.com/apps i dodaj produkt "Facebook Login"`
|
||||
auths.tip.github=Zarejestruj nową aplikację OAuth na https://github.com/settings/applications/new
|
||||
auths.tip.google_plus=Uzyskaj dane uwierzytelniające klienta OAuth2 z konsoli Google API na https://console.developers.google.com/
|
||||
auths.tip.openid_connect=Użyj adresu URL OpenID Connect Discovery (<server>/.well-known/openid-configuration), aby określić punkty końcowe
|
||||
auths.tip.twitter=Przejdź na https://dev.twitter.com/apps, stwórz aplikację i upewnij się, że opcja “Allow this application to be used to Sign in with Twitter” jest włączona
|
||||
auths.tip.discord=Zarejestruj nową aplikację na https://discordapp.com/developers/applications/me
|
||||
auths.tip.yandex=`Utwórz nową aplikację na https://oauth.yandex.com/client/new. Wybierz następujące uprawnienia z "Yandex.Passport API": "Access to email address", "Access to user avatar" and "Access to username, first name and surname, gender"`
|
||||
|
|
|
@ -652,7 +652,6 @@ cancel=Cancelar
|
|||
language=Idioma
|
||||
ui=Tema
|
||||
hidden_comment_types=Tipos de comentários ocultos
|
||||
hidden_comment_types_description=Os tipos de comentários marcados aqui não serão exibidos nas páginas de issues. Marcar "Rótulo", por exemplo, remove todos os comentários "<usuário> adicionou/removeu <rótulo>".
|
||||
hidden_comment_types.ref_tooltip=Comentários onde este issue foi referenciado de outro issue/commit/…
|
||||
hidden_comment_types.issue_ref_tooltip=Comentários onde o usuário altera o branch/tag associado ao issue
|
||||
comment_type_group_reference=Referência
|
||||
|
@ -1212,7 +1211,6 @@ editor.or=ou
|
|||
editor.cancel_lower=Cancelar
|
||||
editor.commit_signed_changes=Commit de alteradores assinadas
|
||||
editor.commit_changes=Aplicar commit das alterações
|
||||
editor.add_tmpl=Adicionar '<filename>'
|
||||
editor.add=Adicionar %s
|
||||
editor.update=Atualizar %s
|
||||
editor.delete=Excluir %s
|
||||
|
@ -2918,13 +2916,11 @@ auths.tips=Dicas
|
|||
auths.tips.oauth2.general=Autenticação OAuth2
|
||||
auths.tips.oauth2.general.tip=Ao registrar uma nova autenticação OAuth2, o URL de retorno de chamada/redirecionamento deve ser:
|
||||
auths.tip.oauth2_provider=Provedor OAuth2
|
||||
auths.tip.bitbucket=Cadastrar um novo consumidor de OAuth em https://bitbucket.org/account/user/<seu nome de usuário> e adicionar a permissão 'Account' - 'Read'
|
||||
auths.tip.nextcloud=`Registre um novo consumidor OAuth em sua instância usando o seguinte menu "Configurações -> Segurança -> Cliente OAuth 2.0"`
|
||||
auths.tip.dropbox=Criar um novo aplicativo em https://www.dropbox.com/developers/apps
|
||||
auths.tip.facebook=`Cadastrar um novo aplicativo em https://developers.facebook.com/apps e adicionar o produto "Facebook Login"`
|
||||
auths.tip.github=Cadastrar um novo aplicativo de OAuth na https://github.com/settings/applications/new
|
||||
auths.tip.google_plus=Obter credenciais de cliente OAuth2 do console de API do Google em https://console.developers.google.com/
|
||||
auths.tip.openid_connect=Use o OpenID Connect Discovery URL (<servidor>/.well-known/openid-configuration) para especificar os endpoints
|
||||
auths.tip.twitter=Vá em https://dev.twitter.com/apps, crie um aplicativo e certifique-se de que está habilitada a opção “Allow this application to be used to Sign in with Twitter“
|
||||
auths.tip.discord=Cadastrar um novo aplicativo em https://discordapp.com/developers/applications/me
|
||||
auths.tip.yandex=`Crie um novo aplicativo em https://oauth.yandex.com/client/new. Selecione as seguintes permissões da seção "Yandex.Passport API": "Access to email address", "Access to user avatar" and "Access to username, first name and surname, gender"`
|
||||
|
|
|
@ -164,8 +164,8 @@ search=Pesquisar...
|
|||
type_tooltip=Tipo de pesquisa
|
||||
fuzzy=Aproximada
|
||||
fuzzy_tooltip=Incluir também os resultados que estejam próximos do termo de pesquisa
|
||||
match=Fiel
|
||||
match_tooltip=Incluir somente os resultados que correspondam rigorosamente ao termo de pesquisa
|
||||
exact=Fiel
|
||||
exact_tooltip=Incluir somente os resultados que correspondam rigorosamente ao termo de pesquisa
|
||||
repo_kind=Pesquisar repositórios...
|
||||
user_kind=Pesquisar utilizadores...
|
||||
org_kind=Pesquisar organizações...
|
||||
|
@ -179,6 +179,8 @@ branch_kind=Pesquisar ramos...
|
|||
commit_kind=Pesquisar cometimentos...
|
||||
runner_kind=Pesquisar executores...
|
||||
no_results=Não foram encontrados resultados correspondentes.
|
||||
issue_kind=Pesquisar questões...
|
||||
pull_kind=Pesquisar puxadas...
|
||||
keyword_search_unavailable=Pesquisar por palavra-chave não está disponível, neste momento. Entre em contacto com o administrador.
|
||||
|
||||
[aria]
|
||||
|
@ -714,7 +716,7 @@ cancel=Cancelar
|
|||
language=Idioma
|
||||
ui=Tema
|
||||
hidden_comment_types=Tipos de comentários ocultos
|
||||
hidden_comment_types_description=Os tipos de comentário marcados aqui não serão mostrados dentro das páginas das questões. Marcar "Rótulo", por exemplo, remove todos os comentários "<utilizador> adicionou/removeu <rótulo>".
|
||||
hidden_comment_types_description=Os tipos de comentário marcados aqui não serão mostrados dentro das páginas das questões. Marcar "Rótulo", por exemplo, remove todos os comentários "{user} adicionou/removeu {label}".
|
||||
hidden_comment_types.ref_tooltip=Comentários onde esta questão foi referenciada a partir de outra questão/cometimento/…
|
||||
hidden_comment_types.issue_ref_tooltip=Comentários onde o utilizador altera o ramo/etiqueta associado à questão
|
||||
comment_type_group_reference=Referência
|
||||
|
@ -885,6 +887,7 @@ repo_and_org_access=Acesso aos repositórios e às organizações
|
|||
permissions_public_only=Apenas público
|
||||
permissions_access_all=Tudo (público, privado e limitado)
|
||||
select_permissions=Escolher permissões
|
||||
permission_not_set=Não definido
|
||||
permission_no_access=Sem acesso
|
||||
permission_read=Lidas
|
||||
permission_write=Leitura e escrita
|
||||
|
@ -1289,7 +1292,7 @@ editor.or=ou
|
|||
editor.cancel_lower=Cancelar
|
||||
editor.commit_signed_changes=Cometer modificações assinadas
|
||||
editor.commit_changes=Cometer modificações
|
||||
editor.add_tmpl=Adicionar '<filename>'
|
||||
editor.add_tmpl=Adicionar '{filename}'
|
||||
editor.add=Adicionar %s
|
||||
editor.update=Modificar %s
|
||||
editor.delete=Eliminar %s
|
||||
|
@ -2096,6 +2099,7 @@ settings.advanced_settings=Configurações avançadas
|
|||
settings.wiki_desc=Habilitar wiki do repositório
|
||||
settings.use_internal_wiki=Usar o wiki nativo
|
||||
settings.default_wiki_branch_name=Nome do ramo predefinido do wiki
|
||||
settings.default_wiki_everyone_access=Permissão de acesso predefinida para utilizadores registados:
|
||||
settings.failed_to_change_default_wiki_branch=Falhou ao mudar o nome do ramo predefinido do wiki.
|
||||
settings.use_external_wiki=Usar um wiki externo
|
||||
settings.external_wiki_url=URL do wiki externo
|
||||
|
@ -3087,14 +3091,14 @@ auths.tips=Dicas
|
|||
auths.tips.oauth2.general=Autenticação OAuth2
|
||||
auths.tips.oauth2.general.tip=Ao registar uma nova autenticação OAuth2, o URL da ligação de retorno ou do reencaminhamento deve ser:
|
||||
auths.tip.oauth2_provider=Fornecedor OAuth2
|
||||
auths.tip.bitbucket=Registe um novo consumidor de OAuth em https://bitbucket.org/account/user/<o_seu_nome_de_utilizador>/oauth-consumers/new e adicione a permissão 'Account' - 'Read'
|
||||
auths.tip.bitbucket=Registe um novo consumidor de OAuth em https://bitbucket.org/account/user/{your-username}/oauth-consumers/new e adicione a permissão 'Account' - 'Read'
|
||||
auths.tip.nextcloud=`Registe um novo consumidor OAuth na sua instância usando o seguinte menu "Configurações → Segurança → Cliente OAuth 2.0"`
|
||||
auths.tip.dropbox=Crie uma nova aplicação em https://www.dropbox.com/developers/apps
|
||||
auths.tip.facebook=`Registe uma nova aplicação em https://developers.facebook.com/apps e adicione o produto "Facebook Login"`
|
||||
auths.tip.github=Registe uma nova aplicação OAuth em https://github.com/settings/applications/new
|
||||
auths.tip.gitlab_new=Registe uma nova aplicação em https://gitlab.com/-/profile/applications
|
||||
auths.tip.google_plus=Obtenha credenciais de cliente OAuth2 a partir da consola do Google API em https://console.developers.google.com/
|
||||
auths.tip.openid_connect=Use o URL da descoberta de conexão OpenID (<server>/.well-known/openid-configuration) para especificar os extremos
|
||||
auths.tip.openid_connect=Use o URL da descoberta de conexão OpenID "https://{server}/.well-known/openid-configuration" para especificar os extremos
|
||||
auths.tip.twitter=`Vá a https://dev.twitter.com/apps, crie uma aplicação e certifique-se de que está habilitada a opção "Allow this application to be used to Sign in with Twitter"`
|
||||
auths.tip.discord=Registe uma nova aplicação em https://discordapp.com/developers/applications/me
|
||||
auths.tip.gitea=Registe uma nova aplicação OAuth2. O guia pode ser encontrado em https://docs.gitea.com/development/oauth2-provider
|
||||
|
|
|
@ -649,7 +649,6 @@ cancel=Отмена
|
|||
language=Язык
|
||||
ui=Тема
|
||||
hidden_comment_types=Скрытые типы комментариев
|
||||
hidden_comment_types_description=Отмеченные типы комментариев не будут отображаться на страницах задач. Например, если выбрать «Метки», не станет всех комментариев «<пользователь> добавил/удалил <метку>».
|
||||
hidden_comment_types.ref_tooltip=Комментарии об упоминании задачи в другой задаче/коммите/…
|
||||
hidden_comment_types.issue_ref_tooltip=Комментарии об изменении ветки/тега, связанных с этой задачей
|
||||
comment_type_group_reference=Упоминания
|
||||
|
@ -1192,7 +1191,6 @@ editor.or=или
|
|||
editor.cancel_lower=Отменить
|
||||
editor.commit_signed_changes=Зафиксировать подписанные изменения
|
||||
editor.commit_changes=Сохранить правки
|
||||
editor.add_tmpl=Добавить '<filename>'
|
||||
editor.add=Добавить %s
|
||||
editor.update=Обновить %s
|
||||
editor.delete=Удалить %s
|
||||
|
@ -2909,13 +2907,11 @@ auths.sspi_default_language_helper=Язык по умолчанию для по
|
|||
auths.tips=Советы
|
||||
auths.tips.oauth2.general=Аутентификация OAuth2
|
||||
auths.tip.oauth2_provider=Поставщик OAuth2
|
||||
auths.tip.bitbucket=`Создайте OAuth URI на странице https://bitbucket.org/account/user/<имя пользователя>/oauth-consumers/new и добавьте права "Account" - "Read"`
|
||||
auths.tip.nextcloud=`Зарегистрируйте нового потребителя OAuth в вашем экземпляре, используя меню "Settings -> Security -> OAuth 2.0 client"`
|
||||
auths.tip.dropbox=Добавьте новое приложение на https://www.dropbox.com/developers/apps
|
||||
auths.tip.facebook=Зарегистрируйте новое приложение на https://developers.facebook.com/apps и добавьте модуль «Facebook Login»
|
||||
auths.tip.github=Добавьте OAuth приложение на https://github.com/settings/applications/new
|
||||
auths.tip.google_plus=Получите учётные данные клиента OAuth2 в консоли Google API на странице https://console.developers.google.com/
|
||||
auths.tip.openid_connect=Используйте OpenID Connect Discovery URL (<server>/.well-known/openid-configuration) для автоматической настройки входа OAuth
|
||||
auths.tip.twitter=Перейдите на https://dev.twitter.com/apps, создайте приложение и убедитесь, что включена опция «Разрешить это приложение для входа в систему с помощью Twitter»
|
||||
auths.tip.discord=Добавьте новое приложение на https://discordapp.com/developers/applications/me
|
||||
auths.tip.yandex=`Создайте новое приложение по адресу https://oauth.yandex.com/client/new. В разделе "API Яндекс.Паспорта" выберите следующие разрешения: "Доступ к адресу электронной почты", "Доступ к аватару пользователя" и "Доступ к имени пользователя, фамилии и полу"`
|
||||
|
|
|
@ -919,7 +919,6 @@ editor.or=හෝ
|
|||
editor.cancel_lower=අවලංගු කරන්න
|
||||
editor.commit_signed_changes=අත්සන් කළ වෙනස්කම් සිදු කරන්න
|
||||
editor.commit_changes=වෙනස්කම් සිදු කරන්න
|
||||
editor.add_tmpl='<filename>' එකතු කරන්න
|
||||
editor.commit_message_desc=විකල්ප දීර්ඝ විස්තරයක් එක් කරන්න…
|
||||
editor.signoff_desc=කැපවූ ලොග් පණිවිඩය අවසානයේ දී කැපකරු විසින් සිග්නෙඩ්-ඕෆ්-විසින් ට්රේලරයක් එක් කරන්න.
|
||||
editor.commit_directly_to_this_branch=<strong class="branch-name">%s</strong> ශාඛාවට කෙලින්ම කැප කරන්න.
|
||||
|
@ -2261,7 +2260,6 @@ auths.tip.dropbox=https://www.dropbox.com/developers/apps හි නව යෙ
|
|||
auths.tip.facebook=https://developers.facebook.com/apps හි නව යෙදුමක් ලියාපදිංචි කර නිෂ්පාදනය එකතු කරන්න “ෆේස්බුක් ලොගින් වන්න”
|
||||
auths.tip.github=https://github.com/settings/applications/new හි නව OAUTH අයදුම්පතක් ලියාපදිංචි කරන්න
|
||||
auths.tip.google_plus=ගූගල් API කොන්සෝලය වෙතින් OUT2 සේවාදායක අක්තපත්ර ලබා ගන්න https://console.developers.google.com/
|
||||
auths.tip.openid_connect=අන්ත ලක්ෂ්ය නියම කිරීම සඳහා OpenID Connect ඩිස්කවරි URL (<server>/.හොඳින් දැන /openid-වින්යාසය) භාවිතා කරන්න
|
||||
auths.tip.twitter=https://dev.twitter.com/apps වෙත යන්න, යෙදුමක් සාදන්න සහ “මෙම යෙදුම ට්විටර් සමඟ පුරනය වීමට භාවිතා කිරීමට ඉඩ දෙන්න” විකල්පය සක්රීය කර ඇති බවට සහතික වන්න
|
||||
auths.tip.discord=https://discordapp.com/developers/applications/me හි නව අයදුම්පතක් ලියාපදිංචි කරන්න
|
||||
auths.tip.yandex=https://oauth.yandex.com/client/new හි නව යෙදුමක් සාදන්න. “Yandex.Passport API” කොටසේ පහත සඳහන් අවසරයන් තෝරන්න: “විද්යුත් තැපැල් ලිපිනය වෙත ප්රවේශය”, “පරිශීලක අවතාර් වෙත ප්රවේශය” සහ “පරිශීලක නාමය, මුල් නම සහ වාසගම, ස්ත්රී පුරුෂ භාවය”
|
||||
|
|
|
@ -779,7 +779,6 @@ editor.or=eller
|
|||
editor.cancel_lower=Avbryt
|
||||
editor.commit_signed_changes=Committa signerade ändringar
|
||||
editor.commit_changes=Checka in ändringar
|
||||
editor.add_tmpl=Lägg till '<filename>'
|
||||
editor.commit_message_desc=Lägg till en valfri utökad beskrivning…
|
||||
editor.commit_directly_to_this_branch=Checka in direkt till grenen <strong class="branch-name">%s</strong>.
|
||||
editor.create_new_branch=Skapa en <strong>ny gren</strong> för denna incheckning och påbörja en hämtningsbegäran.
|
||||
|
@ -1801,12 +1800,10 @@ auths.enable_auto_register=Aktivera Automatisk Registrering
|
|||
auths.tips=Tips
|
||||
auths.tips.oauth2.general=OAuth2 Autensiering
|
||||
auths.tip.oauth2_provider=OAuth2 leverantör
|
||||
auths.tip.bitbucket=Registrera en ny OAuth konsument på https://bitbucket.org/account/user/<your username>/oauth-consumers/new och lägg till behörighet 'Account' - 'Read'
|
||||
auths.tip.dropbox=Skapa en ny applikation på https://www.dropbox.com/developers/apps
|
||||
auths.tip.facebook=Registrera en ny appliaktion på https://developers.facebook.com/apps och lägg till produkten ”Facebook-inloggning”
|
||||
auths.tip.github=Registrera en ny OAuth applikation på https://github.com/settings/applications/new
|
||||
auths.tip.google_plus=Erhåll inloggningsuppgifter för OAuth2 från Google API-konsolen på https://console.developers.google.com/
|
||||
auths.tip.openid_connect=Använd OpenID Connect Discovery länken (<server>/.well-known/openid-configuration) för att ange slutpunkterna
|
||||
auths.tip.twitter=Gå till https://dev.twitter.com/app, skapa en applikation och försäkra att alternativet "Allow this application to be used to Sign in with Twitter" är aktiverat
|
||||
auths.tip.discord=Registrera en ny applikation på https://discordapp.com/developers/applications/me
|
||||
auths.edit=Redigera autensieringskälla
|
||||
|
|
|
@ -25,6 +25,7 @@ enable_javascript=Bu web sitesinin çalışması için JavaScript gereklidir.
|
|||
toc=İçindekiler Tablosu
|
||||
licenses=Lisanslar
|
||||
return_to_gitea=Gitea'ya Dön
|
||||
more_items=Daha fazla öğe
|
||||
|
||||
username=Kullanıcı Adı
|
||||
email=E-posta Adresi
|
||||
|
@ -113,6 +114,7 @@ loading=Yükleniyor…
|
|||
error=Hata
|
||||
error404=Ulaşmaya çalıştığınız sayfa <strong>mevcut değil</strong> veya <strong>görüntüleme yetkiniz yok</strong>.
|
||||
go_back=Geri Git
|
||||
invalid_data=Geçersiz veri: %v
|
||||
|
||||
never=Asla
|
||||
unknown=Bilinmiyor
|
||||
|
@ -123,6 +125,7 @@ pin=Sabitle
|
|||
unpin=Sabitlemeyi kaldır
|
||||
|
||||
artifacts=Yapılar
|
||||
confirm_delete_artifact=%s yapısını silmek istediğinizden emin misiniz?
|
||||
|
||||
archived=Arşivlenmiş
|
||||
|
||||
|
@ -142,13 +145,43 @@ name=İsim
|
|||
value=Değer
|
||||
|
||||
filter=Filtre
|
||||
filter.clear=Filtreyi Temizle
|
||||
filter.is_archived=Arşivlenmiş
|
||||
filter.not_archived=Arşivlenmemiş
|
||||
filter.is_fork=Çatallanmış
|
||||
filter.not_fork=Çatallanmamış
|
||||
filter.is_mirror=Yansılanmış
|
||||
filter.not_mirror=Yansılanmamış
|
||||
filter.is_template=Şablon
|
||||
filter.not_template=Şablon değil
|
||||
filter.public=Genel
|
||||
filter.private=Özel
|
||||
|
||||
no_results_found=Sonuç bulunamadı.
|
||||
|
||||
[search]
|
||||
search=Ara...
|
||||
type_tooltip=Arama türü
|
||||
fuzzy=Bulanık
|
||||
fuzzy_tooltip=Arama terimine benzeyen sonuçları da içer
|
||||
exact=Tam
|
||||
exact_tooltip=Sadece arama terimiyle tamamen eşleşen sonuçları içer
|
||||
repo_kind=Depoları ara...
|
||||
user_kind=Kullanıcıları ara...
|
||||
org_kind=Organizasyonları ara...
|
||||
team_kind=Takımları ara...
|
||||
code_kind=Kod ara...
|
||||
code_search_unavailable=Kod arama şu an mevcut değil. Lütfen site yöneticisiyle iletişime geçin.
|
||||
code_search_by_git_grep=Mevcut kod arama sonuçları "git grep" ile sağlanıyor. Eğer yönetici Depo Dizinleyici'yi etkinleştirirse daha iyi sonuçlar çıkabilir.
|
||||
package_kind=Paketleri ara...
|
||||
project_kind=Projeleri ara...
|
||||
branch_kind=Dalları ara...
|
||||
commit_kind=İşlemeleri ara...
|
||||
runner_kind=Çalıştırıcıları ara...
|
||||
no_results=Eşleşen sonuç bulunamadı.
|
||||
issue_kind=Konuları ara...
|
||||
pull_kind=Değişiklikleri ara...
|
||||
keyword_search_unavailable=Anahtar kelime ile arama şu an mevcut değil. Lütfen site yöneticinizle iletişime geçin.
|
||||
|
||||
[aria]
|
||||
navbar=Gezinti Çubuğu
|
||||
|
@ -255,6 +288,7 @@ email_title=E-posta Ayarları
|
|||
smtp_addr=SMTP Sunucusu
|
||||
smtp_port=SMTP Portu
|
||||
smtp_from=E-posta Gönderen
|
||||
smtp_from_invalid=`"E-posta Olarak Gönder" adresi geçersiz`
|
||||
smtp_from_helper=Gitea'nın kullanacağı e-posta adresi. Yalın bir e-posta adresi girin veya "İsim" <eposta@ornek.com> biçimini kullanın.
|
||||
mailer_user=SMTP Kullanıcı Adı
|
||||
mailer_password=SMTP Parolası
|
||||
|
@ -314,6 +348,7 @@ 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:
|
||||
|
||||
[home]
|
||||
nav_menu=Gezinti Menüsü
|
||||
uname_holder=Kullanıcı Adı veya E-Posta Adresi
|
||||
password_holder=Parola
|
||||
switch_dashboard_context=Panoya Geçiş Yap
|
||||
|
@ -362,6 +397,7 @@ forgot_password_title=Şifremi unuttum
|
|||
forgot_password=Şifrenizi mi unuttunuz?
|
||||
sign_up_now=Bir hesaba mı ihtiyacınız var? Hemen kaydolun.
|
||||
sign_up_successful=Hesap başarılı bir şekilde oluşturuldu. Hoşgeldiniz!
|
||||
confirmation_mail_sent_prompt_ex=Yeni bir doğrulama e-postası <b>%s</b> adresine gönderildi. Lütfen kayıt sürecini tamamlamak için %s içinde gelen kutunuzu denetleyin. Eğer kayıt e-posta adresiniz hatalı ise, tekrar oturum açıp değiştirebilirsiniz.
|
||||
must_change_password=Parolanızı güncelleyin
|
||||
allow_password_change=Kullanıcıyı parola değiştirmeye zorla (önerilen)
|
||||
reset_password_mail_sent_prompt=<b>%s</b> adresine bir onay e-postası gönderildi. Hesap kurtarma işlemini tamamlamak için lütfen gelen kutunuzu sonraki %s içinde kontrol edin.
|
||||
|
@ -371,6 +407,7 @@ prohibit_login=Oturum Açma Yasağı
|
|||
prohibit_login_desc=Hesabınız ile oturum açmanız yasaklanmış, lütfen site yöneticinizle iletişime geçin.
|
||||
resent_limit_prompt=Zaten bir etkinleştirme e-postası talep ettiniz. Lütfen 3 dakika bekleyip tekrar deneyin.
|
||||
has_unconfirmed_mail=Merhaba %s, doğrulanmamış bir e-posta adresin var (<b>%s</b>). Bir doğrulama e-postası almadıysanız ya da yenisine ihtiyacınız varsa lütfen aşağıdaki düğmeye tıklayın.
|
||||
change_unconfirmed_mail_address=Eğer kayıt e-posta adresiniz hatalı ise, burada değiştirebilir ve yeni bir doğrulama e-postası gönderebilirsiniz.
|
||||
resend_mail=Etkinleştirme e-postasını tekrar almak için buraya tıklayın
|
||||
email_not_associate=Bu e-posta adresi hiçbir hesap ile ilişkilendirilmemiştir.
|
||||
send_reset_mail=Hesap Kurtarma E-postası Gönder
|
||||
|
@ -418,6 +455,7 @@ authorization_failed_desc=Geçersiz bir istek tespit ettiğimiz için yetkilendi
|
|||
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 <a target="_blank" rel="noopener noreferrer" href="https://haveibeenpwned.com/Passwords">çalınan parola listesindedir</a>. 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.
|
||||
|
||||
[mail]
|
||||
view_it_on=%s üzerinde görüntüle
|
||||
|
@ -550,6 +588,7 @@ team_name_been_taken=Takım adı zaten alınmış.
|
|||
team_no_units_error=En az bir depo bölümüne erişimine izin ver.
|
||||
email_been_used=E-posta adresi zaten kullanılıyor.
|
||||
email_invalid=E-posta adresi geçersiz.
|
||||
email_domain_is_not_allowed=Kullanıcı e-posta adresi <b>%s</b> alan adı EMAIL_DOMAIN_ALLOWLIST veya EMAIL_DOMAIN_BLOCKLIST ile çelişiyor. Lütfen işleminizin beklendiğinden emin olun.
|
||||
openid_been_used=OpenID adresi "%s" zaten kullanılıyor.
|
||||
username_password_incorrect=Kullanıcı adı veya parola hatalı.
|
||||
password_complexity=Parola, karmaşıklık gereksinimlerini karşılamıyor:
|
||||
|
@ -561,6 +600,8 @@ enterred_invalid_repo_name=Girdiğiniz depo adı hatalı.
|
|||
enterred_invalid_org_name=Girdiğiniz organizsyon adı hatalı.
|
||||
enterred_invalid_owner_name=Yeni sahip ismi hatalı.
|
||||
enterred_invalid_password=Girdiğiniz parola hatalı.
|
||||
unset_password=Oturum açma kullanıcısı parola belirlemedi.
|
||||
unsupported_login_type=Oturum açma türü hesap silmeyi desteklemiyor.
|
||||
user_not_exist=Böyle bir kullanıcı yok.
|
||||
team_not_exist=Böyle bir takım bulunmuyor.
|
||||
last_org_owner=Son kullanıcıyı 'sahipler' takımından çıkaramazsınız. Bir organizasyonun en az bir sahibi olmalıdır.
|
||||
|
@ -583,6 +624,7 @@ org_still_own_packages=Bu organizasyon hala bir veya daha fazla pakete sahip, ö
|
|||
|
||||
target_branch_not_exist=Hedef dal mevcut değil.
|
||||
|
||||
admin_cannot_delete_self=Yöneticiyken kendinizi silemezsiniz. Lütfen önce yönetici haklarınızı kaldırın.
|
||||
|
||||
[user]
|
||||
change_avatar=Profil resmini değiştir…
|
||||
|
@ -609,6 +651,29 @@ form.name_reserved=`"%s" kullanıcı adı rezerve edilmiş.`
|
|||
form.name_pattern_not_allowed=Kullanıcı adında "%s" deseni kullanılamaz.
|
||||
form.name_chars_not_allowed=`"%s" kullanıcı adı geçersiz karakterler içeriyor.`
|
||||
|
||||
block.block=Engelle
|
||||
block.block.user=Kullanıcıyı engelle
|
||||
block.block.org=Kullanıcıyı organizasyonda engelle
|
||||
block.block.failure=Kullanıcı engellenemedi: %s
|
||||
block.unblock=Engeli kaldır
|
||||
block.unblock.failure=Kullanıcının engeli kaldırılamadı: %s
|
||||
block.blocked=Bu kullanıcıyı engelledin.
|
||||
block.title=Bir kullanıcı engelle
|
||||
block.info=Bir kullanıcıyı engellemek depoarla, değişiklik isteği veya konu açmak veya yorumlamak gibi, etkileşim kurmasını önler. Bir kullanıcı engelleme hakkında daha fazlasını öğrenin.
|
||||
block.info_1=Bir kullanıcıyı engellemek, hesabınızda ve depolarınızda şu eylemleri önler:
|
||||
block.info_2=hesabınızı takip etmek
|
||||
block.info_3=kullanıcı adınızdan @bahsederek size bildirim göndermek
|
||||
block.info_4=kendi depolarına sizi katkıcı olarak davet etmek
|
||||
block.info_5=depolara yıldız koymak, çatallamak veya izlemek
|
||||
block.info_6=konu veya değişiklik isteği açmak ve yorum eklemek
|
||||
block.info_7=konularda veya değişiklik isteklerinde yorumlarınıza tepki vermek
|
||||
block.user_to_block=Engellenecek kullanıcı
|
||||
block.note=Not
|
||||
block.note.title=İsteğe bağlı not:
|
||||
block.note.info=Not engellenen kullanıcıya gösterilmez.
|
||||
block.note.edit=Notu düzenle
|
||||
block.list=Engellenmiş kullanıcılar
|
||||
block.list.none=Engellediğiniz kullanıcı yok.
|
||||
|
||||
[settings]
|
||||
profile=Profil
|
||||
|
@ -651,7 +716,7 @@ cancel=İptal
|
|||
language=Dil
|
||||
ui=Tema
|
||||
hidden_comment_types=Gizli yorum türleri
|
||||
hidden_comment_types_description=Burada işaretlenen yorum türleri konu sayfalarında görüntülenmeyecektir. Örneğin "Etiket" seçildiğinde tüm "<user>, <label> ekledi/çıkardı" yorumları kalkacaktır.
|
||||
hidden_comment_types_description=Burada işaretlenen yorum türleri konu sayfalarında görüntülenmeyecektir. Örneğin "Etiket" seçildiğinde tüm "{user}, {label} ekledi/çıkardı" yorumları kalkacaktır.
|
||||
hidden_comment_types.ref_tooltip=Bu konuya başka konu/işlem tarafından değinilen yorumlar…
|
||||
hidden_comment_types.issue_ref_tooltip=Kullanıcının konuyla ilişkili dalı/etiketi değiştirdiği yorumlar
|
||||
comment_type_group_reference=Referans
|
||||
|
@ -822,6 +887,7 @@ repo_and_org_access=Depo ve Organizasyon Erişimi
|
|||
permissions_public_only=Yalnızca herkese açık
|
||||
permissions_access_all=Tümü (herkese açık, özel ve sınırlı)
|
||||
select_permissions=İzinleri seçin
|
||||
permission_not_set=Ayarlanmadı
|
||||
permission_no_access=Erişim Yok
|
||||
permission_read=Okunmuş
|
||||
permission_write=Okuma ve Yazma
|
||||
|
@ -946,7 +1012,9 @@ fork_visibility_helper=Çatallanmış bir deponun görünürlüğü değiştiril
|
|||
fork_branch=Çatala klonlanacak dal
|
||||
all_branches=Tüm dallar
|
||||
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
|
||||
open_with_editor=%s ile aç
|
||||
download_zip=ZIP indir
|
||||
download_tar=TAR.GZ indir
|
||||
download_bundle=BUNDLE indir
|
||||
|
@ -962,6 +1030,8 @@ 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? <a target="_blank" rel="noopener noreferrer" href="%s">Lisans seçme</a> konusuna bakın
|
||||
object_format=Nesne Biçimi
|
||||
object_format_helper=Deponun nesne biçimi. Daha sonra değiştirilemez. SHA1 en uyumlu olandır.
|
||||
readme=README
|
||||
readme_helper=Bir README dosyası şablonu seçin.
|
||||
readme_helper_desc=Projeniz için eksiksiz bir açıklama yazabileceğiniz yer burasıdır.
|
||||
|
@ -979,6 +1049,7 @@ mirror_prune=Buda
|
|||
mirror_prune_desc=Kullanılmayan uzak depoları izleyen referansları kaldır
|
||||
mirror_interval=Yansı Aralığı (geçerli zaman birimleri 'h', 'm', 's'). Periyodik senkronizasyonu devre dışı bırakmak için 0 kullanın. (Asgari aralık: %s)
|
||||
mirror_interval_invalid=Yansı süre aralığı geçerli değil.
|
||||
mirror_sync=eşitlendi
|
||||
mirror_sync_on_commit=İşlemeler gönderildiğinde senkronize et
|
||||
mirror_address=URL'den Klonla
|
||||
mirror_address_desc=Yetkilendirme bölümüne gerekli tüm kimlik bilgilerini girin.
|
||||
|
@ -996,6 +1067,7 @@ watchers=İzleyenler
|
|||
stargazers=Yıldızlayanlar
|
||||
stars_remove_warning=Bu depodan tüm yıldızları kaldıracaktır.
|
||||
forks=Çatallamalar
|
||||
stars=Yıldızlar
|
||||
reactions_more=ve %d daha fazla
|
||||
unit_disabled=Site yöneticisi bu depo bölümünü devre dışı bıraktı.
|
||||
language_other=Diğer
|
||||
|
@ -1029,6 +1101,7 @@ desc.public=Genel
|
|||
desc.template=Şablon
|
||||
desc.internal=Dahili
|
||||
desc.archived=Arşivlenmiş
|
||||
desc.sha256=SHA256
|
||||
|
||||
template.items=Şablon Öğeleri
|
||||
template.git_content=Git İçeriği (Varsayılan Dal)
|
||||
|
@ -1116,6 +1189,7 @@ watch=İzle
|
|||
unstar=Yıldızı Kaldır
|
||||
star=Yıldızla
|
||||
fork=Çatalla
|
||||
action.blocked_user=İşlem gerçekleştirilemiyor, depo sahibi tarafından engellenmişsiniz.
|
||||
download_archive=Depoyu İndir
|
||||
more_operations=Daha Fazla İşlem
|
||||
|
||||
|
@ -1162,6 +1236,8 @@ file_view_rendered=Oluşturulanları Görüntüle
|
|||
file_view_raw=Ham Görünüm
|
||||
file_permalink=Kalıcı Bağlantı
|
||||
file_too_large=Bu dosya görüntülemek için çok büyük.
|
||||
code_preview_line_from_to=%[3]s içinde %[1]d ve %[2]d arasındaki satırlar
|
||||
code_preview_line_in=%[2]s içinde %[1]d satırı
|
||||
invisible_runes_header=`Bu dosya görünmez Evrensel Kodlu karakter içeriyor`
|
||||
invisible_runes_description=`Bu dosya, insanlar tarafından ayırt edilemeyen ama bir bilgisayar tarafından farklı bir şekilde işlenebilecek görünmez evrensel kodlu karakter içeriyor. Eğer bunu kasıtlı olarak yaptıysanız bu uyarıyı yok sayabilirsiniz. Gizli karakterleri göstermek için Kaçış Karakterli düğmesine tıklayın.`
|
||||
ambiguous_runes_header=`Bu dosya muğlak Evrensel Kodlu karakter içeriyor`
|
||||
|
@ -1179,6 +1255,8 @@ audio_not_supported_in_browser=Tarayıcınız HTML5 'audio' etiketini desteklemi
|
|||
stored_lfs=Git LFS ile depolandı
|
||||
symbolic_link=Sembolik Bağlantı
|
||||
executable_file=Çalıştırılabilir Dosya
|
||||
vendored=Sağlanmış
|
||||
generated=Üretilmiş
|
||||
commit_graph=İşleme Grafiği
|
||||
commit_graph.select=Dalları seç
|
||||
commit_graph.hide_pr_refs=Değişiklik İsteklerini Gizle
|
||||
|
@ -1214,7 +1292,7 @@ editor.or=veya
|
|||
editor.cancel_lower=İptal
|
||||
editor.commit_signed_changes=İmzalı Değişiklikleri İşle
|
||||
editor.commit_changes=Değişiklikleri Uygula
|
||||
editor.add_tmpl='<dosyaadi>' eklendi
|
||||
editor.add_tmpl='{filename}' ekle
|
||||
editor.add=%s Ekle
|
||||
editor.update=%s Güncelle
|
||||
editor.delete=%s Sil
|
||||
|
@ -1242,6 +1320,8 @@ editor.file_editing_no_longer_exists=Düzenlenmekte olan "%s" dosyası artık bu
|
|||
editor.file_deleting_no_longer_exists=Silinen "%s" dosyası artık bu depoda yer almıyor.
|
||||
editor.file_changed_while_editing=Düzenlemeye başladığınızdan beri dosya içeriği değişti. Görmek için <a target="_blank" rel="noopener noreferrer" href="%s">burayı tıklayın</a> veya üzerine yazmak için <strong>değişiklikleri yine de işleyin</strong>.
|
||||
editor.file_already_exists=Bu depoda "%s" isimli bir dosya zaten var.
|
||||
editor.commit_id_not_matching=İşleme ID'si, düzenlemeye başladığınız ID ile uyuşmuyor, bir yama dalına işleme yapın ve sonra birleştirin.
|
||||
editor.push_out_of_date=İtme eskimiş.
|
||||
editor.commit_empty_file_header=Boş bir dosya işle
|
||||
editor.commit_empty_file_text=İşlemek üzere olduğunuz dosya boş. Devam edilsin mi?
|
||||
editor.no_changes_to_show=Gösterilecek değişiklik yok.
|
||||
|
@ -1266,6 +1346,7 @@ commits.commits=İşleme
|
|||
commits.no_commits=Ortak bir işleme yok. "%s" ve "%s" tamamen farklı geçmişlere sahip.
|
||||
commits.nothing_to_compare=Bu dallar eşit.
|
||||
commits.search.tooltip=Anahtar kelimeleri "author:", "committer:", "after:" veya "before:" ile kullanabilirsiniz, örneğin "revert author:Alice before:2019-01-13".
|
||||
commits.search_branch=Bu Dal
|
||||
commits.search_all=Tüm Dallar
|
||||
commits.author=Yazar
|
||||
commits.message=Mesaj
|
||||
|
@ -1324,6 +1405,7 @@ projects.column.new=Yeni Sütun
|
|||
projects.column.set_default=Varsayılanı Ayarla
|
||||
projects.column.set_default_desc=Bu sütunu kategorize edilmemiş konular ve değişiklik istekleri için varsayılan olarak ayarlayın
|
||||
projects.column.delete=Sutün Sil
|
||||
projects.column.deletion_desc=Bir proje sütununun silinmesi, ilgili tüm konuları varsayılan sütuna taşır. Devam edilsin mi?
|
||||
projects.column.color=Renk
|
||||
projects.open=Aç
|
||||
projects.close=Kapat
|
||||
|
@ -1358,6 +1440,8 @@ issues.new.assignees=Atananlar
|
|||
issues.new.clear_assignees=Atamaları Temizle
|
||||
issues.new.no_assignees=Atanan Kişi Yok
|
||||
issues.new.no_reviewers=Değerlendirici yok
|
||||
issues.new.blocked_user=Konu oluşturulamıyor, depo sahibi tarafından engellenmişsiniz.
|
||||
issues.edit.blocked_user=İçerik düzenlenemiyor, gönderen veya depo sahibi tarafından engellenmişsiniz.
|
||||
issues.choose.get_started=Başla
|
||||
issues.choose.open_external_link=Aç
|
||||
issues.choose.blank=Varsayılan
|
||||
|
@ -1472,6 +1556,7 @@ issues.close_comment_issue=Yorum Yap ve Kapat
|
|||
issues.reopen_issue=Yeniden aç
|
||||
issues.reopen_comment_issue=Yorum Yap ve Yeniden Aç
|
||||
issues.create_comment=Yorum yap
|
||||
issues.comment.blocked_user=Yorum oluşturulamıyor veya düzenlenemiyor, gönderen veya depo sahibi tarafından engellenmişsiniz.
|
||||
issues.closed_at=`<a id="%[1]s" href="#%[1]s">%[2]s</a> konusunu kapattı`
|
||||
issues.reopened_at=`<a id="%[1]s" href="#%[1]s">%[2]s</a> konusunu yeniden açtı`
|
||||
issues.commit_ref_at=`<a id="%[1]s" href="#%[1]s">%[2]s</a> işlemesinde bu konuyu işaret etti`
|
||||
|
@ -1670,6 +1755,7 @@ compare.compare_head=karşılaştır
|
|||
|
||||
pulls.desc=Değişiklik isteklerini ve kod incelemelerini etkinleştir.
|
||||
pulls.new=Yeni Değişiklik İsteği
|
||||
pulls.new.blocked_user=Değişiklik isteği oluşturulamıyor, depo sahibi tarafından engellenmişsiniz.
|
||||
pulls.view=Değişiklik İsteği Görüntüle
|
||||
pulls.compare_changes=Yeni Değişiklik İsteği
|
||||
pulls.allow_edits_from_maintainers=Bakımcıların düzenlemelerine izin ver
|
||||
|
@ -1694,6 +1780,7 @@ pulls.select_commit_hold_shift_for_range=İşleme seç. Bir aralık seçmek içi
|
|||
pulls.review_only_possible_for_full_diff=İnceleme sadece tam fark görüntülemede mümkündür
|
||||
pulls.filter_changes_by_commit=İşleme ile süz
|
||||
pulls.nothing_to_compare=Bu dallar eşit. Değişiklik isteği oluşturmaya gerek yok.
|
||||
pulls.nothing_to_compare_have_tag=Seçili dal/etiket aynı.
|
||||
pulls.nothing_to_compare_and_allow_empty_pr=Bu dallar eşittir. Bu Dİ boş olacak.
|
||||
pulls.has_pull_request=`Bu dallar arasında zaten bir değişiklik isteği var: <a href="%[1]s">%[2]s#%[3]d</a>`
|
||||
pulls.create=Değişiklik İsteği Oluştur
|
||||
|
@ -1752,6 +1839,7 @@ pulls.merge_pull_request=Birleştirme işlemi oluştur
|
|||
pulls.rebase_merge_pull_request=Yeniden yapılandır ve ileri sar
|
||||
pulls.rebase_merge_commit_pull_request=Yeniden yapılandır ve birleştirme işlemi oluştur
|
||||
pulls.squash_merge_pull_request=Ezme işlemi oluştur
|
||||
pulls.fast_forward_only_merge_pull_request=Sadece ileri sarma
|
||||
pulls.merge_manually=Elle birleştirildi
|
||||
pulls.merge_commit_id=Birleştirme işlemesi kimliği
|
||||
pulls.require_signed_wont_sign=Dal imzalı işlemeler gerektiriyor, ancak bu birleştirme imzalanmayacak
|
||||
|
@ -1888,6 +1976,10 @@ wiki.page_name_desc=Bu Viki sayfası için bir ad girin. Bazı özel isimler 'Ho
|
|||
wiki.original_git_entry_tooltip=Kolay bağlantı kullanmak yerine özgün Git dosyasını görüntüle.
|
||||
|
||||
activity=Aktivite
|
||||
activity.navbar.pulse=Eğilim
|
||||
activity.navbar.code_frequency=Kod Frekansı
|
||||
activity.navbar.contributors=Katkıda Bulunanlar
|
||||
activity.navbar.recent_commits=Son İşlemeler
|
||||
activity.period.filter_label=Dönem:
|
||||
activity.period.daily=1 gün
|
||||
activity.period.halfweekly=3 gün
|
||||
|
@ -1953,7 +2045,10 @@ activity.git_stats_and_deletions=ve
|
|||
activity.git_stats_deletion_1=%d silme oldu
|
||||
activity.git_stats_deletion_n=%d silme oldu
|
||||
|
||||
contributors.contribution_type.filter_label=Katkı türü:
|
||||
contributors.contribution_type.commits=İşleme
|
||||
contributors.contribution_type.additions=Eklemeler
|
||||
contributors.contribution_type.deletions=Silmeler
|
||||
|
||||
settings=Ayarlar
|
||||
settings.desc=Ayarlar, deponun ayarlarını yönetebileceğiniz yerdir
|
||||
|
@ -1981,6 +2076,7 @@ settings.mirror_settings.docs.doc_link_title=Depoların yansısını nasıl olu
|
|||
settings.mirror_settings.docs.doc_link_pull_section=belgelerin "uzak bir depodan çekmek" bölümü.
|
||||
settings.mirror_settings.docs.pulling_remote_title=Uzak bir depodan çekmek
|
||||
settings.mirror_settings.mirrored_repository=Yansıtılmış depo
|
||||
settings.mirror_settings.pushed_repository=İtilmiş depo
|
||||
settings.mirror_settings.direction=Yön
|
||||
settings.mirror_settings.direction.pull=Çek
|
||||
settings.mirror_settings.direction.push=Gönder
|
||||
|
@ -2002,6 +2098,9 @@ settings.branches.add_new_rule=Yeni Kural Ekle
|
|||
settings.advanced_settings=Gelişmiş Ayarlar
|
||||
settings.wiki_desc=Depo Wiki'sini Etkinkleştir
|
||||
settings.use_internal_wiki=Dahili Wiki Kullan
|
||||
settings.default_wiki_branch_name=Varsayılan Viki Dal Adı
|
||||
settings.default_wiki_everyone_access=Oturum açmış kullanıcılar için Varsayılan Erişim İzinleri:
|
||||
settings.failed_to_change_default_wiki_branch=Varsayılan viki dalı değiştirilemedi.
|
||||
settings.use_external_wiki=Harici Wiki Kullan
|
||||
settings.external_wiki_url=Harici Wiki bağlantısı
|
||||
settings.external_wiki_url_error=Harici wiki URL'si geçerli bir URL değil.
|
||||
|
@ -2032,6 +2131,9 @@ settings.pulls.default_allow_edits_from_maintainers=Bakımcıların düzenlemele
|
|||
settings.releases_desc=Depo Sürümlerini Etkinleştir
|
||||
settings.packages_desc=Depo Paket Kütüğünü Etkinleştir
|
||||
settings.projects_desc=Depo Projelerini Etkinleştir
|
||||
settings.projects_mode_desc=Proje Modu (ne tür projeler görüntülensin)
|
||||
settings.projects_mode_repo=Sadece depo projeleri
|
||||
settings.projects_mode_owner=Sadece kullanıcı veya organizasyon projeleri
|
||||
settings.projects_mode_all=Tüm projeler
|
||||
settings.actions_desc=Depo İşlemlerini Etkinleştir
|
||||
settings.admin_settings=Yönetici Ayarları
|
||||
|
@ -2058,6 +2160,7 @@ settings.convert_fork_succeed=Çatal normal bir depoya dönüştürüldü.
|
|||
settings.transfer=Sahipliği Aktar
|
||||
settings.transfer.rejected=Depo aktarımı reddedildi.
|
||||
settings.transfer.success=Depo aktarımı başarıyla tamamlandı.
|
||||
settings.transfer.blocked_user=Depo transfer edilemiyor, yeni sahibi tarafından engellenmişsiniz.
|
||||
settings.transfer_abort=Aktarımı iptal et
|
||||
settings.transfer_abort_invalid=Var olmayan bir depo aktarımını iptal edemezsiniz.
|
||||
settings.transfer_abort_success=%s tarafına yapılan depo aktarımı başarıyla iptal edildi.
|
||||
|
@ -2103,6 +2206,7 @@ settings.add_collaborator_success=Katkıcı eklendi.
|
|||
settings.add_collaborator_inactive_user=Etkin olmayan bir kullanıcı katkıcı olarak eklenemez.
|
||||
settings.add_collaborator_owner=Bir sahip katkıcı olarak eklenemez.
|
||||
settings.add_collaborator_duplicate=Katkıcı bu depoya zaten eklenmiş.
|
||||
settings.add_collaborator.blocked_user=Katkıcı depo sahibi tarafından engellenmiş veya depo sahibini engellemiş.
|
||||
settings.delete_collaborator=Sil
|
||||
settings.collaborator_deletion=Katkıcıyı Sil
|
||||
settings.collaborator_deletion_desc=Bir katkıcıyı silmek, bu depoya erişimini iptal edecektir. Devam et?
|
||||
|
@ -2287,6 +2391,8 @@ settings.protect_approvals_whitelist_users=Beyaz listedeki incelemeciler:
|
|||
settings.protect_approvals_whitelist_teams=Gözden geçirme için beyaz listedeki takımlar:
|
||||
settings.dismiss_stale_approvals=Eski onayları reddet
|
||||
settings.dismiss_stale_approvals_desc=Değişiklik isteğinin içeriğini değiştiren yeni işlemeler dala itildiğinde, eski onaylar reddedilir.
|
||||
settings.ignore_stale_approvals=Eskimiş onayları yoksay
|
||||
settings.ignore_stale_approvals_desc=Daha eski işlemelere (eski incelemelere) yapılmış olan onayları, Dİ'nin kaç onayı olduğunu belirlerken sayma. Eskimiş incelemeler atıldıysa bu ilgisizdir.
|
||||
settings.require_signed_commits=İmzalı İşleme Gerekli
|
||||
settings.require_signed_commits_desc=Reddetme, onlar imzasızsa veya doğrulanamazsa bu dala gönderir.
|
||||
settings.protect_branch_name_pattern=Korunmuş Dal Adı Deseni
|
||||
|
@ -2342,6 +2448,7 @@ settings.archive.error=Depoyu arşivlemeye çalışırken bir hata oluştu. Daha
|
|||
settings.archive.error_ismirror=Yansılanmış bir depoyu arşivleyemezsiniz.
|
||||
settings.archive.branchsettings_unavailable=Depo arşivlenirse dal ayarları kullanılamaz.
|
||||
settings.archive.tagsettings_unavailable=Depo arşivlenmişse etiket ayarları kullanılamaz.
|
||||
settings.archive.mirrors_unavailable=Depo arşivlenmişse yansılar kullanılamaz.
|
||||
settings.unarchive.button=Depoyu Arşivden Çıkar
|
||||
settings.unarchive.header=Bu Depoyu Arşivden Çıkar
|
||||
settings.unarchive.text=Depoyu arşivden çıkarmak, yeni sorunların ve değişiklik isteklerinin yanı sıra işleme ve itme yeteneğini de geri kazandıracaktır.
|
||||
|
@ -2538,8 +2645,16 @@ find_file.no_matching=Eşleşen dosya bulunamadı
|
|||
error.csv.too_large=Bu dosya çok büyük olduğu için işlenemiyor.
|
||||
error.csv.unexpected=%d satırı ve %d sütununda beklenmeyen bir karakter içerdiğinden bu dosya işlenemiyor.
|
||||
error.csv.invalid_field_count=%d satırında yanlış sayıda alan olduğundan bu dosya işlenemiyor.
|
||||
error.broken_git_hook=Bu deponun Git İstemcileri bozuk gibi gözüküyor. Onarmak için lütfen <a target="_blank" rel="noreferrer" href="%s">belgelere</a> bakın, daha sonra durumu yenilemek için bazı işlemeler itin.
|
||||
|
||||
[graphs]
|
||||
component_loading=%s yükleniyor...
|
||||
component_loading_failed=%s yüklenemedi
|
||||
component_loading_info=Bu biraz sürebilir…
|
||||
component_failed_to_load=Beklenmedik bir hata oluştu.
|
||||
code_frequency.what=kod frekansı
|
||||
contributors.what=katkılar
|
||||
recent_commits.what=son işlemeler
|
||||
|
||||
[org]
|
||||
org_name_holder=Organizasyon Adı
|
||||
|
@ -2653,6 +2768,7 @@ teams.add_nonexistent_repo=Eklemeye çalıştığınz depo mevcut değil. Lütfe
|
|||
teams.add_duplicate_users=Kullanıcı zaten takımın üyesi.
|
||||
teams.repos.none=Bu takım tarafından hiçbir depoya erişilemedi.
|
||||
teams.members.none=Bu takımda üye yok.
|
||||
teams.members.blocked_user=Kullanıcı eklenemiyor, çünkü organizasyon tarafından engellenmiş.
|
||||
teams.specific_repositories=Belirli depolar
|
||||
teams.specific_repositories_helper=Üyeler, yalnızca takıma açıkça eklenen depolara erişebilir. Bunu seçmek, <i>Tüm depolarla</i> zaten eklenmiş olan depoları otomatik olarak <strong>kaldırmaz</strong>.
|
||||
teams.all_repositories=Tüm depolar
|
||||
|
@ -2665,7 +2781,9 @@ teams.invite.by=%s tarafından davet edildi
|
|||
teams.invite.description=Takıma katılmak için aşağıdaki düğmeye tıklayın.
|
||||
|
||||
[admin]
|
||||
maintenance=Bakım
|
||||
dashboard=Pano
|
||||
self_check=Öz Denetim
|
||||
identity_access=Kimlik ve Erişim
|
||||
users=Kullanıcı Hesapları
|
||||
organizations=Organizasyonlar
|
||||
|
@ -2687,6 +2805,7 @@ settings=Yönetici Ayarları
|
|||
|
||||
dashboard.new_version_hint=Gitea %s şimdi hazır, %s çalıştırıyorsunuz. Ayrıntılar için <a target="_blank" rel="noreferrer" href="https://blog.gitea.io">blog</a>'a bakabilirsiniz.
|
||||
dashboard.statistic=Özet
|
||||
dashboard.maintenance_operations=Bakım İşlemleri
|
||||
dashboard.system_status=Sistem Durumu
|
||||
dashboard.operation_name=İşlem Adı
|
||||
dashboard.operation_switch=Geç
|
||||
|
@ -2712,6 +2831,7 @@ dashboard.delete_missing_repos=Git dosyaları eksik olan tüm depoları sil
|
|||
dashboard.delete_missing_repos.started=Git dosyaları eksik olan tüm depoları silme görevi başladı.
|
||||
dashboard.delete_generated_repository_avatars=Oluşturulan depo resimlerini sil
|
||||
dashboard.sync_repo_branches=Eşzamanlama git verisinden veritabanlarına dalları kaçırdı
|
||||
dashboard.sync_repo_tags=Etiketleri git verisinden veritabanına eşitle
|
||||
dashboard.update_mirrors=Yansıları Güncelle
|
||||
dashboard.repo_health_check=Tüm depoların sağlığını denetle
|
||||
dashboard.check_repo_stats=Tüm depo istatistiklerini denetle
|
||||
|
@ -2766,6 +2886,7 @@ dashboard.stop_endless_tasks=Daimi görevleri durdur
|
|||
dashboard.cancel_abandoned_jobs=Terkedilmiş görevleri iptal et
|
||||
dashboard.start_schedule_tasks=Zamanlanmış görevleri başlat
|
||||
dashboard.sync_branch.started=Dal Eşzamanlaması başladı
|
||||
dashboard.sync_tag.started=Etiket eşitlemesi başladı
|
||||
dashboard.rebuild_issue_indexer=Konu indeksini yeniden oluştur
|
||||
|
||||
users.user_manage_panel=Kullanıcı Hesap Yönetimi
|
||||
|
@ -2970,13 +3091,14 @@ auths.tips=İpuçları
|
|||
auths.tips.oauth2.general=OAuth2 Kimlik Doğrulama
|
||||
auths.tips.oauth2.general.tip=Yeni bir OAuth2 kimlik doğrulama kaydederken, geri çağırma/yönlendirme URL'si şu olmalıdır:
|
||||
auths.tip.oauth2_provider=OAuth2 Sağlayıcısı
|
||||
auths.tip.bitbucket=https://bitbucket.org/account/user/<kullanıcı adınız>/oauth-consumers/new adında yeni bir OAuth tüketicisi kaydedin ve 'Hesap' - 'Oku' iznini ekleyin
|
||||
auths.tip.bitbucket=https://bitbucket.org/account/user/{your-username}/oauth-consumers/new sayfasında yeni bir OAuth tüketicisi kaydedin ve 'Hesap' - 'Oku' iznini ekleyin
|
||||
auths.tip.nextcloud=Aşağıdaki "Ayarlar -> Güvenlik -> OAuth 2.0 istemcisi" menüsünü kullanarak örneğinize yeni bir OAuth tüketicisi kaydedin
|
||||
auths.tip.dropbox=https://www.dropbox.com/developers/apps adresinde yeni bir uygulama oluştur
|
||||
auths.tip.facebook=https://developers.facebook.com/apps adresinde yeni bir uygulama kaydedin ve "Facebook Giriş" ürününü ekleyin
|
||||
auths.tip.github=https://github.com/settings/applications/new adresinde yeni bir OAuth uygulaması kaydedin
|
||||
auths.tip.gitlab_new=https://gitlab.com/-/profile/applications adresinde yeni bir uygulama kaydedin
|
||||
auths.tip.google_plus=OAuth2 istemci kimlik bilgilerini https://console.developers.google.com/ adresindeki Google API konsolundan edinin
|
||||
auths.tip.openid_connect=Bitiş noktalarını belirlemek için OpenID Connect Discovery URL'sini kullanın (<server>/.well-known/openid-configuration)
|
||||
auths.tip.openid_connect=Bitiş noktalarını belirlemek için OpenID Connect Discovery URL'sini (https://{server}/.well-known/openid-configuration) kullanın
|
||||
auths.tip.twitter=https://dev.twitter.com/apps adresine gidin, bir uygulama oluşturun ve “Bu uygulamanın Twitter ile oturum açmak için kullanılmasına izin ver” seçeneğinin etkin olduğundan emin olun
|
||||
auths.tip.discord=https://discordapp.com/developers/applications/me adresinde yeni bir uygulama kaydedin
|
||||
auths.tip.gitea=Yeni bir OAuth2 uygulaması kaydedin. Rehber https://docs.gitea.com/development/oauth2-provider adresinde bulunabilir
|
||||
|
@ -3110,6 +3232,7 @@ config.picture_config=Resim ve Avatar Yapılandırması
|
|||
config.picture_service=Resim Servisi
|
||||
config.disable_gravatar=Gravatar Hizmet Dışı
|
||||
config.enable_federated_avatar=Birleştirilmiş Avatarları Etkinleştir
|
||||
config.open_with_editor_app_help=Klon menüsü için "Birlikte aç" düzenleyicileri. Boş bırakılırsa, varsayılan kullanılacaktır. Varsayılanı görmek için genişletin.
|
||||
|
||||
config.git_config=Git Yapılandırması
|
||||
config.git_disable_diff_highlight=Değişiklik Sözdizimi Vurgusunu Devre Dışı Bırak
|
||||
|
@ -3188,6 +3311,13 @@ notices.desc=Açıklama
|
|||
notices.op=İşlem
|
||||
notices.delete_success=Sistem bildirimleri silindi.
|
||||
|
||||
self_check.no_problem_found=Henüz bir sorun bulunmadı.
|
||||
self_check.startup_warnings=Başlangıç uyarıları:
|
||||
self_check.database_collation_mismatch=Veritabanının şu harmanlamayı kullanmasını bekle: %s
|
||||
self_check.database_collation_case_insensitive=Veritabanı %s harmanlamasını kullanıyor, bu duyarsız bir harmanlamadır. Her ne kadar Gitea bununla çalışabilse de, beklendiği gibi çalışmadığı nadir durumlar ortaya çıkabilir.
|
||||
self_check.database_inconsistent_collation_columns=Veritabanı %s harmanlamasını kullanıyor, ancak bu sütunlar uyumsuz harmanlamalar kullanıyor. Bu beklenmedik sorunlar oluşturabilir.
|
||||
self_check.database_fix_mysql=MySQL/MariaDB kullanıcıları "gitea doctor convert" komutunu harmanlama sorunlarını çözmek için kullanabilir veya "ALTER ... COLLATE ..." SQL'lerini şahsen çalıştırarak sorunu çözebilirler.
|
||||
self_check.database_fix_mssql=MSSQL kullanıcıları sorunu şu an sadece "ALTER ... COLLATE ..." SQL'lerini şahsen çalıştırarak çözebilirler.
|
||||
|
||||
[action]
|
||||
create_repo=depo <a href="%s">%s</a> oluşturuldu
|
||||
|
@ -3375,6 +3505,7 @@ rpm.distros.suse=SUSE tabanlı dağıtımlarda
|
|||
rpm.install=Paketi kurmak için, aşağıdaki komutu çalıştırın:
|
||||
rpm.repository=Depo Bilgisi
|
||||
rpm.repository.architectures=Mimariler
|
||||
rpm.repository.multiple_groups=Bu paket birçok grupta mevcut.
|
||||
rubygems.install=Paketi gem ile kurmak için, şu komutu çalıştırın:
|
||||
rubygems.install2=veya paketi Gemfile dosyasına ekleyin:
|
||||
rubygems.dependencies.runtime=Çalışma Zamanı Bağımlılıkları
|
||||
|
@ -3501,12 +3632,15 @@ runs.scheduled=Zamanlanmış
|
|||
runs.pushed_by=iten
|
||||
runs.invalid_workflow_helper=İş akışı yapılandırma dosyası geçersiz. Lütfen yapılandırma dosyanızı denetleyin: %s
|
||||
runs.no_matching_online_runner_helper=Şu etiket ile eşleşen çevrimiçi çalıştırıcı bulunamadı: %s
|
||||
runs.no_job_without_needs=İş akışı en azından bağımlılığı olmayan bir görev içermelidir.
|
||||
runs.actor=Aktör
|
||||
runs.status=Durum
|
||||
runs.actors_no_select=Tüm aktörler
|
||||
runs.status_no_select=Tüm durumlar
|
||||
runs.no_results=Eşleşen sonuç yok.
|
||||
runs.no_workflows=Henüz hiç bir iş akışı yok.
|
||||
runs.no_workflows.quick_start=Gitea İşlemlerini nasıl başlatacağınızı bilmiyor musunuz? <a target="_blank" rel="noopener noreferrer" href="%s">Hızlı başlangıç kılavuzuna</a> bakabilirsiniz.
|
||||
runs.no_workflows.documentation=Gitea İşlemleri hakkında daha fazla bilgi için, <a target="_blank" rel="noopener noreferrer" href="%s">belgelere</a> bakabilirsiniz.
|
||||
runs.no_runs=İş akışı henüz hiç çalıştırılmadı.
|
||||
runs.empty_commit_message=(boş işleme iletisi)
|
||||
|
||||
|
@ -3525,6 +3659,7 @@ variables.none=Henüz hiçbir değişken yok.
|
|||
variables.deletion=Değişkeni kaldır
|
||||
variables.deletion.description=Bir değişkeni kaldırma kalıcıdır ve geri alınamaz. Devam edilsin mi?
|
||||
variables.description=Değişkenler belirli işlemlere aktarılacaktır, bunun dışında okunamaz.
|
||||
variables.id_not_exist=%d kimlikli değişken mevcut değil.
|
||||
variables.edit=Değişkeni Düzenle
|
||||
variables.deletion.failed=Değişken kaldırılamadı.
|
||||
variables.deletion.success=Değişken kaldırıldı.
|
||||
|
|
|
@ -955,7 +955,6 @@ editor.or=або
|
|||
editor.cancel_lower=Скасувати
|
||||
editor.commit_signed_changes=Внести підписані зміни
|
||||
editor.commit_changes=Закомітити зміни
|
||||
editor.add_tmpl=Додати '<filename>'
|
||||
editor.commit_message_desc=Додати необов'язковий розширений опис…
|
||||
editor.signoff_desc=Додатиь Signed-off-by комітом в конці повідомлення журналу комітів.
|
||||
editor.commit_directly_to_this_branch=Зробіть коміт прямо в гілку <strong class="branch-name">%s</strong>.
|
||||
|
@ -2306,13 +2305,11 @@ auths.sspi_default_language_helper=Типова мова для користув
|
|||
auths.tips=Поради
|
||||
auths.tips.oauth2.general=OAuth2 автентифікація
|
||||
auths.tip.oauth2_provider=Постачальник OAuth2
|
||||
auths.tip.bitbucket=Створіть OAuth URI на сторінці https://bitbucket.org/account/user/<your username>/oauth-consumers/new і додайте права 'Account' - 'Read'
|
||||
auths.tip.nextcloud=`Зареєструйте нового споживача OAuth у вашому екземплярі за допомогою наступного меню "Налаштування -> Безпека -> клієнт OAuth 2.0"`
|
||||
auths.tip.dropbox=Додайте новий додаток на https://www.dropbox.com/developers/apps
|
||||
auths.tip.facebook=`Створіть новий додаток на https://developers.facebook.com/apps і додайте модуль "Facebook Login"`
|
||||
auths.tip.github=Додайте OAuth додаток на https://github.com/settings/applications/new
|
||||
auths.tip.google_plus=Отримайте облікові дані клієнта OAuth2 в консолі Google API на сторінці https://console.developers.google.com/
|
||||
auths.tip.openid_connect=Використовуйте OpenID Connect Discovery URL (<server>/.well-known/openid-configuration) для автоматичної настройки входу OAuth
|
||||
auths.tip.twitter=Перейдіть на https://dev.twitter.com/apps, створіть програму і переконайтеся, що включена опція «Дозволити цю програму для входу в систему за допомогою Twitter»
|
||||
auths.tip.discord=Зареєструйте новий додаток на https://discordapp.com/developers/applications/me
|
||||
auths.tip.yandex=`Створіть нову програму в https://oauth.yandex.com/client/new. Виберіть наступні дозволи з "Yandex. assport API": "Доступ до адреси електронної пошти", "Доступ до аватара" і "Доступ до імені користувача, імені та прізвища, статі"`
|
||||
|
|
|
@ -163,18 +163,25 @@ no_results_found=未找到结果
|
|||
search=搜索...
|
||||
type_tooltip=搜索类型
|
||||
fuzzy=模糊
|
||||
match=匹配
|
||||
fuzzy_tooltip=包含近似匹配搜索词的结果
|
||||
exact=精确
|
||||
exact_tooltip=仅包含精确匹配搜索词的结果
|
||||
repo_kind=搜索仓库...
|
||||
user_kind=搜索用户...
|
||||
org_kind=搜索组织...
|
||||
team_kind=搜索团队...
|
||||
code_kind=搜索代码...
|
||||
code_search_unavailable=代码搜索当前不可用。请与网站管理员联系。
|
||||
code_search_by_git_grep=当前代码搜索结果由“git grep”提供。如果站点管理员启用仓库索引器,可能会有更好的结果。
|
||||
package_kind=搜索软件包...
|
||||
project_kind=搜索项目...
|
||||
branch_kind=搜索分支...
|
||||
commit_kind=搜索提交记录...
|
||||
runner_kind=搜索runners...
|
||||
no_results=未找到匹配结果
|
||||
issue_kind=搜索工单...
|
||||
pull_kind=搜索合并请求...
|
||||
keyword_search_unavailable=按关键字搜索当前不可用。请联系站点管理员。
|
||||
|
||||
[aria]
|
||||
navbar=导航栏
|
||||
|
@ -281,6 +288,7 @@ email_title=电子邮箱设置
|
|||
smtp_addr=SMTP 主机地址
|
||||
smtp_port=SMTP 端口
|
||||
smtp_from=电子邮件发件人
|
||||
smtp_from_invalid=`"发送电子邮件为"地址无效`
|
||||
smtp_from_helper=请输入一个用于 Gitea 的电子邮件地址,或者使用完整格式:"名称" <email@example.com>
|
||||
mailer_user=SMTP 用户名
|
||||
mailer_password=SMTP 密码
|
||||
|
@ -389,6 +397,7 @@ forgot_password_title=忘记密码
|
|||
forgot_password=忘记密码?
|
||||
sign_up_now=还没帐户?马上注册。
|
||||
sign_up_successful=帐户创建成功。欢迎!
|
||||
confirmation_mail_sent_prompt_ex=一封新的确认邮件已经发送到 <b>%s</b>请在下一个 %s 中检查您的收件箱以完成注册过程。 如果您的注册电子邮件地址不正确,您可以重新登录并更改它。
|
||||
must_change_password=更新您的密码
|
||||
allow_password_change=要求用户更改密码(推荐)
|
||||
reset_password_mail_sent_prompt=确认电子邮件已被发送到 <b>%s</b>。请您在 %s 内检查您的收件箱 ,完成密码重置过程。
|
||||
|
@ -398,6 +407,7 @@ prohibit_login=禁止登录
|
|||
prohibit_login_desc=您的帐户被禁止登录,请与网站管理员联系。
|
||||
resent_limit_prompt=您请求发送激活邮件过于频繁,请等待 3 分钟后再试!
|
||||
has_unconfirmed_mail=%s 您好,系统检测到您有一封发送至 <b>%s</b> 但未被确认的邮件。如果您未收到激活邮件,或需要重新发送,请单击下方的按钮。
|
||||
change_unconfirmed_mail_address=如果您的注册电子邮件地址不正确,您可以在此更改并重新发送新的确认电子邮件。
|
||||
resend_mail=单击此处重新发送确认邮件
|
||||
email_not_associate=您输入的邮箱地址未被关联到任何帐号!
|
||||
send_reset_mail=发送账户恢复邮件
|
||||
|
@ -578,6 +588,7 @@ team_name_been_taken=团队名称已被使用。
|
|||
team_no_units_error=至少选择一项仓库单元。
|
||||
email_been_used=该电子邮件地址已在使用中。
|
||||
email_invalid=此邮箱地址无效。
|
||||
email_domain_is_not_allowed=用户 <b>%s</b> 与EMAIL_DOMAIN_ALLOWLIT 或 EMAIL_DOMAIN_BLOCKLIT 冲突。请确保您的操作是预期的。
|
||||
openid_been_used=OpenID 地址 "%s" 已被使用。
|
||||
username_password_incorrect=用户名或密码不正确。
|
||||
password_complexity=密码未达到复杂程度要求:
|
||||
|
@ -589,6 +600,8 @@ enterred_invalid_repo_name=输入的仓库名称不正确
|
|||
enterred_invalid_org_name=您输入的组织名称不正确。
|
||||
enterred_invalid_owner_name=新的所有者名称无效。
|
||||
enterred_invalid_password=输入的密码不正确
|
||||
unset_password=登录用户没有设置密码。
|
||||
unsupported_login_type=此登录类型不支持手动删除帐户。
|
||||
user_not_exist=该用户不存在
|
||||
team_not_exist=团队不存在
|
||||
last_org_owner=您不能从 "所有者" 团队中删除最后一个用户。组织中必须至少有一个所有者。
|
||||
|
@ -643,8 +656,24 @@ block.block.user=屏蔽用户
|
|||
block.block.org=屏蔽用户访问组织
|
||||
block.block.failure=屏蔽用户失败: %s
|
||||
block.unblock=取消屏蔽
|
||||
block.unblock.failure=屏蔽用户失败: %s
|
||||
block.blocked=您已屏蔽此用户。
|
||||
block.title=屏蔽一个用户
|
||||
block.info=屏蔽用户会阻止他们与仓库进行交互,例如打开或评论合并请求或出现问题。了解更多关于屏蔽用户的信息。
|
||||
block.info_1=阻止用户在您的帐户和仓库中进行以下操作:
|
||||
block.info_2=关注你的账号
|
||||
block.info_3=通过@提及您的用户名向您发送通知
|
||||
block.info_4=邀请您作为协作者到他们的仓库中
|
||||
block.info_5=在仓库中点赞、派生或关注
|
||||
block.info_6=打开和评论工单或合并请求
|
||||
block.info_7=在问题或合并请求中对您的评论做出反应
|
||||
block.user_to_block=要屏蔽的用户
|
||||
block.note=备注
|
||||
block.note.title=可选备注:
|
||||
block.note.info=该备注对被屏蔽的用户不可见。
|
||||
block.note.edit=编辑备注
|
||||
block.list=已屏蔽用户
|
||||
block.list.none=您没有已屏蔽的用户。
|
||||
|
||||
[settings]
|
||||
profile=个人信息
|
||||
|
@ -858,6 +887,7 @@ repo_and_org_access=仓库和组织访问权限
|
|||
permissions_public_only=仅公开
|
||||
permissions_access_all=全部(公开、私有和受限)
|
||||
select_permissions=选择权限
|
||||
permission_not_set=未设置
|
||||
permission_no_access=无访问权限
|
||||
permission_read=可读
|
||||
permission_write=读写
|
||||
|
@ -982,7 +1012,9 @@ fork_visibility_helper=无法更改派生仓库的可见性。
|
|||
fork_branch=要克隆到 Fork 的分支
|
||||
all_branches=所有分支
|
||||
fork_no_valid_owners=这个代码仓库无法被派生,因为没有有效的所有者。
|
||||
fork.blocked_user=无法克隆仓库,因为您被仓库所有者屏蔽。
|
||||
use_template=使用此模板
|
||||
open_with_editor=用 %s 打开
|
||||
download_zip=下载 ZIP
|
||||
download_tar=下载 TAR.GZ
|
||||
download_bundle=下载 BUNDLE
|
||||
|
@ -1035,6 +1067,7 @@ watchers=关注者
|
|||
stargazers=称赞者
|
||||
stars_remove_warning=这将清除此仓库的所有点赞数。
|
||||
forks=派生仓库
|
||||
stars=点赞数
|
||||
reactions_more=再加载 %d
|
||||
unit_disabled=站点管理员已禁用此仓库单元。
|
||||
language_other=其它
|
||||
|
@ -1156,6 +1189,7 @@ watch=关注
|
|||
unstar=取消点赞
|
||||
star=点赞
|
||||
fork=派生
|
||||
action.blocked_user=无法执行操作,因为您已被仓库所有者屏蔽。
|
||||
download_archive=下载此仓库
|
||||
more_operations=更多操作
|
||||
|
||||
|
@ -1202,6 +1236,8 @@ file_view_rendered=渲染模式
|
|||
file_view_raw=查看原始文件
|
||||
file_permalink=永久链接
|
||||
file_too_large=文件过大,无法显示。
|
||||
code_preview_line_from_to=在 %[3]s 的第 %[1]d 行到 %[2]d 行
|
||||
code_preview_line_in=在 %[2]s 的第 %[1]d 行
|
||||
invisible_runes_header=`此文件含有不可见的 Unicode 字符`
|
||||
invisible_runes_description=`此文件含有人类无法区分的不可见的 Unicode 字符,但可以由计算机进行不同的处理。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。`
|
||||
ambiguous_runes_header=`此文件含有模棱两可的 Unicode 字符`
|
||||
|
@ -1256,7 +1292,7 @@ editor.or=或
|
|||
editor.cancel_lower=取消
|
||||
editor.commit_signed_changes=提交已签名的更改
|
||||
editor.commit_changes=提交变更
|
||||
editor.add_tmpl=添加 '<filename>'
|
||||
editor.add_tmpl=添加 '{filename}'
|
||||
editor.add=添加 %s
|
||||
editor.update=更新 %s
|
||||
editor.delete=删除 %s
|
||||
|
@ -1284,6 +1320,8 @@ editor.file_editing_no_longer_exists=正在编辑的文件 %s 已不存在。
|
|||
editor.file_deleting_no_longer_exists=正在删除的文件 %s 已不存在。
|
||||
editor.file_changed_while_editing=文件内容在您进行编辑时已经发生变动。<a target="_blank" rel="noopener noreferrer" href="%s">单击此处</a> 查看变动的具体内容,或者 <strong>再次提交</strong> 覆盖已发生的变动。
|
||||
editor.file_already_exists=此仓库已经存在名为 %s 的文件。
|
||||
editor.commit_id_not_matching=提交ID与您开始编辑时的ID不匹配。请提交到补丁分支然后合并。
|
||||
editor.push_out_of_date=推送似乎已经过时。
|
||||
editor.commit_empty_file_header=提交一个空文件
|
||||
editor.commit_empty_file_text=您要提交的文件是空的,继续吗?
|
||||
editor.no_changes_to_show=没有可以显示的变更。
|
||||
|
@ -1402,6 +1440,8 @@ issues.new.assignees=指派成员
|
|||
issues.new.clear_assignees=取消指派成员
|
||||
issues.new.no_assignees=未指派成员
|
||||
issues.new.no_reviewers=无审核者
|
||||
issues.new.blocked_user=无法创建工单,因为您已被仓库所有者屏蔽。
|
||||
issues.edit.blocked_user=无法编辑内容,因为您已被仓库所有者或工单创建者屏蔽。
|
||||
issues.choose.get_started=开始
|
||||
issues.choose.open_external_link=开启
|
||||
issues.choose.blank=默认模板
|
||||
|
@ -1516,6 +1556,7 @@ issues.close_comment_issue=评论并关闭
|
|||
issues.reopen_issue=重新开启
|
||||
issues.reopen_comment_issue=评论并重新开启
|
||||
issues.create_comment=评论
|
||||
issues.comment.blocked_user=无法创建或编辑评论,因为您已被仓库所有者或工单创建者屏蔽。
|
||||
issues.closed_at=`于 <a id="%[1]s" href="#%[1]s">%[2]s</a> 关闭此工单`
|
||||
issues.reopened_at=`重新打开此问题 <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.commit_ref_at=`于 <a id="%[1]s" href="#%[1]s">%[2]s</a> 在代码提交中引用了该工单`
|
||||
|
@ -1714,6 +1755,7 @@ compare.compare_head=比较
|
|||
|
||||
pulls.desc=启用合并请求和代码评审。
|
||||
pulls.new=创建合并请求
|
||||
pulls.new.blocked_user=无法创建合并请求,因为您已被仓库所有者屏蔽。
|
||||
pulls.view=查看拉取请求
|
||||
pulls.compare_changes=创建合并请求
|
||||
pulls.allow_edits_from_maintainers=允许维护者编辑
|
||||
|
@ -1797,6 +1839,7 @@ pulls.merge_pull_request=创建合并提交
|
|||
pulls.rebase_merge_pull_request=变基后快进
|
||||
pulls.rebase_merge_commit_pull_request=变基后创建合并提交
|
||||
pulls.squash_merge_pull_request=创建压缩提交
|
||||
pulls.fast_forward_only_merge_pull_request=仅快进
|
||||
pulls.merge_manually=手动合并
|
||||
pulls.merge_commit_id=合并提交 ID
|
||||
pulls.require_signed_wont_sign=分支需要签名的提交,但这个合并将不会被签名
|
||||
|
@ -1933,6 +1976,7 @@ wiki.page_name_desc=输入此 Wiki 页面的名称。特殊名称有:'Home', '
|
|||
wiki.original_git_entry_tooltip=查看原始的 Git 文件而不是使用友好链接。
|
||||
|
||||
activity=动态
|
||||
activity.navbar.pulse=活动
|
||||
activity.navbar.code_frequency=代码频率
|
||||
activity.navbar.contributors=贡献者
|
||||
activity.navbar.recent_commits=最近的提交
|
||||
|
@ -2055,6 +2099,7 @@ settings.advanced_settings=高级设置
|
|||
settings.wiki_desc=启用仓库百科
|
||||
settings.use_internal_wiki=使用内置百科
|
||||
settings.default_wiki_branch_name=默认百科分支名称
|
||||
settings.default_wiki_everyone_access=登录用户的默认访问权限:
|
||||
settings.failed_to_change_default_wiki_branch=更改百科默认分支失败。
|
||||
settings.use_external_wiki=使用外部百科
|
||||
settings.external_wiki_url=外部 Wiki 链接
|
||||
|
@ -3046,14 +3091,14 @@ auths.tips=帮助提示
|
|||
auths.tips.oauth2.general=OAuth2 认证
|
||||
auths.tips.oauth2.general.tip=当注册新的 OAuth2 身份验证时,回调/重定向 URL 应该是:
|
||||
auths.tip.oauth2_provider=OAuth2 提供程序
|
||||
auths.tip.bitbucket=`在 https://bitbucket.org/account/user/<your username>/oauth-consumers/new 注册新的 OAuth 消费者同时添加权限"帐户"-"读"`
|
||||
auths.tip.bitbucket=在 https://bitbucket.org/account/user/{your username}/oauth-consumers/new 注册新的 OAuth 使用者同时添加权限“账号”-“读取”
|
||||
auths.tip.nextcloud=使用下面的菜单“设置(Settings) -> 安全(Security) -> OAuth 2.0 client”在您的实例上注册一个新的 OAuth 客户端。
|
||||
auths.tip.dropbox=在 https://www.dropbox.com/developers/apps 上创建一个新的应用程序
|
||||
auths.tip.facebook=`在 https://developers.facebook.com/apps 注册一个新的应用,并添加产品"Facebook 登录"`
|
||||
auths.tip.github=在 https://github.com/settings/applications/new 注册一个 OAuth 应用程序
|
||||
auths.tip.gitlab_new=在 https://gitlab.com/-/profile/applications 注册一个新的应用
|
||||
auths.tip.google_plus=从谷歌 API 控制台 (https://console.developers.google.com/) 获得 OAuth2 客户端凭据
|
||||
auths.tip.openid_connect=使用 OpenID 连接发现 URL (<server>/.well-known/openid-configuration) 来指定终点
|
||||
auths.tip.openid_connect=使用 OpenID 连接发现 URL ({server}/.well-known/openid-configuration) 来指定终点
|
||||
auths.tip.twitter=访问 https://dev.twitter.com/apps,创建应用并确保启用了"允许此应用程序用于登录 Twitter"的选项。
|
||||
auths.tip.discord=在 https://discordapp.com/developers/applications/me 上注册新应用程序
|
||||
auths.tip.gitea=注册一个新的 OAuth2 应用程序。可以访问 https://docs.gitea.com/development/oauth2-provider 查看帮助
|
||||
|
|
|
@ -809,7 +809,6 @@ auths.tip.oauth2_provider=OAuth2 提供者
|
|||
auths.tip.dropbox=建立新 App 在 https://www.dropbox.com/developers/apps
|
||||
auths.tip.facebook=`在 https://developers.facebook.com/apps 註冊一個新的應用,並且新增一個產品 "Facebook Login"`
|
||||
auths.tip.github=在 https://github.com/settings/applications/new 註冊一個新的 OAuth 應用程式
|
||||
auths.tip.openid_connect=使用 OpenID 連接探索 URL (<server>/.well-known/openid-configuration) 來指定節點
|
||||
auths.delete=刪除認證來源
|
||||
auths.delete_auth_title=刪除認證來源
|
||||
|
||||
|
|
|
@ -1103,7 +1103,6 @@ editor.or=或
|
|||
editor.cancel_lower=取消
|
||||
editor.commit_signed_changes=提交簽署過的變更
|
||||
editor.commit_changes=提交變更
|
||||
editor.add_tmpl=新增「<filename>」
|
||||
editor.add=新增 %s
|
||||
editor.update=更新 %s
|
||||
editor.delete=刪除 %s
|
||||
|
@ -2704,13 +2703,11 @@ auths.sspi_default_language_helper=SSPI 認證方法自動建立之使用者的
|
|||
auths.tips=幫助提示
|
||||
auths.tips.oauth2.general=OAuth2 認證
|
||||
auths.tip.oauth2_provider=OAuth2 提供者
|
||||
auths.tip.bitbucket=註冊新的 OAuth 客戶端並加入權限「Account - Read」。網址:https://bitbucket.org/account/user/<your username>/oauth-consumers/new
|
||||
auths.tip.nextcloud=在您的執行個體中,於選單「設定 -> 安全性 -> OAuth 2.0 客戶端」註冊新的 OAuth 客戶端
|
||||
auths.tip.dropbox=建立新的 App。網址:https://www.dropbox.com/developers/apps
|
||||
auths.tip.facebook=註冊新的應用程式並新增產品「Facebook 登入」。網址:https://developers.facebook.com/apps
|
||||
auths.tip.github=註冊新的 OAuth 應用程式。網址:https://github.com/settings/applications/new
|
||||
auths.tip.google_plus=從 Google API 控制台取得 OAuth2 用戶端憑證。網址:https://console.developers.google.com/
|
||||
auths.tip.openid_connect=使用 OpenID 連接探索 URL (<server>/.well-known/openid-configuration) 來指定節點
|
||||
auths.tip.twitter=建立應用程式並確保有啟用「Allow this application to be used to Sign in with Twitter」。網址:https://dev.twitter.com/apps
|
||||
auths.tip.discord=註冊新的應用程式。網址:https://discordapp.com/developers/applications/me
|
||||
auths.tip.yandex=建立新的應用程式,從「Yandex.Passport API」區塊選擇「Access to email address」、「Access to user avatar」和「Access to username, first name and surname, gender」。網址:https://oauth.yandex.com/client/new
|
||||
|
|
|
@ -388,7 +388,8 @@ func EnumeratePackageVersionsV3(ctx *context.Context) {
|
|||
ctx.JSON(http.StatusOK, resp)
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/nuget/api/package-base-address-resource#download-package-content-nupkg
|
||||
// https://learn.microsoft.com/en-us/nuget/api/package-base-address-resource#download-package-manifest-nuspec
|
||||
// https://learn.microsoft.com/en-us/nuget/api/package-base-address-resource#download-package-content-nupkg
|
||||
func DownloadPackageFile(ctx *context.Context) {
|
||||
packageName := ctx.Params("id")
|
||||
packageVersion := ctx.Params("version")
|
||||
|
@ -431,7 +432,7 @@ func UploadPackage(ctx *context.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
_, _, err := packages_service.CreatePackageAndAddFile(
|
||||
pv, _, err := packages_service.CreatePackageAndAddFile(
|
||||
ctx,
|
||||
&packages_service.PackageCreationInfo{
|
||||
PackageInfo: packages_service.PackageInfo{
|
||||
|
@ -465,6 +466,33 @@ func UploadPackage(ctx *context.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
nuspecBuf, err := packages_module.CreateHashedBufferFromReaderWithSize(np.NuspecContent, np.NuspecContent.Len())
|
||||
if err != nil {
|
||||
apiError(ctx, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
defer nuspecBuf.Close()
|
||||
|
||||
_, err = packages_service.AddFileToPackageVersionInternal(
|
||||
ctx,
|
||||
pv,
|
||||
&packages_service.PackageFileCreationInfo{
|
||||
PackageFileInfo: packages_service.PackageFileInfo{
|
||||
Filename: strings.ToLower(fmt.Sprintf("%s.nuspec", np.ID)),
|
||||
},
|
||||
Data: nuspecBuf,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
switch err {
|
||||
case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize:
|
||||
apiError(ctx, http.StatusForbidden, err)
|
||||
default:
|
||||
apiError(ctx, http.StatusInternalServerError, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Status(http.StatusCreated)
|
||||
}
|
||||
|
||||
|
|
|
@ -209,11 +209,7 @@ func repoAssignment() func(ctx *context.APIContext) {
|
|||
ctx.Error(http.StatusInternalServerError, "LoadUnits", err)
|
||||
return
|
||||
}
|
||||
ctx.Repo.Permission.Units = ctx.Repo.Repository.Units
|
||||
ctx.Repo.Permission.UnitsMode = make(map[unit.Type]perm.AccessMode)
|
||||
for _, u := range ctx.Repo.Repository.Units {
|
||||
ctx.Repo.Permission.UnitsMode[u.Type] = ctx.Repo.Permission.AccessMode
|
||||
}
|
||||
ctx.Repo.Permission.SetUnitsWithDefaultAccessMode(ctx.Repo.Repository.Units, ctx.Repo.Permission.AccessMode)
|
||||
} else {
|
||||
ctx.Repo.Permission, err = access_model.GetUserRepoPermission(ctx, repo, ctx.Doer)
|
||||
if err != nil {
|
||||
|
|
|
@ -437,7 +437,7 @@ func GetBranchProtection(ctx *context.APIContext) {
|
|||
return
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, convert.ToBranchProtection(ctx, bp))
|
||||
ctx.JSON(http.StatusOK, convert.ToBranchProtection(ctx, bp, repo))
|
||||
}
|
||||
|
||||
// ListBranchProtections list branch protections for a repo
|
||||
|
@ -470,7 +470,7 @@ func ListBranchProtections(ctx *context.APIContext) {
|
|||
}
|
||||
apiBps := make([]*api.BranchProtection, len(bps))
|
||||
for i := range bps {
|
||||
apiBps[i] = convert.ToBranchProtection(ctx, bps[i])
|
||||
apiBps[i] = convert.ToBranchProtection(ctx, bps[i], repo)
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, apiBps)
|
||||
|
@ -681,7 +681,7 @@ func CreateBranchProtection(ctx *context.APIContext) {
|
|||
return
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusCreated, convert.ToBranchProtection(ctx, bp))
|
||||
ctx.JSON(http.StatusCreated, convert.ToBranchProtection(ctx, bp, repo))
|
||||
}
|
||||
|
||||
// EditBranchProtection edits a branch protection for a repo
|
||||
|
@ -959,7 +959,7 @@ func EditBranchProtection(ctx *context.APIContext) {
|
|||
return
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, convert.ToBranchProtection(ctx, bp))
|
||||
ctx.JSON(http.StatusOK, convert.ToBranchProtection(ctx, bp, repo))
|
||||
}
|
||||
|
||||
// DeleteBranchProtection deletes a branch protection for a repo
|
||||
|
|
|
@ -481,11 +481,7 @@ func (ctx *preReceiveContext) loadPusherAndPermission() bool {
|
|||
})
|
||||
return false
|
||||
}
|
||||
ctx.userPerm.Units = ctx.Repo.Repository.Units
|
||||
ctx.userPerm.UnitsMode = make(map[unit.Type]perm_model.AccessMode)
|
||||
for _, u := range ctx.Repo.Repository.Units {
|
||||
ctx.userPerm.UnitsMode[u.Type] = ctx.userPerm.AccessMode
|
||||
}
|
||||
ctx.userPerm.SetUnitsWithDefaultAccessMode(ctx.Repo.Repository.Units, ctx.userPerm.AccessMode)
|
||||
} else {
|
||||
user, err := user_model.GetUserByID(ctx, ctx.opts.UserID)
|
||||
if err != nil {
|
||||
|
|
|
@ -104,7 +104,7 @@ func Projects(ctx *context.Context) {
|
|||
}
|
||||
|
||||
for _, project := range projects {
|
||||
project.RenderedContent = templates.SanitizeHTML(project.Description) // FIXME: is it right? why not render?
|
||||
project.RenderedContent = templates.RenderMarkdownToHtml(ctx, project.Description)
|
||||
}
|
||||
|
||||
err = shared_user.LoadHeaderCount(ctx)
|
||||
|
@ -372,7 +372,7 @@ func ViewProject(ctx *context.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
project.RenderedContent = templates.SanitizeHTML(project.Description) // FIXME: is it right? why not render?
|
||||
project.RenderedContent = templates.RenderMarkdownToHtml(ctx, project.Description)
|
||||
ctx.Data["LinkedPRs"] = linkedPrsMap
|
||||
ctx.Data["PageIsViewProjects"] = true
|
||||
ctx.Data["CanWriteProjects"] = canWriteProjects(ctx)
|
||||
|
|
|
@ -16,6 +16,7 @@ import (
|
|||
actions_model "code.gitea.io/gitea/models/actions"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/organization"
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
unit_model "code.gitea.io/gitea/models/unit"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
|
@ -476,9 +477,10 @@ func SettingsPost(ctx *context.Context) {
|
|||
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeWiki)
|
||||
} else if form.EnableWiki && !form.EnableExternalWiki && !unit_model.TypeWiki.UnitGlobalDisabled() {
|
||||
units = append(units, repo_model.RepoUnit{
|
||||
RepoID: repo.ID,
|
||||
Type: unit_model.TypeWiki,
|
||||
Config: new(repo_model.UnitConfig),
|
||||
RepoID: repo.ID,
|
||||
Type: unit_model.TypeWiki,
|
||||
Config: new(repo_model.UnitConfig),
|
||||
EveryoneAccessMode: perm.ParseAccessMode(form.DefaultWikiEveryoneAccess, perm.AccessModeNone, perm.AccessModeRead, perm.AccessModeWrite),
|
||||
})
|
||||
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeExternalWiki)
|
||||
} else {
|
||||
|
|
|
@ -684,7 +684,7 @@ func markupRender(ctx *context.Context, renderCtx *markup.RenderContext, input i
|
|||
}
|
||||
|
||||
func checkHomeCodeViewable(ctx *context.Context) {
|
||||
if len(ctx.Repo.Units) > 0 {
|
||||
if ctx.Repo.HasUnits() {
|
||||
if ctx.Repo.Repository.IsBeingCreated() {
|
||||
task, err := admin_model.GetMigratingTask(ctx, ctx.Repo.Repository.ID)
|
||||
if err != nil {
|
||||
|
@ -721,12 +721,13 @@ func checkHomeCodeViewable(ctx *context.Context) {
|
|||
}
|
||||
|
||||
var firstUnit *unit_model.Unit
|
||||
for _, repoUnit := range ctx.Repo.Units {
|
||||
if repoUnit.Type == unit_model.TypeCode {
|
||||
for _, repoUnitType := range ctx.Repo.Permission.ReadableUnitTypes() {
|
||||
if repoUnitType == unit_model.TypeCode {
|
||||
// we are doing this check in "code" unit related pages, so if the code unit is readable, no need to do any further redirection
|
||||
return
|
||||
}
|
||||
|
||||
unit, ok := unit_model.Units[repoUnit.Type]
|
||||
unit, ok := unit_model.Units[repoUnitType]
|
||||
if ok && (firstUnit == nil || !firstUnit.IsLessThan(unit)) {
|
||||
firstUnit = &unit
|
||||
}
|
||||
|
|
|
@ -447,6 +447,8 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
|
|||
User: ctx.Doer,
|
||||
}
|
||||
|
||||
isFuzzy := ctx.FormBool("fuzzy")
|
||||
|
||||
// Search all repositories which
|
||||
//
|
||||
// As user:
|
||||
|
@ -546,7 +548,9 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
|
|||
// USING FINAL STATE OF opts FOR A QUERY.
|
||||
var issues issues_model.IssueList
|
||||
{
|
||||
issueIDs, _, err := issue_indexer.SearchIssues(ctx, issue_indexer.ToSearchOptions(keyword, opts))
|
||||
issueIDs, _, err := issue_indexer.SearchIssues(ctx, issue_indexer.ToSearchOptions(keyword, opts).Copy(
|
||||
func(o *issue_indexer.SearchOptions) { o.IsFuzzyKeyword = isFuzzy },
|
||||
))
|
||||
if err != nil {
|
||||
ctx.ServerError("issueIDsFromSearch", err)
|
||||
return
|
||||
|
@ -567,7 +571,9 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
|
|||
// -------------------------------
|
||||
// Fill stats to post to ctx.Data.
|
||||
// -------------------------------
|
||||
issueStats, err := getUserIssueStats(ctx, ctxUser, filterMode, issue_indexer.ToSearchOptions(keyword, opts))
|
||||
issueStats, err := getUserIssueStats(ctx, ctxUser, filterMode, issue_indexer.ToSearchOptions(keyword, opts).Copy(
|
||||
func(o *issue_indexer.SearchOptions) { o.IsFuzzyKeyword = isFuzzy },
|
||||
))
|
||||
if err != nil {
|
||||
ctx.ServerError("getUserIssueStats", err)
|
||||
return
|
||||
|
@ -621,6 +627,7 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
|
|||
ctx.Data["SortType"] = sortType
|
||||
ctx.Data["IsShowClosed"] = isShowClosed
|
||||
ctx.Data["SelectLabels"] = selectedLabels
|
||||
ctx.Data["IsFuzzy"] = isFuzzy
|
||||
|
||||
if isShowClosed {
|
||||
ctx.Data["State"] = "closed"
|
||||
|
@ -634,6 +641,7 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
|
|||
pager.AddParamString("sort", sortType)
|
||||
pager.AddParamString("state", fmt.Sprint(ctx.Data["State"]))
|
||||
pager.AddParamString("labels", selectedLabels)
|
||||
pager.AddParamString("fuzzy", fmt.Sprintf("%v", isFuzzy))
|
||||
ctx.Data["Page"] = pager
|
||||
|
||||
ctx.HTML(http.StatusOK, tplIssues)
|
||||
|
|
|
@ -54,10 +54,7 @@ import (
|
|||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const (
|
||||
// GzipMinSize represents min size to compress for the body size of response
|
||||
GzipMinSize = 1400
|
||||
)
|
||||
const GzipMinSize = 1400 // min size to compress for the body size of response
|
||||
|
||||
// optionsCorsHandler return a http handler which sets CORS options if enabled by config, it blocks non-CORS OPTIONS requests.
|
||||
func optionsCorsHandler() func(next http.Handler) http.Handler {
|
||||
|
@ -261,7 +258,7 @@ func Routes() *web.Route {
|
|||
routes.Get("/metrics", append(mid, Metrics)...)
|
||||
}
|
||||
|
||||
routes.Get("/robots.txt", append(mid, misc.RobotsTxt)...)
|
||||
routes.Methods("GET,HEAD", "/robots.txt", append(mid, misc.RobotsTxt)...)
|
||||
routes.Get("/ssh_info", misc.SSHInfo)
|
||||
routes.Get("/api/healthz", healthcheck.Check)
|
||||
|
||||
|
@ -493,6 +490,7 @@ func registerRoutes(m *web.Route) {
|
|||
}, explore.Code)
|
||||
m.Get("/topics/search", explore.TopicSearch)
|
||||
}, ignExploreSignIn)
|
||||
|
||||
m.Group("/issues", func() {
|
||||
m.Get("", user.Issues)
|
||||
m.Get("/search", repo.SearchIssues)
|
||||
|
@ -802,6 +800,7 @@ func registerRoutes(m *web.Route) {
|
|||
reqRepoCodeReader := context.RequireRepoReader(unit.TypeCode)
|
||||
reqRepoReleaseWriter := context.RequireRepoWriter(unit.TypeReleases)
|
||||
reqRepoReleaseReader := context.RequireRepoReader(unit.TypeReleases)
|
||||
reqRepoWikiReader := context.RequireRepoReader(unit.TypeWiki)
|
||||
reqRepoWikiWriter := context.RequireRepoWriter(unit.TypeWiki)
|
||||
reqRepoIssueReader := context.RequireRepoReader(unit.TypeIssues)
|
||||
reqRepoPullsReader := context.RequireRepoReader(unit.TypePullRequests)
|
||||
|
@ -838,12 +837,12 @@ func registerRoutes(m *web.Route) {
|
|||
}
|
||||
}
|
||||
|
||||
// ***** START: Organization *****
|
||||
m.Group("/org", func() {
|
||||
m.Group("/{org}", func() {
|
||||
m.Get("/members", org.Members)
|
||||
}, context.OrgAssignment())
|
||||
}, ignSignIn)
|
||||
// end "/org": members
|
||||
|
||||
m.Group("/org", func() {
|
||||
m.Group("", func() {
|
||||
|
@ -958,9 +957,8 @@ func registerRoutes(m *web.Route) {
|
|||
}, ctxDataSet("EnableOAuth2", setting.OAuth2.Enabled, "EnablePackages", setting.Packages.Enabled, "PageIsOrgSettings", true))
|
||||
}, context.OrgAssignment(true, true))
|
||||
}, reqSignIn)
|
||||
// ***** END: Organization *****
|
||||
// end "/org": most org routes
|
||||
|
||||
// ***** START: Repository *****
|
||||
m.Group("/repo", func() {
|
||||
m.Get("/create", repo.Create)
|
||||
m.Post("/create", web.Bind(forms.CreateRepoForm{}), repo.CreatePost)
|
||||
|
@ -968,6 +966,7 @@ func registerRoutes(m *web.Route) {
|
|||
m.Post("/migrate", web.Bind(forms.MigrateRepoForm{}), repo.MigratePost)
|
||||
m.Get("/search", repo.SearchRepo)
|
||||
}, reqSignIn)
|
||||
// end "/repo": create, migrate, search
|
||||
|
||||
m.Group("/{username}/-", func() {
|
||||
if setting.Packages.Enabled {
|
||||
|
@ -1008,7 +1007,6 @@ func registerRoutes(m *web.Route) {
|
|||
m.Put("", web.Bind(forms.EditProjectBoardForm{}), org.EditProjectBoard)
|
||||
m.Delete("", org.DeleteProjectBoard)
|
||||
m.Post("/default", org.SetDefaultProjectBoard)
|
||||
|
||||
m.Post("/move", org.MoveIssues)
|
||||
})
|
||||
})
|
||||
|
@ -1023,125 +1021,152 @@ func registerRoutes(m *web.Route) {
|
|||
m.Group("", func() {
|
||||
m.Get("/code", user.CodeSearch)
|
||||
}, reqUnitAccess(unit.TypeCode, perm.AccessModeRead, false), individualPermsChecker)
|
||||
}, ignSignIn, context.UserAssignmentWeb(), context.OrgAssignment()) // for "/{username}/-" (packages, projects, code)
|
||||
}, ignSignIn, context.UserAssignmentWeb(), context.OrgAssignment())
|
||||
// end "/{username}/-": packages, projects, code
|
||||
|
||||
m.Group("/{username}/{reponame}/settings", func() {
|
||||
m.Group("", func() {
|
||||
m.Combo("").Get(repo_setting.Settings).
|
||||
Post(web.Bind(forms.RepoSettingForm{}), repo_setting.SettingsPost)
|
||||
}, repo_setting.SettingsCtxData)
|
||||
m.Post("/avatar", web.Bind(forms.AvatarForm{}), repo_setting.SettingsAvatar)
|
||||
m.Post("/avatar/delete", repo_setting.SettingsDeleteAvatar)
|
||||
|
||||
m.Group("/collaboration", func() {
|
||||
m.Combo("").Get(repo_setting.Collaboration).Post(repo_setting.CollaborationPost)
|
||||
m.Post("/access_mode", repo_setting.ChangeCollaborationAccessMode)
|
||||
m.Post("/delete", repo_setting.DeleteCollaboration)
|
||||
m.Group("/team", func() {
|
||||
m.Post("", repo_setting.AddTeamPost)
|
||||
m.Post("/delete", repo_setting.DeleteTeam)
|
||||
})
|
||||
})
|
||||
|
||||
m.Group("/branches", func() {
|
||||
m.Post("/", repo_setting.SetDefaultBranchPost)
|
||||
}, repo.MustBeNotEmpty)
|
||||
|
||||
m.Group("/branches", func() {
|
||||
m.Get("/", repo_setting.ProtectedBranchRules)
|
||||
m.Combo("/edit").Get(repo_setting.SettingsProtectedBranch).
|
||||
Post(web.Bind(forms.ProtectBranchForm{}), context.RepoMustNotBeArchived(), repo_setting.SettingsProtectedBranchPost)
|
||||
m.Post("/{id}/delete", repo_setting.DeleteProtectedBranchRulePost)
|
||||
}, repo.MustBeNotEmpty)
|
||||
|
||||
m.Post("/rename_branch", web.Bind(forms.RenameBranchForm{}), context.RepoMustNotBeArchived(), repo_setting.RenameBranchPost)
|
||||
|
||||
m.Group("/tags", func() {
|
||||
m.Get("", repo_setting.ProtectedTags)
|
||||
m.Post("", web.Bind(forms.ProtectTagForm{}), context.RepoMustNotBeArchived(), repo_setting.NewProtectedTagPost)
|
||||
m.Post("/delete", context.RepoMustNotBeArchived(), repo_setting.DeleteProtectedTagPost)
|
||||
m.Get("/{id}", repo_setting.EditProtectedTag)
|
||||
m.Post("/{id}", web.Bind(forms.ProtectTagForm{}), context.RepoMustNotBeArchived(), repo_setting.EditProtectedTagPost)
|
||||
})
|
||||
|
||||
m.Group("/hooks/git", func() {
|
||||
m.Get("", repo_setting.GitHooks)
|
||||
m.Combo("/{name}").Get(repo_setting.GitHooksEdit).
|
||||
Post(repo_setting.GitHooksEditPost)
|
||||
}, context.GitHookService())
|
||||
|
||||
m.Group("/hooks", func() {
|
||||
m.Get("", repo_setting.Webhooks)
|
||||
m.Post("/delete", repo_setting.DeleteWebhook)
|
||||
addWebhookAddRoutes()
|
||||
m.Group("/{id}", func() {
|
||||
m.Get("", repo_setting.WebHooksEdit)
|
||||
m.Post("/test", repo_setting.TestWebhook)
|
||||
m.Post("/replay/{uuid}", repo_setting.ReplayWebhook)
|
||||
})
|
||||
addWebhookEditRoutes()
|
||||
}, webhooksEnabled)
|
||||
|
||||
m.Group("/keys", func() {
|
||||
m.Combo("").Get(repo_setting.DeployKeys).
|
||||
Post(web.Bind(forms.AddKeyForm{}), repo_setting.DeployKeysPost)
|
||||
m.Post("/delete", repo_setting.DeleteDeployKey)
|
||||
})
|
||||
|
||||
m.Group("/lfs", func() {
|
||||
m.Get("/", repo_setting.LFSFiles)
|
||||
m.Get("/show/{oid}", repo_setting.LFSFileGet)
|
||||
m.Post("/delete/{oid}", repo_setting.LFSDelete)
|
||||
m.Get("/pointers", repo_setting.LFSPointerFiles)
|
||||
m.Post("/pointers/associate", repo_setting.LFSAutoAssociate)
|
||||
m.Get("/find", repo_setting.LFSFileFind)
|
||||
m.Group("/locks", func() {
|
||||
m.Get("/", repo_setting.LFSLocks)
|
||||
m.Post("/", repo_setting.LFSLockFile)
|
||||
m.Post("/{lid}/unlock", repo_setting.LFSUnlock)
|
||||
})
|
||||
})
|
||||
m.Group("/actions", func() {
|
||||
m.Get("", repo_setting.RedirectToDefaultSetting)
|
||||
addSettingsRunnersRoutes()
|
||||
addSettingsSecretsRoutes()
|
||||
addSettingsVariablesRoutes()
|
||||
}, actions.MustEnableActions)
|
||||
// the follow handler must be under "settings", otherwise this incomplete repo can't be accessed
|
||||
m.Group("/migrate", func() {
|
||||
m.Post("/retry", repo.MigrateRetryPost)
|
||||
m.Post("/cancel", repo.MigrateCancelPost)
|
||||
})
|
||||
},
|
||||
reqSignIn, context.RepoAssignment, reqRepoAdmin, context.RepoRef(),
|
||||
ctxDataSet("PageIsRepoSettings", true, "LFSStartServer", setting.LFS.StartServer),
|
||||
)
|
||||
// end "/{username}/{reponame}/settings"
|
||||
|
||||
// user/org home, including rss feeds
|
||||
m.Get("/{username}/{reponame}", ignSignIn, context.RepoAssignment, context.RepoRef(), repo.SetEditorconfigIfExists, repo.Home)
|
||||
|
||||
m.Group("/{username}/{reponame}", func() {
|
||||
m.Group("/settings", func() {
|
||||
m.Group("", func() {
|
||||
m.Combo("").Get(repo_setting.Settings).
|
||||
Post(web.Bind(forms.RepoSettingForm{}), repo_setting.SettingsPost)
|
||||
}, repo_setting.SettingsCtxData)
|
||||
m.Post("/avatar", web.Bind(forms.AvatarForm{}), repo_setting.SettingsAvatar)
|
||||
m.Post("/avatar/delete", repo_setting.SettingsDeleteAvatar)
|
||||
|
||||
m.Group("/collaboration", func() {
|
||||
m.Combo("").Get(repo_setting.Collaboration).Post(repo_setting.CollaborationPost)
|
||||
m.Post("/access_mode", repo_setting.ChangeCollaborationAccessMode)
|
||||
m.Post("/delete", repo_setting.DeleteCollaboration)
|
||||
m.Group("/team", func() {
|
||||
m.Post("", repo_setting.AddTeamPost)
|
||||
m.Post("/delete", repo_setting.DeleteTeam)
|
||||
})
|
||||
})
|
||||
|
||||
m.Group("/branches", func() {
|
||||
m.Post("/", repo_setting.SetDefaultBranchPost)
|
||||
}, repo.MustBeNotEmpty)
|
||||
|
||||
m.Group("/branches", func() {
|
||||
m.Get("/", repo_setting.ProtectedBranchRules)
|
||||
m.Combo("/edit").Get(repo_setting.SettingsProtectedBranch).
|
||||
Post(web.Bind(forms.ProtectBranchForm{}), context.RepoMustNotBeArchived(), repo_setting.SettingsProtectedBranchPost)
|
||||
m.Post("/{id}/delete", repo_setting.DeleteProtectedBranchRulePost)
|
||||
}, repo.MustBeNotEmpty)
|
||||
|
||||
m.Post("/rename_branch", web.Bind(forms.RenameBranchForm{}), context.RepoMustNotBeArchived(), repo_setting.RenameBranchPost)
|
||||
|
||||
m.Group("/tags", func() {
|
||||
m.Get("", repo_setting.ProtectedTags)
|
||||
m.Post("", web.Bind(forms.ProtectTagForm{}), context.RepoMustNotBeArchived(), repo_setting.NewProtectedTagPost)
|
||||
m.Post("/delete", context.RepoMustNotBeArchived(), repo_setting.DeleteProtectedTagPost)
|
||||
m.Get("/{id}", repo_setting.EditProtectedTag)
|
||||
m.Post("/{id}", web.Bind(forms.ProtectTagForm{}), context.RepoMustNotBeArchived(), repo_setting.EditProtectedTagPost)
|
||||
})
|
||||
|
||||
m.Group("/hooks/git", func() {
|
||||
m.Get("", repo_setting.GitHooks)
|
||||
m.Combo("/{name}").Get(repo_setting.GitHooksEdit).
|
||||
Post(repo_setting.GitHooksEditPost)
|
||||
}, context.GitHookService())
|
||||
|
||||
m.Group("/hooks", func() {
|
||||
m.Get("", repo_setting.Webhooks)
|
||||
m.Post("/delete", repo_setting.DeleteWebhook)
|
||||
addWebhookAddRoutes()
|
||||
m.Group("/{id}", func() {
|
||||
m.Get("", repo_setting.WebHooksEdit)
|
||||
m.Post("/test", repo_setting.TestWebhook)
|
||||
m.Post("/replay/{uuid}", repo_setting.ReplayWebhook)
|
||||
})
|
||||
addWebhookEditRoutes()
|
||||
}, webhooksEnabled)
|
||||
|
||||
m.Group("/keys", func() {
|
||||
m.Combo("").Get(repo_setting.DeployKeys).
|
||||
Post(web.Bind(forms.AddKeyForm{}), repo_setting.DeployKeysPost)
|
||||
m.Post("/delete", repo_setting.DeleteDeployKey)
|
||||
})
|
||||
|
||||
m.Group("/lfs", func() {
|
||||
m.Get("/", repo_setting.LFSFiles)
|
||||
m.Get("/show/{oid}", repo_setting.LFSFileGet)
|
||||
m.Post("/delete/{oid}", repo_setting.LFSDelete)
|
||||
m.Get("/pointers", repo_setting.LFSPointerFiles)
|
||||
m.Post("/pointers/associate", repo_setting.LFSAutoAssociate)
|
||||
m.Get("/find", repo_setting.LFSFileFind)
|
||||
m.Group("/locks", func() {
|
||||
m.Get("/", repo_setting.LFSLocks)
|
||||
m.Post("/", repo_setting.LFSLockFile)
|
||||
m.Post("/{lid}/unlock", repo_setting.LFSUnlock)
|
||||
})
|
||||
})
|
||||
m.Group("/actions", func() {
|
||||
m.Get("", repo_setting.RedirectToDefaultSetting)
|
||||
addSettingsRunnersRoutes()
|
||||
addSettingsSecretsRoutes()
|
||||
addSettingsVariablesRoutes()
|
||||
}, actions.MustEnableActions)
|
||||
// the follow handler must be under "settings", otherwise this incomplete repo can't be accessed
|
||||
m.Group("/migrate", func() {
|
||||
m.Post("/retry", repo.MigrateRetryPost)
|
||||
m.Post("/cancel", repo.MigrateCancelPost)
|
||||
})
|
||||
}, ctxDataSet("PageIsRepoSettings", true, "LFSStartServer", setting.LFS.StartServer))
|
||||
}, reqSignIn, context.RepoAssignment, context.UnitTypes(), reqRepoAdmin, context.RepoRef())
|
||||
|
||||
m.Post("/{username}/{reponame}/action/{action}", reqSignIn, context.RepoAssignment, context.UnitTypes(), repo.Action)
|
||||
|
||||
// Grouping for those endpoints not requiring authentication (but should respect ignSignIn)
|
||||
m.Group("/{username}/{reponame}", func() {
|
||||
m.Group("/milestone", func() {
|
||||
m.Get("/{id}", repo.MilestoneIssuesAndPulls)
|
||||
}, reqRepoIssuesOrPullsReader, context.RepoRef())
|
||||
m.Get("/find/*", repo.FindFiles)
|
||||
m.Group("/tree-list", func() {
|
||||
m.Get("/branch/*", context.RepoRefByType(context.RepoRefBranch), repo.TreeList)
|
||||
m.Get("/tag/*", context.RepoRefByType(context.RepoRefTag), repo.TreeList)
|
||||
m.Get("/commit/*", context.RepoRefByType(context.RepoRefCommit), repo.TreeList)
|
||||
})
|
||||
m.Get("/compare", repo.MustBeNotEmpty, reqRepoCodeReader, repo.SetEditorconfigIfExists, ignSignIn, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.CompareDiff)
|
||||
m.Combo("/compare/*", repo.MustBeNotEmpty, reqRepoCodeReader, repo.SetEditorconfigIfExists).
|
||||
m.Get("/compare", repo.MustBeNotEmpty, repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.CompareDiff)
|
||||
m.Combo("/compare/*", repo.MustBeNotEmpty, repo.SetEditorconfigIfExists).
|
||||
Get(repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.CompareDiff).
|
||||
Post(reqSignIn, context.RepoMustNotBeArchived(), reqRepoPullsReader, repo.MustAllowPulls, web.Bind(forms.CreateIssueForm{}), repo.SetWhitespaceBehavior, repo.CompareAndPullRequestPost)
|
||||
}, ignSignIn, context.RepoAssignment, reqRepoCodeReader)
|
||||
// end "/{username}/{reponame}": find, compare, list (code related)
|
||||
|
||||
m.Group("/{username}/{reponame}", func() {
|
||||
m.Get("/issues/posters", repo.IssuePosters) // it can't use {type:issues|pulls} because it would conflict with other routes like "/pulls/{index}"
|
||||
m.Get("/pulls/posters", repo.PullPosters)
|
||||
m.Get("/comments/{id}/attachments", repo.GetCommentAttachments)
|
||||
m.Get("/labels", repo.RetrieveLabels, repo.Labels)
|
||||
m.Get("/milestones", repo.Milestones)
|
||||
m.Get("/milestone/{id}", context.RepoRef(), repo.MilestoneIssuesAndPulls)
|
||||
m.Group("/{type:issues|pulls}", func() {
|
||||
m.Group("/{index}", func() {
|
||||
m.Get("/info", repo.GetIssueInfo)
|
||||
m.Get("/attachments", repo.GetIssueAttachments)
|
||||
m.Get("/attachments/{uuid}", repo.GetAttachment)
|
||||
m.Group("/content-history", func() {
|
||||
m.Get("/overview", repo.GetContentHistoryOverview)
|
||||
m.Get("/list", repo.GetContentHistoryList)
|
||||
m.Get("/detail", repo.GetContentHistoryDetail)
|
||||
})
|
||||
})
|
||||
}, context.RepoRef())
|
||||
}, ignSignIn, context.RepoAssignment, reqRepoIssuesOrPullsReader)
|
||||
// end "/{username}/{reponame}": view milestone, label, issue, pull, etc
|
||||
|
||||
m.Group("/{username}/{reponame}", func() {
|
||||
m.Group("/{type:issues|pulls}", func() {
|
||||
m.Get("", repo.Issues)
|
||||
m.Group("/{index}", func() {
|
||||
m.Get("", repo.ViewIssue)
|
||||
})
|
||||
})
|
||||
}, ignSignIn, context.RepoAssignment, context.UnitTypes()) // for "/{username}/{reponame}" which doesn't require authentication
|
||||
}, ignSignIn, context.RepoAssignment, context.RequireRepoReaderOr(unit.TypeIssues, unit.TypePullRequests, unit.TypeExternalTracker))
|
||||
// end "/{username}/{reponame}": issue/pull list, issue/pull view, external tracker
|
||||
|
||||
// Grouping for those endpoints that do require authentication
|
||||
m.Group("/{username}/{reponame}", func() {
|
||||
m.Group("/{username}/{reponame}", func() { // edit issues, pulls, labels, milestones, etc
|
||||
m.Group("/issues", func() {
|
||||
m.Group("/new", func() {
|
||||
m.Combo("").Get(context.RepoRef(), repo.NewIssue).
|
||||
|
@ -1150,6 +1175,7 @@ func registerRoutes(m *web.Route) {
|
|||
})
|
||||
m.Get("/search", repo.ListIssues)
|
||||
}, context.RepoMustNotBeArchived(), reqRepoIssueReader)
|
||||
|
||||
// FIXME: should use different URLs but mostly same logic for comments of issue and pull request.
|
||||
// So they can apply their own enable/disable logic on routers.
|
||||
m.Group("/{type:issues|pulls}", func() {
|
||||
|
@ -1179,10 +1205,7 @@ func registerRoutes(m *web.Route) {
|
|||
m.Post("/unlock", reqRepoIssuesOrPullsWriter, repo.UnlockIssue)
|
||||
m.Post("/delete", reqRepoAdmin, repo.DeleteIssue)
|
||||
}, context.RepoMustNotBeArchived())
|
||||
m.Group("/{index}", func() {
|
||||
m.Get("/attachments", repo.GetIssueAttachments)
|
||||
m.Get("/attachments/{uuid}", repo.GetAttachment)
|
||||
})
|
||||
|
||||
m.Group("/{index}", func() {
|
||||
m.Post("/content-history/soft-delete", repo.SoftDeleteContentHistory)
|
||||
})
|
||||
|
@ -1191,25 +1214,25 @@ func registerRoutes(m *web.Route) {
|
|||
m.Post("/milestone", reqRepoIssuesOrPullsWriter, repo.UpdateIssueMilestone)
|
||||
m.Post("/projects", reqRepoIssuesOrPullsWriter, reqRepoProjectsReader, repo.UpdateIssueProject)
|
||||
m.Post("/assignee", reqRepoIssuesOrPullsWriter, repo.UpdateIssueAssignee)
|
||||
m.Post("/request_review", reqRepoIssuesOrPullsReader, repo.UpdatePullReviewRequest)
|
||||
m.Post("/request_review", repo.UpdatePullReviewRequest)
|
||||
m.Post("/dismiss_review", reqRepoAdmin, web.Bind(forms.DismissReviewForm{}), repo.DismissReview)
|
||||
m.Post("/status", reqRepoIssuesOrPullsWriter, repo.UpdateIssueStatus)
|
||||
m.Post("/delete", reqRepoAdmin, repo.BatchDeleteIssues)
|
||||
m.Post("/resolve_conversation", reqRepoIssuesOrPullsReader, repo.SetShowOutdatedComments, repo.UpdateResolveConversation)
|
||||
m.Post("/resolve_conversation", repo.SetShowOutdatedComments, repo.UpdateResolveConversation)
|
||||
m.Post("/attachments", repo.UploadIssueAttachment)
|
||||
m.Post("/attachments/remove", repo.DeleteAttachment)
|
||||
m.Delete("/unpin/{index}", reqRepoAdmin, repo.IssueUnpin)
|
||||
m.Post("/move_pin", reqRepoAdmin, repo.IssuePinMove)
|
||||
}, context.RepoMustNotBeArchived())
|
||||
|
||||
m.Group("/comments/{id}", func() {
|
||||
m.Post("", repo.UpdateCommentContent)
|
||||
m.Post("/delete", repo.DeleteComment)
|
||||
m.Post("/reactions/{action}", web.Bind(forms.ReactionForm{}), repo.ChangeCommentReaction)
|
||||
}, context.RepoMustNotBeArchived())
|
||||
m.Group("/comments/{id}", func() {
|
||||
m.Get("/attachments", repo.GetCommentAttachments)
|
||||
})
|
||||
|
||||
m.Post("/markup", web.Bind(structs.MarkupOption{}), misc.Markup)
|
||||
|
||||
m.Group("/labels", func() {
|
||||
m.Post("/new", web.Bind(forms.CreateLabelForm{}), repo.NewLabel)
|
||||
m.Post("/edit", web.Bind(forms.CreateLabelForm{}), repo.UpdateLabel)
|
||||
|
@ -1227,7 +1250,10 @@ func registerRoutes(m *web.Route) {
|
|||
m.Group("/pull", func() {
|
||||
m.Post("/{index}/target_branch", repo.UpdatePullRequestTarget)
|
||||
}, context.RepoMustNotBeArchived())
|
||||
}, reqSignIn, context.RepoAssignment, reqRepoIssuesOrPullsReader)
|
||||
// end "/{username}/{reponame}": create or edit issues, pulls, labels, milestones
|
||||
|
||||
m.Group("/{username}/{reponame}", func() { // repo code
|
||||
m.Group("", func() {
|
||||
m.Group("", func() {
|
||||
m.Combo("/_edit/*").Get(repo.EditFile).
|
||||
|
@ -1261,26 +1287,26 @@ func registerRoutes(m *web.Route) {
|
|||
m.Post("/restore", repo.RestoreBranchPost)
|
||||
}, context.RepoMustNotBeArchived(), reqRepoCodeWriter, repo.MustBeNotEmpty)
|
||||
|
||||
m.Combo("/fork", reqRepoCodeReader).Get(repo.Fork).Post(web.Bind(forms.CreateRepoForm{}), repo.ForkPost)
|
||||
}, reqSignIn, context.RepoAssignment, context.UnitTypes())
|
||||
m.Combo("/fork").Get(repo.Fork).Post(web.Bind(forms.CreateRepoForm{}), repo.ForkPost)
|
||||
}, reqSignIn, context.RepoAssignment, reqRepoCodeReader)
|
||||
// end "/{username}/{reponame}": repo code
|
||||
|
||||
// Tags
|
||||
m.Group("/{username}/{reponame}", func() {
|
||||
m.Group("/{username}/{reponame}", func() { // repo tags
|
||||
m.Group("/tags", func() {
|
||||
m.Get("", repo.TagsList)
|
||||
m.Get("/list", repo.GetTagList)
|
||||
m.Get(".rss", feedEnabled, repo.TagsListFeedRSS)
|
||||
m.Get(".atom", feedEnabled, repo.TagsListFeedAtom)
|
||||
}, ctxDataSet("EnableFeed", setting.Other.EnableFeed),
|
||||
repo.MustBeNotEmpty, reqRepoCodeReader, context.RepoRefByType(context.RepoRefTag, true))
|
||||
repo.MustBeNotEmpty, context.RepoRefByType(context.RepoRefTag, true))
|
||||
m.Post("/tags/delete", repo.DeleteTag, reqSignIn,
|
||||
repo.MustBeNotEmpty, context.RepoMustNotBeArchived(), reqRepoCodeWriter, context.RepoRef())
|
||||
}, ignSignIn, context.RepoAssignment, context.UnitTypes())
|
||||
}, ignSignIn, context.RepoAssignment, reqRepoCodeReader)
|
||||
// end "/{username}/{reponame}": repo tags
|
||||
|
||||
// Releases
|
||||
m.Group("/{username}/{reponame}", func() {
|
||||
m.Group("/{username}/{reponame}", func() { // repo releases
|
||||
m.Group("/releases", func() {
|
||||
m.Get("/", repo.Releases)
|
||||
m.Get("", repo.Releases)
|
||||
m.Get("/tag/*", repo.SingleRelease)
|
||||
m.Get("/latest", repo.LatestRelease)
|
||||
m.Get(".rss", feedEnabled, repo.ReleasesFeedRSS)
|
||||
|
@ -1300,148 +1326,141 @@ func registerRoutes(m *web.Route) {
|
|||
m.Get("/edit/*", repo.EditRelease)
|
||||
m.Post("/edit/*", web.Bind(forms.EditReleaseForm{}), repo.EditReleasePost)
|
||||
}, reqSignIn, repo.MustBeNotEmpty, context.RepoMustNotBeArchived(), reqRepoReleaseWriter, repo.CommitInfoCache)
|
||||
}, ignSignIn, context.RepoAssignment, context.UnitTypes(), reqRepoReleaseReader)
|
||||
}, ignSignIn, context.RepoAssignment, reqRepoReleaseReader)
|
||||
// end "/{username}/{reponame}": repo releases
|
||||
|
||||
// to maintain compatibility with old attachments
|
||||
m.Group("/{username}/{reponame}", func() {
|
||||
m.Group("/{username}/{reponame}", func() { // to maintain compatibility with old attachments
|
||||
m.Get("/attachments/{uuid}", repo.GetAttachment)
|
||||
}, ignSignIn, context.RepoAssignment, context.UnitTypes())
|
||||
}, ignSignIn, context.RepoAssignment)
|
||||
// end "/{username}/{reponame}": compatibility with old attachments
|
||||
|
||||
m.Group("/{username}/{reponame}", func() {
|
||||
m.Post("/topics", repo.TopicsPost)
|
||||
}, context.RepoAssignment, context.RepoMustNotBeArchived(), reqRepoAdmin)
|
||||
}, context.RepoAssignment, reqRepoAdmin, context.RepoMustNotBeArchived())
|
||||
|
||||
m.Group("/{username}/{reponame}", func() {
|
||||
m.Group("", func() {
|
||||
m.Get("/issues/posters", repo.IssuePosters) // it can't use {type:issues|pulls} because other routes like "/pulls/{index}" has higher priority
|
||||
m.Get("/{type:issues|pulls}", repo.Issues)
|
||||
m.Get("/{type:issues|pulls}/{index}", repo.ViewIssue)
|
||||
m.Group("/{type:issues|pulls}/{index}/content-history", func() {
|
||||
m.Get("/overview", repo.GetContentHistoryOverview)
|
||||
m.Get("/list", repo.GetContentHistoryList)
|
||||
m.Get("/detail", repo.GetContentHistoryDetail)
|
||||
})
|
||||
m.Get("/labels", reqRepoIssuesOrPullsReader, repo.RetrieveLabels, repo.Labels)
|
||||
m.Get("/milestones", reqRepoIssuesOrPullsReader, repo.Milestones)
|
||||
}, context.RepoRef())
|
||||
|
||||
if setting.Packages.Enabled {
|
||||
m.Get("/packages", repo.Packages)
|
||||
}
|
||||
}, ignSignIn, context.RepoAssignment)
|
||||
|
||||
m.Group("/projects", func() {
|
||||
m.Get("", repo.Projects)
|
||||
m.Get("/{id}", repo.ViewProject)
|
||||
m.Group("", func() { //nolint:dupl
|
||||
m.Get("/new", repo.RenderNewProject)
|
||||
m.Post("/new", web.Bind(forms.CreateProjectForm{}), repo.NewProjectPost)
|
||||
m.Group("/{id}", func() {
|
||||
m.Post("", web.Bind(forms.EditProjectBoardForm{}), repo.AddBoardToProjectPost)
|
||||
m.Post("/delete", repo.DeleteProject)
|
||||
m.Group("/{username}/{reponame}/projects", func() {
|
||||
m.Get("", repo.Projects)
|
||||
m.Get("/{id}", repo.ViewProject)
|
||||
m.Group("", func() { //nolint:dupl
|
||||
m.Get("/new", repo.RenderNewProject)
|
||||
m.Post("/new", web.Bind(forms.CreateProjectForm{}), repo.NewProjectPost)
|
||||
m.Group("/{id}", func() {
|
||||
m.Post("", web.Bind(forms.EditProjectBoardForm{}), repo.AddBoardToProjectPost)
|
||||
m.Post("/delete", repo.DeleteProject)
|
||||
|
||||
m.Get("/edit", repo.RenderEditProject)
|
||||
m.Post("/edit", web.Bind(forms.CreateProjectForm{}), repo.EditProjectPost)
|
||||
m.Post("/{action:open|close}", repo.ChangeProjectStatus)
|
||||
m.Get("/edit", repo.RenderEditProject)
|
||||
m.Post("/edit", web.Bind(forms.CreateProjectForm{}), repo.EditProjectPost)
|
||||
m.Post("/{action:open|close}", repo.ChangeProjectStatus)
|
||||
|
||||
m.Group("/{boardID}", func() {
|
||||
m.Put("", web.Bind(forms.EditProjectBoardForm{}), repo.EditProjectBoard)
|
||||
m.Delete("", repo.DeleteProjectBoard)
|
||||
m.Post("/default", repo.SetDefaultProjectBoard)
|
||||
|
||||
m.Post("/move", repo.MoveIssues)
|
||||
})
|
||||
m.Group("/{boardID}", func() {
|
||||
m.Put("", web.Bind(forms.EditProjectBoardForm{}), repo.EditProjectBoard)
|
||||
m.Delete("", repo.DeleteProjectBoard)
|
||||
m.Post("/default", repo.SetDefaultProjectBoard)
|
||||
m.Post("/move", repo.MoveIssues)
|
||||
})
|
||||
}, reqRepoProjectsWriter, context.RepoMustNotBeArchived())
|
||||
}, reqRepoProjectsReader, repo.MustEnableRepoProjects)
|
||||
})
|
||||
}, reqRepoProjectsWriter, context.RepoMustNotBeArchived())
|
||||
}, ignSignIn, context.RepoAssignment, reqRepoProjectsReader, repo.MustEnableRepoProjects)
|
||||
// end "/{username}/{reponame}/projects"
|
||||
|
||||
m.Group("/actions", func() {
|
||||
m.Get("", actions.List)
|
||||
m.Post("/disable", reqRepoAdmin, actions.DisableWorkflowFile)
|
||||
m.Post("/enable", reqRepoAdmin, actions.EnableWorkflowFile)
|
||||
m.Group("/{username}/{reponame}/actions", func() {
|
||||
m.Get("", actions.List)
|
||||
m.Post("/disable", reqRepoAdmin, actions.DisableWorkflowFile)
|
||||
m.Post("/enable", reqRepoAdmin, actions.EnableWorkflowFile)
|
||||
|
||||
m.Group("/runs/{run}", func() {
|
||||
m.Group("/runs/{run}", func() {
|
||||
m.Combo("").
|
||||
Get(actions.View).
|
||||
Post(web.Bind(actions.ViewRequest{}), actions.ViewPost)
|
||||
m.Group("/jobs/{job}", func() {
|
||||
m.Combo("").
|
||||
Get(actions.View).
|
||||
Post(web.Bind(actions.ViewRequest{}), actions.ViewPost)
|
||||
m.Group("/jobs/{job}", func() {
|
||||
m.Combo("").
|
||||
Get(actions.View).
|
||||
Post(web.Bind(actions.ViewRequest{}), actions.ViewPost)
|
||||
m.Post("/rerun", reqRepoActionsWriter, actions.Rerun)
|
||||
m.Get("/logs", actions.Logs)
|
||||
})
|
||||
m.Post("/cancel", reqRepoActionsWriter, actions.Cancel)
|
||||
m.Post("/approve", reqRepoActionsWriter, actions.Approve)
|
||||
m.Get("/artifacts", actions.ArtifactsView)
|
||||
m.Get("/artifacts/{artifact_name}", actions.ArtifactsDownloadView)
|
||||
m.Delete("/artifacts/{artifact_name}", actions.ArtifactsDeleteView)
|
||||
m.Post("/rerun", reqRepoActionsWriter, actions.Rerun)
|
||||
m.Get("/logs", actions.Logs)
|
||||
})
|
||||
m.Group("/workflows/{workflow_name}", func() {
|
||||
m.Get("/badge.svg", actions.GetWorkflowBadge)
|
||||
})
|
||||
}, reqRepoActionsReader, actions.MustEnableActions)
|
||||
|
||||
m.Group("/wiki", func() {
|
||||
m.Combo("/").
|
||||
Get(repo.Wiki).
|
||||
Post(context.RepoMustNotBeArchived(), reqSignIn, reqRepoWikiWriter, web.Bind(forms.NewWikiForm{}), repo.WikiPost)
|
||||
m.Combo("/*").
|
||||
Get(repo.Wiki).
|
||||
Post(context.RepoMustNotBeArchived(), reqSignIn, reqRepoWikiWriter, web.Bind(forms.NewWikiForm{}), repo.WikiPost)
|
||||
m.Get("/commit/{sha:[a-f0-9]{7,64}}", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.Diff)
|
||||
m.Get("/commit/{sha:[a-f0-9]{7,64}}.{ext:patch|diff}", repo.RawDiff)
|
||||
}, repo.MustEnableWiki, func(ctx *context.Context) {
|
||||
ctx.Data["PageIsWiki"] = true
|
||||
ctx.Data["CloneButtonOriginLink"] = ctx.Repo.Repository.WikiCloneLink()
|
||||
m.Post("/cancel", reqRepoActionsWriter, actions.Cancel)
|
||||
m.Post("/approve", reqRepoActionsWriter, actions.Approve)
|
||||
m.Get("/artifacts", actions.ArtifactsView)
|
||||
m.Get("/artifacts/{artifact_name}", actions.ArtifactsDownloadView)
|
||||
m.Delete("/artifacts/{artifact_name}", actions.ArtifactsDeleteView)
|
||||
m.Post("/rerun", reqRepoActionsWriter, actions.Rerun)
|
||||
})
|
||||
m.Group("/workflows/{workflow_name}", func() {
|
||||
m.Get("/badge.svg", actions.GetWorkflowBadge)
|
||||
})
|
||||
}, ignSignIn, context.RepoAssignment, reqRepoActionsReader, actions.MustEnableActions)
|
||||
// end "/{username}/{reponame}/actions"
|
||||
|
||||
m.Group("/wiki", func() {
|
||||
m.Get("/raw/*", repo.WikiRaw)
|
||||
}, repo.MustEnableWiki)
|
||||
m.Group("/{username}/{reponame}/wiki", func() {
|
||||
m.Combo("").
|
||||
Get(repo.Wiki).
|
||||
Post(context.RepoMustNotBeArchived(), reqSignIn, reqRepoWikiWriter, web.Bind(forms.NewWikiForm{}), repo.WikiPost)
|
||||
m.Combo("/*").
|
||||
Get(repo.Wiki).
|
||||
Post(context.RepoMustNotBeArchived(), reqSignIn, reqRepoWikiWriter, web.Bind(forms.NewWikiForm{}), repo.WikiPost)
|
||||
m.Get("/commit/{sha:[a-f0-9]{7,64}}", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.Diff)
|
||||
m.Get("/commit/{sha:[a-f0-9]{7,64}}.{ext:patch|diff}", repo.RawDiff)
|
||||
m.Get("/raw/*", repo.WikiRaw)
|
||||
}, ignSignIn, context.RepoAssignment, repo.MustEnableWiki, reqRepoWikiReader, func(ctx *context.Context) {
|
||||
ctx.Data["PageIsWiki"] = true
|
||||
ctx.Data["CloneButtonOriginLink"] = ctx.Repo.Repository.WikiCloneLink()
|
||||
})
|
||||
// end "/{username}/{reponame}/wiki"
|
||||
|
||||
m.Group("/activity", func() {
|
||||
m.Get("", repo.Activity)
|
||||
m.Get("/{period}", repo.Activity)
|
||||
m.Group("/contributors", func() {
|
||||
m.Get("", repo.Contributors)
|
||||
m.Get("/data", repo.ContributorsData)
|
||||
})
|
||||
m.Group("/code-frequency", func() {
|
||||
m.Get("", repo.CodeFrequency)
|
||||
m.Get("/data", repo.CodeFrequencyData)
|
||||
})
|
||||
m.Group("/recent-commits", func() {
|
||||
m.Get("", repo.RecentCommits)
|
||||
m.Get("/data", repo.RecentCommitsData)
|
||||
})
|
||||
}, context.RepoRef(), repo.MustBeNotEmpty, context.RequireRepoReaderOr(unit.TypePullRequests, unit.TypeIssues, unit.TypeReleases))
|
||||
m.Group("/{username}/{reponame}/activity", func() {
|
||||
m.Get("", repo.Activity)
|
||||
m.Get("/{period}", repo.Activity)
|
||||
m.Group("/contributors", func() {
|
||||
m.Get("", repo.Contributors)
|
||||
m.Get("/data", repo.ContributorsData)
|
||||
})
|
||||
m.Group("/code-frequency", func() {
|
||||
m.Get("", repo.CodeFrequency)
|
||||
m.Get("/data", repo.CodeFrequencyData)
|
||||
})
|
||||
m.Group("/recent-commits", func() {
|
||||
m.Get("", repo.RecentCommits)
|
||||
m.Get("/data", repo.RecentCommitsData)
|
||||
})
|
||||
},
|
||||
ignSignIn, context.RepoAssignment, context.RequireRepoReaderOr(unit.TypePullRequests, unit.TypeIssues, unit.TypeReleases),
|
||||
context.RepoRef(), repo.MustBeNotEmpty,
|
||||
)
|
||||
// end "/{username}/{reponame}/activity"
|
||||
|
||||
m.Group("/{username}/{reponame}", func() {
|
||||
m.Group("/activity_author_data", func() {
|
||||
m.Get("", repo.ActivityAuthors)
|
||||
m.Get("/{period}", repo.ActivityAuthors)
|
||||
}, context.RepoRef(), repo.MustBeNotEmpty, context.RequireRepoReaderOr(unit.TypeCode))
|
||||
}, context.RepoRef(), repo.MustBeNotEmpty)
|
||||
|
||||
m.Group("/archive", func() {
|
||||
m.Get("/*", repo.Download)
|
||||
m.Post("/*", repo.InitiateDownload)
|
||||
}, repo.MustBeNotEmpty, dlSourceEnabled, reqRepoCodeReader)
|
||||
}, repo.MustBeNotEmpty, dlSourceEnabled)
|
||||
|
||||
m.Group("/branches", func() {
|
||||
m.Get("/list", repo.GetBranchesList)
|
||||
m.Get("", repo.Branches)
|
||||
}, repo.MustBeNotEmpty, context.RepoRef(), reqRepoCodeReader)
|
||||
}, repo.MustBeNotEmpty, context.RepoRef())
|
||||
|
||||
m.Group("/blob_excerpt", func() {
|
||||
m.Get("/{sha}", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.ExcerptBlob)
|
||||
}, func(ctx *context.Context) gocontext.CancelFunc {
|
||||
// FIXME: refactor this function, use separate routes for wiki/code
|
||||
if ctx.FormBool("wiki") {
|
||||
ctx.Data["PageIsWiki"] = true
|
||||
repo.MustEnableWiki(ctx)
|
||||
return nil
|
||||
}
|
||||
|
||||
reqRepoCodeReader(ctx)
|
||||
if ctx.Written() {
|
||||
return nil
|
||||
}
|
||||
|
@ -1454,7 +1473,6 @@ func registerRoutes(m *web.Route) {
|
|||
return cancel
|
||||
})
|
||||
|
||||
m.Get("/pulls/posters", repo.PullPosters)
|
||||
m.Group("/pulls/{index}", func() {
|
||||
m.Get("", repo.SetWhitespaceBehavior, repo.GetPullDiffStats, repo.ViewIssue)
|
||||
m.Get(".diff", repo.DownloadPullDiff)
|
||||
|
@ -1488,7 +1506,7 @@ func registerRoutes(m *web.Route) {
|
|||
m.Get("/blob/{sha}", context.RepoRefByType(context.RepoRefBlob), repo.DownloadByIDOrLFS)
|
||||
// "/*" route is deprecated, and kept for backward compatibility
|
||||
m.Get("/*", context.RepoRefByType(context.RepoRefLegacy), repo.SingleDownloadOrLFS)
|
||||
}, repo.MustBeNotEmpty, reqRepoCodeReader)
|
||||
}, repo.MustBeNotEmpty)
|
||||
|
||||
m.Group("/raw", func() {
|
||||
m.Get("/branch/*", context.RepoRefByType(context.RepoRefBranch), repo.SingleDownload)
|
||||
|
@ -1497,14 +1515,14 @@ func registerRoutes(m *web.Route) {
|
|||
m.Get("/blob/{sha}", context.RepoRefByType(context.RepoRefBlob), repo.DownloadByID)
|
||||
// "/*" route is deprecated, and kept for backward compatibility
|
||||
m.Get("/*", context.RepoRefByType(context.RepoRefLegacy), repo.SingleDownload)
|
||||
}, repo.MustBeNotEmpty, reqRepoCodeReader)
|
||||
}, repo.MustBeNotEmpty)
|
||||
|
||||
m.Group("/render", func() {
|
||||
m.Get("/branch/*", context.RepoRefByType(context.RepoRefBranch), repo.RenderFile)
|
||||
m.Get("/tag/*", context.RepoRefByType(context.RepoRefTag), repo.RenderFile)
|
||||
m.Get("/commit/*", context.RepoRefByType(context.RepoRefCommit), repo.RenderFile)
|
||||
m.Get("/blob/{sha}", context.RepoRefByType(context.RepoRefBlob), repo.RenderFile)
|
||||
}, repo.MustBeNotEmpty, reqRepoCodeReader)
|
||||
}, repo.MustBeNotEmpty)
|
||||
|
||||
m.Group("/commits", func() {
|
||||
m.Get("/branch/*", context.RepoRefByType(context.RepoRefBranch), repo.RefCommits)
|
||||
|
@ -1512,20 +1530,20 @@ func registerRoutes(m *web.Route) {
|
|||
m.Get("/commit/*", context.RepoRefByType(context.RepoRefCommit), repo.RefCommits)
|
||||
// "/*" route is deprecated, and kept for backward compatibility
|
||||
m.Get("/*", context.RepoRefByType(context.RepoRefLegacy), repo.RefCommits)
|
||||
}, repo.MustBeNotEmpty, reqRepoCodeReader)
|
||||
}, repo.MustBeNotEmpty)
|
||||
|
||||
m.Group("/blame", func() {
|
||||
m.Get("/branch/*", context.RepoRefByType(context.RepoRefBranch), repo.RefBlame)
|
||||
m.Get("/tag/*", context.RepoRefByType(context.RepoRefTag), repo.RefBlame)
|
||||
m.Get("/commit/*", context.RepoRefByType(context.RepoRefCommit), repo.RefBlame)
|
||||
}, repo.MustBeNotEmpty, reqRepoCodeReader)
|
||||
}, repo.MustBeNotEmpty)
|
||||
|
||||
m.Group("", func() {
|
||||
m.Get("/graph", repo.Graph)
|
||||
m.Get("/commit/{sha:([a-f0-9]{7,64})$}", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.Diff)
|
||||
m.Get("/commit/{sha:([a-f0-9]{7,64})$}/load-branches-and-tags", repo.LoadBranchesAndTags)
|
||||
m.Get("/cherry-pick/{sha:([a-f0-9]{7,64})$}", repo.SetEditorconfigIfExists, repo.CherryPick)
|
||||
}, repo.MustBeNotEmpty, context.RepoRef(), reqRepoCodeReader)
|
||||
}, repo.MustBeNotEmpty, context.RepoRef())
|
||||
|
||||
m.Get("/rss/branch/*", context.RepoRefByType(context.RepoRefBranch), feedEnabled, feed.RenderBranchFeed)
|
||||
m.Get("/atom/branch/*", context.RepoRefByType(context.RepoRefBranch), feedEnabled, feed.RenderBranchFeed)
|
||||
|
@ -1534,51 +1552,42 @@ func registerRoutes(m *web.Route) {
|
|||
m.Get("/branch/*", context.RepoRefByType(context.RepoRefBranch), repo.Home)
|
||||
m.Get("/tag/*", context.RepoRefByType(context.RepoRefTag), repo.Home)
|
||||
m.Get("/commit/*", context.RepoRefByType(context.RepoRefCommit), repo.Home)
|
||||
// "/*" route is deprecated, and kept for backward compatibility
|
||||
m.Get("/*", context.RepoRefByType(context.RepoRefLegacy), repo.Home)
|
||||
m.Get("/*", context.RepoRefByType(context.RepoRefLegacy), repo.Home) // "/*" route is deprecated, and kept for backward compatibility
|
||||
}, repo.SetEditorconfigIfExists)
|
||||
|
||||
m.Group("", func() {
|
||||
m.Get("/forks", repo.Forks)
|
||||
}, context.RepoRef(), reqRepoCodeReader)
|
||||
m.Get("/commit/{sha:([a-f0-9]{7,64})}.{ext:patch|diff}", repo.MustBeNotEmpty, reqRepoCodeReader, repo.RawDiff)
|
||||
}, ignSignIn, context.RepoAssignment, context.UnitTypes())
|
||||
|
||||
m.Post("/{username}/{reponame}/lastcommit/*", ignSignInAndCsrf, context.RepoAssignment, context.UnitTypes(), context.RepoRefByType(context.RepoRefCommit), reqRepoCodeReader, repo.LastCommit)
|
||||
m.Get("/forks", context.RepoRef(), repo.Forks)
|
||||
m.Get("/commit/{sha:([a-f0-9]{7,64})}.{ext:patch|diff}", repo.MustBeNotEmpty, repo.RawDiff)
|
||||
m.Post("/lastcommit/*", context.RepoRefByType(context.RepoRefCommit), repo.LastCommit)
|
||||
}, ignSignIn, context.RepoAssignment, reqRepoCodeReader)
|
||||
// end "/{username}/{reponame}": repo code
|
||||
|
||||
m.Group("/{username}/{reponame}", func() {
|
||||
m.Get("/stars", repo.Stars)
|
||||
m.Get("/watchers", repo.Watchers)
|
||||
m.Get("/search", reqRepoCodeReader, repo.Search)
|
||||
}, ignSignIn, context.RepoAssignment, context.RepoRef(), context.UnitTypes())
|
||||
m.Post("/action/{action}", reqSignIn, repo.Action)
|
||||
}, ignSignIn, context.RepoAssignment, context.RepoRef())
|
||||
|
||||
m.Group("/{username}", func() {
|
||||
m.Group("/{reponame}", func() {
|
||||
m.Get("", repo.SetEditorconfigIfExists, repo.Home)
|
||||
}, ignSignIn, context.RepoAssignment, context.RepoRef(), context.UnitTypes())
|
||||
|
||||
m.Group("/{reponame}", func() {
|
||||
m.Group("/info/lfs", func() {
|
||||
m.Post("/objects/batch", lfs.CheckAcceptMediaType, lfs.BatchHandler)
|
||||
m.Put("/objects/{oid}/{size}", lfs.UploadHandler)
|
||||
m.Get("/objects/{oid}/{filename}", lfs.DownloadHandler)
|
||||
m.Get("/objects/{oid}", lfs.DownloadHandler)
|
||||
m.Post("/verify", lfs.CheckAcceptMediaType, lfs.VerifyHandler)
|
||||
m.Group("/locks", func() {
|
||||
m.Get("/", lfs.GetListLockHandler)
|
||||
m.Post("/", lfs.PostLockHandler)
|
||||
m.Post("/verify", lfs.VerifyLockHandler)
|
||||
m.Post("/{lid}/unlock", lfs.UnLockHandler)
|
||||
}, lfs.CheckAcceptMediaType)
|
||||
m.Any("/*", func(ctx *context.Context) {
|
||||
ctx.NotFound("", nil)
|
||||
})
|
||||
}, ignSignInAndCsrf, lfsServerEnabled)
|
||||
|
||||
gitHTTPRouters(m)
|
||||
})
|
||||
m.Group("/{username}/{reponame}", func() {
|
||||
m.Group("/info/lfs", func() {
|
||||
m.Post("/objects/batch", lfs.CheckAcceptMediaType, lfs.BatchHandler)
|
||||
m.Put("/objects/{oid}/{size}", lfs.UploadHandler)
|
||||
m.Get("/objects/{oid}/{filename}", lfs.DownloadHandler)
|
||||
m.Get("/objects/{oid}", lfs.DownloadHandler)
|
||||
m.Post("/verify", lfs.CheckAcceptMediaType, lfs.VerifyHandler)
|
||||
m.Group("/locks", func() {
|
||||
m.Get("/", lfs.GetListLockHandler)
|
||||
m.Post("/", lfs.PostLockHandler)
|
||||
m.Post("/verify", lfs.VerifyLockHandler)
|
||||
m.Post("/{lid}/unlock", lfs.UnLockHandler)
|
||||
}, lfs.CheckAcceptMediaType)
|
||||
m.Any("/*", func(ctx *context.Context) {
|
||||
ctx.NotFound("", nil)
|
||||
})
|
||||
}, ignSignInAndCsrf, lfsServerEnabled)
|
||||
gitHTTPRouters(m)
|
||||
})
|
||||
// ***** END: Repository *****
|
||||
// end "/{username}/{reponame}.git": git support
|
||||
|
||||
m.Group("/notifications", func() {
|
||||
m.Get("", user.Notifications)
|
||||
|
@ -1601,6 +1610,7 @@ func registerRoutes(m *web.Route) {
|
|||
|
||||
m.NotFound(func(w http.ResponseWriter, req *http.Request) {
|
||||
ctx := context.GetWebContext(req)
|
||||
routing.UpdateFuncInfo(ctx, routing.GetFuncInfo(ctx.NotFound, "GlobalNotFound"))
|
||||
ctx.NotFound("", nil)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -78,6 +78,11 @@ func newNotifyInput(repo *repo_model.Repository, doer *user_model.User, event we
|
|||
}
|
||||
}
|
||||
|
||||
func newNotifyInputForSchedules(repo *repo_model.Repository) *notifyInput {
|
||||
// the doer here will be ignored as we force using action user when handling schedules
|
||||
return newNotifyInput(repo, user_model.NewActionsUser(), webhook_module.HookEventSchedule)
|
||||
}
|
||||
|
||||
func (input *notifyInput) WithDoer(doer *user_model.User) *notifyInput {
|
||||
input.Doer = doer
|
||||
return input
|
||||
|
@ -485,7 +490,7 @@ func handleSchedules(
|
|||
RepoID: input.Repo.ID,
|
||||
OwnerID: input.Repo.OwnerID,
|
||||
WorkflowID: dwf.EntryName,
|
||||
TriggerUserID: input.Doer.ID,
|
||||
TriggerUserID: user_model.ActionsUserID,
|
||||
Ref: ref,
|
||||
CommitSHA: commit.ID.String(),
|
||||
Event: input.Event,
|
||||
|
@ -527,7 +532,7 @@ func DetectAndHandleSchedules(ctx context.Context, repo *repo_model.Repository)
|
|||
// We need a notifyInput to call handleSchedules
|
||||
// if repo is a mirror, commit author maybe an external user,
|
||||
// so we use action user as the Doer of the notifyInput
|
||||
notifyInput := newNotifyInput(repo, user_model.NewActionsUser(), webhook_module.HookEventSchedule)
|
||||
notifyInput := newNotifyInputForSchedules(repo)
|
||||
|
||||
return handleSchedules(ctx, scheduleWorkflows, commit, notifyInput, repo.DefaultBranch)
|
||||
}
|
||||
|
|
|
@ -102,6 +102,18 @@ func NewTemplateContextForWeb(ctx *Context) TemplateContext {
|
|||
tmplCtx["Locale"] = ctx.Base.Locale
|
||||
tmplCtx["AvatarUtils"] = templates.NewAvatarUtils(ctx)
|
||||
tmplCtx["RootData"] = ctx.Data
|
||||
tmplCtx["Consts"] = map[string]any{
|
||||
"RepoUnitTypeCode": unit.TypeCode,
|
||||
"RepoUnitTypeIssues": unit.TypeIssues,
|
||||
"RepoUnitTypePullRequests": unit.TypePullRequests,
|
||||
"RepoUnitTypeReleases": unit.TypeReleases,
|
||||
"RepoUnitTypeWiki": unit.TypeWiki,
|
||||
"RepoUnitTypeExternalWiki": unit.TypeExternalWiki,
|
||||
"RepoUnitTypeExternalTracker": unit.TypeExternalTracker,
|
||||
"RepoUnitTypeProjects": unit.TypeProjects,
|
||||
"RepoUnitTypePackages": unit.TypePackages,
|
||||
"RepoUnitTypeActions": unit.TypeActions,
|
||||
}
|
||||
return tmplCtx
|
||||
}
|
||||
|
||||
|
|
|
@ -383,7 +383,6 @@ func repoAssignment(ctx *Context, repo *repo_model.Repository) {
|
|||
ctx.NotFound("no access right", nil)
|
||||
return
|
||||
}
|
||||
ctx.Data["HasAccess"] = true
|
||||
ctx.Data["Permission"] = &ctx.Repo.Permission
|
||||
|
||||
if repo.IsMirror {
|
||||
|
@ -1052,19 +1051,3 @@ func GitHookService() func(ctx *Context) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// UnitTypes returns a middleware to set unit types to context variables.
|
||||
func UnitTypes() func(ctx *Context) {
|
||||
return func(ctx *Context) {
|
||||
ctx.Data["UnitTypeCode"] = unit_model.TypeCode
|
||||
ctx.Data["UnitTypeIssues"] = unit_model.TypeIssues
|
||||
ctx.Data["UnitTypePullRequests"] = unit_model.TypePullRequests
|
||||
ctx.Data["UnitTypeReleases"] = unit_model.TypeReleases
|
||||
ctx.Data["UnitTypeWiki"] = unit_model.TypeWiki
|
||||
ctx.Data["UnitTypeExternalWiki"] = unit_model.TypeExternalWiki
|
||||
ctx.Data["UnitTypeExternalTracker"] = unit_model.TypeExternalTracker
|
||||
ctx.Data["UnitTypeProjects"] = unit_model.TypeProjects
|
||||
ctx.Data["UnitTypePackages"] = unit_model.TypePackages
|
||||
ctx.Data["UnitTypeActions"] = unit_model.TypeActions
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import (
|
|||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
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/log"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
|
@ -105,33 +106,46 @@ func ToBranch(ctx context.Context, repo *repo_model.Repository, branchName strin
|
|||
return branch, nil
|
||||
}
|
||||
|
||||
// getWhitelistEntities returns the names of the entities that are in the whitelist
|
||||
func getWhitelistEntities[T *user_model.User | *organization.Team](entities []T, whitelistIDs []int64) []string {
|
||||
whitelistUserIDsSet := container.SetOf(whitelistIDs...)
|
||||
whitelistNames := make([]string, 0)
|
||||
for _, entity := range entities {
|
||||
switch v := any(entity).(type) {
|
||||
case *user_model.User:
|
||||
if whitelistUserIDsSet.Contains(v.ID) {
|
||||
whitelistNames = append(whitelistNames, v.Name)
|
||||
}
|
||||
case *organization.Team:
|
||||
if whitelistUserIDsSet.Contains(v.ID) {
|
||||
whitelistNames = append(whitelistNames, v.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return whitelistNames
|
||||
}
|
||||
|
||||
// ToBranchProtection convert a ProtectedBranch to api.BranchProtection
|
||||
func ToBranchProtection(ctx context.Context, bp *git_model.ProtectedBranch) *api.BranchProtection {
|
||||
pushWhitelistUsernames, err := user_model.GetUserNamesByIDs(ctx, bp.WhitelistUserIDs)
|
||||
func ToBranchProtection(ctx context.Context, bp *git_model.ProtectedBranch, repo *repo_model.Repository) *api.BranchProtection {
|
||||
readers, err := access_model.GetRepoReaders(ctx, repo)
|
||||
if err != nil {
|
||||
log.Error("GetUserNamesByIDs (WhitelistUserIDs): %v", err)
|
||||
log.Error("GetRepoReaders: %v", err)
|
||||
}
|
||||
mergeWhitelistUsernames, err := user_model.GetUserNamesByIDs(ctx, bp.MergeWhitelistUserIDs)
|
||||
|
||||
pushWhitelistUsernames := getWhitelistEntities(readers, bp.WhitelistUserIDs)
|
||||
mergeWhitelistUsernames := getWhitelistEntities(readers, bp.MergeWhitelistUserIDs)
|
||||
approvalsWhitelistUsernames := getWhitelistEntities(readers, bp.ApprovalsWhitelistUserIDs)
|
||||
|
||||
teamReaders, err := organization.OrgFromUser(repo.Owner).TeamsWithAccessToRepo(ctx, repo.ID, perm.AccessModeRead)
|
||||
if err != nil {
|
||||
log.Error("GetUserNamesByIDs (MergeWhitelistUserIDs): %v", err)
|
||||
}
|
||||
approvalsWhitelistUsernames, err := user_model.GetUserNamesByIDs(ctx, bp.ApprovalsWhitelistUserIDs)
|
||||
if err != nil {
|
||||
log.Error("GetUserNamesByIDs (ApprovalsWhitelistUserIDs): %v", err)
|
||||
}
|
||||
pushWhitelistTeams, err := organization.GetTeamNamesByID(ctx, bp.WhitelistTeamIDs)
|
||||
if err != nil {
|
||||
log.Error("GetTeamNamesByID (WhitelistTeamIDs): %v", err)
|
||||
}
|
||||
mergeWhitelistTeams, err := organization.GetTeamNamesByID(ctx, bp.MergeWhitelistTeamIDs)
|
||||
if err != nil {
|
||||
log.Error("GetTeamNamesByID (MergeWhitelistTeamIDs): %v", err)
|
||||
}
|
||||
approvalsWhitelistTeams, err := organization.GetTeamNamesByID(ctx, bp.ApprovalsWhitelistTeamIDs)
|
||||
if err != nil {
|
||||
log.Error("GetTeamNamesByID (ApprovalsWhitelistTeamIDs): %v", err)
|
||||
log.Error("Repo.Owner.TeamsWithAccessToRepo: %v", err)
|
||||
}
|
||||
|
||||
pushWhitelistTeams := getWhitelistEntities(teamReaders, bp.WhitelistTeamIDs)
|
||||
mergeWhitelistTeams := getWhitelistEntities(teamReaders, bp.MergeWhitelistTeamIDs)
|
||||
approvalsWhitelistTeams := getWhitelistEntities(teamReaders, bp.ApprovalsWhitelistTeamIDs)
|
||||
|
||||
branchName := ""
|
||||
if !git_model.IsRuleNameSpecial(bp.RuleName) {
|
||||
branchName = bp.RuleName
|
||||
|
@ -322,7 +336,7 @@ func ToTeams(ctx context.Context, teams []*organization.Team, loadOrgs bool) ([]
|
|||
Description: t.Description,
|
||||
IncludesAllRepositories: t.IncludesAllRepositories,
|
||||
CanCreateOrgRepo: t.CanCreateOrgRepo,
|
||||
Permission: t.AccessMode.String(),
|
||||
Permission: t.AccessMode.ToString(),
|
||||
Units: t.GetUnitNames(),
|
||||
UnitsMap: t.GetUnitsMap(),
|
||||
}
|
||||
|
|
|
@ -25,12 +25,13 @@ func ToRepo(ctx context.Context, repo *repo_model.Repository, permissionInRepo a
|
|||
func innerToRepo(ctx context.Context, repo *repo_model.Repository, permissionInRepo access_model.Permission, isParent bool) *api.Repository {
|
||||
var parent *api.Repository
|
||||
|
||||
if permissionInRepo.Units == nil && permissionInRepo.UnitsMode == nil {
|
||||
// If Units and UnitsMode are both nil, it means that it's a hard coded permission,
|
||||
// like access_model.Permission{AccessMode: perm.AccessModeAdmin}.
|
||||
// So we need to load units for the repo, or UnitAccessMode will always return perm.AccessModeNone.
|
||||
if !permissionInRepo.HasUnits() && permissionInRepo.AccessMode > perm.AccessModeNone {
|
||||
// If units is empty, it means that it's a hard-coded permission, like access_model.Permission{AccessMode: perm.AccessModeAdmin}
|
||||
// So we need to load units for the repo, otherwise UnitAccessMode will just return perm.AccessModeNone.
|
||||
// TODO: this logic is still not right (because unit modes are not correctly prepared)
|
||||
// the caller should prepare a proper "permission" before calling this function.
|
||||
_ = repo.LoadUnits(ctx) // the error is not important, so ignore it
|
||||
permissionInRepo.Units = repo.Units
|
||||
permissionInRepo.SetUnitsWithDefaultAccessMode(repo.Units, permissionInRepo.AccessMode)
|
||||
}
|
||||
|
||||
cloneLink := repo.CloneLink()
|
||||
|
|
|
@ -103,7 +103,7 @@ func User2UserSettings(user *user_model.User) api.UserSettings {
|
|||
func ToUserAndPermission(ctx context.Context, user, doer *user_model.User, accessMode perm.AccessMode) api.RepoCollaboratorPermission {
|
||||
return api.RepoCollaboratorPermission{
|
||||
User: ToUser(ctx, user, doer),
|
||||
Permission: accessMode.String(),
|
||||
RoleName: accessMode.String(),
|
||||
Permission: accessMode.ToString(),
|
||||
RoleName: accessMode.ToString(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -134,6 +134,7 @@ type RepoSettingForm struct {
|
|||
EnableWiki bool
|
||||
EnableExternalWiki bool
|
||||
DefaultWikiBranch string
|
||||
DefaultWikiEveryoneAccess string
|
||||
ExternalWikiURL string
|
||||
EnableIssues bool
|
||||
EnableExternalTracker bool
|
||||
|
|
|
@ -4,11 +4,12 @@
|
|||
<title>Links for {{.PackageDescriptor.Package.Name}}</title>
|
||||
</head>
|
||||
<body>
|
||||
{{- /* PEP 503 – Simple Repository API: https://peps.python.org/pep-0503/ */ -}}
|
||||
<h1>Links for {{.PackageDescriptor.Package.Name}}</h1>
|
||||
{{range .PackageDescriptors}}
|
||||
{{$p := .}}
|
||||
{{$pd := .}}
|
||||
{{range .Files}}
|
||||
<a href="{{$.RegistryURL}}/files/{{$p.Package.LowerName}}/{{$p.Version.Version}}/{{.File.Name}}#sha256-{{.Blob.HashSHA256}}"{{if $p.Metadata.RequiresPython}} data-requires-python="{{$p.Metadata.RequiresPython}}"{{end}}>{{.File.Name}}</a><br>
|
||||
<a href="{{$.RegistryURL}}/files/{{$pd.Package.LowerName}}/{{$pd.Version.Version}}/{{.File.Name}}#sha256={{.Blob.HashSHA256}}"{{if $pd.Metadata.RequiresPython}} data-requires-python="{{$pd.Metadata.RequiresPython}}"{{end}}>{{.File.Name}}</a><br>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</body>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<a class="{{if .PageIsExploreOrganizations}}active {{end}}item" href="{{AppSubUrl}}/explore/organizations">
|
||||
{{svg "octicon-organization"}} {{ctx.Locale.Tr "explore.organizations"}}
|
||||
</a>
|
||||
{{if and (not $.UnitTypeCode.UnitGlobalDisabled) .IsRepoIndexerEnabled}}
|
||||
{{if and (not ctx.Consts.RepoUnitTypeCode.UnitGlobalDisabled) .IsRepoIndexerEnabled}}
|
||||
<a class="{{if .PageIsExploreCode}}active {{end}}item" href="{{AppSubUrl}}/explore/code">
|
||||
{{svg "octicon-code"}} {{ctx.Locale.Tr "explore.code"}}
|
||||
</a>
|
||||
|
|
|
@ -174,7 +174,7 @@
|
|||
<div class="inline field {{if .Err_SMTPFrom}}error{{end}}">
|
||||
<label for="smtp_from">{{ctx.Locale.Tr "install.smtp_from"}}</label>
|
||||
<input id="smtp_from" name="smtp_from" value="{{.smtp_from}}">
|
||||
<span class="help">{{ctx.Locale.Tr "install.smtp_from_helper"}}</span>
|
||||
<span class="help">{{ctx.Locale.TrString "install.smtp_from_helper"}}{{/* it contains lt/gt chars*/}}</span>
|
||||
</div>
|
||||
<div class="inline field {{if .Err_SMTPUser}}error{{end}}">
|
||||
<label for="smtp_user">{{ctx.Locale.Tr "install.mailer_user"}}</label>
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</h4>
|
||||
<div class="ui attached table unstackable segment">
|
||||
<div class="ui bottom attached table unstackable segment">
|
||||
<div class="file-view code-view unicode-escaped">
|
||||
{{if .IsFileTooLarge}}
|
||||
{{template "shared/filetoolarge" dict "RawFileLink" .RawFileLink}}
|
||||
|
@ -80,7 +80,7 @@
|
|||
</table>
|
||||
{{end}}{{/* end if .IsFileTooLarge */}}
|
||||
<div class="code-line-menu tippy-target">
|
||||
{{if $.Permission.CanRead $.UnitTypeIssues}}
|
||||
{{if $.Permission.CanRead ctx.Consts.RepoUnitTypeIssues}}
|
||||
<a class="item ref-in-new-issue" role="menuitem" data-url-issue-new="{{.RepoLink}}/issues/new" data-url-param-body-link="{{.Repository.Link}}/src/commit/{{PathEscape .CommitID}}/{{PathEscapeSegments .TreePath}}{{if $.HasSourceRenderedToggle}}?display=source{{end}}" rel="nofollow noindex">{{ctx.Locale.Tr "repo.issues.context.reference_issue"}}</a>
|
||||
{{end}}
|
||||
<a class="item copy-line-permalink" role="menuitem" data-url="{{.Repository.Link}}/src/commit/{{PathEscape .CommitID}}/{{PathEscapeSegments .TreePath}}{{if $.HasSourceRenderedToggle}}?display=source{{end}}">{{ctx.Locale.Tr "repo.file_copy_permalink"}}</a>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{{if .Permission.CanRead $.UnitTypeCode}}
|
||||
{{if .Permission.CanRead ctx.Consts.RepoUnitTypeCode}}
|
||||
<div id="repo-code-frequency-chart"
|
||||
data-locale-loading-title="{{ctx.Locale.Tr "graphs.component_loading" (ctx.Locale.Tr "graphs.code_frequency.what")}}"
|
||||
data-locale-loading-title-failed="{{ctx.Locale.Tr "graphs.component_loading_failed" (ctx.Locale.Tr "graphs.code_frequency.what")}}"
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
<a class="ui primary tiny button" href="{{.SourcePath}}">
|
||||
{{ctx.Locale.Tr "repo.diff.browse_source"}}
|
||||
</a>
|
||||
{{if and ($.Permission.CanWrite $.UnitTypeCode) (not $.Repository.IsArchived) (not .IsDeleted)}}{{- /* */ -}}
|
||||
{{if and ($.Permission.CanWrite ctx.Consts.RepoUnitTypeCode) (not $.Repository.IsArchived) (not .IsDeleted)}}{{- /* */ -}}
|
||||
<div class="ui dropdown primary tiny button">
|
||||
{{ctx.Locale.Tr "repo.commit.operations"}}
|
||||
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
||||
|
|
|
@ -6,14 +6,23 @@
|
|||
<div class="singular-commit" id="{{$tag}}">
|
||||
<span class="badge badge-commit">{{svg "octicon-git-commit"}}</span>
|
||||
{{if .User}}
|
||||
<a class="avatar" href="{{.User.HomeLink}}">{{ctx.AvatarUtils.Avatar .User}}</a>
|
||||
<a class="avatar" href="{{.User.HomeLink}}">{{ctx.AvatarUtils.Avatar .User 20}}</a>
|
||||
{{else}}
|
||||
{{ctx.AvatarUtils.AvatarByEmail .Author.Email .Author.Name}}
|
||||
{{ctx.AvatarUtils.AvatarByEmail .Author.Email .Author.Name 20}}
|
||||
{{end}}
|
||||
|
||||
{{$commitLink:= printf "%s/commit/%s" $.comment.Issue.PullRequest.BaseRepo.Link (PathEscape .ID.String)}}
|
||||
|
||||
<span class="shabox tw-flex tw-items-center tw-float-right">
|
||||
<span class="tw-flex-1 gt-ellipsis tw-font-mono{{if gt .ParentCount 1}} grey text{{end}}" title="{{.Summary}}">{{RenderCommitMessageLinkSubject $.root.Context .Message $commitLink ($.comment.Issue.PullRequest.BaseRepo.ComposeMetas ctx)}}</span>
|
||||
|
||||
{{if IsMultilineCommitMessage .Message}}
|
||||
<button class="ui button js-toggle-commit-body ellipsis-button" aria-expanded="false">...</button>
|
||||
{{end}}
|
||||
{{if IsMultilineCommitMessage .Message}}
|
||||
<pre class="commit-body tw-hidden">{{RenderCommitBody $.root.Context .Message ($.comment.Issue.PullRequest.BaseRepo.ComposeMetas ctx)}}</pre>
|
||||
{{end}}
|
||||
|
||||
<span class="shabox tw-flex tw-items-center">
|
||||
{{template "repo/commit_statuses" dict "Status" .Status "Statuses" .Statuses}}
|
||||
{{$class := "ui sha label"}}
|
||||
{{if .Signature}}
|
||||
|
@ -37,14 +46,6 @@
|
|||
{{end}}
|
||||
</a>
|
||||
</span>
|
||||
|
||||
<span class="tw-font-mono commit-summary {{if gt .ParentCount 1}} grey text{{end}}" title="{{.Summary}}">{{RenderCommitMessageLinkSubject $.root.Context .Message $commitLink ($.comment.Issue.PullRequest.BaseRepo.ComposeMetas ctx)}}</span>
|
||||
{{if IsMultilineCommitMessage .Message}}
|
||||
<button class="ui button js-toggle-commit-body ellipsis-button" aria-expanded="false">...</button>
|
||||
{{end}}
|
||||
{{if IsMultilineCommitMessage .Message}}
|
||||
<pre class="commit-body tw-hidden">{{RenderCommitBody $.root.Context .Message ($.comment.Issue.PullRequest.BaseRepo.ComposeMetas ctx)}}</pre>
|
||||
{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{{if .Permission.CanRead $.UnitTypeCode}}
|
||||
{{if .Permission.CanRead ctx.Consts.RepoUnitTypeCode}}
|
||||
<div id="repo-contributors-chart"
|
||||
data-locale-filter-label="{{ctx.Locale.Tr "repo.contributors.contribution_type.filter_label"}}"
|
||||
data-locale-contribution-type-commits="{{ctx.Locale.Tr "repo.contributors.contribution_type.commits"}}"
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
{{if eq $refGroup "pull"}}
|
||||
{{if or (not $.HidePRRefs) (SliceUtils.Contains $.SelectedBranches .Name)}}
|
||||
<!-- it's intended to use issues not pulls, if it's a pull you will get redirected -->
|
||||
<a class="ui labelled basic tiny button" href="{{$.RepoLink}}/{{if $.Repository.UnitEnabled $.Context $.UnitTypePullRequests}}pulls{{else}}issues{{end}}/{{.ShortName|PathEscape}}">
|
||||
<a class="ui labelled basic tiny button" href="{{$.RepoLink}}/{{if $.Repository.UnitEnabled $.Context ctx.Consts.RepoUnitTypePullRequests}}pulls{{else}}issues{{end}}/{{.ShortName|PathEscape}}">
|
||||
{{svg "octicon-git-pull-request"}} #{{.ShortName}}
|
||||
</a>
|
||||
{{end}}
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
{{if not $.DisableStars}}
|
||||
{{template "repo/star_unstar" $}}
|
||||
{{end}}
|
||||
{{if and (not .IsEmpty) ($.Permission.CanRead $.UnitTypeCode)}}
|
||||
{{if and (not .IsEmpty) ($.Permission.CanRead ctx.Consts.RepoUnitTypeCode)}}
|
||||
<div class="ui labeled button
|
||||
{{if or (not $.IsSigned) (and (not $.CanSignedUserFork) (not $.UserAndOrgForks))}}
|
||||
disabled
|
||||
|
@ -91,28 +91,28 @@
|
|||
>
|
||||
{{svg "octicon-repo-forked"}}<span class="text not-mobile">{{ctx.Locale.Tr "repo.fork"}}</span>
|
||||
</a>
|
||||
<div class="ui small modal" id="fork-repo-modal">
|
||||
<div class="header">
|
||||
{{ctx.Locale.Tr "repo.already_forked" .Name}}
|
||||
</div>
|
||||
<div class="content tw-text-left">
|
||||
<div class="ui list">
|
||||
{{range $.UserAndOrgForks}}
|
||||
<div class="ui item tw-py-2">
|
||||
<a href="{{.Link}}">{{svg "octicon-repo-forked" 16 "tw-mr-2"}}{{.FullName}}</a>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
{{if $.CanSignedUserFork}}
|
||||
<div class="divider"></div>
|
||||
<a href="{{$.RepoLink}}/fork">{{ctx.Locale.Tr "repo.fork_to_different_account"}}</a>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
<a class="ui basic label" href="{{.Link}}/forks">
|
||||
{{CountFmt .NumForks}}
|
||||
</a>
|
||||
</div>
|
||||
<div class="ui small modal" id="fork-repo-modal">
|
||||
<div class="header">
|
||||
{{ctx.Locale.Tr "repo.already_forked" .Name}}
|
||||
</div>
|
||||
<div class="content tw-text-left">
|
||||
<div class="ui list">
|
||||
{{range $.UserAndOrgForks}}
|
||||
<div class="ui item tw-py-2">
|
||||
<a href="{{.Link}}">{{svg "octicon-repo-forked" 16 "tw-mr-2"}}{{.FullName}}</a>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
{{if $.CanSignedUserFork}}
|
||||
<div class="divider"></div>
|
||||
<a href="{{$.RepoLink}}/fork">{{ctx.Locale.Tr "repo.fork_to_different_account"}}</a>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
|
@ -131,13 +131,13 @@
|
|||
<overflow-menu class="ui container secondary pointing tabular top attached borderless menu tw-pt-0 tw-my-0">
|
||||
{{if not (or .Repository.IsBeingCreated .Repository.IsBroken)}}
|
||||
<div class="overflow-menu-items">
|
||||
{{if .Permission.CanRead $.UnitTypeCode}}
|
||||
{{if .Permission.CanRead ctx.Consts.RepoUnitTypeCode}}
|
||||
<a class="{{if .PageIsViewCode}}active {{end}}item" href="{{.RepoLink}}{{if and (ne .BranchName .Repository.DefaultBranch) (not $.PageIsWiki)}}/src/{{.BranchNameSubURL}}{{end}}">
|
||||
{{svg "octicon-code"}} {{ctx.Locale.Tr "repo.code"}}
|
||||
</a>
|
||||
{{end}}
|
||||
|
||||
{{if .Permission.CanRead $.UnitTypeIssues}}
|
||||
{{if .Permission.CanRead ctx.Consts.RepoUnitTypeIssues}}
|
||||
<a class="{{if .PageIsIssueList}}active {{end}}item" href="{{.RepoLink}}/issues">
|
||||
{{svg "octicon-issue-opened"}} {{ctx.Locale.Tr "repo.issues"}}
|
||||
{{if .Repository.NumOpenIssues}}
|
||||
|
@ -146,13 +146,13 @@
|
|||
</a>
|
||||
{{end}}
|
||||
|
||||
{{if .Permission.CanRead $.UnitTypeExternalTracker}}
|
||||
{{if .Permission.CanRead ctx.Consts.RepoUnitTypeExternalTracker}}
|
||||
<a class="{{if .PageIsIssueList}}active {{end}}item" href="{{.RepoExternalIssuesLink}}" target="_blank" rel="noopener noreferrer">
|
||||
{{svg "octicon-link-external"}} {{ctx.Locale.Tr "repo.issues"}}
|
||||
</a>
|
||||
{{end}}
|
||||
|
||||
{{if and .Repository.CanEnablePulls (.Permission.CanRead $.UnitTypePullRequests)}}
|
||||
{{if and .Repository.CanEnablePulls (.Permission.CanRead ctx.Consts.RepoUnitTypePullRequests)}}
|
||||
<a class="{{if .PageIsPullList}}active {{end}}item" href="{{.RepoLink}}/pulls">
|
||||
{{svg "octicon-git-pull-request"}} {{ctx.Locale.Tr "repo.pulls"}}
|
||||
{{if .Repository.NumOpenPulls}}
|
||||
|
@ -161,7 +161,7 @@
|
|||
</a>
|
||||
{{end}}
|
||||
|
||||
{{if and .EnableActions (not .UnitActionsGlobalDisabled) (.Permission.CanRead $.UnitTypeActions)}}
|
||||
{{if and .EnableActions (not .UnitActionsGlobalDisabled) (.Permission.CanRead ctx.Consts.RepoUnitTypeActions)}}
|
||||
<a class="{{if .PageIsActions}}active {{end}}item" href="{{.RepoLink}}/actions">
|
||||
{{svg "octicon-play"}} {{ctx.Locale.Tr "actions.actions"}}
|
||||
{{if .Repository.NumOpenActionRuns}}
|
||||
|
@ -170,14 +170,14 @@
|
|||
</a>
|
||||
{{end}}
|
||||
|
||||
{{if .Permission.CanRead $.UnitTypePackages}}
|
||||
{{if .Permission.CanRead ctx.Consts.RepoUnitTypePackages}}
|
||||
<a href="{{.RepoLink}}/packages" class="{{if .IsPackagesPage}}active {{end}}item">
|
||||
{{svg "octicon-package"}} {{ctx.Locale.Tr "packages.title"}}
|
||||
</a>
|
||||
{{end}}
|
||||
|
||||
{{$projectsUnit := .Repository.MustGetUnit $.Context $.UnitTypeProjects}}
|
||||
{{if and (not .UnitProjectsGlobalDisabled) (.Permission.CanRead $.UnitTypeProjects) ($projectsUnit.ProjectsConfig.IsProjectsAllowed "repo")}}
|
||||
{{$projectsUnit := .Repository.MustGetUnit $.Context ctx.Consts.RepoUnitTypeProjects}}
|
||||
{{if and (not .UnitProjectsGlobalDisabled) (.Permission.CanRead ctx.Consts.RepoUnitTypeProjects) ($projectsUnit.ProjectsConfig.IsProjectsAllowed "repo")}}
|
||||
<a href="{{.RepoLink}}/projects" class="{{if .IsProjectsPage}}active {{end}}item">
|
||||
{{svg "octicon-project"}} {{ctx.Locale.Tr "repo.project_board"}}
|
||||
{{if .Repository.NumOpenProjects}}
|
||||
|
@ -186,7 +186,7 @@
|
|||
</a>
|
||||
{{end}}
|
||||
|
||||
{{if and (.Permission.CanRead $.UnitTypeReleases) (not .IsEmptyRepo)}}
|
||||
{{if and (.Permission.CanRead ctx.Consts.RepoUnitTypeReleases) (not .IsEmptyRepo)}}
|
||||
<a class="{{if or .PageIsReleaseList .PageIsTagList}}active {{end}}item" href="{{.RepoLink}}/releases">
|
||||
{{svg "octicon-tag"}} {{ctx.Locale.Tr "repo.releases"}}
|
||||
{{if .NumReleases}}
|
||||
|
@ -195,19 +195,19 @@
|
|||
</a>
|
||||
{{end}}
|
||||
|
||||
{{if .Permission.CanRead $.UnitTypeWiki}}
|
||||
{{if .Permission.CanRead ctx.Consts.RepoUnitTypeWiki}}
|
||||
<a class="{{if .PageIsWiki}}active {{end}}item" href="{{.RepoLink}}/wiki">
|
||||
{{svg "octicon-book"}} {{ctx.Locale.Tr "repo.wiki"}}
|
||||
</a>
|
||||
{{end}}
|
||||
|
||||
{{if .Permission.CanRead $.UnitTypeExternalWiki}}
|
||||
<a class="item" href="{{(.Repository.MustGetUnit $.Context $.UnitTypeExternalWiki).ExternalWikiConfig.ExternalWikiURL}}" target="_blank" rel="noopener noreferrer">
|
||||
{{if .Permission.CanRead ctx.Consts.RepoUnitTypeExternalWiki}}
|
||||
<a class="item" href="{{(.Repository.MustGetUnit $.Context ctx.Consts.RepoUnitTypeExternalWiki).ExternalWikiConfig.ExternalWikiURL}}" target="_blank" rel="noopener noreferrer">
|
||||
{{svg "octicon-link-external"}} {{ctx.Locale.Tr "repo.wiki"}}
|
||||
</a>
|
||||
{{end}}
|
||||
|
||||
{{if and (.Permission.CanReadAny $.UnitTypePullRequests $.UnitTypeIssues $.UnitTypeReleases) (not .IsEmptyRepo)}}
|
||||
{{if and (.Permission.CanReadAny ctx.Consts.RepoUnitTypePullRequests ctx.Consts.RepoUnitTypeIssues ctx.Consts.RepoUnitTypeReleases) (not .IsEmptyRepo)}}
|
||||
<a class="{{if .PageIsActivity}}active {{end}}item" href="{{.RepoLink}}/activity">
|
||||
{{svg "octicon-pulse"}} {{ctx.Locale.Tr "repo.activity"}}
|
||||
</a>
|
||||
|
|
|
@ -196,7 +196,7 @@
|
|||
{{end}}
|
||||
|
||||
{{if .AllowMerge}} {{/* user is allowed to merge */}}
|
||||
{{$prUnit := .Repository.MustGetUnit $.Context $.UnitTypePullRequests}}
|
||||
{{$prUnit := .Repository.MustGetUnit $.Context ctx.Consts.RepoUnitTypePullRequests}}
|
||||
{{$approvers := (.Issue.PullRequest.GetApprovers ctx)}}
|
||||
{{if or $prUnit.PullRequestsConfig.AllowMerge $prUnit.PullRequestsConfig.AllowRebase $prUnit.PullRequestsConfig.AllowRebaseMerge $prUnit.PullRequestsConfig.AllowSquash $prUnit.PullRequestsConfig.AllowFastForwardOnly}}
|
||||
{{$hasPendingPullRequestMergeTip := ""}}
|
||||
|
|
|
@ -5,26 +5,24 @@
|
|||
<div class="content tw-text-left">
|
||||
<form class="ui form form-fetch-action" action="{{printf "%s/issues/new" .Repository.Link}}" method="post">
|
||||
{{.CsrfTokenHtml}}
|
||||
<div class="ui segment content">
|
||||
<div class="field">
|
||||
<span class="text"><strong>{{ctx.Locale.Tr "repository"}}</strong></span>
|
||||
<div class="ui search normal selection dropdown issue_reference_repository_search">
|
||||
<div class="default text">{{.Repository.FullName}}</div>
|
||||
<div class="menu"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<span class="text"><strong>{{ctx.Locale.Tr "repo.milestones.title"}}</strong></span>
|
||||
<input name="title" value="" autofocus required maxlength="255" autocomplete="off">
|
||||
</div>
|
||||
<div class="field">
|
||||
<span class="text"><strong>{{ctx.Locale.Tr "repo.issues.reference_issue.body"}}</strong></span>
|
||||
<textarea name="content" class="form-control"></textarea>
|
||||
</div>
|
||||
<div class="text right">
|
||||
<button class="ui primary button">{{ctx.Locale.Tr "repo.issues.create"}}</button>
|
||||
<div class="field">
|
||||
<label><strong>{{ctx.Locale.Tr "repository"}}</strong></label>
|
||||
<div class="ui search selection dropdown issue_reference_repository_search">
|
||||
<div class="default text">{{.Repository.FullName}}</div>
|
||||
<div class="menu"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label><strong>{{ctx.Locale.Tr "repo.milestones.title"}}</strong></label>
|
||||
<input name="title" value="" autofocus required maxlength="255" autocomplete="off">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label><strong>{{ctx.Locale.Tr "repo.issues.reference_issue.body"}}</strong></label>
|
||||
<textarea name="content" class="form-control"></textarea>
|
||||
</div>
|
||||
<div class="text right">
|
||||
<button class="ui primary button">{{ctx.Locale.Tr "repo.issues.create"}}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -18,10 +18,10 @@
|
|||
</div>
|
||||
</h2>
|
||||
|
||||
{{if (or (.Permission.CanRead $.UnitTypeIssues) (.Permission.CanRead $.UnitTypePullRequests))}}
|
||||
{{if (or (.Permission.CanRead ctx.Consts.RepoUnitTypeIssues) (.Permission.CanRead ctx.Consts.RepoUnitTypePullRequests))}}
|
||||
<h4 class="ui top attached header">{{ctx.Locale.Tr "repo.activity.overview"}}</h4>
|
||||
<div class="ui attached segment two column grid">
|
||||
{{if .Permission.CanRead $.UnitTypePullRequests}}
|
||||
{{if .Permission.CanRead ctx.Consts.RepoUnitTypePullRequests}}
|
||||
<div class="column">
|
||||
{{if gt .Activity.ActivePRCount 0}}
|
||||
<div class="stats-table">
|
||||
|
@ -38,7 +38,7 @@
|
|||
{{ctx.Locale.TrN .Activity.ActivePRCount "repo.activity.active_prs_count_1" "repo.activity.active_prs_count_n" .Activity.ActivePRCount}}
|
||||
</div>
|
||||
{{end}}
|
||||
{{if .Permission.CanRead $.UnitTypeIssues}}
|
||||
{{if .Permission.CanRead ctx.Consts.RepoUnitTypeIssues}}
|
||||
<div class="column">
|
||||
{{if gt .Activity.ActiveIssueCount 0}}
|
||||
<div class="stats-table">
|
||||
|
@ -57,7 +57,7 @@
|
|||
{{end}}
|
||||
</div>
|
||||
<div class="ui attached segment horizontal segments">
|
||||
{{if .Permission.CanRead $.UnitTypePullRequests}}
|
||||
{{if .Permission.CanRead ctx.Consts.RepoUnitTypePullRequests}}
|
||||
<a href="#merged-pull-requests" class="ui attached segment text center">
|
||||
<span class="text purple">{{svg "octicon-git-pull-request"}}</span> <strong>{{.Activity.MergedPRCount}}</strong><br>
|
||||
{{ctx.Locale.TrN .Activity.MergedPRCount "repo.activity.merged_prs_count_1" "repo.activity.merged_prs_count_n"}}
|
||||
|
@ -67,7 +67,7 @@
|
|||
{{ctx.Locale.TrN .Activity.OpenedPRCount "repo.activity.opened_prs_count_1" "repo.activity.opened_prs_count_n"}}
|
||||
</a>
|
||||
{{end}}
|
||||
{{if .Permission.CanRead $.UnitTypeIssues}}
|
||||
{{if .Permission.CanRead ctx.Consts.RepoUnitTypeIssues}}
|
||||
<a href="#closed-issues" class="ui attached segment text center">
|
||||
<span class="text red">{{svg "octicon-issue-closed"}}</span> <strong>{{.Activity.ClosedIssueCount}}</strong><br>
|
||||
{{ctx.Locale.TrN .Activity.ClosedIssueCount "repo.activity.closed_issues_count_1" "repo.activity.closed_issues_count_n"}}
|
||||
|
@ -80,7 +80,7 @@
|
|||
</div>
|
||||
{{end}}
|
||||
|
||||
{{if .Permission.CanRead $.UnitTypeCode}}
|
||||
{{if .Permission.CanRead ctx.Consts.RepoUnitTypeCode}}
|
||||
{{if eq .Activity.Code.CommitCountInAllBranches 0}}
|
||||
<div class="ui center aligned segment">
|
||||
<h4 class="ui header">{{ctx.Locale.Tr "repo.activity.no_git_activity"}}</h4>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{{if .Permission.CanRead $.UnitTypeCode}}
|
||||
{{if .Permission.CanRead ctx.Consts.RepoUnitTypeCode}}
|
||||
<div id="repo-recent-commits-chart"
|
||||
data-locale-loading-title="{{ctx.Locale.Tr "graphs.component_loading" (ctx.Locale.Tr "graphs.recent_commits.what")}}"
|
||||
data-locale-loading-title-failed="{{ctx.Locale.Tr "graphs.component_loading_failed" (ctx.Locale.Tr "graphs.recent_commits.what")}}"
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
{{$release := $info.Release}}
|
||||
<li class="ui grid">
|
||||
<div class="ui four wide column meta">
|
||||
<a class="muted" href="{{if not (and $release.Sha1 ($.Permission.CanRead $.UnitTypeCode))}}#{{else}}{{$.RepoLink}}/src/tag/{{$release.TagName | PathEscapeSegments}}{{end}}" rel="nofollow">{{svg "octicon-tag" 16 "tw-mr-1"}}{{$release.TagName}}</a>
|
||||
{{if and $release.Sha1 ($.Permission.CanRead $.UnitTypeCode)}}
|
||||
<a class="muted" href="{{if not (and $release.Sha1 ($.Permission.CanRead ctx.Consts.RepoUnitTypeCode))}}#{{else}}{{$.RepoLink}}/src/tag/{{$release.TagName | PathEscapeSegments}}{{end}}" rel="nofollow">{{svg "octicon-tag" 16 "tw-mr-1"}}{{$release.TagName}}</a>
|
||||
{{if and $release.Sha1 ($.Permission.CanRead ctx.Consts.RepoUnitTypeCode)}}
|
||||
<a class="muted tw-font-mono" href="{{$.RepoLink}}/src/commit/{{$release.Sha1}}" rel="nofollow">{{svg "octicon-git-commit" 16 "tw-mr-1"}}{{ShortSha $release.Sha1}}</a>
|
||||
{{template "repo/branch_dropdown" dict "root" $ "release" $release}}
|
||||
{{end}}
|
||||
|
@ -53,7 +53,7 @@
|
|||
{{if $release.CreatedUnix}}
|
||||
<span class="time">{{TimeSinceUnix $release.CreatedUnix ctx.Locale}}</span>
|
||||
{{end}}
|
||||
{{if and (not $release.IsDraft) ($.Permission.CanRead $.UnitTypeCode)}}
|
||||
{{if and (not $release.IsDraft) ($.Permission.CanRead ctx.Consts.RepoUnitTypeCode)}}
|
||||
| <span class="ahead"><a href="{{$.RepoLink}}/compare/{{$release.TagName | PathEscapeSegments}}...{{$release.TargetBehind | PathEscapeSegments}}">{{ctx.Locale.Tr "repo.release.ahead.commits" $release.NumCommitsBehind}}</a> {{ctx.Locale.Tr "repo.release.ahead.target" $release.TargetBehind}}</span>
|
||||
{{end}}
|
||||
</p>
|
||||
|
@ -66,7 +66,7 @@
|
|||
{{ctx.Locale.Tr "repo.release.downloads"}}
|
||||
</summary>
|
||||
<ul class="list">
|
||||
{{if and (not $.DisableDownloadSourceArchives) (not $release.IsDraft) ($.Permission.CanRead $.UnitTypeCode)}}
|
||||
{{if and (not $.DisableDownloadSourceArchives) (not $release.IsDraft) ($.Permission.CanRead ctx.Consts.RepoUnitTypeCode)}}
|
||||
<li>
|
||||
<a class="archive-link" href="{{$.RepoLink}}/archive/{{$release.TagName | PathEscapeSegments}}.zip" rel="nofollow"><strong>{{svg "octicon-file-zip" 16 "tw-mr-1"}}{{ctx.Locale.Tr "repo.release.source_code"}} (ZIP)</strong></a>
|
||||
</li>
|
||||
|
@ -99,7 +99,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{{if (and ($.Permission.CanWrite $.UnitTypeCode) .PageIsTagList)}}
|
||||
{{if (and ($.Permission.CanWrite ctx.Consts.RepoUnitTypeCode) .PageIsTagList)}}
|
||||
<div class="ui g-modal-confirm delete modal">
|
||||
<div class="header">
|
||||
{{svg "octicon-trash"}}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{{$canReadReleases := $.Permission.CanRead $.UnitTypeReleases}}
|
||||
{{$canReadCode := $.Permission.CanRead $.UnitTypeCode}}
|
||||
{{$canReadReleases := $.Permission.CanRead ctx.Consts.RepoUnitTypeReleases}}
|
||||
{{$canReadCode := $.Permission.CanRead ctx.Consts.RepoUnitTypeCode}}
|
||||
|
||||
{{if $canReadReleases}}
|
||||
<div class="tw-flex">
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<a class="ui primary tiny button" href="{{.LFSFilesLink}}/find?oid={{.LFSFile.Oid}}&size={{.LFSFile.Size}}">{{ctx.Locale.Tr "repo.settings.lfs_findcommits"}}</a>
|
||||
</div>
|
||||
</h4>
|
||||
<div class="ui attached table unstackable segment">
|
||||
<div class="ui bottom attached table unstackable segment">
|
||||
{{template "repo/unicode_escape_prompt" dict "EscapeStatus" .EscapeStatus "root" $}}
|
||||
<div class="file-view{{if .IsMarkup}} markup {{.MarkupType}}{{else if .IsPlainText}} plain-text{{else if .IsTextFile}} code-view{{end}}">
|
||||
{{if .IsFileTooLarge}}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
{{ctx.Locale.Tr "repo.settings.hooks"}}
|
||||
</a>
|
||||
{{end}}
|
||||
{{if .Repository.UnitEnabled $.Context $.UnitTypeCode}}
|
||||
{{if .Repository.UnitEnabled $.Context ctx.Consts.RepoUnitTypeCode}}
|
||||
{{if not .Repository.IsEmpty}}
|
||||
<a class="{{if .PageIsSettingsBranches}}active {{end}}item" href="{{.RepoLink}}/settings/branches">
|
||||
{{ctx.Locale.Tr "repo.settings.branches"}}
|
||||
|
@ -35,7 +35,7 @@
|
|||
</a>
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{if and .EnableActions (not .UnitActionsGlobalDisabled) (.Permission.CanRead $.UnitTypeActions)}}
|
||||
{{if and .EnableActions (not .UnitActionsGlobalDisabled) (.Permission.CanRead ctx.Consts.RepoUnitTypeActions)}}
|
||||
<details class="item toggleable-item" {{if or .PageIsSharedSettingsRunners .PageIsSharedSettingsSecrets .PageIsSharedSettingsVariables}}open{{end}}>
|
||||
<summary>{{ctx.Locale.Tr "actions.actions"}}</summary>
|
||||
<div class="menu">
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
{{.CsrfTokenHtml}}
|
||||
<input type="hidden" name="action" value="update">
|
||||
<div class="required field {{if .Err_RepoName}}error{{end}}">
|
||||
<label for="repo_name">{{ctx.Locale.Tr "repo.repo_name"}}</label>
|
||||
<input id="repo_name" name="repo_name" value="{{.Repository.Name}}" data-repo-name="{{.Repository.Name}}" autofocus required>
|
||||
<label>{{ctx.Locale.Tr "repo.repo_name"}}</label>
|
||||
<input name="repo_name" value="{{.Repository.Name}}" data-repo-name="{{.Repository.Name}}" autofocus required>
|
||||
</div>
|
||||
<div class="inline field">
|
||||
<label>{{ctx.Locale.Tr "repo.repo_size"}}</label>
|
||||
|
@ -66,7 +66,7 @@
|
|||
{{/* These variables exist to make the logic in the Settings window easier to comprehend and are not used later on. */}}
|
||||
{{$newMirrorsPartiallyEnabled := or (not .DisableNewPullMirrors) (not .DisableNewPushMirrors)}}
|
||||
{{/* .Repository.IsMirror is not always reliable if the repository is not actively acting as a mirror because of errors. */}}
|
||||
{{$showMirrorSettings := and (.Repository.UnitEnabled $.Context $.UnitTypeCode) (or $newMirrorsPartiallyEnabled .Repository.IsMirror .PullMirror .PushMirrors)}}
|
||||
{{$showMirrorSettings := and (.Repository.UnitEnabled $.Context ctx.Consts.RepoUnitTypeCode) (or $newMirrorsPartiallyEnabled .Repository.IsMirror .PullMirror .PushMirrors)}}
|
||||
{{$newMirrorsEntirelyEnabled := and (not .DisableNewPullMirrors) (not .DisableNewPushMirrors)}}
|
||||
{{$onlyNewPushMirrorsEnabled := and (not .DisableNewPushMirrors) .DisableNewPullMirrors}}
|
||||
{{$onlyNewPullMirrorsEnabled := and .DisableNewPushMirrors (not .DisableNewPullMirrors)}}
|
||||
|
@ -307,8 +307,8 @@
|
|||
{{.CsrfTokenHtml}}
|
||||
<input type="hidden" name="action" value="advanced">
|
||||
|
||||
{{$isCodeEnabled := .Repository.UnitEnabled $.Context $.UnitTypeCode}}
|
||||
{{$isCodeGlobalDisabled := .UnitTypeCode.UnitGlobalDisabled}}
|
||||
{{$isCodeEnabled := .Repository.UnitEnabled $.Context ctx.Consts.RepoUnitTypeCode}}
|
||||
{{$isCodeGlobalDisabled := ctx.Consts.RepoUnitTypeCode.UnitGlobalDisabled}}
|
||||
<div class="inline field">
|
||||
<label>{{ctx.Locale.Tr "repo.code"}}</label>
|
||||
<div class="ui checkbox{{if $isCodeGlobalDisabled}} disabled{{end}}"{{if $isCodeGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
|
||||
|
@ -317,9 +317,11 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{{$isWikiEnabled := or (.Repository.UnitEnabled $.Context $.UnitTypeWiki) (.Repository.UnitEnabled $.Context $.UnitTypeExternalWiki)}}
|
||||
{{$isWikiGlobalDisabled := .UnitTypeWiki.UnitGlobalDisabled}}
|
||||
{{$isExternalWikiGlobalDisabled := .UnitTypeExternalWiki.UnitGlobalDisabled}}
|
||||
{{$isInternalWikiEnabled := .Repository.UnitEnabled ctx ctx.Consts.RepoUnitTypeWiki}}
|
||||
{{$isExternalWikiEnabled := .Repository.UnitEnabled ctx ctx.Consts.RepoUnitTypeExternalWiki}}
|
||||
{{$isWikiEnabled := or $isInternalWikiEnabled $isExternalWikiEnabled}}
|
||||
{{$isWikiGlobalDisabled := ctx.Consts.RepoUnitTypeWiki.UnitGlobalDisabled}}
|
||||
{{$isExternalWikiGlobalDisabled := ctx.Consts.RepoUnitTypeExternalWiki.UnitGlobalDisabled}}
|
||||
{{$isBothWikiGlobalDisabled := and $isWikiGlobalDisabled $isExternalWikiGlobalDisabled}}
|
||||
<div class="inline field">
|
||||
<label>{{ctx.Locale.Tr "repo.wiki"}}</label>
|
||||
|
@ -331,32 +333,44 @@
|
|||
<div class="field{{if not $isWikiEnabled}} disabled{{end}}" id="wiki_box">
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox{{if $isWikiGlobalDisabled}} disabled{{end}}"{{if $isWikiGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
|
||||
<input class="enable-system-radio" name="enable_external_wiki" type="radio" value="false" data-target="#external_wiki_box" {{if not (.Repository.UnitEnabled $.Context $.UnitTypeExternalWiki)}}checked{{end}}>
|
||||
<input class="enable-system-radio" name="enable_external_wiki" type="radio" value="false" data-context="#internal_wiki_box" data-target="#external_wiki_box" {{if $isInternalWikiEnabled}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.use_internal_wiki"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="inline field tw-pl-4">
|
||||
<label>{{ctx.Locale.Tr "repo.settings.default_wiki_branch_name"}}</label>
|
||||
<input name="default_wiki_branch" value="{{.Repository.DefaultWikiBranch}}">
|
||||
<div id="internal_wiki_box" class="field tw-pl-4 {{if not $isInternalWikiEnabled}}disabled{{end}}">
|
||||
<div class="inline field">
|
||||
<label>{{ctx.Locale.Tr "repo.settings.default_wiki_branch_name"}}</label>
|
||||
<input name="default_wiki_branch" value="{{.Repository.DefaultWikiBranch}}">
|
||||
</div>
|
||||
<div class="inline field">
|
||||
{{$unitInternalWiki := .Repository.MustGetUnit ctx ctx.Consts.RepoUnitTypeWiki}}
|
||||
<label>{{ctx.Locale.Tr "repo.settings.default_wiki_everyone_access"}}</label>
|
||||
<select name="default_wiki_everyone_access" class="ui dropdown">
|
||||
{{/* everyone access mode is different from others, none means it is unset and won't be applied */}}
|
||||
<option value="none" {{Iif (eq $unitInternalWiki.EveryoneAccessMode 0) "selected"}}>{{ctx.Locale.Tr "settings.permission_not_set"}}</option>
|
||||
<option value="read" {{Iif (eq $unitInternalWiki.EveryoneAccessMode 1) "selected"}}>{{ctx.Locale.Tr "settings.permission_read"}}</option>
|
||||
<option value="write" {{Iif (eq $unitInternalWiki.EveryoneAccessMode 2) "selected"}}>{{ctx.Locale.Tr "settings.permission_write"}}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox{{if $isExternalWikiGlobalDisabled}} disabled{{end}}"{{if $isExternalWikiGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
|
||||
<input class="enable-system-radio" name="enable_external_wiki" type="radio" value="true" data-target="#external_wiki_box" {{if .Repository.UnitEnabled $.Context $.UnitTypeExternalWiki}}checked{{end}}>
|
||||
<input class="enable-system-radio" name="enable_external_wiki" type="radio" value="true" data-context="#internal_wiki_box" data-target="#external_wiki_box" {{if $isExternalWikiEnabled}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.use_external_wiki"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field tw-pl-4 {{if not (.Repository.UnitEnabled $.Context $.UnitTypeExternalWiki)}}disabled{{end}}" id="external_wiki_box">
|
||||
<div id="external_wiki_box" class="field tw-pl-4 {{if not $isExternalWikiEnabled}}disabled{{end}}">
|
||||
<label for="external_wiki_url">{{ctx.Locale.Tr "repo.settings.external_wiki_url"}}</label>
|
||||
<input id="external_wiki_url" name="external_wiki_url" type="url" value="{{(.Repository.MustGetUnit $.Context $.UnitTypeExternalWiki).ExternalWikiConfig.ExternalWikiURL}}">
|
||||
<input id="external_wiki_url" name="external_wiki_url" type="url" value="{{(.Repository.MustGetUnit $.Context ctx.Consts.RepoUnitTypeExternalWiki).ExternalWikiConfig.ExternalWikiURL}}">
|
||||
<p class="help">{{ctx.Locale.Tr "repo.settings.external_wiki_url_desc"}}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="divider"></div>
|
||||
|
||||
{{$isIssuesEnabled := or (.Repository.UnitEnabled $.Context $.UnitTypeIssues) (.Repository.UnitEnabled $.Context $.UnitTypeExternalTracker)}}
|
||||
{{$isIssuesGlobalDisabled := .UnitTypeIssues.UnitGlobalDisabled}}
|
||||
{{$isExternalTrackerGlobalDisabled := .UnitTypeExternalTracker.UnitGlobalDisabled}}
|
||||
{{$isIssuesEnabled := or (.Repository.UnitEnabled $.Context ctx.Consts.RepoUnitTypeIssues) (.Repository.UnitEnabled $.Context ctx.Consts.RepoUnitTypeExternalTracker)}}
|
||||
{{$isIssuesGlobalDisabled := ctx.Consts.RepoUnitTypeIssues.UnitGlobalDisabled}}
|
||||
{{$isExternalTrackerGlobalDisabled := ctx.Consts.RepoUnitTypeExternalTracker.UnitGlobalDisabled}}
|
||||
{{$isIssuesAndExternalGlobalDisabled := and $isIssuesGlobalDisabled $isExternalTrackerGlobalDisabled}}
|
||||
<div class="inline field">
|
||||
<label>{{ctx.Locale.Tr "repo.issues"}}</label>
|
||||
|
@ -368,11 +382,11 @@
|
|||
<div class="field {{if not $isIssuesEnabled}}disabled{{end}}" id="issue_box">
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox{{if $isIssuesGlobalDisabled}} disabled{{end}}"{{if $isIssuesGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
|
||||
<input class="enable-system-radio" name="enable_external_tracker" type="radio" value="false" data-context="#internal_issue_box" data-target="#external_issue_box" {{if not (.Repository.UnitEnabled $.Context $.UnitTypeExternalTracker)}}checked{{end}}>
|
||||
<input class="enable-system-radio" name="enable_external_tracker" type="radio" value="false" data-context="#internal_issue_box" data-target="#external_issue_box" {{if not (.Repository.UnitEnabled $.Context ctx.Consts.RepoUnitTypeExternalTracker)}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.use_internal_issue_tracker"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field tw-pl-4 {{if (.Repository.UnitEnabled $.Context $.UnitTypeExternalTracker)}}disabled{{end}}" id="internal_issue_box">
|
||||
<div class="field tw-pl-4 {{if (.Repository.UnitEnabled $.Context ctx.Consts.RepoUnitTypeExternalTracker)}}disabled{{end}}" id="internal_issue_box">
|
||||
{{if .Repository.CanEnableTimetracker}}
|
||||
<div class="field">
|
||||
<div class="ui checkbox">
|
||||
|
@ -400,26 +414,26 @@
|
|||
</div>
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox{{if $isExternalTrackerGlobalDisabled}} disabled{{end}}"{{if $isExternalTrackerGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
|
||||
<input class="enable-system-radio" name="enable_external_tracker" type="radio" value="true" data-context="#internal_issue_box" data-target="#external_issue_box" {{if .Repository.UnitEnabled $.Context $.UnitTypeExternalTracker}}checked{{end}}>
|
||||
<input class="enable-system-radio" name="enable_external_tracker" type="radio" value="true" data-context="#internal_issue_box" data-target="#external_issue_box" {{if .Repository.UnitEnabled $.Context ctx.Consts.RepoUnitTypeExternalTracker}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.use_external_issue_tracker"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field tw-pl-4 {{if not (.Repository.UnitEnabled $.Context $.UnitTypeExternalTracker)}}disabled{{end}}" id="external_issue_box">
|
||||
<div class="field tw-pl-4 {{if not (.Repository.UnitEnabled $.Context ctx.Consts.RepoUnitTypeExternalTracker)}}disabled{{end}}" id="external_issue_box">
|
||||
<div class="field">
|
||||
<label for="external_tracker_url">{{ctx.Locale.Tr "repo.settings.external_tracker_url"}}</label>
|
||||
<input id="external_tracker_url" name="external_tracker_url" type="url" value="{{(.Repository.MustGetUnit $.Context $.UnitTypeExternalTracker).ExternalTrackerConfig.ExternalTrackerURL}}">
|
||||
<input id="external_tracker_url" name="external_tracker_url" type="url" value="{{(.Repository.MustGetUnit $.Context ctx.Consts.RepoUnitTypeExternalTracker).ExternalTrackerConfig.ExternalTrackerURL}}">
|
||||
<p class="help">{{ctx.Locale.Tr "repo.settings.external_tracker_url_desc"}}</p>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="tracker_url_format">{{ctx.Locale.Tr "repo.settings.tracker_url_format"}}</label>
|
||||
<input id="tracker_url_format" name="tracker_url_format" type="url" value="{{(.Repository.MustGetUnit $.Context $.UnitTypeExternalTracker).ExternalTrackerConfig.ExternalTrackerFormat}}" placeholder="https://github.com/{user}/{repo}/issues/{index}">
|
||||
<input id="tracker_url_format" name="tracker_url_format" type="url" value="{{(.Repository.MustGetUnit $.Context ctx.Consts.RepoUnitTypeExternalTracker).ExternalTrackerConfig.ExternalTrackerFormat}}" placeholder="https://github.com/{user}/{repo}/issues/{index}">
|
||||
<p class="help">{{ctx.Locale.Tr "repo.settings.tracker_url_format_desc"}}</p>
|
||||
</div>
|
||||
<div class="inline fields">
|
||||
<label for="issue_style">{{ctx.Locale.Tr "repo.settings.tracker_issue_style"}}</label>
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox">
|
||||
{{$externalTracker := (.Repository.MustGetUnit $.Context $.UnitTypeExternalTracker)}}
|
||||
{{$externalTracker := (.Repository.MustGetUnit $.Context ctx.Consts.RepoUnitTypeExternalTracker)}}
|
||||
{{$externalTrackerStyle := $externalTracker.ExternalTrackerConfig.ExternalTrackerStyle}}
|
||||
<input class="js-tracker-issue-style" name="tracker_issue_style" type="radio" value="numeric" {{if eq $externalTrackerStyle "numeric"}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.tracker_issue_style.numeric"}} <span class="ui light grey text">#1234</span></label>
|
||||
|
@ -440,7 +454,7 @@
|
|||
</div>
|
||||
<div class="field {{if ne $externalTrackerStyle "regexp"}}disabled{{end}}" id="tracker-issue-style-regex-box">
|
||||
<label for="external_tracker_regexp_pattern">{{ctx.Locale.Tr "repo.settings.tracker_issue_style.regexp_pattern"}}</label>
|
||||
<input id="external_tracker_regexp_pattern" name="external_tracker_regexp_pattern" value="{{(.Repository.MustGetUnit $.Context $.UnitTypeExternalTracker).ExternalTrackerConfig.ExternalTrackerRegexpPattern}}">
|
||||
<input id="external_tracker_regexp_pattern" name="external_tracker_regexp_pattern" value="{{(.Repository.MustGetUnit $.Context ctx.Consts.RepoUnitTypeExternalTracker).ExternalTrackerConfig.ExternalTrackerRegexpPattern}}">
|
||||
<p class="help">{{ctx.Locale.Tr "repo.settings.tracker_issue_style.regexp_pattern_desc"}}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -448,9 +462,9 @@
|
|||
|
||||
<div class="divider"></div>
|
||||
|
||||
{{$isProjectsEnabled := .Repository.UnitEnabled $.Context $.UnitTypeProjects}}
|
||||
{{$isProjectsGlobalDisabled := .UnitTypeProjects.UnitGlobalDisabled}}
|
||||
{{$projectsUnit := .Repository.MustGetUnit $.Context $.UnitTypeProjects}}
|
||||
{{$isProjectsEnabled := .Repository.UnitEnabled $.Context ctx.Consts.RepoUnitTypeProjects}}
|
||||
{{$isProjectsGlobalDisabled := ctx.Consts.RepoUnitTypeProjects.UnitGlobalDisabled}}
|
||||
{{$projectsUnit := .Repository.MustGetUnit $.Context ctx.Consts.RepoUnitTypeProjects}}
|
||||
<div class="inline field">
|
||||
<label>{{ctx.Locale.Tr "repo.project_board"}}</label>
|
||||
<div class="ui checkbox{{if $isProjectsGlobalDisabled}} disabled{{end}}"{{if $isProjectsGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
|
||||
|
@ -490,8 +504,8 @@
|
|||
|
||||
<div class="divider"></div>
|
||||
|
||||
{{$isReleasesEnabled := .Repository.UnitEnabled $.Context $.UnitTypeReleases}}
|
||||
{{$isReleasesGlobalDisabled := .UnitTypeReleases.UnitGlobalDisabled}}
|
||||
{{$isReleasesEnabled := .Repository.UnitEnabled $.Context ctx.Consts.RepoUnitTypeReleases}}
|
||||
{{$isReleasesGlobalDisabled := ctx.Consts.RepoUnitTypeReleases.UnitGlobalDisabled}}
|
||||
<div class="inline field">
|
||||
<label>{{ctx.Locale.Tr "repo.releases"}}</label>
|
||||
<div class="ui checkbox{{if $isReleasesGlobalDisabled}} disabled{{end}}"{{if $isReleasesGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
|
||||
|
@ -500,8 +514,8 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{{$isPackagesEnabled := .Repository.UnitEnabled $.Context $.UnitTypePackages}}
|
||||
{{$isPackagesGlobalDisabled := .UnitTypePackages.UnitGlobalDisabled}}
|
||||
{{$isPackagesEnabled := .Repository.UnitEnabled $.Context ctx.Consts.RepoUnitTypePackages}}
|
||||
{{$isPackagesGlobalDisabled := ctx.Consts.RepoUnitTypePackages.UnitGlobalDisabled}}
|
||||
<div class="inline field">
|
||||
<label>{{ctx.Locale.Tr "repo.packages"}}</label>
|
||||
<div class="ui checkbox{{if $isPackagesGlobalDisabled}} disabled{{end}}"{{if $isPackagesGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
|
||||
|
@ -511,8 +525,8 @@
|
|||
</div>
|
||||
|
||||
{{if .EnableActions}}
|
||||
{{$isActionsEnabled := .Repository.UnitEnabled $.Context $.UnitTypeActions}}
|
||||
{{$isActionsGlobalDisabled := .UnitTypeActions.UnitGlobalDisabled}}
|
||||
{{$isActionsEnabled := .Repository.UnitEnabled $.Context ctx.Consts.RepoUnitTypeActions}}
|
||||
{{$isActionsGlobalDisabled := ctx.Consts.RepoUnitTypeActions.UnitGlobalDisabled}}
|
||||
<div class="inline field">
|
||||
<label>{{ctx.Locale.Tr "actions.actions"}}</label>
|
||||
<div class="ui checkbox{{if $isActionsGlobalDisabled}} disabled{{end}}"{{if $isActionsGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
|
||||
|
@ -524,9 +538,9 @@
|
|||
|
||||
{{if not .IsMirror}}
|
||||
<div class="divider"></div>
|
||||
{{$pullRequestEnabled := .Repository.UnitEnabled $.Context $.UnitTypePullRequests}}
|
||||
{{$pullRequestGlobalDisabled := .UnitTypePullRequests.UnitGlobalDisabled}}
|
||||
{{$prUnit := .Repository.MustGetUnit $.Context $.UnitTypePullRequests}}
|
||||
{{$pullRequestEnabled := .Repository.UnitEnabled $.Context ctx.Consts.RepoUnitTypePullRequests}}
|
||||
{{$pullRequestGlobalDisabled := ctx.Consts.RepoUnitTypePullRequests.UnitGlobalDisabled}}
|
||||
{{$prUnit := .Repository.MustGetUnit $.Context ctx.Consts.RepoUnitTypePullRequests}}
|
||||
<div class="inline field">
|
||||
<label>{{ctx.Locale.Tr "repo.pulls"}}</label>
|
||||
<div class="ui checkbox{{if $pullRequestGlobalDisabled}} disabled{{end}}"{{if $pullRequestGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
|
||||
|
@ -816,7 +830,7 @@
|
|||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
{{if .Permission.CanRead $.UnitTypeWiki}}
|
||||
{{if .Permission.CanRead ctx.Consts.RepoUnitTypeWiki}}
|
||||
<div class="flex-item">
|
||||
<div class="flex-item-main">
|
||||
<div class="flex-item-title">{{ctx.Locale.Tr "repo.settings.wiki_delete"}}</div>
|
||||
|
@ -884,8 +898,8 @@
|
|||
</label>
|
||||
</div>
|
||||
<div class="required field">
|
||||
<label for="repo_name">{{ctx.Locale.Tr "repo.repo_name"}}</label>
|
||||
<input id="repo_name" name="repo_name" required maxlength="100">
|
||||
<label>{{ctx.Locale.Tr "repo.repo_name"}}</label>
|
||||
<input name="repo_name" required maxlength="100">
|
||||
</div>
|
||||
|
||||
<div class="text right actions">
|
||||
|
@ -915,8 +929,8 @@
|
|||
</label>
|
||||
</div>
|
||||
<div class="required field">
|
||||
<label for="repo_name">{{ctx.Locale.Tr "repo.repo_name"}}</label>
|
||||
<input id="repo_name" name="repo_name" required>
|
||||
<label>{{ctx.Locale.Tr "repo.repo_name"}}</label>
|
||||
<input name="repo_name" required>
|
||||
</div>
|
||||
|
||||
<div class="text right actions">
|
||||
|
@ -947,8 +961,8 @@
|
|||
</label>
|
||||
</div>
|
||||
<div class="required field">
|
||||
<label for="repo_name">{{ctx.Locale.Tr "repo.repo_name"}}</label>
|
||||
<input id="repo_name" name="repo_name" required>
|
||||
<label>{{ctx.Locale.Tr "repo.repo_name"}}</label>
|
||||
<input name="repo_name" required>
|
||||
</div>
|
||||
<div class="required field">
|
||||
<label for="new_owner_name">{{ctx.Locale.Tr "repo.settings.transfer_owner"}}</label>
|
||||
|
@ -997,7 +1011,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{{if .Repository.UnitEnabled $.Context $.UnitTypeWiki}}
|
||||
{{if .Repository.UnitEnabled $.Context ctx.Consts.RepoUnitTypeWiki}}
|
||||
<div class="ui small modal" id="delete-wiki-modal">
|
||||
<div class="header">
|
||||
{{ctx.Locale.Tr "repo.settings.wiki_delete"}}
|
||||
|
@ -1017,8 +1031,8 @@
|
|||
</label>
|
||||
</div>
|
||||
<div class="required field">
|
||||
<label for="repo_name">{{ctx.Locale.Tr "repo.repo_name"}}</label>
|
||||
<input id="repo_name" name="repo_name" required>
|
||||
<label>{{ctx.Locale.Tr "repo.repo_name"}}</label>
|
||||
<input name="repo_name" required>
|
||||
</div>
|
||||
|
||||
<div class="text right actions">
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
{{if $.IsStaringRepo}}{{$buttonText = ctx.Locale.Tr "repo.unstar"}}{{end}}
|
||||
<button type="submit" class="ui compact small basic button"{{if not $.IsSigned}} disabled{{end}} aria-label="{{$buttonText}}">
|
||||
{{if $.IsStaringRepo}}{{svg "octicon-star-fill"}}{{else}}{{svg "octicon-star"}}{{end}}
|
||||
<span class="not-mobile" aria-hidden="true">{{$buttonText}}</span>
|
||||
<span aria-hidden="true">{{$buttonText}}</span>
|
||||
</button>
|
||||
<a hx-boost="false" class="ui basic label" href="{{$.RepoLink}}/stars">
|
||||
{{CountFmt .Repository.NumStars}}
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
{{if and (not .HideRepoInfo) (not .IsBlame)}}
|
||||
<div class="ui segments repository-summary tw-mt-1 tw-mb-0">
|
||||
<div class="ui segment sub-menu repository-menu">
|
||||
{{if and (.Permission.CanRead $.UnitTypeCode) (not .IsEmptyRepo)}}
|
||||
{{if and (.Permission.CanRead ctx.Consts.RepoUnitTypeCode) (not .IsEmptyRepo)}}
|
||||
<a class="item muted {{if .PageIsCommits}}active{{end}}" href="{{.RepoLink}}/commits/{{.BranchNameSubURL}}">
|
||||
{{svg "octicon-history"}} <b>{{ctx.Locale.PrettyNumber .CommitsCount}}</b> {{ctx.Locale.TrN .CommitsCount "repo.commit" "repo.commits"}}
|
||||
</a>
|
||||
<a class="item muted {{if .PageIsBranches}}active{{end}}" href="{{.RepoLink}}/branches">
|
||||
{{svg "octicon-git-branch"}} <b>{{ctx.Locale.PrettyNumber .BranchesCount}}</b> {{ctx.Locale.TrN .BranchesCount "repo.branch" "repo.branches"}}
|
||||
</a>
|
||||
{{if $.Permission.CanRead $.UnitTypeCode}}
|
||||
{{if $.Permission.CanRead ctx.Consts.RepoUnitTypeCode}}
|
||||
<a class="item muted {{if .PageIsTagList}}active{{end}}" href="{{.RepoLink}}/tags">
|
||||
{{svg "octicon-tag"}} <b>{{ctx.Locale.PrettyNumber .NumTags}}</b> {{ctx.Locale.TrN .NumTags "repo.tag" "repo.tags"}}
|
||||
</a>
|
||||
|
@ -20,7 +20,7 @@
|
|||
</span>
|
||||
{{end}}
|
||||
</div>
|
||||
{{if and (.Permission.CanRead $.UnitTypeCode) (not .IsEmptyRepo) .LanguageStats}}
|
||||
{{if and (.Permission.CanRead ctx.Consts.RepoUnitTypeCode) (not .IsEmptyRepo) .LanguageStats}}
|
||||
<div class="ui segment sub-menu language-stats-details tw-hidden">
|
||||
{{range .LanguageStats}}
|
||||
<div class="item">
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
{{svg "octicon-tag" 16 "tw-mr-1"}}{{ctx.Locale.Tr "repo.release.tags"}}
|
||||
</div>
|
||||
</h4>
|
||||
{{$canReadReleases := $.Permission.CanRead $.UnitTypeReleases}}
|
||||
{{$canReadReleases := $.Permission.CanRead ctx.Consts.RepoUnitTypeReleases}}
|
||||
<div class="ui attached table segment">
|
||||
<table class="ui very basic striped fixed table single line" id="tags-table">
|
||||
<tbody class="tag-list">
|
||||
|
@ -24,7 +24,7 @@
|
|||
{{end}}
|
||||
</h3>
|
||||
<div class="download tw-flex tw-items-center">
|
||||
{{if $.Permission.CanRead $.UnitTypeCode}}
|
||||
{{if $.Permission.CanRead ctx.Consts.RepoUnitTypeCode}}
|
||||
{{if .CreatedUnix}}
|
||||
<span class="tw-mr-2">{{svg "octicon-clock" 16 "tw-mr-1"}}{{TimeSinceUnix .CreatedUnix ctx.Locale}}</span>
|
||||
{{end}}
|
||||
|
@ -40,7 +40,7 @@
|
|||
<a class="tw-mr-2 muted" href="{{$.RepoLink}}/releases/new?tag={{.TagName}}">{{svg "octicon-tag" 16 "tw-mr-1"}}{{ctx.Locale.Tr "repo.release.new_release"}}</a>
|
||||
{{end}}
|
||||
|
||||
{{if (and ($.Permission.CanWrite $.UnitTypeCode) $release.IsTag)}}
|
||||
{{if (and ($.Permission.CanWrite ctx.Consts.RepoUnitTypeCode) $release.IsTag)}}
|
||||
<a class="ui delete-button tw-mr-2 muted" data-url="{{$.RepoLink}}/tags/delete" data-id="{{.ID}}">
|
||||
{{svg "octicon-trash" 16 "tw-mr-1"}}{{ctx.Locale.Tr "repo.release.delete_tag"}}
|
||||
</a>
|
||||
|
@ -62,7 +62,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{{if $.Permission.CanWrite $.UnitTypeCode}}
|
||||
{{if $.Permission.CanWrite ctx.Consts.RepoUnitTypeCode}}
|
||||
<div class="ui g-modal-confirm delete modal">
|
||||
<div class="header">
|
||||
{{svg "octicon-trash"}}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
{{end}}
|
||||
|
||||
{{if not .ReadmeInList}}
|
||||
<div id="repo-file-commit-box" class="ui top attached header list-header tw-mb-4 tw-flex tw-justify-between">
|
||||
<div id="repo-file-commit-box" class="ui segment list-header tw-mb-4 tw-flex tw-justify-between">
|
||||
<div class="latest-commit">
|
||||
{{template "repo/latest_commit" .}}
|
||||
</div>
|
||||
|
@ -84,7 +84,7 @@
|
|||
{{end}}
|
||||
</div>
|
||||
</h4>
|
||||
<div class="ui attached table unstackable segment">
|
||||
<div class="ui bottom attached table unstackable segment">
|
||||
{{if not (or .IsMarkup .IsRenderedHTML)}}
|
||||
{{template "repo/unicode_escape_prompt" dict "EscapeStatus" .EscapeStatus "root" $}}
|
||||
{{end}}
|
||||
|
@ -129,7 +129,7 @@
|
|||
</tbody>
|
||||
</table>
|
||||
<div class="code-line-menu tippy-target">
|
||||
{{if $.Permission.CanRead $.UnitTypeIssues}}
|
||||
{{if $.Permission.CanRead ctx.Consts.RepoUnitTypeIssues}}
|
||||
<a class="item ref-in-new-issue" role="menuitem" data-url-issue-new="{{.RepoLink}}/issues/new" data-url-param-body-link="{{.Repository.Link}}/src/commit/{{PathEscape .CommitID}}/{{PathEscapeSegments .TreePath}}{{if $.HasSourceRenderedToggle}}?display=source{{end}}" rel="nofollow noindex">{{ctx.Locale.Tr "repo.issues.context.reference_issue"}}</a>
|
||||
{{end}}
|
||||
<a class="item view_git_blame" role="menuitem" href="{{.Repository.Link}}/blame/commit/{{PathEscape .CommitID}}/{{PathEscapeSegments .TreePath}}">{{ctx.Locale.Tr "repo.view_git_blame"}}</a>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
{{if $.IsWatchingRepo}}{{$buttonText = ctx.Locale.Tr "repo.unwatch"}}{{end}}
|
||||
<button type="submit" class="ui compact small basic button"{{if not $.IsSigned}} disabled{{end}} aria-label="{{$buttonText}}">
|
||||
{{svg "octicon-eye"}}
|
||||
<span class="not-mobile" aria-hidden="true">{{$buttonText}}</span>
|
||||
<span aria-hidden="true">{{$buttonText}}</span>
|
||||
</button>
|
||||
<a hx-boost="false" class="ui basic label" href="{{.RepoLink}}/watchers">
|
||||
{{CountFmt .Repository.NumWatches}}
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
{{/* IsFuzzy - state of the fuzzy search toggle */}}
|
||||
<div class="ui small dropdown selection {{if .Disabled}} disabled{{end}}" data-tooltip-content="{{ctx.Locale.Tr "search.type_tooltip"}}">
|
||||
<input name="fuzzy" type="hidden"{{if .Disabled}} disabled{{end}} value="{{.IsFuzzy}}">{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
||||
<div class="text">{{if .IsFuzzy}}{{ctx.Locale.Tr "search.fuzzy"}}{{else}}{{ctx.Locale.Tr "search.match"}}{{end}}</div>
|
||||
<div class="text">{{if .IsFuzzy}}{{ctx.Locale.Tr "search.fuzzy"}}{{else}}{{ctx.Locale.Tr "search.exact"}}{{end}}</div>
|
||||
<div class="menu">
|
||||
<div class="item" data-value="true" data-tooltip-content="{{ctx.Locale.Tr "search.fuzzy_tooltip"}}">{{ctx.Locale.Tr "search.fuzzy"}}</div>
|
||||
<div class="item" data-value="false" data-tooltip-content="{{ctx.Locale.Tr "search.match_tooltip"}}">{{ctx.Locale.Tr "search.match"}}</div>
|
||||
<div class="item" data-value="false" data-tooltip-content="{{ctx.Locale.Tr "search.exact_tooltip"}}">{{ctx.Locale.Tr "search.exact"}}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -6,29 +6,29 @@
|
|||
<div class="flex-container">
|
||||
<div class="flex-container-nav">
|
||||
<div class="ui secondary vertical filter menu tw-bg-transparent">
|
||||
<a class="{{if eq .ViewType "your_repositories"}}active{{end}} item" href="?type=your_repositories&sort={{$.SortType}}&state={{.State}}&q={{$.Keyword}}">
|
||||
<a class="{{if eq .ViewType "your_repositories"}}active{{end}} item" href="?type=your_repositories&sort={{$.SortType}}&state={{.State}}&q={{$.Keyword}}&fuzzy={{.IsFuzzy}}">
|
||||
{{ctx.Locale.Tr "home.issues.in_your_repos"}}
|
||||
<strong>{{CountFmt .IssueStats.YourRepositoriesCount}}</strong>
|
||||
</a>
|
||||
<a class="{{if eq .ViewType "assigned"}}active{{end}} item" href="?type=assigned&sort={{$.SortType}}&state={{.State}}&q={{$.Keyword}}">
|
||||
<a class="{{if eq .ViewType "assigned"}}active{{end}} item" href="?type=assigned&sort={{$.SortType}}&state={{.State}}&q={{$.Keyword}}&fuzzy={{.IsFuzzy}}">
|
||||
{{ctx.Locale.Tr "repo.issues.filter_type.assigned_to_you"}}
|
||||
<strong>{{CountFmt .IssueStats.AssignCount}}</strong>
|
||||
</a>
|
||||
<a class="{{if eq .ViewType "created_by"}}active{{end}} item" href="?type=created_by&sort={{$.SortType}}&state={{.State}}&q={{$.Keyword}}">
|
||||
<a class="{{if eq .ViewType "created_by"}}active{{end}} item" href="?type=created_by&sort={{$.SortType}}&state={{.State}}&q={{$.Keyword}}&fuzzy={{.IsFuzzy}}">
|
||||
{{ctx.Locale.Tr "repo.issues.filter_type.created_by_you"}}
|
||||
<strong>{{CountFmt .IssueStats.CreateCount}}</strong>
|
||||
</a>
|
||||
{{if .PageIsPulls}}
|
||||
<a class="{{if eq .ViewType "review_requested"}}active{{end}} item" href="?type=review_requested&sort={{$.SortType}}&state={{.State}}&q={{$.Keyword}}">
|
||||
<a class="{{if eq .ViewType "review_requested"}}active{{end}} item" href="?type=review_requested&sort={{$.SortType}}&state={{.State}}&q={{$.Keyword}}&fuzzy={{.IsFuzzy}}">
|
||||
{{ctx.Locale.Tr "repo.issues.filter_type.review_requested"}}
|
||||
<strong>{{CountFmt .IssueStats.ReviewRequestedCount}}</strong>
|
||||
</a>
|
||||
<a class="{{if eq .ViewType "reviewed_by"}}active{{end}} item" href="?type=reviewed_by&sort={{$.SortType}}&state={{.State}}&q={{$.Keyword}}">
|
||||
<a class="{{if eq .ViewType "reviewed_by"}}active{{end}} item" href="?type=reviewed_by&sort={{$.SortType}}&state={{.State}}&q={{$.Keyword}}&fuzzy={{.IsFuzzy}}">
|
||||
{{ctx.Locale.Tr "repo.issues.filter_type.reviewed_by_you"}}
|
||||
<strong>{{CountFmt .IssueStats.ReviewedCount}}</strong>
|
||||
</a>
|
||||
{{end}}
|
||||
<a class="{{if eq .ViewType "mentioned"}}active{{end}} item" href="?type=mentioned&sort={{$.SortType}}&state={{.State}}&q={{$.Keyword}}">
|
||||
<a class="{{if eq .ViewType "mentioned"}}active{{end}} item" href="?type=mentioned&sort={{$.SortType}}&state={{.State}}&q={{$.Keyword}}&fuzzy={{.IsFuzzy}}">
|
||||
{{ctx.Locale.Tr "repo.issues.filter_type.mentioning_you"}}
|
||||
<strong>{{CountFmt .IssueStats.MentionCount}}</strong>
|
||||
</a>
|
||||
|
@ -37,11 +37,11 @@
|
|||
<div class="flex-container-main content">
|
||||
<div class="list-header">
|
||||
<div class="small-menu-items ui compact tiny menu list-header-toggle">
|
||||
<a class="item{{if not .IsShowClosed}} active{{end}}" href="?type={{$.ViewType}}&sort={{$.SortType}}&state=open&q={{$.Keyword}}">
|
||||
<a class="item{{if not .IsShowClosed}} active{{end}}" href="?type={{$.ViewType}}&sort={{$.SortType}}&state=open&q={{$.Keyword}}&fuzzy={{.IsFuzzy}}">
|
||||
{{svg "octicon-issue-opened" 16 "tw-mr-2"}}
|
||||
{{ctx.Locale.PrettyNumber .IssueStats.OpenCount}} {{ctx.Locale.Tr "repo.issues.open_title"}}
|
||||
</a>
|
||||
<a class="item{{if .IsShowClosed}} active{{end}}" href="?type={{$.ViewType}}&sort={{$.SortType}}&state=closed&q={{$.Keyword}}">
|
||||
<a class="item{{if .IsShowClosed}} active{{end}}" href="?type={{$.ViewType}}&sort={{$.SortType}}&state=closed&q={{$.Keyword}}&fuzzy={{.IsFuzzy}}">
|
||||
{{svg "octicon-issue-closed" 16 "tw-mr-2"}}
|
||||
{{ctx.Locale.PrettyNumber .IssueStats.ClosedCount}} {{ctx.Locale.Tr "repo.issues.closed_title"}}
|
||||
</a>
|
||||
|
@ -51,9 +51,11 @@
|
|||
<input type="hidden" name="type" value="{{$.ViewType}}">
|
||||
<input type="hidden" name="sort" value="{{$.SortType}}">
|
||||
<input type="hidden" name="state" value="{{$.State}}">
|
||||
{{template "shared/search/input" dict "Value" $.Keyword}}
|
||||
<button id="issue-list-quick-goto" class="ui small icon button tw-hidden" data-tooltip-content="{{ctx.Locale.Tr "explore.go_to"}}">{{svg "octicon-hash"}}</button>
|
||||
{{template "shared/search/button"}}
|
||||
{{if .PageIsPulls}}
|
||||
{{template "shared/search/combo_fuzzy" dict "Value" $.Keyword "IsFuzzy" $.IsFuzzy "Placeholder" (ctx.Locale.Tr "search.pull_kind") "Tooltip" (ctx.Locale.Tr "explorer.go")}}
|
||||
{{else}}
|
||||
{{template "shared/search/combo_fuzzy" dict "Value" $.Keyword "IsFuzzy" $.IsFuzzy "Placeholder" (ctx.Locale.Tr "search.issue_kind") "Tooltip" (ctx.Locale.Tr "explorer.go")}}
|
||||
{{end}}
|
||||
</div>
|
||||
</form>
|
||||
<!-- Sort -->
|
||||
|
@ -63,14 +65,14 @@
|
|||
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
||||
</span>
|
||||
<div class="menu">
|
||||
<a class="{{if eq .SortType "recentupdate"}}active {{end}}item" href="?type={{$.ViewType}}&sort=recentupdate&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.recentupdate"}}</a>
|
||||
<a class="{{if eq .SortType "leastupdate"}}active {{end}}item" href="?type={{$.ViewType}}&sort=leastupdate&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.leastupdate"}}</a>
|
||||
<a class="{{if or (eq .SortType "latest") (not .SortType)}}active {{end}}item" href="?type={{$.ViewType}}&sort=latest&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.latest"}}</a>
|
||||
<a class="{{if eq .SortType "oldest"}}active {{end}}item" href="?type={{$.ViewType}}&sort=oldest&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.oldest"}}</a>
|
||||
<a class="{{if eq .SortType "mostcomment"}}active {{end}}item" href="?type={{$.ViewType}}&sort=mostcomment&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.mostcomment"}}</a>
|
||||
<a class="{{if eq .SortType "leastcomment"}}active {{end}}item" href="?type={{$.ViewType}}&sort=leastcomment&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.leastcomment"}}</a>
|
||||
<a class="{{if eq .SortType "nearduedate"}}active {{end}}item" href="?type={{$.ViewType}}&sort=nearduedate&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.nearduedate"}}</a>
|
||||
<a class="{{if eq .SortType "farduedate"}}active {{end}}item" href="?type={{$.ViewType}}&sort=farduedate&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.farduedate"}}</a>
|
||||
<a class="{{if eq .SortType "recentupdate"}}active {{end}}item" href="?type={{$.ViewType}}&sort=recentupdate&state={{$.State}}&q={{$.Keyword}}&fuzzy={{.IsFuzzy}}">{{ctx.Locale.Tr "repo.issues.filter_sort.recentupdate"}}</a>
|
||||
<a class="{{if eq .SortType "leastupdate"}}active {{end}}item" href="?type={{$.ViewType}}&sort=leastupdate&state={{$.State}}&q={{$.Keyword}}&fuzzy={{.IsFuzzy}}">{{ctx.Locale.Tr "repo.issues.filter_sort.leastupdate"}}</a>
|
||||
<a class="{{if or (eq .SortType "latest") (not .SortType)}}active {{end}}item" href="?type={{$.ViewType}}&sort=latest&state={{$.State}}&q={{$.Keyword}}&fuzzy={{.IsFuzzy}}">{{ctx.Locale.Tr "repo.issues.filter_sort.latest"}}</a>
|
||||
<a class="{{if eq .SortType "oldest"}}active {{end}}item" href="?type={{$.ViewType}}&sort=oldest&state={{$.State}}&q={{$.Keyword}}&fuzzy={{.IsFuzzy}}">{{ctx.Locale.Tr "repo.issues.filter_sort.oldest"}}</a>
|
||||
<a class="{{if eq .SortType "mostcomment"}}active {{end}}item" href="?type={{$.ViewType}}&sort=mostcomment&state={{$.State}}&q={{$.Keyword}}&fuzzy={{.IsFuzzy}}">{{ctx.Locale.Tr "repo.issues.filter_sort.mostcomment"}}</a>
|
||||
<a class="{{if eq .SortType "leastcomment"}}active {{end}}item" href="?type={{$.ViewType}}&sort=leastcomment&state={{$.State}}&q={{$.Keyword}}&fuzzy={{.IsFuzzy}}">{{ctx.Locale.Tr "repo.issues.filter_sort.leastcomment"}}</a>
|
||||
<a class="{{if eq .SortType "nearduedate"}}active {{end}}item" href="?type={{$.ViewType}}&sort=nearduedate&state={{$.State}}&q={{$.Keyword}}&fuzzy={{.IsFuzzy}}">{{ctx.Locale.Tr "repo.issues.filter_sort.nearduedate"}}</a>
|
||||
<a class="{{if eq .SortType "farduedate"}}active {{end}}item" href="?type={{$.ViewType}}&sort=farduedate&state={{$.State}}&q={{$.Keyword}}&fuzzy={{.IsFuzzy}}">{{ctx.Locale.Tr "repo.issues.filter_sort.farduedate"}}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// Copyright 2021 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package integration
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue