Merge branch 'feat/add-oidc-ssh-keys' of codeberg.org:Maks1mS/forgejo into feat/add-oidc-ssh-keys

This commit is contained in:
Maxim Slipenko 2024-12-27 11:18:27 +03:00
commit af88ddae8c
89 changed files with 4813 additions and 1391 deletions

View file

@ -14,6 +14,12 @@
# secrets.CASCADE_DESTINATION_TOKEN: <generated from code.forgejo.org/forgejo-ci> scope read:user, write:repository, write:issue # secrets.CASCADE_DESTINATION_TOKEN: <generated from code.forgejo.org/forgejo-ci> scope read:user, write:repository, write:issue
# vars.CASCADE_DESTINATION_DOER: forgejo-ci # vars.CASCADE_DESTINATION_DOER: forgejo-ci
# #
# vars.SKIP_END_TO_END: `true` or `false`
# It must be `false` (or absent) so https://code.forgejo.org/forgejo/end-to-end is run
# with the newly built release.
# It must be set to `true` when a release is missing, for instance because it was
# removed and failed to upload.
#
on: on:
push: push:
tags: 'v[0-9]+.[0-9]+.*' tags: 'v[0-9]+.[0-9]+.*'

View file

@ -49,7 +49,7 @@ GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v1 # renovate: datasour
DEADCODE_PACKAGE ?= golang.org/x/tools/cmd/deadcode@v0.28.0 # renovate: datasource=go DEADCODE_PACKAGE ?= golang.org/x/tools/cmd/deadcode@v0.28.0 # renovate: datasource=go
GOMOCK_PACKAGE ?= go.uber.org/mock/mockgen@v0.4.0 # renovate: datasource=go GOMOCK_PACKAGE ?= go.uber.org/mock/mockgen@v0.4.0 # renovate: datasource=go
GOPLS_PACKAGE ?= golang.org/x/tools/gopls@v0.17.0 # renovate: datasource=go GOPLS_PACKAGE ?= golang.org/x/tools/gopls@v0.17.0 # renovate: datasource=go
RENOVATE_NPM_PACKAGE ?= renovate@39.69.2 # renovate: datasource=docker packageName=code.forgejo.org/forgejo-contrib/renovate RENOVATE_NPM_PACKAGE ?= renovate@39.82.1 # renovate: datasource=docker packageName=code.forgejo.org/forgejo-contrib/renovate
# https://github.com/disposable-email-domains/disposable-email-domains/commits/main/ # https://github.com/disposable-email-domains/disposable-email-domains/commits/main/
DISPOSABLE_EMAILS_SHA ?= 0c27e671231d27cf66370034d7f6818037416989 # renovate: ... DISPOSABLE_EMAILS_SHA ?= 0c27e671231d27cf66370034d7f6818037416989 # renovate: ...

View file

@ -1042,7 +1042,7 @@
{ {
"name": "golang.org/x/time/rate", "name": "golang.org/x/time/rate",
"path": "golang.org/x/time/rate/LICENSE", "path": "golang.org/x/time/rate/LICENSE",
"licenseText": "Copyright (c) 2009 The Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" "licenseText": "Copyright 2009 The Go Authors.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n * Neither the name of Google LLC nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
}, },
{ {
"name": "google.golang.org/genproto/googleapis/rpc/status", "name": "google.golang.org/genproto/googleapis/rpc/status",

View file

@ -11,13 +11,4 @@ package main
import ( import (
// for embed // for embed
_ "github.com/shurcooL/vfsgen" _ "github.com/shurcooL/vfsgen"
// for cover merge
_ "golang.org/x/tools/cover"
// for vet
_ "code.gitea.io/gitea-vet"
// for swagger
_ "github.com/go-swagger/go-swagger/cmd/swagger"
) )

View file

@ -1,118 +0,0 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// Copyright (c) 2015, Wade Simmons
// SPDX-License-Identifier: MIT
// gocovmerge takes the results from multiple `go test -coverprofile` runs and
// merges them into one profile
//go:build ignore
package main
import (
"flag"
"fmt"
"io"
"log"
"os"
"sort"
"golang.org/x/tools/cover"
)
func mergeProfiles(p, merge *cover.Profile) {
if p.Mode != merge.Mode {
log.Fatalf("cannot merge profiles with different modes")
}
// Since the blocks are sorted, we can keep track of where the last block
// was inserted and only look at the blocks after that as targets for merge
startIndex := 0
for _, b := range merge.Blocks {
startIndex = mergeProfileBlock(p, b, startIndex)
}
}
func mergeProfileBlock(p *cover.Profile, pb cover.ProfileBlock, startIndex int) int {
sortFunc := func(i int) bool {
pi := p.Blocks[i+startIndex]
return pi.StartLine >= pb.StartLine && (pi.StartLine != pb.StartLine || pi.StartCol >= pb.StartCol)
}
i := 0
if sortFunc(i) != true {
i = sort.Search(len(p.Blocks)-startIndex, sortFunc)
}
i += startIndex
if i < len(p.Blocks) && p.Blocks[i].StartLine == pb.StartLine && p.Blocks[i].StartCol == pb.StartCol {
if p.Blocks[i].EndLine != pb.EndLine || p.Blocks[i].EndCol != pb.EndCol {
log.Fatalf("OVERLAP MERGE: %v %v %v", p.FileName, p.Blocks[i], pb)
}
switch p.Mode {
case "set":
p.Blocks[i].Count |= pb.Count
case "count", "atomic":
p.Blocks[i].Count += pb.Count
default:
log.Fatalf("unsupported covermode: '%s'", p.Mode)
}
} else {
if i > 0 {
pa := p.Blocks[i-1]
if pa.EndLine >= pb.EndLine && (pa.EndLine != pb.EndLine || pa.EndCol > pb.EndCol) {
log.Fatalf("OVERLAP BEFORE: %v %v %v", p.FileName, pa, pb)
}
}
if i < len(p.Blocks)-1 {
pa := p.Blocks[i+1]
if pa.StartLine <= pb.StartLine && (pa.StartLine != pb.StartLine || pa.StartCol < pb.StartCol) {
log.Fatalf("OVERLAP AFTER: %v %v %v", p.FileName, pa, pb)
}
}
p.Blocks = append(p.Blocks, cover.ProfileBlock{})
copy(p.Blocks[i+1:], p.Blocks[i:])
p.Blocks[i] = pb
}
return i + 1
}
func addProfile(profiles []*cover.Profile, p *cover.Profile) []*cover.Profile {
i := sort.Search(len(profiles), func(i int) bool { return profiles[i].FileName >= p.FileName })
if i < len(profiles) && profiles[i].FileName == p.FileName {
mergeProfiles(profiles[i], p)
} else {
profiles = append(profiles, nil)
copy(profiles[i+1:], profiles[i:])
profiles[i] = p
}
return profiles
}
func dumpProfiles(profiles []*cover.Profile, out io.Writer) {
if len(profiles) == 0 {
return
}
fmt.Fprintf(out, "mode: %s\n", profiles[0].Mode)
for _, p := range profiles {
for _, b := range p.Blocks {
fmt.Fprintf(out, "%s:%d.%d,%d.%d %d %d\n", p.FileName, b.StartLine, b.StartCol, b.EndLine, b.EndCol, b.NumStmt, b.Count)
}
}
}
func main() {
flag.Parse()
var merged []*cover.Profile
for _, file := range flag.Args() {
profiles, err := cover.ParseProfiles(file)
if err != nil {
log.Fatalf("failed to parse profile '%s': %v", file, err)
}
for _, p := range profiles {
merged = addProfile(merged, p)
}
}
dumpProfiles(merged, os.Stdout)
}

View file

@ -59,9 +59,9 @@ func initRemoveTags() {
oldnew := []string{} oldnew := []string{}
for _, el := range []string{ for _, el := range []string{
"email@example.com", "correu@example.com", "epasts@domens.lv", "email@exemplo.com", "eposta@ornek.com", "email@példa.hu", "email@esempio.it", "email@example.com", "correu@example.com", "epasts@domens.lv", "email@exemplo.com", "eposta@ornek.com", "email@példa.hu", "email@esempio.it",
"user", "utente", "lietotājs", "gebruiker", "usuário", "Benutzer", "Bruker", "user", "utente", "lietotājs", "gebruiker", "usuário", "Benutzer", "Bruker", "bruger",
"server", "servidor", "kiszolgáló", "serveris", "server", "servidor", "kiszolgáló", "serveris",
"label", "etichetta", "etiķete", "rótulo", "Label", "utilizador", "label", "etichetta", "etiķete", "rótulo", "Label", "utilizador", "etiket", "iezīme",
} { } {
oldnew = append(oldnew, "<"+el+">", "REPLACED-TAG") oldnew = append(oldnew, "<"+el+">", "REPLACED-TAG")
} }

97
go.mod
View file

@ -13,7 +13,6 @@ require (
code.forgejo.org/go-chi/captcha v1.0.1 code.forgejo.org/go-chi/captcha v1.0.1
code.forgejo.org/go-chi/session v1.0.1 code.forgejo.org/go-chi/session v1.0.1
code.gitea.io/actions-proto-go v0.4.0 code.gitea.io/actions-proto-go v0.4.0
code.gitea.io/gitea-vet v0.2.3
code.gitea.io/sdk/gitea v0.17.1 code.gitea.io/sdk/gitea v0.17.1
codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570 codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570
connectrpc.com/connect v1.17.0 connectrpc.com/connect v1.17.0
@ -49,8 +48,7 @@ require (
github.com/go-ldap/ldap/v3 v3.4.6 github.com/go-ldap/ldap/v3 v3.4.6
github.com/go-openapi/spec v0.20.14 github.com/go-openapi/spec v0.20.14
github.com/go-sql-driver/mysql v1.8.1 github.com/go-sql-driver/mysql v1.8.1
github.com/go-swagger/go-swagger v0.30.5 github.com/go-testfixtures/testfixtures/v3 v3.14.0
github.com/go-testfixtures/testfixtures/v3 v3.12.0
github.com/go-webauthn/webauthn v0.11.2 github.com/go-webauthn/webauthn v0.11.2
github.com/gobwas/glob v0.2.3 github.com/gobwas/glob v0.2.3
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f
@ -110,9 +108,8 @@ require (
golang.org/x/sync v0.10.0 golang.org/x/sync v0.10.0
golang.org/x/sys v0.28.0 golang.org/x/sys v0.28.0
golang.org/x/text v0.21.0 golang.org/x/text v0.21.0
golang.org/x/tools v0.28.0 google.golang.org/grpc v1.69.2
google.golang.org/grpc v1.68.0 google.golang.org/protobuf v1.36.1
google.golang.org/protobuf v1.36.0
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
gopkg.in/ini.v1 v1.67.0 gopkg.in/ini.v1 v1.67.0
gopkg.in/yaml.v3 v3.0.1 gopkg.in/yaml.v3 v3.0.1
@ -122,22 +119,26 @@ require (
) )
require ( require (
cloud.google.com/go/compute/metadata v0.5.0 // indirect cel.dev/expr v0.16.2 // indirect
cloud.google.com/go v0.116.0 // indirect
cloud.google.com/go/auth v0.9.9 // indirect
cloud.google.com/go/auth/oauth2adapt v0.2.4 // indirect
cloud.google.com/go/compute/metadata v0.5.2 // indirect
cloud.google.com/go/iam v1.2.1 // indirect
cloud.google.com/go/longrunning v0.6.1 // indirect
cloud.google.com/go/monitoring v1.21.1 // indirect
cloud.google.com/go/spanner v1.73.0 // indirect
dario.cat/mergo v1.0.0 // indirect dario.cat/mergo v1.0.0 // indirect
filippo.io/edwards25519 v1.1.0 // indirect filippo.io/edwards25519 v1.1.0 // indirect
git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078 // indirect git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078 // indirect
github.com/ClickHouse/ch-go v0.61.5 // indirect
github.com/ClickHouse/clickhouse-go/v2 v2.26.0 // indirect
github.com/DataDog/zstd v1.5.5 // indirect github.com/DataDog/zstd v1.5.5 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.5.0 // indirect
github.com/Masterminds/semver/v3 v3.2.1 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.24.2 // indirect
github.com/Masterminds/sprig/v3 v3.2.3 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/RoaringBitmap/roaring v1.9.3 // indirect github.com/RoaringBitmap/roaring v1.9.3 // indirect
github.com/andybalholm/brotli v1.1.0 // indirect github.com/andybalholm/brotli v1.1.1 // indirect
github.com/andybalholm/cascadia v1.3.2 // indirect github.com/andybalholm/cascadia v1.3.2 // indirect
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/aymerick/douceur v0.2.0 // indirect github.com/aymerick/douceur v0.2.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect
github.com/bits-and-blooms/bitset v1.13.0 // indirect github.com/bits-and-blooms/bitset v1.13.0 // indirect
@ -161,9 +162,11 @@ require (
github.com/boombuler/barcode v1.0.1 // indirect github.com/boombuler/barcode v1.0.1 // indirect
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // indirect github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // indirect
github.com/caddyserver/zerossl v0.1.3 // indirect github.com/caddyserver/zerossl v0.1.3 // indirect
github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect
github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a // indirect github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/cloudflare/circl v1.3.8 // indirect github.com/cloudflare/circl v1.3.8 // indirect
github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
github.com/cyphar/filepath-securejoin v0.2.4 // indirect github.com/cyphar/filepath-securejoin v0.2.4 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
@ -172,27 +175,22 @@ require (
github.com/dlclark/regexp2 v1.11.0 // indirect github.com/dlclark/regexp2 v1.11.0 // indirect
github.com/emersion/go-sasl v0.0.0-20231106173351-e73c9f7bad43 // indirect github.com/emersion/go-sasl v0.0.0-20231106173351-e73c9f7bad43 // indirect
github.com/emirpasic/gods v1.18.1 // indirect github.com/emirpasic/gods v1.18.1 // indirect
github.com/envoyproxy/go-control-plane v0.13.1 // indirect
github.com/envoyproxy/protoc-gen-validate v1.1.0 // indirect
github.com/fatih/color v1.16.0 // indirect github.com/fatih/color v1.16.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/go-ap/errors v0.0.0-20231003111023-183eef4b31b7 // indirect github.com/go-ap/errors v0.0.0-20231003111023-183eef4b31b7 // indirect
github.com/go-asn1-ber/asn1-ber v1.5.5 // indirect github.com/go-asn1-ber/asn1-ber v1.5.5 // indirect
github.com/go-enry/go-oniguruma v1.2.1 // indirect github.com/go-enry/go-oniguruma v1.2.1 // indirect
github.com/go-faster/city v1.0.1 // indirect
github.com/go-faster/errors v0.7.1 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-git/go-billy/v5 v5.5.0 // indirect github.com/go-git/go-billy/v5 v5.5.0 // indirect
github.com/go-ini/ini v1.67.0 // indirect github.com/go-ini/ini v1.67.0 // indirect
github.com/go-openapi/analysis v0.22.2 // indirect github.com/go-logr/logr v1.4.2 // indirect
github.com/go-openapi/errors v0.21.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/inflect v0.19.0 // indirect
github.com/go-openapi/jsonpointer v0.20.2 // indirect github.com/go-openapi/jsonpointer v0.20.2 // indirect
github.com/go-openapi/jsonreference v0.20.4 // indirect github.com/go-openapi/jsonreference v0.20.4 // indirect
github.com/go-openapi/loads v0.21.5 // indirect
github.com/go-openapi/runtime v0.26.2 // indirect
github.com/go-openapi/strfmt v0.22.0 // indirect
github.com/go-openapi/swag v0.22.7 // indirect github.com/go-openapi/swag v0.22.7 // indirect
github.com/go-openapi/validate v0.22.6 // indirect
github.com/go-webauthn/x v0.1.14 // indirect github.com/go-webauthn/x v0.1.14 // indirect
github.com/goccy/go-json v0.10.3 // indirect github.com/goccy/go-json v0.10.3 // indirect
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
@ -204,23 +202,20 @@ require (
github.com/google/go-cmp v0.6.0 // indirect github.com/google/go-cmp v0.6.0 // indirect
github.com/google/go-querystring v1.1.0 // indirect github.com/google/go-querystring v1.1.0 // indirect
github.com/google/go-tpm v0.9.1 // indirect github.com/google/go-tpm v0.9.1 // indirect
github.com/google/s2a-go v0.1.8 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect
github.com/googleapis/gax-go/v2 v2.13.0 // indirect
github.com/googleapis/go-sql-spanner v1.7.4 // indirect
github.com/gorilla/css v1.0.1 // indirect github.com/gorilla/css v1.0.1 // indirect
github.com/gorilla/handlers v1.5.2 // indirect
github.com/gorilla/mux v1.8.1 // indirect github.com/gorilla/mux v1.8.1 // indirect
github.com/gorilla/securecookie v1.1.2 // indirect github.com/gorilla/securecookie v1.1.2 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/imdario/mergo v0.3.16 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/jessevdk/go-flags v1.5.0 // indirect
github.com/josharian/intern v1.0.0 // indirect github.com/josharian/intern v1.0.0 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/klauspost/pgzip v1.2.6 // indirect github.com/klauspost/pgzip v1.2.6 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/libdns/libdns v0.2.2 // indirect github.com/libdns/libdns v0.2.2 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mailru/easyjson v0.7.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect
github.com/markbates/going v1.0.3 // indirect github.com/markbates/going v1.0.3 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-colorable v0.1.13 // indirect
@ -228,66 +223,58 @@ require (
github.com/mholt/acmez/v2 v2.0.3 // indirect github.com/mholt/acmez/v2 v2.0.3 // indirect
github.com/miekg/dns v1.1.62 // indirect github.com/miekg/dns v1.1.62 // indirect
github.com/minio/md5-simd v1.1.2 // indirect github.com/minio/md5-simd v1.1.2 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/mrjones/oauth v0.0.0-20190623134757-126b35219450 // indirect github.com/mrjones/oauth v0.0.0-20190623134757-126b35219450 // indirect
github.com/mschoch/smat v0.2.0 // indirect github.com/mschoch/smat v0.2.0 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/nwaples/rardecode v1.1.3 // indirect github.com/nwaples/rardecode v1.1.3 // indirect
github.com/oklog/ulid v1.3.1 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/onsi/ginkgo v1.16.5 // indirect github.com/onsi/ginkgo v1.16.5 // indirect
github.com/paulmach/orb v0.11.1 // indirect
github.com/pelletier/go-toml/v2 v2.1.1 // indirect
github.com/pierrec/lz4/v4 v4.1.21 // indirect github.com/pierrec/lz4/v4 v4.1.21 // indirect
github.com/pjbgf/sha1cd v0.3.0 // indirect github.com/pjbgf/sha1cd v0.3.0 // indirect
github.com/pkg/errors v0.9.1 // indirect github.com/pkg/errors v0.9.1 // indirect
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/common v0.55.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect github.com/prometheus/procfs v0.15.1 // indirect
github.com/rhysd/actionlint v1.6.27 // indirect github.com/rhysd/actionlint v1.6.27 // indirect
github.com/rivo/uniseg v0.4.7 // indirect github.com/rivo/uniseg v0.4.7 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/rs/xid v1.6.0 // indirect github.com/rs/xid v1.6.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sagikazarmark/locafero v0.4.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/segmentio/asm v1.2.0 // indirect
github.com/shopspring/decimal v1.4.0 // indirect
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c // indirect github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c // indirect
github.com/sirupsen/logrus v1.9.3 // indirect github.com/sirupsen/logrus v1.9.3 // indirect
github.com/skeema/knownhosts v1.2.1 // indirect github.com/skeema/knownhosts v1.2.1 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.11.0 // indirect
github.com/spf13/cast v1.6.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.18.2 // indirect
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/toqueteos/webbrowser v1.2.0 // indirect
github.com/x448/float16 v0.8.4 // indirect github.com/x448/float16 v0.8.4 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
github.com/zeebo/blake3 v0.2.4 // indirect github.com/zeebo/blake3 v0.2.4 // indirect
go.etcd.io/bbolt v1.3.9 // indirect go.etcd.io/bbolt v1.3.9 // indirect
go.mongodb.org/mongo-driver v1.13.1 // indirect go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/otel v1.26.0 // indirect go.opentelemetry.io/contrib/detectors/gcp v1.31.0 // indirect
go.opentelemetry.io/otel/trace v1.26.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect
go.opentelemetry.io/otel v1.31.0 // indirect
go.opentelemetry.io/otel/metric v1.31.0 // indirect
go.opentelemetry.io/otel/sdk v1.31.0 // indirect
go.opentelemetry.io/otel/sdk/metric v1.31.0 // indirect
go.opentelemetry.io/otel/trace v1.31.0 // indirect
go.uber.org/atomic v1.11.0 // indirect go.uber.org/atomic v1.11.0 // indirect
go.uber.org/multierr v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect go.uber.org/zap v1.27.0 // indirect
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a // indirect
golang.org/x/mod v0.22.0 // indirect golang.org/x/mod v0.22.0 // indirect
golang.org/x/time v0.5.0 // indirect golang.org/x/time v0.7.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect golang.org/x/tools v0.28.0 // indirect
google.golang.org/api v0.203.0 // indirect
google.golang.org/genproto v0.0.0-20241015192408-796eee8c2d53 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
) )
replace github.com/hashicorp/go-version => github.com/6543/go-version v1.3.1 replace github.com/hashicorp/go-version => github.com/6543/go-version v1.3.1

1588
go.sum

File diff suppressed because it is too large Load diff

View file

@ -153,28 +153,34 @@ func UpdateRunJob(ctx context.Context, job *ActionRunJob, cond builder.Cond, col
} }
func AggregateJobStatus(jobs []*ActionRunJob) Status { func AggregateJobStatus(jobs []*ActionRunJob) Status {
allDone := true allSuccessOrSkipped := len(jobs) != 0
allWaiting := true allSkipped := len(jobs) != 0
hasFailure := false var hasFailure, hasCancelled, hasWaiting, hasRunning, hasBlocked bool
for _, job := range jobs { for _, job := range jobs {
if !job.Status.IsDone() { allSuccessOrSkipped = allSuccessOrSkipped && (job.Status == StatusSuccess || job.Status == StatusSkipped)
allDone = false allSkipped = allSkipped && job.Status == StatusSkipped
} hasFailure = hasFailure || job.Status == StatusFailure
if job.Status != StatusWaiting && !job.Status.IsDone() { hasCancelled = hasCancelled || job.Status == StatusCancelled
allWaiting = false hasWaiting = hasWaiting || job.Status == StatusWaiting
} hasRunning = hasRunning || job.Status == StatusRunning
if job.Status == StatusFailure || job.Status == StatusCancelled { hasBlocked = hasBlocked || job.Status == StatusBlocked
hasFailure = true
}
} }
if allDone { switch {
if hasFailure { case allSkipped:
return StatusFailure return StatusSkipped
} case allSuccessOrSkipped:
return StatusSuccess return StatusSuccess
} case hasCancelled:
if allWaiting { return StatusCancelled
case hasFailure:
return StatusFailure
case hasRunning:
return StatusRunning
case hasWaiting:
return StatusWaiting return StatusWaiting
case hasBlocked:
return StatusBlocked
default:
return StatusUnknown // it shouldn't happen
} }
return StatusRunning
} }

View file

@ -0,0 +1,85 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package actions
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestAggregateJobStatus(t *testing.T) {
testStatuses := func(expected Status, statuses []Status) {
t.Helper()
var jobs []*ActionRunJob
for _, v := range statuses {
jobs = append(jobs, &ActionRunJob{Status: v})
}
actual := AggregateJobStatus(jobs)
if !assert.Equal(t, expected, actual) {
var statusStrings []string
for _, s := range statuses {
statusStrings = append(statusStrings, s.String())
}
t.Errorf("AggregateJobStatus(%v) = %v, want %v", statusStrings, statusNames[actual], statusNames[expected])
}
}
cases := []struct {
statuses []Status
expected Status
}{
// unknown cases, maybe it shouldn't happen in real world
{[]Status{}, StatusUnknown},
{[]Status{StatusUnknown, StatusSuccess}, StatusUnknown},
{[]Status{StatusUnknown, StatusSkipped}, StatusUnknown},
{[]Status{StatusUnknown, StatusFailure}, StatusFailure},
{[]Status{StatusUnknown, StatusCancelled}, StatusCancelled},
{[]Status{StatusUnknown, StatusWaiting}, StatusWaiting},
{[]Status{StatusUnknown, StatusRunning}, StatusRunning},
{[]Status{StatusUnknown, StatusBlocked}, StatusBlocked},
// success with other status
{[]Status{StatusSuccess}, StatusSuccess},
{[]Status{StatusSuccess, StatusSkipped}, StatusSuccess}, // skipped doesn't affect success
{[]Status{StatusSuccess, StatusFailure}, StatusFailure},
{[]Status{StatusSuccess, StatusCancelled}, StatusCancelled},
{[]Status{StatusSuccess, StatusWaiting}, StatusWaiting},
{[]Status{StatusSuccess, StatusRunning}, StatusRunning},
{[]Status{StatusSuccess, StatusBlocked}, StatusBlocked},
// any cancelled, then cancelled
{[]Status{StatusCancelled}, StatusCancelled},
{[]Status{StatusCancelled, StatusSuccess}, StatusCancelled},
{[]Status{StatusCancelled, StatusSkipped}, StatusCancelled},
{[]Status{StatusCancelled, StatusFailure}, StatusCancelled},
{[]Status{StatusCancelled, StatusWaiting}, StatusCancelled},
{[]Status{StatusCancelled, StatusRunning}, StatusCancelled},
{[]Status{StatusCancelled, StatusBlocked}, StatusCancelled},
// failure with other status, fail fast
// Should "running" win? Maybe no: old code does make "running" win, but GitHub does fail fast.
{[]Status{StatusFailure}, StatusFailure},
{[]Status{StatusFailure, StatusSuccess}, StatusFailure},
{[]Status{StatusFailure, StatusSkipped}, StatusFailure},
{[]Status{StatusFailure, StatusCancelled}, StatusCancelled},
{[]Status{StatusFailure, StatusWaiting}, StatusFailure},
{[]Status{StatusFailure, StatusRunning}, StatusFailure},
{[]Status{StatusFailure, StatusBlocked}, StatusFailure},
// skipped with other status
// TODO: need to clarify whether a PR with "skipped" job status is considered as "mergeable" or not.
{[]Status{StatusSkipped}, StatusSkipped},
{[]Status{StatusSkipped, StatusSuccess}, StatusSuccess},
{[]Status{StatusSkipped, StatusFailure}, StatusFailure},
{[]Status{StatusSkipped, StatusCancelled}, StatusCancelled},
{[]Status{StatusSkipped, StatusWaiting}, StatusWaiting},
{[]Status{StatusSkipped, StatusRunning}, StatusRunning},
{[]Status{StatusSkipped, StatusBlocked}, StatusBlocked},
}
for _, c := range cases {
testStatuses(c.expected, c.statuses)
}
}

View file

@ -432,6 +432,25 @@
updated: 1683636626 updated: 1683636626
need_approval: 0 need_approval: 0
approved_by: 0 approved_by: 0
-
id: 794
title: "job output"
repo_id: 4
owner_id: 1
workflow_id: "test.yaml"
index: 190
trigger_user_id: 1
ref: "refs/heads/test"
commit_sha: "c2d72f548424103f01ee1dc02889c1e2bff816b0"
event: "push"
is_fork_pull_request: 0
status: 1
started: 1683636528
stopped: 1683636626
created: 1683636108
updated: 1683636626
need_approval: 0
approved_by: 0
- -
id: 891 id: 891
title: "update actions" title: "update actions"

View file

@ -45,3 +45,15 @@
is_deleted: false is_deleted: false
deleted_by_id: 0 deleted_by_id: 0
deleted_unix: 0 deleted_unix: 0
-
id: 15
repo_id: 4
name: 'master'
commit_id: 'c7cd3cd144e6d23c9d6f3d07e52b2c1a956e0338'
commit_message: 'add Readme'
commit_time: 1588147171
pusher_id: 13
is_deleted: false
deleted_by_id: 0
deleted_unix: 0

View file

@ -20,9 +20,34 @@ import (
func MigrateTwoFactorToKeying(x *xorm.Engine) error { func MigrateTwoFactorToKeying(x *xorm.Engine) error {
var err error var err error
// When upgrading from Forgejo v9 to v10, this migration will already be
// called from models/migrations/migrations.go migration 304 and must not
// be run twice.
var version int
_, err = x.Table("version").Where("`id` = 1").Select("version").Get(&version)
if err != nil {
// the version table does not exist when a test environment only applies Forgejo migrations
} else if version > 304 {
return nil
}
switch x.Dialect().URI().DBType { switch x.Dialect().URI().DBType {
case schemas.MYSQL: case schemas.MYSQL:
_, err = x.Exec("ALTER TABLE `two_factor` MODIFY `secret` BLOB") _, err = x.Exec("ALTER TABLE `two_factor` MODIFY `secret` BLOB")
case schemas.SQLITE:
_, err = x.Exec("ALTER TABLE `two_factor` RENAME COLUMN `secret` TO `secret_backup`")
if err != nil {
return err
}
_, err = x.Exec("ALTER TABLE `two_factor` ADD COLUMN `secret` BLOB")
if err != nil {
return err
}
_, err = x.Exec("UPDATE `two_factor` SET `secret` = `secret_backup`")
if err != nil {
return err
}
_, err = x.Exec("ALTER TABLE `two_factor` DROP COLUMN `secret_backup`")
case schemas.POSTGRES: case schemas.POSTGRES:
_, err = x.Exec("ALTER TABLE `two_factor` ALTER COLUMN `secret` SET DATA TYPE bytea USING secret::text::bytea") _, err = x.Exec("ALTER TABLE `two_factor` ALTER COLUMN `secret` SET DATA TYPE bytea USING secret::text::bytea")
} }

View file

@ -362,6 +362,10 @@ func prepareMigrationTasks() []*migration {
newMigration(300, "Add force-push branch protection support", v1_23.AddForcePushBranchProtection), newMigration(300, "Add force-push branch protection support", v1_23.AddForcePushBranchProtection),
newMigration(301, "Add skip_secondary_authorization option to oauth2 application table", v1_23.AddSkipSecondaryAuthColumnToOAuth2ApplicationTable), newMigration(301, "Add skip_secondary_authorization option to oauth2 application table", v1_23.AddSkipSecondaryAuthColumnToOAuth2ApplicationTable),
newMigration(302, "Add index to action_task stopped log_expired", v1_23.AddIndexToActionTaskStoppedLogExpired), newMigration(302, "Add index to action_task stopped log_expired", v1_23.AddIndexToActionTaskStoppedLogExpired),
// Migration to Forgejo v10
newMigration(303, "Gitea last drop", v1_23.GiteaLastDrop),
newMigration(304, "Migrate `secret` column to store keying material", forgejo_migrations.MigrateTwoFactorToKeying),
} }
return preparedMigrations return preparedMigrations
} }

View file

@ -0,0 +1,33 @@
// Copyright 2024 The Forgejo Authors.
// SPDX-License-Identifier: MIT
package v1_23 //nolint
import (
"code.gitea.io/gitea/models/migrations/base"
"xorm.io/xorm"
)
func GiteaLastDrop(x *xorm.Engine) error {
sess := x.NewSession()
defer sess.Close()
if err := base.DropTableColumns(sess, "badge", "slug"); err != nil {
return err
}
if err := base.DropTableColumns(sess, "oauth2_application", "skip_secondary_authorization"); err != nil {
return err
}
if err := base.DropTableColumns(sess, "repository", "default_wiki_branch"); err != nil {
return err
}
// the migration v297.go that adds everyone_access_mode exists in Gitea >= v1.22 and the column must be dropped
// but it does not exist in Forgejo and a failure to drop the column can be ignored
base.DropTableColumns(sess, "repo_unit", "everyone_access_mode")
if err := base.DropTableColumns(sess, "protected_branch", "can_force_push", "enable_force_push_allowlist", "force_push_allowlist_user_i_ds", "force_push_allowlist_team_i_ds", "force_push_allowlist_deploy_keys"); err != nil {
return err
}
return sess.Commit()
}

View file

@ -29,6 +29,15 @@ const (
MergeStyleRebaseUpdate MergeStyle = "rebase-update-only" MergeStyleRebaseUpdate MergeStyle = "rebase-update-only"
) )
type UpdateStyle string
const (
// UpdateStyleMerge create merge commit to update
UpdateStyleMerge UpdateStyle = "merge"
// UpdateStyleRebase rebase to update
UpdateStyleRebase UpdateStyle = "rebase"
)
// UpdateDefaultBranch updates the default branch // UpdateDefaultBranch updates the default branch
func UpdateDefaultBranch(ctx context.Context, repo *Repository) error { func UpdateDefaultBranch(ctx context.Context, repo *Repository) error {
_, err := db.GetEngine(ctx).ID(repo.ID).Cols("default_branch").Update(repo) _, err := db.GetEngine(ctx).ID(repo.ID).Cols("default_branch").Update(repo)

View file

@ -159,6 +159,7 @@ type PullRequestsConfig struct {
AllowRebaseUpdate bool AllowRebaseUpdate bool
DefaultDeleteBranchAfterMerge bool DefaultDeleteBranchAfterMerge bool
DefaultMergeStyle MergeStyle DefaultMergeStyle MergeStyle
DefaultUpdateStyle UpdateStyle
DefaultAllowMaintainerEdit bool DefaultAllowMaintainerEdit bool
} }
@ -197,6 +198,25 @@ func (cfg *PullRequestsConfig) GetDefaultMergeStyle() MergeStyle {
return MergeStyleMerge return MergeStyleMerge
} }
// IsUpdateStyleAllowed returns if update style is allowed
func (cfg *PullRequestsConfig) IsUpdateStyleAllowed(updateStyle UpdateStyle) bool {
return updateStyle == UpdateStyleMerge ||
updateStyle == UpdateStyleRebase && cfg.AllowRebaseUpdate
}
// GetDefaultUpdateStyle returns the default update style for this pull request
func (cfg *PullRequestsConfig) GetDefaultUpdateStyle() UpdateStyle {
if len(cfg.DefaultUpdateStyle) != 0 {
return cfg.DefaultUpdateStyle
}
if setting.Repository.PullRequest.DefaultUpdateStyle != "" {
return UpdateStyle(setting.Repository.PullRequest.DefaultUpdateStyle)
}
return UpdateStyleMerge
}
type ActionsConfig struct { type ActionsConfig struct {
DisabledWorkflows []string DisabledWorkflows []string
} }

View file

@ -7,6 +7,8 @@ import (
"testing" "testing"
"code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/test"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -37,3 +39,50 @@ func TestRepoUnitAccessMode(t *testing.T) {
assert.Equal(t, perm.AccessModeWrite, UnitAccessModeWrite.ToAccessMode(perm.AccessModeAdmin)) assert.Equal(t, perm.AccessModeWrite, UnitAccessModeWrite.ToAccessMode(perm.AccessModeAdmin))
assert.Equal(t, perm.AccessModeRead, UnitAccessModeUnset.ToAccessMode(perm.AccessModeRead)) assert.Equal(t, perm.AccessModeRead, UnitAccessModeUnset.ToAccessMode(perm.AccessModeRead))
} }
func TestRepoPRIsUpdateStyleAllowed(t *testing.T) {
var cfg PullRequestsConfig
cfg = PullRequestsConfig{
AllowRebaseUpdate: true,
}
assert.True(t, cfg.IsUpdateStyleAllowed(UpdateStyleMerge))
assert.True(t, cfg.IsUpdateStyleAllowed(UpdateStyleRebase))
cfg = PullRequestsConfig{
AllowRebaseUpdate: false,
}
assert.True(t, cfg.IsUpdateStyleAllowed(UpdateStyleMerge))
assert.False(t, cfg.IsUpdateStyleAllowed(UpdateStyleRebase))
}
func TestRepoPRGetDefaultUpdateStyle(t *testing.T) {
defer test.MockVariableValue(&setting.Repository.PullRequest.DefaultUpdateStyle, "merge")()
var cfg PullRequestsConfig
cfg = PullRequestsConfig{
DefaultUpdateStyle: "",
}
assert.Equal(t, UpdateStyleMerge, cfg.GetDefaultUpdateStyle())
cfg = PullRequestsConfig{
DefaultUpdateStyle: "rebase",
}
assert.Equal(t, UpdateStyleRebase, cfg.GetDefaultUpdateStyle())
cfg = PullRequestsConfig{
DefaultUpdateStyle: "merge",
}
assert.Equal(t, UpdateStyleMerge, cfg.GetDefaultUpdateStyle())
setting.Repository.PullRequest.DefaultUpdateStyle = "rebase"
cfg = PullRequestsConfig{
DefaultUpdateStyle: "",
}
assert.Equal(t, UpdateStyleRebase, cfg.GetDefaultUpdateStyle())
cfg = PullRequestsConfig{
DefaultUpdateStyle: "rebase",
}
assert.Equal(t, UpdateStyleRebase, cfg.GetDefaultUpdateStyle())
cfg = PullRequestsConfig{
DefaultUpdateStyle: "merge",
}
assert.Equal(t, UpdateStyleMerge, cfg.GetDefaultUpdateStyle())
}

View file

@ -18,10 +18,10 @@ import (
) )
type Setting struct { type Setting struct {
ID int64 `xorm:"pk autoincr"` ID int64 `xorm:"pk autoincr"`
SettingKey string `xorm:"varchar(255) unique"` // key should be lowercase SettingKey string `xorm:"varchar(255) unique"` // key should be lowercase
SettingValue string `xorm:"text"` SettingValue string `xorm:"text"`
Version int `xorm:"version"` Version int
Created timeutil.TimeStamp `xorm:"created"` Created timeutil.TimeStamp `xorm:"created"`
Updated timeutil.TimeStamp `xorm:"updated"` Updated timeutil.TimeStamp `xorm:"updated"`
} }

View file

@ -36,13 +36,15 @@ const (
RegExpGrepMode RegExpGrepMode
) )
var GrepSearchOptions = [3]string{"exact", "union", "regexp"}
type GrepOptions struct { type GrepOptions struct {
RefName string RefName string
MaxResultLimit int MaxResultLimit int
MatchesPerFile int // >= git 2.38 MatchesPerFile int // >= git 2.38
ContextLineNumber int ContextLineNumber int
Mode grepMode Mode grepMode
PathSpec []setting.Glob Filename string
} }
func (opts *GrepOptions) ensureDefaults() { func (opts *GrepOptions) ensureDefaults() {
@ -112,12 +114,38 @@ func GrepSearch(ctx context.Context, repo *Repository, search string, opts GrepO
} }
// pathspec // pathspec
files := make([]string, 0, includeLen := len(setting.Indexer.IncludePatterns)
len(setting.Indexer.IncludePatterns)+ if len(opts.Filename) > 0 {
len(setting.Indexer.ExcludePatterns)+ includeLen = 1
len(opts.PathSpec)) }
for _, expr := range append(setting.Indexer.IncludePatterns, opts.PathSpec...) { files := make([]string, 0, len(setting.Indexer.ExcludePatterns)+includeLen)
files = append(files, ":"+expr.Pattern()) if len(opts.Filename) > 0 && len(setting.Indexer.IncludePatterns) > 0 {
// if the both a global include pattern and the per search path is defined
// we only include results where the path matches the globally set pattern
// (eg, global pattern = "src/**" and path = "node_modules/")
// FIXME: this is a bit too restrictive, and fails to consider cases where the
// gloabally set include pattern refers to a file than a directory
// (eg, global pattern = "**.go" and path = "modules/git")
exprMatched := false
for _, expr := range setting.Indexer.IncludePatterns {
if expr.Match(opts.Filename) {
files = append(files, ":(literal)"+opts.Filename)
exprMatched = true
break
}
}
if !exprMatched {
log.Warn("git-grep: filepath %s does not match any include pattern", opts.Filename)
}
} else if len(opts.Filename) > 0 {
// if the path is only set we just include results that matches it
files = append(files, ":(literal)"+opts.Filename)
} else {
// otherwise if global include patterns are set include results that strictly match them
for _, expr := range setting.Indexer.IncludePatterns {
files = append(files, ":"+expr.Pattern())
}
} }
for _, expr := range setting.Indexer.ExcludePatterns { for _, expr := range setting.Indexer.ExcludePatterns {
files = append(files, ":^"+expr.Pattern()) files = append(files, ":^"+expr.Pattern())

View file

@ -89,6 +89,20 @@ func TestGrepSearch(t *testing.T) {
}, },
}, res) }, res)
res, err = GrepSearch(context.Background(), repo, "world", GrepOptions{
MatchesPerFile: 1,
Filename: "java-hello/",
})
require.NoError(t, err)
assert.Equal(t, []*GrepResult{
{
Filename: "java-hello/main.java",
LineNumbers: []int{1},
LineCodes: []string{"public class HelloWorld"},
HighlightedRanges: [][3]int{{0, 18, 23}},
},
}, res)
res, err = GrepSearch(context.Background(), repo, "no-such-content", GrepOptions{}) res, err = GrepSearch(context.Background(), repo, "no-such-content", GrepOptions{})
require.NoError(t, err) require.NoError(t, err)
assert.Empty(t, res) assert.Empty(t, res)

View file

@ -230,7 +230,7 @@ func (repo *Repository) CommitsByFileAndRange(opts CommitsByFileAndRangeOptions)
go func() { go func() {
stderr := strings.Builder{} stderr := strings.Builder{}
gitCmd := NewCommand(repo.Ctx, "rev-list"). gitCmd := NewCommand(repo.Ctx, "rev-list").
AddOptionFormat("--max-count=%d", setting.Git.CommitsRangeSize*opts.Page). AddOptionFormat("--max-count=%d", setting.Git.CommitsRangeSize).
AddOptionFormat("--skip=%d", skip) AddOptionFormat("--skip=%d", skip)
gitCmd.AddDynamicArguments(opts.Revision) gitCmd.AddDynamicArguments(opts.Revision)

View file

@ -7,6 +7,9 @@ import (
"path/filepath" "path/filepath"
"testing" "testing"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/test"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -138,3 +141,61 @@ func TestGetTagCommit(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
assert.EqualValues(t, lTagCommitID, lTag.ID.String()) assert.EqualValues(t, lTagCommitID, lTag.ID.String())
} }
func TestCommitsByRange(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path)
require.NoError(t, err)
defer bareRepo1.Close()
baseCommit, err := bareRepo1.GetBranchCommit("master")
require.NoError(t, err)
testCases := []struct {
Page int
ExpectedCommitCount int
}{
{1, 3},
{2, 3},
{3, 1},
{4, 0},
}
for _, testCase := range testCases {
commits, err := baseCommit.CommitsByRange(testCase.Page, 3, "")
require.NoError(t, err)
assert.Len(t, commits, testCase.ExpectedCommitCount, "page: %d", testCase.Page)
}
}
func TestCommitsByFileAndRange(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path)
require.NoError(t, err)
defer bareRepo1.Close()
defer test.MockVariableValue(&setting.Git.CommitsRangeSize, 2)()
testCases := []struct {
File string
Page int
ExpectedCommitCount int
}{
{"file1.txt", 1, 1},
{"file2.txt", 1, 1},
{"file*.txt", 1, 2},
{"foo", 1, 2},
{"foo", 2, 1},
{"foo", 3, 0},
{"f*", 1, 2},
{"f*", 2, 2},
{"f*", 3, 1},
}
for _, testCase := range testCases {
commits, err := bareRepo1.CommitsByFileAndRange(CommitsByFileAndRangeOptions{
Revision: "master",
File: testCase.File,
Page: testCase.Page,
})
require.NoError(t, err)
assert.Len(t, commits, testCase.ExpectedCommitCount, "file: '%s', page: %d", testCase.File, testCase.Page)
}
}

View file

@ -17,6 +17,7 @@ import (
"code.gitea.io/gitea/modules/charset" "code.gitea.io/gitea/modules/charset"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/gitrepo"
tokenizer_hierarchy "code.gitea.io/gitea/modules/indexer/code/bleve/tokenizer/hierarchy"
"code.gitea.io/gitea/modules/indexer/code/internal" "code.gitea.io/gitea/modules/indexer/code/internal"
indexer_internal "code.gitea.io/gitea/modules/indexer/internal" indexer_internal "code.gitea.io/gitea/modules/indexer/internal"
inner_bleve "code.gitea.io/gitea/modules/indexer/internal/bleve" inner_bleve "code.gitea.io/gitea/modules/indexer/internal/bleve"
@ -56,6 +57,7 @@ func addUnicodeNormalizeTokenFilter(m *mapping.IndexMappingImpl) error {
type RepoIndexerData struct { type RepoIndexerData struct {
RepoID int64 RepoID int64
CommitID string CommitID string
Filename string
Content string Content string
Language string Language string
UpdatedAt time.Time UpdatedAt time.Time
@ -69,7 +71,8 @@ func (d *RepoIndexerData) Type() string {
const ( const (
repoIndexerAnalyzer = "repoIndexerAnalyzer" repoIndexerAnalyzer = "repoIndexerAnalyzer"
repoIndexerDocType = "repoIndexerDocType" repoIndexerDocType = "repoIndexerDocType"
repoIndexerLatestVersion = 6 pathHierarchyAnalyzer = "pathHierarchyAnalyzer"
repoIndexerLatestVersion = 7
) )
// generateBleveIndexMapping generates a bleve index mapping for the repo indexer // generateBleveIndexMapping generates a bleve index mapping for the repo indexer
@ -89,6 +92,11 @@ func generateBleveIndexMapping() (mapping.IndexMapping, error) {
docMapping.AddFieldMappingsAt("Language", termFieldMapping) docMapping.AddFieldMappingsAt("Language", termFieldMapping)
docMapping.AddFieldMappingsAt("CommitID", termFieldMapping) docMapping.AddFieldMappingsAt("CommitID", termFieldMapping)
pathFieldMapping := bleve.NewTextFieldMapping()
pathFieldMapping.IncludeInAll = false
pathFieldMapping.Analyzer = pathHierarchyAnalyzer
docMapping.AddFieldMappingsAt("Filename", pathFieldMapping)
timeFieldMapping := bleve.NewDateTimeFieldMapping() timeFieldMapping := bleve.NewDateTimeFieldMapping()
timeFieldMapping.IncludeInAll = false timeFieldMapping.IncludeInAll = false
docMapping.AddFieldMappingsAt("UpdatedAt", timeFieldMapping) docMapping.AddFieldMappingsAt("UpdatedAt", timeFieldMapping)
@ -103,6 +111,13 @@ func generateBleveIndexMapping() (mapping.IndexMapping, error) {
"token_filters": []string{unicodeNormalizeName, camelcase.Name, lowercase.Name}, "token_filters": []string{unicodeNormalizeName, camelcase.Name, lowercase.Name},
}); err != nil { }); err != nil {
return nil, err return nil, err
} else if err := mapping.AddCustomAnalyzer(pathHierarchyAnalyzer, map[string]any{
"type": analyzer_custom.Name,
"char_filters": []string{},
"tokenizer": tokenizer_hierarchy.Name,
"token_filters": []string{unicodeNormalizeName},
}); err != nil {
return nil, err
} }
mapping.DefaultAnalyzer = repoIndexerAnalyzer mapping.DefaultAnalyzer = repoIndexerAnalyzer
mapping.AddDocumentMapping(repoIndexerDocType, docMapping) mapping.AddDocumentMapping(repoIndexerDocType, docMapping)
@ -178,6 +193,7 @@ func (b *Indexer) addUpdate(ctx context.Context, batchWriter git.WriteCloserErro
return batch.Index(id, &RepoIndexerData{ return batch.Index(id, &RepoIndexerData{
RepoID: repo.ID, RepoID: repo.ID,
CommitID: commitSha, CommitID: commitSha,
Filename: update.Filename,
Content: string(charset.ToUTF8DropErrors(fileContents, charset.ConvertOpts{})), Content: string(charset.ToUTF8DropErrors(fileContents, charset.ConvertOpts{})),
Language: analyze.GetCodeLanguage(update.Filename, fileContents), Language: analyze.GetCodeLanguage(update.Filename, fileContents),
UpdatedAt: time.Now().UTC(), UpdatedAt: time.Now().UTC(),
@ -266,22 +282,30 @@ func (b *Indexer) Search(ctx context.Context, opts *internal.SearchOptions) (int
indexerQuery = keywordQuery indexerQuery = keywordQuery
} }
opts.Filename = strings.Trim(opts.Filename, "/")
if len(opts.Filename) > 0 {
// we use a keyword analyzer for the query than path hierarchy analyzer
// to match only the exact path
// eg, a query for modules/indexer/code
// should not provide results for modules/ nor modules/indexer
indexerQuery = bleve.NewConjunctionQuery(
indexerQuery,
inner_bleve.MatchQuery(opts.Filename, "Filename", analyzer_keyword.Name, 0),
)
}
// Save for reuse without language filter // Save for reuse without language filter
facetQuery := indexerQuery facetQuery := indexerQuery
if len(opts.Language) > 0 { if len(opts.Language) > 0 {
languageQuery := bleve.NewMatchQuery(opts.Language)
languageQuery.FieldVal = "Language"
languageQuery.Analyzer = analyzer_keyword.Name
indexerQuery = bleve.NewConjunctionQuery( indexerQuery = bleve.NewConjunctionQuery(
indexerQuery, indexerQuery,
languageQuery, inner_bleve.MatchQuery(opts.Language, "Language", analyzer_keyword.Name, 0),
) )
} }
from, pageSize := opts.GetSkipTake() from, pageSize := opts.GetSkipTake()
searchRequest := bleve.NewSearchRequestOptions(indexerQuery, pageSize, from, false) searchRequest := bleve.NewSearchRequestOptions(indexerQuery, pageSize, from, false)
searchRequest.Fields = []string{"Content", "RepoID", "Language", "CommitID", "UpdatedAt"} searchRequest.Fields = []string{"Content", "RepoID", "Filename", "Language", "CommitID", "UpdatedAt"}
searchRequest.IncludeLocations = true searchRequest.IncludeLocations = true
if len(opts.Language) == 0 { if len(opts.Language) == 0 {
@ -320,7 +344,7 @@ func (b *Indexer) Search(ctx context.Context, opts *internal.SearchOptions) (int
RepoID: int64(hit.Fields["RepoID"].(float64)), RepoID: int64(hit.Fields["RepoID"].(float64)),
StartIndex: startIndex, StartIndex: startIndex,
EndIndex: endIndex, EndIndex: endIndex,
Filename: internal.FilenameOfIndexerID(hit.ID), Filename: hit.Fields["Filename"].(string),
Content: hit.Fields["Content"].(string), Content: hit.Fields["Content"].(string),
CommitID: hit.Fields["CommitID"].(string), CommitID: hit.Fields["CommitID"].(string),
UpdatedUnix: updatedUnix, UpdatedUnix: updatedUnix,
@ -333,7 +357,7 @@ func (b *Indexer) Search(ctx context.Context, opts *internal.SearchOptions) (int
if len(opts.Language) > 0 { if len(opts.Language) > 0 {
// Use separate query to go get all language counts // Use separate query to go get all language counts
facetRequest := bleve.NewSearchRequestOptions(facetQuery, 1, 0, false) facetRequest := bleve.NewSearchRequestOptions(facetQuery, 1, 0, false)
facetRequest.Fields = []string{"Content", "RepoID", "Language", "CommitID", "UpdatedAt"} facetRequest.Fields = []string{"Content", "RepoID", "Filename", "Language", "CommitID", "UpdatedAt"}
facetRequest.IncludeLocations = true facetRequest.IncludeLocations = true
facetRequest.AddFacet("languages", bleve.NewFacetRequest("Language", 10)) facetRequest.AddFacet("languages", bleve.NewFacetRequest("Language", 10))

View file

@ -0,0 +1,69 @@
// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package hierarchy
import (
"bytes"
"github.com/blevesearch/bleve/v2/analysis"
"github.com/blevesearch/bleve/v2/registry"
)
const Name = "path_hierarchy"
type PathHierarchyTokenizer struct{}
// Similar to elastic's path_hierarchy tokenizer
// This tokenizes a given path into all the possible hierarchies
// For example,
// modules/indexer/code/search.go =>
//
// modules/
// modules/indexer
// modules/indexer/code
// modules/indexer/code/search.go
func (t *PathHierarchyTokenizer) Tokenize(input []byte) analysis.TokenStream {
// trim any extra slashes
input = bytes.Trim(input, "/")
// zero allocations until the nested directories exceed a depth of 8 (which is unlikely)
rv := make(analysis.TokenStream, 0, 8)
count, off := 1, 0
// iterate till all directory seperators
for i := bytes.IndexRune(input[off:], '/'); i != -1; i = bytes.IndexRune(input[off:], '/') {
// the index is relative to input[offest...]
// add this index to the accumlated offset to get the index of the current seperator in input[0...]
off += i
rv = append(rv, &analysis.Token{
Term: input[:off], // take the slice, input[0...index of seperator]
Start: 0,
End: off,
Position: count,
Type: analysis.AlphaNumeric,
})
// increment the offset after considering the seperator
off++
count++
}
// the entire file path should always be the last token
rv = append(rv, &analysis.Token{
Term: input,
Start: 0,
End: len(input),
Position: count,
Type: analysis.AlphaNumeric,
})
return rv
}
func TokenizerConstructor(config map[string]any, cache *registry.Cache) (analysis.Tokenizer, error) {
return &PathHierarchyTokenizer{}, nil
}
func init() {
registry.RegisterTokenizer(Name, TokenizerConstructor)
}

View file

@ -0,0 +1,59 @@
// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package hierarchy
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestIndexerBleveHierarchyTokenizer(t *testing.T) {
tokenizer := &PathHierarchyTokenizer{}
keywords := []struct {
Term string
Results []string
}{
{
Term: "modules/indexer/code/search.go",
Results: []string{
"modules",
"modules/indexer",
"modules/indexer/code",
"modules/indexer/code/search.go",
},
},
{
Term: "/tmp/forgejo/",
Results: []string{
"tmp",
"tmp/forgejo",
},
},
{
Term: "a/b/c/d/e/f/g/h/i/j",
Results: []string{
"a",
"a/b",
"a/b/c",
"a/b/c/d",
"a/b/c/d/e",
"a/b/c/d/e/f",
"a/b/c/d/e/f/g",
"a/b/c/d/e/f/g/h",
"a/b/c/d/e/f/g/h/i",
"a/b/c/d/e/f/g/h/i/j",
},
},
}
for _, kw := range keywords {
tokens := tokenizer.Tokenize([]byte(kw.Term))
assert.Len(t, tokens, len(kw.Results))
for i, token := range tokens {
assert.Equal(t, i+1, token.Position)
assert.Equal(t, kw.Results[i], string(token.Term))
}
}
}

View file

@ -30,7 +30,7 @@ import (
) )
const ( const (
esRepoIndexerLatestVersion = 1 esRepoIndexerLatestVersion = 2
// multi-match-types, currently only 2 types are used // multi-match-types, currently only 2 types are used
// Reference: https://www.elastic.co/guide/en/elasticsearch/reference/7.0/query-dsl-multi-match-query.html#multi-match-types // Reference: https://www.elastic.co/guide/en/elasticsearch/reference/7.0/query-dsl-multi-match-query.html#multi-match-types
esMultiMatchTypeBestFields = "best_fields" esMultiMatchTypeBestFields = "best_fields"
@ -57,6 +57,21 @@ func NewIndexer(url, indexerName string) *Indexer {
const ( const (
defaultMapping = `{ defaultMapping = `{
"settings": {
"analysis": {
"analyzer": {
"custom_path_tree": {
"tokenizer": "custom_hierarchy"
}
},
"tokenizer": {
"custom_hierarchy": {
"type": "path_hierarchy",
"delimiter": "/"
}
}
}
},
"mappings": { "mappings": {
"properties": { "properties": {
"repo_id": { "repo_id": {
@ -72,6 +87,15 @@ const (
"type": "keyword", "type": "keyword",
"index": true "index": true
}, },
"filename": {
"type": "text",
"fields": {
"tree": {
"type": "text",
"analyzer": "custom_path_tree"
}
}
},
"language": { "language": {
"type": "keyword", "type": "keyword",
"index": true "index": true
@ -138,6 +162,7 @@ func (b *Indexer) addUpdate(ctx context.Context, batchWriter git.WriteCloserErro
"repo_id": repo.ID, "repo_id": repo.ID,
"content": string(charset.ToUTF8DropErrors(fileContents, charset.ConvertOpts{})), "content": string(charset.ToUTF8DropErrors(fileContents, charset.ConvertOpts{})),
"commit_id": sha, "commit_id": sha,
"filename": update.Filename,
"language": analyze.GetCodeLanguage(update.Filename, fileContents), "language": analyze.GetCodeLanguage(update.Filename, fileContents),
"updated_at": timeutil.TimeStampNow(), "updated_at": timeutil.TimeStampNow(),
}), }),
@ -267,7 +292,6 @@ func convertResult(searchResult *elastic.SearchResult, kw string, pageSize int)
panic(fmt.Sprintf("2===%#v", hit.Highlight)) panic(fmt.Sprintf("2===%#v", hit.Highlight))
} }
repoID, fileName := internal.ParseIndexerID(hit.Id)
res := make(map[string]any) res := make(map[string]any)
if err := json.Unmarshal(hit.Source, &res); err != nil { if err := json.Unmarshal(hit.Source, &res); err != nil {
return 0, nil, nil, err return 0, nil, nil, err
@ -276,8 +300,8 @@ func convertResult(searchResult *elastic.SearchResult, kw string, pageSize int)
language := res["language"].(string) language := res["language"].(string)
hits = append(hits, &internal.SearchResult{ hits = append(hits, &internal.SearchResult{
RepoID: repoID, RepoID: int64(res["repo_id"].(float64)),
Filename: fileName, Filename: res["filename"].(string),
CommitID: res["commit_id"].(string), CommitID: res["commit_id"].(string),
Content: res["content"].(string), Content: res["content"].(string),
UpdatedUnix: timeutil.TimeStamp(res["updated_at"].(float64)), UpdatedUnix: timeutil.TimeStamp(res["updated_at"].(float64)),
@ -326,6 +350,9 @@ func (b *Indexer) Search(ctx context.Context, opts *internal.SearchOptions) (int
repoQuery := elastic.NewTermsQuery("repo_id", repoStrs...) repoQuery := elastic.NewTermsQuery("repo_id", repoStrs...)
query = query.Must(repoQuery) query = query.Must(repoQuery)
} }
if len(opts.Filename) > 0 {
query = query.Filter(elastic.NewTermsQuery("filename.tree", opts.Filename))
}
var ( var (
start, pageSize = opts.GetSkipTake() start, pageSize = opts.GetSkipTake()

View file

@ -34,10 +34,11 @@ func testIndexer(name string, t *testing.T, indexer internal.Indexer) {
err := index(git.DefaultContext, indexer, repoID) err := index(git.DefaultContext, indexer, repoID)
require.NoError(t, err) require.NoError(t, err)
keywords := []struct { keywords := []struct {
RepoIDs []int64 RepoIDs []int64
Keyword string Keyword string
IDs []int64 IDs []int64
Langs int Langs int
Filename string
}{ }{
{ {
RepoIDs: nil, RepoIDs: nil,
@ -51,6 +52,20 @@ func testIndexer(name string, t *testing.T, indexer internal.Indexer) {
IDs: []int64{}, IDs: []int64{},
Langs: 0, Langs: 0,
}, },
{
RepoIDs: nil,
Keyword: "Description",
IDs: []int64{},
Langs: 0,
Filename: "NOT-README.md",
},
{
RepoIDs: nil,
Keyword: "Description",
IDs: []int64{repoID},
Langs: 1,
Filename: "README.md",
},
{ {
RepoIDs: nil, RepoIDs: nil,
Keyword: "Description for", Keyword: "Description for",
@ -86,6 +101,7 @@ func testIndexer(name string, t *testing.T, indexer internal.Indexer) {
Page: 1, Page: 1,
PageSize: 10, PageSize: 10,
}, },
Filename: kw.Filename,
IsKeywordFuzzy: true, IsKeywordFuzzy: true,
}) })
require.NoError(t, err) require.NoError(t, err)

View file

@ -24,6 +24,7 @@ type SearchOptions struct {
RepoIDs []int64 RepoIDs []int64
Keyword string Keyword string
Language string Language string
Filename string
IsKeywordFuzzy bool IsKeywordFuzzy bool

View file

@ -3,30 +3,8 @@
package internal package internal
import ( import "code.gitea.io/gitea/modules/indexer/internal"
"strings"
"code.gitea.io/gitea/modules/indexer/internal"
"code.gitea.io/gitea/modules/log"
)
func FilenameIndexerID(repoID int64, filename string) string { func FilenameIndexerID(repoID int64, filename string) string {
return internal.Base36(repoID) + "_" + filename return internal.Base36(repoID) + "_" + filename
} }
func ParseIndexerID(indexerID string) (int64, string) {
index := strings.IndexByte(indexerID, '_')
if index == -1 {
log.Error("Unexpected ID in repo indexer: %s", indexerID)
}
repoID, _ := internal.ParseBase36(indexerID[:index])
return repoID, indexerID[index+1:]
}
func FilenameOfIndexerID(indexerID string) string {
index := strings.IndexByte(indexerID, '_')
if index == -1 {
log.Error("Unexpected ID in repo indexer: %s", indexerID)
}
return indexerID[index+1:]
}

View file

@ -35,6 +35,8 @@ type SearchResultLanguages = internal.SearchResultLanguages
type SearchOptions = internal.SearchOptions type SearchOptions = internal.SearchOptions
var CodeSearchOptions = [2]string{"exact", "fuzzy"}
func indices(content string, selectionStartIndex, selectionEndIndex int) (int, int) { func indices(content string, selectionStartIndex, selectionEndIndex int) (int, int) {
startIndex := selectionStartIndex startIndex := selectionStartIndex
numLinesBefore := 0 numLinesBefore := 0

View file

@ -28,13 +28,16 @@ var (
// The hash used for HKDF. // The hash used for HKDF.
hash = sha256.New hash = sha256.New
// The AEAD used for encryption/decryption. // The AEAD used for encryption/decryption.
aead = chacha20poly1305.NewX aead = chacha20poly1305.NewX
aeadKeySize = chacha20poly1305.KeySize
aeadNonceSize = chacha20poly1305.NonceSizeX
// The pseudorandom key generated by HKDF-Extract. // The pseudorandom key generated by HKDF-Extract.
prk []byte prk []byte
) )
const (
aeadKeySize = chacha20poly1305.KeySize
aeadNonceSize = chacha20poly1305.NonceSizeX
)
// Set the main IKM for this module. // Set the main IKM for this module.
func Init(ikm []byte) { func Init(ikm []byte) {
// Salt is intentionally left empty, it's not useful to Forgejo's use case. // Salt is intentionally left empty, it's not useful to Forgejo's use case.
@ -55,7 +58,7 @@ var (
// Derive *the* key for a given context, this is a deterministic function. // Derive *the* key for a given context, this is a deterministic function.
// The same key will be provided for the same context. // The same key will be provided for the same context.
func DeriveKey(context Context) *Key { func DeriveKey(context Context) *Key {
if len(prk) == 0 { if len(prk) != sha256.Size {
panic("keying: not initialized") panic("keying: not initialized")
} }
@ -63,7 +66,7 @@ func DeriveKey(context Context) *Key {
key := make([]byte, aeadKeySize) key := make([]byte, aeadKeySize)
// This should never return an error, but if it does, panic. // This should never return an error, but if it does, panic.
if _, err := r.Read(key); err != nil { if n, err := r.Read(key); err != nil || n != aeadKeySize {
panic(err) panic(err)
} }
@ -92,7 +95,7 @@ func (k *Key) Encrypt(plaintext, additionalData []byte) []byte {
// Generate a random nonce. // Generate a random nonce.
nonce := make([]byte, aeadNonceSize) nonce := make([]byte, aeadNonceSize)
if _, err := rand.Read(nonce); err != nil { if n, err := rand.Read(nonce); err != nil || n != aeadNonceSize {
panic(err) panic(err)
} }

View file

@ -89,8 +89,9 @@ func CreateRepositoryByExample(ctx context.Context, doer, u *user_model.User, re
Type: tp, Type: tp,
Config: &repo_model.PullRequestsConfig{ Config: &repo_model.PullRequestsConfig{
AllowMerge: true, AllowRebase: true, AllowRebaseMerge: true, AllowSquash: true, AllowFastForwardOnly: true, AllowMerge: true, AllowRebase: true, AllowRebaseMerge: true, AllowSquash: true, AllowFastForwardOnly: true,
DefaultMergeStyle: repo_model.MergeStyle(setting.Repository.PullRequest.DefaultMergeStyle), DefaultMergeStyle: repo_model.MergeStyle(setting.Repository.PullRequest.DefaultMergeStyle),
AllowRebaseUpdate: true, DefaultUpdateStyle: repo_model.UpdateStyle(setting.Repository.PullRequest.DefaultUpdateStyle),
AllowRebaseUpdate: true,
}, },
}) })
} else { } else {

View file

@ -87,6 +87,7 @@ var (
DefaultMergeMessageAllAuthors bool DefaultMergeMessageAllAuthors bool
DefaultMergeMessageMaxApprovers int DefaultMergeMessageMaxApprovers int
DefaultMergeMessageOfficialApproversOnly bool DefaultMergeMessageOfficialApproversOnly bool
DefaultUpdateStyle string
PopulateSquashCommentWithCommitMessages bool PopulateSquashCommentWithCommitMessages bool
AddCoCommitterTrailers bool AddCoCommitterTrailers bool
TestConflictingPatchesWithGitApply bool TestConflictingPatchesWithGitApply bool
@ -216,6 +217,7 @@ var (
DefaultMergeMessageAllAuthors bool DefaultMergeMessageAllAuthors bool
DefaultMergeMessageMaxApprovers int DefaultMergeMessageMaxApprovers int
DefaultMergeMessageOfficialApproversOnly bool DefaultMergeMessageOfficialApproversOnly bool
DefaultUpdateStyle string
PopulateSquashCommentWithCommitMessages bool PopulateSquashCommentWithCommitMessages bool
AddCoCommitterTrailers bool AddCoCommitterTrailers bool
TestConflictingPatchesWithGitApply bool TestConflictingPatchesWithGitApply bool
@ -232,6 +234,7 @@ var (
DefaultMergeMessageAllAuthors: false, DefaultMergeMessageAllAuthors: false,
DefaultMergeMessageMaxApprovers: 10, DefaultMergeMessageMaxApprovers: 10,
DefaultMergeMessageOfficialApproversOnly: true, DefaultMergeMessageOfficialApproversOnly: true,
DefaultUpdateStyle: "merge",
PopulateSquashCommentWithCommitMessages: false, PopulateSquashCommentWithCommitMessages: false,
AddCoCommitterTrailers: true, AddCoCommitterTrailers: true,
RetargetChildrenOnMerge: true, RetargetChildrenOnMerge: true,

View file

@ -105,6 +105,7 @@ type Repository struct {
DefaultDeleteBranchAfterMerge bool `json:"default_delete_branch_after_merge"` DefaultDeleteBranchAfterMerge bool `json:"default_delete_branch_after_merge"`
DefaultMergeStyle string `json:"default_merge_style"` DefaultMergeStyle string `json:"default_merge_style"`
DefaultAllowMaintainerEdit bool `json:"default_allow_maintainer_edit"` DefaultAllowMaintainerEdit bool `json:"default_allow_maintainer_edit"`
DefaultUpdateStyle string `json:"default_update_style"`
AvatarURL string `json:"avatar_url"` AvatarURL string `json:"avatar_url"`
Internal bool `json:"internal"` Internal bool `json:"internal"`
MirrorInterval string `json:"mirror_interval"` MirrorInterval string `json:"mirror_interval"`
@ -225,6 +226,8 @@ type EditRepoOption struct {
DefaultDeleteBranchAfterMerge *bool `json:"default_delete_branch_after_merge,omitempty"` DefaultDeleteBranchAfterMerge *bool `json:"default_delete_branch_after_merge,omitempty"`
// set to a merge style to be used by this repository: "merge", "rebase", "rebase-merge", "squash", or "fast-forward-only". // set to a merge style to be used by this repository: "merge", "rebase", "rebase-merge", "squash", or "fast-forward-only".
DefaultMergeStyle *string `json:"default_merge_style,omitempty"` DefaultMergeStyle *string `json:"default_merge_style,omitempty"`
// set to a update style to be used by this repository: "rebase" or "merge"
DefaultUpdateStyle *string `json:"default_update_style,omitempty"`
// set to `true` to allow edits from maintainers by default // set to `true` to allow edits from maintainers by default
DefaultAllowMaintainerEdit *bool `json:"default_allow_maintainer_edit,omitempty"` DefaultAllowMaintainerEdit *bool `json:"default_allow_maintainer_edit,omitempty"`
// set to `true` to archive this repository. // set to `true` to archive this repository.

View file

@ -1010,7 +1010,7 @@ remove_account_link=Odstranit propojený účet
remove_account_link_desc=Odstraněním propojeného účtu zrušíte jeho přístup k vašemu Forgejo účtu. Pokračovat? remove_account_link_desc=Odstraněním propojeného účtu zrušíte jeho přístup k vašemu Forgejo účtu. Pokračovat?
remove_account_link_success=Propojený účet byl odstraněn. remove_account_link_success=Propojený účet byl odstraněn.
hooks.desc=Přidat webhooky, které budou spouštěny pro <strong>všechny repozitáře</strong> vve vašem vlastnictví. hooks.desc=Přidejte webhooky, které budou spouštěny pro <strong>všechny repozitáře</strong> ve vašem vlastnictví.
orgs_none=Nejste členem žádné organizace. orgs_none=Nejste členem žádné organizace.
repos_none=Nevlastníte žádné repozitáře. repos_none=Nevlastníte žádné repozitáře.
@ -2849,6 +2849,7 @@ issues.num_reviews_one = %d kontrola
issues.num_reviews_few = %d kontrol issues.num_reviews_few = %d kontrol
issues.summary_card_alt = Souhrn problému s názvem „%s“ v repozitáři %s issues.summary_card_alt = Souhrn problému s názvem „%s“ v repozitáři %s
editor.add_tmpl.filename = nazevsouboru editor.add_tmpl.filename = nazevsouboru
settings.default_update_style_desc = Výchozí způsob aktualizací používaný pro aktualizace žádostí o sloučení, které jsou pozadu oproti základní větvi.
[graphs] [graphs]
component_loading_info = Tohle může chvíli trvat… component_loading_info = Tohle může chvíli trvat…

View file

@ -0,0 +1,907 @@
[common]
home = Hjem
dashboard = Instrumentpanel
explore = Udforsk
help = Hjælp
logo = Logo
sign_in = Login
sign_in_with_provider = Login med %s
sign_in_or = eller
sign_out = Logud
sign_up = Register
return_to_forgejo = Vend tilbage til Forgejo
new_repo.title = Ny repository
retry = Prøv igen
link_account = Link konto
register = Register
powered_by = Baseret på %s
version = Version
create_new = Opret…
user_profile_and_more = Profil og indstillinger…
page = Side
template = Skabelon
language = Sprog
notifications = Notifikationer
active_stopwatch = Aktiv tidsregistrering
enable_javascript = Dette websted kræver JavaScript.
toc = Indholdsfortegnelse
licenses = Licenser
more_items = Flere genstande
username = Brugernavn
email = E-mailadresse
password = Adgangskode
access_token = Adgangstoken
re_type = Bekræft adgangskode
captcha = CAPTCHA
twofa = To-faktor autentificering
twofa_scratch = To-faktor skrabekode
webauthn_sign_in = Tryk på knappen på din sikkerhedsnøgle. Hvis din sikkerhedsnøgle ikke har nogen knap, skal du indsætte den igen.
webauthn_use_twofa = Brug en tofaktorkode fra din telefon
webauthn_error = Kunne ikke læse din sikkerhedsnøgle.
webauthn_unsupported_browser = Din browser understøtter i øjeblikket ikke WebAuthn.
webauthn_error_unknown = Der opstod en ukendt fejl. Prøv venligst igen.
webauthn_error_unable_to_process = Serveren kunne ikke behandle din anmodning.
webauthn_error_duplicated = Sikkerhedsnøglen er ikke tilladt for denne anmodning. Sørg for, at nøglen ikke allerede er registreret.
webauthn_error_empty = Du skal angive et navn for denne nøgle.
organization = Organisation
mirror = Mirror
new_mirror = Ny mirror
new_fork = Ny repository fork
new_project = Nyt projekt
new_project_column = Ny kolonne
admin_panel = Side administration
settings = Indstillinger
your_profile = Profil
your_starred = Stjernemarkeret
your_settings = Indstillinger
passcode = Passcode
repository = Repository
new_org.title = Ny organisation
new_repo.link = Nyt repository
new_migrate.link = Ny migration
new_org.link = Ny organisation
all = Alle
sources = Kilder
mirrors = Mirrors
collaborative = Samarbejdende
forks = Forks
activities = Aktiviteter
pull_requests = Pull anmodninger
issues = Problemer
milestones = Milepæle
ok = OK
cancel = Annuller
rerun = Kør igen
rerun_all = Kør alle jobs igen
save = Gem
add = Tilføj
add_all = Tilføj alle
remove = Slet
remove_all = Slet alle
remove_label_str = Slet genstand "%s"
edit = Redigere
view = Se
test = Test
disabled = Deaktiveret
copy = Kopiér
copy_generic = Kopiér til udklipsholder
copy_url = Kopiér URL
copy_path = Kopiér sti
copy_content = Kopier indhold
copy_branch = Kopiér branch navn
copy_success = Kopieret!
copy_error = Kopiering mislykkedes
write = Skriv
preview = Forhåndsvisning
loading = Indlæser…
error = Fejl
error413 = Du har opbrugt din kvote.
go_back = Gå tilbage
never = Aldrig
unknown = Ukendt
rss_feed = RSS feed
pin = Pin
unpin = Frigør
artifacts = Artefakter
archived = Arkiveret
concept_system_global = Global
concept_user_individual = Individuel
concept_code_repository = Repository
concept_user_organization = Organisation
show_timestamps = Vis tidsstempler
show_log_seconds = Vis sekunder
tracked_time_summary = Opsummering af sporet tid baseret på filtre af problemliste
signed_in_as = Logget ind som
webauthn_error_insecure = WebAuthn understøtter kun sikre forbindelser. Til test over HTTP kan du bruge oprindelsen "localhost" eller "127.0.0.1"
invalid_data = Ugyldige data: %v
webauthn_insert_key = Indsæt din sikkerhedsnøgle
webauthn_press_button = Tryk venligst på knappen på din sikkerhedsnøgle…
webauthn_error_timeout = Timeout nået, før din nøgle kunne læses. Genindlæs denne side og prøv igen.
enabled = Aktiveret
locked = Låst
copy_hash = Kopiér hash
error404 = Den side, du forsøger at nå, enten <strong>findes ikke</strong> eller <strong>du er ikke autoriseret</strong> til at se den.
confirm_delete_artifact = Er du sikker på, at du vil slette artefakten "%s"?
new_migrate.title = Ny migration
copy_type_unsupported = Denne filtype kan ikke kopieres
toggle_menu = TIl/Fra menu
show_full_screen = Vis fuld skærm
download_logs = Download logs
confirm_delete_selected = Bekræft at slette alle valgte genstande?
name = Navn
value = Værdi
filter = Filter
filter.clear = Ryd filtre
filter.is_archived = Arkiveret
filter.not_archived = Ikke arkiveret
filter.is_fork = Forks
filter.not_fork = Ikke forks
filter.is_mirror = Mirrors
filter.not_mirror = Ikke mirrors
filter.is_template = Skabeloner
filter.not_template = Ikke skabeloner
filter.public = Offentlig
filter.private = Privat
[search]
search = Søg...
type_tooltip = Søge type
fuzzy = Fuzzy
fuzzy_tooltip = Medtag resultater, der også matcher søgeordet tæt
union = Almindelig
union_tooltip = Inkluder resultater, der matcher et hvilket som helst af de mellemrumsadskilte søgeord
exact = Nøjagtig
exact_tooltip = Medtag kun resultater, der matcher den nøjagtige søgeterm
regexp = RegExp
regexp_tooltip = Fortolk søgetermen som et regulært udtryk
org_kind = Søg i organisationer...
team_kind = Søg efter hold...
code_kind = Søg kode...
code_search_by_git_grep = Aktuelle kodesøgeresultater leveres af "git grep". Der kan være bedre resultater, hvis webstedsadministratoren aktiverer kodeindeksering.
package_kind = Søg pakker...
project_kind = Søg efter projekter...
commit_kind = Søg commits...
branch_kind = Søg branches...
runner_kind = Søg runners...
issue_kind = Søg i problemer...
milestone_kind = Søg milepæle...
pull_kind = Søg pulls...
repo_kind = Søg depoter...
code_search_unavailable = Kodesøgning er ikke tilgængelig i øjeblikket. Kontakt venligst webstedets administrator.
no_results = Ingen matchende resultater fundet.
user_kind = Søg brugere...
keyword_search_unavailable = Søgning efter nøgleord er ikke tilgængelig i øjeblikket. Kontakt venligst webstedets administrator.
[aria]
navbar = Navigationslinje
footer = Sidefod
footer.software = Omkring dette software
footer.links = Links
[heatmap]
number_of_contributions_in_the_last_12_months = %s bidrag inden for de sidste 12 måneder
contributions_zero = Ingen bidrag
contributions_format = {contributions} på {month} {day}, {year}
contributions_one = bidrag
contributions_few = bidragene
less = Mindre
more = Mere
[editor]
buttons.heading.tooltip = Tilføj overskrift
buttons.bold.tooltip = Tilføj fed tekst
buttons.italic.tooltip = Tilføj kursiv tekst
buttons.quote.tooltip = Citat tekst
buttons.code.tooltip = Tilføj kode
buttons.link.tooltip = Tilføj et link
buttons.list.unordered.tooltip = Tilføj en punktliste
buttons.list.task.tooltip = Tilføj en liste over opgaver
buttons.list.ordered.tooltip = Tilføj en nummereret liste
buttons.mention.tooltip = Nævn en bruger eller et hold
buttons.ref.tooltip = Henvis til et problem eller pull-anmodning
buttons.enable_monospace_font = Aktiver monospace-skrifttype
buttons.disable_monospace_font = Deaktiver monospace-skrifttype
buttons.new_table.tooltip = Tilføj tabel
table_modal.header = Tilføj tabel
table_modal.placeholder.header = Hoved
table_modal.placeholder.content = Indhold
table_modal.label.rows = Rækker
table_modal.label.columns = Kolonner
buttons.unindent.tooltip = Udsortere genstande med ét niveau
buttons.indent.tooltip = Indlejring af genstande med ét niveau
buttons.switch_to_legacy.tooltip = Brug den gamle editor i stedet
[filter]
string.asc = A - Z
string.desc = Z - A
[error]
occurred = Der opstod en fejl
not_found = Målet kunne ikke findes.
network_error = Netværksfejl
server_internal = Intern serverfejl
report_message = Hvis du mener, at dette er en Forgejo-fejl, skal du søge efter problemer på <a href="%s" target="_blank">Codeberg</a> eller åbne et nyt problem, hvis det er nødvendigt.
[startpage]
app_desc = En smertefri, selv-hostet Git-tjeneste
install = Nem at installere
platform = På tværs af platforme
platform_desc = Det er bekræftet, at Forgejo kører på frie operativsystemer som Linux og FreeBSD, samt forskellige CPU-arkitekturer. Vælg den du elsker!
lightweight = Letvægtig
lightweight_desc = Forgejo har lave minimale krav og kan køre på en billig Raspberry Pi. Spar din maskines energi!
license = Åben kildekode
license_desc = Få <a target="_blank" rel="noopener noreferrer" href="%[1]s">Forgejo</a>! Slut dig til os ved at <a target="_blank" rel="noopener noreferrer" href="%[2]s">bidrage</a> til at gøre dette projekt endnu bedre. Vær ikke genert over at være en bidragyder!
install_desc = Du skal blot <a target="_blank" rel="noopener noreferrer" href="%[1]s">køre binæren</a> for din platform, send den med <a target="_blank" rel="noopener noreferrer" href="%[2]s">Docker</a>, eller få det <a target="_blank" rel="noopener noreferrer" href="%[3]s">pakket</a>.
[install]
install = Installation
title = Indledende konfiguration
docker_helper = Hvis du kører Forgejo inde i Docker, skal du læse <a target="_blank" rel="noopener noreferrer" href="%s">dokumentationen</a>, før du ændrer nogen indstillinger.
require_db_desc = Forgejo kræver MySQL, PostgreSQL, SQLite3 eller TiDB (MySQL-protokol).
db_title = Database indstillinger
db_type = Database type
host = Vært
user = Brugernavn
password = Adgangskode
db_name = Database navn
db_schema = Schema
db_schema_helper = Lad stå tom for databasestandard ("offentlig").
ssl_mode = SSL
reinstall_error = Du forsøger at installere i en eksisterende Forgejo-database
reinstall_confirm_check_1 = Dataene krypteret af SECRET_KEY i app.ini kan gå tabt: brugere kan muligvis ikke logge ind med 2FA/OTP, og mirrors fungerer muligvis ikke korrekt. Ved at markere dette felt bekræfter du, at den aktuelle app.ini-fil indeholder den korrekte SECRET_KEY.
reinstall_confirm_check_3 = Du bekræfter, at du er helt sikker på, at denne Forgejo kører med den korrekte app.ini placering, og at du er sikker på, at du skal gen-installere. Du bekræfter, at du anerkender ovenstående risici.
err_empty_db_path = SQLite3-databasestien må ikke være tom.
no_admin_and_disable_registration = Du kan ikke deaktivere brugerens selvregistrering uden at oprette en administratorkonto.
err_empty_admin_password = Administratoradgangskoden må ikke være tom.
err_empty_admin_email = Administrator-e-mailen må ikke være tom.
err_admin_name_is_reserved = Administratorbrugernavnet er ugyldigt, brugernavnet er reserveret
err_admin_name_pattern_not_allowed = Administratorbrugernavnet er ugyldigt, brugernavnet matcher et reserveret mønster
err_admin_name_is_invalid = Administratorbrugernavnet er ugyldigt
general_title = Generelle indstillinger
app_name = Instans titel
app_slogan_helper = Indtast dit instans slogan her. Lad være tom for at deaktivere.
lfs_path_helper = Filer sporet af Git LFS vil blive gemt i denne mappe. Lad være tom for at deaktivere.
run_user = Bruger at køre som
lfs_path = Git LFS rodsti
repo_path = Depot rodsti
domain = Server domæne
domain_helper = Domæne eller værtsadresse for serveren.
ssh_port = SSH server port
ssh_port_helper = Portnummer, der vil blive brugt af SSH-serveren. Lad være tomt for at deaktivere SSH-serveren.
http_port = HTTP lytte port
http_port_helper = Portnummer, der vil blive brugt af Forgejo-webserveren.
app_url = Base URL
log_root_path = Log sti
log_root_path_helper = Logfiler vil blive skrevet til denne mappe.
optional_title = Valgfrie indstillinger
email_title = E-mail-indstillinger
smtp_addr = SMTP vært
smtp_port = SMTP port
smtp_from = Send e-mail som
smtp_from_invalid = "Send e-mail som"-adressen er ugyldig
mailer_user = SMTP brugernavn
mailer_password = SMTP adgangskode
register_confirm = Kræv e-mail-bekræftelse for at registrere
mail_notify = Aktiver e-mailmeddelelser
server_service_title = Server- og tredjeparts tjenesteindstillinger
offline_mode = Aktiver lokal tilstand
disable_gravatar = Deaktiver Gravatar
disable_gravatar.description = Deaktiver brug af Gravatar eller andre tredjeparts avatar kilder. Standardbilleder vil blive brugt til bruger avatarer, medmindre de uploader deres egen avatar til instansen.
federated_avatar_lookup = Aktiver fødererede avatarer
federated_avatar_lookup.description = Slå avatarer op ved hjælp af Libravatar.
disable_registration = Deaktiver selvregistrering
allow_only_external_registration = Tillad kun registrering via eksterne tjenester
allow_only_external_registration.description = Brugere vil kun være i stand til at oprette nye konti ved at bruge konfigurerede eksterne tjenester.
openid_signin = Aktiver OpenID-logon
openid_signin.description = Tillad brugere at logge ind via OpenID.
app_slogan = Instans slogan
repo_path_helper = Fjerne Git depoter vil blive gemt i denne mappe.
smtp_from_helper = E-mailadresse Forgejo vil bruge. Indtast en almindelig e-mailadresse, eller brug formatet "Navn" <email@example.com>.
run_user_helper = Operativsystemets brugernavn, som Forgejo kører som. Bemærk, at denne bruger skal have adgang til depotets rodsti.
app_name_helper = Indtast dit instans-navn her. Det vil blive vist på hver side.
offline_mode.description = Deaktiver tredjeparts indholdsleverings netværk og server alle ressourcer lokalt.
disable_registration.description = Kun instans administratoren vil være i stand til at oprette nye brugerkonti. Det anbefales stærkt at holde registreringen deaktiveret, medmindre du har til hensigt at være vært for en offentlig instans for alle og klar til at håndtere store mængder spamkonti.
openid_signup = Aktiver OpenID-selvregistrering
sqlite_helper = Filsti til SQLite3-databasen.<br>Indtast en absolut sti, hvis du kører Forgejo som en tjeneste.
path = Sti
reinstall_confirm_message = Geninstallation med en eksisterende Forgejo-database kan forårsage flere problemer. I de fleste tilfælde bør du bruge din eksisterende "app.ini" til at køre Forgejo. Hvis du ved, hvad du laver, skal du bekræfte følgende:
reinstall_confirm_check_2 = Depoterne og indstillingerne skal muligvis synkroniseres igen. Ved at markere dette felt bekræfter du, at du vil re-synkronisere hooks for depoter og authorized_keys-filen manuelt. Du bekræfter, at du vil sikre dig, at indstillingerne for depoter og mirror er korrekte.
app_url_helper = Base adresse for HTTP(S)-klone-URL'er og e-mail-meddelelser.
enable_captcha = Aktiver registrering CAPTCHA
enable_captcha.description = Kræv brugere at bestå CAPTCHA for at oprette konti.
require_sign_in_view = Kræv at logge ind for at se instansindhold
default_keep_email_private = Skjul e-mailadresser som standard
default_keep_email_private.description = Aktiver skjulning af e-mail-adresser for nye brugere som standard, så disse oplysninger ikke lækkes umiddelbart efter tilmelding.
default_allow_create_organization = Tillad oprettelse af organisationer som standard
default_enable_timetracking = Aktiver tidsregistrering som standard
default_enable_timetracking.description = Tillad som standard brug af tidssporings-funktion for nye depoter.
admin_title = Indstillinger for administratorkonto
admin_setting.description = Det er valgfrit at oprette en administratorkonto. Den første registrerede bruger bliver automatisk administrator.
admin_name = Administrator brugernavn
admin_password = Adgangskode
confirm_password = Bekræft adgangskode
admin_email = E-mailadresse
config_location_hint = Disse konfigurationsmuligheder vil blive gemt i:
install_btn_confirm = Installer Forgejo
invalid_db_setting = Databaseindstillingerne er ugyldige: %v
invalid_db_table = Databasetabellen "%s" er ugyldig: %v
invalid_repo_path = Depotets rodsti er ugyldig: %v
invalid_app_data_path = Appens datasti er ugyldig: %v
run_user_not_match = Brugernavnet som "bruger det skal køres som" er ikke det aktuelle brugernavn: %s -> %s
internal_token_failed = Kunne ikke generere intern token: %v
secret_key_failed = Kunne ikke generere hemmelig nøgle: %v
save_config_failed = Konfigurationen kunne ikke gemmes: %v
invalid_admin_setting = Administratorkonto indstillingen er ugyldig: %v
invalid_log_root_path = Log stien er ugyldig: %v
allow_dots_in_usernames = Tillad brugere at bruge prikker i deres brugernavne. Påvirker ikke eksisterende konti.
no_reply_address = Skjult e-mail-domæne
invalid_password_algorithm = Ugyldig hash-algoritme for adgangskode
enable_update_checker = Aktiver opdateringskontrol
env_config_keys = Miljøkonfiguration
env_config_keys_prompt = Følgende miljøvariabler vil også blive anvendt på din konfigurationsfil:
test_git_failed = Kunne ikke teste "git" kommandoen: %v
sqlite3_not_available = Denne Forgejo-version understøtter ikke SQLite3. Download venligst den officielle binære version fra %s (ikke "gobuild"-versionen).
no_reply_address_helper = Domænenavn til brugere med en skjult e-mailadresse. For eksempel vil brugernavnet "joe" blive logget i Git som "joe@noreply.example.org", hvis det skjulte e-mail-domæne er sat til "noreply.example.org".
require_sign_in_view.description = Begræns indholdsadgang til ind-loggede brugere. Gæster vil kun kunne besøge autentificerings sider..
default_allow_create_organization.description = Tillad nye brugere at oprette organisationer som standard. Når denne mulighed er deaktiveret, skal en administrator give tilladelse til at oprette organisationer til nye brugere.
password_algorithm = Adgangskode hash algoritme
enable_update_checker_helper_forgejo = Den vil med jævne mellemrum tjekke for nye Forgejo versioner ved at tjekke en TXT DNS-posten på release.forgejo.org.
password_algorithm_helper = Indstil adgangskode-hash-algoritmen. Algoritmer har forskellige krav og styrke. Argon2-algoritmen er ret sikker, men bruger meget hukommelse og kan være upassende til små systemer.
openid_signup.description = Tillad brugere at oprette konti via OpenID, hvis selvregistrering er aktiveret.
[home]
uname_holder = Brugernavn eller e-mailadresse
switch_dashboard_context = Skift instrumentpanel-kontekst
my_repos = Depoter
my_orgs = Organisationer
view_home = Se %s
filter = Andre filtre
filter_by_team_repositories = Filtrer efter holddepoter
feed_of = Feed of "%s"
show_archived = Arkiveret
show_both_archived_unarchived = Viser både arkiveret og ikke-arkiveret
show_only_archived = Viser kun arkiverede
show_only_unarchived = Viser kun ikke-arkiveret
show_private = Privat
show_only_private = Viser kun privat
show_only_public = Viser kun offentligt
issues.in_your_repos = I dine depoter
show_both_private_public = Viser både offentlige og private
[explore]
repos = Depoter
users = Brugere
stars_one = %d stjerne
stars_few = %d stjerner
forks_one = %d fork
forks_few = %d forks
organizations = Organisationer
code = Kode
code_last_indexed_at = Sidst indekseret %s
relevant_repositories = Kun relevante depoter vises, <a href="%s">vis ufiltrerede resultater</a>.
go_to = Gå til
relevant_repositories_tooltip = Depoter som er forks, eller som ikke har noget emne, intet ikon og ingen beskrivelse, er skjult.
[auth]
create_new_account = Registrer konto
disable_register_prompt = Registrering er deaktiveret. Kontakt venligst din side-administrator.
disable_register_mail = E-mailbekræftelse for registrering er deaktiveret.
manual_activation_only = Kontakt din side-administrator for at fuldføre aktiveringen.
remember_me = Husk denne enhed
forgot_password_title = Glemt adgangskode
forgot_password = Glemt adgangskode?
hint_register = Har du brug for en konto? <a href="%s">Registrer dig nu.</a>
sign_up_button = Registrer nu.
sign_up_successful = Kontoen blev oprettet. Velkommen!
must_change_password = Opdater din adgangskode
allow_password_change = Kræv, at brugeren ændrer adgangskode (anbefales)
reset_password_mail_sent_prompt = En bekræftelses-e-mail er blevet sendt til <b>%s</b>. For at fuldføre kontogendannelses-processen skal du tjekke din indbakke og følge det medfølgende link inden for de næste %s.
active_your_account = Aktiver din konto
account_activated = Kontoen er blevet aktiveret
prohibit_login = Kontoen er suspenderet
prohibit_login_desc = Din konto er blevet suspenderet fra interaktion med instansen. Kontakt instans-administratoren for at få adgang igen.
change_unconfirmed_email_summary = Skift den e-mailadresse, aktiveringsmail sendes til.
change_unconfirmed_email_error = Kan ikke ændre e-mailadressen: %v
resend_mail = Klik her for at sende din aktiverings-e-mail igen
send_reset_mail = Send gendannelses-e-mail
reset_password = Kontogendannelse
invalid_code = Din bekræftelseskode er ugyldig eller er udløbet.
invalid_code_forgot_password = Din bekræftelseskode er ugyldig eller er udløbet. Klik <a href="%s">her</a> for at starte en ny session.
invalid_password = Din adgangskode stemmer ikke overens med den adgangskode, der blev brugt til at oprette kontoen.
reset_password_helper = Gendan konto
resent_limit_prompt = Du har allerede anmodet om en aktiverings-e-mail for nylig. Vent venligst 3 minutter, og prøv igen.
reset_password_wrong_user = Du er logget ind som %s, men linket til kontogendannelse er beregnet til %s
confirmation_mail_sent_prompt = En ny bekræftelses-e-mail er blevet sendt til <b>%s</b>. For at fuldføre registreringsprocessen skal du tjekke din indbakke og følge det medfølgende link inden for de næste %s. Hvis e-mailen er forkert, kan du logge ind og anmode om, at endnu en bekræftelses-e-mail sendes til en anden adresse.
change_unconfirmed_email = Hvis du har opgivet den forkerte e-mailadresse under tilmeldingen, kan du ændre den nedenfor, og der vil i stedet blive sendt en bekræftelse til den nye adresse.
hint_login = Har du allerede en konto? <a href="%s">Log ind nu!</a>
has_unconfirmed_mail = Hej %s, du har en ubekræftet e-mailadresse (<b>%s</b>). Hvis du ikke har modtaget en bekræftelses-e-mail eller har brug for at sende en ny, bedes du klikke på knappen nedenfor.
password_too_short = Adgangskodelængden må ikke være mindre end %d tegn.
non_local_account = Ikke-lokale brugere kan ikke opdatere deres adgangskode via Forgejo-webgrænsefladen.
verify = Verificere
unauthorized_credentials = Legitimationsoplysningerne er forkerte eller er udløbet. Prøv din kommando igen, eller se %s for at få flere oplysninger
scratch_code = Skrabekode
use_scratch_code = Brug en skrabekode
use_onetime_code = Brug en engangskode
twofa_scratch_used = Du har brugt din skrabekode. Du er blevet omdirigeret til siden med to-faktorindstillinger, så du kan fjerne din enhedstilmelding eller generere en ny skrabekode.
twofa_passcode_incorrect = Din passcode er forkert. Hvis du har forlagt din enhed, skal du bruge din skrabekode til at logge ind.
twofa_scratch_token_incorrect = Din skrabekode er forkert.
login_userpass = Login
oauth_signup_tab = Registrer ny konto
oauth_signup_title = Fuldfør ny konto
oauth_signup_submit = Gennemfør konto
oauth_signin_tab = Link til en eksisterende konto
oauth_signin_title = Log ind for at godkende linket konto
oauth_signin_submit = Link konto
oauth.signin.error = Der opstod en fejl under behandling af godkendelsesanmodningen. Hvis denne fejl fortsætter, bedes du kontakte webstedets administrator.
oauth.signin.error.access_denied = Godkendelsesanmodningen blev afvist.
oauth.signin.error.temporarily_unavailable = Godkendelse mislykkedes, fordi godkendelsesserveren midlertidigt ikke er tilgængelig. Prøv venligst igen senere.
openid_connect_submit = Forbind
openid_connect_title = Opret forbindelse til en eksisterende konto
openid_register_title = Opret ny konto
openid_register_desc = Den valgte OpenID URI er ukendt. Knyt den til en ny konto her.
disable_forgot_password_mail = Kontogendannelse er deaktiveret, fordi der ikke er konfigureret nogen e-mail. Kontakt venligst din webstedsadministrator.
email_domain_blacklisted = Du kan ikke registrere dig med din e-mailadresse.
authorize_application = Godkend Applikation
authorize_redirect_notice = Du vil blive omdirigeret til %s, hvis du godkender denne applikation.
authorize_application_created_by = Denne applikation blev oprettet af %s.
authorize_application_description = Hvis du giver adgangen, vil den være i stand til at få adgang til og skrive til alle dine kontooplysninger, inklusive private depoter og organisationer.
authorize_title = Tillad "%s" at få adgang til din konto?
authorization_failed = Godkendelse mislykkedes
password_pwned_err = Kunne ikke fuldføre anmodningen til HaveIBeenPwned
last_admin = Du kan ikke fjerne den sidste admin. Der skal være mindst én administrator.
back_to_sign_in = Tilbage til Log ind
sign_in_openid = Fortsæt med OpenID
openid_signin_desc = Indtast din OpenID URI. For eksempel: alice.openid.example.org eller https://openid.example.org/alice.
disable_forgot_password_mail_admin = Kontogendannelse er kun tilgængelig, når e-mail er konfigureret. Konfigurer venligst e-mail for at aktivere kontogendannelse.
password_pwned = Den adgangskode, du valgte, er på en <a target="_blank" rel="noopener noreferrer" href="%s">liste over stjålne adgangskoder</a>, der tidligere er blevet afsløret i forbindelse med offentlige databrud. Prøv venligst igen med en anden adgangskode, og overvej også at ændre denne adgangskode et andet sted.
openid_connect_desc = Den valgte OpenID URI er ukendt. Knyt den til en ny konto her.
authorization_failed_desc = Godkendelsen mislykkedes, fordi vi har registreret en ugyldig anmodning. Kontakt venligst vedligeholderen af den app, du har forsøgt at godkende.
[mail]
view_it_on = Se det på %s
reply = eller svar direkte på denne e-mail
link_not_working_do_paste = Virker linket ikke? Prøv at kopiere og indsætte det i din browsers URL-linje.
hi_user_x = Hej <b>%s</b>,
activate_account = Aktiver venligst din konto
activate_account.text_1 = Hej <b>%[1]s</b>, tak, fordi du registrerede dig hos %[2]s!
activate_account.text_2 = Klik venligst på følgende link for at aktivere din konto inden for <b>%s</b>:
activate_email = Bekræft din e-mailadresse
admin.new_user.subject = Ny bruger %s har lige tilmeldt sig
admin.new_user.user_info = Brugeroplysninger
admin.new_user.text = Venligst <a href="%s">klik her</a> for at administrere denne bruger fra administrationspanelet.
register_notify = Velkommen til %s
register_notify.text_1 = dette er din registreringsbekræftelses-e-mail for %s!
register_notify.text_3 = Hvis en anden har lavet denne konto for dig, skal du først <a href="%s">indstille din adgangskode</a>.
reset_password = Gendan din konto
password_change.subject = Din adgangskode er blevet ændret
password_change.text_1 = Adgangskoden til din konto er lige blevet ændret.
primary_mail_change.subject = Din primære mail er blevet ændret
totp_disabled.subject = TOTP er blevet deaktiveret
totp_disabled.text_1 = Tidsbaseret engangsadgangskode (TOTP) på din konto er netop blevet deaktiveret.
totp_disabled.no_2fa = Der er ikke længere konfigureret andre 2FA-metoder, hvilket betyder, at det ikke længere er nødvendigt at logge ind på din konto hos 2FA.
removed_security_key.subject = En sikkerhedsnøgle er blevet fjernet
removed_security_key.text_1 = Sikkerhedsnøglen "%[1]s" er lige blevet fjernet fra din konto.
account_security_caution.text_1 = Hvis dette var dig, så kan du roligt ignorere denne mail.
totp_enrolled.subject = Du har aktiveret TOTP som 2FA-metode
totp_enrolled.text_1.has_webauthn = Du har lige aktiveret TOTP for din konto. Dette betyder, at du for alle fremtidige login til din konto kan bruge TOTP som en 2FA-metode eller bruge en af dine sikkerhedsnøgler.
register_success = Registreringen lykkedes
issue_assigned.pull = @%[1]s har tildelt dig at trække anmodning %[2]s i depotet %[3]s.
issue_assigned.issue = @%[1]s har tildelt dig et problem %[2]s i depotet %[3]s.
register_notify.text_2 = Du kan logge ind på din konto med dit brugernavn: %s
primary_mail_change.text_1 = Din kontos primære mail er lige blevet ændret til %[1]s. Det betyder, at denne e-mailadresse ikke længere vil modtage e-mail-meddelelser for din konto.
account_security_caution.text_2 = Hvis dette ikke var dig, er din konto kompromitteret. Kontakt venligst administratorerne af dette websted.
activate_email.text = Klik venligst på følgende link for at bekræfte din e-mailadresse inden for <b>%s</b>:
reset_password.text = Hvis dette var dig, skal du klikke på følgende link for at gendanne din konto inden for <b>%s</b>:
removed_security_key.no_2fa = Der er ikke længere konfigureret andre 2FA-metoder, hvilket betyder, at det ikke længere er nødvendigt at logge ind på din konto hos 2FA.
totp_enrolled.text_1.no_webauthn = Du har lige aktiveret TOTP for din konto. Det betyder, at du for alle fremtidige login til din konto skal bruge TOTP som 2FA-metode.
issue.x_mentioned_you = <b>@%s</b> nævnte dig:
issue.action.force_push = <b>%[1]s</b> tvangs pushed <b>%[2]s</b> fra %[3]s til %[4]s.
issue.action.push_1 = <b>@%[1]s</b> pushed %[3]d commit til %[2]s
issue.action.push_n = <b>@%[1]s</b> pushed %[3]d commits til %[2]s
issue.action.close = <b>@%[1]s</b> lukket #%[2]d.
issue.action.reopen = <b>@%[1]s</b> genåbnet #%[2]d.
issue.action.merge = <b>@%[1]s</b> merged #%[2]d ind i %[3]s.
issue.action.approve = <b>@%[1]s</b> godkendte denne pull-anmodning.
issue.action.reject = <b>@%[1]s</b> anmodede om ændringer på denne pull-anmodning.
issue.action.review = <b>@%[1]s</b> kommenterede denne pull-anmodning.
issue.action.review_dismissed = <b>@%[1]s</b> afviste den seneste kontrol fra %[2]s for denne pull-anmodning.
issue.action.ready_for_review = <b>@%[1]s</b> markerede denne pull-anmodning klar til gennemgang.
issue.action.new = <b>@%[1]s</b> oprettede #%[2]d.
issue.in_tree_path = I %s:
release.new.subject = %s i %s udgivet
release.new.text = <b>@%[1]s</b> udgivet %[2]s i %[3]s
release.title = Title: %s
release.note = Note:
release.downloads = Downloads:
release.download.zip = Kildekode (ZIP)
release.download.targz = Kildekode (TAR.GZ)
repo.transfer.subject_to = %s ønsker at overføre depotet "%s" til %s
repo.transfer.subject_to_you = %s ønsker at overføre depotet "%s" til dig
repo.transfer.to_you = dig
repo.transfer.body = For at acceptere eller afvise det, besøg %s eller ignorer det.
repo.collaborator.added.subject = %s føjede dig til %s som samarbejdspartner
repo.collaborator.added.text = Du er blevet tilføjet som samarbejdspartner til depotet:
team_invite.subject = %[1]s har inviteret dig til at deltage i %[2]s organisationen
team_invite.text_1 = %[1]s har inviteret dig til at deltage i teamet %[2]s i organisationen %[3]s.
team_invite.text_2 = Klik venligst på følgende link for at blive medlem af holdet:
team_invite.text_3 = Note: Denne invitation var beregnet til %[1]s. Hvis du ikke forventede denne invitation, kan du ignorere denne e-mail.
[modal]
yes = Ja
no = Nej
confirm = Bekærft
cancel = Annuller
modify = Updatere
[form]
UserName = Brugernavn
FullName = Fulde navn
Description = Beskrivelse
Pronouns = Stedord
Biography = Biografi
Website = Websted
Location = Lokation
RepoName = Depot navn
Email = E-mailadresse
Password = Adgangskode
Retype = Bekræft adgangskode
PayloadUrl = Payload URL
TeamName = Holdnavn
AuthName = Autorisationsnavn
AdminEmail = Admin email
To = Gren navn
AccessToken = Adgangstoken
NewBranchName = Nyt gren navn
CommitSummary = Commit oversigt
CommitMessage = Commit besked
CommitChoice = Commit valg
TreeName = Fil sti
Content = Indhold
SSPISeparatorReplacement = Separator
SSPIDefaultLanguage = Standard sprog
require_error = ` må ikke være tomt.`
alpha_dash_error = ` bør kun indeholde alfanumeriske, bindestreg ("-") og understregningstegn ("_").`
alpha_dash_dot_error = ` bør kun indeholde alfanumeriske tegn, bindestreg ("-"), understregning ("_") og prik ("".").`
git_ref_name_error = ` skal være et veludformet Git-referencenavn.`
size_error = ` skal være størrelse %s.`
min_size_error = ` skal indeholde mindst %s tegn.`
email_error = ` er ikke en gyldig e-mailadresse.`
url_error = `"%s" er ikke en gyldig URL.`
include_error = ` skal indeholde understreng "%s".`
glob_pattern_error = ` globmønster er ugyldigt: %s.`
regex_pattern_error = ` regex-mønster er ugyldigt: %s.`
invalid_group_team_map_error = ` mapping er ugyldig: %s`
unknown_error = Ukendt fejl:
captcha_incorrect = CAPTCHA-koden er forkert.
password_not_match = Adgangskoderne stemmer ikke overens.
lang_select_error = Vælg et sprog fra listen.
username_been_taken = Brugernavnet er allerede taget.
username_change_not_local_user = Ikke-lokale brugere må ikke ændre deres brugernavn.
repo_name_been_taken = Depotnavnet er allerede brugt.
repository_force_private = Tving Privat er aktiveret: private depoter kan ikke gøres offentlige.
repository_files_already_exist = Der findes allerede filer for dette depot. Kontakt systemadministratoren.
repository_files_already_exist.delete = Der findes allerede filer for dette depot. Du skal slette dem.
visit_rate_limit = Fjernbesøg adresseret takstbegrænsning.
2fa_auth_required = Fjernbesøg krævede godkendelse af to faktorer.
org_name_been_taken = Organisationsnavnet er allerede taget.
team_name_been_taken = Holdnavnet er allerede taget.
team_no_units_error = Tillad adgang til mindst én depotsektion.
email_been_used = E-mailadressen er allerede brugt.
email_invalid = E-mailadressen er ugyldig.
openid_been_used = OpenID-adressen "%s" er allerede brugt.
password_complexity = Adgangskoden opfylder ikke kompleksitetskravene:
password_lowercase_one = Mindst ét lille bogstav
password_uppercase_one = Mindst ét stort tegn
password_digit_one = Mindst ét ciffer
enterred_invalid_repo_name = Det depotnavn, du indtastede, er forkert.
enterred_invalid_org_name = Det organisationsnavn, du har indtastet, er forkert.
enterred_invalid_owner_name = Det nye ejernavn er ikke gyldigt.
enterred_invalid_password = Den adgangskode, du indtastede, er forkert.
unset_password = Login-brugeren har ikke angivet adgangskoden.
user_not_exist = Brugeren eksisterer ikke.
team_not_exist = Holdet eksisterer ikke.
last_org_owner = Du kan ikke fjerne den sidste bruger fra "ejere"-teamet. Der skal være mindst én ejer for en organisation.
duplicate_invite_to_team = Brugeren var allerede inviteret som et holdmedlem.
organization_leave_success = Du har forladt organisationen %s.
invalid_ssh_key = Kan ikke bekræfte din SSH-nøgle: %s
invalid_gpg_key = Kan ikke bekræfte din GPG-nøgle: %s
invalid_ssh_principal = Ugyldig principal: %s
unable_verify_ssh_key = Kan ikke bekræfte SSH-nøglen, dobbelttjek den for fejl.
auth_failed = Godkendelse mislykkedes: %v
still_own_repo = Din konto ejer et eller flere depoter, slet eller overfør dem først.
still_has_org = Din konto er medlem af en eller flere organisationer, forlad dem først.
still_own_packages = Din konto ejer en eller flere pakker, slet dem først.
org_still_own_packages = Denne organisation ejer stadig en eller flere pakker, slet dem først.
target_branch_not_exist = Gren målet eksisterer ikke.
admin_cannot_delete_self = Du kan ikke slette dig selv, når du er administrator. Fjern venligst dine administratorrettigheder først.
required_prefix = Input skal starte med "%s"
username_error = ` kan kun indeholde alfanumeriske tegn ("0-9","a-z","A-Z"), bindestreg ("-"), understregning ("_") og prik ("."). Det kan ikke begynde eller slutte med ikke-alfanumeriske tegn, og på hinanden følgende ikke-alfanumeriske tegn er også forbudt.`
max_size_error = ` må højst indeholde %s tegn.`
repository_files_already_exist.adopt_or_delete = Der findes allerede filer for dette depot. Enten adopter dem eller slet dem.
org_still_own_repo = Denne organisation ejer stadig et eller flere depoter, slet eller overfør dem først.
username_error_no_dots = ` kan kun indeholde alfanumeriske tegn ("0-9","a-z","A-Z"), bindestreg ("-") og understregning ("_"). Det kan ikke begynde eller slutte med ikke-alfanumeriske tegn, og på hinanden følgende ikke-alfanumeriske tegn er også forbudt.`
username_password_incorrect = Brugernavn eller adgangskode er forkert.
repository_files_already_exist.adopt = Filer findes allerede for dette depot og kan kun adopteres.
password_special_one = Mindst ét specialtegn (tegnsætning, parenteser, anførselstegn osv.)
unsupported_login_type = Login typen understøttes ikke for at slette kontoen.
cannot_add_org_to_team = En organisation kan ikke tilføjes som et holdmedlem.
must_use_public_key = Nøglen du har angivet er en privat nøgle. Lad være med at uploade din private nøgle nogen steder. Brug din offentlige nøgle i stedet.
[user]
change_avatar = Skift din avatar…
joined_on = Tilmeldte sig den %s
repositories = Depoter
activity = Offentlig aktivitet
followers.title.one = Følger
followers.title.few = Følgere
following.title.one = Følger
following.title.few = Følger
followers_one = %d følger
followers_few = %d følgere
following_one = %d følger
following_few = %d følger
follow = Følg
unfollow = Fjern følg
block_user = Bloker bruger
block_user.detail = Bemærk venligst, at blokering af en bruger har andre effekter, såsom:
block_user.detail_1 = I vil holde op med at følge hinanden og vil ikke være i stand til at følge hinanden.
block_user.detail_2 = Denne bruger vil ikke være i stand til at interagere med de depoter, du ejer, eller de problemer og kommentarer, du har oprettet.
block_user.detail_3 = I vil ikke være i stand til at tilføje hinanden som depot-samarbejdspartnere.
follow_blocked_user = Du kan ikke følge denne bruger, fordi du har blokeret denne bruger, eller denne bruger har blokeret dig.
starred = Stjernemarkerede depoter
watched = Overvågede depoter
code = Kode
overview = Oversigt
block = Block
user_bio = Biografi
email_visibility.limited = Din e-mailadresse er synlig for alle godkendte brugere
show_on_map = Vis dette sted på et kort
settings = Brugerindstillinger
public_activity.visibility_hint.admin_public = Denne aktivitet er synlig for alle, men som administrator kan du også se interaktioner i private rum.
public_activity.visibility_hint.self_private = Din aktivitet er kun synlig for dig og instans-administratorerne. <a href="%s">Konfigurer</a>.
public_activity.visibility_hint.admin_private = Denne aktivitet er synlig for dig, fordi du er administrator, men brugeren ønsker, at den forbliver privat.
form.name_reserved = Brugernavnet "%s" er reserveret.
form.name_pattern_not_allowed = Mønsteret "%s" er ikke tilladt i et brugernavn.
form.name_chars_not_allowed = Brugernavnet "%s" indeholder ugyldige tegn.
unblock = Fjern blokering
projects = Projekter
disabled_public_activity = Denne bruger har deaktiveret den offentlige synlighed af aktiviteten.
public_activity.visibility_hint.self_public = Din aktivitet er synlig for alle, undtagen interaktioner i private rum. <a href="%s">Konfigurer</a>.
public_activity.visibility_hint.self_private_profile = Din aktivitet er kun synlig for dig og instans-administratorerne, fordi din profil er privat. <a href="%s">Konfigurer</a>.
[settings]
profile = Profil
account = Konto
appearance = Udseende
password = Adgangskode
security = Sikkerhed
avatar = Avatar
ssh_gpg_keys = SSH / GPG nøgler
applications = Applikationer
orgs = Organisationer
repos = Depoter
delete = Slet konto
twofa = To-faktor-godkendelse (TOTP)
organization = Organisationer
uid = UID
webauthn = To-faktor-godkendelse (sikkerhedsnøgler)
blocked_users = Blokerede brugere
public_profile = Offentlig profil
location_placeholder = Del din omtrentlige placering med andre
password_username_disabled = Ikke-lokale brugere må ikke ændre deres brugernavn. Kontakt venligst din webstedsadministrator for flere detaljer.
full_name = Fulde navn
website = Websted
location = Lokation
pronouns = Stedord
pronouns_custom = Brugerdefineret
pronouns_unspecified = Uspecificeret
update_theme = Skift tema
update_language = Skift sprog
update_language_success = Sproget er blevet opdateret.
update_profile_success = Din profil er blevet opdateret.
change_username = Dit brugernavn er blevet ændret.
change_username_redirect_prompt = Det gamle brugernavn vil omdirigere, indtil nogen gør krav på det.
continue = Fortsæt
cancel = Annuller
language = Sprog
language.title = Standard sprog
language.description = Dette sprog gemmes på din konto og bruges som standard, når du logger ind.
ui = Tema
additional_repo_units_hint = Foreslå at aktivere yderligere depotenheder
additional_repo_units_hint_description = Vis et "Aktiver mere"-tip for depoter, der ikke har alle tilgængelige enheder aktiveret.
update_hints = Opdater tips
hints = Tips
update_hints_success = Tips er blevet opdateret.
hidden_comment_types = Skjulte kommentartyper
hidden_comment_types.ref_tooltip = Kommentarer, hvor dette problem blev refereret fra en anden problem/commit/…
hidden_comment_types.issue_ref_tooltip = Kommentarer, hvor brugeren ændrer grenen/taget, der er knyttet til problemet
comment_type_group_reference = Reference
comment_type_group_label = Etiket
comment_type_group_milestone = Milepæl
comment_type_group_assignee = Udpegningsmodtager
comment_type_group_title = Title
comment_type_group_branch = Gren
comment_type_group_time_tracking = Tidsregistrering
comment_type_group_deadline = Tidsfrist
comment_type_group_dependency = Dependency
comment_type_group_lock = Lås status
comment_type_group_review_request = Gennemgå anmodning
comment_type_group_pull_request_push = Tilføjet commits
comment_type_group_project = Projekt
comment_type_group_issue_ref = Problem henvisning
privacy = Privatliv
keep_activity_private = Skjul aktivitet fra profilsiden
lookup_avatar_by_mail = Slå avatar up efter e-mailadresse
enable_custom_avatar = Brug tilpasset avatar
delete_current_avatar = Slet nuværende avatar
uploaded_avatar_not_a_image = Den uploadede fil er ikke et billede.
update_avatar_success = Din avatar er blevet opdateret.
update_user_avatar_success = Brugerens avatar er blevet opdateret.
change_password = Skift adgangskode
update_password = Opdater adgangskode
old_password = Nuværende adgangskode
new_password = Ny adgangskode
retype_new_password = Bekræft ny adgangskode
password_incorrect = Den aktuelle adgangskode er forkert.
password_change_disabled = Ikke-lokale brugere kan ikke opdatere deres adgangskode via Forgejo-webgrænsefladen.
manage_emails = Administrer e-mailadresser
manage_themes = Standard tema
manage_openid = OpenID-adresser
theme_desc = Dette tema vil blive brugt til webgrænsefladen, når du er logget ind.
primary = Primær
activated = Aktiveret
requires_activation = Kræver aktivering
primary_email = Gør til primær
activate_email = Send aktivering
activations_pending = Aktiveringer afventer
can_not_add_email_activations_pending = Der er en afventende aktivering, prøv igen om et par minutter, hvis du vil tilføje en ny e-mail.
delete_email = Slet
email_deletion = Fjern e-mailadresse
email_deletion_success = E-mailadressen er blevet fjernet.
theme_update_success = Dit tema blev opdateret.
theme_update_error = Det valgte tema findes ikke.
openid_deletion = Fjern OpenID-adresse
openid_deletion_desc = Fjernelse af denne OpenID-adresse fra din konto vil forhindre dig i at logge ind med den. Fortsætte?
openid_deletion_success = OpenID-adressen er blevet fjernet.
add_new_email = Tilføj e-mailadresse
add_new_openid = Tilføj ny OpenID URI
language.localization_project = Hjælp os med at oversætte Forgejo til dit sprog! <a href="%s">Få flere oplysninger</a>.
update_language_not_found = Sprog "%s" er ikke tilgængeligt.
hidden_comment_types_description = Kommentartyper, der er markeret her, vil ikke blive vist på problemsider. Hvis du f.eks. markerer "Etiket", fjernes alle "<bruger> tilføjede/fjernede <etiket>" kommentarer.
update_profile = Opdater profil
change_username_prompt = Note: Ændring af dit brugernavn ændrer også din konto-URL.
biography_placeholder = Fortæl andre lidt om dig selv! (Markdown understøttes)
profile_desc = Styr, hvordan din profil vises til andre brugere. Din primære e-mailadresse vil blive brugt til meddelelser, gendannelse af adgangskode og webbaserede Git-operationer.
saved_successfully = Dine indstillinger blev gemt.
keep_activity_private.description = Din <a href="%s">offentlige aktivitet</a> vil kun være synlig for dig og instans-administratorerne.
email_desc = Din primære e-mailadresse vil blive brugt til meddelelser, gendannelse af adgangskode og, forudsat at den ikke er skjult, webbaserede Git-operationer.
uploaded_avatar_is_too_big = Den uploadede filstørrelse (%d KiB) overstiger den maksimale størrelse (%d KiB).
email_deletion_desc = E-mailadressen og relaterede oplysninger vil blive fjernet fra din konto. Git commits af denne e-mailadresse forbliver uændret. Fortsætte?
choose_new_avatar = Vælg ny avatar
update_avatar = Opdater avatar
change_password_success = Din adgangskode er blevet opdateret. Log ind med din nye adgangskode fra nu af.
add_email = Tilføj e-mailadresse
add_openid = Tilføj OpenID URI
add_email_confirmation_sent = En bekræftelses-e-mail er blevet sendt til "%s". For at bekræfte din e-mailadresse, tjek venligst din indbakke og følg det medfølgende link inden for de næste %s.
add_openid_success = Den nye OpenID-adresse er blevet tilføjet.
keep_email_private = Skjul e-mailadresse
openid_desc = OpenID lader dig uddelegere godkendelse til en ekstern udbyder.
manage_ssh_keys = Administrer SSH-nøgler
manage_ssh_principals = Administrer SSH-certifikatprincippere
manage_gpg_keys = Administrer GPG-nøgler
add_key = Tilføj nøgle
ssh_desc = Disse offentlige SSH-nøgler er knyttet til din konto. De tilsvarende private nøgler giver fuld adgang til dine depoter. SSH-nøgler, der er blevet bekræftet, kan bruges til at bekræfte SSH-signerede Git-commits.
principal_desc = Disse SSH-certifikatprincipper er knyttet til din konto og giver fuld adgang til dine depoter.
ssh_helper = <strong>Har du brug for hjælp?</strong> Se vejledningen til at <a href="%s">oprette dine egne SSH-nøgler</a> eller løse <a href="%s">almindelige problemer</a> a> du kan støde på når du bruger SSH.
gpg_helper = <strong>Har du brug for hjælp?</strong> Se vejledningen <a href="%s">om GPG</a>.
key_content_gpg_placeholder = Begynder med "-----BEGIN PGP PUBLIC KEY BLOCK-----"
add_new_principal = Tilføj principal
ssh_key_been_used = Denne SSH-nøgle er allerede blevet tilføjet til serveren.
ssh_key_name_used = En SSH-nøgle med samme navn findes allerede på din konto.
ssh_principal_been_used = Denne principal er allerede blevet tilføjet til serveren.
gpg_key_id_used = Der findes allerede en offentlig GPG-nøgle med samme id.
gpg_no_key_email_found = Denne GPG-nøgle matcher ikke nogen aktiveret e-mail-adresse tilknyttet din konto. Det kan stadig tilføjes, hvis du underskriver det medfølgende token.
gpg_key_matched_identities = Matchede identiteter:
gpg_key_verified = Verificeret nøgle
gpg_key_verified_long = Nøglen er blevet bekræftet med et token og kan bruges til at bekræfte commits, der matcher alle aktiverede e-mailadresser for denne bruger ud over eventuelle matchede identiteter for denne nøgle.
gpg_key_verify = Bekræft
gpg_invalid_token_signature = Den medfølgende GPG-nøgle, signatur og token stemmer ikke overens, eller token er forældet.
gpg_token_required = Du skal angive en underskrift for nedenstående token
gpg_token = Token
gpg_token_signature = Pansret GPG-signatur
key_signature_gpg_placeholder = Begynder med "-----BEGIN PGP SIGNATURE-----"
verify_gpg_key_success = GPG-nøglen "%s" er blevet bekræftet.
ssh_key_verified = Verificeret nøgle
ssh_token_required = Du skal angive en underskrift for nedenstående token
ssh_token = Token
ssh_token_help = Du kan generere en signatur ved at bruge:
ssh_token_signature = Pansret SSH signatur
key_signature_ssh_placeholder = Begynder med "-----BEGIN SSH SIGNATURE-----"
verify_ssh_key_success = SSH-nøglen "%s" er blevet bekræftet.
subkeys = Undernøgler
key_name = Nøglenavn
key_id = Nøgle ID
key_content = Indhold
principal_content = Indhold
add_key_success = SSH-nøglen "%s" er blevet tilføjet.
add_principal_success = SSH-certifikatprincippet "%s" er blevet tilføjet.
delete_key = Slet
ssh_key_deletion = Slet SSH-nøgle
gpg_key_deletion = Slet GPG-nøglen
ssh_principal_deletion = Slet SSH Certificate Principal
gpg_key_deletion_desc = Fjernelse af en GPG-nøgle afbekræfter commits, der er underskrevet af den. Fortsætte?
ssh_principal_deletion_desc = Fjernelse af en SSH Certificate Principal tilbagekalder dens adgang til din konto. Fortsætte?
ssh_key_deletion_success = SSH-nøglen er blevet fjernet.
ssh_principal_deletion_success = Principal er blevet fjernet.
added_on = Tilføjet den %s
valid_until_date = Gyldig indtil %s
last_used = Sidst brugt på
no_activity = Ingen nylig aktivitet
can_read_info = Læs
can_write_info = Skriv
token_state_desc = Dette token er blevet brugt inden for de sidste 7 dage
principal_state_desc = Denne principal er blevet brugt inden for de sidste 7 dage
show_openid = Vis på profil
hide_openid = Skjul fra profil
ssh_externally_managed = Denne SSH-nøgle administreres eksternt for denne bruger
manage_access_token = Adgangstoken
generate_new_token = Generer nyt token
tokens_desc = Disse tokens giver adgang til din konto ved hjælp af Forgejo API.
token_name = Token navn
generate_token = Generer token
generate_token_success = Dit nye token er blevet genereret. Kopier den nu, da den ikke vises igen.
delete_token = Slet
access_token_deletion = Slet adgangstoken
access_token_deletion_desc = Sletning af et token vil tilbagekalde adgangen til din konto for applikationer, der bruger den. Dette kan ikke fortrydes. Fortsætte?
repo_and_org_access = Depot og organisationsadgang
permissions_public_only = Kun offentlig
permissions_access_all = Alle (offentlige, private og begrænsede)
select_permissions = Vælg tilladelser
permission_no_access = Ingen adgang
permission_read = Læs
permission_write = Læs og skriv
permissions_list = Tilladelser:
manage_oauth2_applications = Administrer OAuth2-applikationer
edit_oauth2_application = Rediger OAuth2-applikation
add_email_success = Den nye e-mailadresse er blevet tilføjet.
key_content_ssh_placeholder = Begynder med "ssh-ed25519", "ssh-rsa", "ecdsa-sha2-nistp256", "ecdsa-sha2-nistp384", "ecdsa-sha2-nistp521", "sk-ecdsa-sha2-nistp256@openssh.com", eller "sk-ssh-ed25519@openssh.com"
gpg_key_matched_identities_long = De indlejrede identiteter i denne nøgle matcher de følgende aktiverede e-mailadresser for denne bruger. Commits, der matcher disse e-mailadresser, kan bekræftes med denne nøgle.
gpg_key_deletion_success = GPG-nøglen er blevet fjernet.
email_preference_set_success = E-mail-præference er blevet indstillet.
keep_email_private_popup = Dette vil skjule din e-mailadresse fra din profil. Det vil ikke længere være standard for commits foretaget via webgrænsefladen, såsom filupload og redigeringer, og vil ikke blive brugt til merge commits. I stedet kan en speciel adresse %s bruges til at knytte commits til din konto. Bemærk, at ændring af denne mulighed ikke vil påvirke eksisterende commits.
gpg_desc = Disse offentlige GPG-nøgler er knyttet til din konto og bruges til at bekræfte dine commits. Opbevar dine private nøgler sikkert, da de giver dig mulighed for at underskrive commits med din identitet.
gpg_token_help = Du kan generere en signatur ved at bruge:
ssh_key_verified_long = Nøglen er blevet bekræftet med et token og kan bruges til at bekræfte commits, der matcher enhver aktiveret e-mail-adresse for denne bruger.
ssh_key_deletion_desc = Fjernelse af en SSH-nøgle tilbagekalder dens adgang til din konto. Fortsætte?
ssh_signonly = SSH er i øjeblikket deaktiveret, så disse nøgler bruges kun til bekræftelse af commit signatur.
at_least_one_permission = Du skal vælge mindst én tilladelse for at oprette et token
ssh_key_verify = Bekræft
ssh_invalid_token_signature = Den angivne SSH-nøgle, signatur eller token stemmer ikke overens, eller token er forældet.
add_gpg_key_success = GPG-nøglen "%s" er blevet tilføjet.
valid_forever = Gyldig for evigt
ssh_disabled = SSH er deaktiveret
key_state_desc = Denne nøgle er blevet brugt inden for de sidste 7 dage
generate_token_name_duplicate = <strong>%s</strong> er allerede blevet brugt som applikationsnavn. Brug venligst en ny.
delete_token_success = Tokenet er blevet slettet. Applikationer, der bruger den, har ikke længere adgang til din konto.
access_token_desc = Valgte tokentilladelser begrænser kun autorisation til de tilsvarende <a href="%[1]s" target="_blank">API</a>-ruter. Læs <a href="%[2]s" target="_blank">dokumentationen</a> for at få flere oplysninger.
oauth2_applications_desc = OAuth2-applikationer gør det muligt for din tredjepartsapplikation at godkende brugere sikkert i denne Forgejo-instans.
remove_oauth2_application = Slet OAuth2-applikation
remove_oauth2_application_desc = Sletning af en OAuth2-applikation vil tilbagekalde adgangen til alle signerede adgangstokens. Vil du fortsætte?
remove_oauth2_application_success = Ansøgningen er blevet slettet.
create_oauth2_application = Opret en ny OAuth2-applikation
create_oauth2_application_button = Opret applikation
create_oauth2_application_success = Du har oprettet en ny OAuth2-applikation.
update_oauth2_application_success = Du har opdateret OAuth2-applikationen.
oauth2_application_name = Applikationsnavn
oauth2_redirect_uris = Omdiriger URI'er. Brug venligst en ny linje for hver URI.
save_application = Gem
oauth2_client_id = Klient ID
oauth2_client_secret = Klient hemmelighed
oauth2_regenerate_secret = Genskab hemmeligheden
oauth2_regenerate_secret_hint = Har du mistet din hemmelighed?
oauth2_client_secret_hint = Hemmeligheden vil ikke blive vist igen, når du forlader eller opdaterer denne side. Sørg for, at du har gemt den.
oauth2_application_edit = Redigere
oauth2_confidential_client = Fortrolig klient. Vælg for apps, der holder hemmeligheden fortrolig, såsom webapps. Vælg ikke for indbyggede apps, herunder desktop- og mobilapps.

View file

@ -814,7 +814,7 @@ manage_emails=E-Mail-Adressen verwalten
manage_themes=Standard-Theme manage_themes=Standard-Theme
manage_openid=OpenID-Adressen manage_openid=OpenID-Adressen
email_desc=Deine primäre E-Mail-Adresse wird für Benachrichtigungen, Passwort-Wiederherstellung und, sofern sie nicht versteckt ist, web-basierte Git-Operationen verwendet. email_desc=Deine primäre E-Mail-Adresse wird für Benachrichtigungen, Passwort-Wiederherstellung und, sofern sie nicht versteckt ist, web-basierte Git-Operationen verwendet.
theme_desc=Dies wird dein Standard-Theme auf der Seite sein. theme_desc=Dieses Thema wird für die Weboberfläche verwendet, wenn du angemeldet bist.
primary=Primär primary=Primär
activated=Aktiviert activated=Aktiviert
requires_activation=Erfordert Aktivierung requires_activation=Erfordert Aktivierung
@ -1097,7 +1097,7 @@ issue_labels=Labels
issue_labels_helper=Wähle eine Label-Sammlung issue_labels_helper=Wähle eine Label-Sammlung
license=Lizenz license=Lizenz
license_helper=Wähle eine Lizenz license_helper=Wähle eine Lizenz
license_helper_desc=Eine Lizenz regelt, was andere mit deinem Code tun (oder nicht tun) können. Unsicher, welches für dein Projekt die Richtige ist? Siehe <a target="_blank" rel="noopener noreferrer" href="%s">Choose a license.</a> license_helper_desc=Eine Lizenz regelt, was andere mit deinem Code tun (oder nicht tun) können. Unsicher, welches für dein Projekt die Richtige ist? Siehe <a target="_blank" rel="noopener noreferrer" href="%s">Choose a license</a>.
readme=README readme=README
readme_helper=Wähle eine README-Vorlage readme_helper=Wähle eine README-Vorlage
readme_helper_desc=Hier kannst du eine komplette Beschreibung für dein Projekt schreiben. readme_helper_desc=Hier kannst du eine komplette Beschreibung für dein Projekt schreiben.
@ -2490,8 +2490,8 @@ settings.archive.text=Durch das Archivieren wird ein Repo vollständig schreibge
settings.archive.success=Das Repo wurde erfolgreich archiviert. settings.archive.success=Das Repo wurde erfolgreich archiviert.
settings.archive.error=Beim Versuch, das Repository zu archivieren, ist ein Fehler aufgetreten. Weitere Details finden sich im Log. settings.archive.error=Beim Versuch, das Repository zu archivieren, ist ein Fehler aufgetreten. Weitere Details finden sich im Log.
settings.archive.error_ismirror=Du kannst kein gespiegeltes Repo archivieren. settings.archive.error_ismirror=Du kannst kein gespiegeltes Repo archivieren.
settings.archive.branchsettings_unavailable=Branch-Einstellungen sind nicht verfügbar wenn das Repo archiviert ist. settings.archive.branchsettings_unavailable=Branch-Einstellungen sind nicht verfügbar in archivierten Repos.
settings.archive.tagsettings_unavailable=Tag Einstellungen sind nicht verfügbar, wenn das Repo archiviert wurde. settings.archive.tagsettings_unavailable=Tag-Einstellungen sind nicht verfügbar in archivierten Repos.
settings.unarchive.button=Archivierung zurücksetzen settings.unarchive.button=Archivierung zurücksetzen
settings.unarchive.header=Archivierung dieses Repositorys zurücksetzen settings.unarchive.header=Archivierung dieses Repositorys zurücksetzen
settings.unarchive.text=Durch das Aufheben der Archivierung kann das Repo wieder Commits und Pushes sowie neue Issues und Pull-Requests empfangen. settings.unarchive.text=Durch das Aufheben der Archivierung kann das Repo wieder Commits und Pushes sowie neue Issues und Pull-Requests empfangen.
@ -2690,7 +2690,7 @@ error.csv.too_large=Diese Datei kann nicht gerendert werden, da sie zu groß ist
error.csv.unexpected=Diese Datei kann nicht gerendert werden, da sie ein unerwartetes Zeichen in Zeile %d und Spalte %d enthält. error.csv.unexpected=Diese Datei kann nicht gerendert werden, da sie ein unerwartetes Zeichen in Zeile %d und Spalte %d enthält.
error.csv.invalid_field_count=Diese Datei kann nicht gerendert werden, da sie eine falsche Anzahl an Feldern in Zeile %d hat. error.csv.invalid_field_count=Diese Datei kann nicht gerendert werden, da sie eine falsche Anzahl an Feldern in Zeile %d hat.
rss.must_be_on_branch = Du musst auf einem Branch sein, um einen RSS-Feed zu haben. rss.must_be_on_branch = Du musst auf einem Branch sein, um einen RSS-Feed zu haben.
new_repo_helper = Ein Repository enthält alle Projektdateien inklusive der Revisionshistorie. Bereits woanders gehostet? <a href="%s">Repository migrieren.</a> new_repo_helper = Ein Repository enthält alle Projektdateien inklusive der Revisionshistorie. Bereits woanders gehostet? <a href="%s">Repository migrieren</a>.
issues.comment.blocked_by_user = Du kannst kein Kommentar für dieses Issue erstellen, weil du vom Repository-Besitzer oder dem Autoren des Issues blockiert wurdest. issues.comment.blocked_by_user = Du kannst kein Kommentar für dieses Issue erstellen, weil du vom Repository-Besitzer oder dem Autoren des Issues blockiert wurdest.
clone_in_vscodium = In VSCodium klonen clone_in_vscodium = In VSCodium klonen
settings.units.add_more = Mehr aktivieren settings.units.add_more = Mehr aktivieren
@ -2704,7 +2704,7 @@ settings.add_collaborator_blocked_them = Der Mitarbeiter konnte nicht hinzugefü
settings.wiki_rename_branch_main = Den Wiki-Branch-Namen normalisieren settings.wiki_rename_branch_main = Den Wiki-Branch-Namen normalisieren
settings.enter_repo_name = Gib den Besitzer- und den Repository-Namen genau wie angezeigt ein: settings.enter_repo_name = Gib den Besitzer- und den Repository-Namen genau wie angezeigt ein:
settings.wiki_branch_rename_success = Der Branch-Name des Repository-Wikis wurde erfolgreich normalisiert. settings.wiki_branch_rename_success = Der Branch-Name des Repository-Wikis wurde erfolgreich normalisiert.
settings.archive.mirrors_unavailable = Spiegel sind nicht verfügbar, wenn das Repo archiviert ist. settings.archive.mirrors_unavailable = Spiegel sind nicht verfügbar in archivierten Repos.
pulls.blocked_by_user = Du kannst keinen Pull-Request in diesem Repository erstellen, weil du vom Repository-Besitzer blockiert wurdest. pulls.blocked_by_user = Du kannst keinen Pull-Request in diesem Repository erstellen, weil du vom Repository-Besitzer blockiert wurdest.
settings.add_collaborator_blocked_our = Der Mitarbeiter konnte nicht hinzugefügt werden, weil der Repository-Besitzer ihn blockiert hat. settings.add_collaborator_blocked_our = Der Mitarbeiter konnte nicht hinzugefügt werden, weil der Repository-Besitzer ihn blockiert hat.
issues.blocked_by_user = Du kannst kein Issue in diesem Repository erstellen, weil du vom Repository-Besitzer blockiert wurdest. issues.blocked_by_user = Du kannst kein Issue in diesem Repository erstellen, weil du vom Repository-Besitzer blockiert wurdest.
@ -3686,12 +3686,12 @@ conan.registry=Diese Registry über die Kommandozeile einrichten:
conan.install=Um das Paket mit Conan zu installieren, führe den folgenden Befehl aus: conan.install=Um das Paket mit Conan zu installieren, führe den folgenden Befehl aus:
conda.registry=Richte diese Registry als Conda-Repository in deiner <code>.condarc</code>-Datei ein: conda.registry=Richte diese Registry als Conda-Repository in deiner <code>.condarc</code>-Datei ein:
conda.install=Um das Paket mit Conda zu installieren, führe den folgenden Befehl aus: conda.install=Um das Paket mit Conda zu installieren, führe den folgenden Befehl aus:
container.details.type=Container-Image Typ container.details.type=Abbildtyp
container.details.platform=Plattform container.details.platform=Plattform
container.pull=Downloade das Container-Image aus der Kommandozeile: container.pull=Downloade das Container-Image aus der Kommandozeile:
container.digest=Digest container.digest=Digest
container.multi_arch=Betriebsystem / Architektur container.multi_arch=Betriebsystem / Architektur
container.layers=Container-Image Ebenen container.layers=Abbildebenen
container.labels=Labels container.labels=Labels
container.labels.key=Schlüssel container.labels.key=Schlüssel
container.labels.value=Wert container.labels.value=Wert

View file

@ -2246,6 +2246,7 @@ settings.pulls_desc = Enable repository pull requests
settings.pulls.ignore_whitespace = Ignore whitespace for conflicts settings.pulls.ignore_whitespace = Ignore whitespace for conflicts
settings.pulls.enable_autodetect_manual_merge = Enable autodetect manual merge (Note: In some special cases, misjudgments can occur) settings.pulls.enable_autodetect_manual_merge = Enable autodetect manual merge (Note: In some special cases, misjudgments can occur)
settings.pulls.allow_rebase_update = Enable updating pull request branch by rebase settings.pulls.allow_rebase_update = Enable updating pull request branch by rebase
settings.default_update_style_desc=Default update style used for updating pull requests that are behind the base branch.
settings.pulls.default_delete_branch_after_merge = Delete pull request branch after merge by default settings.pulls.default_delete_branch_after_merge = Delete pull request branch after merge by default
settings.pulls.default_allow_edits_from_maintainers = Allow edits from maintainers by default settings.pulls.default_allow_edits_from_maintainers = Allow edits from maintainers by default
settings.releases_desc = Enable repository releases settings.releases_desc = Enable repository releases

View file

@ -319,7 +319,7 @@ default_keep_email_private=Piilota sähköpostiosoitteet oletuksena
default_keep_email_private.description=Piilota oletusarvoisesti uusien käyttäjätilien sähköpostiosoitteet estääksesi tietojen vuotamisen rekisteröinnin yhteydessä. default_keep_email_private.description=Piilota oletusarvoisesti uusien käyttäjätilien sähköpostiosoitteet estääksesi tietojen vuotamisen rekisteröinnin yhteydessä.
default_enable_timetracking=Ota ajanseuranta oletusarvoisesti käyttöön default_enable_timetracking=Ota ajanseuranta oletusarvoisesti käyttöön
default_enable_timetracking.description=Salli uusien repositorioiden aikaseurannan käyttöönotto oletusarvoisesti. default_enable_timetracking.description=Salli uusien repositorioiden aikaseurannan käyttöönotto oletusarvoisesti.
no_reply_address=Piilotettu sähköpostin verkkotunnus no_reply_address=Piilotetun sähköpostin verkkotunnus
no_reply_address_helper=Verkkotunnuksen nimi käyttäjille, joilla on piilotettu sähköpostiosoite. Esimerkiksi käyttäjätunnus 'joe' kirjataan Git-palveluun nimellä 'joe@noreply.example.org' jos piilotetun sähköpostiosoitteen arvoksi on asetettu 'noreply.example.org'. no_reply_address_helper=Verkkotunnuksen nimi käyttäjille, joilla on piilotettu sähköpostiosoite. Esimerkiksi käyttäjätunnus 'joe' kirjataan Git-palveluun nimellä 'joe@noreply.example.org' jos piilotetun sähköpostiosoitteen arvoksi on asetettu 'noreply.example.org'.
password_algorithm=Salasanan hajautusalgoritmi password_algorithm=Salasanan hajautusalgoritmi
enable_update_checker_helper_forgejo = Se tarkistaa tietyin väliajoin uusia Forgejo-versioita tutkimalla sen TXT DNS record -tietoja osoitteesta release.forgejo.org . enable_update_checker_helper_forgejo = Se tarkistaa tietyin väliajoin uusia Forgejo-versioita tutkimalla sen TXT DNS record -tietoja osoitteesta release.forgejo.org .
@ -461,6 +461,9 @@ change_unconfirmed_email = Jos annoit väärän sähköpostiosoitteen rekisterö
invalid_code_forgot_password = Vahvistuskoodisi on virheellinen tai vanhentunut. Napsauta <a href="%s">tästä</a> aloittaaksesi uuden istunnon. invalid_code_forgot_password = Vahvistuskoodisi on virheellinen tai vanhentunut. Napsauta <a href="%s">tästä</a> aloittaaksesi uuden istunnon.
openid_signin_desc = Kirjoita OpenID-URI:si. Esimerkki: alice.openid.example.org tai https://openid.example.org/alice. openid_signin_desc = Kirjoita OpenID-URI:si. Esimerkki: alice.openid.example.org tai https://openid.example.org/alice.
change_unconfirmed_email_summary = Vaihda sähköpostiosoite, johon aktivointisähköposti lähetetään. change_unconfirmed_email_summary = Vaihda sähköpostiosoite, johon aktivointisähköposti lähetetään.
reset_password_wrong_user = Olet kirjautuneena tilillä %s, mutta tilin palautuslinkki on tarkoitettu tilille %s
last_admin = Et voi poistaa viimeistä ylläpitäjää. Ylläpitäjiä tulee olla vähintään yksi.
password_pwned = Valitsemasi salasana on <a target="_blank" rel="noopener noreferrer" href="%s">varastettujen salasanojen listalla</a>, eli se on paljastanut jossain julkisessa tietovuodossa. Kokeile asettaa eri salasana, ja jos käytät samaa salasanaa muissa palveluissa, vaihda kyseinen salasana.
[mail] [mail]
view_it_on=Näytä %s view_it_on=Näytä %s
@ -629,6 +632,8 @@ following_one = %d seurataan
block_user.detail = Huomaa, että käyttäjän estämisellä on muita vaikutuksia, kuten: block_user.detail = Huomaa, että käyttäjän estämisellä on muita vaikutuksia, kuten:
show_on_map = Näytä paikka kartalla show_on_map = Näytä paikka kartalla
form.name_chars_not_allowed = Käyttäjätunnus "%s" sisältää virheellisiä merkkejä. form.name_chars_not_allowed = Käyttäjätunnus "%s" sisältää virheellisiä merkkejä.
follow_blocked_user = Et voi seurata tätä käyttäjää, koska olet estänyt kyseisen käyttäjän tai kyseinen käyttäjä on estänyt sinut.
disabled_public_activity = Käyttäjä on poistanut käytöstä toiminnan julkisen näkyvyyden.
[settings] [settings]
@ -684,7 +689,7 @@ keep_activity_private_popup=Tekee toiminnon näkyvän vain sinulle ja ylläpitä
lookup_avatar_by_mail=Hae profiilikuva sähköpostin perusteella lookup_avatar_by_mail=Hae profiilikuva sähköpostin perusteella
federated_avatar_lookup=Ulkopuolinen profiilikuvan haku federated_avatar_lookup=Ulkopuolinen profiilikuvan haku
enable_custom_avatar=Ota käyttöön mukautettu profiilikuva enable_custom_avatar=Käytä mukautettua profiilikuvaa
choose_new_avatar=Valitse uusi profiilikuva choose_new_avatar=Valitse uusi profiilikuva
update_avatar=Päivitä profiilikuva update_avatar=Päivitä profiilikuva
delete_current_avatar=Poista nykyinen profiilikuva delete_current_avatar=Poista nykyinen profiilikuva
@ -699,9 +704,9 @@ password_change_disabled=Ei-lokaalit käyttäjät eivät voi päivittää salasa
emails=Sähköposti osoitteet emails=Sähköposti osoitteet
manage_emails=Hallitse sähköpostiosoitteita manage_emails=Hallitse sähköpostiosoitteita
manage_themes=Valitse oletusteema manage_themes=Oletusteema
manage_openid=Hallitse OpenID osoitteita manage_openid=OpenID-osoitteet
theme_desc=mä on sivuston oletusteemasi. theme_desc=tä teemaa käytetään verkkosivuston käyttöliittymässä, kun olet sisäänkirjautuneena.
primary=Ensisijainen primary=Ensisijainen
activated=Aktivoitu activated=Aktivoitu
requires_activation=Vaatii aktivoinnin requires_activation=Vaatii aktivoinnin
@ -717,7 +722,7 @@ theme_update_error=Valittua teemaa ei löydy.
openid_deletion=Poista OpenID-osoite openid_deletion=Poista OpenID-osoite
openid_deletion_success=OpenID-osoite on poistettu. openid_deletion_success=OpenID-osoite on poistettu.
add_new_email=Lisää uusi sähköpostiosoite add_new_email=Lisää uusi sähköpostiosoite
add_new_openid=Lisää uusi OpenID URI add_new_openid=Lisää uusi OpenID-URI
add_email=Lisää sähköpostiosoite add_email=Lisää sähköpostiosoite
add_openid=Lisää OpenID URI add_openid=Lisää OpenID URI
add_email_success=Uusi sähköpostiosoite on lisätty. add_email_success=Uusi sähköpostiosoite on lisätty.
@ -729,14 +734,14 @@ openid_desc=OpenID mahdollistaa todentamisen delegoinnin ulkopuoliselle palvelun
manage_ssh_keys=Hallitse SSH-avaimia manage_ssh_keys=Hallitse SSH-avaimia
manage_gpg_keys=Hallitse GPG-avaimia manage_gpg_keys=Hallitse GPG-avaimia
add_key=Lisää avain add_key=Lisää avain
ssh_desc=Nämä julkiset SSH-avaimet on liitetty tiliisi. Vastaavat yksityiset avaimet antavat täyden pääsyn repoihisi. ssh_desc=Nämä julkiset SSH-avaimet on liitetty tiliisi. Vastaavat yksityiset avaimet antavat täyden pääsyn repoihisi. Vahvistettuja SSH-avaimia voi käyttää SSH-allekirjoitettujen Git-kommittien vahvistamiseen.
gpg_desc=Nämä julkiset GPG-avaimet on liitetty tiliisi. Pidä yksityiset avaimet turvassa, koska ne mahdollistavat committien todentamisen. gpg_desc=Nämä julkiset GPG-avaimet on liitetty tiliisi, ja niitä käytetään kommittien vahvistamiseen. Pidä yksityiset avaimet turvassa, koska ne mahdollistavat kommittien allekirjoittamisen sinun nimissä.
ssh_helper=<strong>Tarvitsetko apua?</strong> Tutustu GitHubin oppaaseen <a href="%s">omien SSH-avainten luonnista</a> tai <a href="%s">yleisistä ongelmista</a>, joita voit kohdata SSH:n kanssa. ssh_helper=<strong>Tarvitsetko apua?</strong> Tutustu GitHubin oppaaseen <a href="%s">omien SSH-avainten luonnista</a> tai <a href="%s">yleisistä ongelmista</a>, joita voit kohdata SSH:n kanssa.
gpg_helper=<strong>Tarvitsetko apua?</strong> Katso GitHubin opas <a href="%s">GPG</a>:stä. gpg_helper=<strong>Tarvitsetko apua?</strong> Katso GitHubin opas <a href="%s">GPG</a>:stä.
add_new_key=Lisää SSH avain add_new_key=Lisää SSH avain
add_new_gpg_key=Lisää GPG-avain add_new_gpg_key=Lisää GPG-avain
key_content_ssh_placeholder=Alkaa sanoilla 'ssh-ed25519', 'ssh-rsa', 'ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384', 'ecdsa-sha2-nistp521', 'sk-ecdsa-sha2-nistp256@openssh.com', tai 'sk-ssh-ed25519@openssh.com' key_content_ssh_placeholder=Alkaa sanoilla "ssh-ed25519", "ssh-rsa", "ecdsa-sha2-nistp256", "ecdsa-sha2-nistp384", "ecdsa-sha2-nistp521", "sk-ecdsa-sha2-nistp256@openssh.com" tai "sk-ssh-ed25519@openssh.com"
key_content_gpg_placeholder=Alkaa sanoilla '-----BEGIN PGP PUBLIC KEY BLOCK-----' key_content_gpg_placeholder=Alkaa sanoilla "-----BEGIN PGP PUBLIC KEY BLOCK-----"
ssh_key_name_used=Samanniminen SSH avain on jo olemassa tililläsi. ssh_key_name_used=Samanniminen SSH avain on jo olemassa tililläsi.
gpg_key_id_used=Julkinen GPG-avain samalla tunnuksella on jo olemassa. gpg_key_id_used=Julkinen GPG-avain samalla tunnuksella on jo olemassa.
gpg_no_key_email_found=Tämä GPG-avain ei vastaa mitään tiliisi liitettyä aktivoitua sähköpostiosoitetta. Se voidaan silti lisätä, jos allekirjoitat annetun pääsymerkin. gpg_no_key_email_found=Tämä GPG-avain ei vastaa mitään tiliisi liitettyä aktivoitua sähköpostiosoitetta. Se voidaan silti lisätä, jos allekirjoitat annetun pääsymerkin.
@ -748,7 +753,7 @@ gpg_token=Pääsymerkki
gpg_token_help=Voit luoda allekirjoituksen käyttäen: gpg_token_help=Voit luoda allekirjoituksen käyttäen:
gpg_token_code=echo "%s" | gpg -a --default-key %s --detach-sig gpg_token_code=echo "%s" | gpg -a --default-key %s --detach-sig
gpg_token_signature=Panssaroitu GPG-allekirjoitus gpg_token_signature=Panssaroitu GPG-allekirjoitus
key_signature_gpg_placeholder=Alkaa sanoilla '-----BEGIN PGP SIGNATURE-----' key_signature_gpg_placeholder=Alkaa sanoilla "-----BEGIN PGP SIGNATURE-----"
ssh_key_verified=Vahvistettu avain ssh_key_verified=Vahvistettu avain
ssh_key_verified_long=Avain on vahvistettu pääsymerkillä ja sitä voidaan käyttää todentamaan commitit, jotka vastaavat tämän käyttäjän aktivoituja sähköpostiosoitteita. ssh_key_verified_long=Avain on vahvistettu pääsymerkillä ja sitä voidaan käyttää todentamaan commitit, jotka vastaavat tämän käyttäjän aktivoituja sähköpostiosoitteita.
ssh_key_verify=Vahvista ssh_key_verify=Vahvista
@ -756,7 +761,7 @@ ssh_token_required=Sinun täytyy antaa allekirjoitus alla olevalle pääsymerkil
ssh_token=Pääsymerkki ssh_token=Pääsymerkki
ssh_token_help=Voit luoda allekirjoituksen käyttäen: ssh_token_help=Voit luoda allekirjoituksen käyttäen:
ssh_token_signature=Panssaroitu SSH-allekirjoitus ssh_token_signature=Panssaroitu SSH-allekirjoitus
key_signature_ssh_placeholder=Alkaa sanoilla '-----BEGIN SSH SIGNATURE-----' key_signature_ssh_placeholder=Alkaa sanoilla "-----BEGIN SSH SIGNATURE-----"
subkeys=Aliavaimet subkeys=Aliavaimet
key_id=Avain ID key_id=Avain ID
key_name=Avaimen nimi key_name=Avaimen nimi
@ -774,7 +779,7 @@ can_read_info=Luku
can_write_info=Kirjoitus can_write_info=Kirjoitus
show_openid=Näytä profiilissa show_openid=Näytä profiilissa
hide_openid=Piilota profiilista hide_openid=Piilota profiilista
ssh_disabled=SSH pois käytöstä ssh_disabled=SSH on pois käytöstä
manage_social=Hallitse liitettyjä sosiaalisia tilejä manage_social=Hallitse liitettyjä sosiaalisia tilejä
manage_access_token=Hallitse pääsymerkkejä manage_access_token=Hallitse pääsymerkkejä
@ -795,7 +800,7 @@ create_oauth2_application=Luo uusi OAuth2-sovellus
create_oauth2_application_button=Luo sovellus create_oauth2_application_button=Luo sovellus
oauth2_application_name=Sovelluksen nimi oauth2_application_name=Sovelluksen nimi
save_application=Tallenna save_application=Tallenna
oauth2_regenerate_secret=Luo secret uudelleen oauth2_regenerate_secret=Luo salaisuus uudelleen
oauth2_regenerate_secret_hint=Kadotitko secretin? oauth2_regenerate_secret_hint=Kadotitko secretin?
oauth2_application_edit=Muokkaa oauth2_application_edit=Muokkaa
@ -811,10 +816,10 @@ twofa_enrolled=Tiliisi on otettu käyttöön kaksivaiheinen vahvistus. Ota palau
webauthn_nickname=Nimimerkki webauthn_nickname=Nimimerkki
manage_account_links=Hallitse linkitettyjä tilejä manage_account_links=Yhdistetyt tilit
manage_account_links_desc=Nämä ulkoiset tilit on linkitetty Forgejo tiliisi. manage_account_links_desc=Nämä ulkoiset tilit on linkitetty Forgejo tiliisi.
link_account=Yhdistä tili link_account=Yhdistä tili
remove_account_link=Poista linkitetty tili remove_account_link=Poista yhdistetty tili
remove_account_link_desc=Linkitetyn tilin poistaminen peruuttaa pääsyn Forgejo-tiliisi linkitetyn tili kautta. Jatketaanko? remove_account_link_desc=Linkitetyn tilin poistaminen peruuttaa pääsyn Forgejo-tiliisi linkitetyn tili kautta. Jatketaanko?
remove_account_link_success=Linkitetty tili on poistettu. remove_account_link_success=Linkitetty tili on poistettu.
@ -854,7 +859,7 @@ location_placeholder = Jaa likimääräinen sijaintisi muiden kanssa
retype_new_password = Vahvista uusi salasana retype_new_password = Vahvista uusi salasana
create_oauth2_application_success = Loit uuden OAuth2-sovelluksen. create_oauth2_application_success = Loit uuden OAuth2-sovelluksen.
repos_none = Et omista yhtäkään repositoriota. repos_none = Et omista yhtäkään repositoriota.
visibility.limited_tooltip = Näkyvissä vain tunnistautuneille käyttäjille visibility.limited_tooltip = Näkyvissä vain kirjautuneille käyttäjille
email_notifications.disable = Poista sähköposti-ilmoitukset käytöstä email_notifications.disable = Poista sähköposti-ilmoitukset käytöstä
webauthn_register_key = Lisää turva-avain webauthn_register_key = Lisää turva-avain
blocked_users = Estetyt käyttäjät blocked_users = Estetyt käyttäjät
@ -892,6 +897,28 @@ twofa_disable = Poista kaksivaiheinen todennus käytöstä
twofa_disable_desc = Kaksivaiheisen todennuksen poistaminen asettaa tilisi aiempaa suurempaan uhkaan. Jatketaanko? twofa_disable_desc = Kaksivaiheisen todennuksen poistaminen asettaa tilisi aiempaa suurempaan uhkaan. Jatketaanko?
update_language_not_found = Kieli "%s" ei ole käytettävissä. update_language_not_found = Kieli "%s" ei ole käytettävissä.
change_username_prompt = Huomio: Käyttäjätunnuksen vaihtaminen muuttaa myös tilisi URL-osoitteen. change_username_prompt = Huomio: Käyttäjätunnuksen vaihtaminen muuttaa myös tilisi URL-osoitteen.
oauth2_client_secret_hint = Tätä salaisuutta ei näytetä uudelleen, kun olet poistunut sivulta tai päivittänyt sivun. Varmista, että olet ottanut salaisuuden talteen.
blocked_since = Estetty %s lähtien
user_unblock_success = Käyttäjän esto on poistettu.
oauth2_redirect_uris = Uudelleenohjaus-URI:t. Käytä uutta riviä (newline) jokaista URI:a kohden.
oauth2_client_secret = Asiakkaan salaisuus
verify_ssh_key_success = SSH-avain "%s" on vahvistettu.
change_username_redirect_prompt = Vanha käyttäjätunnus uudelleenohjaa, kunnes joku muu ottaa käyttäjätunnuksen käyttönsä.
uploaded_avatar_is_too_big = Lähetetyn tiedoston koko (%d KiB) ylittää enimmäiskoon (%d KiB).
ssh_key_been_used = Tämä SSH-avain on jo lisätty palvelimelle.
verify_gpg_key_success = GPG-avain "%s" on vahvistettu.
add_key_success = SSH-avain "%s" on lisätty.
add_gpg_key_success = GPG-avain "%s" on lisätty.
ssh_key_deletion_success = SSH-avain on poistettu.
valid_until_date = Kelvollinen %s asti
oauth2_client_id = Asiakkaan tunniste
email_notifications.onmention = Ilmoitus vain maininnasta
email_notifications.submit = Aseta valinta
email_notifications.andyourown = Ja omat ilmoitukset
key_state_desc = Tätä avainta on käytetty viimeisen 7 päivän aikana
oauth2_application_create_description = OAuth2-sovellukset mahdollistavat kolmannen osapuolen sovelluksen pääsyn tilillesi tässä instanssissa.
oauth2_confidential_client = Luottamuksellinen sovellus. Valitse sovelluksille, jotka pitävät salaisuuden luottamuksellisena, kuten web-sovelluksille. Älä valitse natiiveille sovelluksille mukaan lukien työpöytä- ja mobiilisovellukset.
ssh_key_deletion_desc = SSH-avaimen poistaminen kumoaa pääsyn tilillesi kyseistä avainta käyttäen. Jatketaanko?
[repo] [repo]
owner=Omistaja owner=Omistaja
@ -917,7 +944,7 @@ repo_gitignore_helper=Valitse .gitignore-mallit
issue_labels=Ongelmien tunnisteet issue_labels=Ongelmien tunnisteet
issue_labels_helper=Valitse pohja ongelmien nimilapuille. issue_labels_helper=Valitse pohja ongelmien nimilapuille.
license=Lisenssi license=Lisenssi
license_helper=Valitse lisenssitiedosto. license_helper=Valitse lisenssitiedosto
readme=README readme=README
auto_init=Alusta repo (Luo .gitignore, License ja README) auto_init=Alusta repo (Luo .gitignore, License ja README)
create_repo=Luo repo create_repo=Luo repo
@ -1316,7 +1343,7 @@ activity.new_issues_count_1=Uusi ongelma
activity.new_issues_count_n=uutta ongelmaa activity.new_issues_count_n=uutta ongelmaa
activity.new_issue_label=Avoinna activity.new_issue_label=Avoinna
activity.unresolved_conv_label=Auki activity.unresolved_conv_label=Auki
activity.published_release_label=Julkaistu activity.published_release_label=Julkaisu
activity.git_stats_pushed_1=on työntänyt activity.git_stats_pushed_1=on työntänyt
activity.git_stats_file_1=%d tiedosto activity.git_stats_file_1=%d tiedosto
activity.git_stats_file_n=%d tiedostoa activity.git_stats_file_n=%d tiedostoa
@ -1361,9 +1388,9 @@ settings.transfer.title=Siirrä omistajuus
settings.transfer_form_title=Syötä repon nimi vahvistuksena: settings.transfer_form_title=Syötä repon nimi vahvistuksena:
settings.transfer_notices_3=- Jos arkisto on yksityinen ja se siirretään yksittäiselle käyttäjälle, tämä toiminto varmistaa, että käyttäjällä on ainakin lukuoikeudet (ja muuttaa käyttöoikeuksia tarvittaessa). settings.transfer_notices_3=- Jos arkisto on yksityinen ja se siirretään yksittäiselle käyttäjälle, tämä toiminto varmistaa, että käyttäjällä on ainakin lukuoikeudet (ja muuttaa käyttöoikeuksia tarvittaessa).
settings.transfer_owner=Uusi omistaja settings.transfer_owner=Uusi omistaja
settings.wiki_delete=Poista Wiki data settings.wiki_delete=Poista wikidata
settings.wiki_delete_desc=Repon wikin data poistaminen on pysyvä eikä voi peruuttaa. settings.wiki_delete_desc=Repon wikin data poistaminen on pysyvä eikä voi peruuttaa.
settings.confirm_wiki_delete=Wiki datan poistaminen settings.confirm_wiki_delete=Poista wikidata
settings.wiki_deletion_success=Repon wiki data on poistettu. settings.wiki_deletion_success=Repon wiki data on poistettu.
settings.delete=Poista tämä repo settings.delete=Poista tämä repo
settings.delete_desc=Repon poistaminen on pysyvä eikä voi peruuttaa. settings.delete_desc=Repon poistaminen on pysyvä eikä voi peruuttaa.
@ -1384,7 +1411,7 @@ settings.webhook.body=Sisältö
settings.githook_edit_desc=Jos koukku ei ole käytössä, esitellään esimerkkisisältö. Sisällön jättäminen tyhjäksi arvoksi poistaa tämän koukun käytöstä. settings.githook_edit_desc=Jos koukku ei ole käytössä, esitellään esimerkkisisältö. Sisällön jättäminen tyhjäksi arvoksi poistaa tämän koukun käytöstä.
settings.githook_name=Koukun nimi settings.githook_name=Koukun nimi
settings.githook_content=Koukun sisältö settings.githook_content=Koukun sisältö
settings.update_githook=Päivitys koukku settings.update_githook=Päivitä koukku
settings.payload_url=Kohde URL settings.payload_url=Kohde URL
settings.http_method=HTTP-menetelmä settings.http_method=HTTP-menetelmä
settings.secret=Salaus settings.secret=Salaus
@ -1406,7 +1433,7 @@ settings.event_push_desc=Git push repoon.
settings.event_repository=Repo settings.event_repository=Repo
settings.event_repository_desc=Repo luotu tai poistettu. settings.event_repository_desc=Repo luotu tai poistettu.
settings.event_header_issue=Ongelmien tapahtumat settings.event_header_issue=Ongelmien tapahtumat
settings.event_issues=Ongelmat settings.event_issues=Muokkaus
settings.event_issues_desc=Ongelma avattu, suljettu, avattu uudelleen tai muokattu. settings.event_issues_desc=Ongelma avattu, suljettu, avattu uudelleen tai muokattu.
settings.event_issue_assign=Ongelma määritetty settings.event_issue_assign=Ongelma määritetty
settings.event_issue_assign_desc=Ongelma osoitettu tai osoitus poistettu. settings.event_issue_assign_desc=Ongelma osoitettu tai osoitus poistettu.
@ -1414,7 +1441,7 @@ settings.event_issue_label_desc=Ongelman tunnisteet päivitetty tai tyhjennetty.
settings.event_issue_milestone_desc=Merkkipaalu lisätty, poistettu tai muokattu. settings.event_issue_milestone_desc=Merkkipaalu lisätty, poistettu tai muokattu.
settings.event_issue_comment_desc=Ongelman kommentti luotu, muokattu tai poistettu. settings.event_issue_comment_desc=Ongelman kommentti luotu, muokattu tai poistettu.
settings.event_header_pull_request=Vetopyyntöjen tapahtumat settings.event_header_pull_request=Vetopyyntöjen tapahtumat
settings.event_pull_request=Vetopyyntö settings.event_pull_request=Muokkaus
settings.event_package_desc=Paketti on luotu tai poistettu repossa. settings.event_package_desc=Paketti on luotu tai poistettu repossa.
settings.active_helper=Tiedot käynnistetyistä tapahtumista lähetetään tähän webkoukun URL-osoitteeseen. settings.active_helper=Tiedot käynnistetyistä tapahtumista lähetetään tähän webkoukun URL-osoitteeseen.
settings.add_hook_success=Uusi webkoukku on lisätty. settings.add_hook_success=Uusi webkoukku on lisätty.
@ -1883,7 +1910,7 @@ migrate.gitlab.description = Tee migraatio gitlab.comista tai muista GitLab-inst
migrate.gitea.description = Tee migraatio gitea.comista tai muista Gitea-instansseista. migrate.gitea.description = Tee migraatio gitea.comista tai muista Gitea-instansseista.
repo_gitignore_helper_desc = Valitse mitä tiedostoja ei seurata yleisimpien kielten mallipohjista. Tyypilliset artefaktit, joita eri kielten koostamistyökalut tuottavat, lisätään .gitignore-tiedostoon oletusarvoisesti. repo_gitignore_helper_desc = Valitse mitä tiedostoja ei seurata yleisimpien kielten mallipohjista. Tyypilliset artefaktit, joita eri kielten koostamistyökalut tuottavat, lisätään .gitignore-tiedostoon oletusarvoisesti.
milestones.filter_sort.latest_due_date = Kaukaisin määräpäivä milestones.filter_sort.latest_due_date = Kaukaisin määräpäivä
license_helper_desc = Lisenssi määrää, mitä muut voivat ja eivät voi tehdä koodillasi. Etkö ole varma, mikä lisenssi soveltuu projektillesi? Lue <a target="_blank" rel="noopener noreferrer" href="%s">ohje lisenssin valinnasta.</a> license_helper_desc = Lisenssi määrää, mitä muut voivat ja eivät voi tehdä koodillasi. Etkö ole varma, mikä lisenssi soveltuu projektillesi? Lue <a target="_blank" rel="noopener noreferrer" href="%s">ohje lisenssin valinnasta</a>.
milestones.filter_sort.earliest_due_data = Lähin määräpäivä milestones.filter_sort.earliest_due_data = Lähin määräpäivä
issues.filter_type.reviewed_by_you = Katselmoitu toimestasi issues.filter_type.reviewed_by_you = Katselmoitu toimestasi
settings.units.overview = Yleisnäkymä settings.units.overview = Yleisnäkymä
@ -1959,6 +1986,31 @@ editor.must_have_write_access = Sinulla täytyy olla kirjoitusoikeus tehdäksesi
issues.re_request_review = Pyydä katselmointia uudelleen issues.re_request_review = Pyydä katselmointia uudelleen
pulls.status_checks_details = Yksityiskohdat pulls.status_checks_details = Yksityiskohdat
release.title_empty = Nimi ei voi olla tyhjä. release.title_empty = Nimi ei voi olla tyhjä.
archive.title = Tämä repo on arkistoitu. Voit katsella sen sisältämiä tiedostoja ja kloonata repon, mutta et voi pushata, avata ongelmia tai luoda vetopyyntöjä.
reactions_more = ja %d lisää
mirror_address = Kloonaa URL-osoitteesta
migrate_items_merge_requests = Yhdistämispyynnöt
stars_remove_warning = Tämä poistaa kaikki tähdet tästä reposta.
archive.issue.nocomment = Tämä repo on arkistoitu. Et voi kommentoida ongelmia.
archive.pull.nocomment = Tämä repo on arkistoitu. Et voi kommentoida vetopyyntöjä.
settings.webhook_deletion_desc = Webkoukun poistaminen poistaa sen asetukset ja toimitushistorian. Jatketaanko?
settings.discord_icon_url.exceeds_max_length = Kuvakkeen URL-osoite voi sisältää enintään 2048 merkkiä
settings.event_wiki_desc = Wiki-sivu luotu, nimetty uudelleen, muokattu tai poistettu.
settings.event_pull_request_desc = Vetopyyntö avattu, suljettu, avattu uudelleen tai muokattu.
settings.protect_branch_name_pattern = Suojatun haaran nimen kaava
issues.dependency.add_error_dep_not_same_repo = Molempien ongelmien tulee olla samassa repossa.
settings.event_release = Julkaisu
pulls.merge_pull_request = Luo yhdistämiskommitti
settings.pull_mirror_sync_quota_exceeded = Kiintiö ylitetty, ei vedetä muutoksia.
settings.wiki_rename_branch_main_notices_1 = Tätä toimintoa <strong>EI VOI</strong> perua.
settings.webhook.test_delivery_desc_disabled = Aktivoi webkoukku testataksesi sitä tekaistulla tapahtumalla.
settings.discord_icon_url = Kuvakkeen URL-osoite
settings.archive.branchsettings_unavailable = Haaran asetukset eivät ole saatavilla arkistoiduissa repoissa.
pulls.ready_for_review = Valmiina katselmointiin?
issues.time_spent_total = Käytetty kokonaisaika
settings.webhook.test_delivery_desc = Testaa tätä webkoukkua tekaistulla tapahtumalla.
pulls.switch_comparison_type = Vaihda vertailutyyppiä
settings.hooks_desc = Webkoukut tekevät automaattisesti HTTP POST -pyyntöjä palvelimelle, kun jotkin Forgejo-tapahtumat käynnistyvät. Lue lisää <a target="_blank" rel="noopener noreferrer" href="%s">webkoukkujen oppaasta</a>.
@ -2102,8 +2154,8 @@ dashboard.operation_switch=Vaihda
dashboard.operation_run=Suorita dashboard.operation_run=Suorita
dashboard.delete_inactive_accounts=Poista kaikki aktivoimattomat käyttäjät dashboard.delete_inactive_accounts=Poista kaikki aktivoimattomat käyttäjät
dashboard.delete_repo_archives=Poista kaikki repojen arkistot (ZIP, TAR.GZ, jne..) dashboard.delete_repo_archives=Poista kaikki repojen arkistot (ZIP, TAR.GZ, jne..)
dashboard.server_uptime=Palvelimen Uptime dashboard.server_uptime=Palvelimen uptime
dashboard.current_goroutine=Nykyiset Goroutinet dashboard.current_goroutine=Nykyiset goroutinet
dashboard.current_memory_usage=Nykyinen muistinkäyttö dashboard.current_memory_usage=Nykyinen muistinkäyttö
dashboard.total_memory_allocated=Yhteensä muistia varattu dashboard.total_memory_allocated=Yhteensä muistia varattu
dashboard.memory_obtained=Muistia saatu dashboard.memory_obtained=Muistia saatu
@ -2279,7 +2331,7 @@ config.default_visibility_organization=Uuden organisaation oletusnäkyvyys
config.webhook_config=Webkoukkujen asetukset config.webhook_config=Webkoukkujen asetukset
config.queue_length=Jonon pituus config.queue_length=Jonon pituus
config.deliver_timeout=Toimitus aikakatkaisu config.deliver_timeout=Toimituksen aikakatkaisu
config.mailer_enabled=Käytössä config.mailer_enabled=Käytössä
config.mailer_name=Nimi config.mailer_name=Nimi
@ -2426,6 +2478,8 @@ dashboard.task.unknown = Tuntematon tehtävä: %[1]s
dashboard.cron.error = Virhe Cronissa: %s: %[3]s dashboard.cron.error = Virhe Cronissa: %s: %[3]s
dashboard.task.started = Käynnistetty tehtävä: %[1]s dashboard.task.started = Käynnistetty tehtävä: %[1]s
dashboard.cron.finished = Cron: %[1]s on valmistunut dashboard.cron.finished = Cron: %[1]s on valmistunut
dashboard.resync_all_sshkeys = Päivitä ".ssh/authorized_keys"-tiedosto Forgejo:n SSH-avaimilla.
dashboard.cleanup_packages = Siivoa vanhentuneet paketit
[action] [action]
@ -2601,6 +2655,15 @@ settings.link = Linkitä tämä paketti repositorioon
maven.download = Lataa riippuvuus suorittamalla komentorivillä: maven.download = Lataa riippuvuus suorittamalla komentorivillä:
registry.documentation = Lisätietoja %s-rekisteristä on <a target="_blank" rel="noopener noreferrer" href="%s">dokumentaatiossa</a>. registry.documentation = Lisätietoja %s-rekisteristä on <a target="_blank" rel="noopener noreferrer" href="%s">dokumentaatiossa</a>.
owner.settings.chef.keypair.description = Avainpari vaaditaan Chef-rekisteriin tunnistautumista varten. Jos olet luonut avainparin aiemmin, uuden avainparin luominen hylkää aiemman avainparin. owner.settings.chef.keypair.description = Avainpari vaaditaan Chef-rekisteriin tunnistautumista varten. Jos olet luonut avainparin aiemmin, uuden avainparin luominen hylkää aiemman avainparin.
owner.settings.cleanuprules.keep.pattern = Säilytä kaavaa vastaavat versiot
owner.settings.cleanuprules.pattern_full_match = Toteuta kaavio paketin koko nimeen
owner.settings.cleanuprules.keep.title = Näitä sääntöjä vastaavat versiot säilytetään, vaikka ne vastaisivat alla olevaa poistosääntöä.
owner.settings.cleanuprules.keep.count = Säilytä viimeisimmät
owner.settings.cleanuprules.remove.pattern = Poista kaavaa vastaavat versiot
owner.settings.cleanuprules.keep.pattern.container = Viimeisin (<code>latest</code>) versio säilytetään aina Container-paketeista.
owner.settings.cleanuprules.remove.title = Näitä sääntöjä vastaavat versiot poistetaan, ellei sääntö yläpuolella käske säilyttää niitä.
owner.settings.cleanuprules.remove.days = Poista versiot, jotka ovat vanhempia kuin
arch.pacman.helper.gpg = Lisää luottamusvarmenne pacmanille:
[secrets] [secrets]
creation.failed = Salaisuuden lisääminen epäonnistui. creation.failed = Salaisuuden lisääminen epäonnistui.

View file

@ -165,6 +165,7 @@ error413 = Votre quota est épuisé.
new_repo.title = Nouveau dépôt new_repo.title = Nouveau dépôt
new_migrate.link = Nouvelle migration new_migrate.link = Nouvelle migration
new_org.link = Nouvelle organisation new_org.link = Nouvelle organisation
copy_path = Copier le chemin
[aria] [aria]
navbar=Barre de navigation navbar=Barre de navigation
@ -811,7 +812,7 @@ manage_emails=Gérer les adresses courriels
manage_themes=Thème par défaut manage_themes=Thème par défaut
manage_openid=Adresses OpenID manage_openid=Adresses OpenID
email_desc=Votre adresse courriel principale sera utilisée pour les notifications, la récupération de mot de passe et, à condition qu'elle ne soit pas cachée, les opérations Git basées sur le Web. email_desc=Votre adresse courriel principale sera utilisée pour les notifications, la récupération de mot de passe et, à condition qu'elle ne soit pas cachée, les opérations Git basées sur le Web.
theme_desc=Ce sera votre thème par défaut sur le site. theme_desc=Ce thème sera utilisé pour l'interface web lorsque vous êtes authentifié.
primary=Principale primary=Principale
activated=Activé activated=Activé
requires_activation=Nécessite une activation requires_activation=Nécessite une activation
@ -1055,7 +1056,7 @@ language.localization_project = Aidez-nous à traduire Forgejo dans votre langue
language.description = Cette langue sera enregistrée dans votre compte et utilisée comme langue par défaut après votre connexion. language.description = Cette langue sera enregistrée dans votre compte et utilisée comme langue par défaut après votre connexion.
[repo] [repo]
new_repo_helper=Un dépôt contient tous les fichiers dun projet, ainsi que lhistorique de leurs modifications. Vous avez déjà ça ailleurs ? <a href="%s">Migrez-le ici.</a> new_repo_helper=Un dépôt contient tous les fichiers dun projet, ainsi que lhistorique de leurs modifications. Vous avez déjà ça ailleurs ? <a href="%s">Migrez-le ici.</a>.
owner=Propriétaire owner=Propriétaire
owner_helper=Certaines organisations peuvent ne pas apparaître dans la liste déroulante en raison d'une limite maximale du nombre de dépôts. owner_helper=Certaines organisations peuvent ne pas apparaître dans la liste déroulante en raison d'une limite maximale du nombre de dépôts.
repo_name=Nom du dépôt repo_name=Nom du dépôt
@ -1095,7 +1096,7 @@ issue_labels=Étiquettes
issue_labels_helper=Sélectionner un jeu d'étiquettes issue_labels_helper=Sélectionner un jeu d'étiquettes
license=Licence license=Licence
license_helper=Sélectionner une licence license_helper=Sélectionner une licence
license_helper_desc=Une licence réglemente ce que les autres peuvent ou ne peuvent pas faire avec votre code. Vous ne savez pas laquelle est la bonne pour votre projet ? Comment <a target="_blank" rel="noopener noreferrer" href="%s">choisir une licence.</a> license_helper_desc=Une licence réglemente ce que les autres peuvent ou ne peuvent pas faire avec votre code. Vous ne savez pas laquelle est la bonne pour votre projet ? Comment <a target="_blank" rel="noopener noreferrer" href="%s">choisir une licence.</a>.
readme=LISEZMOI readme=LISEZMOI
readme_helper=Choisissez un modèle de fichier LISEZMOI readme_helper=Choisissez un modèle de fichier LISEZMOI
readme_helper_desc=Le README est l'endroit idéal pour décrire votre projet et accueillir des contributeurs. readme_helper_desc=Le README est l'endroit idéal pour décrire votre projet et accueillir des contributeurs.
@ -2508,7 +2509,7 @@ settings.archive.error=Une erreur s'est produite lors de l'archivage du dépôt.
settings.archive.error_ismirror=Vous ne pouvez pas archiver un dépôt en miroir. settings.archive.error_ismirror=Vous ne pouvez pas archiver un dépôt en miroir.
settings.archive.branchsettings_unavailable=Le paramétrage des branches n'est pas disponible quand le dépôt est archivé. settings.archive.branchsettings_unavailable=Le paramétrage des branches n'est pas disponible quand le dépôt est archivé.
settings.archive.tagsettings_unavailable=Le paramétrage des étiquettes n'est pas disponible si le dépôt est archivé. settings.archive.tagsettings_unavailable=Le paramétrage des étiquettes n'est pas disponible si le dépôt est archivé.
settings.archive.mirrors_unavailable = Les mirroirs ne sont pas disponibles si le dépôt a été archivé. settings.archive.mirrors_unavailable = Les miroirs ne sont pas disponibles si le dépôt a été archivé.
settings.unarchive.button=Désarchiver ce dépôt settings.unarchive.button=Désarchiver ce dépôt
settings.unarchive.header=Réhabiliter ce dépôt settings.unarchive.header=Réhabiliter ce dépôt
settings.unarchive.text=Réhabiliter un dépôt dégèle les actions de révisions et de soumissions, la gestion des tickets et des demandes d'ajouts. settings.unarchive.text=Réhabiliter un dépôt dégèle les actions de révisions et de soumissions, la gestion des tickets et des demandes d'ajouts.
@ -2844,6 +2845,10 @@ diff.git-notes.remove-body = Cette note sera supprimée.
diff.git-notes.add = Ajouter une note diff.git-notes.add = Ajouter une note
diff.git-notes.remove-header = Supprimer la note diff.git-notes.remove-header = Supprimer la note
issues.summary_card_alt = Fiche de synthèse d'un ticket nommé "%s" dans le dépôt %s issues.summary_card_alt = Fiche de synthèse d'un ticket nommé "%s" dans le dépôt %s
editor.add_tmpl.filename = fichier
issues.num_reviews_one = %d revue
issues.num_reviews_few = %d revues
settings.default_update_style_desc = Style de mise à jour des demandes de fusion qui sont en retard par rapport à la branche de base.
[graphs] [graphs]
component_loading = Chargement %s... component_loading = Chargement %s...
@ -3662,7 +3667,7 @@ alpine.registry=Configurez ce registre en ajoutant lURL dans votre fichier <c
alpine.registry.key=Téléchargez la clé RSA publique du registre dans le dossier <code>/etc/apk/keys/</code> pour vérifier la signature de l'index : alpine.registry.key=Téléchargez la clé RSA publique du registre dans le dossier <code>/etc/apk/keys/</code> pour vérifier la signature de l'index :
alpine.registry.info=Choisissez $branch et $repository dans la liste ci-dessous. alpine.registry.info=Choisissez $branch et $repository dans la liste ci-dessous.
alpine.install=Pour installer le paquet, exécutez la commande suivante : alpine.install=Pour installer le paquet, exécutez la commande suivante :
alpine.repository=Informations sur le Dépôt alpine.repository=Informations sur le dépôt
alpine.repository.branches=Branches alpine.repository.branches=Branches
alpine.repository.repositories=Dépôts alpine.repository.repositories=Dépôts
alpine.repository.architectures=Architectures alpine.repository.architectures=Architectures
@ -3682,7 +3687,7 @@ conda.install=Pour installer le paquet en utilisant Conda, exécutez la commande
container.details.type=Type d'image container.details.type=Type d'image
container.details.platform=Plateforme container.details.platform=Plateforme
container.pull=Tirez l'image depuis un terminal : container.pull=Tirez l'image depuis un terminal :
container.digest=Empreinte : container.digest=Empreinte
container.multi_arch=SE / Arch container.multi_arch=SE / Arch
container.layers=Calques d'image container.layers=Calques d'image
container.labels=Labels container.labels=Labels
@ -3797,6 +3802,7 @@ arch.version.conflicts = Conflits
arch.version.replaces = Remplace arch.version.replaces = Remplace
arch.version.backup = Sauvegarde arch.version.backup = Sauvegarde
arch.version.makedepends = Faire des dépendances arch.version.makedepends = Faire des dépendances
container.images.title = Images
[secrets] [secrets]
secrets=Secrets secrets=Secrets

View file

@ -765,7 +765,7 @@ cancel=Atcelt
language=Valoda language=Valoda
ui=Motīvs ui=Motīvs
hidden_comment_types=Slēpjamo piebilžu veidi hidden_comment_types=Slēpjamo piebilžu veidi
hidden_comment_types_description=Šeit atzīmētie piebilžu veidi netiks attēloti pieteikumu lapās. "Iezīme" atzīmēšana, piemēram, noņems visas "<lietotājs> pievienoja/noņēma <label>" piebildes. hidden_comment_types_description=Šeit atzīmētie piebilžu veidi netiks attēloti pieteikumu lapās. "Iezīme" atzīmēšana, piemēram, noņems visas "<lietotājs> pievienoja/noņēma <iezīme>" piebildes.
hidden_comment_types.ref_tooltip=Piebildes, kurās ir atsauces uz šo pieteikumu no cita pieteikuma/iesūtījuma/… hidden_comment_types.ref_tooltip=Piebildes, kurās ir atsauces uz šo pieteikumu no cita pieteikuma/iesūtījuma/…
hidden_comment_types.issue_ref_tooltip=Piebildes, kurās lietotājs maina ar pieteikumu saistītu zaru/birku hidden_comment_types.issue_ref_tooltip=Piebildes, kurās lietotājs maina ar pieteikumu saistītu zaru/birku
comment_type_group_reference=Atsauces comment_type_group_reference=Atsauces
@ -1020,7 +1020,7 @@ delete_prompt=Šī darbība neatgriezeniski izdzēsīs lietotāja kontu. To <str
delete_with_all_comments=Konts ir jaunāks kā %s. Lai izvairītos no spoku piebildēm, visas pieteikumu/izmaiņu pieprasījumu piebildes tiks izdzēstas kopā ar to. delete_with_all_comments=Konts ir jaunāks kā %s. Lai izvairītos no spoku piebildēm, visas pieteikumu/izmaiņu pieprasījumu piebildes tiks izdzēstas kopā ar to.
confirm_delete_account=Apstiprināt izdzēšanu confirm_delete_account=Apstiprināt izdzēšanu
delete_account_title=Izdzēst lietotāja kontu delete_account_title=Izdzēst lietotāja kontu
delete_account_desc=Vai tiešām vēlaties dzēst šo kontu? delete_account_desc=Vai tiešām neatgriezeniski izdzēst šo lietotāja kontu?
email_notifications.enable=Iespējot e-pasta paziņojumus email_notifications.enable=Iespējot e-pasta paziņojumus
email_notifications.onmention=Tikai, ja piemin mani email_notifications.onmention=Tikai, ja piemin mani
@ -1046,6 +1046,13 @@ blocked_users_none = Nav liegto lietotāju.
pronouns = Vietniekvārdi pronouns = Vietniekvārdi
pronouns_custom = Pielāgoti pronouns_custom = Pielāgoti
blocked_users = Liegtie lietotāji blocked_users = Liegtie lietotāji
pronouns_unspecified = Nav norādīts
language.title = Noklusējuma valoda
language.localization_project = Palīdzi mums tulkot Forgejo savā valodā! <a href="%s">Uzzināt vairāk</a>.
hints = Norādes
additional_repo_units_hint = Ieteikt iespējot papildu glabātavas vienības
additional_repo_units_hint_description = Attēlot norādi "Iespējot vēl" glabātavās, kurās nav iespējotas visas pieejamās vienības.
language.description = Šī valoda tiks saglabāta kontā un pēc pieteikšanās tiks izmantota kā noklusējuma.
[repo] [repo]
new_repo_helper=Glabātava satur visas projekta datnes, tajā skaitā izmaiņu vēsturi. Jau tiek izmantota kaut kur citur? <a href="%s">Pārcelt glabātavu</a>. new_repo_helper=Glabātava satur visas projekta datnes, tajā skaitā izmaiņu vēsturi. Jau tiek izmantota kaut kur citur? <a href="%s">Pārcelt glabātavu</a>.
@ -1207,26 +1214,26 @@ migrate.invalid_local_path=Nederīgs vietējais ceļš. Tas nepastāv vai nenor
migrate.invalid_lfs_endpoint=LFS galapunkts nav derīgs. migrate.invalid_lfs_endpoint=LFS galapunkts nav derīgs.
migrate.failed=Pārcelšana neizdevās: %v migrate.failed=Pārcelšana neizdevās: %v
migrate.migrate_items_options=Ir nepieciešama piekļuves pilnvara, lai pārceltu papildu vienumus migrate.migrate_items_options=Ir nepieciešama piekļuves pilnvara, lai pārceltu papildu vienumus
migrated_from=Migrēts no <a href="%[1]s">%[2]s</a> migrated_from=Pārcelta no <a href="%[1]s">%[2]s</a>
migrated_from_fake=Pārcelta no %[1]s migrated_from_fake=Pārcelta no %[1]s
migrate.migrate=Pārcelt no %s migrate.migrate=Pārcelt no %s
migrate.migrating=Pārceļ no <b>%s</b> ... migrate.migrating=Pārceļ no <b>%s</b> ...
migrate.migrating_failed=Pārcelšana no <b>%s</b> neizdevās. migrate.migrating_failed=Pārcelšana no <b>%s</b> neizdevās.
migrate.migrating_failed.error=Neizdevās pārcelt: %s migrate.migrating_failed.error=Neizdevās pārcelt: %s
migrate.migrating_failed_no_addr=Pārcelšana neizdevās. migrate.migrating_failed_no_addr=Pārcelšana neizdevās.
migrate.github.description=Migrēt datus no github.com vai citām GitHub instancēm. migrate.github.description=Pārcelt datus no github.com vai GitHub Enterprise servera.
migrate.git.description=Pārcelt tikai glabātavu no jebkura Git pakalpojuma. migrate.git.description=Pārcelt tikai glabātavu no jebkura Git pakalpojuma.
migrate.gitlab.description=Migrēt datus no gitlab.com vai citām GitLab instancēm. migrate.gitlab.description=Pārcelt datus no gitlab.com vai citiem GitLab serveriem.
migrate.gitea.description=Pārcelt datus no gitea.com vai citiem Gitea/Forgejo serveriem. migrate.gitea.description=Pārcelt datus no gitea.com vai citiem Gitea/Forgejo serveriem.
migrate.gogs.description=Migrēt datus no notabug.org vai citām Gogs instancēm. migrate.gogs.description=Pārcelt datus no notabug.org vai citiem Gogs serveriem.
migrate.onedev.description=Migrēt datus no code.onedev.io vai citām OneDev instancēm. migrate.onedev.description=Pārcelt datus no code.onedev.io vai citiem OneDev serveriem.
migrate.codebase.description=Migrēt datus no codebasehq.com. migrate.codebase.description=Pārcelt datus no codebasehq.com.
migrate.gitbucket.description=Migrēt datus no GitBucket instancēm. migrate.gitbucket.description=Pārcelt datus no GitBucket serveriem.
migrate.migrating_git=Migrē git datus migrate.migrating_git=Pārceļ Git datus
migrate.migrating_topics=Migrē tēmas migrate.migrating_topics=Pārceļ tēmas
migrate.migrating_milestones=Migrē atskaites punktus migrate.migrating_milestones=Pārceļ atskaites punktus
migrate.migrating_labels=Pārceļ iezīmes migrate.migrating_labels=Pārceļ iezīmes
migrate.migrating_releases=Migrē laidienus migrate.migrating_releases=Pārceļ laidienus
migrate.migrating_issues=Pārnes pieteikumus migrate.migrating_issues=Pārnes pieteikumus
migrate.migrating_pulls=Pārceļ izmaiņu pieprasījumus migrate.migrating_pulls=Pārceļ izmaiņu pieprasījumus
migrate.cancel_migrating_title=Atcelt pārcelšanu migrate.cancel_migrating_title=Atcelt pārcelšanu
@ -1691,7 +1698,7 @@ issues.unlock.title=Atslēgt šī pieteikuma apspriešanu.
issues.comment_on_locked=Nevar pievienot piebildi aizslēgtam pieteikumam. issues.comment_on_locked=Nevar pievienot piebildi aizslēgtam pieteikumam.
issues.delete=Dzēst issues.delete=Dzēst
issues.delete.title=Izdzēst šo pieteikumu? issues.delete.title=Izdzēst šo pieteikumu?
issues.delete.text=Vai patiešām vēlaties dzēst šo problemu? (Neatgriezeniski tiks izdzēsts viss saturs. Apsveriet iespēju to aizvērt, ja vēlaties informāciju saglabāt vēsturei) issues.delete.text=Vai tiešām izdzēst šo pieteikumu? (Tas neatgriezeniski noņems visu saturu. Tā vietā vēlams apsvērt aizvēršanu, ja ir paredzēts paturēt to arhivētu)
issues.tracker=Laika uzskaite issues.tracker=Laika uzskaite
issues.start_tracking_short=Uzsākt laika skaitīšanu issues.start_tracking_short=Uzsākt laika skaitīšanu
issues.start_tracking=Uzsākt laika uzskaiti issues.start_tracking=Uzsākt laika uzskaiti
@ -1820,7 +1827,7 @@ pulls.collapse_files=Savērst visas datnes
pulls.compare_base=pamata pulls.compare_base=pamata
pulls.compare_compare=atgādāt no pulls.compare_compare=atgādāt no
pulls.switch_comparison_type=Mainīt salīdzināšanas tipu pulls.switch_comparison_type=Mainīt salīdzināšanas tipu
pulls.switch_head_and_base=Mainīt galvas un pamata atzarus pulls.switch_head_and_base=Mainīt galotnes un pamata zarus
pulls.filter_branch=Atlasīt zarus pulls.filter_branch=Atlasīt zarus
pulls.no_results=Nekas netika atrasts. pulls.no_results=Nekas netika atrasts.
pulls.show_all_commits=Rādīt visus iesūtījumus pulls.show_all_commits=Rādīt visus iesūtījumus
@ -1943,8 +1950,8 @@ pulls.auto_merge_canceled_schedule=Šī izmaiņu pieprasījuma automātiskā apv
pulls.auto_merge_newly_scheduled_comment=`ieplānoja šī izmaiņu pieprasījuma automātisko apvienošanu, kad visas pārbaudes tiks sekmīgi pabeigtas %[1]s` pulls.auto_merge_newly_scheduled_comment=`ieplānoja šī izmaiņu pieprasījuma automātisko apvienošanu, kad visas pārbaudes tiks sekmīgi pabeigtas %[1]s`
pulls.auto_merge_canceled_schedule_comment=`atcēla šī izmaiņu pieprasījuma automātisku apvienošanu pēc visu pārbaužu sekmīgas izpildes %[1]s` pulls.auto_merge_canceled_schedule_comment=`atcēla šī izmaiņu pieprasījuma automātisku apvienošanu pēc visu pārbaužu sekmīgas izpildes %[1]s`
pulls.delete.title=Dzēst šo izmaiņu pieprasījumu? pulls.delete.title=Izdzēst šo izmaiņu pieprasījumu?
pulls.delete.text=Vai patiešām vēlaties dzēst šo izmaiņu pieprasījumu? (Neatgriezeniski tiks izdzēsts viss saturs. Apsveriet iespēju to aizvērt, ja vēlaties informāciju saglabāt vēsturei) pulls.delete.text=Vai tiešām izdzēst šo izmaiņu pieprasījumu? (Tiks neatgriezeniski izdzēsts viss saturs. Jāapsver iespēja to aizvērt, ja ir nolūks to paturēt arhivētu)
pulls.recently_pushed_new_branches=Tu aizgādāji izmaiņas zarā <a href="%[3]s"><strong>%[1]s</strong></a> %[2]s pulls.recently_pushed_new_branches=Tu aizgādāji izmaiņas zarā <a href="%[3]s"><strong>%[1]s</strong></a> %[2]s
@ -2035,7 +2042,7 @@ activity.period.semiyearly=6 mēneši
activity.period.yearly=1 gads activity.period.yearly=1 gads
activity.overview=Pārskats activity.overview=Pārskats
activity.active_prs_count_1=<strong>%d</strong> atvērts izmaiņu pieprasījums activity.active_prs_count_1=<strong>%d</strong> atvērts izmaiņu pieprasījums
activity.active_prs_count_n=<strong>%d</strong> aktīvi izmaiņu pieprasījumi activity.active_prs_count_n=<strong>%d</strong> atvērti izmaiņu pieprasījumi
activity.merged_prs_count_1=Iekļauts izmaiņu pieprasījums activity.merged_prs_count_1=Iekļauts izmaiņu pieprasījums
activity.merged_prs_count_n=Iekļauti izmaiņu pieprasījumi activity.merged_prs_count_n=Iekļauti izmaiņu pieprasījumi
activity.opened_prs_count_1=Ierosināts izmaiņu pieprasījums activity.opened_prs_count_1=Ierosināts izmaiņu pieprasījums
@ -2256,16 +2263,16 @@ settings.collaborator_deletion_desc=Līdzdalībnieka noņemšana atsauks tā pie
settings.remove_collaborator_success=Līdzdalībnieks tika noņemts. settings.remove_collaborator_success=Līdzdalībnieks tika noņemts.
settings.search_user_placeholder=Meklēt lietotāju… settings.search_user_placeholder=Meklēt lietotāju…
settings.org_not_allowed_to_be_collaborator=Apvienības nevar tikt pievienotas kā līdzdalībnieki. settings.org_not_allowed_to_be_collaborator=Apvienības nevar tikt pievienotas kā līdzdalībnieki.
settings.change_team_access_not_allowed=Iespēja mainīt komandu piekļuvi repozitorijam ir organizācijas īpašniekam settings.change_team_access_not_allowed=Komandu piekļuves mainīšana glabātavai ir pieejama tikai apvienības īpašniekam
settings.team_not_in_organization=Komanda nav tajā pašā organizācijā kā repozitorijs settings.team_not_in_organization=Komanda nav tajā pašā apvienībā kā glabātava
settings.teams=Komandas settings.teams=Komandas
settings.add_team=Pievienot komandu settings.add_team=Pievienot komandu
settings.add_team_duplicate=Komandai jau ir piekļuve šim repozitorijam settings.add_team_duplicate=Komandai jau ir piekļuve glabātavai
settings.add_team_success=Komandai tagad ir piekļuve glabātavai. settings.add_team_success=Komandai tagad ir piekļuve glabātavai.
settings.search_team=Meklēt komandu… settings.search_team=Meklēt komandu…
settings.change_team_permission_tip=Komandas tiesības tiek uzstādītas komandas iestatījumu lapā un nevar tikt individuāli mainītas katram repozitorijam atsevišķi settings.change_team_permission_tip=Komandas atļauja ir iestatīta komandas iestatījumu lapā un nav maināma katrai glabātavai atsevišķi
settings.delete_team_tip=Komandai ir piekļuve visiem repozitorijiem un tā nevar tikt noņemta individuāli settings.delete_team_tip=Komandai ir piekļuve visām glabātavām, un to nevar noņemt
settings.remove_team_success=Komandas piekļuve šim repozitorijam ir noņemta. settings.remove_team_success=Tika noņemta komandas piekļuve glabātavai.
settings.add_webhook=Pievienot tīmekļa aizķeri settings.add_webhook=Pievienot tīmekļa aizķeri
settings.add_webhook.invalid_channel_name=Tīmekļa aizķeres plūsmas nosaukums nevar būt tukšs vai saturēt tikai rakstzīmi #. settings.add_webhook.invalid_channel_name=Tīmekļa aizķeres plūsmas nosaukums nevar būt tukšs vai saturēt tikai rakstzīmi #.
settings.hooks_desc=Tīmekļa aizķeres automātiski sūta serverim HTTP POST pieprasījumus, kad iedarbojas noteikti Forgejo notikumi. Vairāk ir lasāms <a target="_blank" rel="noopener noreferrer" href="%s">tīmekļa aizķeru rokasgrāmatā</a>. settings.hooks_desc=Tīmekļa aizķeres automātiski sūta serverim HTTP POST pieprasījumus, kad iedarbojas noteikti Forgejo notikumi. Vairāk ir lasāms <a target="_blank" rel="noopener noreferrer" href="%s">tīmekļa aizķeru rokasgrāmatā</a>.
@ -2315,8 +2322,8 @@ settings.event_release=Laidiens
settings.event_release_desc=Laists klajā, atjaunināts vai izdzēsts laidiens glabātavā. settings.event_release_desc=Laists klajā, atjaunināts vai izdzēsts laidiens glabātavā.
settings.event_push=Aizgādāšana settings.event_push=Aizgādāšana
settings.event_push_desc=Git aizgādāšana uz glabātavu. settings.event_push_desc=Git aizgādāšana uz glabātavu.
settings.event_repository=Repozitorijs settings.event_repository=Glabātava
settings.event_repository_desc=Repozitorijs izveidots vai dzēsts. settings.event_repository_desc=Izveidota vai izdzēsta glabātava.
settings.event_header_issue=Pieteikumu notikumi settings.event_header_issue=Pieteikumu notikumi
settings.event_issues=Izmainīšana settings.event_issues=Izmainīšana
settings.event_issues_desc=Pieteikums atvērts, aizvērts, atkārtoti atvērts vai labots. settings.event_issues_desc=Pieteikums atvērts, aizvērts, atkārtoti atvērts vai labots.
@ -2348,7 +2355,7 @@ settings.event_pull_request_review_request_desc=Pieprasīta izmaiņu pieprasīju
settings.event_pull_request_approvals=Izmaiņu pieprasījuma apstiprinājumi settings.event_pull_request_approvals=Izmaiņu pieprasījuma apstiprinājumi
settings.event_pull_request_merge=Izmaiņu pieprasījuma iekļaušana settings.event_pull_request_merge=Izmaiņu pieprasījuma iekļaušana
settings.event_package=Pakotne settings.event_package=Pakotne
settings.event_package_desc=Repozitorijā izveidota vai dzēsta pakotne. settings.event_package_desc=Izveidota vai izdzēsta pakotne glabātavā.
settings.branch_filter=Zaru atlase settings.branch_filter=Zaru atlase
settings.branch_filter_desc=Zaru baltais saraksts aizgādāšanas, zaru izveidošanas un izdzēšanas notikumiem, kas ir norādīts kā glob paraugs. Ja tukšs vai <code>*</code>, tiks nosūtīti visu zaru notikumi. Par pierakstu skatīt<a href="%[1]s">%[2]s</a> dokumentācijā. Piemēri: <code>main</code>, <code>{main,release*}</code>. settings.branch_filter_desc=Zaru baltais saraksts aizgādāšanas, zaru izveidošanas un izdzēšanas notikumiem, kas ir norādīts kā glob paraugs. Ja tukšs vai <code>*</code>, tiks nosūtīti visu zaru notikumi. Par pierakstu skatīt<a href="%[1]s">%[2]s</a> dokumentācijā. Piemēri: <code>main</code>, <code>{main,release*}</code>.
settings.authorization_header=Pilnvarošanas galvene settings.authorization_header=Pilnvarošanas galvene
@ -2364,7 +2371,7 @@ settings.hook_type=Aizķeres veids
settings.slack_token=Pilnvara settings.slack_token=Pilnvara
settings.slack_domain=Domēns settings.slack_domain=Domēns
settings.slack_channel=Kanāls settings.slack_channel=Kanāls
settings.add_web_hook_desc=Integrēt <a target="_blank" rel="noreferrer" href="%s">%s</a> repozitorijā. settings.add_web_hook_desc=Iekļaut <a target="_blank" rel="noreferrer" href="%s">%s</a> savā glabātavā.
settings.web_hook_name_gitea=Gitea settings.web_hook_name_gitea=Gitea
settings.web_hook_name_forgejo = Forgejo settings.web_hook_name_forgejo = Forgejo
settings.web_hook_name_gogs=Gogs settings.web_hook_name_gogs=Gogs
@ -2384,7 +2391,7 @@ settings.packagist_api_token=API pilnvara
settings.packagist_package_url=Packagist pakotnes URL settings.packagist_package_url=Packagist pakotnes URL
settings.deploy_keys=Izvietošanas atslēgas settings.deploy_keys=Izvietošanas atslēgas
settings.add_deploy_key=Pievienot izvietošanas atslēgu settings.add_deploy_key=Pievienot izvietošanas atslēgu
settings.deploy_key_desc=Izvietošanas atslēgām ir lasīšanas piekļuve repozitorijam. settings.deploy_key_desc=Izvietošanas atslēgām ir lasīšanas piekļuve glabātavai.
settings.is_writable=Iespējot rakstīšanas piekļuvi settings.is_writable=Iespējot rakstīšanas piekļuvi
settings.is_writable_info=Atļaut šai izvietošanas atslēgai <strong>aizgādāt</strong> uz glabātavu. settings.is_writable_info=Atļaut šai izvietošanas atslēgai <strong>aizgādāt</strong> uz glabātavu.
settings.no_deploy_keys=Pagaidām nav nevienas izvietošanas atslēgas. settings.no_deploy_keys=Pagaidām nav nevienas izvietošanas atslēgas.
@ -2394,7 +2401,7 @@ settings.key_been_used=Izvietošanas atslēga ar šādu saturu jau ir pievienota
settings.key_name_used=Jau pastāv izvietošanas atslēga ar tādu pašu nosaukumu. settings.key_name_used=Jau pastāv izvietošanas atslēga ar tādu pašu nosaukumu.
settings.add_key_success=Izvietošanas atslēga "%s" tika pievienota. settings.add_key_success=Izvietošanas atslēga "%s" tika pievienota.
settings.deploy_key_deletion=Noņemt izvietošanas atslēgu settings.deploy_key_deletion=Noņemt izvietošanas atslēgu
settings.deploy_key_deletion_desc=Noņemot izvietošanas atslēgu, tai tiks liegta piekļuve šim repozitorija. Vai turpināt? settings.deploy_key_deletion_desc=Izvietošanas atslēgas noņemšana atsauks tās piekļuvi šai glabātavai. Turpināt?
settings.deploy_key_deletion_success=Izvietošanas atslēga tika noņemta. settings.deploy_key_deletion_success=Izvietošanas atslēga tika noņemta.
settings.branches=Zari settings.branches=Zari
settings.protected_branch=Zaru aizsardzība settings.protected_branch=Zaru aizsardzība
@ -2427,7 +2434,7 @@ settings.protect_check_status_contexts=Iespējot statusu pārbaudi
settings.protect_status_check_patterns=Stāvokļa pārbaudes paraugi settings.protect_status_check_patterns=Stāvokļa pārbaudes paraugi
settings.protect_status_check_patterns_desc=Jāievada paraugi, lai norādītu, kurām stāvokļa pārbaudēm sekmīgi jāizpildās, pirms zari var tikt iekļauti zarā, kas atbilst šai kārtulai. Katrā rindā ir norādāms viens paraugs. Paraugi nevar būt tukši. settings.protect_status_check_patterns_desc=Jāievada paraugi, lai norādītu, kurām stāvokļa pārbaudēm sekmīgi jāizpildās, pirms zari var tikt iekļauti zarā, kas atbilst šai kārtulai. Katrā rindā ir norādāms viens paraugs. Paraugi nevar būt tukši.
settings.protect_check_status_contexts_desc=Pirms apvienošanas ir nepieciešama sekmīga stāvokļa pārbaužu izpilde. Kad iespējots, iesūtījumiem vispirms jābūt aizgādātiem citā zarā, tad pēc stāvokļa pārbaužu sekmīgas izpildes iekļautiem vai aizgādātiem tieši zarā, kas atbilst šai kārtulai. Ja nav atbilstošu kontekstu, pēdējam iesūtījumam jābūt sekmīgam neatkarīgi no konteksta. settings.protect_check_status_contexts_desc=Pirms apvienošanas ir nepieciešama sekmīga stāvokļa pārbaužu izpilde. Kad iespējots, iesūtījumiem vispirms jābūt aizgādātiem citā zarā, tad pēc stāvokļa pārbaužu sekmīgas izpildes iekļautiem vai aizgādātiem tieši zarā, kas atbilst šai kārtulai. Ja nav atbilstošu kontekstu, pēdējam iesūtījumam jābūt sekmīgam neatkarīgi no konteksta.
settings.protect_check_status_contexts_list=Statusu pārbaudes, kas šim repozitorijam bijušas pēdējās nedēļas laikā settings.protect_check_status_contexts_list=Stāvokļa pārbaudes, kas šajā glabātavā atrastas pēdējās nedēļas laikā
settings.protect_status_check_matched=Atbilst settings.protect_status_check_matched=Atbilst
settings.protect_invalid_status_check_pattern=Kļūdains statusa pārbaudes šablons: "%s". settings.protect_invalid_status_check_pattern=Kļūdains statusa pārbaudes šablons: "%s".
settings.protect_no_valid_status_check_patterns=Nav derīgu stāvokļa pārbaužu paraugu. settings.protect_no_valid_status_check_patterns=Nav derīgu stāvokļa pārbaužu paraugu.
@ -2490,16 +2497,16 @@ settings.archive.button=Arhivēt glabātavu
settings.archive.header=Arhivēt šo glabātavu settings.archive.header=Arhivēt šo glabātavu
settings.archive.text=Glabātavas arhivēšana padarīs to tikai lasāmu. Tā nebūs redzama pārskata panelī. Neviens (pat ne Tu) nevarēs izveidot jaunus iesūtījumus vai atvērt pieteikumus vai izmaiņu pieprasījumus. settings.archive.text=Glabātavas arhivēšana padarīs to tikai lasāmu. Tā nebūs redzama pārskata panelī. Neviens (pat ne Tu) nevarēs izveidot jaunus iesūtījumus vai atvērt pieteikumus vai izmaiņu pieprasījumus.
settings.archive.success=Glabātava tika sekmīgi arhivēts. settings.archive.success=Glabātava tika sekmīgi arhivēts.
settings.archive.error=Arhivējot repozitoriju radās neparedzēta kļūda. Pārbaudiet kļūdu žurnālu, lai uzzinātu sīkāk. settings.archive.error=Atgadījās kļūda, kad tika mēģināts arhivēt glabātavu. Jāapskata žurnāls, lai uzzinātu vairāk.
settings.archive.error_ismirror=Nevar arhivēt spoguļotu glabātavu. settings.archive.error_ismirror=Nevar arhivēt spoguļotu glabātavu.
settings.archive.branchsettings_unavailable=Zaru iestatījumi nav pieejami arhivētās glabātavās. settings.archive.branchsettings_unavailable=Zaru iestatījumi nav pieejami arhivētās glabātavās.
settings.archive.tagsettings_unavailable=Tagu iestatījumi nav pieejami, ja repozitorijs ir arhivēts. settings.archive.tagsettings_unavailable=Birku iestatījumi arhivētās glabātavās nav pieejami.
settings.unarchive.button=Atcelt repozitorija arhivēšanu settings.unarchive.button=Atcelt glabātavas arhivēšanu
settings.unarchive.header=Atcelt šī repozitorija arhivēšanu settings.unarchive.header=Atcelt šīs glabātavas arhivēšanu
settings.unarchive.text=Glabātavas arhivēšanas atcelšana atjaunos tās spēju saņemt izmaiņas, kā arī jaunus pieteikumus un izmaiņu pieprasījumus. settings.unarchive.text=Glabātavas arhivēšanas atcelšana atjaunos tās spēju saņemt izmaiņas, kā arī jaunus pieteikumus un izmaiņu pieprasījumus.
settings.unarchive.success=Glabātavas arhivēšana tika sekmīgi atcelta. settings.unarchive.success=Glabātavas arhivēšana tika sekmīgi atcelta.
settings.unarchive.error=Repozitorija arhivēšanas atcelšanas laikā atgadījās kļūda. Vairāk ir redzams žurnālā. settings.unarchive.error=Glabātavas arhivēšanas atcelšanas laikā atgadījās kļūda. Vairāk ir redzams žurnālā.
settings.update_avatar_success=Repozitorija attēls tika atjaunināts. settings.update_avatar_success=Glabātavas attēls tika atjaunināts.
settings.lfs=LFS settings.lfs=LFS
settings.lfs_filelist=Šajā glabātavā uzglabātās LFS datnes settings.lfs_filelist=Šajā glabātavā uzglabātās LFS datnes
settings.lfs_no_lfs_files=Šajā glabātavā nav uzglabātu LFS datņu settings.lfs_no_lfs_files=Šajā glabātavā nav uzglabātu LFS datņu
@ -2634,7 +2641,7 @@ release.downloads=Lejupielādes
release.download_count=Lejupielādes: %s release.download_count=Lejupielādes: %s
release.add_tag_msg=Izmantot laidiena nosaukumu un saturu kā birkas ziņojumu. release.add_tag_msg=Izmantot laidiena nosaukumu un saturu kā birkas ziņojumu.
release.add_tag=Izveidot birku release.add_tag=Izveidot birku
release.releases_for=Repozitorja %s laidieni release.releases_for=Glabātavas %s laidieni
release.tags_for=%s birkas release.tags_for=%s birkas
branch.name=Zara nosaukums branch.name=Zara nosaukums
@ -2782,6 +2789,23 @@ issues.review.add_remove_review_requests = pieprasīja izskatīšanas no %[1] un
issues.author.tooltip.pr = Šis lietotājs ir šī izmaiņu pieprasījuma izveidotājs. issues.author.tooltip.pr = Šis lietotājs ir šī izmaiņu pieprasījuma izveidotājs.
pulls.edit.already_changed = Neizdevās saglabāt izmaiņu pieprasījuma izmaiņas. Izskatās, ka saturu jau ir mainījis kāds cits lietotājs. Lūgums atsvaidzināt lapu un mēģināt labot vēlreiz, lai izvairītos no izmaiņu pārrakstīšanas pulls.edit.already_changed = Neizdevās saglabāt izmaiņu pieprasījuma izmaiņas. Izskatās, ka saturu jau ir mainījis kāds cits lietotājs. Lūgums atsvaidzināt lapu un mēģināt labot vēlreiz, lai izvairītos no izmaiņu pārrakstīšanas
pulls.blocked_by_user = Tu nevari izveidot izmaiņu pieprasījumu šajā glabātavā, jo tās īpašnieks ir Tevi liedzis. pulls.blocked_by_user = Tu nevari izveidot izmaiņu pieprasījumu šajā glabātavā, jo tās īpašnieks ir Tevi liedzis.
issues.all_title = Visi
pulls.commit_ref_at = ` atsaucāš uz šo izmaiņu pieprasījumu iesūtījumā <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.num_participants_one = %d dalībnieks
pulls.title_desc_one = vēlas iekļaut %[1]d iesūtījumu no <code>%[2]s</code> <code id="%[4]s">%[3]s</code>
issues.archived_label_description = (Arhivēts) %s
issues.blocked_by_user = Šajā glabātavā nevari izveidot pieteikumus, jo tās īpašnieks ir liedzis Tevi.
issues.summary_card_alt = Pieteikuma "%s" kopsavilkuma karte glabātavā %s
pulls.nothing_to_compare_have_tag = Atlasītie zari/birkas ir vienādi.
pulls.merged_title_desc_one = iekļāva %[1]d iesūtījumu no <code>%[2]s</code> <code>%[3]s</code> %[4]s
pulls.reopen_failed.head_branch = Izmaiņu pieprasījumu nevar atkārtoti atvērt, jo galotnes zars vairs nepastāv.
pulls.reopen_failed.base_branch = Izmaiņu pieprasījumu nevar atkārtoti atvērt, jo pamata zars vairs nepastāv.
pulls.cmd_instruction_merge_warning = <b>Brīdinājums</b>: "Automātiski noteikt pašrocīgu apvienošanu" šajā glabātavā nav iespējots, pēcāk būs nepieciešams atzīmēt šo izmaiņu pieprasījumu kā pašrocīgi apvienotu.
issues.author.tooltip.issue = Šis lietotājs ir šī pieteikuma izveidotājs.
issues.review.add_review_requests = pieprasīja izskatīšanu no %[1]s %[2]s
issues.comment.blocked_by_user = Tu šim pieteikumam nevari pievienot piebildi, jo glabātavas īpašnieks vai pieteikuma izveidotājs ir liedzis Tevi.
issues.num_reviews_one = %d izskatīšana
issues.num_reviews_few = %d izskatīšanas
[graphs] [graphs]
component_loading=Ielādē %s... component_loading=Ielādē %s...
@ -2802,7 +2826,7 @@ members=Dalībnieki
teams=Komandas teams=Komandas
code=Kods code=Kods
lower_members=dalībnieki lower_members=dalībnieki
lower_repositories=repozitoriji lower_repositories=glabātavas
create_new_team=Jauna komanda create_new_team=Jauna komanda
create_team=Izveidot komandu create_team=Izveidot komandu
org_desc=Apraksts org_desc=Apraksts
@ -2810,9 +2834,9 @@ team_name=Komandas nosaukums
team_desc=Apraksts team_desc=Apraksts
team_name_helper=Komandu nosaukumiem vēlams būt īsiem un tādiem, ko viegli atcerēties. team_name_helper=Komandu nosaukumiem vēlams būt īsiem un tādiem, ko viegli atcerēties.
team_desc_helper=Aprakstiet komandas mērķi vai lomu. team_desc_helper=Aprakstiet komandas mērķi vai lomu.
team_access_desc=Piekļuve repozitorijiem team_access_desc=Glabātavu piekļuve
team_permission_desc=Atļauja team_permission_desc=Atļauja
team_unit_desc=Atļaut piekļuvi repozitorija sadaļām team_unit_desc=Atļaut piekļuvi glabātavas sadaļām
team_unit_disabled=(Atspējots) team_unit_disabled=(Atspējots)
form.name_reserved=Organizācijas nosaukums "%s" ir rezervēts. form.name_reserved=Organizācijas nosaukums "%s" ir rezervēts.
@ -2867,7 +2891,7 @@ members.invite_now=Uzaicināt tagad
teams.join=Pievienoties teams.join=Pievienoties
teams.leave=Atstāt teams.leave=Atstāt
teams.leave.detail=Pamest organizāciju %s? teams.leave.detail=Pamest organizāciju %s?
teams.can_create_org_repo=Veidot jaunus repozitorijus teams.can_create_org_repo=Izveidot glabātavas
teams.can_create_org_repo_helper=Dalībnieki apvienībā var izveidot jaunas glabātavas. Izveidotājs iegūs jaunās glabātavas pārvaldītāja piekļuvi. teams.can_create_org_repo_helper=Dalībnieki apvienībā var izveidot jaunas glabātavas. Izveidotājs iegūs jaunās glabātavas pārvaldītāja piekļuvi.
teams.none_access=Nav piekļuves teams.none_access=Nav piekļuves
teams.none_access_helper="Nav piekļuve" iespēja iedarbojas tikai privātās glabātavās. teams.none_access_helper="Nav piekļuve" iespēja iedarbojas tikai privātās glabātavās.
@ -2889,18 +2913,18 @@ teams.add_team_member=Pievienot komandas biedru
teams.invite_team_member=`Uzaicināt komandā "%s"` teams.invite_team_member=`Uzaicināt komandā "%s"`
teams.invite_team_member.list=Neapstiprinātie uzaicinājumi teams.invite_team_member.list=Neapstiprinātie uzaicinājumi
teams.delete_team_title=Dzēst komandu teams.delete_team_title=Dzēst komandu
teams.delete_team_desc=Dzēšot komandu, tās biedri var zaudēt piekļuvi dažiem vai pat visiem repozitorijiem. Vai turpināt? teams.delete_team_desc=Komandas izdzēšana tās dalībniekiem atsauc piekļuvi glabātavām. Turpināt?
teams.delete_team_success=Komanda tika izdzēsta. teams.delete_team_success=Komanda tika izdzēsta.
teams.read_permission_desc=Šī komanda nodrošina <strong>lasīšanas</strong> piekļuvi: dalībnieki var apskatīt un klonēt komandas glabātavas. teams.read_permission_desc=Šī komanda nodrošina <strong>lasīšanas</strong> piekļuvi: dalībnieki var apskatīt un klonēt komandas glabātavas.
teams.write_permission_desc=Šī komanda nodrošina <strong>rakstīšanas</strong> piekļuvi: dalībnieki var lasīt un aizgādāt izmaiņas uz komandas glabātavām. teams.write_permission_desc=Šī komanda nodrošina <strong>rakstīšanas</strong> piekļuvi: dalībnieki var lasīt un aizgādāt izmaiņas uz komandas glabātavām.
teams.admin_permission_desc=Šī komanda nodrošina <strong>pārvaldītāja</strong> piekļuvi: dalībnieki var lasīt no, aizgādāt izmaiņas uz un pievienot līdzdalībniekus komandas glabātavām. teams.admin_permission_desc=Šī komanda nodrošina <strong>pārvaldītāja</strong> piekļuvi: dalībnieki var lasīt no, aizgādāt izmaiņas uz un pievienot līdzdalībniekus komandas glabātavām.
teams.create_repo_permission_desc=Papildus šī komanda nodrošina atļauju <strong>Izveidot glabātavu</strong>: dalībnieki apvienībā var izveidot jaunas glabātavas. teams.create_repo_permission_desc=Papildus šī komanda nodrošina atļauju <strong>Izveidot glabātavu</strong>: dalībnieki apvienībā var izveidot jaunas glabātavas.
teams.repositories=Komandas repozitoriji teams.repositories=Komandas glabātavas
teams.search_repo_placeholder=Meklēt repozitorijā… teams.search_repo_placeholder=Meklēt repozitorijā…
teams.remove_all_repos_title=Noņemt visus komandas repozitorijus teams.remove_all_repos_title=Noņemt visas komandas glabātavas
teams.remove_all_repos_desc=Šī darbība noņems visus repozitorijus no komandas. teams.remove_all_repos_desc=Šī darbība noņems visas komandas glabātavas.
teams.add_all_repos_title=Pievienot visus repozitorijus teams.add_all_repos_title=Pievienot visas glabātavas
teams.add_all_repos_desc=Šī darbība pievienos visus organizācijas repozitorijus šai komandai. teams.add_all_repos_desc=Komandai tiks pievienotas visas apvienības glabātavas.
teams.add_nonexistent_repo=Pievienojamā glabātava nepastāv, lūgums vispirms to izveidot. teams.add_nonexistent_repo=Pievienojamā glabātava nepastāv, lūgums vispirms to izveidot.
teams.add_duplicate_users=Lietotājs jau ir šajā komandā. teams.add_duplicate_users=Lietotājs jau ir šajā komandā.
teams.repos.none=Šai komandai nav piekļuves nevienam repozitorijam. teams.repos.none=Šai komandai nav piekļuves nevienam repozitorijam.
@ -3091,7 +3115,7 @@ emails.updated=E-pasta adrese atjaunināta
emails.not_updated=Neizdevās atjaunot pieprasīto e-pasta adresi: %v emails.not_updated=Neizdevās atjaunot pieprasīto e-pasta adresi: %v
emails.duplicate_active=E-pasta adrese jau ir aktīva citam lietotājam. emails.duplicate_active=E-pasta adrese jau ir aktīva citam lietotājam.
emails.change_email_header=Atjaunot e-pasta rekvizītus emails.change_email_header=Atjaunot e-pasta rekvizītus
emails.change_email_text=Vai patiešām vēlaties atjaunot šo e-pasta adresi? emails.change_email_text=Vai tiešām atjaunināt šo e-pasta adresi?
orgs.org_manage_panel=Organizāciju pārvaldība orgs.org_manage_panel=Organizāciju pārvaldība
orgs.name=Nosaukums orgs.name=Nosaukums
@ -3667,7 +3691,7 @@ settings.link.success=Glabātavas saite tika sekmīgi atjaunināta.
settings.link.error=Neizdevās atjaunot repozitorija saiti. settings.link.error=Neizdevās atjaunot repozitorija saiti.
settings.delete=Dzēst pakotni settings.delete=Dzēst pakotni
settings.delete.description=Pakotne tiks neatgriezeniski izdzēsta. settings.delete.description=Pakotne tiks neatgriezeniski izdzēsta.
settings.delete.notice=Tiks dzēsts %s (%s). Šī darbība ir neatgriezeniska. Vai vēlaties turpināt? settings.delete.notice=Tiks izdzēsta pakotne %s (%s). Šī darbība ir neatgriezeniska. Tiešām turpināt?
settings.delete.success=Pakotne tika izdzēsta. settings.delete.success=Pakotne tika izdzēsta.
settings.delete.error=Neizdevās izdzēst pakotni. settings.delete.error=Neizdevās izdzēst pakotni.
owner.settings.cargo.title=Cargo reģistra inkdess owner.settings.cargo.title=Cargo reģistra inkdess

View file

@ -2548,6 +2548,7 @@ diff.git-notes.remove-body = Deeses Anmarken word wegdaan.
issues.num_reviews_one = %d Nakieken issues.num_reviews_one = %d Nakieken
issues.summary_card_alt = Tosamenfatens-Kaart vun eenem Gefall mit de Naam »%s« im Repositorium %s issues.summary_card_alt = Tosamenfatens-Kaart vun eenem Gefall mit de Naam »%s« im Repositorium %s
issues.num_reviews_few = %d Nakiekens issues.num_reviews_few = %d Nakiekens
settings.default_update_style_desc = Normaale Vernejens-Aard, wat bruukt word, um Haalvörslagens to vernejen, wat achter de Grund-Twieg torügg sünd.
[repo.permissions] [repo.permissions]
code.read = <b>Lesen:</b> De Quelltext vun deesem Repositorium ankieken un klonen. code.read = <b>Lesen:</b> De Quelltext vun deesem Repositorium ankieken un klonen.

View file

@ -813,7 +813,7 @@ manage_emails=Gerenciar endereços de e-mail
manage_themes=Tema padrão manage_themes=Tema padrão
manage_openid=Endereços OpenID manage_openid=Endereços OpenID
email_desc=Seu endereço de e-mail principal será usado para notificações, recuperação de senha e, desde que não esteja oculto, para operações do Git baseadas na Web. email_desc=Seu endereço de e-mail principal será usado para notificações, recuperação de senha e, desde que não esteja oculto, para operações do Git baseadas na Web.
theme_desc=Este será o seu tema padrão em todo o site. theme_desc=Este tema será usado para a interface web quando você fizer login.
primary=Principal primary=Principal
activated=Ativado activated=Ativado
requires_activation=Requer ativação requires_activation=Requer ativação
@ -1094,7 +1094,7 @@ issue_labels=Etiquetas
issue_labels_helper=Selecione um conjunto de etiquetas issue_labels_helper=Selecione um conjunto de etiquetas
license=Licença license=Licença
license_helper=Selecione um arquivo de licença license_helper=Selecione um arquivo de licença
license_helper_desc=Uma licença define o que os outros podem e não podem fazer com o seu código. Não tem certeza qual é a mais adequada para o seu projeto? Veja <a target="_blank" rel="noopener noreferrer" href="%s">Escolher uma licença.</a> license_helper_desc=Uma licença define o que os outros podem e não podem fazer com o seu código. Não tem certeza qual é a mais adequada para o seu projeto? Veja <a target="_blank" rel="noopener noreferrer" href="%s">Escolher uma licença</a>.
readme=LEIA-ME readme=LEIA-ME
readme_helper=Selecione um modelo de arquivo README readme_helper=Selecione um modelo de arquivo README
readme_helper_desc=Aqui você pode escrever uma descrição completa para o seu projeto. readme_helper_desc=Aqui você pode escrever uma descrição completa para o seu projeto.
@ -2440,8 +2440,8 @@ settings.archive.header=Arquivar este repositório
settings.archive.success=O repositório foi arquivado com sucesso. settings.archive.success=O repositório foi arquivado com sucesso.
settings.archive.error=Um erro ocorreu enquanto estava sendo arquivado o repositório. Veja o log para mais detalhes. settings.archive.error=Um erro ocorreu enquanto estava sendo arquivado o repositório. Veja o log para mais detalhes.
settings.archive.error_ismirror=Você não pode arquivar um repositório espelhado. settings.archive.error_ismirror=Você não pode arquivar um repositório espelhado.
settings.archive.branchsettings_unavailable=Configurações do branch não estão disponíveis quando o repositório está arquivado. settings.archive.branchsettings_unavailable=Configurações de branch não estão disponíveis em repositórios arquivados.
settings.archive.tagsettings_unavailable=As configurações de tag não estão disponíveis se o repositório estiver arquivado. settings.archive.tagsettings_unavailable=Configurações de tag não estão disponíveis em repositórios arquivados.
settings.update_avatar_success=O avatar do repositório foi atualizado. settings.update_avatar_success=O avatar do repositório foi atualizado.
settings.lfs=LFS settings.lfs=LFS
settings.lfs_filelist=Arquivos LFS armazenados neste repositório settings.lfs_filelist=Arquivos LFS armazenados neste repositório
@ -2641,7 +2641,7 @@ settings.unarchive.success = O repositório foi desarquivado.
settings.unarchive.button = Desarquivar repositório settings.unarchive.button = Desarquivar repositório
settings.unarchive.header = Desarquivar este repositório settings.unarchive.header = Desarquivar este repositório
diff.comment.add_line_comment = Adicionar comentário na linha diff.comment.add_line_comment = Adicionar comentário na linha
new_repo_helper = Um repositório contém todos os arquivos de projeto, incluindo o histórico de revisões. Já hospeda um repositório em outra plataforma? <a href="%s">Migrar repositório</a> new_repo_helper = Um repositório contém todos os arquivos de projeto, incluindo o histórico de revisões. Já hospeda um repositório em outra plataforma? <a href="%s">Migrar repositório</a>.
blame.ignore_revs.failed = Falha ao ignorar as revisões em <a href="%s">.git-blame-ignore-revs</a>. blame.ignore_revs.failed = Falha ao ignorar as revisões em <a href="%s">.git-blame-ignore-revs</a>.
migrate.forgejo.description = Migrar dados do codeberg.org ou outras servidores Forgejo. migrate.forgejo.description = Migrar dados do codeberg.org ou outras servidores Forgejo.
commits.browse_further = Ver mais commits.browse_further = Ver mais
@ -2726,7 +2726,7 @@ comments.edit.already_changed = Falha ao salvar as alterações ao comentário.
activity.navbar.code_frequency = Frequência de código activity.navbar.code_frequency = Frequência de código
settings.protect_status_check_matched = Correspondente settings.protect_status_check_matched = Correspondente
branch.tag_collision = O ramo "%s" não pode ser criado porque já existe uma etiqueta com o mesmo nome no repositório. branch.tag_collision = O ramo "%s" não pode ser criado porque já existe uma etiqueta com o mesmo nome no repositório.
settings.archive.mirrors_unavailable = As réplicas ficarão indisponíveis se o repositório estiver arquivado. settings.archive.mirrors_unavailable = Réplicas não estão disponíveis em repositórios arquivados.
release.download_count_one = %s download release.download_count_one = %s download
settings.mirror_settings.docs.no_new_mirrors = O seu repositório está replicando alterações de ou para outro repositório. Observe que não é possível criar novas réplicas no momento. settings.mirror_settings.docs.no_new_mirrors = O seu repositório está replicando alterações de ou para outro repositório. Observe que não é possível criar novas réplicas no momento.
settings.mirror_settings.docs.pull_mirror_instructions = Para configurar uma réplica de outro repositório, consulte: settings.mirror_settings.docs.pull_mirror_instructions = Para configurar uma réplica de outro repositório, consulte:
@ -3675,18 +3675,18 @@ chef.install=Para instalar o pacote, execute o seguinte comando:
composer.registry=Configure este registro em seu arquivo <code>~/.composer/config.json</code>: composer.registry=Configure este registro em seu arquivo <code>~/.composer/config.json</code>:
composer.install=Para instalar o pacote usando o Composer, execute o seguinte comando: composer.install=Para instalar o pacote usando o Composer, execute o seguinte comando:
composer.dependencies=Dependências composer.dependencies=Dependências
composer.dependencies.development=Dependências de Desenvolvimento composer.dependencies.development=Dependências de desenvolvimento
conan.details.repository=Repositório conan.details.repository=Repositório
conan.registry=Configure este registro pela linha de comando: conan.registry=Configure este registro pela linha de comando:
conan.install=Para instalar o pacote usando o Conan, execute o seguinte comando: conan.install=Para instalar o pacote usando o Conan, execute o seguinte comando:
conda.registry=Configure este registro como um repositório Conda no arquivo <code>.condarc</code>: conda.registry=Configure este registro como um repositório Conda no arquivo <code>.condarc</code>:
conda.install=Para instalar o pacote usando o Conda, execute o seguinte comando: conda.install=Para instalar o pacote usando o Conda, execute o seguinte comando:
container.details.type=Tipo de Imagem container.details.type=Tipo de imagem
container.details.platform=Plataforma container.details.platform=Plataforma
container.pull=Puxe a imagem pela linha de comando: container.pull=Puxe a imagem pela linha de comando:
container.digest=Digest container.digest=Digest
container.multi_arch=S.O. / Arquitetura container.multi_arch=S.O. / Arquitetura
container.layers=Camadas da Imagem container.layers=Camadas da imagem
container.labels=Rótulos container.labels=Rótulos
container.labels.key=Chave container.labels.key=Chave
container.labels.value=Valor container.labels.value=Valor
@ -3714,9 +3714,9 @@ npm.registry=Configure este registro no arquivo <code>.npmrc</code> do seu proje
npm.install=Para instalar o pacote usando o npm, execute o seguinte comando: npm.install=Para instalar o pacote usando o npm, execute o seguinte comando:
npm.install2=ou adicione-o ao arquivo package.json: npm.install2=ou adicione-o ao arquivo package.json:
npm.dependencies=Dependências npm.dependencies=Dependências
npm.dependencies.development=Dependências de Desenvolvimento npm.dependencies.development=Dependências de desenvolvimento
npm.dependencies.peer=Dependências Peer npm.dependencies.peer=Dependências peer
npm.dependencies.optional=Dependências Opcionais npm.dependencies.optional=Dependências opcionais
npm.details.tag=Tag npm.details.tag=Tag
pub.install=Para instalar o pacote usando Dart, execute o seguinte comando: pub.install=Para instalar o pacote usando Dart, execute o seguinte comando:
pypi.requires=Requer Python pypi.requires=Requer Python
@ -3729,8 +3729,8 @@ rpm.repository = Informações do repositório
rpm.repository.architectures = Arquiteturas rpm.repository.architectures = Arquiteturas
rubygems.install=Para instalar o pacote usando gem, execute o seguinte comando: rubygems.install=Para instalar o pacote usando gem, execute o seguinte comando:
rubygems.install2=ou adicione-o ao Gemfile: rubygems.install2=ou adicione-o ao Gemfile:
rubygems.dependencies.runtime=Dependências de Execução rubygems.dependencies.runtime=Dependências de tempo de execução
rubygems.dependencies.development=Dependências de Desenvolvimento rubygems.dependencies.development=Dependências de desenvolvimento
rubygems.required.ruby=Requer o Ruby versão rubygems.required.ruby=Requer o Ruby versão
rubygems.required.rubygems=Requer o RubyGem versão rubygems.required.rubygems=Requer o RubyGem versão
swift.registry=Configure este registro pela linha de comando: swift.registry=Configure este registro pela linha de comando:
@ -3777,11 +3777,11 @@ owner.settings.cleanuprules.success.delete=Regra de limpeza foi excluída.
owner.settings.chef.title=Registro Chef owner.settings.chef.title=Registro Chef
owner.settings.chef.keypair=Gerar par de chaves owner.settings.chef.keypair=Gerar par de chaves
rpm.repository.multiple_groups = Este pacote está disponível em vários grupos. rpm.repository.multiple_groups = Este pacote está disponível em vários grupos.
npm.dependencies.bundle = Dependências empacotadas npm.dependencies.bundle = Dependências em bundle
registry.documentation = Para mais informações sobre o registro %s, veja <a target="_blank" rel="noopener noreferrer" href="%s">a documentação</a>. registry.documentation = Para mais informações sobre o registro %s, veja <a target="_blank" rel="noopener noreferrer" href="%s">a documentação</a>.
arch.version.replaces = Substitui arch.version.replaces = Substitui
arch.version.conflicts = Conflitos arch.version.conflicts = Conflitos
arch.version.properties = Propriedades de Versão arch.version.properties = Propriedades da versão
arch.version.description = Descrição arch.version.description = Descrição
arch.version.groups = Grupo arch.version.groups = Grupo
arch.version.provides = Fornece arch.version.provides = Fornece

View file

@ -166,6 +166,7 @@ new_org.title = Nova organização
new_repo.link = Novo repositório new_repo.link = Novo repositório
new_migrate.link = Nova migração new_migrate.link = Nova migração
new_org.link = Nova organização new_org.link = Nova organização
copy_path = Copiar caminho
[aria] [aria]
navbar=Barra de navegação navbar=Barra de navegação
@ -2847,6 +2848,7 @@ pulls.delete_after_merge.head_branch.insufficient_branch = Não tem permissão p
issues.summary_card_alt = Sumário de uma questão com o título "%s" no repositório %s issues.summary_card_alt = Sumário de uma questão com o título "%s" no repositório %s
issues.num_reviews_one = %d revisão issues.num_reviews_one = %d revisão
issues.num_reviews_few = %d revisões issues.num_reviews_few = %d revisões
editor.add_tmpl.filename = nome do ficheiro
[graphs] [graphs]
component_loading=A carregar %s... component_loading=A carregar %s...
@ -3799,6 +3801,7 @@ arch.version.checkdepends = Verificar dependências
arch.version.conflicts = Conflitos arch.version.conflicts = Conflitos
arch.version.backup = Cópia de segurança arch.version.backup = Cópia de segurança
arch.version.replaces = Substitui arch.version.replaces = Substitui
container.images.title = Imagens
[secrets] [secrets]
secrets=Segredos secrets=Segredos

View file

@ -234,7 +234,7 @@ license_desc=Всё это на <a target="_blank" rel="noopener noreferrer" hre
[install] [install]
install=Установка install=Установка
title=Начальная конфигурация title=Начальная конфигурация
docker_helper=Если вы запускаете Forgejo под Docker, пожалуйста, ознакомьтесь с <a target="_blank" rel="noopener noreferrer" href="%s">документацией</a>, прежде чем изменять любые настройки. docker_helper=Если вы запускаете Forgejo под Docker, прежде чем изменять любые настройки, пожалуйста, ознакомьтесь с <a target="_blank" rel="noopener noreferrer" href="%s">документацией</a>.
require_db_desc=Forgejo требуется MySQL, PostgreSQL, SQLite3 или TiDB (по протоколу MySQL). require_db_desc=Forgejo требуется MySQL, PostgreSQL, SQLite3 или TiDB (по протоколу MySQL).
db_title=Настройки базы данных db_title=Настройки базы данных
db_type=Тип базы данных db_type=Тип базы данных
@ -267,16 +267,16 @@ repo_path=Путь до каталога репозиториев
repo_path_helper=Все удалённые Git репозитории будут сохранены в этом каталоге. repo_path_helper=Все удалённые Git репозитории будут сохранены в этом каталоге.
lfs_path=Путь до корневого каталога Git LFS lfs_path=Путь до корневого каталога Git LFS
lfs_path_helper=В этом каталоге будут храниться файлы Git LFS. Оставьте пустым, чтобы отключить LFS. lfs_path_helper=В этом каталоге будут храниться файлы Git LFS. Оставьте пустым, чтобы отключить LFS.
run_user=Выполнение под пользователем run_user=Работа под пользователем
run_user_helper=Имя пользователя операционной системы, под которым работает Forgejo. Обратите внимание, что этот пользователь должен иметь доступ к корневому пути репозиториев. run_user_helper=Имя пользователя операционной системы, под которым работает Forgejo. Обратите внимание, что этот пользователь должен иметь доступ к корневому пути репозиториев.
domain=Домен сервера domain=Домен сервера
domain_helper=Домен или адрес хоста для сервера. domain_helper=Домен или адрес хоста для сервера.
ssh_port=Порт SSH-сервера ssh_port=Порт SSH-сервера
ssh_port_helper=Номер порта, используемый SSH-сервером. Оставьте пустым для отключения доступа по SSH. ssh_port_helper=Номер порта, используемый для входящих подключений по SSH. Оставьте пустым для отключения доступа по SSH.
http_port=Порт HTTP-сервера http_port=Порт HTTP-сервера
http_port_helper=Номер порта, используемый веб-сервером Forgejo. http_port_helper=Номер порта, используемый веб-сервером Forgejo.
app_url=Базовый URL Forgejo app_url=Базовый URL
app_url_helper=Этот параметр влияет на URL для клонирования по HTTP/HTTPS и на некоторые уведомления по эл. почте. app_url_helper=Этот параметр влияет на URL клонирования по HTTP/HTTPS и на ссылки в уведомлениях по эл. почте.
log_root_path=Путь журналов log_root_path=Путь журналов
log_root_path_helper=Файлы журнала будут записываться в этот каталог. log_root_path_helper=Файлы журнала будут записываться в этот каталог.
@ -284,9 +284,9 @@ optional_title=Дополнительные настройки
email_title=Настройки эл. почты email_title=Настройки эл. почты
smtp_addr=Адрес SMTP smtp_addr=Адрес SMTP
smtp_port=Порт SMTP smtp_port=Порт SMTP
smtp_from=Отправлять письма от smtp_from=Отправитель
smtp_from_helper=Адрес эл. почты, который будет использоваться Forgejo. Введите обычный адрес эл. почты или используйте формат "Имя" <email@example.com>. smtp_from_helper=Адрес эл. почты, который будет использоваться Forgejo. Введите обычный адрес эл. почты или используйте формат "Имя" <email@example.com>.
mailer_user=Логин SMTP mailer_user=Имя пользователя SMTP
mailer_password=Пароль SMTP mailer_password=Пароль SMTP
register_confirm=Требовать подтверждение по эл. почте для регистрации register_confirm=Требовать подтверждение по эл. почте для регистрации
mail_notify=Уведомления по эл. почте mail_notify=Уведомления по эл. почте
@ -316,7 +316,7 @@ confirm_password=Подтверждение пароля
admin_email=Адрес эл. почты admin_email=Адрес эл. почты
install_btn_confirm=Установить Forgejo install_btn_confirm=Установить Forgejo
test_git_failed=Не удалось проверить команду «git»: %v test_git_failed=Не удалось проверить команду «git»: %v
sqlite3_not_available=Эта версия Forgejo не поддерживает SQLite3. Пожалуйста, загрузите официальную бинарную сборку из %s (не сборку «gobuild»). sqlite3_not_available=Эта версия Forgejo не поддерживает SQLite3. Пожалуйста, скачайте официальную сборку из %s (не версию «gobuild»).
invalid_db_setting=Некорректные настройки базы данных: %v invalid_db_setting=Некорректные настройки базы данных: %v
invalid_db_table=Таблица «%s» базы данных некорректна: %v invalid_db_table=Таблица «%s» базы данных некорректна: %v
invalid_repo_path=Недопустимый путь к корню репозитория: %v invalid_repo_path=Недопустимый путь к корню репозитория: %v
@ -360,7 +360,7 @@ my_orgs=Организации
my_mirrors=Мои зеркала my_mirrors=Мои зеркала
view_home=Показать %s view_home=Показать %s
search_repos=Поиск репозитория… search_repos=Поиск репозитория…
filter=Другие фильтры filter=Прочие фильтры
filter_by_team_repositories=Фильтровать по репозиториям команды filter_by_team_repositories=Фильтровать по репозиториям команды
feed_of=Лента «%s» feed_of=Лента «%s»
@ -687,13 +687,13 @@ change_avatar=Изменить изображение профиля…
joined_on=Регистрация %s joined_on=Регистрация %s
repositories=Репозитории repositories=Репозитории
activity=Публичная активность activity=Публичная активность
followers_few=%d подписчики followers_few=%d подписчиков
starred=Избранные репозитории starred=Избранные репозитории
watched=Отслеживаемые репозитории watched=Отслеживаемые репозитории
code=Код code=Код
projects=Проекты projects=Проекты
overview=Обзор overview=Обзор
following_few=%d подписки following_few=%d подписок
follow=Подписаться follow=Подписаться
unfollow=Отписаться unfollow=Отписаться
user_bio=О себе user_bio=О себе
@ -810,7 +810,7 @@ password_change_disabled=Нелокальные учётные записи не
emails=Адреса эл. почты emails=Адреса эл. почты
manage_emails=Управление адресами эл. почты manage_emails=Управление адресами эл. почты
manage_themes=Тема по умолчанию manage_themes=Тема интерфейса
manage_openid=Адреса OpenID manage_openid=Адреса OpenID
email_desc=Ваш основной адрес эл. почты будет использоваться для уведомлений, восстановления пароля и, если он не скрыт, для действий с Git в веб-интерфейсе. email_desc=Ваш основной адрес эл. почты будет использоваться для уведомлений, восстановления пароля и, если он не скрыт, для действий с Git в веб-интерфейсе.
theme_desc=Эта тема оформления будет использоваться при входе на сайт под этой учётной записью. theme_desc=Эта тема оформления будет использоваться при входе на сайт под этой учётной записью.
@ -941,7 +941,7 @@ select_permissions=Выбрать разрешения
permission_no_access=Нет доступа permission_no_access=Нет доступа
permission_read=Чтение permission_read=Чтение
permission_write=Чтение и запись permission_write=Чтение и запись
access_token_desc=Выбранные области действия токена ограничивают авторизацию только соответствующими маршрутами <a href="%[1]s" target="_blank">API</a>. Читайте <a href="%[2]s" target="_blank">документацию</a> для получения дополнительной информации. access_token_desc=Выбранные области действия токена ограничивают его использование до соответствующих маршрутов <a href="%[1]s" target="_blank">API</a>. Для получения подробностей ознакомьтесь с <a href="%[2]s" target="_blank">документацией</a> .
at_least_one_permission=Необходимо выбрать хотя бы одно разрешение для создания токена at_least_one_permission=Необходимо выбрать хотя бы одно разрешение для создания токена
permissions_list=Разрешения: permissions_list=Разрешения:
@ -949,7 +949,7 @@ manage_oauth2_applications=Управление приложениями OAuth2
edit_oauth2_application=Изменить приложение OAuth2 edit_oauth2_application=Изменить приложение OAuth2
oauth2_applications_desc=Приложения OAuth2 позволяет стороннему приложению к безопасно аутентифицировать пользователей данной установки Forgejo. oauth2_applications_desc=Приложения OAuth2 позволяет стороннему приложению к безопасно аутентифицировать пользователей данной установки Forgejo.
remove_oauth2_application=Удаление приложения OAuth2 remove_oauth2_application=Удаление приложения OAuth2
remove_oauth2_application_desc=Удаление приложения OAuth2 отменит доступ ко всем подписанным токенам доступа. Продолжить? remove_oauth2_application_desc=Удаление этого приложения отменит доступ ко всем подписанным токенам доступа. Продолжить?
remove_oauth2_application_success=Приложение было успешно удалено. remove_oauth2_application_success=Приложение было успешно удалено.
create_oauth2_application=Создать новое приложение OAuth2 create_oauth2_application=Создать новое приложение OAuth2
create_oauth2_application_button=Создать приложение create_oauth2_application_button=Создать приложение
@ -1051,7 +1051,7 @@ additional_repo_units_hint_description = Показывать подсказку
pronouns_custom = Другие pronouns_custom = Другие
pronouns = Местоимения pronouns = Местоимения
pronouns_unspecified = Не указаны pronouns_unspecified = Не указаны
language.title = Язык по умолчанию language.title = Язык интерфейса
keep_activity_private.description = Ваша <a href="%s">публичная активность</a> будет видна только вам и администраторам сервера. keep_activity_private.description = Ваша <a href="%s">публичная активность</a> будет видна только вам и администраторам сервера.
language.description = Выбранный язык будет сохранён в вашей уч. записи и будет использован по умолчанию после входа. language.description = Выбранный язык будет сохранён в вашей уч. записи и будет использован по умолчанию после входа.
language.localization_project = Помогите с переводом Forgejo на свой язык! <a href="%s">Подробнее</a>. language.localization_project = Помогите с переводом Forgejo на свой язык! <a href="%s">Подробнее</a>.
@ -1065,11 +1065,11 @@ repo_size=Размер репозитория
size_format = `%[1]s: %[2]s; %[3]s: %[4]s` size_format = `%[1]s: %[2]s; %[3]s: %[4]s`
template=Шаблон template=Шаблон
template_select=Выберите шаблон template_select=Выберите шаблон
template_helper=Сделать репозиторий шаблоном template_helper=Пометить репозиторий как шаблон
template_description=Шаблонные репозитории дают возможность пользователям создавать новые репозитории с той же структурой каталогов, файлами и дополнительными настройками. template_description=Шаблонные репозитории дают возможность пользователям создавать новые репозитории с той же структурой каталогов, файлами и дополнительными настройками.
visibility=Видимость visibility=Видимость
visibility_description=Это увидят только владелец организации или участники при наличии прав. visibility_description=Он будет видим только владельцу организации и её участникам при наличии прав.
visibility_helper=Сделать репозиторий приватным visibility_helper=Частный репозиторий
visibility_helper_forced=Администратор сайта настроил параметр видимости новых репозиториев. Репозиторий приватный по умолчанию. visibility_helper_forced=Администратор сайта настроил параметр видимости новых репозиториев. Репозиторий приватный по умолчанию.
visibility_fork_helper=(Это изменит видимость всех ответвлений.) visibility_fork_helper=(Это изменит видимость всех ответвлений.)
clone_helper=Нужна помощь в клонировании? Посетите страницу <a target="_blank" rel="noopener noreferrer" href="%s">помощи</a>. clone_helper=Нужна помощь в клонировании? Посетите страницу <a target="_blank" rel="noopener noreferrer" href="%s">помощи</a>.
@ -1091,12 +1091,12 @@ repo_desc=Описание
repo_desc_helper=Добавьте краткое описание (необязательно) repo_desc_helper=Добавьте краткое описание (необязательно)
repo_lang=Язык repo_lang=Язык
repo_gitignore_helper=Выберите шаблоны .gitignore repo_gitignore_helper=Выберите шаблоны .gitignore
repo_gitignore_helper_desc=Выберите из списка шаблонов для популярных языков , какие файлы не надо отслеживать. По умолчанию в .gitignore включены типичные артефакты, создаваемые инструментами сборки каждого языка. repo_gitignore_helper_desc=Выберите шаблоны из списка для популярных языков. .gitignore определяет, какие файлы не надо отслеживать в проекте. По умолчанию в него включены типичные артефакты, создаваемые инструментами сборки каждого языка.
issue_labels=Метки issue_labels=Метки
issue_labels_helper=Выберите набор меток issue_labels_helper=Выберите набор меток
license=Лицензия license=Лицензия
license_helper=Выберите лицензию license_helper=Выберите лицензию
license_helper_desc=Лицензия определяет, что другие люди могут, а что не могут делать с вашим кодом. Не уверены, какая лицензия подходит для вашего проекта? Смотрите <a target="_blank" rel="noopener noreferrer" href="%s">Выберите лицензию</a>. license_helper_desc=Лицензия определяет, что другие могут и не могут делать с вашим кодом. Не знаете, какая лицензия подойдёт для вашего проекта? Ознакомьтесь с <a target="_blank" rel="noopener noreferrer" href="%s">Выбором лицензии</a>.
readme=README readme=README
readme_helper=Выберите шаблон README readme_helper=Выберите шаблон README
readme_helper_desc=Это место, где вы можете написать подробное описание вашего проекта. readme_helper_desc=Это место, где вы можете написать подробное описание вашего проекта.
@ -1719,8 +1719,8 @@ issues.due_date_form_add=Добавить срок выполнения
issues.due_date_form_edit=Изменить issues.due_date_form_edit=Изменить
issues.due_date_form_remove=Удалить issues.due_date_form_remove=Удалить
issues.due_date_not_set=Срок выполнения не установлен. issues.due_date_not_set=Срок выполнения не установлен.
issues.due_date_added=добавлен срок выполнения %s %s issues.due_date_added=добавлен срок выполнения %s, %s
issues.due_date_modified=срок выполнения передвинут с %[2]s на %[1]s %[3]s issues.due_date_modified=срок выполнения изменён с %[2]s на %[1]s %[3]s
issues.due_date_remove=убран срок выполнения %s %s issues.due_date_remove=убран срок выполнения %s %s
issues.due_date_overdue=Просроченные issues.due_date_overdue=Просроченные
issues.due_date_invalid=Срок выполнения недействителен или находится за пределами допустимого диапазона. Пожалуйста, используйте формат «гггг-мм-дд». issues.due_date_invalid=Срок выполнения недействителен или находится за пределами допустимого диапазона. Пожалуйста, используйте формат «гггг-мм-дд».
@ -2850,6 +2850,7 @@ issues.num_reviews_few = %d рецензий
issues.num_reviews_one = %d рецензия issues.num_reviews_one = %d рецензия
issues.summary_card_alt = Карточка со сводкой задачи "%s" в репозитории %s issues.summary_card_alt = Карточка со сводкой задачи "%s" в репозитории %s
editor.add_tmpl.filename = имя файла editor.add_tmpl.filename = имя файла
settings.default_update_style_desc = Стиль обновления отстающих ветвей запросов на слияние по умолчанию.
[graphs] [graphs]
component_loading_failed = Не удалось загрузить %s component_loading_failed = Не удалось загрузить %s
@ -3315,13 +3316,13 @@ auths.invalid_openIdConnectAutoDiscoveryURL=Неверный URL для авто
config.server_config=Конфигурация сервера config.server_config=Конфигурация сервера
config.app_name=Название сервера config.app_name=Название сервера
config.app_ver=Версия Forgejo config.app_ver=Версия Forgejo
config.app_url=Базовый URL Forgejo config.app_url=Базовый URL
config.custom_conf=Путь к файлу конфигурации config.custom_conf=Путь к файлу конфигурации
config.custom_file_root_path=Путь до каталога с файлами для персонализации config.custom_file_root_path=Путь до каталога с файлами для персонализации
config.domain=Домен сервера config.domain=Домен сервера
config.offline_mode=Локальный режим config.offline_mode=Локальный режим
config.disable_router_log=Отключение журнала маршрутизатора config.disable_router_log=Отключение журнала маршрутизатора
config.run_user=Выполнение под пользователем config.run_user=Работа под пользователем
config.run_mode=Режим работы config.run_mode=Режим работы
config.git_version=Версия git config.git_version=Версия git
config.app_data_path=Путь к данным приложения config.app_data_path=Путь к данным приложения
@ -3956,28 +3957,28 @@ fuzzy_tooltip = Включает результаты, достаточно по
type_tooltip = Тип поиска type_tooltip = Тип поиска
fuzzy = Приблизительный fuzzy = Приблизительный
match = Точный match = Точный
repo_kind = Поиск репозиториев... repo_kind = Найти репозитории...
user_kind = Поиск пользователей... user_kind = Найти пользователей...
org_kind = Поиск организаций... org_kind = Найти организации...
team_kind = Поиск команд... team_kind = Найти команды...
code_kind = Поиск по коду... code_kind = Найти в коде...
package_kind = Поиск пакетов... package_kind = Найти пакеты...
project_kind = Поиск проектов... project_kind = Найти проекты...
branch_kind = Поиск ветвей... branch_kind = Найти ветви...
commit_kind = Поиск коммитов... commit_kind = Найти коммиты...
no_results = По запросу ничего не найдено. no_results = По запросу ничего не найдено.
keyword_search_unavailable = Поиск по ключевым словам недоступен. Уточните подробности у администратора. keyword_search_unavailable = Поиск по ключевым словам недоступен. Уточните подробности у администратора сервера.
match_tooltip = Включать только результаты, точно соответствующие запросу match_tooltip = Включать только результаты, точно соответствующие запросу
code_search_unavailable = Поиск по коду сейчас недоступен. Уточните подробности у администратора. code_search_unavailable = Поиск в коде недоступен. Уточните подробности у администратора сервера.
runner_kind = Поиск исполнителей... runner_kind = Найти исполнителей...
code_search_by_git_grep = Эти результаты получены через «git grep». Результатов может быть больше, если администратор сервера включит индексатор кода. code_search_by_git_grep = Эти результаты получены через «git grep». Результатов может быть больше, если на сервере будет включен индексатор кода.
exact = Точный exact = Точный
exact_tooltip = Включает только результаты, в точности соответствующие запросу exact_tooltip = Включает только результаты, в точности соответствующие запросу
issue_kind = Поиск задач... issue_kind = Найти задачи...
pull_kind = Поиск слияний... pull_kind = Найти слияния...
union_tooltip = Включает результаты с совпавшими ключевыми словами, разделёнными пробелами union_tooltip = Включает результаты с совпавшими ключевыми словами, разделёнными пробелами
union = Обычный union = Обычный
milestone_kind = Поиск этапов... milestone_kind = Найти этапы...
regexp = Регулярное выражение regexp = Регулярное выражение
regexp_tooltip = Интерпретировать поисковый запрос как регулярное выражение regexp_tooltip = Интерпретировать поисковый запрос как регулярное выражение
@ -3988,7 +3989,7 @@ filepreview.lines = Строки с %[1]d по %[2]d в %[3]s
filepreview.truncated = Предпросмотр был обрезан filepreview.truncated = Предпросмотр был обрезан
[translation_meta] [translation_meta]
test = skip-ci routine :) test = forgejo :)
[repo.permissions] [repo.permissions]
code.write = <b>Запись:</b> отправка изменений в репозиторий, создание веток и тегов. code.write = <b>Запись:</b> отправка изменений в репозиторий, создание веток и тегов.

View file

@ -143,13 +143,13 @@ filter.clear = Очистити фільтри
filter.is_archived = Архівовано filter.is_archived = Архівовано
filter = Фільтри filter = Фільтри
toggle_menu = Перемкнути видимість меню toggle_menu = Перемкнути видимість меню
confirm_delete_artifact = Ви впевнені, що хочете видалити артефакт "%s"? confirm_delete_artifact = Ви впевнені, що хочете видалити артефакт «%s»?
artifacts = Артефакти artifacts = Артефакти
filter.not_archived = Не архівовано filter.not_archived = Не архівовано
filter.public = Загальнодоступні filter.public = Загальнодоступні
filter.private = Приватні filter.private = Приватні
more_items = Більше пунктів more_items = Більше пунктів
remove_label_str = Видалити об'єкт "%s" remove_label_str = Видалити об'єкт «%s»
new_repo.title = Новий репозиторій new_repo.title = Новий репозиторій
new_migrate.title = Нова міграція new_migrate.title = Нова міграція
new_org.title = Нова організація new_org.title = Нова організація
@ -334,7 +334,7 @@ password_algorithm=Алгоритм хешування пароля
config_location_hint = Ці опції налаштувань будуть збережені в: config_location_hint = Ці опції налаштувань будуть збережені в:
env_config_keys = Конфігурація середовища env_config_keys = Конфігурація середовища
env_config_keys_prompt = Ці змінні середовища будуть також застосовані до вашого файлу конфігурації: env_config_keys_prompt = Ці змінні середовища будуть також застосовані до вашого файлу конфігурації:
invalid_db_table = База даних "%s" недійсна: %v invalid_db_table = База даних «%s» недійсна: %v
enable_update_checker = Увімкнути перевірку оновлень enable_update_checker = Увімкнути перевірку оновлень
require_db_desc = Forgejo вимагає MySQL, PostgreSQL, SQLite3 чи TiDB (протокол MySQL). require_db_desc = Forgejo вимагає MySQL, PostgreSQL, SQLite3 чи TiDB (протокол MySQL).
allow_only_external_registration = Дозволити реєстрацію тільки через зовнішні сервіси allow_only_external_registration = Дозволити реєстрацію тільки через зовнішні сервіси
@ -645,7 +645,7 @@ Pronouns = Займенники
Biography = Про себе Biography = Про себе
FullName = Повне ім'я FullName = Повне ім'я
Website = Вебсайт Website = Вебсайт
url_error = `"%s" є недійсним посиланням.` url_error = `«%s» є недійсним посиланням.`
To = Назва гілки To = Назва гілки
Location = Розташування Location = Розташування
AccessToken = Токен доступу AccessToken = Токен доступу
@ -861,7 +861,7 @@ oauth2_applications_desc=Програми OAuth2 дають можливість
remove_oauth2_application=Видалити програму OAuth2 remove_oauth2_application=Видалити програму OAuth2
remove_oauth2_application_desc=Видалення програми OAuth2 скасовує доступ до всіх підписаних маркерів доступу. Продовжити? remove_oauth2_application_desc=Видалення програми OAuth2 скасовує доступ до всіх підписаних маркерів доступу. Продовжити?
remove_oauth2_application_success=Програму видалено. remove_oauth2_application_success=Програму видалено.
create_oauth2_application=Створити нову програму OAuth2 create_oauth2_application=Створити новий додаток OAuth2
create_oauth2_application_button=Створити програму create_oauth2_application_button=Створити програму
oauth2_application_name=Назва програми oauth2_application_name=Назва програми
save_application=Зберегти save_application=Зберегти
@ -965,6 +965,7 @@ comment_type_group_pull_request_push = Додані коміти
permissions_public_only = Тільки публічні permissions_public_only = Тільки публічні
select_permissions = Виберіть дозволи select_permissions = Виберіть дозволи
permissions_access_all = Усі (публічні, приватні й обмежені) permissions_access_all = Усі (публічні, приватні й обмежені)
create_oauth2_application_success = Ви успішно створили новий додаток OAuth2.
[repo] [repo]
owner=Власник owner=Власник
@ -1088,7 +1089,7 @@ migrate_items_merge_requests=Запити на об'єднання
migrate_items_releases=Релізи migrate_items_releases=Релізи
migrate_repo=Перенести репозиторій migrate_repo=Перенести репозиторій
migrate.clone_address=Міграція / клонувати з URL-адреси migrate.clone_address=Міграція / клонувати з URL-адреси
migrate.clone_address_desc=URL-адреса HTTP(S) або Git "clone" існуючого репозиторія migrate.clone_address_desc=URL-адреса HTTP(S) або Git «clone» існуючого репозиторію
migrate.clone_local_path=або шлях до локального серверу migrate.clone_local_path=або шлях до локального серверу
migrate.permission_denied=Вам не дозволено імпортувати локальні репозиторії. migrate.permission_denied=Вам не дозволено імпортувати локальні репозиторії.
migrate.permission_denied_blocked=Ви не можете імпортувати з заборонених вузлів, будь ласка, попросіть адміністратора перевірити налаштування ALLOWED_DOMAINS/ALLOW_LOCALNETWORKS/BLOCKED_DOMAINS. migrate.permission_denied_blocked=Ви не можете імпортувати з заборонених вузлів, будь ласка, попросіть адміністратора перевірити налаштування ALLOWED_DOMAINS/ALLOW_LOCALNETWORKS/BLOCKED_DOMAINS.
@ -2070,7 +2071,7 @@ settings.lfs_findcommits=Знайти коміти
settings.lfs_lfs_file_no_commits=Не знайдено комітів для цього файлу LFS settings.lfs_lfs_file_no_commits=Не знайдено комітів для цього файлу LFS
settings.lfs_noattribute=Цей шлях не має атрибуту блокування в гілці за замовчуванням settings.lfs_noattribute=Цей шлях не має атрибуту блокування в гілці за замовчуванням
settings.lfs_delete=Видалити файл LFS з OID %s settings.lfs_delete=Видалити файл LFS з OID %s
settings.lfs_delete_warning=Видалення файлу LFS може спричинити помилки "Об'єкт не існує" під час перевірки. Ви впевнені? settings.lfs_delete_warning=Видалення файлу LFS може спричинити помилки «Об'єкт не існує» під час перевірки. Ви впевнені?
settings.lfs_findpointerfiles=Знайти файли-посилання settings.lfs_findpointerfiles=Знайти файли-посилання
settings.lfs_locks=Блокування settings.lfs_locks=Блокування
settings.lfs_invalid_locking_path=Неприпустимий шлях: %s settings.lfs_invalid_locking_path=Неприпустимий шлях: %s
@ -2797,15 +2798,15 @@ auths.tips.oauth2.general=Автентифікація OAuth2
auths.tip.oauth2_provider=Постачальник OAuth2 auths.tip.oauth2_provider=Постачальник OAuth2
auths.tip.bitbucket=Створіть OAuth URI на сторінці %s auths.tip.bitbucket=Створіть OAuth URI на сторінці %s
auths.tip.nextcloud=`Зареєструйте нового споживача OAuth у вашому екземплярі за допомогою наступного меню "Налаштування -> Безпека -> клієнт OAuth 2.0"` auths.tip.nextcloud=`Зареєструйте нового споживача OAuth у вашому екземплярі за допомогою наступного меню "Налаштування -> Безпека -> клієнт OAuth 2.0"`
auths.tip.dropbox=Додайте новий додаток на %s auths.tip.dropbox=Створіть новий додаток на %s
auths.tip.facebook=`Створіть новий додаток на %s і додайте модуль "Facebook Login"` auths.tip.facebook=Зареєструйте новий додаток на %s і додайте модуль «Facebook Login»
auths.tip.github=Додайте OAuth додаток на %s auths.tip.github=Зареєструйте новий додаток OAuth на %s
auths.tip.gitlab=Додайте новий додаток на https://gitlab.com/profile/applications auths.tip.gitlab=Додайте новий додаток на https://gitlab.com/profile/applications
auths.tip.google_plus=Отримайте облікові дані клієнта OAuth2 в консолі Google API на сторінці %s auths.tip.google_plus=Отримайте облікові дані клієнта OAuth2 в консолі Google API на сторінці %s
auths.tip.openid_connect=Використовуйте OpenID Connect Discovery URL (<server>/.well-known/openid-configuration) для автоматичної настройки входу OAuth auths.tip.openid_connect=Використовуйте OpenID Connect Discovery URL (<server>/.well-known/openid-configuration) для автоматичної настройки входу OAuth
auths.tip.twitter=Перейдіть на %s, створіть програму і переконайтеся, що включена опція «Дозволити цю програму для входу в систему за допомогою Twitter» auths.tip.twitter=Перейдіть на %s, створіть програму і переконайтеся, що включена опція «Дозволити цю програму для входу в систему за допомогою Twitter»
auths.tip.discord=Зареєструйте новий додаток на %s auths.tip.discord=Зареєструйте новий додаток на %s
auths.tip.yandex=`Створіть нову програму в %s. Виберіть наступні дозволи з "Yandex. assport API": "Доступ до адреси електронної пошти", "Доступ до аватара" і "Доступ до імені користувача, імені та прізвища, статі"` auths.tip.yandex=Створіть новий додаток на %s. Виберіть наступні дозволи з «Yandex. assport API»: «Доступ до адреси електронної пошти», «Доступ до аватара» і «Доступ до імені користувача, імені та прізвища, статі»
auths.tip.mastodon=Введіть URL спеціального екземпляра для екземпляра mastodon, який ви хочете автентифікувати за допомогою (або використовувати за замовчуванням) auths.tip.mastodon=Введіть URL спеціального екземпляра для екземпляра mastodon, який ви хочете автентифікувати за допомогою (або використовувати за замовчуванням)
auths.edit=Редагувати джерело автентифікації auths.edit=Редагувати джерело автентифікації
auths.activated=Це джерело авторизації активоване auths.activated=Це джерело авторизації активоване
@ -2830,7 +2831,7 @@ config.disable_router_log=Вимкнути логування роутеру
config.run_user=Користувач, від якого запустити config.run_user=Користувач, від якого запустити
config.run_mode=Режим виконання config.run_mode=Режим виконання
config.git_version=Версія Git config.git_version=Версія Git
config.repo_root_path=Кореневий шлях репозиторія config.repo_root_path=Шлях до кореня репозиторію
config.lfs_root_path=Кореневий шлях LFS config.lfs_root_path=Кореневий шлях LFS
config.log_file_root_path=Шлях до лог файлу config.log_file_root_path=Шлях до лог файлу
config.script_type=Тип скрипта config.script_type=Тип скрипта
@ -3020,6 +3021,8 @@ monitor.queue.settings.desc = Пули динамічно зростають у
monitor.queue.settings.remove_all_items_done = Усі елементи в черзі видалено. monitor.queue.settings.remove_all_items_done = Усі елементи в черзі видалено.
monitor.queue.settings.remove_all_items = Видалити всі monitor.queue.settings.remove_all_items = Видалити всі
config.app_slogan = Гасло екземпляра config.app_slogan = Гасло екземпляра
auths.tip.gitea = Зареєструйте новий додаток OAuth. Інструкцію можна знайти на %s
auths.tip.gitlab_new = Зареєструйте новий додаток на %s
[action] [action]
@ -3307,7 +3310,7 @@ milestone_kind = Шукати віхи...
commit_kind = Шукати коментарі... commit_kind = Шукати коментарі...
no_results = Не знайдено відповідних результатів. no_results = Не знайдено відповідних результатів.
keyword_search_unavailable = Пошук за ключовими словами наразі недоступний. Будь ласка, зв'яжіться з адміністратором сайту. keyword_search_unavailable = Пошук за ключовими словами наразі недоступний. Будь ласка, зв'яжіться з адміністратором сайту.
code_search_by_git_grep = Поточні результати пошуку коду надаються з "git grep". Тут можуть бути кращі результати, якщо адміністратор сайту ввімкнув індексацію коду. code_search_by_git_grep = Поточні результати пошуку коду надаються з «git grep». Тут можуть бути кращі результати, якщо адміністратор сайту ввімкнув індексацію коду.
package_kind = Шукати пакунки... package_kind = Шукати пакунки...
project_kind = Шукати проєкти... project_kind = Шукати проєкти...
branch_kind = Шукати гілки... branch_kind = Шукати гілки...

View file

@ -2750,7 +2750,7 @@ pulls.made_using_agit = AGit
activity.navbar.pulse = 动态 activity.navbar.pulse = 动态
activity.navbar.code_frequency = 代码频率 activity.navbar.code_frequency = 代码频率
activity.navbar.recent_commits = 近期提交 activity.navbar.recent_commits = 近期提交
pulls.agit_explanation = 该合并请求是用 AGit 创建的。AGit 是一种可以让贡献者直接通过 “git push” 提出更改代码而不需要派生或建立新分支 pulls.agit_explanation = 该合并请求是用 AGit 工作流创建的。使用 AGit贡献者无需派生或创建分支就可以直接通过 “git push” 提出更改代码
error.broken_git_hook = 该仓库的 Git 钩子似乎已经损坏,请按照 <a target="_blank" rel="noreferrer" href="%s">此文档</a>来修复这些问题,然后推送一些提交来刷新状态。 error.broken_git_hook = 该仓库的 Git 钩子似乎已经损坏,请按照 <a target="_blank" rel="noreferrer" href="%s">此文档</a>来修复这些问题,然后推送一些提交来刷新状态。
pulls.merged_title_desc_one = 已将来自 <code>%[2]s</code> 的 %[1]d 提交合并入 <code>%[3]s</code> %[4]s pulls.merged_title_desc_one = 已将来自 <code>%[2]s</code> 的 %[1]d 提交合并入 <code>%[3]s</code> %[4]s
commits.search_branch = 此分支 commits.search_branch = 此分支

1427
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -55,7 +55,7 @@
"vue-loader": "17.4.2", "vue-loader": "17.4.2",
"vue3-calendar-heatmap": "2.0.5", "vue3-calendar-heatmap": "2.0.5",
"webpack": "5.97.1", "webpack": "5.97.1",
"webpack-cli": "5.1.4", "webpack-cli": "6.0.1",
"wrap-ansi": "9.0.0" "wrap-ansi": "9.0.0"
}, },
"devDependencies": { "devDependencies": {
@ -65,15 +65,15 @@
"@stoplight/spectral-cli": "6.14.2", "@stoplight/spectral-cli": "6.14.2",
"@stylistic/eslint-plugin-js": "2.12.1", "@stylistic/eslint-plugin-js": "2.12.1",
"@stylistic/stylelint-plugin": "3.1.1", "@stylistic/stylelint-plugin": "3.1.1",
"@typescript-eslint/parser": "8.18.1", "@typescript-eslint/parser": "8.18.2",
"@vitejs/plugin-vue": "5.1.5", "@vitejs/plugin-vue": "5.1.5",
"@vitest/coverage-v8": "2.1.8", "@vitest/coverage-v8": "2.1.8",
"@vitest/eslint-plugin": "1.1.16", "@vitest/eslint-plugin": "1.1.20",
"@vue/test-utils": "2.4.6", "@vue/test-utils": "2.4.6",
"eslint": "9.17.0", "eslint": "9.17.0",
"eslint-import-resolver-typescript": "3.7.0", "eslint-import-resolver-typescript": "3.7.0",
"eslint-plugin-array-func": "5.0.2", "eslint-plugin-array-func": "5.0.2",
"eslint-plugin-import-x": "4.5.1", "eslint-plugin-import-x": "4.6.1",
"eslint-plugin-no-jquery": "3.1.0", "eslint-plugin-no-jquery": "3.1.0",
"eslint-plugin-no-use-extend-native": "0.7.2", "eslint-plugin-no-use-extend-native": "0.7.2",
"eslint-plugin-playwright": "2.1.0", "eslint-plugin-playwright": "2.1.0",
@ -95,7 +95,7 @@
"stylelint-value-no-unknown-custom-properties": "6.0.1", "stylelint-value-no-unknown-custom-properties": "6.0.1",
"svgo": "3.2.0", "svgo": "3.2.0",
"typescript": "5.7.2", "typescript": "5.7.2",
"typescript-eslint": "8.18.1", "typescript-eslint": "8.18.2",
"vite-string-plugin": "1.3.4", "vite-string-plugin": "1.3.4",
"vitest": "2.1.8" "vitest": "2.1.8"
}, },

79
poetry.lock generated
View file

@ -2,13 +2,13 @@
[[package]] [[package]]
name = "click" name = "click"
version = "8.1.7" version = "8.1.8"
description = "Composable command line interface toolkit" description = "Composable command line interface toolkit"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"},
{file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"},
] ]
[package.dependencies] [package.dependencies]
@ -59,33 +59,33 @@ six = ">=1.13.0"
[[package]] [[package]]
name = "djlint" name = "djlint"
version = "1.36.3" version = "1.36.4"
description = "HTML Template Linter and Formatter" description = "HTML Template Linter and Formatter"
optional = false optional = false
python-versions = ">=3.9" python-versions = ">=3.9"
files = [ files = [
{file = "djlint-1.36.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2ae7c620b58e16d6bf003bd7de3f71376a7a3daa79dc02e77f3726d5a75243f2"}, {file = "djlint-1.36.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a2dfb60883ceb92465201bfd392291a7597c6752baede6fbb6f1980cac8d6c5c"},
{file = "djlint-1.36.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e155ce0970d4a28d0a2e9f2e106733a2ad05910eee90e056b056d48049e4a97b"}, {file = "djlint-1.36.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4bc6a1320c0030244b530ac200642f883d3daa451a115920ef3d56d08b644292"},
{file = "djlint-1.36.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8e8bb0406e60cc696806aa6226df137618f3889c72f2dbdfa76c908c99151579"}, {file = "djlint-1.36.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3164a048c7bb0baf042387b1e33f9bbbf99d90d1337bb4c3d66eb0f96f5400a1"},
{file = "djlint-1.36.3-cp310-cp310-win_amd64.whl", hash = "sha256:76d32faf988ad58ef2e7a11d04046fc984b98391761bf1b61f9a6044da53d414"}, {file = "djlint-1.36.4-cp310-cp310-win_amd64.whl", hash = "sha256:3196d5277da5934962d67ad6c33a948ba77a7b6eadf064648bef6ee5f216b03c"},
{file = "djlint-1.36.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:32f7a5834000fff22e94d1d35f95aaf2e06f2af2cae18af0ed2a4e215d60e730"}, {file = "djlint-1.36.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d68da0ed10ee9ca1e32e225cbb8e9b98bf7e6f8b48a8e4836117b6605b88cc7"},
{file = "djlint-1.36.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3eb1b9c0be499e63e8822a051e7e55f188ff1ab8172a85d338a8ae21c872060e"}, {file = "djlint-1.36.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c0478d5392247f1e6ee29220bbdbf7fb4e1bc0e7e83d291fda6fb926c1787ba7"},
{file = "djlint-1.36.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c2e0dd1f26eb472b8c84eb70d6482877b6497a1fd031d7534864088f016d5ea"}, {file = "djlint-1.36.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:962f7b83aee166e499eff916d631c6dde7f1447d7610785a60ed2a75a5763483"},
{file = "djlint-1.36.3-cp311-cp311-win_amd64.whl", hash = "sha256:a06b531ab9d049c46ad4d2365d1857004a1a9dd0c23c8eae94aa0d233c6ec00d"}, {file = "djlint-1.36.4-cp311-cp311-win_amd64.whl", hash = "sha256:53cbc450aa425c832f09bc453b8a94a039d147b096740df54a3547fada77ed08"},
{file = "djlint-1.36.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e66361a865e5e5a4bbcb40f56af7f256fd02cbf9d48b763a40172749cc294084"}, {file = "djlint-1.36.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ff9faffd7d43ac20467493fa71d5355b5b330a00ade1c4d1e859022f4195223b"},
{file = "djlint-1.36.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:36e102b80d83e9ac2e6be9a9ded32fb925945f6dbc7a7156e4415de1b0aa0dba"}, {file = "djlint-1.36.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:79489e262b5ac23a8dfb7ca37f1eea979674cfc2d2644f7061d95bea12c38f7e"},
{file = "djlint-1.36.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9ac4b7370d80bd82281e57a470de8923ac494ffb571b89d8787cef57c738c69a"}, {file = "djlint-1.36.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e58c5fa8c6477144a0be0a87273706a059e6dd0d6efae01146ae8c29cdfca675"},
{file = "djlint-1.36.3-cp312-cp312-win_amd64.whl", hash = "sha256:107cc56bbef13d60cc0ae774a4d52881bf98e37c02412e573827a3e549217e3a"}, {file = "djlint-1.36.4-cp312-cp312-win_amd64.whl", hash = "sha256:bb6903777bf3124f5efedcddf1f4716aef097a7ec4223fc0fa54b865829a6e08"},
{file = "djlint-1.36.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2a9f51971d6e63c41ea9b3831c928e1f21ae6fe57e87a3452cfe672d10232433"}, {file = "djlint-1.36.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ead475013bcac46095b1bbc8cf97ed2f06e83422335734363f8a76b4ba7e47c2"},
{file = "djlint-1.36.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:080c98714b55d8f0fef5c42beaee8247ebb2e3d46b0936473bd6c47808bb6302"}, {file = "djlint-1.36.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6c601dfa68ea253311deb4a29a7362b7a64933bdfcfb5a06618f3e70ad1fa835"},
{file = "djlint-1.36.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f65a80e0b5cb13d357ea51ca6570b34c2d9d18974c1e57142de760ea27d49ed0"}, {file = "djlint-1.36.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bda5014f295002363381969864addeb2db13955f1b26e772657c3b273ed7809f"},
{file = "djlint-1.36.3-cp313-cp313-win_amd64.whl", hash = "sha256:95ef6b67ef7f2b90d9434bba37d572031079001dc8524add85c00ef0386bda1e"}, {file = "djlint-1.36.4-cp313-cp313-win_amd64.whl", hash = "sha256:16ce37e085afe5a30953b2bd87cbe34c37843d94c701fc68a2dda06c1e428ff4"},
{file = "djlint-1.36.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8e2317a32094d525bc41cd11c8dc064bf38d1b442c99cc3f7c4a2616b5e6ce6e"}, {file = "djlint-1.36.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:89678661888c03d7bc6cadd75af69db29962b5ecbf93a81518262f5c48329f04"},
{file = "djlint-1.36.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e82266c28793cd15f97b93535d72bfbc77306eaaf6b210dd90910383a814ee6c"}, {file = "djlint-1.36.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5b01a98df3e1ab89a552793590875bc6e954cad661a9304057db75363d519fa0"},
{file = "djlint-1.36.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01b2101c2d1b079e8d545e6d9d03487fcca14d2371e44cbfdedee15b0bf4567c"}, {file = "djlint-1.36.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dabbb4f7b93223d471d09ae34ed515fef98b2233cbca2449ad117416c44b1351"},
{file = "djlint-1.36.3-cp39-cp39-win_amd64.whl", hash = "sha256:15cde63ef28beb5194ff4137883025f125676ece1b574b64a3e1c6daed734639"}, {file = "djlint-1.36.4-cp39-cp39-win_amd64.whl", hash = "sha256:7a483390d17e44df5bc23dcea29bdf6b63f3ed8b4731d844773a4829af4f5e0b"},
{file = "djlint-1.36.3-py3-none-any.whl", hash = "sha256:0c05cd5b76785de2c41a2420c06ffd112800bfc0f9c0f399cc7cea7c42557f4c"}, {file = "djlint-1.36.4-py3-none-any.whl", hash = "sha256:e9699b8ac3057a6ed04fb90835b89bee954ed1959c01541ce4f8f729c938afdd"},
{file = "djlint-1.36.3.tar.gz", hash = "sha256:d85735da34bc7ac93ad8ef9b4822cc2a23d5f0ce33f25438737b8dca1d404f78"}, {file = "djlint-1.36.4.tar.gz", hash = "sha256:17254f218b46fe5a714b224c85074c099bcb74e3b2e1f15c2ddc2cf415a408a1"},
] ]
[package.dependencies] [package.dependencies]
@ -99,15 +99,17 @@ pyyaml = ">=6"
regex = ">=2023" regex = ">=2023"
tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""} tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""}
tqdm = ">=4.62.2" tqdm = ">=4.62.2"
typing-extensions = {version = ">=3.6.6", markers = "python_version < \"3.11\""}
[[package]] [[package]]
name = "editorconfig" name = "editorconfig"
version = "0.12.4" version = "0.17.0"
description = "EditorConfig File Locator and Interpreter for Python" description = "EditorConfig File Locator and Interpreter for Python"
optional = false optional = false
python-versions = "*" python-versions = "*"
files = [ files = [
{file = "EditorConfig-0.12.4.tar.gz", hash = "sha256:24857fa1793917dd9ccf0c7810a07e05404ce9b823521c7dce22a4fb5d125f80"}, {file = "EditorConfig-0.17.0-py3-none-any.whl", hash = "sha256:fe491719c5f65959ec00b167d07740e7ffec9a3f362038c72b289330b9991dfc"},
{file = "editorconfig-0.17.0.tar.gz", hash = "sha256:8739052279699840065d3a9f5c125d7d5a98daeefe53b0e5274261d77cb49aa2"},
] ]
[[package]] [[package]]
@ -316,13 +318,13 @@ files = [
[[package]] [[package]]
name = "six" name = "six"
version = "1.16.0" version = "1.17.0"
description = "Python 2 and 3 compatibility utilities" description = "Python 2 and 3 compatibility utilities"
optional = false optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
files = [ files = [
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"},
{file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"},
] ]
[[package]] [[package]]
@ -387,6 +389,17 @@ notebook = ["ipywidgets (>=6)"]
slack = ["slack-sdk"] slack = ["slack-sdk"]
telegram = ["requests"] telegram = ["requests"]
[[package]]
name = "typing-extensions"
version = "4.12.2"
description = "Backported and Experimental Type Hints for Python 3.8+"
optional = false
python-versions = ">=3.8"
files = [
{file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"},
{file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"},
]
[[package]] [[package]]
name = "yamllint" name = "yamllint"
version = "1.35.1" version = "1.35.1"
@ -408,4 +421,4 @@ dev = ["doc8", "flake8", "flake8-import-order", "rstcheck[sphinx]", "sphinx"]
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = "^3.10" python-versions = "^3.10"
content-hash = "23017e1bfd215dcbb046aaf68d4d2668737e17c687e6655be46e9bfd9a3df4c5" content-hash = "64588702d556674c109df1bacaac08353a40f0863e7e72513d22f197f0c340c4"

View file

@ -5,7 +5,7 @@ package-mode = false
python = "^3.10" python = "^3.10"
[tool.poetry.group.dev.dependencies] [tool.poetry.group.dev.dependencies]
djlint = "1.36.3" djlint = "1.36.4"
yamllint = "1.35.1" yamllint = "1.35.1"
codespell = "^2.2.6" codespell = "^2.2.6"

View file

View file

@ -937,6 +937,7 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error {
AllowRebaseUpdate: true, AllowRebaseUpdate: true,
DefaultDeleteBranchAfterMerge: false, DefaultDeleteBranchAfterMerge: false,
DefaultMergeStyle: repo_model.MergeStyleMerge, DefaultMergeStyle: repo_model.MergeStyleMerge,
DefaultUpdateStyle: repo_model.UpdateStyleMerge,
DefaultAllowMaintainerEdit: false, DefaultAllowMaintainerEdit: false,
} }
} else { } else {
@ -976,6 +977,9 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error {
if opts.DefaultMergeStyle != nil { if opts.DefaultMergeStyle != nil {
config.DefaultMergeStyle = repo_model.MergeStyle(*opts.DefaultMergeStyle) config.DefaultMergeStyle = repo_model.MergeStyle(*opts.DefaultMergeStyle)
} }
if opts.DefaultUpdateStyle != nil {
config.DefaultUpdateStyle = repo_model.UpdateStyle(*opts.DefaultUpdateStyle)
}
if opts.DefaultAllowMaintainerEdit != nil { if opts.DefaultAllowMaintainerEdit != nil {
config.DefaultAllowMaintainerEdit = *opts.DefaultAllowMaintainerEdit config.DefaultAllowMaintainerEdit = *opts.DefaultAllowMaintainerEdit
} }

View file

@ -35,6 +35,7 @@ func Code(ctx *context.Context) {
language := ctx.FormTrim("l") language := ctx.FormTrim("l")
keyword := ctx.FormTrim("q") keyword := ctx.FormTrim("q")
path := ctx.FormTrim("path")
isFuzzy := ctx.FormOptionalBool("fuzzy").ValueOrDefault(true) isFuzzy := ctx.FormOptionalBool("fuzzy").ValueOrDefault(true)
if mode := ctx.FormTrim("mode"); len(mode) > 0 { if mode := ctx.FormTrim("mode"); len(mode) > 0 {
@ -91,6 +92,7 @@ func Code(ctx *context.Context) {
Keyword: keyword, Keyword: keyword,
IsKeywordFuzzy: isFuzzy, IsKeywordFuzzy: isFuzzy,
Language: language, Language: language,
Filename: path,
Paginator: &db.ListOptions{ Paginator: &db.ListOptions{
Page: page, Page: page,
PageSize: setting.UI.RepoSearchPagingNum, PageSize: setting.UI.RepoSearchPagingNum,

View file

@ -5,6 +5,7 @@ package actions
import ( import (
"bytes" "bytes"
stdCtx "context"
"fmt" "fmt"
"net/http" "net/http"
"slices" "slices"
@ -224,7 +225,7 @@ func List(ctx *context.Context) {
return return
} }
if err := loadIsRefDeleted(ctx, runs); err != nil { if err := loadIsRefDeleted(ctx, ctx.Repo.Repository.ID, runs); err != nil {
log.Error("LoadIsRefDeleted", err) log.Error("LoadIsRefDeleted", err)
} }
@ -254,7 +255,7 @@ func List(ctx *context.Context) {
// loadIsRefDeleted loads the IsRefDeleted field for each run in the list. // loadIsRefDeleted loads the IsRefDeleted field for each run in the list.
// TODO: move this function to models/actions/run_list.go but now it will result in a circular import. // TODO: move this function to models/actions/run_list.go but now it will result in a circular import.
func loadIsRefDeleted(ctx *context.Context, runs actions_model.RunList) error { func loadIsRefDeleted(ctx stdCtx.Context, repoID int64, runs actions_model.RunList) error {
branches := make(container.Set[string], len(runs)) branches := make(container.Set[string], len(runs))
for _, run := range runs { for _, run := range runs {
refName := git.RefName(run.Ref) refName := git.RefName(run.Ref)
@ -266,14 +267,14 @@ func loadIsRefDeleted(ctx *context.Context, runs actions_model.RunList) error {
return nil return nil
} }
branchInfos, err := git_model.GetBranches(ctx, ctx.Repo.Repository.ID, branches.Values(), false) branchInfos, err := git_model.GetBranches(ctx, repoID, branches.Values(), false)
if err != nil { if err != nil {
return err return err
} }
branchSet := git_model.BranchesToNamesSet(branchInfos) branchSet := git_model.BranchesToNamesSet(branchInfos)
for _, run := range runs { for _, run := range runs {
refName := git.RefName(run.Ref) refName := git.RefName(run.Ref)
if refName.IsBranch() && !branchSet.Contains(run.Ref) { if refName.IsBranch() && !branchSet.Contains(refName.ShortName()) {
run.IsRefDeleted = true run.IsRefDeleted = true
} }
} }

View file

@ -0,0 +1,33 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package actions
import (
"testing"
actions_model "code.gitea.io/gitea/models/actions"
"code.gitea.io/gitea/models/db"
unittest "code.gitea.io/gitea/models/unittest"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func Test_loadIsRefDeleted(t *testing.T) {
unittest.PrepareTestEnv(t)
runs, total, err := db.FindAndCount[actions_model.ActionRun](db.DefaultContext,
actions_model.FindRunOptions{RepoID: 4, Ref: "refs/heads/test"})
require.NoError(t, err)
assert.Len(t, runs, 1)
assert.EqualValues(t, 1, total)
for _, run := range runs {
assert.False(t, run.IsRefDeleted)
}
require.NoError(t, loadIsRefDeleted(db.DefaultContext, 4, runs))
for _, run := range runs {
assert.True(t, run.IsRefDeleted)
}
}

View file

@ -0,0 +1,14 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package actions
import (
"testing"
"code.gitea.io/gitea/models/unittest"
)
func TestMain(m *testing.M) {
unittest.MainTest(m)
}

View file

@ -1918,6 +1918,21 @@ func ViewIssue(ctx *context.Context) {
ctx.Data["MergeStyle"] = mergeStyle ctx.Data["MergeStyle"] = mergeStyle
var updateStyle repo_model.UpdateStyle
// Check correct values and select default
if ms, ok := ctx.Data["UpdateStyle"].(repo_model.UpdateStyle); !ok ||
!prConfig.IsUpdateStyleAllowed(ms) {
defaultUpdateStyle := prConfig.GetDefaultUpdateStyle()
if prConfig.IsUpdateStyleAllowed(defaultUpdateStyle) && !ok {
updateStyle = defaultUpdateStyle
} else if prConfig.AllowMerge {
updateStyle = repo_model.UpdateStyleMerge
} else if prConfig.AllowRebase {
updateStyle = repo_model.UpdateStyleRebase
}
}
ctx.Data["UpdateStyle"] = updateStyle
defaultMergeMessage, defaultMergeBody, err := pull_service.GetDefaultMergeMessage(ctx, ctx.Repo.GitRepo, pull, mergeStyle) defaultMergeMessage, defaultMergeBody, err := pull_service.GetDefaultMergeMessage(ctx, ctx.Repo.GitRepo, pull, mergeStyle)
if err != nil { if err != nil {
ctx.ServerError("GetDefaultMergeMessage", err) ctx.ServerError("GetDefaultMergeMessage", err)

View file

@ -54,6 +54,7 @@ func Search(ctx *context.Context) {
language := ctx.FormTrim("l") language := ctx.FormTrim("l")
keyword := ctx.FormTrim("q") keyword := ctx.FormTrim("q")
path := ctx.FormTrim("path")
mode := ExactSearchMode mode := ExactSearchMode
if modeStr := ctx.FormString("mode"); len(modeStr) > 0 { if modeStr := ctx.FormString("mode"); len(modeStr) > 0 {
mode = searchModeFromString(modeStr) mode = searchModeFromString(modeStr)
@ -63,6 +64,7 @@ func Search(ctx *context.Context) {
ctx.Data["Keyword"] = keyword ctx.Data["Keyword"] = keyword
ctx.Data["Language"] = language ctx.Data["Language"] = language
ctx.Data["CodeSearchPath"] = path
ctx.Data["CodeSearchMode"] = mode.String() ctx.Data["CodeSearchMode"] = mode.String()
ctx.Data["PageIsViewCode"] = true ctx.Data["PageIsViewCode"] = true
@ -86,6 +88,7 @@ func Search(ctx *context.Context) {
Keyword: keyword, Keyword: keyword,
IsKeywordFuzzy: mode == FuzzySearchMode, IsKeywordFuzzy: mode == FuzzySearchMode,
Language: language, Language: language,
Filename: path,
Paginator: &db.ListOptions{ Paginator: &db.ListOptions{
Page: page, Page: page,
PageSize: setting.UI.RepoSearchPagingNum, PageSize: setting.UI.RepoSearchPagingNum,
@ -100,11 +103,12 @@ func Search(ctx *context.Context) {
} else { } else {
ctx.Data["CodeIndexerUnavailable"] = !code_indexer.IsAvailable(ctx) ctx.Data["CodeIndexerUnavailable"] = !code_indexer.IsAvailable(ctx)
} }
ctx.Data["CodeSearchOptions"] = []string{"exact", "fuzzy"} ctx.Data["CodeSearchOptions"] = code_indexer.CodeSearchOptions
} else { } else {
grepOpt := git.GrepOptions{ grepOpt := git.GrepOptions{
ContextLineNumber: 1, ContextLineNumber: 1,
RefName: ctx.Repo.RefName, RefName: ctx.Repo.RefName,
Filename: path,
} }
switch mode { switch mode {
case FuzzySearchMode: case FuzzySearchMode:
@ -130,10 +134,12 @@ func Search(ctx *context.Context) {
// UpdatedUnix: not supported yet // UpdatedUnix: not supported yet
// Language: not supported yet // Language: not supported yet
// Color: not supported yet // Color: not supported yet
Lines: code_indexer.HighlightSearchResultCode(r.Filename, r.LineNumbers, r.HighlightedRanges, strings.Join(r.LineCodes, "\n")), Lines: code_indexer.HighlightSearchResultCode(
r.Filename, r.LineNumbers, r.HighlightedRanges,
strings.Join(r.LineCodes, "\n")),
}) })
} }
ctx.Data["CodeSearchOptions"] = []string{"exact", "union", "regexp"} ctx.Data["CodeSearchOptions"] = git.GrepSearchOptions
} }
ctx.Data["CodeIndexerDisabled"] = !setting.Indexer.RepoIndexerEnabled ctx.Data["CodeIndexerDisabled"] = !setting.Indexer.RepoIndexerEnabled

View file

@ -262,6 +262,7 @@ func UnitsPost(ctx *context.Context) {
AllowRebaseUpdate: form.PullsAllowRebaseUpdate, AllowRebaseUpdate: form.PullsAllowRebaseUpdate,
DefaultDeleteBranchAfterMerge: form.DefaultDeleteBranchAfterMerge, DefaultDeleteBranchAfterMerge: form.DefaultDeleteBranchAfterMerge,
DefaultMergeStyle: repo_model.MergeStyle(form.PullsDefaultMergeStyle), DefaultMergeStyle: repo_model.MergeStyle(form.PullsDefaultMergeStyle),
DefaultUpdateStyle: repo_model.UpdateStyle(form.PullsDefaultUpdateStyle),
DefaultAllowMaintainerEdit: form.DefaultAllowMaintainerEdit, DefaultAllowMaintainerEdit: form.DefaultAllowMaintainerEdit,
}, },
}) })

View file

@ -39,6 +39,7 @@ import (
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/highlight" "code.gitea.io/gitea/modules/highlight"
code_indexer "code.gitea.io/gitea/modules/indexer/code"
"code.gitea.io/gitea/modules/lfs" "code.gitea.io/gitea/modules/lfs"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup"
@ -1152,6 +1153,12 @@ PostRecentBranchCheck:
ctx.Data["TreeNames"] = treeNames ctx.Data["TreeNames"] = treeNames
ctx.Data["BranchLink"] = branchLink ctx.Data["BranchLink"] = branchLink
ctx.Data["CodeIndexerDisabled"] = !setting.Indexer.RepoIndexerEnabled ctx.Data["CodeIndexerDisabled"] = !setting.Indexer.RepoIndexerEnabled
if setting.Indexer.RepoIndexerEnabled {
ctx.Data["CodeIndexerUnavailable"] = !code_indexer.IsAvailable(ctx)
ctx.Data["CodeSearchOptions"] = code_indexer.CodeSearchOptions
} else {
ctx.Data["CodeSearchOptions"] = git.GrepSearchOptions
}
ctx.HTML(http.StatusOK, tplRepoHome) ctx.HTML(http.StatusOK, tplRepoHome)
} }

View file

@ -39,6 +39,7 @@ func CodeSearch(ctx *context.Context) {
language := ctx.FormTrim("l") language := ctx.FormTrim("l")
keyword := ctx.FormTrim("q") keyword := ctx.FormTrim("q")
path := ctx.FormTrim("path")
isFuzzy := ctx.FormOptionalBool("fuzzy").ValueOrDefault(true) isFuzzy := ctx.FormOptionalBool("fuzzy").ValueOrDefault(true)
if mode := ctx.FormTrim("mode"); len(mode) > 0 { if mode := ctx.FormTrim("mode"); len(mode) > 0 {
@ -88,6 +89,7 @@ func CodeSearch(ctx *context.Context) {
Keyword: keyword, Keyword: keyword,
IsKeywordFuzzy: isFuzzy, IsKeywordFuzzy: isFuzzy,
Language: language, Language: language,
Filename: path,
Paginator: &db.ListOptions{ Paginator: &db.ListOptions{
Page: page, Page: page,
PageSize: setting.UI.RepoSearchPagingNum, PageSize: setting.UI.RepoSearchPagingNum,

View file

@ -29,6 +29,11 @@ func ToAPIPullRequest(ctx context.Context, pr *issues_model.PullRequest, doer *u
err error err error
) )
if err = pr.LoadIssue(ctx); err != nil {
log.Error("pr.LoadIssue[%d]: %v", pr.ID, err)
return nil
}
if err = pr.Issue.LoadRepo(ctx); err != nil { if err = pr.Issue.LoadRepo(ctx); err != nil {
log.Error("pr.Issue.LoadRepo[%d]: %v", pr.ID, err) log.Error("pr.Issue.LoadRepo[%d]: %v", pr.ID, err)
return nil return nil

View file

@ -101,6 +101,7 @@ func innerToRepo(ctx context.Context, repo *repo_model.Repository, permissionInR
allowRebaseUpdate := false allowRebaseUpdate := false
defaultDeleteBranchAfterMerge := false defaultDeleteBranchAfterMerge := false
defaultMergeStyle := repo_model.MergeStyleMerge defaultMergeStyle := repo_model.MergeStyleMerge
defaultUpdateStyle := repo_model.UpdateStyleMerge
defaultAllowMaintainerEdit := false defaultAllowMaintainerEdit := false
if unit, err := repo.GetUnit(ctx, unit_model.TypePullRequests); err == nil { if unit, err := repo.GetUnit(ctx, unit_model.TypePullRequests); err == nil {
config := unit.PullRequestsConfig() config := unit.PullRequestsConfig()
@ -114,6 +115,7 @@ func innerToRepo(ctx context.Context, repo *repo_model.Repository, permissionInR
allowRebaseUpdate = config.AllowRebaseUpdate allowRebaseUpdate = config.AllowRebaseUpdate
defaultDeleteBranchAfterMerge = config.DefaultDeleteBranchAfterMerge defaultDeleteBranchAfterMerge = config.DefaultDeleteBranchAfterMerge
defaultMergeStyle = config.GetDefaultMergeStyle() defaultMergeStyle = config.GetDefaultMergeStyle()
defaultUpdateStyle = config.GetDefaultUpdateStyle()
defaultAllowMaintainerEdit = config.DefaultAllowMaintainerEdit defaultAllowMaintainerEdit = config.DefaultAllowMaintainerEdit
} }
hasProjects := false hasProjects := false
@ -231,6 +233,7 @@ func innerToRepo(ctx context.Context, repo *repo_model.Repository, permissionInR
AllowRebaseUpdate: allowRebaseUpdate, AllowRebaseUpdate: allowRebaseUpdate,
DefaultDeleteBranchAfterMerge: defaultDeleteBranchAfterMerge, DefaultDeleteBranchAfterMerge: defaultDeleteBranchAfterMerge,
DefaultMergeStyle: string(defaultMergeStyle), DefaultMergeStyle: string(defaultMergeStyle),
DefaultUpdateStyle: string(defaultUpdateStyle),
DefaultAllowMaintainerEdit: defaultAllowMaintainerEdit, DefaultAllowMaintainerEdit: defaultAllowMaintainerEdit,
AvatarURL: repo.AvatarLink(ctx), AvatarURL: repo.AvatarLink(ctx),
Internal: !repo.IsPrivate && repo.Owner.Visibility == api.VisibleTypePrivate, Internal: !repo.IsPrivate && repo.Owner.Visibility == api.VisibleTypePrivate,

View file

@ -189,6 +189,7 @@ type RepoUnitSettingForm struct {
PullsAllowFastForwardOnly bool PullsAllowFastForwardOnly bool
PullsAllowManualMerge bool PullsAllowManualMerge bool
PullsDefaultMergeStyle string PullsDefaultMergeStyle string
PullsDefaultUpdateStyle string
EnableAutodetectManualMerge bool EnableAutodetectManualMerge bool
PullsAllowRebaseUpdate bool PullsAllowRebaseUpdate bool
DefaultDeleteBranchAfterMerge bool DefaultDeleteBranchAfterMerge bool

View file

@ -72,7 +72,8 @@ func ReviewRequest(ctx context.Context, issue *issues_model.Issue, doer, reviewe
return nil, err return nil, err
} }
if comment != nil { // don't notify if the user is requesting itself as reviewer
if comment != nil && doer.ID != reviewer.ID {
notify_service.PullRequestReviewRequest(ctx, doer, issue, reviewer, isAdd, comment) notify_service.PullRequestReviewRequest(ctx, doer, issue, reviewer, isAdd, comment)
} }

View file

@ -8,7 +8,6 @@ import (
"fmt" "fmt"
"io" "io"
"strconv" "strconv"
"strings"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
@ -107,7 +106,18 @@ func RemoveRandomAvatars(ctx context.Context) error {
// generateAvatar generates the avatar from a template repository // generateAvatar generates the avatar from a template repository
func generateAvatar(ctx context.Context, templateRepo, generateRepo *repo_model.Repository) error { func generateAvatar(ctx context.Context, templateRepo, generateRepo *repo_model.Repository) error {
generateRepo.Avatar = strings.Replace(templateRepo.Avatar, strconv.FormatInt(templateRepo.ID, 10), strconv.FormatInt(generateRepo.ID, 10), 1) file, err := storage.RepoAvatars.Open(templateRepo.CustomAvatarRelativePath())
if err != nil {
return err
}
defer file.Close()
data, err := io.ReadAll(file)
if err != nil {
return err
}
generateRepo.Avatar = avatar.HashAvatar(generateRepo.ID, data)
if _, err := storage.Copy(storage.RepoAvatars, generateRepo.CustomAvatarRelativePath(), storage.RepoAvatars, templateRepo.CustomAvatarRelativePath()); err != nil { if _, err := storage.Copy(storage.RepoAvatars, generateRepo.CustomAvatarRelativePath(), storage.RepoAvatars, templateRepo.CustomAvatarRelativePath()); err != nil {
return err return err
} }

View file

@ -29,7 +29,7 @@ func TestUploadAvatar(t *testing.T) {
err := UploadAvatar(db.DefaultContext, repo, buff.Bytes()) err := UploadAvatar(db.DefaultContext, repo, buff.Bytes())
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, avatar.HashAvatar(10, buff.Bytes()), repo.Avatar) assert.Equal(t, avatar.HashAvatar(repo.ID, buff.Bytes()), repo.Avatar)
} }
func TestUploadBigAvatar(t *testing.T) { func TestUploadBigAvatar(t *testing.T) {
@ -62,3 +62,27 @@ func TestDeleteAvatar(t *testing.T) {
assert.Equal(t, "", repo.Avatar) assert.Equal(t, "", repo.Avatar)
} }
func TestTemplateGenerateAvatar(t *testing.T) {
// Generate image
myImage := image.NewRGBA(image.Rect(0, 0, 1, 1))
var buff bytes.Buffer
png.Encode(&buff, myImage)
require.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10})
// Upload Avatar
err := UploadAvatar(db.DefaultContext, repo, buff.Bytes())
require.NoError(t, err)
assert.Equal(t, avatar.HashAvatar(repo.ID, buff.Bytes()), repo.Avatar)
// Generate the Avatar for Another Repo
genRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 11})
err = generateAvatar(db.DefaultContext, repo, genRepo)
require.NoError(t, err)
assert.Equal(t, avatar.HashAvatar(genRepo.ID, buff.Bytes()), genRepo.Avatar)
// Make sure The 2 Hashes are not the same
assert.NotEqual(t, repo.Avatar, genRepo.Avatar)
}

View file

@ -126,24 +126,32 @@ func (gt *GiteaTemplate) Globs() []glob.Glob {
} }
func checkGiteaTemplate(tmpDir string) (*GiteaTemplate, error) { func checkGiteaTemplate(tmpDir string) (*GiteaTemplate, error) {
gtPath := filepath.Join(tmpDir, ".gitea", "template") configDirs := []string{".forgejo", ".gitea"}
if _, err := os.Stat(gtPath); os.IsNotExist(err) { var templateFilePath string
return nil, nil
} else if err != nil { for _, dir := range configDirs {
return nil, err candidatePath := filepath.Join(tmpDir, dir, "template")
if _, err := os.Stat(candidatePath); err == nil {
templateFilePath = candidatePath
break
} else if !os.IsNotExist(err) {
return nil, err
}
} }
content, err := os.ReadFile(gtPath) if templateFilePath == "" {
return nil, nil
}
content, err := os.ReadFile(templateFilePath)
if err != nil { if err != nil {
return nil, err return nil, err
} }
gt := &GiteaTemplate{ return &GiteaTemplate{
Path: gtPath, Path: templateFilePath,
Content: content, Content: content,
} }, nil
return gt, nil
} }
func generateRepoCommit(ctx context.Context, repo, templateRepo, generateRepo *repo_model.Repository, tmpDir string) error { func generateRepoCommit(ctx context.Context, repo, templateRepo, generateRepo *repo_model.Repository, tmpDir string) error {

View file

@ -409,6 +409,10 @@ func (m *webhookNotifier) CreateIssueComment(ctx context.Context, doer *user_mod
var pullRequest *api.PullRequest var pullRequest *api.PullRequest
if issue.IsPull { if issue.IsPull {
eventType = webhook_module.HookEventPullRequestComment eventType = webhook_module.HookEventPullRequestComment
if err := issue.LoadPullRequest(ctx); err != nil {
log.Error("LoadPullRequest: %v", err)
return
}
pullRequest = convert.ToAPIPullRequest(ctx, issue.PullRequest, doer) pullRequest = convert.ToAPIPullRequest(ctx, issue.PullRequest, doer)
} else { } else {
eventType = webhook_module.HookEventIssueComment eventType = webhook_module.HookEventIssueComment

View file

@ -36,11 +36,13 @@
</thead> </thead>
<tbody> <tbody>
{{range .PackageDescriptor.Metadata.Manifests}} {{range .PackageDescriptor.Metadata.Manifests}}
<tr> {{if ne .Platform "unknown/unknown"}}
<tr>
<td><a href="{{$.PackageDescriptor.PackageWebLink}}/{{PathEscape .Digest}}">{{.Digest}}</a></td> <td><a href="{{$.PackageDescriptor.PackageWebLink}}/{{PathEscape .Digest}}">{{.Digest}}</a></td>
<td>{{.Platform}}</td> <td>{{.Platform}}</td>
<td>{{ctx.Locale.TrSize .Size}}</td> <td>{{ctx.Locale.TrSize .Size}}</td>
</tr> </tr>
{{end}}
{{end}} {{end}}
</tbody> </tbody>
</table> </table>

View file

@ -17,13 +17,15 @@
{{svg "octicon-check-circle-fill" $size (printf "text green %s" $className)}} {{svg "octicon-check-circle-fill" $size (printf "text green %s" $className)}}
{{else if eq .status "skipped"}} {{else if eq .status "skipped"}}
{{svg "octicon-skip" $size (printf "text grey %s" $className)}} {{svg "octicon-skip" $size (printf "text grey %s" $className)}}
{{else if eq .status "cancelled"}}
{{svg "octicon-stop" $size (printf "text grey %s" $className)}}
{{else if eq .status "waiting"}} {{else if eq .status "waiting"}}
{{svg "octicon-clock" $size (printf "text yellow %s" $className)}} {{svg "octicon-clock" $size (printf "text yellow %s" $className)}}
{{else if eq .status "blocked"}} {{else if eq .status "blocked"}}
{{svg "octicon-blocked" $size (printf "text yellow %s" $className)}} {{svg "octicon-blocked" $size (printf "text yellow %s" $className)}}
{{else if eq .status "running"}} {{else if eq .status "running"}}
{{svg "octicon-meter" $size (printf "text yellow job-status-rotate %s" $className)}} {{svg "octicon-meter" $size (printf "text yellow job-status-rotate %s" $className)}}
{{else if or (eq .status "failure") or (eq .status "cancelled") or (eq .status "unknown")}} {{else}}{{/*failure, unknown*/}}
{{svg "octicon-x-circle-fill" $size (printf "text red %s" $className)}} {{svg "octicon-x-circle-fill" $size (printf "text red %s" $className)}}
{{end}} {{end}}
</span> </span>

View file

@ -11,12 +11,6 @@
{{if $description}}<span class="description">{{$description | RenderCodeBlock}}</span>{{else}}<span class="no-description text-italic">{{ctx.Locale.Tr "repo.no_desc"}}</span>{{end}} {{if $description}}<span class="description">{{$description | RenderCodeBlock}}</span>{{else}}<span class="no-description text-italic">{{ctx.Locale.Tr "repo.no_desc"}}</span>{{end}}
{{if .Repository.Website}}<a class="link" href="{{.Repository.Website}}">{{.Repository.Website}}</a>{{end}} {{if .Repository.Website}}<a class="link" href="{{.Repository.Website}}">{{.Repository.Website}}</a>{{end}}
</div> </div>
<form class="ignore-dirty" action="{{.RepoLink}}/search/{{if .CodeIndexerDisabled}}{{.BranchNameSubURL}}{{end}}" method="get" data-test-tag="codesearch">
<div class="ui small action input">
<input name="q" value="{{.Keyword}}" placeholder="{{ctx.Locale.Tr "search.code_kind"}}">
{{template "shared/search/button"}}
</div>
</form>
</div> </div>
<div class="tw-flex tw-items-center tw-flex-wrap tw-gap-2 tw-my-2" id="repo-topics"> <div class="tw-flex tw-items-center tw-flex-wrap tw-gap-2 tw-my-2" id="repo-topics">
{{/* it should match the code in issue-home.js */}} {{/* it should match the code in issue-home.js */}}
@ -158,6 +152,22 @@
{{else if .IsBlame}} {{else if .IsBlame}}
{{template "repo/blame" .}} {{template "repo/blame" .}}
{{else}}{{/* IsViewDirectory */}} {{else}}{{/* IsViewDirectory */}}
{{/* display the search bar only if */}}
{{$isCommit := StringUtils.HasPrefix .BranchNameSubURL "commit"}}
{{if and (not $isCommit) (or .CodeIndexerDisabled (and (not .TagName) (eq .Repository.DefaultBranch .BranchName)))}}
<div class="code-search tw-w-full tw-py-2 tw-px-2 tw-bg-box-header tw-rounded-t tw-border tw-border-secondary tw-border-b-0">
<form class="ui form ignore-dirty" action="{{.RepoLink}}/search/{{if .CodeIndexerDisabled}}{{.BranchNameSubURL}}{{end}}" method="get" data-test-tag="codesearch">
<input type="hidden" name="path" value="{{.TreePath | PathEscapeSegments}}">
{{template "shared/search/combo_multi"
dict
"Value" .Keyword
"Disabled" .CodeIndexerUnavailable
"Placeholder" (ctx.Locale.Tr "search.code_kind")
"Selected" (index .CodeSearchOptions 0)
"Options" .CodeSearchOptions}}
</form>
</div>
{{end}}
{{template "repo/view_list" .}} {{template "repo/view_list" .}}
{{end}} {{end}}
</div> </div>

View file

@ -9,23 +9,31 @@
{{if and $.UpdateAllowed $.UpdateByRebaseAllowed}} {{if and $.UpdateAllowed $.UpdateByRebaseAllowed}}
<div class="tw-inline-block"> <div class="tw-inline-block">
<div class="ui buttons update-button"> <div class="ui buttons update-button">
<button class="ui button" data-do="{{$.Link}}/update" data-redirect="{{$.Link}}"> <button class="ui button" data-do="{{$.Link}}/update?style={{$.UpdateStyle}}" data-redirect="{{$.Link}}">
<span class="button-text"> <span class="button-text">
{{ctx.Locale.Tr "repo.pulls.update_branch"}} {{if eq $.UpdateStyle "rebase"}}
{{ctx.Locale.Tr "repo.pulls.update_branch_rebase"}}
{{else}}
{{ctx.Locale.Tr "repo.pulls.update_branch"}}
{{end}}
</span> </span>
</button> </button>
<div class="ui dropdown icon button"> <div class="ui dropdown icon button">
{{svg "octicon-triangle-down"}} {{svg "octicon-triangle-down"}}
<div class="menu"> <div class="menu">
<a class="item active selected" data-do="{{$.Link}}/update">{{ctx.Locale.Tr "repo.pulls.update_branch"}}</a> <a class="item {{if ne $.UpdateStyle "rebase"}}active selected{{end}}" data-do="{{$.Link}}/update?style=merge">
<a class="item" data-do="{{$.Link}}/update?style=rebase">{{ctx.Locale.Tr "repo.pulls.update_branch_rebase"}}</a> {{ctx.Locale.Tr "repo.pulls.update_branch"}}
</a>
<a class="item {{if eq $.UpdateStyle "rebase"}}active selected{{end}}" data-do="{{$.Link}}/update?style=rebase">
{{ctx.Locale.Tr "repo.pulls.update_branch_rebase"}}
</a>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
{{end}} {{end}}
{{if and $.UpdateAllowed (not $.UpdateByRebaseAllowed)}} {{if and $.UpdateAllowed (not $.UpdateByRebaseAllowed)}}
<form action="{{$.Link}}/update" method="post" class="ui update-branch-form"> <form action="{{$.Link}}/update?style=merge" method="post" class="ui update-branch-form">
{{$.CsrfTokenHtml}} {{$.CsrfTokenHtml}}
<button class="ui compact button"> <button class="ui compact button">
<span class="ui text">{{ctx.Locale.Tr "repo.pulls.update_branch"}}</span> <span class="ui text">{{ctx.Locale.Tr "repo.pulls.update_branch"}}</span>

View file

@ -105,6 +105,29 @@
<label>{{ctx.Locale.Tr "repo.settings.pulls.allow_rebase_update"}}</label> <label>{{ctx.Locale.Tr "repo.settings.pulls.allow_rebase_update"}}</label>
</div> </div>
</div> </div>
<div class="field">
<p>
{{ctx.Locale.Tr "repo.settings.default_update_style_desc"}}
</p>
<div class="ui dropdown selection">
<select name="pulls_default_update_style">
<option value="merge" {{if or (not $pullRequestEnabled) (eq $prUnit.PullRequestsConfig.DefaultUpdateStyle "merge")}}selected{{end}}>{{ctx.Locale.Tr "repo.pulls.update_branch"}}</option>
<option value="rebase" {{if or (not $pullRequestEnabled) (eq $prUnit.PullRequestsConfig.DefaultUpdateStyle "rebase")}}selected{{end}}>{{ctx.Locale.Tr "repo.pulls.update_branch_rebase"}}</option>
</select>{{svg "octicon-triangle-down" 14 "dropdown icon"}}
<div class="default text">
{{if (eq $prUnit.PullRequestsConfig.DefaultUpdateStyle "merge")}}
{{ctx.Locale.Tr "repo.pulls.update_branch"}}
{{end}}
{{if (eq $prUnit.PullRequestsConfig.DefaultUpdateStyle "rebase")}}
{{ctx.Locale.Tr "repo.pulls.update_branch_rebase"}}
{{end}}
</div>
<div class="menu">
<div class="item" data-value="merge">{{ctx.Locale.Tr "repo.pulls.update_branch"}}</div>
<div class="item" data-value="rebase">{{ctx.Locale.Tr "repo.pulls.update_branch_rebase"}}</div>
</div>
</div>
</div>
<div class="field"> <div class="field">
<div class="ui checkbox"> <div class="ui checkbox">
<input name="default_delete_branch_after_merge" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.DefaultDeleteBranchAfterMerge)}}checked{{end}}> <input name="default_delete_branch_after_merge" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.DefaultDeleteBranchAfterMerge)}}checked{{end}}>

View file

@ -1,6 +1,6 @@
{{if and (not .HideRepoInfo) (not .IsBlame)}} {{if and (not .HideRepoInfo) (not .IsBlame)}}
<div class="ui segments repository-summary tw-mt-1 tw-mb-0"> <div class="ui segments repository-summary tw-mt-1 tw-mb-0">
<div class="ui segment sub-menu repository-menu"> <div class="ui segment repository-menu">
{{if and (.Permission.CanRead $.UnitTypeCode) (not .IsEmptyRepo)}} {{if and (.Permission.CanRead $.UnitTypeCode) (not .IsEmptyRepo)}}
<a class="item muted {{if .PageIsCommits}}active{{end}}" href="{{.RepoLink}}/commits/{{.BranchNameSubURL}}"> <a class="item muted {{if .PageIsCommits}}active{{end}}" href="{{.RepoLink}}/commits/{{.BranchNameSubURL}}">
{{svg "octicon-history"}} {{ctx.Locale.TrN .CommitsCount "repo.n_commit_one" "repo.n_commit_few" (printf "<b>%d</b>" .CommitsCount | SafeHTML)}} {{svg "octicon-history"}} {{ctx.Locale.TrN .CommitsCount "repo.n_commit_one" "repo.n_commit_few" (printf "<b>%d</b>" .CommitsCount | SafeHTML)}}
@ -13,7 +13,7 @@
{{svg "octicon-tag"}} {{ctx.Locale.TrN .NumTags "repo.n_tag_one" "repo.n_tag_few" (printf "<b>%d</b>" .NumTags | SafeHTML)}} {{svg "octicon-tag"}} {{ctx.Locale.TrN .NumTags "repo.n_tag_one" "repo.n_tag_few" (printf "<b>%d</b>" .NumTags | SafeHTML)}}
</a> </a>
{{end}} {{end}}
<span class="item not-mobile" {{if not (eq .Repository.Size 0)}}data-tooltip-content="{{.Repository.SizeDetailsString ctx.Locale}}"{{end}}> <span class="item" {{if not (eq .Repository.Size 0)}}data-tooltip-content="{{.Repository.SizeDetailsString ctx.Locale}}"{{end}}>
{{$fileSizeFields := ctx.Locale.TrSize .Repository.Size}} {{$fileSizeFields := ctx.Locale.TrSize .Repository.Size}}
{{svg "octicon-database"}} <b>{{$fileSizeFields.PrettyNumber}}</b> {{$fileSizeFields.TranslatedUnit}} {{svg "octicon-database"}} <b>{{$fileSizeFields.PrettyNumber}}</b> {{$fileSizeFields.TranslatedUnit}}
</span> </span>

View file

@ -1,7 +1,7 @@
<div class="flex-text-block tw-flex-wrap"> <div class="flex-text-block tw-flex-wrap">
{{range $term := .SearchResultLanguages}} {{range $term := .SearchResultLanguages}}
<a class="ui {{if eq $.Language $term.Language}}primary{{end}} basic label tw-m-0" <a class="ui {{if eq $.Language $term.Language}}primary{{end}} basic label tw-m-0"
href="?q={{$.Keyword}}{{if ne $.Language $term.Language}}&l={{$term.Language}}{{end}}&mode={{$.CodeSearchMode}}"> href="?q={{$.Keyword}}{{if ne $.Language $term.Language}}&l={{$term.Language}}{{end}}&mode={{$.CodeSearchMode}}&path={{$.CodeSearchPath}}">
<i class="color-icon tw-mr-2" style="background-color: {{$term.Color}}"></i> <i class="color-icon tw-mr-2" style="background-color: {{$term.Color}}"></i>
{{$term.Language}} {{$term.Language}}
<div class="detail">{{$term.Count}}</div> <div class="detail">{{$term.Count}}</div>
@ -13,7 +13,7 @@
{{$repo := or $.Repo (index $.RepoMaps .RepoID)}} {{$repo := or $.Repo (index $.RepoMaps .RepoID)}}
<details class="tw-group diff-file-box diff-box file-content non-diff-file-content repo-search-result" open> <details class="tw-group diff-file-box diff-box file-content non-diff-file-content repo-search-result" open>
<summary class="tw-list-none"> <summary class="tw-list-none">
<h4 class="ui top attached header tw-font-normal tw-flex tw-flex-wrap tw-transform-reset"> <h4 class="ui top attached header tw-font-normal tw-flex tw-items-center tw-flex-wrap tw-transform-reset">
<span class="tw-h-4 tw-transition -tw-rotate-90 group-open:tw-rotate-0"> <span class="tw-h-4 tw-transition -tw-rotate-90 group-open:tw-rotate-0">
{{svg "octicon-chevron-down"}} {{svg "octicon-chevron-down"}}
</span> </span>

View file

@ -1,4 +1,5 @@
<form class="ui form ignore-dirty"> <form class="ui form ignore-dirty">
<input type="hidden" name="path" value="{{.CodeSearchPath}}">
{{template "shared/search/combo_multi" {{template "shared/search/combo_multi"
dict dict
"Value" .Keyword "Value" .Keyword
@ -14,6 +15,23 @@
<p>{{ctx.Locale.Tr "search.code_search_unavailable"}}</p> <p>{{ctx.Locale.Tr "search.code_search_unavailable"}}</p>
</div> </div>
{{else}} {{else}}
{{if .CodeSearchPath}}
<div class="tw-mb-4">
<span class="breadcrumb">
<a class="section" href="?q={{.Keyword}}&mode={{.CodeSearchMode}}">@</a>
{{$href := ""}}
{{- range $i, $path := StringUtils.Split .CodeSearchPath "/" -}}
{{if eq $i 0}}
{{$href = $path}}
{{else}}
{{$href = StringUtils.Join (StringUtils.Make $href $path) "/"}}
{{end}}
<span class="breadcrumb-divider">/</span>
<span class="section"><a href="?q={{$.Keyword}}&mode={{$.CodeSearchMode}}&path={{$href}}">{{$path}}</a></span>
{{- end -}}
</span>
</div>
{{end}}
{{if .CodeIndexerDisabled}} {{if .CodeIndexerDisabled}}
<div class="ui message" data-test-tag="grep"> <div class="ui message" data-test-tag="grep">
<p>{{ctx.Locale.Tr "search.code_search_by_git_grep"}}</p> <p>{{ctx.Locale.Tr "search.code_search_by_git_grep"}}</p>

View file

@ -23321,6 +23321,11 @@
"type": "string", "type": "string",
"x-go-name": "DefaultMergeStyle" "x-go-name": "DefaultMergeStyle"
}, },
"default_update_style": {
"description": "set to a update style to be used by this repository: \"rebase\" or \"merge\"",
"type": "string",
"x-go-name": "DefaultUpdateStyle"
},
"description": { "description": {
"description": "a short description of the repository.", "description": "a short description of the repository.",
"type": "string", "type": "string",
@ -26605,6 +26610,10 @@
"type": "string", "type": "string",
"x-go-name": "DefaultMergeStyle" "x-go-name": "DefaultMergeStyle"
}, },
"default_update_style": {
"type": "string",
"x-go-name": "DefaultUpdateStyle"
},
"description": { "description": {
"type": "string", "type": "string",
"x-go-name": "Description" "x-go-name": "Description"

View file

@ -5,6 +5,7 @@ package integration
import ( import (
"context" "context"
"fmt"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"net/url" "net/url"
@ -19,6 +20,7 @@ import (
"code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/gitrepo"
repo_module "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/test" "code.gitea.io/gitea/modules/test"
issue_service "code.gitea.io/gitea/services/issue" issue_service "code.gitea.io/gitea/services/issue"
repo_service "code.gitea.io/gitea/services/repository" repo_service "code.gitea.io/gitea/services/repository"
@ -62,6 +64,74 @@ func loadComment(t *testing.T, commentID string) *issues_model.Comment {
return unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: id}) return unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: id})
} }
func TestPullView_SelfReviewNotification(t *testing.T) {
onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
user1Session := loginUser(t, "user1")
user2Session := loginUser(t, "user2")
user1csrf := GetCSRF(t, user1Session, "/")
oldUser1NotificationCount := getUserNotificationCount(t, user1Session, user1csrf)
user2csrf := GetCSRF(t, user2Session, "/")
oldUser2NotificationCount := getUserNotificationCount(t, user2Session, user2csrf)
user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
repo, _, f := tests.CreateDeclarativeRepo(t, user2, "test_reviewer", nil, nil, []*files_service.ChangeRepoFile{
{
Operation: "create",
TreePath: "CODEOWNERS",
ContentReader: strings.NewReader("README.md @user5\n"),
},
})
defer f()
// we need to add user1 as collaborator so it can be added as reviewer
err := repo_module.AddCollaborator(db.DefaultContext, repo, user1)
require.NoError(t, err)
// create a new branch to prepare for pull request
_, err = files_service.ChangeRepoFiles(db.DefaultContext, repo, user2, &files_service.ChangeRepoFilesOptions{
NewBranch: "codeowner-basebranch",
Files: []*files_service.ChangeRepoFile{
{
Operation: "update",
TreePath: "README.md",
ContentReader: strings.NewReader("# This is a new project\n"),
},
},
})
require.NoError(t, err)
// Create a pull request.
resp := testPullCreate(t, user2Session, "user2", "test_reviewer", false, repo.DefaultBranch, "codeowner-basebranch", "Test Pull Request")
prURL := test.RedirectURL(resp)
elem := strings.Split(prURL, "/")
assert.EqualValues(t, "pulls", elem[3])
req := NewRequest(t, http.MethodGet, prURL)
resp = MakeRequest(t, req, http.StatusOK)
doc := NewHTMLParser(t, resp.Body)
attributeFilter := fmt.Sprintf("[data-update-url='/%s/%s/issues/request_review']", user2.Name, repo.Name)
issueID, ok := doc.Find(attributeFilter).Attr("data-issue-id")
assert.True(t, ok, "doc must contain data-issue-id")
user1csrf = GetCSRF(t, user1Session, "/")
testAssignReviewer(t, user1Session, user1csrf, user2.Name, repo.Name, issueID, "1", http.StatusOK)
// both user notification should keep the same notification count since
// user2 added itself as reviewer.
user1csrf = GetCSRF(t, user1Session, "/")
notificationCount := getUserNotificationCount(t, user1Session, user1csrf)
assert.Equal(t, oldUser1NotificationCount, notificationCount)
user2csrf = GetCSRF(t, user2Session, "/")
notificationCount = getUserNotificationCount(t, user2Session, user2csrf)
assert.Equal(t, oldUser2NotificationCount, notificationCount)
})
}
func TestPullView_ResolveInvalidatedReviewComment(t *testing.T) { func TestPullView_ResolveInvalidatedReviewComment(t *testing.T) {
defer tests.PrepareTestEnv(t)() defer tests.PrepareTestEnv(t)()
session := loginUser(t, "user1") session := loginUser(t, "user1")
@ -474,6 +544,28 @@ func TestPullView_GivenApproveOrRejectReviewOnClosedPR(t *testing.T) {
}) })
} }
func testNofiticationCount(t *testing.T, session *TestSession, csrf string, expectedSubmitStatus int) *httptest.ResponseRecorder {
options := map[string]string{
"_csrf": csrf,
}
req := NewRequestWithValues(t, "GET", "/", options)
return session.MakeRequest(t, req, expectedSubmitStatus)
}
func testAssignReviewer(t *testing.T, session *TestSession, csrf, owner, repo, pullID, reviewer string, expectedSubmitStatus int) *httptest.ResponseRecorder {
options := map[string]string{
"_csrf": csrf,
"action": "attach",
"issue_ids": pullID,
"id": reviewer,
}
submitURL := path.Join(owner, repo, "issues", "request_review")
req := NewRequestWithValues(t, "POST", submitURL, options)
return session.MakeRequest(t, req, expectedSubmitStatus)
}
func testSubmitReview(t *testing.T, session *TestSession, csrf, owner, repo, pullNumber, commitID, reviewType string, expectedSubmitStatus int) *httptest.ResponseRecorder { func testSubmitReview(t *testing.T, session *TestSession, csrf, owner, repo, pullNumber, commitID, reviewType string, expectedSubmitStatus int) *httptest.ResponseRecorder {
options := map[string]string{ options := map[string]string{
"_csrf": csrf, "_csrf": csrf,
@ -502,3 +594,9 @@ func testIssueClose(t *testing.T, session *TestSession, owner, repo, issueNumber
req = NewRequestWithValues(t, "POST", closeURL, options) req = NewRequestWithValues(t, "POST", closeURL, options)
return session.MakeRequest(t, req, http.StatusOK) return session.MakeRequest(t, req, http.StatusOK)
} }
func getUserNotificationCount(t *testing.T, session *TestSession, csrf string) string {
resp := testNofiticationCount(t, session, csrf, http.StatusOK)
doc := NewHTMLParser(t, resp.Body)
return doc.Find(`.notification_count`).Text()
}

View file

@ -4,6 +4,7 @@
package integration package integration
import ( import (
"fmt"
"net/http" "net/http"
"net/url" "net/url"
"strings" "strings"
@ -16,6 +17,9 @@ import (
"code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/test"
pull_service "code.gitea.io/gitea/services/pull" pull_service "code.gitea.io/gitea/services/pull"
repo_service "code.gitea.io/gitea/services/repository" repo_service "code.gitea.io/gitea/services/repository"
files_service "code.gitea.io/gitea/services/repository/files" files_service "code.gitea.io/gitea/services/repository/files"
@ -83,6 +87,102 @@ func TestAPIPullUpdateByRebase(t *testing.T) {
}) })
} }
func TestAPIViewUpdateSettings(t *testing.T) {
onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
defer tests.PrepareTestEnv(t)()
// Create PR to test
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
org26 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 26})
pr := createOutdatedPR(t, user, org26)
// Test GetDiverging
diffCount, err := pull_service.GetDiverging(git.DefaultContext, pr)
require.NoError(t, err)
assert.EqualValues(t, 1, diffCount.Behind)
assert.EqualValues(t, 1, diffCount.Ahead)
require.NoError(t, pr.LoadBaseRepo(db.DefaultContext))
require.NoError(t, pr.LoadIssue(db.DefaultContext))
session := loginUser(t, "user2")
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeAll)
defaultUpdateStyle := "rebase"
editOption := api.EditRepoOption{
DefaultUpdateStyle: &defaultUpdateStyle,
}
req := NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", pr.BaseRepo.OwnerName, pr.BaseRepo.Name), editOption).AddTokenAuth(token)
session.MakeRequest(t, req, http.StatusOK)
assertViewPullUpdate(t, pr, session, "rebase", true)
defaultUpdateStyle = "merge"
req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", pr.BaseRepo.OwnerName, pr.BaseRepo.Name), editOption).AddTokenAuth(token)
session.MakeRequest(t, req, http.StatusOK)
assertViewPullUpdate(t, pr, session, "merge", true)
})
}
func TestViewPullUpdateByMerge(t *testing.T) {
onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
testViewPullUpdate(t, "merge")
})
}
func TestViewPullUpdateByRebase(t *testing.T) {
onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
testViewPullUpdate(t, "rebase")
})
}
func testViewPullUpdate(t *testing.T, updateStyle string) {
defer test.MockVariableValue(&setting.Repository.PullRequest.DefaultUpdateStyle, updateStyle)()
defer tests.PrepareTestEnv(t)()
// Create PR to test
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
org26 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 26})
pr := createOutdatedPR(t, user, org26)
// Test GetDiverging
diffCount, err := pull_service.GetDiverging(git.DefaultContext, pr)
require.NoError(t, err)
assert.EqualValues(t, 1, diffCount.Behind)
assert.EqualValues(t, 1, diffCount.Ahead)
require.NoError(t, pr.LoadBaseRepo(db.DefaultContext))
require.NoError(t, pr.LoadIssue(db.DefaultContext))
session := loginUser(t, "user2")
assertViewPullUpdate(t, pr, session, updateStyle, true)
}
func assertViewPullUpdate(t *testing.T, pr *issues_model.PullRequest, session *TestSession, expectedStyle string, dropdownExpected bool) {
req := NewRequest(t, "GET", fmt.Sprintf("%s/%s/pulls/%d", pr.BaseRepo.OwnerName, pr.BaseRepo.Name, pr.Issue.Index))
resp := session.MakeRequest(t, req, http.StatusOK)
htmlDoc := NewHTMLParser(t, resp.Body)
// Verify that URL of the update button is shown correctly.
var mainExpectedURL string
mergeExpectedURL := fmt.Sprintf("/%s/%s/pulls/%d/update?style=merge", pr.BaseRepo.OwnerName, pr.BaseRepo.Name, pr.Issue.Index)
rebaseExpectedURL := fmt.Sprintf("/%s/%s/pulls/%d/update?style=rebase", pr.BaseRepo.OwnerName, pr.BaseRepo.Name, pr.Issue.Index)
if expectedStyle == "rebase" {
mainExpectedURL = rebaseExpectedURL
if dropdownExpected {
htmlDoc.AssertElement(t, fmt.Sprintf(".update-button .dropdown .menu .item[data-do=\"%s\"]:not(.active.selected)", mergeExpectedURL), true)
htmlDoc.AssertElement(t, fmt.Sprintf(".update-button .dropdown .menu .active.selected.item[data-do=\"%s\"]", rebaseExpectedURL), true)
}
} else {
mainExpectedURL = mergeExpectedURL
if dropdownExpected {
htmlDoc.AssertElement(t, fmt.Sprintf(".update-button .dropdown .menu .active.selected.item[data-do=\"%s\"]", mergeExpectedURL), true)
htmlDoc.AssertElement(t, fmt.Sprintf(".update-button .dropdown .menu .item[data-do=\"%s\"]:not(.active.selected)", rebaseExpectedURL), true)
}
}
if dropdownExpected {
htmlDoc.AssertElement(t, fmt.Sprintf(".update-button .button[data-do=\"%s\"]", mainExpectedURL), true)
} else {
htmlDoc.AssertElement(t, fmt.Sprintf("form[action=\"%s\"]", mainExpectedURL), true)
}
}
func createOutdatedPR(t *testing.T, actor, forkOrg *user_model.User) *issues_model.PullRequest { func createOutdatedPR(t *testing.T, actor, forkOrg *user_model.User) *issues_model.PullRequest {
baseRepo, _, _ := tests.CreateDeclarativeRepo(t, actor, "repo-pr-update", nil, nil, nil) baseRepo, _, _ := tests.CreateDeclarativeRepo(t, actor, "repo-pr-update", nil, nil, nil)

View file

@ -7,6 +7,7 @@ package integration
import ( import (
"fmt" "fmt"
"net/http" "net/http"
"net/url"
"strconv" "strconv"
"strings" "strings"
"testing" "testing"
@ -14,9 +15,11 @@ import (
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/optional"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/test" "code.gitea.io/gitea/modules/test"
"code.gitea.io/gitea/modules/translation" "code.gitea.io/gitea/modules/translation"
files_service "code.gitea.io/gitea/services/repository/files"
"code.gitea.io/gitea/tests" "code.gitea.io/gitea/tests"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -76,10 +79,14 @@ func testRepoGenerate(t *testing.T, session *TestSession, templateID, templateOw
// Step4: check the existence of the generated repo // Step4: check the existence of the generated repo
req = NewRequestf(t, "GET", "/%s/%s", generateOwner.Name, generateRepoName) req = NewRequestf(t, "GET", "/%s/%s", generateOwner.Name, generateRepoName)
session.MakeRequest(t, req, http.StatusOK) session.MakeRequest(t, req, http.StatusOK)
}
// Step5: check substituted values in Readme func testRepoGenerateWithFixture(t *testing.T, session *TestSession, templateID, templateOwnerName, templateRepoName string, user, generateOwner *user_model.User, generateRepoName string) {
req = NewRequestf(t, "GET", "/%s/%s/raw/branch/master/README.md", generateOwner.Name, generateRepoName) testRepoGenerate(t, session, templateID, templateOwnerName, templateRepoName, user, generateOwner, generateRepoName)
resp = session.MakeRequest(t, req, http.StatusOK)
// check substituted values in Readme
req := NewRequestf(t, "GET", "/%s/%s/raw/branch/master/README.md", generateOwner.Name, generateRepoName)
resp := session.MakeRequest(t, req, http.StatusOK)
body := fmt.Sprintf(`# %s Readme body := fmt.Sprintf(`# %s Readme
Owner: %s Owner: %s
Link: /%s/%s Link: /%s/%s
@ -125,7 +132,7 @@ func TestRepoGenerate(t *testing.T) {
session := loginUser(t, userName) session := loginUser(t, userName)
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: userName}) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: userName})
testRepoGenerate(t, session, "44", "user27", "template1", user, user, "generated1") testRepoGenerateWithFixture(t, session, "44", "user27", "template1", user, user, "generated1")
} }
func TestRepoGenerateToOrg(t *testing.T) { func TestRepoGenerateToOrg(t *testing.T) {
@ -135,7 +142,7 @@ func TestRepoGenerateToOrg(t *testing.T) {
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: userName}) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: userName})
org := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "org3"}) org := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "org3"})
testRepoGenerate(t, session, "44", "user27", "template1", user, org, "generated2") testRepoGenerateWithFixture(t, session, "44", "user27", "template1", user, org, "generated2")
} }
func TestRepoCreateFormTrimSpace(t *testing.T) { func TestRepoCreateFormTrimSpace(t *testing.T) {
@ -153,3 +160,66 @@ func TestRepoCreateFormTrimSpace(t *testing.T) {
assert.EqualValues(t, "/user2/spaced-name", test.RedirectURL(resp)) assert.EqualValues(t, "/user2/spaced-name", test.RedirectURL(resp))
unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: 2, Name: "spaced-name"}) unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: 2, Name: "spaced-name"})
} }
func TestRepoGenerateTemplating(t *testing.T) {
onGiteaRun(t, func(t *testing.T, u *url.URL) {
input := `# $REPO_NAME
This is a Repo By $REPO_OWNER
ThisIsThe${REPO_NAME}InAnInlineWay`
expected := `# %s
This is a Repo By %s
ThisIsThe%sInAnInlineWay`
templateName := "my_template"
generatedName := "my_generated"
userName := "user1"
session := loginUser(t, userName)
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: userName})
template, _, f := tests.CreateDeclarativeRepoWithOptions(t, user, tests.DeclarativeRepoOptions{
Name: optional.Some(templateName),
IsTemplate: optional.Some(true),
Files: optional.Some([]*files_service.ChangeRepoFile{
{
Operation: "create",
TreePath: ".forgejo/template",
ContentReader: strings.NewReader("Readme.md"),
},
{
Operation: "create",
TreePath: "Readme.md",
ContentReader: strings.NewReader(input),
},
}),
})
defer f()
// The repo.TemplateID field is not initalized. Luckly the ID field holds the expected value
templateID := strconv.FormatInt(template.ID, 10)
testRepoGenerate(
t,
session,
templateID,
user.Name,
templateName,
user,
user,
generatedName,
)
req := NewRequestf(
t,
"GET", "/%s/%s/raw/branch/%s/Readme.md",
user.Name,
generatedName,
template.DefaultBranch,
)
resp := session.MakeRequest(t, req, http.StatusOK)
body := fmt.Sprintf(expected,
generatedName,
user.Name,
generatedName)
assert.Equal(t, body, resp.Body.String())
})
}

View file

@ -1009,16 +1009,29 @@ func TestRepoCodeSearchForm(t *testing.T) {
resp := MakeRequest(t, req, http.StatusOK) resp := MakeRequest(t, req, http.StatusOK)
htmlDoc := NewHTMLParser(t, resp.Body) htmlDoc := NewHTMLParser(t, resp.Body)
action, exists := htmlDoc.doc.Find("form[data-test-tag=codesearch]").Attr("action") formEl := htmlDoc.doc.Find("form[data-test-tag=codesearch]")
action, exists := formEl.Attr("action")
assert.True(t, exists) assert.True(t, exists)
branchSubURL := "/branch/master" branchSubURL := "/branch/master"
if indexer { if indexer {
assert.NotContains(t, action, branchSubURL) assert.NotContains(t, action, branchSubURL)
} else { } else {
assert.Contains(t, action, branchSubURL) assert.Contains(t, action, branchSubURL)
} }
filepath, exists := formEl.Find("input[name=path]").Attr("value")
assert.True(t, exists)
assert.Empty(t, filepath)
req = NewRequest(t, "GET", "/user2/glob/src/branch/master/x/y")
resp = MakeRequest(t, req, http.StatusOK)
filepath, exists = NewHTMLParser(t, resp.Body).doc.
Find("form[data-test-tag=codesearch] input[name=path]").
Attr("value")
assert.True(t, exists)
assert.Equal(t, "x/y", filepath)
} }
t.Run("indexer disabled", func(t *testing.T) { t.Run("indexer disabled", func(t *testing.T) {

View file

@ -389,6 +389,11 @@ td .commit-summary {
cursor: default; cursor: default;
} }
.code-search + #repo-files-table {
border-top-left-radius: 0;
border-top-right-radius: 0;
}
.view-raw { .view-raw {
display: flex; display: flex;
justify-content: center; justify-content: center;
@ -2008,15 +2013,27 @@ details.repo-search-result summary::marker {
box-shadow: none; box-shadow: none;
} }
.repository .repository-summary .repository-menu {
display: grid;
grid-template-columns: repeat(4, 1fr);
padding: 0 0.5em;
}
@media (max-width: 767.98px) {
.repository .repository-summary .repository-menu {
grid-template-rows: repeat(2, 1fr);
grid-template-columns: repeat(2, 1fr);
}
}
.repository .repository-summary .segment.sub-menu { .repository .repository-summary .segment.sub-menu {
border: none; border: none;
display: flex; display: flex;
align-items: center; align-items: center;
padding: 0; padding: 0;
overflow: hidden;
} }
.repository .repository-summary .sub-menu .item { .repository .repository-summary .item {
flex: 1; flex: 1;
height: 30px; height: 30px;
line-height: var(--line-height-default); line-height: var(--line-height-default);
@ -2024,7 +2041,6 @@ details.repo-search-result summary::marker {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
gap: 0.25em; gap: 0.25em;
padding: 0 0.5em; /* make the UI look better for narrow (mobile) view */
text-decoration: none; text-decoration: none;
} }

View file

@ -492,9 +492,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "22.10.1", "version": "22.10.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.1.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.2.tgz",
"integrity": "sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==", "integrity": "sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"undici-types": "~6.20.0" "undici-types": "~6.20.0"
@ -1115,9 +1115,9 @@
} }
}, },
"node_modules/browserslist": { "node_modules/browserslist": {
"version": "4.24.2", "version": "4.24.3",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.3.tgz",
"integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", "integrity": "sha512-1CPmv8iobE2fyRMV97dAcMVegvvWKxmq94hkLiAkUGwKVTyDLw33K+ZxiFrREKmmps4rIw6grcCFCnTMSZ/YiA==",
"funding": [ "funding": [
{ {
"type": "opencollective", "type": "opencollective",
@ -1134,9 +1134,9 @@
], ],
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"caniuse-lite": "^1.0.30001669", "caniuse-lite": "^1.0.30001688",
"electron-to-chromium": "^1.5.41", "electron-to-chromium": "^1.5.73",
"node-releases": "^2.0.18", "node-releases": "^2.0.19",
"update-browserslist-db": "^1.1.1" "update-browserslist-db": "^1.1.1"
}, },
"bin": { "bin": {
@ -1191,16 +1191,44 @@
} }
}, },
"node_modules/call-bind": { "node_modules/call-bind": {
"version": "1.0.7", "version": "1.0.8",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
"integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"call-bind-apply-helpers": "^1.0.0",
"es-define-property": "^1.0.0", "es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.4", "get-intrinsic": "^1.2.4",
"set-function-length": "^1.2.1" "set-function-length": "^1.2.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/call-bind-apply-helpers": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz",
"integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/call-bound": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz",
"integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"get-intrinsic": "^1.2.6"
}, },
"engines": { "engines": {
"node": ">= 0.4" "node": ">= 0.4"
@ -1219,9 +1247,9 @@
} }
}, },
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001686", "version": "1.0.30001690",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001686.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001690.tgz",
"integrity": "sha512-Y7deg0Aergpa24M3qLC5xjNklnKnhsmSyR/V89dLZ1n0ucJIFNs7PgR2Yfa/Zf6W79SbBicgtGxZr2juHkEUIA==", "integrity": "sha512-5ExiE3qQN6oF8Clf8ifIDcMRCRE/dMGcETG/XGMD8/XiXm6HXQgQTh1yZYLXXpSOsEUlJm1Xr7kGULZTuGtP/w==",
"funding": [ "funding": [
{ {
"type": "opencollective", "type": "opencollective",
@ -1833,6 +1861,20 @@
"node": ">=0.3.1" "node": ">=0.3.1"
} }
}, },
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"es-errors": "^1.3.0",
"gopd": "^1.2.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/duplexer2": { "node_modules/duplexer2": {
"version": "0.0.2", "version": "0.0.2",
"resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz",
@ -1961,9 +2003,9 @@
} }
}, },
"node_modules/electron-to-chromium": { "node_modules/electron-to-chromium": {
"version": "1.5.68", "version": "1.5.75",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.68.tgz", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.75.tgz",
"integrity": "sha512-FgMdJlma0OzUYlbrtZ4AeXjKxKPk6KT8WOP8BjcqxWtlg8qyJQjRzPJzUtUn5GBg1oQ26hFs7HOOHJMYiJRnvQ==", "integrity": "sha512-Lf3++DumRE/QmweGjU+ZcKqQ+3bKkU/qjaKYhIJKEOhgIO9Xs6IiAQFkfFoj+RhgDk4LUeNsLo6plExHqSyu6Q==",
"license": "ISC" "license": "ISC"
}, },
"node_modules/emoji-regex": { "node_modules/emoji-regex": {
@ -2004,13 +2046,10 @@
} }
}, },
"node_modules/es-define-property": { "node_modules/es-define-property": {
"version": "1.0.0", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"license": "MIT", "license": "MIT",
"dependencies": {
"get-intrinsic": "^1.2.4"
},
"engines": { "engines": {
"node": ">= 0.4" "node": ">= 0.4"
} }
@ -2024,6 +2063,18 @@
"node": ">= 0.4" "node": ">= 0.4"
} }
}, },
"node_modules/es-object-atoms": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz",
"integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es5-ext": { "node_modules/es5-ext": {
"version": "0.10.64", "version": "0.10.64",
"resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz",
@ -2662,16 +2713,21 @@
} }
}, },
"node_modules/get-intrinsic": { "node_modules/get-intrinsic": {
"version": "1.2.4", "version": "1.2.6",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.6.tgz",
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "integrity": "sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"dunder-proto": "^1.0.0",
"es-define-property": "^1.0.1",
"es-errors": "^1.3.0", "es-errors": "^1.3.0",
"es-object-atoms": "^1.0.0",
"function-bind": "^1.1.2", "function-bind": "^1.1.2",
"has-proto": "^1.0.1", "gopd": "^1.2.0",
"has-symbols": "^1.0.3", "has-symbols": "^1.1.0",
"hasown": "^2.0.0" "hasown": "^2.0.2",
"math-intrinsics": "^1.0.0"
}, },
"engines": { "engines": {
"node": ">= 0.4" "node": ">= 0.4"
@ -2867,13 +2923,10 @@
} }
}, },
"node_modules/gopd": { "node_modules/gopd": {
"version": "1.1.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.1.0.tgz", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-FQoVQnqcdk4hVM4JN1eromaun4iuS34oStkdlLENLdpULsuQcTyXj8w7ayhuUfPwEYZ1ZOooOTT6fdA9Vmx/RA==", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"license": "MIT", "license": "MIT",
"dependencies": {
"get-intrinsic": "^1.2.4"
},
"engines": { "engines": {
"node": ">= 0.4" "node": ">= 0.4"
}, },
@ -4288,21 +4341,6 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/has-proto": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.1.0.tgz",
"integrity": "sha512-QLdzI9IIO1Jg7f9GT1gXpPpXArAn6cS31R1eEZqz08Gc+uQ8/XiqHWt17Fiw+2p6oTTIq5GXEpQkAlA88YRl/Q==",
"license": "MIT",
"dependencies": {
"call-bind": "^1.0.7"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-symbols": { "node_modules/has-symbols": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
@ -4625,9 +4663,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/is-core-module": { "node_modules/is-core-module": {
"version": "2.15.1", "version": "2.16.1",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
"integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"hasown": "^2.0.2" "hasown": "^2.0.2"
@ -5558,6 +5596,15 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/merge-stream": { "node_modules/merge-stream": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
@ -5893,9 +5940,9 @@
} }
}, },
"node_modules/node-releases": { "node_modules/node-releases": {
"version": "2.0.18", "version": "2.0.19",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
"integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/node.extend": { "node_modules/node.extend": {
@ -6077,14 +6124,16 @@
} }
}, },
"node_modules/object.assign": { "node_modules/object.assign": {
"version": "4.1.5", "version": "4.1.7",
"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz",
"integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"call-bind": "^1.0.5", "call-bind": "^1.0.8",
"call-bound": "^1.0.3",
"define-properties": "^1.2.1", "define-properties": "^1.2.1",
"has-symbols": "^1.0.3", "es-object-atoms": "^1.0.0",
"has-symbols": "^1.1.0",
"object-keys": "^1.1.1" "object-keys": "^1.1.1"
}, },
"engines": { "engines": {
@ -6847,18 +6896,21 @@
"license": "ISC" "license": "ISC"
}, },
"node_modules/resolve": { "node_modules/resolve": {
"version": "1.22.8", "version": "1.22.10",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
"integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"is-core-module": "^2.13.0", "is-core-module": "^2.16.0",
"path-parse": "^1.0.7", "path-parse": "^1.0.7",
"supports-preserve-symlinks-flag": "^1.0.0" "supports-preserve-symlinks-flag": "^1.0.0"
}, },
"bin": { "bin": {
"resolve": "bin/resolve" "resolve": "bin/resolve"
}, },
"engines": {
"node": ">= 0.4"
},
"funding": { "funding": {
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }

View file

@ -28,12 +28,13 @@ export default {
}; };
</script> </script>
<template> <template>
<span class="tw-flex tw-items-center" :data-tooltip-content="localeStatus" v-if="status"> <span class="tw-flex tw-items-center" :data-tooltip-content="localeStatus ?? status" v-if="status">
<SvgIcon name="octicon-check-circle-fill" class="text green" :size="size" :class-name="className" v-if="status === 'success'"/> <SvgIcon name="octicon-check-circle-fill" class="text green" :size="size" :class-name="className" v-if="status === 'success'"/>
<SvgIcon name="octicon-skip" class="text grey" :size="size" :class-name="className" v-else-if="status === 'skipped'"/> <SvgIcon name="octicon-skip" class="text grey" :size="size" :class-name="className" v-else-if="status === 'skipped'"/>
<SvgIcon name="octicon-stop" class="text yellow" :size="size" :class-name="className" v-else-if="status === 'cancelled'"/>
<SvgIcon name="octicon-clock" class="text yellow" :size="size" :class-name="className" v-else-if="status === 'waiting'"/> <SvgIcon name="octicon-clock" class="text yellow" :size="size" :class-name="className" v-else-if="status === 'waiting'"/>
<SvgIcon name="octicon-blocked" class="text yellow" :size="size" :class-name="className" v-else-if="status === 'blocked'"/> <SvgIcon name="octicon-blocked" class="text yellow" :size="size" :class-name="className" v-else-if="status === 'blocked'"/>
<SvgIcon name="octicon-meter" class="text yellow" :size="size" :class-name="'job-status-rotate ' + className" v-else-if="status === 'running'"/> <SvgIcon name="octicon-meter" class="text yellow" :size="size" :class-name="'job-status-rotate ' + className" v-else-if="status === 'running'"/>
<SvgIcon name="octicon-x-circle-fill" class="text red" :size="size" v-else-if="['failure', 'cancelled', 'unknown'].includes(status)"/> <SvgIcon name="octicon-x-circle-fill" class="text red" :size="size" v-else/><!-- failure, unknown -->
</span> </span>
</template> </template>

View file

@ -570,11 +570,13 @@ export function initRepositoryActionView() {
.action-info-summary-title { .action-info-summary-title {
display: flex; display: flex;
align-items: center;
gap: 0.5em;
} }
.action-info-summary-title-text { .action-info-summary-title-text {
font-size: 20px; font-size: 20px;
margin: 0 0 0 8px; margin: 0;
flex: 1; flex: 1;
overflow-wrap: anywhere; overflow-wrap: anywhere;
} }

View file

@ -64,6 +64,7 @@ import octiconSidebarCollapse from '../../public/assets/img/svg/octicon-sidebar-
import octiconSidebarExpand from '../../public/assets/img/svg/octicon-sidebar-expand.svg'; import octiconSidebarExpand from '../../public/assets/img/svg/octicon-sidebar-expand.svg';
import octiconSkip from '../../public/assets/img/svg/octicon-skip.svg'; import octiconSkip from '../../public/assets/img/svg/octicon-skip.svg';
import octiconStar from '../../public/assets/img/svg/octicon-star.svg'; import octiconStar from '../../public/assets/img/svg/octicon-star.svg';
import octiconStop from '../../public/assets/img/svg/octicon-stop.svg';
import octiconStrikethrough from '../../public/assets/img/svg/octicon-strikethrough.svg'; import octiconStrikethrough from '../../public/assets/img/svg/octicon-strikethrough.svg';
import octiconSync from '../../public/assets/img/svg/octicon-sync.svg'; import octiconSync from '../../public/assets/img/svg/octicon-sync.svg';
import octiconTable from '../../public/assets/img/svg/octicon-table.svg'; import octiconTable from '../../public/assets/img/svg/octicon-table.svg';
@ -138,6 +139,7 @@ const svgs = {
'octicon-sidebar-expand': octiconSidebarExpand, 'octicon-sidebar-expand': octiconSidebarExpand,
'octicon-skip': octiconSkip, 'octicon-skip': octiconSkip,
'octicon-star': octiconStar, 'octicon-star': octiconStar,
'octicon-stop': octiconStop,
'octicon-strikethrough': octiconStrikethrough, 'octicon-strikethrough': octiconStrikethrough,
'octicon-sync': octiconSync, 'octicon-sync': octiconSync,
'octicon-table': octiconTable, 'octicon-table': octiconTable,