Merge branch 'forgejo' into feat/add-oidc-ssh-keys

This commit is contained in:
Maks1mS 2024-12-26 14:33:09 +00:00
commit 8a3fb4885e
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
# 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:
push:
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
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
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/
DISPOSABLE_EMAILS_SHA ?= 0c27e671231d27cf66370034d7f6818037416989 # renovate: ...

View file

@ -1042,7 +1042,7 @@
{
"name": "golang.org/x/time/rate",
"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",

View file

@ -11,13 +11,4 @@ package main
import (
// for embed
_ "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{}
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",
"user", "utente", "lietotājs", "gebruiker", "usuário", "Benutzer", "Bruker",
"user", "utente", "lietotājs", "gebruiker", "usuário", "Benutzer", "Bruker", "bruger",
"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")
}

97
go.mod
View file

@ -13,7 +13,6 @@ require (
code.forgejo.org/go-chi/captcha v1.0.1
code.forgejo.org/go-chi/session v1.0.1
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
codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570
connectrpc.com/connect v1.17.0
@ -49,8 +48,7 @@ require (
github.com/go-ldap/ldap/v3 v3.4.6
github.com/go-openapi/spec v0.20.14
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.12.0
github.com/go-testfixtures/testfixtures/v3 v3.14.0
github.com/go-webauthn/webauthn v0.11.2
github.com/gobwas/glob v0.2.3
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f
@ -110,9 +108,8 @@ require (
golang.org/x/sync v0.10.0
golang.org/x/sys v0.28.0
golang.org/x/text v0.21.0
golang.org/x/tools v0.28.0
google.golang.org/grpc v1.68.0
google.golang.org/protobuf v1.36.0
google.golang.org/grpc v1.69.2
google.golang.org/protobuf v1.36.1
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
gopkg.in/ini.v1 v1.67.0
gopkg.in/yaml.v3 v3.0.1
@ -122,22 +119,26 @@ 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
filippo.io/edwards25519 v1.1.0 // 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/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.2.1 // indirect
github.com/Masterminds/sprig/v3 v3.2.3 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.5.0 // indirect
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.24.2 // indirect
github.com/Microsoft/go-winio v0.6.2 // 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/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/beorn7/perks v1.0.1 // 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/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // 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/cespare/xxhash/v2 v2.3.0 // 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/cyphar/filepath-securejoin v0.2.4 // 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/emersion/go-sasl v0.0.0-20231106173351-e73c9f7bad43 // 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/felixge/httpsnoop v1.0.4 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // 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-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/go-billy/v5 v5.5.0 // indirect
github.com/go-ini/ini v1.67.0 // indirect
github.com/go-openapi/analysis v0.22.2 // indirect
github.com/go-openapi/errors v0.21.0 // indirect
github.com/go-openapi/inflect v0.19.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/jsonpointer v0.20.2 // 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/validate v0.22.6 // indirect
github.com/go-webauthn/x v0.1.14 // indirect
github.com/goccy/go-json v0.10.3 // 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-querystring v1.1.0 // 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/handlers v1.5.2 // indirect
github.com/gorilla/mux v1.8.1 // indirect
github.com/gorilla/securecookie v1.1.2 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // 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/jessevdk/go-flags v1.5.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/kevinburke/ssh_config v1.2.0 // 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/magiconair/properties v1.8.7 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/markbates/going v1.0.3 // 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/miekg/dns v1.1.62 // 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/reflectwalk v1.0.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/mrjones/oauth v0.0.0-20190623134757-126b35219450 // indirect
github.com/mschoch/smat v0.2.0 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // 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/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/pjbgf/sha1cd v0.3.0 // 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/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.55.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
github.com/rhysd/actionlint v1.6.27 // 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/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/sirupsen/logrus v1.9.3 // 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/subosito/gotenv v1.6.0 // indirect
github.com/toqueteos/webbrowser v1.2.0 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
github.com/zeebo/blake3 v0.2.4 // indirect
go.etcd.io/bbolt v1.3.9 // indirect
go.mongodb.org/mongo-driver v1.13.1 // indirect
go.opentelemetry.io/otel v1.26.0 // indirect
go.opentelemetry.io/otel/trace v1.26.0 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/contrib/detectors/gcp v1.31.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/multierr v1.11.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/time v0.5.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect
golang.org/x/time v0.7.0 // 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/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

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 {
allDone := true
allWaiting := true
hasFailure := false
allSuccessOrSkipped := len(jobs) != 0
allSkipped := len(jobs) != 0
var hasFailure, hasCancelled, hasWaiting, hasRunning, hasBlocked bool
for _, job := range jobs {
if !job.Status.IsDone() {
allDone = false
}
if job.Status != StatusWaiting && !job.Status.IsDone() {
allWaiting = false
}
if job.Status == StatusFailure || job.Status == StatusCancelled {
hasFailure = true
}
}
if allDone {
if hasFailure {
return StatusFailure
allSuccessOrSkipped = allSuccessOrSkipped && (job.Status == StatusSuccess || job.Status == StatusSkipped)
allSkipped = allSkipped && job.Status == StatusSkipped
hasFailure = hasFailure || job.Status == StatusFailure
hasCancelled = hasCancelled || job.Status == StatusCancelled
hasWaiting = hasWaiting || job.Status == StatusWaiting
hasRunning = hasRunning || job.Status == StatusRunning
hasBlocked = hasBlocked || job.Status == StatusBlocked
}
switch {
case allSkipped:
return StatusSkipped
case allSuccessOrSkipped:
return StatusSuccess
}
if allWaiting {
return StatusWaiting
}
case hasCancelled:
return StatusCancelled
case hasFailure:
return StatusFailure
case hasRunning:
return StatusRunning
case hasWaiting:
return StatusWaiting
case hasBlocked:
return StatusBlocked
default:
return StatusUnknown // it shouldn't happen
}
}

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
need_approval: 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
title: "update actions"

View file

@ -45,3 +45,15 @@
is_deleted: false
deleted_by_id: 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 {
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 {
case schemas.MYSQL:
_, 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:
_, 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(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),
// 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
}

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"
)
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
func UpdateDefaultBranch(ctx context.Context, repo *Repository) error {
_, err := db.GetEngine(ctx).ID(repo.ID).Cols("default_branch").Update(repo)

View file

@ -159,6 +159,7 @@ type PullRequestsConfig struct {
AllowRebaseUpdate bool
DefaultDeleteBranchAfterMerge bool
DefaultMergeStyle MergeStyle
DefaultUpdateStyle UpdateStyle
DefaultAllowMaintainerEdit bool
}
@ -197,6 +198,25 @@ func (cfg *PullRequestsConfig) GetDefaultMergeStyle() MergeStyle {
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 {
DisabledWorkflows []string
}

View file

@ -7,6 +7,8 @@ import (
"testing"
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/test"
"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.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

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

View file

@ -36,13 +36,15 @@ const (
RegExpGrepMode
)
var GrepSearchOptions = [3]string{"exact", "union", "regexp"}
type GrepOptions struct {
RefName string
MaxResultLimit int
MatchesPerFile int // >= git 2.38
ContextLineNumber int
Mode grepMode
PathSpec []setting.Glob
Filename string
}
func (opts *GrepOptions) ensureDefaults() {
@ -112,13 +114,39 @@ func GrepSearch(ctx context.Context, repo *Repository, search string, opts GrepO
}
// pathspec
files := make([]string, 0,
len(setting.Indexer.IncludePatterns)+
len(setting.Indexer.ExcludePatterns)+
len(opts.PathSpec))
for _, expr := range append(setting.Indexer.IncludePatterns, opts.PathSpec...) {
includeLen := len(setting.Indexer.IncludePatterns)
if len(opts.Filename) > 0 {
includeLen = 1
}
files := make([]string, 0, len(setting.Indexer.ExcludePatterns)+includeLen)
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 {
files = append(files, ":^"+expr.Pattern())
}

View file

@ -89,6 +89,20 @@ func TestGrepSearch(t *testing.T) {
},
}, 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{})
require.NoError(t, err)
assert.Empty(t, res)

View file

@ -230,7 +230,7 @@ func (repo *Repository) CommitsByFileAndRange(opts CommitsByFileAndRangeOptions)
go func() {
stderr := strings.Builder{}
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)
gitCmd.AddDynamicArguments(opts.Revision)

View file

@ -7,6 +7,9 @@ import (
"path/filepath"
"testing"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/test"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@ -138,3 +141,61 @@ func TestGetTagCommit(t *testing.T) {
require.NoError(t, err)
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/git"
"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"
indexer_internal "code.gitea.io/gitea/modules/indexer/internal"
inner_bleve "code.gitea.io/gitea/modules/indexer/internal/bleve"
@ -56,6 +57,7 @@ func addUnicodeNormalizeTokenFilter(m *mapping.IndexMappingImpl) error {
type RepoIndexerData struct {
RepoID int64
CommitID string
Filename string
Content string
Language string
UpdatedAt time.Time
@ -69,7 +71,8 @@ func (d *RepoIndexerData) Type() string {
const (
repoIndexerAnalyzer = "repoIndexerAnalyzer"
repoIndexerDocType = "repoIndexerDocType"
repoIndexerLatestVersion = 6
pathHierarchyAnalyzer = "pathHierarchyAnalyzer"
repoIndexerLatestVersion = 7
)
// 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("CommitID", termFieldMapping)
pathFieldMapping := bleve.NewTextFieldMapping()
pathFieldMapping.IncludeInAll = false
pathFieldMapping.Analyzer = pathHierarchyAnalyzer
docMapping.AddFieldMappingsAt("Filename", pathFieldMapping)
timeFieldMapping := bleve.NewDateTimeFieldMapping()
timeFieldMapping.IncludeInAll = false
docMapping.AddFieldMappingsAt("UpdatedAt", timeFieldMapping)
@ -103,6 +111,13 @@ func generateBleveIndexMapping() (mapping.IndexMapping, error) {
"token_filters": []string{unicodeNormalizeName, camelcase.Name, lowercase.Name},
}); err != nil {
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.AddDocumentMapping(repoIndexerDocType, docMapping)
@ -178,6 +193,7 @@ func (b *Indexer) addUpdate(ctx context.Context, batchWriter git.WriteCloserErro
return batch.Index(id, &RepoIndexerData{
RepoID: repo.ID,
CommitID: commitSha,
Filename: update.Filename,
Content: string(charset.ToUTF8DropErrors(fileContents, charset.ConvertOpts{})),
Language: analyze.GetCodeLanguage(update.Filename, fileContents),
UpdatedAt: time.Now().UTC(),
@ -266,22 +282,30 @@ func (b *Indexer) Search(ctx context.Context, opts *internal.SearchOptions) (int
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
facetQuery := indexerQuery
if len(opts.Language) > 0 {
languageQuery := bleve.NewMatchQuery(opts.Language)
languageQuery.FieldVal = "Language"
languageQuery.Analyzer = analyzer_keyword.Name
indexerQuery = bleve.NewConjunctionQuery(
indexerQuery,
languageQuery,
inner_bleve.MatchQuery(opts.Language, "Language", analyzer_keyword.Name, 0),
)
}
from, pageSize := opts.GetSkipTake()
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
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)),
StartIndex: startIndex,
EndIndex: endIndex,
Filename: internal.FilenameOfIndexerID(hit.ID),
Filename: hit.Fields["Filename"].(string),
Content: hit.Fields["Content"].(string),
CommitID: hit.Fields["CommitID"].(string),
UpdatedUnix: updatedUnix,
@ -333,7 +357,7 @@ func (b *Indexer) Search(ctx context.Context, opts *internal.SearchOptions) (int
if len(opts.Language) > 0 {
// Use separate query to go get all language counts
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.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 (
esRepoIndexerLatestVersion = 1
esRepoIndexerLatestVersion = 2
// 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
esMultiMatchTypeBestFields = "best_fields"
@ -57,6 +57,21 @@ func NewIndexer(url, indexerName string) *Indexer {
const (
defaultMapping = `{
"settings": {
"analysis": {
"analyzer": {
"custom_path_tree": {
"tokenizer": "custom_hierarchy"
}
},
"tokenizer": {
"custom_hierarchy": {
"type": "path_hierarchy",
"delimiter": "/"
}
}
}
},
"mappings": {
"properties": {
"repo_id": {
@ -72,6 +87,15 @@ const (
"type": "keyword",
"index": true
},
"filename": {
"type": "text",
"fields": {
"tree": {
"type": "text",
"analyzer": "custom_path_tree"
}
}
},
"language": {
"type": "keyword",
"index": true
@ -138,6 +162,7 @@ func (b *Indexer) addUpdate(ctx context.Context, batchWriter git.WriteCloserErro
"repo_id": repo.ID,
"content": string(charset.ToUTF8DropErrors(fileContents, charset.ConvertOpts{})),
"commit_id": sha,
"filename": update.Filename,
"language": analyze.GetCodeLanguage(update.Filename, fileContents),
"updated_at": timeutil.TimeStampNow(),
}),
@ -267,7 +292,6 @@ func convertResult(searchResult *elastic.SearchResult, kw string, pageSize int)
panic(fmt.Sprintf("2===%#v", hit.Highlight))
}
repoID, fileName := internal.ParseIndexerID(hit.Id)
res := make(map[string]any)
if err := json.Unmarshal(hit.Source, &res); err != nil {
return 0, nil, nil, err
@ -276,8 +300,8 @@ func convertResult(searchResult *elastic.SearchResult, kw string, pageSize int)
language := res["language"].(string)
hits = append(hits, &internal.SearchResult{
RepoID: repoID,
Filename: fileName,
RepoID: int64(res["repo_id"].(float64)),
Filename: res["filename"].(string),
CommitID: res["commit_id"].(string),
Content: res["content"].(string),
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...)
query = query.Must(repoQuery)
}
if len(opts.Filename) > 0 {
query = query.Filter(elastic.NewTermsQuery("filename.tree", opts.Filename))
}
var (
start, pageSize = opts.GetSkipTake()

View file

@ -38,6 +38,7 @@ func testIndexer(name string, t *testing.T, indexer internal.Indexer) {
Keyword string
IDs []int64
Langs int
Filename string
}{
{
RepoIDs: nil,
@ -51,6 +52,20 @@ func testIndexer(name string, t *testing.T, indexer internal.Indexer) {
IDs: []int64{},
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,
Keyword: "Description for",
@ -86,6 +101,7 @@ func testIndexer(name string, t *testing.T, indexer internal.Indexer) {
Page: 1,
PageSize: 10,
},
Filename: kw.Filename,
IsKeywordFuzzy: true,
})
require.NoError(t, err)

View file

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

View file

@ -3,30 +3,8 @@
package internal
import (
"strings"
"code.gitea.io/gitea/modules/indexer/internal"
"code.gitea.io/gitea/modules/log"
)
import "code.gitea.io/gitea/modules/indexer/internal"
func FilenameIndexerID(repoID int64, filename string) string {
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
var CodeSearchOptions = [2]string{"exact", "fuzzy"}
func indices(content string, selectionStartIndex, selectionEndIndex int) (int, int) {
startIndex := selectionStartIndex
numLinesBefore := 0

View file

@ -29,12 +29,15 @@ var (
hash = sha256.New
// The AEAD used for encryption/decryption.
aead = chacha20poly1305.NewX
aeadKeySize = chacha20poly1305.KeySize
aeadNonceSize = chacha20poly1305.NonceSizeX
// The pseudorandom key generated by HKDF-Extract.
prk []byte
)
const (
aeadKeySize = chacha20poly1305.KeySize
aeadNonceSize = chacha20poly1305.NonceSizeX
)
// Set the main IKM for this module.
func Init(ikm []byte) {
// 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.
// The same key will be provided for the same context.
func DeriveKey(context Context) *Key {
if len(prk) == 0 {
if len(prk) != sha256.Size {
panic("keying: not initialized")
}
@ -63,7 +66,7 @@ func DeriveKey(context Context) *Key {
key := make([]byte, aeadKeySize)
// 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)
}
@ -92,7 +95,7 @@ func (k *Key) Encrypt(plaintext, additionalData []byte) []byte {
// Generate a random nonce.
nonce := make([]byte, aeadNonceSize)
if _, err := rand.Read(nonce); err != nil {
if n, err := rand.Read(nonce); err != nil || n != aeadNonceSize {
panic(err)
}

View file

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

View file

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

View file

@ -105,6 +105,7 @@ type Repository struct {
DefaultDeleteBranchAfterMerge bool `json:"default_delete_branch_after_merge"`
DefaultMergeStyle string `json:"default_merge_style"`
DefaultAllowMaintainerEdit bool `json:"default_allow_maintainer_edit"`
DefaultUpdateStyle string `json:"default_update_style"`
AvatarURL string `json:"avatar_url"`
Internal bool `json:"internal"`
MirrorInterval string `json:"mirror_interval"`
@ -225,6 +226,8 @@ type EditRepoOption struct {
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".
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
DefaultAllowMaintainerEdit *bool `json:"default_allow_maintainer_edit,omitempty"`
// 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_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.
repos_none=Nevlastníte žádné repozitáře.
@ -2849,6 +2849,7 @@ issues.num_reviews_one = %d kontrola
issues.num_reviews_few = %d kontrol
issues.summary_card_alt = Souhrn problému s názvem „%s“ v repozitáři %s
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]
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_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.
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
activated=Aktiviert
requires_activation=Erfordert Aktivierung
@ -1097,7 +1097,7 @@ issue_labels=Labels
issue_labels_helper=Wähle eine Label-Sammlung
license=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_helper=Wähle eine README-Vorlage
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.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.branchsettings_unavailable=Branch-Einstellungen sind nicht verfügbar wenn das Repo archiviert ist.
settings.archive.tagsettings_unavailable=Tag Einstellungen sind nicht verfügbar, wenn das Repo archiviert wurde.
settings.archive.branchsettings_unavailable=Branch-Einstellungen sind nicht verfügbar in archivierten Repos.
settings.archive.tagsettings_unavailable=Tag-Einstellungen sind nicht verfügbar in archivierten Repos.
settings.unarchive.button=Archivierung 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.
@ -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.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.
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.
clone_in_vscodium = In VSCodium klonen
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.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.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.
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.
@ -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:
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:
container.details.type=Container-Image Typ
container.details.type=Abbildtyp
container.details.platform=Plattform
container.pull=Downloade das Container-Image aus der Kommandozeile:
container.digest=Digest
container.multi_arch=Betriebsystem / Architektur
container.layers=Container-Image Ebenen
container.layers=Abbildebenen
container.labels=Labels
container.labels.key=Schlüssel
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.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.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_allow_edits_from_maintainers = Allow edits from maintainers by default
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_enable_timetracking=Ota ajanseuranta oletusarvoisesti käyttöön
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'.
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 .
@ -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.
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.
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]
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:
show_on_map = Näytä paikka kartalla
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]
@ -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
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
update_avatar=Päivitä 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
manage_emails=Hallitse sähköpostiosoitteita
manage_themes=Valitse oletusteema
manage_openid=Hallitse OpenID osoitteita
theme_desc=mä on sivuston oletusteemasi.
manage_themes=Oletusteema
manage_openid=OpenID-osoitteet
theme_desc=tä teemaa käytetään verkkosivuston käyttöliittymässä, kun olet sisäänkirjautuneena.
primary=Ensisijainen
activated=Aktivoitu
requires_activation=Vaatii aktivoinnin
@ -717,7 +722,7 @@ theme_update_error=Valittua teemaa ei löydy.
openid_deletion=Poista OpenID-osoite
openid_deletion_success=OpenID-osoite on poistettu.
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_openid=Lisää OpenID URI
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_gpg_keys=Hallitse GPG-avaimia
add_key=Lisää avain
ssh_desc=Nämä julkiset SSH-avaimet on liitetty tiliisi. Vastaavat yksityiset avaimet antavat täyden pääsyn repoihisi.
gpg_desc=Nämä julkiset GPG-avaimet on liitetty tiliisi. Pidä yksityiset avaimet turvassa, koska ne mahdollistavat committien todentamisen.
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, 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.
gpg_helper=<strong>Tarvitsetko apua?</strong> Katso GitHubin opas <a href="%s">GPG</a>:stä.
add_new_key=Lisää SSH 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_gpg_placeholder=Alkaa sanoilla '-----BEGIN PGP PUBLIC KEY BLOCK-----'
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-----"
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_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_code=echo "%s" | gpg -a --default-key %s --detach-sig
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_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
@ -756,7 +761,7 @@ ssh_token_required=Sinun täytyy antaa allekirjoitus alla olevalle pääsymerkil
ssh_token=Pääsymerkki
ssh_token_help=Voit luoda allekirjoituksen käyttäen:
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
key_id=Avain ID
key_name=Avaimen nimi
@ -774,7 +779,7 @@ can_read_info=Luku
can_write_info=Kirjoitus
show_openid=Näytä profiilissa
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_access_token=Hallitse pääsymerkkejä
@ -795,7 +800,7 @@ create_oauth2_application=Luo uusi OAuth2-sovellus
create_oauth2_application_button=Luo sovellus
oauth2_application_name=Sovelluksen nimi
save_application=Tallenna
oauth2_regenerate_secret=Luo secret uudelleen
oauth2_regenerate_secret=Luo salaisuus uudelleen
oauth2_regenerate_secret_hint=Kadotitko secretin?
oauth2_application_edit=Muokkaa
@ -811,10 +816,10 @@ twofa_enrolled=Tiliisi on otettu käyttöön kaksivaiheinen vahvistus. Ota palau
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.
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_success=Linkitetty tili on poistettu.
@ -854,7 +859,7 @@ location_placeholder = Jaa likimääräinen sijaintisi muiden kanssa
retype_new_password = Vahvista uusi salasana
create_oauth2_application_success = Loit uuden OAuth2-sovelluksen.
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ä
webauthn_register_key = Lisää turva-avain
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?
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.
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]
owner=Omistaja
@ -917,7 +944,7 @@ repo_gitignore_helper=Valitse .gitignore-mallit
issue_labels=Ongelmien tunnisteet
issue_labels_helper=Valitse pohja ongelmien nimilapuille.
license=Lisenssi
license_helper=Valitse lisenssitiedosto.
license_helper=Valitse lisenssitiedosto
readme=README
auto_init=Alusta repo (Luo .gitignore, License ja README)
create_repo=Luo repo
@ -1316,7 +1343,7 @@ activity.new_issues_count_1=Uusi ongelma
activity.new_issues_count_n=uutta ongelmaa
activity.new_issue_label=Avoinna
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_file_1=%d tiedosto
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_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.wiki_delete=Poista Wiki data
settings.wiki_delete=Poista wikidata
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.delete=Poista tämä repo
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_name=Koukun nimi
settings.githook_content=Koukun sisältö
settings.update_githook=Päivitys koukku
settings.update_githook=Päivitä koukku
settings.payload_url=Kohde URL
settings.http_method=HTTP-menetelmä
settings.secret=Salaus
@ -1406,7 +1433,7 @@ settings.event_push_desc=Git push repoon.
settings.event_repository=Repo
settings.event_repository_desc=Repo luotu tai poistettu.
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_issue_assign=Ongelma määritetty
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_comment_desc=Ongelman kommentti luotu, muokattu tai poistettu.
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.active_helper=Tiedot käynnistetyistä tapahtumista lähetetään tähän webkoukun URL-osoitteeseen.
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.
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ä
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ä
issues.filter_type.reviewed_by_you = Katselmoitu toimestasi
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
pulls.status_checks_details = Yksityiskohdat
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.delete_inactive_accounts=Poista kaikki aktivoimattomat käyttäjät
dashboard.delete_repo_archives=Poista kaikki repojen arkistot (ZIP, TAR.GZ, jne..)
dashboard.server_uptime=Palvelimen Uptime
dashboard.current_goroutine=Nykyiset Goroutinet
dashboard.server_uptime=Palvelimen uptime
dashboard.current_goroutine=Nykyiset goroutinet
dashboard.current_memory_usage=Nykyinen muistinkäyttö
dashboard.total_memory_allocated=Yhteensä muistia varattu
dashboard.memory_obtained=Muistia saatu
@ -2279,7 +2331,7 @@ config.default_visibility_organization=Uuden organisaation oletusnäkyvyys
config.webhook_config=Webkoukkujen asetukset
config.queue_length=Jonon pituus
config.deliver_timeout=Toimitus aikakatkaisu
config.deliver_timeout=Toimituksen aikakatkaisu
config.mailer_enabled=Käytössä
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.task.started = Käynnistetty tehtävä: %[1]s
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]
@ -2601,6 +2655,15 @@ settings.link = Linkitä tämä paketti repositorioon
maven.download = Lataa riippuvuus suorittamalla komentorivillä:
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.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]
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_migrate.link = Nouvelle migration
new_org.link = Nouvelle organisation
copy_path = Copier le chemin
[aria]
navbar=Barre de navigation
@ -811,7 +812,7 @@ manage_emails=Gérer les adresses courriels
manage_themes=Thème par défaut
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.
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
activated=Activé
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.
[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_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
@ -1095,7 +1096,7 @@ issue_labels=Étiquettes
issue_labels_helper=Sélectionner un jeu d'étiquettes
license=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_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.
@ -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.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.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.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.
@ -2844,6 +2845,10 @@ diff.git-notes.remove-body = Cette note sera supprimée.
diff.git-notes.add = Ajouter une 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
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]
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.info=Choisissez $branch et $repository dans la liste ci-dessous.
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.repositories=Dépôts
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.platform=Plateforme
container.pull=Tirez l'image depuis un terminal :
container.digest=Empreinte :
container.digest=Empreinte
container.multi_arch=SE / Arch
container.layers=Calques d'image
container.labels=Labels
@ -3797,6 +3802,7 @@ arch.version.conflicts = Conflits
arch.version.replaces = Remplace
arch.version.backup = Sauvegarde
arch.version.makedepends = Faire des dépendances
container.images.title = Images
[secrets]
secrets=Secrets

View file

@ -765,7 +765,7 @@ cancel=Atcelt
language=Valoda
ui=Motīvs
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.issue_ref_tooltip=Piebildes, kurās lietotājs maina ar pieteikumu saistītu zaru/birku
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.
confirm_delete_account=Apstiprināt izdzēšanu
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.onmention=Tikai, ja piemin mani
@ -1046,6 +1046,13 @@ blocked_users_none = Nav liegto lietotāju.
pronouns = Vietniekvārdi
pronouns_custom = Pielāgoti
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]
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.failed=Pārcelšana neizdevās: %v
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
migrate.migrate=Pārcelt no %s
migrate.migrating=Pārceļ no <b>%s</b> ...
migrate.migrating_failed=Pārcelšana no <b>%s</b> neizdevās.
migrate.migrating_failed.error=Neizdevās pārcelt: %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.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.gogs.description=Migrēt datus no notabug.org vai citām Gogs instancēm.
migrate.onedev.description=Migrēt datus no code.onedev.io vai citām OneDev instancēm.
migrate.codebase.description=Migrēt datus no codebasehq.com.
migrate.gitbucket.description=Migrēt datus no GitBucket instancēm.
migrate.migrating_git=Migrē git datus
migrate.migrating_topics=Migrē tēmas
migrate.migrating_milestones=Migrē atskaites punktus
migrate.gogs.description=Pārcelt datus no notabug.org vai citiem Gogs serveriem.
migrate.onedev.description=Pārcelt datus no code.onedev.io vai citiem OneDev serveriem.
migrate.codebase.description=Pārcelt datus no codebasehq.com.
migrate.gitbucket.description=Pārcelt datus no GitBucket serveriem.
migrate.migrating_git=Pārceļ Git datus
migrate.migrating_topics=Pārceļ tēmas
migrate.migrating_milestones=Pārceļ atskaites punktus
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_pulls=Pārceļ izmaiņu pieprasījumus
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.delete=Dzēst
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.start_tracking_short=Uzsākt laika skaitīšanu
issues.start_tracking=Uzsākt laika uzskaiti
@ -1820,7 +1827,7 @@ pulls.collapse_files=Savērst visas datnes
pulls.compare_base=pamata
pulls.compare_compare=atgādāt no
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.no_results=Nekas netika atrasts.
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_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.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.title=Izdzēst šo izmaiņu pieprasījumu?
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
@ -2035,7 +2042,7 @@ activity.period.semiyearly=6 mēneši
activity.period.yearly=1 gads
activity.overview=Pārskats
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_n=Iekļauti izmaiņu pieprasījumi
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.search_user_placeholder=Meklēt lietotāju…
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.team_not_in_organization=Komanda nav tajā pašā organizācijā kā repozitorijs
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šā apvienībā kā glabātava
settings.teams=Komandas
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.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.delete_team_tip=Komandai ir piekļuve visiem repozitorijiem un tā nevar tikt noņemta individuāli
settings.remove_team_success=Komandas piekļuve šim repozitorijam ir noņemta.
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 visām glabātavām, un to nevar noņemt
settings.remove_team_success=Tika noņemta komandas piekļuve glabātavai.
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.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_push=Aizgādāšana
settings.event_push_desc=Git aizgādāšana uz glabātavu.
settings.event_repository=Repozitorijs
settings.event_repository_desc=Repozitorijs izveidots vai dzēsts.
settings.event_repository=Glabātava
settings.event_repository_desc=Izveidota vai izdzēsta glabātava.
settings.event_header_issue=Pieteikumu notikumi
settings.event_issues=Izmainīšana
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_merge=Izmaiņu pieprasījuma iekļaušana
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_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
@ -2364,7 +2371,7 @@ settings.hook_type=Aizķeres veids
settings.slack_token=Pilnvara
settings.slack_domain=Domēns
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_forgejo = Forgejo
settings.web_hook_name_gogs=Gogs
@ -2384,7 +2391,7 @@ settings.packagist_api_token=API pilnvara
settings.packagist_package_url=Packagist pakotnes URL
settings.deploy_keys=Izvietošanas atslēgas
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_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.
@ -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.add_key_success=Izvietošanas atslēga "%s" tika pievienota.
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.branches=Zari
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_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_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_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.
@ -2490,16 +2497,16 @@ settings.archive.button=Arhivēt 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.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.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.unarchive.button=Atcelt repozitorija arhivēšanu
settings.unarchive.header=Atcelt šī repozitorija arhivēšanu
settings.archive.tagsettings_unavailable=Birku iestatījumi arhivētās glabātavās nav pieejami.
settings.unarchive.button=Atcelt glabātavas 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.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.update_avatar_success=Repozitorija attēls tika atjaunināts.
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=Glabātavas attēls tika atjaunināts.
settings.lfs=LFS
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
@ -2634,7 +2641,7 @@ release.downloads=Lejupielādes
release.download_count=Lejupielādes: %s
release.add_tag_msg=Izmantot laidiena nosaukumu un saturu kā birkas ziņojumu.
release.add_tag=Izveidot birku
release.releases_for=Repozitorja %s laidieni
release.releases_for=Glabātavas %s laidieni
release.tags_for=%s birkas
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.
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.
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]
component_loading=Ielādē %s...
@ -2802,7 +2826,7 @@ members=Dalībnieki
teams=Komandas
code=Kods
lower_members=dalībnieki
lower_repositories=repozitoriji
lower_repositories=glabātavas
create_new_team=Jauna komanda
create_team=Izveidot komandu
org_desc=Apraksts
@ -2810,9 +2834,9 @@ team_name=Komandas nosaukums
team_desc=Apraksts
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_access_desc=Piekļuve repozitorijiem
team_access_desc=Glabātavu piekļuve
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)
form.name_reserved=Organizācijas nosaukums "%s" ir rezervēts.
@ -2867,7 +2891,7 @@ members.invite_now=Uzaicināt tagad
teams.join=Pievienoties
teams.leave=Atstāt
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.none_access=Nav piekļuves
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.list=Neapstiprinātie uzaicinājumi
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.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.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.repositories=Komandas repozitoriji
teams.repositories=Komandas glabātavas
teams.search_repo_placeholder=Meklēt repozitorijā…
teams.remove_all_repos_title=Noņemt visus komandas repozitorijus
teams.remove_all_repos_desc=Šī darbība noņems visus repozitorijus no komandas.
teams.add_all_repos_title=Pievienot visus repozitorijus
teams.add_all_repos_desc=Šī darbība pievienos visus organizācijas repozitorijus šai komandai.
teams.remove_all_repos_title=Noņemt visas komandas glabātavas
teams.remove_all_repos_desc=Šī darbība noņems visas komandas glabātavas.
teams.add_all_repos_title=Pievienot visas glabātavas
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_duplicate_users=Lietotājs jau ir šajā komandā.
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.duplicate_active=E-pasta adrese jau ir aktīva citam lietotājam.
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.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.delete=Dzēst pakotni
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.error=Neizdevās izdzēst pakotni.
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.summary_card_alt = Tosamenfatens-Kaart vun eenem Gefall mit de Naam »%s« im Repositorium %s
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]
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_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.
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
activated=Ativado
requires_activation=Requer ativação
@ -1094,7 +1094,7 @@ issue_labels=Etiquetas
issue_labels_helper=Selecione um conjunto de etiquetas
license=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_helper=Selecione um modelo de arquivo README
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.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.branchsettings_unavailable=Configurações do branch não estão disponíveis quando o repositório está arquivado.
settings.archive.tagsettings_unavailable=As configurações de tag não estão disponíveis se o repositório estiver arquivado.
settings.archive.branchsettings_unavailable=Configurações de branch não estão disponíveis em repositórios arquivados.
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.lfs=LFS
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.header = Desarquivar este repositório
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>.
migrate.forgejo.description = Migrar dados do codeberg.org ou outras servidores Forgejo.
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
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.
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
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:
@ -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.install=Para instalar o pacote usando o Composer, execute o seguinte comando:
composer.dependencies=Dependências
composer.dependencies.development=Dependências de Desenvolvimento
composer.dependencies.development=Dependências de desenvolvimento
conan.details.repository=Repositório
conan.registry=Configure este registro pela linha de 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.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.pull=Puxe a imagem pela linha de comando:
container.digest=Digest
container.multi_arch=S.O. / Arquitetura
container.layers=Camadas da Imagem
container.layers=Camadas da imagem
container.labels=Rótulos
container.labels.key=Chave
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.install2=ou adicione-o ao arquivo package.json:
npm.dependencies=Dependências
npm.dependencies.development=Dependências de Desenvolvimento
npm.dependencies.peer=Dependências Peer
npm.dependencies.optional=Dependências Opcionais
npm.dependencies.development=Dependências de desenvolvimento
npm.dependencies.peer=Dependências peer
npm.dependencies.optional=Dependências opcionais
npm.details.tag=Tag
pub.install=Para instalar o pacote usando Dart, execute o seguinte comando:
pypi.requires=Requer Python
@ -3729,8 +3729,8 @@ rpm.repository = Informações do repositório
rpm.repository.architectures = Arquiteturas
rubygems.install=Para instalar o pacote usando gem, execute o seguinte comando:
rubygems.install2=ou adicione-o ao Gemfile:
rubygems.dependencies.runtime=Dependências de Execução
rubygems.dependencies.development=Dependências de Desenvolvimento
rubygems.dependencies.runtime=Dependências de tempo de execução
rubygems.dependencies.development=Dependências de desenvolvimento
rubygems.required.ruby=Requer o Ruby versão
rubygems.required.rubygems=Requer o RubyGem versão
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.keypair=Gerar par de chaves
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>.
arch.version.replaces = Substitui
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.groups = Grupo
arch.version.provides = Fornece

View file

@ -166,6 +166,7 @@ new_org.title = Nova organização
new_repo.link = Novo repositório
new_migrate.link = Nova migração
new_org.link = Nova organização
copy_path = Copiar caminho
[aria]
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.num_reviews_one = %d revisão
issues.num_reviews_few = %d revisões
editor.add_tmpl.filename = nome do ficheiro
[graphs]
component_loading=A carregar %s...
@ -3799,6 +3801,7 @@ arch.version.checkdepends = Verificar dependências
arch.version.conflicts = Conflitos
arch.version.backup = Cópia de segurança
arch.version.replaces = Substitui
container.images.title = Imagens
[secrets]
secrets=Segredos

View file

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

View file

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

View file

@ -2750,7 +2750,7 @@ pulls.made_using_agit = AGit
activity.navbar.pulse = 动态
activity.navbar.code_frequency = 代码频率
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>来修复这些问题,然后推送一些提交来刷新状态。
pulls.merged_title_desc_one = 已将来自 <code>%[2]s</code> 的 %[1]d 提交合并入 <code>%[3]s</code> %[4]s
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",
"vue3-calendar-heatmap": "2.0.5",
"webpack": "5.97.1",
"webpack-cli": "5.1.4",
"webpack-cli": "6.0.1",
"wrap-ansi": "9.0.0"
},
"devDependencies": {
@ -65,15 +65,15 @@
"@stoplight/spectral-cli": "6.14.2",
"@stylistic/eslint-plugin-js": "2.12.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",
"@vitest/coverage-v8": "2.1.8",
"@vitest/eslint-plugin": "1.1.16",
"@vitest/eslint-plugin": "1.1.20",
"@vue/test-utils": "2.4.6",
"eslint": "9.17.0",
"eslint-import-resolver-typescript": "3.7.0",
"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-use-extend-native": "0.7.2",
"eslint-plugin-playwright": "2.1.0",
@ -95,7 +95,7 @@
"stylelint-value-no-unknown-custom-properties": "6.0.1",
"svgo": "3.2.0",
"typescript": "5.7.2",
"typescript-eslint": "8.18.1",
"typescript-eslint": "8.18.2",
"vite-string-plugin": "1.3.4",
"vitest": "2.1.8"
},

79
poetry.lock generated
View file

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

View file

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

View file

View file

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

View file

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

View file

@ -5,6 +5,7 @@ package actions
import (
"bytes"
stdCtx "context"
"fmt"
"net/http"
"slices"
@ -224,7 +225,7 @@ func List(ctx *context.Context) {
return
}
if err := loadIsRefDeleted(ctx, runs); err != nil {
if err := loadIsRefDeleted(ctx, ctx.Repo.Repository.ID, runs); err != nil {
log.Error("LoadIsRefDeleted", err)
}
@ -254,7 +255,7 @@ func List(ctx *context.Context) {
// 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.
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))
for _, run := range runs {
refName := git.RefName(run.Ref)
@ -266,14 +267,14 @@ func loadIsRefDeleted(ctx *context.Context, runs actions_model.RunList) error {
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 {
return err
}
branchSet := git_model.BranchesToNamesSet(branchInfos)
for _, run := range runs {
refName := git.RefName(run.Ref)
if refName.IsBranch() && !branchSet.Contains(run.Ref) {
if refName.IsBranch() && !branchSet.Contains(refName.ShortName()) {
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
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)
if err != nil {
ctx.ServerError("GetDefaultMergeMessage", err)

View file

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

View file

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

View file

@ -39,6 +39,7 @@ import (
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"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/log"
"code.gitea.io/gitea/modules/markup"
@ -1152,6 +1153,12 @@ PostRecentBranchCheck:
ctx.Data["TreeNames"] = treeNames
ctx.Data["BranchLink"] = branchLink
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)
}

View file

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

View file

@ -29,6 +29,11 @@ func ToAPIPullRequest(ctx context.Context, pr *issues_model.PullRequest, doer *u
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 {
log.Error("pr.Issue.LoadRepo[%d]: %v", pr.ID, err)
return nil

View file

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

View file

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

View file

@ -72,7 +72,8 @@ func ReviewRequest(ctx context.Context, issue *issues_model.Issue, doer, reviewe
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)
}

View file

@ -8,7 +8,6 @@ import (
"fmt"
"io"
"strconv"
"strings"
"code.gitea.io/gitea/models/db"
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
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 {
return err
}

View file

@ -29,7 +29,7 @@ func TestUploadAvatar(t *testing.T) {
err := UploadAvatar(db.DefaultContext, repo, buff.Bytes())
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) {
@ -62,3 +62,27 @@ func TestDeleteAvatar(t *testing.T) {
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) {
gtPath := filepath.Join(tmpDir, ".gitea", "template")
if _, err := os.Stat(gtPath); os.IsNotExist(err) {
return nil, nil
} else if err != nil {
configDirs := []string{".forgejo", ".gitea"}
var templateFilePath string
for _, dir := range configDirs {
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 {
return nil, err
}
gt := &GiteaTemplate{
Path: gtPath,
return &GiteaTemplate{
Path: templateFilePath,
Content: content,
}
return gt, nil
}, nil
}
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
if issue.IsPull {
eventType = webhook_module.HookEventPullRequestComment
if err := issue.LoadPullRequest(ctx); err != nil {
log.Error("LoadPullRequest: %v", err)
return
}
pullRequest = convert.ToAPIPullRequest(ctx, issue.PullRequest, doer)
} else {
eventType = webhook_module.HookEventIssueComment

View file

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

View file

@ -17,13 +17,15 @@
{{svg "octicon-check-circle-fill" $size (printf "text green %s" $className)}}
{{else if eq .status "skipped"}}
{{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"}}
{{svg "octicon-clock" $size (printf "text yellow %s" $className)}}
{{else if eq .status "blocked"}}
{{svg "octicon-blocked" $size (printf "text yellow %s" $className)}}
{{else if eq .status "running"}}
{{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)}}
{{end}}
</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 .Repository.Website}}<a class="link" href="{{.Repository.Website}}">{{.Repository.Website}}</a>{{end}}
</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 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 */}}
@ -158,6 +152,22 @@
{{else if .IsBlame}}
{{template "repo/blame" .}}
{{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" .}}
{{end}}
</div>

View file

@ -9,23 +9,31 @@
{{if and $.UpdateAllowed $.UpdateByRebaseAllowed}}
<div class="tw-inline-block">
<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">
{{if eq $.UpdateStyle "rebase"}}
{{ctx.Locale.Tr "repo.pulls.update_branch_rebase"}}
{{else}}
{{ctx.Locale.Tr "repo.pulls.update_branch"}}
{{end}}
</span>
</button>
<div class="ui dropdown icon button">
{{svg "octicon-triangle-down"}}
<div class="menu">
<a class="item active selected" data-do="{{$.Link}}/update">{{ctx.Locale.Tr "repo.pulls.update_branch"}}</a>
<a class="item" data-do="{{$.Link}}/update?style=rebase">{{ctx.Locale.Tr "repo.pulls.update_branch_rebase"}}</a>
<a class="item {{if ne $.UpdateStyle "rebase"}}active selected{{end}}" data-do="{{$.Link}}/update?style=merge">
{{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>
{{end}}
{{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}}
<button class="ui compact button">
<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>
</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="ui checkbox">
<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)}}
<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)}}
<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)}}
@ -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)}}
</a>
{{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}}
{{svg "octicon-database"}} <b>{{$fileSizeFields.PrettyNumber}}</b> {{$fileSizeFields.TranslatedUnit}}
</span>

View file

@ -1,7 +1,7 @@
<div class="flex-text-block tw-flex-wrap">
{{range $term := .SearchResultLanguages}}
<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>
{{$term.Language}}
<div class="detail">{{$term.Count}}</div>
@ -13,7 +13,7 @@
{{$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>
<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">
{{svg "octicon-chevron-down"}}
</span>

View file

@ -1,4 +1,5 @@
<form class="ui form ignore-dirty">
<input type="hidden" name="path" value="{{.CodeSearchPath}}">
{{template "shared/search/combo_multi"
dict
"Value" .Keyword
@ -14,6 +15,23 @@
<p>{{ctx.Locale.Tr "search.code_search_unavailable"}}</p>
</div>
{{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}}
<div class="ui message" data-test-tag="grep">
<p>{{ctx.Locale.Tr "search.code_search_by_git_grep"}}</p>

View file

@ -23321,6 +23321,11 @@
"type": "string",
"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": "a short description of the repository.",
"type": "string",
@ -26605,6 +26610,10 @@
"type": "string",
"x-go-name": "DefaultMergeStyle"
},
"default_update_style": {
"type": "string",
"x-go-name": "DefaultUpdateStyle"
},
"description": {
"type": "string",
"x-go-name": "Description"

View file

@ -5,6 +5,7 @@ package integration
import (
"context"
"fmt"
"net/http"
"net/http/httptest"
"net/url"
@ -19,6 +20,7 @@ import (
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/gitrepo"
repo_module "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/test"
issue_service "code.gitea.io/gitea/services/issue"
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})
}
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) {
defer tests.PrepareTestEnv(t)()
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 {
options := map[string]string{
"_csrf": csrf,
@ -502,3 +594,9 @@ func testIssueClose(t *testing.T, session *TestSession, owner, repo, issueNumber
req = NewRequestWithValues(t, "POST", closeURL, options)
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
import (
"fmt"
"net/http"
"net/url"
"strings"
@ -16,6 +17,9 @@ import (
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"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"
repo_service "code.gitea.io/gitea/services/repository"
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 {
baseRepo, _, _ := tests.CreateDeclarativeRepo(t, actor, "repo-pr-update", nil, nil, nil)

View file

@ -7,6 +7,7 @@ package integration
import (
"fmt"
"net/http"
"net/url"
"strconv"
"strings"
"testing"
@ -14,9 +15,11 @@ import (
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/optional"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/test"
"code.gitea.io/gitea/modules/translation"
files_service "code.gitea.io/gitea/services/repository/files"
"code.gitea.io/gitea/tests"
"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
req = NewRequestf(t, "GET", "/%s/%s", generateOwner.Name, generateRepoName)
session.MakeRequest(t, req, http.StatusOK)
}
// Step5: 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)
func testRepoGenerateWithFixture(t *testing.T, session *TestSession, templateID, templateOwnerName, templateRepoName string, user, generateOwner *user_model.User, generateRepoName string) {
testRepoGenerate(t, session, templateID, templateOwnerName, templateRepoName, user, generateOwner, generateRepoName)
// 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
Owner: %s
Link: /%s/%s
@ -125,7 +132,7 @@ func TestRepoGenerate(t *testing.T) {
session := loginUser(t, 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) {
@ -135,7 +142,7 @@ func TestRepoGenerateToOrg(t *testing.T) {
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: userName})
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) {
@ -153,3 +160,66 @@ func TestRepoCreateFormTrimSpace(t *testing.T) {
assert.EqualValues(t, "/user2/spaced-name", test.RedirectURL(resp))
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)
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)
branchSubURL := "/branch/master"
if indexer {
assert.NotContains(t, action, branchSubURL)
} else {
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) {

View file

@ -389,6 +389,11 @@ td .commit-summary {
cursor: default;
}
.code-search + #repo-files-table {
border-top-left-radius: 0;
border-top-right-radius: 0;
}
.view-raw {
display: flex;
justify-content: center;
@ -2008,15 +2013,27 @@ details.repo-search-result summary::marker {
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 {
border: none;
display: flex;
align-items: center;
padding: 0;
overflow: hidden;
}
.repository .repository-summary .sub-menu .item {
.repository .repository-summary .item {
flex: 1;
height: 30px;
line-height: var(--line-height-default);
@ -2024,7 +2041,6 @@ details.repo-search-result summary::marker {
align-items: center;
justify-content: center;
gap: 0.25em;
padding: 0 0.5em; /* make the UI look better for narrow (mobile) view */
text-decoration: none;
}

View file

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

View file

@ -28,12 +28,13 @@ export default {
};
</script>
<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-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-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-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>
</template>

View file

@ -570,11 +570,13 @@ export function initRepositoryActionView() {
.action-info-summary-title {
display: flex;
align-items: center;
gap: 0.5em;
}
.action-info-summary-title-text {
font-size: 20px;
margin: 0 0 0 8px;
margin: 0;
flex: 1;
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 octiconSkip from '../../public/assets/img/svg/octicon-skip.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 octiconSync from '../../public/assets/img/svg/octicon-sync.svg';
import octiconTable from '../../public/assets/img/svg/octicon-table.svg';
@ -138,6 +139,7 @@ const svgs = {
'octicon-sidebar-expand': octiconSidebarExpand,
'octicon-skip': octiconSkip,
'octicon-star': octiconStar,
'octicon-stop': octiconStop,
'octicon-strikethrough': octiconStrikethrough,
'octicon-sync': octiconSync,
'octicon-table': octiconTable,