Merge branch 'master' of https://github.com/go-gitea/gitea into issue-due-date-api

# Conflicts:
#	vendor/vendor.json
This commit is contained in:
kolaente 2018-06-08 13:01:44 +02:00
commit 1bf3c47075
No known key found for this signature in database
GPG Key ID: F40E70337AB24C9B
406 changed files with 14464 additions and 33419 deletions

View File

@ -197,6 +197,7 @@ pipeline:
environment: environment:
TAGS: bindata sqlite TAGS: bindata sqlite
commands: commands:
- export PATH=$PATH:$GOPATH/bin
- make release - make release
when: when:
event: [ push, tag ] event: [ push, tag ]

View File

@ -4,6 +4,21 @@ This changelog goes through all the changes that have been made in each release
without substantial changes to our git log; to see the highlights of what has without substantial changes to our git log; to see the highlights of what has
been added to each release, please refer to the [blog](https://blog.gitea.io). been added to each release, please refer to the [blog](https://blog.gitea.io).
## [1.4.2](https://github.com/go-gitea/gitea/releases/tag/v1.4.2) - 2018-06-04
* BUGFIXES
* Adjust z-index for floating labels (#3939) (#3950)
* Add missing token validation on application settings page (#3976) #3978
* Webhook and hook_task clean up (#4006)
* Fix webhook bug of response info is not displayed in UI (#4023)
* Fix writer cannot read bare repo guide (#4033) (#4039)
* Don't force due date to current time (#3830) (#4057)
* Fix wiki redirects (#3919) (#4065)
* Fix attachment ENABLED (#4064) (#4066)
* Added deletion of an empty line at the end of file (#4054) (#4074)
* Use ResolveReference instead of path.Join (#4073)
* Fix #4081 Check for leading / in base before removing it (#4083)
* Respository's home page not updated after first push (#4075)
## [1.4.1](https://github.com/go-gitea/gitea/releases/tag/v1.4.1) - 2018-05-03 ## [1.4.1](https://github.com/go-gitea/gitea/releases/tag/v1.4.1) - 2018-05-03
* BREAKING * BREAKING
* Add "error" as reserved username (#3882) (#3886) * Add "error" as reserved username (#3882) (#3886)

View File

@ -69,14 +69,14 @@ and keep the compatibility on upgrade. To make sure you are
running the test suite exactly like we do, you should install running the test suite exactly like we do, you should install
the CLI for [Drone CI](https://github.com/drone/drone), as the CLI for [Drone CI](https://github.com/drone/drone), as
we are using the server for continous testing, following [these we are using the server for continous testing, following [these
instructions](http://readme.drone.io/usage/getting-started-cli). After that, instructions](http://docs.drone.io/cli-installation/). After that,
you can simply call `drone exec` within your working directory and it will try you can simply call `drone exec --local --build-event "pull_request"` within
to run the test suite locally. your working directory and it will try to run the test suite locally.
## Vendoring ## Vendoring
We keep a cached copy of dependencies within the `vendor/` directory, We keep a cached copy of dependencies within the `vendor/` directory,
managing updates via [govendor](http://github.com/kardianos/govendor). managing updates via [dep](https://github.com/golang/dep).
Pull requests should only include `vendor/` updates if they are part of Pull requests should only include `vendor/` updates if they are part of
the same change, be it a bugfix or a feature addition. the same change, be it a bugfix or a feature addition.
@ -85,6 +85,8 @@ The `vendor/` update needs to be justified as part of the PR description,
and must be verified by the reviewers and/or merger to always reference and must be verified by the reviewers and/or merger to always reference
an existing upstream commit. an existing upstream commit.
You can find more information on how to get started with it on the [dep project website](https://golang.github.io/dep/docs/introduction.html).
## Translation ## Translation
We do all translation work inside [Crowdin](https://crowdin.com/project/gitea). We do all translation work inside [Crowdin](https://crowdin.com/project/gitea).
@ -112,7 +114,7 @@ pull request workflow to do that. And, we also use [LGTM](http://lgtm.co)
to ensure every PR is reviewed by at least 2 maintainers. to ensure every PR is reviewed by at least 2 maintainers.
Please try to make your pull request easy to review for us. And, please read Please try to make your pull request easy to review for us. And, please read
the *[How to get faster PR reviews](https://github.com/kubernetes/community/blob/master/contributors/devel/pull-requests.md#best-practices-for-faster-reviews)* guide; the *[How to get faster PR reviews](https://github.com/kubernetes/community/blob/261cb0fd089b64002c91e8eddceebf032462ccd6/contributors/guide/pull-requests.md#best-practices-for-faster-reviews)* guide;
it has lots of useful tips for any project you may want to contribute. it has lots of useful tips for any project you may want to contribute.
Some of the key points: Some of the key points:

878
Gopkg.lock generated Normal file
View File

@ -0,0 +1,878 @@
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
[[projects]]
branch = "master"
name = "code.gitea.io/git"
packages = ["."]
revision = "31f4b8e8c805438ac6d8914b38accb1d8aaf695e"
[[projects]]
branch = "master"
name = "code.gitea.io/sdk"
packages = ["gitea"]
revision = "b2308e3f700875a3642a78bd3f6e5db8ef6f974d"
[[projects]]
name = "github.com/PuerkitoBio/goquery"
packages = ["."]
revision = "ed7d758e9a34ba1f55e8084e0d731448b46921a8"
[[projects]]
name = "github.com/RoaringBitmap/roaring"
packages = ["."]
revision = "1a28a7fa985680f9f4e1644c0a857ec359a444b0"
version = "v0.4.7"
[[projects]]
branch = "master"
name = "github.com/Smerity/govarint"
packages = ["."]
revision = "7265e41f48f15fd61751e16da866af3c704bb3ab"
[[projects]]
branch = "master"
name = "github.com/Unknwon/cae"
packages = [
".",
"zip"
]
revision = "c6aac99ea2cae2ebaf23f26f76b04fe3fcfc9f8c"
[[projects]]
branch = "master"
name = "github.com/Unknwon/com"
packages = ["."]
revision = "7677a1d7c1137cd3dd5ba7a076d0c898a1ef4520"
[[projects]]
branch = "master"
name = "github.com/Unknwon/i18n"
packages = ["."]
revision = "b64d336589669d317928070e70ba0ae558f16633"
[[projects]]
name = "github.com/Unknwon/paginater"
packages = ["."]
revision = "7748a72e01415173a27d79866b984328e7b0c12b"
[[projects]]
name = "github.com/andybalholm/cascadia"
packages = ["."]
revision = "349dd0209470eabd9514242c688c403c0926d266"
[[projects]]
name = "github.com/blevesearch/bleve"
packages = [
".",
"analysis",
"analysis/analyzer/custom",
"analysis/analyzer/standard",
"analysis/datetime/flexible",
"analysis/datetime/optional",
"analysis/lang/en",
"analysis/token/camelcase",
"analysis/token/lowercase",
"analysis/token/porter",
"analysis/token/stop",
"analysis/token/unicodenorm",
"analysis/token/unique",
"analysis/tokenizer/unicode",
"document",
"geo",
"index",
"index/scorch",
"index/scorch/mergeplan",
"index/scorch/segment",
"index/scorch/segment/mem",
"index/scorch/segment/zap",
"index/store",
"index/store/boltdb",
"index/store/gtreap",
"index/upsidedown",
"mapping",
"numeric",
"registry",
"search",
"search/collector",
"search/facet",
"search/highlight",
"search/highlight/format/html",
"search/highlight/fragmenter/simple",
"search/highlight/highlighter/html",
"search/highlight/highlighter/simple",
"search/query",
"search/scorer",
"search/searcher"
]
revision = "ff210fbc6d348ad67aa5754eaea11a463fcddafd"
[[projects]]
branch = "master"
name = "github.com/blevesearch/go-porterstemmer"
packages = ["."]
revision = "23a2c8e5cf1f380f27722c6d2ae8896431dc7d0e"
[[projects]]
name = "github.com/blevesearch/segment"
packages = ["."]
revision = "db70c57796cc8c310613541dfade3dce627d09c7"
[[projects]]
name = "github.com/boltdb/bolt"
packages = ["."]
revision = "ccd680d8c1a0179ac3d68f692b01e1a1589cbfc7"
source = "github.com/go-gitea/bolt"
[[projects]]
name = "github.com/boombuler/barcode"
packages = [
".",
"qr",
"utils"
]
revision = "fe0f26ff6d26693948ee8189aa064ee8c54141fa"
[[projects]]
name = "github.com/bradfitz/gomemcache"
packages = ["memcache"]
revision = "fb1f79c6b65acda83063cbc69f6bba1522558bfc"
[[projects]]
name = "github.com/chaseadamsio/goorgeous"
packages = ["."]
revision = "098da33fde5f9220736531b3cb26a2dec86a8367"
[[projects]]
name = "github.com/coreos/etcd"
packages = ["error"]
revision = "01c303113d0a3d5a8075864321c3aedb72035bdd"
[[projects]]
branch = "master"
name = "github.com/coreos/go-etcd"
packages = ["etcd"]
revision = "003851be7bb0694fe3cc457a49529a19388ee7cf"
[[projects]]
branch = "master"
name = "github.com/couchbase/vellum"
packages = [
".",
"regexp",
"utf8"
]
revision = "eb6ae3743b3f300f2136f83ca78c08cc071edbd4"
[[projects]]
name = "github.com/davecgh/go-spew"
packages = ["spew"]
revision = "346938d642f2ec3594ed81d874461961cd0faa76"
version = "v1.1.0"
[[projects]]
name = "github.com/denisenkom/go-mssqldb"
packages = ["."]
revision = "e32ca5036449b7ea12c62ed761ea1ad7fc88a4e2"
[[projects]]
name = "github.com/dgrijalva/jwt-go"
packages = ["."]
revision = "9ed569b5d1ac936e6494082958d63a6aa4fff99a"
[[projects]]
branch = "master"
name = "github.com/edsrzf/mmap-go"
packages = ["."]
revision = "0bce6a6887123b67a60366d2c9fe2dfb74289d2e"
[[projects]]
name = "github.com/elazarl/go-bindata-assetfs"
packages = ["."]
revision = "57eb5e1fc594ad4b0b1dbea7b286d299e0cb43c2"
[[projects]]
name = "github.com/ethantkoenig/rupture"
packages = ["."]
revision = "0a76f03a811abcca2e6357329b673e9bb8ef9643"
[[projects]]
branch = "master"
name = "github.com/facebookgo/clock"
packages = ["."]
revision = "600d898af40aa09a7a93ecb9265d87b0504b6f03"
[[projects]]
name = "github.com/facebookgo/grace"
packages = [
"gracehttp",
"gracenet"
]
revision = "5729e484473f52048578af1b80d0008c7024089b"
[[projects]]
branch = "master"
name = "github.com/facebookgo/httpdown"
packages = ["."]
revision = "a3b1354551a26449fbe05f5d855937f6e7acbd71"
[[projects]]
branch = "master"
name = "github.com/facebookgo/stats"
packages = ["."]
revision = "1b76add642e42c6ffba7211ad7b3939ce654526e"
[[projects]]
branch = "master"
name = "github.com/glycerine/go-unsnap-stream"
packages = ["."]
revision = "9f0cb55181dd3a0a4c168d3dbc72d4aca4853126"
[[projects]]
branch = "master"
name = "github.com/go-macaron/bindata"
packages = ["."]
revision = "85786f57eee3e5544a9cc24fa2afe425b97a8652"
[[projects]]
name = "github.com/go-macaron/binding"
packages = ["."]
revision = "9440f336b443056c90d7d448a0a55ad8c7599880"
[[projects]]
branch = "master"
name = "github.com/go-macaron/cache"
packages = [
".",
"memcache",
"redis"
]
revision = "56173531277692bc2925924d51fda1cd0a6b8178"
[[projects]]
name = "github.com/go-macaron/captcha"
packages = ["."]
revision = "8aa5919789ab301e865595eb4b1114d6b9847deb"
[[projects]]
branch = "master"
name = "github.com/go-macaron/csrf"
packages = ["."]
revision = "503617c6b37257a55dff6293ec28556506c3a9a8"
[[projects]]
branch = "master"
name = "github.com/go-macaron/gzip"
packages = ["."]
revision = "cad1c6580a07c56f5f6bc52d66002a05985c5854"
[[projects]]
branch = "master"
name = "github.com/go-macaron/i18n"
packages = ["."]
revision = "ef57533c3b0fc2d8581deda14937e52f11a203ab"
[[projects]]
branch = "master"
name = "github.com/go-macaron/inject"
packages = ["."]
revision = "d8a0b8677191f4380287cfebd08e462217bac7ad"
[[projects]]
name = "github.com/go-macaron/session"
packages = [
".",
"redis"
]
revision = "66031fcb37a0fff002a1f028eb0b3a815c78306b"
[[projects]]
name = "github.com/go-macaron/toolbox"
packages = ["."]
revision = "99a42f20e9e88daec5c0d7beb4e7eac134680ab0"
[[projects]]
name = "github.com/go-sql-driver/mysql"
packages = ["."]
revision = "ce924a41eea897745442daaa1739089b0f3f561d"
[[projects]]
name = "github.com/go-xorm/builder"
packages = ["."]
revision = "488224409dd8aa2ce7a5baf8d10d55764a913738"
[[projects]]
name = "github.com/go-xorm/core"
packages = ["."]
revision = "cb1d0ca71f42d3ee1bf4aba7daa16099bc31a7e9"
[[projects]]
name = "github.com/go-xorm/tidb"
packages = ["."]
revision = "21e49190ce47a766fa741cf7edc831a30c12c6ac"
[[projects]]
name = "github.com/go-xorm/xorm"
packages = ["."]
revision = "d4149d1eee0c2c488a74a5863fd9caf13d60fd03"
[[projects]]
branch = "master"
name = "github.com/gogits/chardet"
packages = ["."]
revision = "2404f777256163ea3eadb273dada5dcb037993c0"
[[projects]]
name = "github.com/gogits/cron"
packages = ["."]
revision = "7f3990acf1833faa5ebd0e86f0a4c72a4b5eba3c"
[[projects]]
name = "github.com/golang/protobuf"
packages = ["proto"]
revision = "99511271042a09d1e01baea8781caa5210fec66e"
[[projects]]
name = "github.com/golang/snappy"
packages = ["."]
revision = "5f1c01d9f64b941dd9582c638279d046eda6ca31"
[[projects]]
name = "github.com/gorilla/context"
packages = ["."]
revision = "08b5f424b9271eedf6f9f0ce86cb9396ed337a42"
version = "v1.1.1"
[[projects]]
name = "github.com/gorilla/mux"
packages = ["."]
revision = "757bef944d0f21880861c2dd9c871ca543023cba"
[[projects]]
name = "github.com/gorilla/securecookie"
packages = ["."]
revision = "e59506cc896acb7f7bf732d4fdf5e25f7ccd8983"
version = "v1.1.1"
[[projects]]
name = "github.com/gorilla/sessions"
packages = ["."]
revision = "ca9ada44574153444b00d3fd9c8559e4cc95f896"
version = "v1.1"
[[projects]]
name = "github.com/issue9/identicon"
packages = ["."]
revision = "d36b54562f4cf70c83653e13dc95c220c79ef521"
[[projects]]
name = "github.com/jaytaylor/html2text"
packages = ["."]
revision = "8fb95d837f7d6db1913fecfd7bcc5333e6499596"
[[projects]]
name = "github.com/juju/errors"
packages = ["."]
revision = "b2c7a7da5b2995941048f60146e67702a292e468"
[[projects]]
name = "github.com/kballard/go-shellquote"
packages = ["."]
revision = "cd60e84ee657ff3dc51de0b4f55dd299a3e136f2"
[[projects]]
name = "github.com/keybase/go-crypto"
packages = [
"brainpool",
"cast5",
"curve25519",
"ed25519",
"ed25519/internal/edwards25519",
"openpgp",
"openpgp/armor",
"openpgp/ecdh",
"openpgp/elgamal",
"openpgp/errors",
"openpgp/packet",
"openpgp/s2k",
"rsa"
]
revision = "00ac4db533f63ef97576cbc7b07939ff7daf7329"
[[projects]]
name = "github.com/klauspost/compress"
packages = [
"flate",
"gzip"
]
revision = "8df558b6cb6f9b445f9586446cfe7223e7d8bd6b"
version = "v1.1"
[[projects]]
name = "github.com/klauspost/cpuid"
packages = ["."]
revision = "09cded8978dc9e80714c4d85b0322337b0a1e5e0"
version = "v1.0"
[[projects]]
name = "github.com/klauspost/crc32"
packages = ["."]
revision = "cb6bfca970f6908083f26f39a79009d608efd5cd"
version = "v1.1"
[[projects]]
name = "github.com/lafriks/xormstore"
packages = [
".",
"util"
]
revision = "9cab149ea91875cf056211bd6ef82379fce9cb67"
version = "v1.0.0"
[[projects]]
name = "github.com/lib/pq"
packages = [
".",
"oid"
]
revision = "456514e2defec52e0cd37f90ccf17ec8b28295e2"
[[projects]]
branch = "master"
name = "github.com/lunny/dingtalk_webhook"
packages = ["."]
revision = "e3534c89ef969912856dfa39e56b09e58c5f5daf"
[[projects]]
name = "github.com/markbates/goth"
packages = [
".",
"gothic",
"providers/bitbucket",
"providers/dropbox",
"providers/facebook",
"providers/github",
"providers/gitlab",
"providers/gplus",
"providers/openidConnect",
"providers/twitter"
]
revision = "4933f155d89c3c52ab4ca545c6602cf4a1e87913"
version = "1.45.5"
[[projects]]
name = "github.com/mattn/go-sqlite3"
packages = ["."]
revision = "acfa60124032040b9f5a9406f5a772ee16fe845e"
[[projects]]
branch = "master"
name = "github.com/mcuadros/go-version"
packages = ["."]
revision = "88e56e02bea1c203c99222c365fa52a69996ccac"
[[projects]]
name = "github.com/microcosm-cc/bluemonday"
packages = ["."]
revision = "f77f16ffc87a6a58814e64ae72d55f9c41374e6d"
[[projects]]
name = "github.com/mrjones/oauth"
packages = ["."]
revision = "3f67d9c274355678b2f9844b08d643e2f9213340"
[[projects]]
branch = "master"
name = "github.com/mschoch/smat"
packages = ["."]
revision = "90eadee771aeab36e8bf796039b8c261bebebe4f"
[[projects]]
name = "github.com/msteinert/pam"
packages = ["."]
revision = "02ccfbfaf0cc627aa3aec8ef7ed5cfeec5b43f63"
[[projects]]
name = "github.com/nfnt/resize"
packages = ["."]
revision = "891127d8d1b52734debe1b3c3d7e747502b6c366"
[[projects]]
name = "github.com/ngaut/deadline"
packages = ["."]
revision = "fae8f9dfd7048de16575b9d4c255278e38c28a4f"
[[projects]]
branch = "master"
name = "github.com/ngaut/go-zookeeper"
packages = ["zk"]
revision = "9c3719e318c7cfd072e41eb48cb71fcaa49d5e05"
[[projects]]
name = "github.com/ngaut/log"
packages = ["."]
revision = "d2af3a61f64d093457fb23b25d20f4ce3cd551ce"
[[projects]]
branch = "master"
name = "github.com/ngaut/pools"
packages = ["."]
revision = "b7bc8c42aac787667ba45adea78233f53f548443"
[[projects]]
branch = "master"
name = "github.com/ngaut/sync2"
packages = ["."]
revision = "7a24ed77b2efb460c1468b7dc917821c66e80e55"
[[projects]]
branch = "master"
name = "github.com/ngaut/tso"
packages = [
"client",
"proto",
"util"
]
revision = "118f6c141d58f1e72577ff61f43f649bf39355ee"
[[projects]]
branch = "master"
name = "github.com/ngaut/zkhelper"
packages = ["."]
revision = "6738bdc138d469112c6687fbfcfe049ccabd6a0a"
[[projects]]
branch = "master"
name = "github.com/petar/GoLLRB"
packages = ["llrb"]
revision = "53be0d36a84c2a886ca057d34b6aa4468df9ccb4"
[[projects]]
name = "github.com/philhofer/fwd"
packages = ["."]
revision = "bb6d471dc95d4fe11e432687f8b70ff496cf3136"
version = "v1.0.0"
[[projects]]
name = "github.com/pingcap/go-hbase"
packages = [
".",
"iohelper",
"proto"
]
revision = "7a98d1fe4e9e115de8c77ae0e158c0d08732c550"
[[projects]]
branch = "master"
name = "github.com/pingcap/go-themis"
packages = [
".",
"oracle",
"oracle/oracles"
]
revision = "dbb996606c1d1fe8571fd9ac6da2254c76d2c5c9"
[[projects]]
name = "github.com/pingcap/tidb"
packages = [
".",
"ast",
"column",
"context",
"ddl",
"domain",
"evaluator",
"executor",
"infoschema",
"inspectkv",
"kv",
"kv/memkv",
"meta",
"meta/autoid",
"model",
"mysql",
"optimizer",
"optimizer/plan",
"parser",
"parser/opcode",
"perfschema",
"privilege",
"privilege/privileges",
"sessionctx",
"sessionctx/autocommit",
"sessionctx/db",
"sessionctx/forupdate",
"sessionctx/variable",
"store/hbase",
"store/localstore",
"store/localstore/boltdb",
"store/localstore/engine",
"store/localstore/goleveldb",
"structure",
"table",
"table/tables",
"terror",
"util",
"util/bytes",
"util/charset",
"util/codec",
"util/distinct",
"util/hack",
"util/segmentmap",
"util/sqlexec",
"util/stringutil",
"util/types"
]
revision = "33197485abe227dcb254644cf5081c9a3c281669"
[[projects]]
name = "github.com/pmezard/go-difflib"
packages = ["difflib"]
revision = "792786c7400a136282c1664665ae0a8db921c6c2"
version = "v1.0.0"
[[projects]]
name = "github.com/pquerna/otp"
packages = [
".",
"hotp",
"totp"
]
revision = "54653902c20e47f3417541d35435cb6d6162e28a"
[[projects]]
branch = "master"
name = "github.com/russross/blackfriday"
packages = ["."]
revision = "11635eb403ff09dbc3a6b5a007ab5ab09151c229"
[[projects]]
name = "github.com/satori/go.uuid"
packages = ["."]
revision = "b061729afc07e77a8aa4fad0a2fd840958f1942a"
[[projects]]
name = "github.com/sergi/go-diff"
packages = ["diffmatchpatch"]
revision = "552b4e9bbdca9e5adafd95ee98c822fdd11b330b"
[[projects]]
name = "github.com/shurcooL/sanitized_anchor_name"
packages = ["."]
revision = "1dba4b3954bc059efc3991ec364f9f9a35f597d2"
[[projects]]
branch = "master"
name = "github.com/steveyen/gtreap"
packages = ["."]
revision = "0abe01ef9be25c4aedc174758ec2d917314d6d70"
[[projects]]
name = "github.com/stretchr/testify"
packages = ["assert"]
revision = "12b6f73e6084dad08a7c6e575284b177ecafbc71"
version = "v1.2.1"
[[projects]]
name = "github.com/syndtr/goleveldb"
packages = [
"leveldb",
"leveldb/cache",
"leveldb/comparer",
"leveldb/errors",
"leveldb/filter",
"leveldb/iterator",
"leveldb/journal",
"leveldb/memdb",
"leveldb/opt",
"leveldb/storage",
"leveldb/table",
"leveldb/util"
]
revision = "917f41c560270110ceb73c5b38be2a9127387071"
[[projects]]
branch = "master"
name = "github.com/tinylib/msgp"
packages = ["msgp"]
revision = "c8cf64dff2009d53fa8f8a16df54d1cdfc64c4a7"
[[projects]]
branch = "master"
name = "github.com/tstranex/u2f"
packages = ["."]
revision = "d21a03e0b1d9fc1df59ff54e7a513655c1748b0c"
[[projects]]
name = "github.com/twinj/uuid"
packages = ["."]
revision = "89173bcdda19db0eb88aef1e1cb1cb2505561d31"
version = "0.10.0"
[[projects]]
name = "github.com/ugorji/go"
packages = ["codec"]
revision = "c062049c1793b01a3cc3fe786108edabbaf7756b"
[[projects]]
name = "github.com/urfave/cli"
packages = ["."]
revision = "d86a009f5e13f83df65d0d6cee9a2e3f1445f0da"
[[projects]]
branch = "master"
name = "github.com/willf/bitset"
packages = ["."]
revision = "8ce1146b8621c95164efd9c8b1124cfa9b8afb4e"
[[projects]]
name = "github.com/yohcop/openid-go"
packages = ["."]
revision = "2c050d2dae5345c417db301f11fda6fbf5ad0f0a"
[[projects]]
name = "golang.org/x/crypto"
packages = [
"curve25519",
"ed25519",
"ed25519/internal/edwards25519",
"md4",
"pbkdf2",
"ssh"
]
revision = "9f005a07e0d31d45e6656d241bb5c0f2efd4bc94"
[[projects]]
name = "golang.org/x/net"
packages = [
"context",
"html",
"html/atom",
"html/charset"
]
revision = "f2499483f923065a842d38eb4c7f1927e6fc6e6d"
[[projects]]
name = "golang.org/x/oauth2"
packages = [
".",
"internal"
]
revision = "c10ba270aa0bf8b8c1c986e103859c67a9103061"
[[projects]]
name = "golang.org/x/sync"
packages = ["syncmap"]
revision = "5a06fca2c336a4b2b2fcb45702e8c47621b2aa2c"
[[projects]]
name = "golang.org/x/sys"
packages = [
"unix",
"windows",
"windows/svc"
]
revision = "a646d33e2ee3172a661fc09bca23bb4889a41bc8"
[[projects]]
name = "golang.org/x/text"
packages = [
"encoding",
"encoding/charmap",
"encoding/htmlindex",
"encoding/internal",
"encoding/internal/identifier",
"encoding/japanese",
"encoding/korean",
"encoding/simplifiedchinese",
"encoding/traditionalchinese",
"encoding/unicode",
"internal/gen",
"internal/tag",
"internal/triegen",
"internal/ucd",
"internal/utf8internal",
"language",
"runes",
"transform",
"unicode/cldr",
"unicode/norm"
]
revision = "2bf8f2a19ec09c670e931282edfe6567f6be21c9"
[[projects]]
branch = "v3"
name = "gopkg.in/alexcesaro/quotedprintable.v3"
packages = ["."]
revision = "2caba252f4dc53eaf6b553000885530023f54623"
[[projects]]
name = "gopkg.in/asn1-ber.v1"
packages = ["."]
revision = "4e86f4367175e39f69d9358a5f17b4dda270378d"
version = "v1.1"
[[projects]]
name = "gopkg.in/bufio.v1"
packages = ["."]
revision = "567b2bfa514e796916c4747494d6ff5132a1dfce"
version = "v1"
[[projects]]
name = "gopkg.in/editorconfig/editorconfig-core-go.v1"
packages = ["."]
revision = "a872f05c2e34b37b567401384d202aff11ba06d4"
version = "v1.2.0"
[[projects]]
branch = "v2"
name = "gopkg.in/gomail.v2"
packages = ["."]
revision = "81ebce5c23dfd25c6c67194b37d3dd3f338c98b1"
[[projects]]
name = "gopkg.in/ini.v1"
packages = ["."]
revision = "7e7da451323b6766da368f8a1e8ec9a88a16b4a0"
version = "v1.31.1"
[[projects]]
name = "gopkg.in/ldap.v2"
packages = ["."]
revision = "d0a5ced67b4dc310b9158d63a2c6f9c5ec13f105"
version = "v2.4.1"
[[projects]]
name = "gopkg.in/macaron.v1"
packages = ["."]
revision = "75f2e9b42e99652f0d82b28ccb73648f44615faa"
version = "v1.2.4"
[[projects]]
name = "gopkg.in/redis.v2"
packages = ["."]
revision = "e6179049628164864e6e84e973cfb56335748dea"
version = "v2.3.2"
[[projects]]
name = "gopkg.in/testfixtures.v2"
packages = ["."]
revision = "b9ef14dc461bf934d8df2dfc6f1f456be5664cca"
version = "v2.0.0"
[[projects]]
name = "gopkg.in/yaml.v2"
packages = ["."]
revision = "a5b47d31c556af34a302ce5d659e6fea44d90de0"
[[projects]]
name = "strk.kbt.io/projects/go/libravatar"
packages = ["."]
revision = "5eed7bff870ae19ef51c5773dbc8f3e9fcbd0982"
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "036b8c882671cf8d2c5e2fdbe53b1bdfbd39f7ebd7765bd50276c7c4ecf16687"
solver-name = "gps-cdcl"
solver-version = 1

106
Gopkg.toml Normal file
View File

@ -0,0 +1,106 @@
ignored = ["google.golang.org/appengine*"]
[prune]
go-tests = true
unused-packages = true
non-go = true
[[constraint]]
branch = "master"
name = "code.gitea.io/git"
[[constraint]]
branch = "master"
name = "code.gitea.io/sdk"
[[constraint]]
revision = "9f005a07e0d31d45e6656d241bb5c0f2efd4bc94"
name = "golang.org/x/crypto"
[[constraint]]
revision = "a646d33e2ee3172a661fc09bca23bb4889a41bc8"
name = "golang.org/x/sys"
[[constraint]]
revision = "2bf8f2a19ec09c670e931282edfe6567f6be21c9"
name = "golang.org/x/text"
[[constraint]]
revision = "f2499483f923065a842d38eb4c7f1927e6fc6e6d"
name = "golang.org/x/net"
[[constraint]]
#version = "v1.0.0"
revision = "33197485abe227dcb254644cf5081c9a3c281669"
name = "github.com/pingcap/tidb"
[[override]]
name = "github.com/go-xorm/xorm"
#version = "0.6.5"
revision = "d4149d1eee0c2c488a74a5863fd9caf13d60fd03"
[[override]]
name = "github.com/gorilla/mux"
revision = "757bef944d0f21880861c2dd9c871ca543023cba"
[[constraint]]
name = "github.com/gorilla/context"
version = "1.1.1"
[[constraint]]
name = "github.com/lafriks/xormstore"
version = "1.0.0"
[[constraint]]
branch = "master"
name = "github.com/lunny/dingtalk_webhook"
[[constraint]]
name = "github.com/markbates/goth"
version = "1.45.5"
[[constraint]]
branch = "master"
name = "github.com/mcuadros/go-version"
[[constraint]]
branch = "master"
name = "github.com/russross/blackfriday"
[[constraint]]
branch = "master"
name = "github.com/tstranex/u2f"
[[constraint]]
name = "gopkg.in/editorconfig/editorconfig-core-go.v1"
version = "1.2.0"
[[constraint]]
branch = "v2"
name = "gopkg.in/gomail.v2"
[[constraint]]
name = "gopkg.in/ini.v1"
version = "1.31.1"
[[constraint]]
name = "gopkg.in/ldap.v2"
version = "2.4.1"
[[constraint]]
name = "gopkg.in/macaron.v1"
version = "1.2.4"
[[constraint]]
name = "gopkg.in/testfixtures.v2"
version = "2.0.0"
[[override]]
name = "github.com/boltdb/bolt"
revision = "ccd680d8c1a0179ac3d68f692b01e1a1589cbfc7"
source = "github.com/go-gitea/bolt"
[[override]]
revision = "c10ba270aa0bf8b8c1c986e103859c67a9103061"
name = "golang.org/x/oauth2"

View File

@ -22,3 +22,4 @@ Peter Žeby <morlinest@gmail.com> (@morlinest)
Matti Ranta <matti@mdranta.net> (@techknowlogick) Matti Ranta <matti@mdranta.net> (@techknowlogick)
Michael Lustfield <mtecknology@debian.org> (@MTecknology) Michael Lustfield <mtecknology@debian.org> (@MTecknology)
Jonas Franz <info@jonasfranz.software> (@JonasFranzDEV) Jonas Franz <info@jonasfranz.software> (@JonasFranzDEV)
Flynn Lufmons <fluf@warpmail.net> (@flufmonster)

View File

@ -100,6 +100,13 @@ swagger-check: generate-swagger
exit 1; \ exit 1; \
fi; fi;
.PHONY: swagger-validate
swagger-validate:
@hash swagger > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
$(GO) get -u github.com/go-swagger/go-swagger/cmd/swagger; \
fi
swagger validate ./public/swagger.v1.json
.PHONY: errcheck .PHONY: errcheck
errcheck: errcheck:
@hash errcheck > /dev/null 2>&1; if [ $$? -ne 0 ]; then \ @hash errcheck > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
@ -153,18 +160,22 @@ coverage:
unit-test-coverage: unit-test-coverage:
for PKG in $(PACKAGES); do $(GO) test -tags=sqlite -cover -coverprofile $$GOPATH/src/$$PKG/coverage.out $$PKG || exit 1; done; for PKG in $(PACKAGES); do $(GO) test -tags=sqlite -cover -coverprofile $$GOPATH/src/$$PKG/coverage.out $$PKG || exit 1; done;
.PHONY: test-vendor .PHONY: vendor
test-vendor: vendor:
@hash govendor > /dev/null 2>&1; if [ $$? -ne 0 ]; then \ @hash dep > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
$(GO) get -u github.com/kardianos/govendor; \ $(GO) get -u github.com/golang/dep/cmd/dep; \
fi fi
govendor list +unused | tee "$(TMPDIR)/wc-gitea-unused" dep ensure -vendor-only
[ $$(cat "$(TMPDIR)/wc-gitea-unused" | wc -l) -eq 0 ] || echo "Warning: /!\\ Some vendor are not used /!\\"
govendor list +outside | tee "$(TMPDIR)/wc-gitea-outside" .PHONY: test-vendor
[ $$(cat "$(TMPDIR)/wc-gitea-outside" | wc -l) -eq 0 ] || exit 1 test-vendor: vendor
@diff=$$(git diff vendor/); \
govendor status || exit 1 if [ -n "$$diff" ]; then \
echo "Please run 'make vendor' and commit the result:"; \
echo "$${diff}"; \
exit 1; \
fi;
#TODO add dep status -missing when implemented
.PHONY: test-sqlite .PHONY: test-sqlite
test-sqlite: integrations.sqlite.test test-sqlite: integrations.sqlite.test
@ -230,7 +241,7 @@ $(EXECUTABLE): $(SOURCES)
$(GO) build $(GOFLAGS) $(EXTRA_GOFLAGS) -tags '$(TAGS)' -ldflags '-s -w $(LDFLAGS)' -o $@ $(GO) build $(GOFLAGS) $(EXTRA_GOFLAGS) -tags '$(TAGS)' -ldflags '-s -w $(LDFLAGS)' -o $@
.PHONY: release .PHONY: release
release: release-dirs release-windows release-linux release-darwin release-copy release-check release: release-dirs release-windows release-linux release-darwin release-copy release-compress release-check
.PHONY: release-dirs .PHONY: release-dirs
release-dirs: release-dirs:
@ -274,6 +285,13 @@ release-copy:
release-check: release-check:
cd $(DIST)/release; $(foreach file,$(wildcard $(DIST)/release/$(EXECUTABLE)-*),sha256sum $(notdir $(file)) > $(notdir $(file)).sha256;) cd $(DIST)/release; $(foreach file,$(wildcard $(DIST)/release/$(EXECUTABLE)-*),sha256sum $(notdir $(file)) > $(notdir $(file)).sha256;)
.PHONY: release-compress
release-compress:
@hash gxz > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
$(GO) get -u github.com/ulikunitz/xz/cmd/gxz; \
fi
cd $(DIST)/release; $(foreach file,$(wildcard $(DIST)/binaries/$(EXECUTABLE)-*),gxz -k -9 $(notdir $(file));)
.PHONY: javascripts .PHONY: javascripts
javascripts: public/js/index.js javascripts: public/js/index.js

View File

@ -91,6 +91,12 @@ Support this project by becoming a sponsor. Your logo will show up here with a l
<a href="https://opencollective.com/gitea/sponsor/8/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/8/avatar.svg"></a> <a href="https://opencollective.com/gitea/sponsor/8/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/8/avatar.svg"></a>
<a href="https://opencollective.com/gitea/sponsor/9/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/9/avatar.svg"></a> <a href="https://opencollective.com/gitea/sponsor/9/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/9/avatar.svg"></a>
## FAQ
**How do you pronounce Gitea?**
Gitea is pronounced [/ɡɪti:/](https://youtu.be/EM71-2uDAoY) as in "gi-tea" with a hard g.
## License ## License
This project is licensed under the MIT License. This project is licensed under the MIT License.

View File

@ -268,7 +268,7 @@ func runServ(c *cli.Context) error {
claims := jwt.MapClaims{ claims := jwt.MapClaims{
"repo": repo.ID, "repo": repo.ID,
"op": lfsVerb, "op": lfsVerb,
"exp": now.Add(5 * time.Minute).Unix(), "exp": now.Add(setting.LFS.HTTPAuthExpiry).Unix(),
"nbf": now.Unix(), "nbf": now.Unix(),
} }
if user != nil { if user != nil {

View File

@ -24,8 +24,8 @@
# Default values # Default values
NAME=gitea NAME=gitea
GITEA_HOME=/home/git/gitea GITEA_HOME=/var/lib/${NAME}
GITEA_PATH=${GITEA_HOME}/$NAME GITEA_PATH=/usr/local/bin/${NAME}
GITEA_USER=git GITEA_USER=git
SERVICENAME="Gitea - Git with a cup of tea" SERVICENAME="Gitea - Git with a cup of tea"
LOCKFILE=/var/lock/subsys/gitea LOCKFILE=/var/lock/subsys/gitea
@ -49,11 +49,11 @@ DAEMON_OPTS="--check $NAME"
start() { start() {
cd ${GITEA_HOME} cd ${GITEA_HOME}
echo -n "Starting ${SERVICENAME}: " echo -n "Starting ${SERVICENAME}: "
daemon $DAEMON_OPTS "${GITEA_PATH} web > ${LOGFILE} 2>&1 &" daemon $DAEMON_OPTS "${GITEA_PATH} web -c /etc/${NAME}/app.ini > ${LOGFILE} 2>&1 &"
RETVAL=$? RETVAL=$?
echo echo
[ $RETVAL = 0 ] && touch ${LOCKFILE} [ $RETVAL = 0 ] && touch ${LOCKFILE}
return $RETVAL return $RETVAL
} }
@ -63,7 +63,7 @@ stop() {
killproc ${NAME} killproc ${NAME}
RETVAL=$? RETVAL=$?
echo echo
[ $RETVAL = 0 ] && rm -f ${LOCKFILE} [ $RETVAL = 0 ] && rm -f ${LOCKFILE}
} }
case "$1" in case "$1" in

View File

@ -14,17 +14,20 @@
# Do NOT "set -e" # Do NOT "set -e"
# PATH should only include /usr/* if it runs after the mountnfs.sh script # PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin
DESC="Git with a cup of tea" DESC="Gitea - Git with a cup of tea"
NAME=gitea NAME=gitea
SERVICEVERBOSE=yes SERVICEVERBOSE=yes
PIDFILE=/var/run/$NAME.pid PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME SCRIPTNAME=/etc/init.d/$NAME
WORKINGDIR=/home/git/gitea WORKINGDIR=/var/lib/$NAME
DAEMON=$WORKINGDIR/$NAME DAEMON=/usr/local/bin/$NAME
DAEMON_ARGS="web" DAEMON_ARGS="web -c /etc/$NAME/app.ini"
USER=git USER=git
USERBIND="setcap cap_net_bind_service=+ep" USERBIND=""
# If you want to bind Gitea to a port below 1024 uncomment
# the line below
#USERBIND="setcap cap_net_bind_service=+ep"
STOP_SCHEDULE="${STOP_SCHEDULE:-QUIT/5/TERM/1/KILL/5}" STOP_SCHEDULE="${STOP_SCHEDULE:-QUIT/5/TERM/1/KILL/5}"
# Read configuration variable file if it is present # Read configuration variable file if it is present
@ -36,7 +39,7 @@ STOP_SCHEDULE="${STOP_SCHEDULE:-QUIT/5/TERM/1/KILL/5}"
do_start() do_start()
{ {
$USERBIND $DAEMON $USERBIND $DAEMON
sh -c "USER=$USER start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile \\ sh -c "USER=$USER HOME=/home/$USER GITEA_WORK_DIR=$WORKINGDIR start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile \\
--background --chdir $WORKINGDIR --chuid $USER \\ --background --chdir $WORKINGDIR --chuid $USER \\
--exec $DAEMON -- $DAEMON_ARGS" --exec $DAEMON -- $DAEMON_ARGS"
} }

View File

@ -19,9 +19,9 @@ load_rc_config $name
: ${gitea_user:="git"} : ${gitea_user:="git"}
: ${gitea_enable:="NO"} : ${gitea_enable:="NO"}
: ${gitea_directory:="/home/git"} : ${gitea_directory:="/var/lib/gitea"}
command="${gitea_directory}/gitea web" command="/usr/local/bin/gitea web -c /etc/gitea/app.ini"
procname="$(echo $command |cut -d' ' -f1)" procname="$(echo $command |cut -d' ' -f1)"
pidfile="${gitea_directory}/${name}.pid" pidfile="${gitea_directory}/${name}.pid"
@ -33,6 +33,7 @@ gitea_start() {
cd ${gitea_directory} cd ${gitea_directory}
export USER=${gitea_user} export USER=${gitea_user}
export HOME=/usr/home/${gitea_user} export HOME=/usr/home/${gitea_user}
export GITEA_WORK_DIR=${gitea_directory}
/usr/sbin/daemon -f -u ${gitea_user} -p ${pidfile} $command /usr/sbin/daemon -f -u ${gitea_user} -p ${pidfile} $command
} }

View File

@ -1,11 +1,11 @@
#!/sbin/openrc-run #!/sbin/openrc-run
DIR=/home/git/gitea DIR=/var/lib/gitea
USER=git USER=git
start_stop_daemon_args="--user ${USER} --chdir ${DIR}" start_stop_daemon_args="--user ${USER} --chdir ${DIR}"
command="${DIR}/gitea" command="/usr/local/bin/gitea"
command_args="web" command_args="web -c /etc/gitea/app.ini"
command_background=yes command_background=yes
pidfile=/var/run/gitea.pid pidfile=/var/run/gitea.pid

View File

@ -2,11 +2,11 @@
# #
# $OpenBSD$ # $OpenBSD$
daemon="/home/git/gitea/gitea" daemon="/usr/local/bin/gitea"
daemon_user="git" daemon_user="git"
daemon_flags="web" daemon_flags="web -c /etc/gitea/app.ini"
gitea_directory="/home/git/gitea" gitea_directory="/var/lib/gitea"
rc_bg=YES rc_bg=YES

View File

@ -18,10 +18,10 @@
# Default values # Default values
NAME=gitea NAME=gitea
GITEA_HOME=/home/git/gitea GITEA_HOME=/var/lib/$NAME
GITEA_PATH=${GITEA_HOME}/$NAME GITEA_PATH=/usr/local/bin/$NAME
GITEA_USER=git GITEA_USER=git
SERVICENAME="Git - with a cup of tea" SERVICENAME="Gitea - Git with a cup of tea"
LOCKFILE=/var/lock/subsys/gitea LOCKFILE=/var/lock/subsys/gitea
LOGPATH=${GITEA_HOME}/log LOGPATH=${GITEA_HOME}/log
LOGFILE=${LOGPATH}/error.log LOGFILE=${LOGPATH}/error.log
@ -58,7 +58,7 @@ case "$1" in
# return skipped as service is already running # return skipped as service is already running
(exit 5) (exit 5)
else else
su - ${GITEA_USER} -c "USER=${GITEA_USER} ${GITEA_PATH} web 2>&1 >>${LOGFILE} &" su - ${GITEA_USER} -c "USER=${GITEA_USER} GITEA_WORK_DIR=${GITEA_HOME} ${GITEA_PATH} web -c /etc/${NAME}/app.ini 2>&1 >>${LOGFILE} &"
fi fi
# Remember status and be verbose # Remember status and be verbose

View File

@ -18,10 +18,10 @@ RestartSec=2s
Type=simple Type=simple
User=git User=git
Group=git Group=git
WorkingDirectory=/home/git/gitea WorkingDirectory=/var/lib/gitea/
ExecStart=/home/git/gitea/gitea web ExecStart=/usr/local/bin/gitea web -c /etc/gitea/app.ini
Restart=always Restart=always
Environment=USER=git HOME=/home/git Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/gitea
# If you want to bind Gitea to a port below 1024 uncomment # If you want to bind Gitea to a port below 1024 uncomment
# the two values below # the two values below
### ###

View File

@ -124,6 +124,7 @@ UNIX_SOCKET_PERMISSION = 666
; Local (DMZ) URL for Gitea workers (such as SSH update) accessing web service. ; Local (DMZ) URL for Gitea workers (such as SSH update) accessing web service.
; In most cases you do not need to change the default value. ; In most cases you do not need to change the default value.
; Alter it only if your SSH server node is not the same as HTTP node. ; Alter it only if your SSH server node is not the same as HTTP node.
; Do not set this variable if PROTOCOL is set to 'unix'.
LOCAL_ROOT_URL = %(PROTOCOL)s://%(HTTP_ADDR)s:%(HTTP_PORT)s/ LOCAL_ROOT_URL = %(PROTOCOL)s://%(HTTP_ADDR)s:%(HTTP_PORT)s/
; Disable SSH feature when not available ; Disable SSH feature when not available
DISABLE_SSH = false DISABLE_SSH = false
@ -188,6 +189,8 @@ LFS_START_SERVER = false
LFS_CONTENT_PATH = data/lfs LFS_CONTENT_PATH = data/lfs
; LFS authentication secret, change this yourself ; LFS authentication secret, change this yourself
LFS_JWT_SECRET = LFS_JWT_SECRET =
; LFS authentication validity period (in time.Duration), pushes taking longer than this may fail.
LFS_HTTP_AUTH_EXPIRY = 20m
; Define allowed algorithms and their minimum key length (use -1 to disable a type) ; Define allowed algorithms and their minimum key length (use -1 to disable a type)
[ssh.minimum_key_sizes] [ssh.minimum_key_sizes]
@ -411,7 +414,7 @@ ENABLE_FEDERATED_AVATAR = false
[attachment] [attachment]
; Whether attachments are enabled. Defaults to `true` ; Whether attachments are enabled. Defaults to `true`
ENABLE = true ENABLED = true
; Path for attachments. Defaults to `data/attachments` ; Path for attachments. Defaults to `data/attachments`
PATH = data/attachments PATH = data/attachments
; One or more allowed types, e.g. image/jpeg|image/png ; One or more allowed types, e.g. image/jpeg|image/png
@ -567,28 +570,21 @@ ENABLE_SWAGGER_ENDPOINT = true
MAX_RESPONSE_ITEMS = 50 MAX_RESPONSE_ITEMS = 50
[i18n] [i18n]
LANGS = en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,ja-JP,es-ES,pt-BR,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sr-SP,sv-SE,ko-KR LANGS = en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,uk-UA,ja-JP,es-ES,pt-BR,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sr-SP,sv-SE,ko-KR
NAMES = English,简体中文,繁體中文(香港),繁體中文(台灣),Deutsch,français,Nederlands,latviešu,русский,日本語,español,português do Brasil,polski,български,italiano,suomi,Türkçe,čeština,српски,svenska,한국어 NAMES = English,简体中文,繁體中文(香港),繁體中文(台灣),Deutsch,français,Nederlands,latviešu,русский,Українська,日本語,español,português do Brasil,polski,български,italiano,suomi,Türkçe,čeština,српски,svenska,한국어
[U2F]
; Two Factor authentication with security keys
; https://developers.yubico.com/U2F/App_ID.html
APP_ID = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s
; Comma seperated list of truisted facets
TRUSTED_FACETS = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s
; Used for datetimepicker ; Used for datetimepicker
[i18n.datelang] [i18n.datelang]
en-US = en en-US = en
zh-CN = zh zh-CN = zh
zh-HK = zh-TW zh-HK = zh-HK
zh-TW = zh-TW zh-TW = zh-TW
de-DE = de de-DE = de
fr-FR = fr fr-FR = fr
nl-NL = nl nl-NL = nl
lv-LV = lv lv-LV = lv
ru-RU = ru ru-RU = ru
uk-UA = uk
ja-JP = ja ja-JP = ja
es-ES = es es-ES = es
pt-BR = pt-BR pt-BR = pt-BR
@ -602,6 +598,13 @@ sr-SP = sr
sv-SE = sv sv-SE = sv
ko-KR = ko ko-KR = ko
[U2F]
; Two Factor authentication with security keys
; https://developers.yubico.com/U2F/App_ID.html
APP_ID = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s
; Comma seperated list of truisted facets
TRUSTED_FACETS = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s
; Extension mapping to highlight class ; Extension mapping to highlight class
; e.g. .toml=ini ; e.g. .toml=ini
[highlight.mapping] [highlight.mapping]

View File

@ -35,6 +35,8 @@ if [ ! -f /data/gitea/conf/app.ini ]; then
DB_USER=${DB_USER:-"root"} \ DB_USER=${DB_USER:-"root"} \
DB_PASSWD=${DB_PASSWD:-""} \ DB_PASSWD=${DB_PASSWD:-""} \
INSTALL_LOCK=${INSTALL_LOCK:-"false"} \ INSTALL_LOCK=${INSTALL_LOCK:-"false"} \
DISABLE_REGISTRATION=${DISABLE_REGISTRATION:-"false"} \
REQUIRE_SIGNIN_VIEW=${REQUIRE_SIGNIN_VIEW:-"false"} \
SECRET_KEY=${SECRET_KEY:-""} \ SECRET_KEY=${SECRET_KEY:-""} \
envsubst < /etc/templates/app.ini > /data/gitea/conf/app.ini envsubst < /etc/templates/app.ini > /data/gitea/conf/app.ini
fi fi

View File

@ -38,3 +38,7 @@ ROOT_PATH = /data/gitea/log
[security] [security]
INSTALL_LOCK = $INSTALL_LOCK INSTALL_LOCK = $INSTALL_LOCK
SECRET_KEY = $SECRET_KEY SECRET_KEY = $SECRET_KEY
[service]
DISABLE_REGISTRATION = $DISABLE_REGISTRATION
REQUIRE_SIGNIN_VIEW = $REQUIRE_SIGNIN_VIEW

View File

@ -95,6 +95,11 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
- If `PROTOCOL` is set to `fcgi`, Gitea will listen for FastCGI requests on TCP socket - If `PROTOCOL` is set to `fcgi`, Gitea will listen for FastCGI requests on TCP socket
defined by `HTTP_ADDR` and `HTTP_PORT` configuration settings. defined by `HTTP_ADDR` and `HTTP_PORT` configuration settings.
- `UNIX_SOCKET_PERMISSION`: **666**: Permissions for the Unix socket. - `UNIX_SOCKET_PERMISSION`: **666**: Permissions for the Unix socket.
- `LOCAL_ROOT_URL`: **%(PROTOCOL)s://%(HTTP_ADDR)s:%(HTTP_PORT)s/**: Local
(DMZ) URL for Gitea workers (such as SSH update) accessing web service. In
most cases you do not need to change the default value. Alter it only if
your SSH server node is not the same as HTTP node. Do not set this variable
if `PROTOCOL` is set to `unix`.
- `DISABLE_SSH`: **false**: Disable SSH feature when it's not available. - `DISABLE_SSH`: **false**: Disable SSH feature when it's not available.
- `START_SSH_SERVER`: **false**: When enabled, use the built-in SSH server. - `START_SSH_SERVER`: **false**: When enabled, use the built-in SSH server.
- `SSH_DOMAIN`: **%(DOMAIN)s**: Domain name of this server, used for displayed clone URL. - `SSH_DOMAIN`: **%(DOMAIN)s**: Domain name of this server, used for displayed clone URL.
@ -110,6 +115,7 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
- `LFS_START_SERVER`: **false**: Enables git-lfs support. - `LFS_START_SERVER`: **false**: Enables git-lfs support.
- `LFS_CONTENT_PATH`: **./data/lfs**: Where to store LFS files. - `LFS_CONTENT_PATH`: **./data/lfs**: Where to store LFS files.
- `LFS_JWT_SECRET`: **\<empty\>**: LFS authentication secret, change this a unique string. - `LFS_JWT_SECRET`: **\<empty\>**: LFS authentication secret, change this a unique string.
- `LFS_HTTP_AUTH_EXPIRY`: **20m**: LFS authentication validity period in time.Duration, pushes taking longer than this may fail.
- `REDIRECT_OTHER_PORT`: **false**: If true and `PROTOCOL` is https, redirects http requests - `REDIRECT_OTHER_PORT`: **false**: If true and `PROTOCOL` is https, redirects http requests
on another (https) port. on another (https) port.
- `PORT_TO_REDIRECT`: **80**: Port used when `REDIRECT_OTHER_PORT` is true. - `PORT_TO_REDIRECT`: **80**: Port used when `REDIRECT_OTHER_PORT` is true.
@ -145,6 +151,7 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
authentication. authentication.
- `DISABLE_GIT_HOOKS`: **false**: Prevent all users (including admin) from creating custom - `DISABLE_GIT_HOOKS`: **false**: Prevent all users (including admin) from creating custom
git hooks. git hooks.
- `IMPORT_LOCAL_PATHS`: **false**: Prevent all users (including admin) from importing local path on server.
## OpenID (`openid`) ## OpenID (`openid`)
@ -272,6 +279,41 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
- `MAX_GIT_DIFF_FILES`: **100**: Max number of files shown in diff view. - `MAX_GIT_DIFF_FILES`: **100**: Max number of files shown in diff view.
- `GC_ARGS`: **\<empty\>**: Arguments for command `git gc`, e.g. `--aggressive --auto`. - `GC_ARGS`: **\<empty\>**: Arguments for command `git gc`, e.g. `--aggressive --auto`.
## API (`api`)
- `ENABLE_SWAGGER_ENDPOINT`: **true**: Enables /api/swagger, /api/v1/swagger etc. endpoints. True or false; default is true.
- `MAX_RESPONSE_ITEMS`: **50**: Max number of items in a page
## i18n (`i18n`)
- `LANGS`: **en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,ja-JP,es-ES,pt-BR,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sr-SP,sv-SE,ko-KR**: List of locales shown in language selector
- `NAMES`: **English,简体中文,繁體中文(香港),繁體中文(台灣),Deutsch,français,Nederlands,latviešu,русский,日本語,español,português do Brasil,polski,български,italiano,suomi,Türkçe,čeština,српски,svenska,한국어**: Visible names corresponding to the locales
### i18n - Datepicker Language (`i18n.datelang`)
Maps locales to the languages used by the datepicker plugin
- `en-US`: **en**
- `zh-CN`: **zh**
- `zh-HK`: **zh-HK**
- `zh-TW`: **zh-TW**
- `de-DE`: **de**
- `fr-FR`: **fr**
- `nl-NL`: **nl**
- `lv-LV`: **lv**
- `ru-RU`: **ru**
- `ja-JP`: **ja**
- `es-ES`: **es**
- `pt-BR`: **pt-BR**
- `pl-PL`: **pl**
- `bg-BG`: **bg**
- `it-IT`: **it**
- `fi-FI`: **fi**
- `tr-TR`: **tr**
- `cs-CZ`: **cs-CZ**
- `sr-SP`: **sr**
- `sv-SE`: **sv**
- `ko-KR`: **ko**
## U2F (`U2F`) ## U2F (`U2F`)
- `APP_ID`: **`ROOT_URL`**: Declares the facet of the application. Requires HTTPS. - `APP_ID`: **`ROOT_URL`**: Declares the facet of the application. Requires HTTPS.
- `TRUSTED_FACETS`: List of additional facets which are trusted. This is not support by all browsers. - `TRUSTED_FACETS`: List of additional facets which are trusted. This is not support by all browsers.

View File

@ -37,6 +37,7 @@ _Symbols used in table:_
<td>GitLab CE</td> <td>GitLab CE</td>
<td>GitLab EE</td> <td>GitLab EE</td>
<td>BitBucket</td> <td>BitBucket</td>
<td>RhodeCode CE</td>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -48,6 +49,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Issue tracker</td> <td>Issue tracker</td>
@ -57,6 +59,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Pull/Merge requests</td> <td>Pull/Merge requests</td>
@ -66,6 +69,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Squash merging</td> <td>Squash merging</td>
@ -75,6 +79,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Rebase merging</td> <td>Rebase merging</td>
@ -84,6 +89,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Pull/Merge request inline comments</td> <td>Pull/Merge request inline comments</td>
@ -93,6 +99,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Pull/Merge request approval</td> <td>Pull/Merge request approval</td>
@ -102,6 +109,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Merge conflict resolution</td> <td>Merge conflict resolution</td>
@ -111,6 +119,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Restrict push and merge access to certain users</td> <td>Restrict push and merge access to certain users</td>
@ -120,6 +129,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Markdown support</td> <td>Markdown support</td>
@ -129,6 +139,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Issues and pull/merge requests templates</td> <td>Issues and pull/merge requests templates</td>
@ -138,6 +149,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Revert specific commits or a merge request</td> <td>Revert specific commits or a merge request</td>
@ -147,6 +159,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Labels</td> <td>Labels</td>
@ -156,6 +169,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Time tracking</td> <td>Time tracking</td>
@ -165,6 +179,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Multiple assignees for issues</td> <td>Multiple assignees for issues</td>
@ -174,6 +189,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Related issues</td> <td>Related issues</td>
@ -183,6 +199,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Confidential issues</td> <td>Confidential issues</td>
@ -192,6 +209,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Comment reactions</td> <td>Comment reactions</td>
@ -201,6 +219,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Lock Discussion</td> <td>Lock Discussion</td>
@ -210,6 +229,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Batch issue handling</td> <td>Batch issue handling</td>
@ -219,6 +239,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Issue Boards</td> <td>Issue Boards</td>
@ -228,6 +249,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Create new branches from issues</td> <td>Create new branches from issues</td>
@ -237,6 +259,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Commit graph</td> <td>Commit graph</td>
@ -246,6 +269,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Web code editor</td> <td>Web code editor</td>
@ -255,6 +279,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Branch manager</td> <td>Branch manager</td>
@ -264,6 +289,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Create new branches</td> <td>Create new branches</td>
@ -273,6 +299,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Repository topics</td> <td>Repository topics</td>
@ -282,6 +309,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Repository code search</td> <td>Repository code search</td>
@ -291,6 +319,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Global code search</td> <td>Global code search</td>
@ -300,6 +329,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Issue search</td> <td>Issue search</td>
@ -309,6 +339,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Global issue search</td> <td>Global issue search</td>
@ -318,6 +349,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Git LFS 2.0</td> <td>Git LFS 2.0</td>
@ -327,6 +359,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Integrated Git-powered wiki</td> <td>Integrated Git-powered wiki</td>
@ -336,6 +369,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Static Git-powered pages</td> <td>Static Git-powered pages</td>
@ -345,6 +379,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Group Milestones</td> <td>Group Milestones</td>
@ -354,6 +389,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Granular user roles (Code, Issues, Wiki etc)</td> <td>Granular user roles (Code, Issues, Wiki etc)</td>
@ -363,6 +399,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Cherry-picking changes</td> <td>Cherry-picking changes</td>
@ -372,6 +409,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>GPG Signed Commits</td> <td>GPG Signed Commits</td>
@ -381,6 +419,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Reject unsigned commits</td> <td>Reject unsigned commits</td>
@ -390,6 +429,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Verified Committer</td> <td>Verified Committer</td>
@ -399,6 +439,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Subgroups: groups within groups</td> <td>Subgroups: groups within groups</td>
@ -408,6 +449,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Custom Git Hooks</td> <td>Custom Git Hooks</td>
@ -417,6 +459,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Repository Activity page</td> <td>Repository Activity page</td>
@ -426,6 +469,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Deploy Tokens</td> <td>Deploy Tokens</td>
@ -435,6 +479,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Repository Tokens with write rights</td> <td>Repository Tokens with write rights</td>
@ -444,6 +489,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Easy upgrade process</td> <td>Easy upgrade process</td>
@ -453,6 +499,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Built-in Container Registry</td> <td>Built-in Container Registry</td>
@ -462,6 +509,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>External git mirroring</td> <td>External git mirroring</td>
@ -471,6 +519,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>AD / LDAP integration</td> <td>AD / LDAP integration</td>
@ -480,6 +529,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Multiple LDAP / AD server support</td> <td>Multiple LDAP / AD server support</td>
@ -489,6 +539,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>LDAP user synchronization</td> <td>LDAP user synchronization</td>
@ -498,6 +549,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>OpenId Connect support</td> <td>OpenId Connect support</td>
@ -507,6 +559,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td>?</td> <td>?</td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>OAuth 2.0 integration (external authorization)</td> <td>OAuth 2.0 integration (external authorization)</td>
@ -516,6 +569,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td>?</td> <td>?</td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Act as OAuth 2.0 provider</td> <td>Act as OAuth 2.0 provider</td>
@ -525,6 +579,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Two factor authentication (2FA)</td> <td>Two factor authentication (2FA)</td>
@ -534,6 +589,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>FIDO U2F (2FA)</td> <td>FIDO U2F (2FA)</td>
@ -543,6 +599,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Webhook support</td> <td>Webhook support</td>
@ -552,6 +609,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Mattermost/Slack integration</td> <td>Mattermost/Slack integration</td>
@ -561,6 +619,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Discord integration</td> <td>Discord integration</td>
@ -570,6 +629,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Built-in CI/CD</td> <td>Built-in CI/CD</td>
@ -579,6 +639,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>External CI/CD status display</td> <td>External CI/CD status display</td>
@ -588,6 +649,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Multiple database support</td> <td>Multiple database support</td>
@ -597,6 +659,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Multiple OS support</td> <td>Multiple OS support</td>
@ -606,6 +669,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr> <tr>
<td>Low resource usage (RAM/CPU)</td> <td>Low resource usage (RAM/CPU)</td>
@ -615,6 +679,7 @@ _Symbols used in table:_
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>

View File

@ -1,5 +1,5 @@
--- ---
date: "2017-01-20T15:00:00+08:00" date: "2018-05-21T15:00:00+00:00"
title: "Support Options" title: "Support Options"
slug: "seek-help" slug: "seek-help"
weight: 10 weight: 10
@ -16,8 +16,7 @@ menu:
# Support Options # Support Options
- [Discord](https://discord.gg/NsatcWJ) - [Discord](https://discord.gg/NsatcWJ)
- [#gitea on Freenode](http://webchat.freenode.net?nick=giteachat....&channels=%23gitea&prompt=1) - [Discourse Forum](https://discourse.gitea.io/)
- [Matrix](https://matrix.to/#/#gitea-dev:matrix.org)
## Bugs ## Bugs

View File

@ -20,8 +20,8 @@ embedded assets. This can be different for older releases. Choose the file match
the destination platform from the [downloads page](https://dl.gitea.io/gitea), copy the destination platform from the [downloads page](https://dl.gitea.io/gitea), copy
the URL and replace the URL within the commands below: the URL and replace the URL within the commands below:
``` ```sh
wget -O gitea https://dl.gitea.io/gitea/1.3.2/gitea-1.3.2-linux-amd64 wget -O gitea https://dl.gitea.io/gitea/1.4.2/gitea-1.4.2-linux-amd64
chmod +x gitea chmod +x gitea
``` ```
@ -34,6 +34,54 @@ location. When launched manually, Gitea can be killed using `Ctrl+C`.
./gitea web ./gitea web
``` ```
## Recommended server configuration
### Prepare environment
Check that git is installed on the server, if it is not install it first.
```sh
git --version
```
Create user to run gitea (ex. `git`)
```sh
adduser \
--system \
--shell /bin/bash \
--gecos 'Git Version Control' \
--group \
--disabled-password \
--home /home/git \
git
```
### Create required directory structure
```sh
mkdir -p /var/lib/gitea/{custom,data,indexers,public,log}
chown git:git /var/lib/gitea/{data,indexers,log}
chmod 750 /var/lib/gitea/{data,indexers,log}
mkdir /etc/gitea
chown root:git /etc/gitea
chmod 770 /etc/gitea
```
**NOTE:** `/etc/gitea` is temporary set with write rights for user `git` so that Web installer could write configuration file. After installation is done it is recommended to set rights to read-only using:
```
chmod 750 /etc/gitea
chmod 644 /etc/gitea/app.ini
```
### Copy gitea binary to global location
```
cp gitea /usr/local/bin/gitea
```
### Create service file to start gitea automatically
See how to create [Linux service]({{< relref "run-as-service-in-ubuntu.en-us.md" >}})
## Troubleshooting ## Troubleshooting
### Old glibc versions ### Old glibc versions

View File

@ -17,16 +17,13 @@ menu:
## Debian ## Debian
The only distribution that has any "official" package of Gitea is Debian. This is currently Although there is a package of Gitea in Debian's [contrib](https://wiki.debian.org/SourcesList),
in Debian's [contrib](https://wiki.debian.org/SourcesList). This is (currently) only available it is not supported directly by us.
in Debian testing and unstable (but should be installable/functional on stable).
- Edit /etc/apt/sourced.list Unfortunately the package is not maintained anymore and broken because of missing sources.
- Add "contrib" to "deb http://deb.debian.org/debian unstable main contrib" Please follow the [deployment from binary]({{< relref "from-binary.en-us.md" >}}) guide instead.
- apt-get update
- apt-get install gitea
For other distributions, see the [deployment from binary]({{< relref "from-binary.en-us.md" >}}) guide. Should the packages get updated and fixed, we will provide up-to-date installation instructions here.
## Windows ## Windows

View File

@ -231,7 +231,7 @@ You can configure some of Gitea's settings via environment variables:
* `APP_NAME`: **"Gitea: Git with a cup of tea"**: Application name, used in the page title. * `APP_NAME`: **"Gitea: Git with a cup of tea"**: Application name, used in the page title.
* `RUN_MODE`: **dev**: For performance and other purposes, change this to `prod` when deployed to a production environment. * `RUN_MODE`: **dev**: For performance and other purposes, change this to `prod` when deployed to a production environment.
* `SSH_DOMAIN`: **localhost**: Domain name of this server, used for displayed clone UR in Gitea's UI. * `SSH_DOMAIN`: **localhost**: Domain name of this server, used for the displayed clone URL in Gitea's UI.
* `SSH_PORT`: **22**: SSH port displayed in clone URL. * `SSH_PORT`: **22**: SSH port displayed in clone URL.
* `DISABLE_SSH`: **false**: Disable SSH feature when it's not available. * `DISABLE_SSH`: **false**: Disable SSH feature when it's not available.
* `HTTP_PORT`: **3000**: HTTP listen port. * `HTTP_PORT`: **3000**: HTTP listen port.
@ -243,6 +243,8 @@ You can configure some of Gitea's settings via environment variables:
* `DB_PASSWD`: **"<empty>"**: Database user password. Use \`your password\` for quoting if you use special characters in the password. * `DB_PASSWD`: **"<empty>"**: Database user password. Use \`your password\` for quoting if you use special characters in the password.
* `INSTALL_LOCK`: **false**: Disallow access to the install page. * `INSTALL_LOCK`: **false**: Disallow access to the install page.
* `SECRET_KEY`: **""**: Global secret key. This should be changed. If this has a value and `INSTALL_LOCK` is empty, `INSTALL_LOCK` will automatically set to `true`. * `SECRET_KEY`: **""**: Global secret key. This should be changed. If this has a value and `INSTALL_LOCK` is empty, `INSTALL_LOCK` will automatically set to `true`.
* `DISABLE_REGISTRATION`: **false**: Disable registration, after which only admin can create accounts for users.
* `REQUIRE_SIGNIN_VIEW`: **false**: Enable this to force users to log in to view any page.
# Customization # Customization

View File

@ -0,0 +1,46 @@
---
date: "2018-06-02T11:00:00+02:00"
title: "Usage: HTTPS setup"
slug: "https-setup"
weight: 12
toc: true
draft: false
menu:
sidebar:
parent: "usage"
name: "HTTPS setup"
weight: 12
identifier: "https-setup"
---
# HTTPS setup to encrypt connections to Gitea
## Using built-in server
Before you enable HTTPS make sure that you have valid SSL/TLS certificates.
You could use self-generated certificates for evaluation and testing. Please run `gitea cert --host [HOST]` to generate a self signed certificate.
To use Gitea's built-in HTTPS support you must change your `app.ini` file:
```ini
[server]
PROTOCOL=https
ROOT_URL = `https://git.example.com:3000/`
HTTP_PORT = 3000
CERT_FILE = cert.pem
KEY_FILE = key.pem
```
To learn more about the config values, please checkout the [Config Cheat Sheet](../config-cheat-sheet#server).
## Using reverse proxy
Setup up your reverse proxy like shown in the [reverse proxy guide](../reverse-proxies).
After that, enable HTTPS by following one of these guides:
* [nginx](https://nginx.org/en/docs/http/configuring_https_servers.html)
* [apache2/httpd](https://httpd.apache.org/docs/2.4/ssl/ssl_howto.html)
* [caddy](https://caddyserver.com/docs/tls)
Note: You connection between your reverse proxy and gitea might be unencrypted. To encrypt it too follow the [built-in server guide](#using-built-in-server) and change
the proxy url to `https://[URL]`.

View File

@ -0,0 +1,104 @@
---
date: "2018-05-22T11:00:00+00:00"
title: "Usage: Reverse Proxies"
slug: "reverse-proxies"
weight: 17
toc: true
draft: false
menu:
sidebar:
parent: "usage"
name: "Reverse Proxies"
weight: 16
identifier: "reverse-proxies"
---
## Using Nginx as a reverse proxy
If you want Nginx to serve your Gitea instance you can the following `server` section inside the `http` section of `nginx.conf`:
```
server {
listen 80;
server_name git.example.com;
location / {
proxy_pass http://localhost:3000;
}
}
```
## Using Nginx with a Sub-path as a reverse proxy
In case you already have a site, and you want Gitea to share the domain name, you can setup Nginx to serve Gitea under a sub-path by adding the following `server` section inside the `http` section of `nginx.conf`:
```
server {
listen 80;
server_name git.example.com;
location /git/ { # Note: Trailing slash
proxy_pass http://localhost:3000/; # Note: Trailing slash
}
}
```
Then set `[server] ROOT_URL = http://git.example.com/git/` in your configuration.
## Using Apache HTTPD as a reverse proxy
If you want Apache HTTPD to serve your Gitea instance you can add the following to you Apache HTTPD configuration (usually located at `/etc/apache2/httpd.conf` in Ubuntu):
```
<VirtualHost *:80>
...
ProxyPreserveHost On
ProxyRequests off
ProxyPass / http://localhost:3000/
ProxyPassReverse / http://localhost:3000/
</VirtualHost>
```
Note: The following Apache HTTPD mods must be enabled: `proxy`, `proxy_http`
## Using Apache HTTPD with a Sub-path as a reverse proxy
In case you already have a site, and you want Gitea to share the domain name, you can setup Apache HTTPD to serve Gitea under a sub-path by adding the following to you Apache HTTPD configuration (usually located at `/etc/apache2/httpd.conf` in Ubuntu):
```
<VirtualHost *:80>
...
<Proxy *>
Order allow,deny
Allow from all
</Proxy>
ProxyPass /git http://localhost:3000 # Note: no trailing slash after either /git or port
ProxyPassReverse /git http://localhost:3000 # Note: no trailing slash after either /git or port
</VirtualHost>
```
Then set `[server] ROOT_URL = http://git.example.com/git/` in your configuration.
Note: The following Apache HTTPD mods must be enabled: `proxy`, `proxy_http`
## Using Caddy with a Sub-path as a reverse proxy
If you want Caddy to serve your Gitea instance you can add the following server block to your Caddyfile:
```
git.example.com {
proxy / http://localhost:3000
}
```
## Using Caddy with a Sub-path as a reverse proxy
In case you already have a site, and you want Gitea to share the domain name, you can setup Caddy to serve Gitea under a sub-path by adding the following to you server block in your Caddyfile:
```
git.example.com {
proxy /git/ http://localhost:3000 # Note: Trailing Slash after /git/
}
```
Then set `[server] ROOT_URL = http://git.example.com/git/` in your configuration.

View File

@ -40,7 +40,11 @@ var gitLDAPUsers = []ldapUser{
Password: "hermes", Password: "hermes",
FullName: "Conrad Hermes", FullName: "Conrad Hermes",
Email: "hermes@planetexpress.com", Email: "hermes@planetexpress.com",
IsAdmin: true, SSHKeys: []string{
"SHA256:qLY06smKfHoW/92yXySpnxFR10QFrLdRjf/GNPvwcW8",
"SHA256:QlVTuM5OssDatqidn2ffY+Lc4YA5Fs78U+0KOHI51jQ",
},
IsAdmin: true,
}, },
{ {
UserName: "fry", UserName: "fry",
@ -89,26 +93,27 @@ func getLDAPServerHost() string {
return host return host
} }
func addAuthSourceLDAP(t *testing.T) { func addAuthSourceLDAP(t *testing.T, sshKeyAttribute string) {
session := loginUser(t, "user1") session := loginUser(t, "user1")
csrf := GetCSRF(t, session, "/admin/auths/new") csrf := GetCSRF(t, session, "/admin/auths/new")
req := NewRequestWithValues(t, "POST", "/admin/auths/new", map[string]string{ req := NewRequestWithValues(t, "POST", "/admin/auths/new", map[string]string{
"_csrf": csrf, "_csrf": csrf,
"type": "2", "type": "2",
"name": "ldap", "name": "ldap",
"host": getLDAPServerHost(), "host": getLDAPServerHost(),
"port": "389", "port": "389",
"bind_dn": "uid=gitea,ou=service,dc=planetexpress,dc=com", "bind_dn": "uid=gitea,ou=service,dc=planetexpress,dc=com",
"bind_password": "password", "bind_password": "password",
"user_base": "ou=people,dc=planetexpress,dc=com", "user_base": "ou=people,dc=planetexpress,dc=com",
"filter": "(&(objectClass=inetOrgPerson)(memberOf=cn=git,ou=people,dc=planetexpress,dc=com)(uid=%s))", "filter": "(&(objectClass=inetOrgPerson)(memberOf=cn=git,ou=people,dc=planetexpress,dc=com)(uid=%s))",
"admin_filter": "(memberOf=cn=admin_staff,ou=people,dc=planetexpress,dc=com)", "admin_filter": "(memberOf=cn=admin_staff,ou=people,dc=planetexpress,dc=com)",
"attribute_username": "uid", "attribute_username": "uid",
"attribute_name": "givenName", "attribute_name": "givenName",
"attribute_surname": "sn", "attribute_surname": "sn",
"attribute_mail": "mail", "attribute_mail": "mail",
"is_sync_enabled": "on", "attribute_ssh_public_key": sshKeyAttribute,
"is_active": "on", "is_sync_enabled": "on",
"is_active": "on",
}) })
session.MakeRequest(t, req, http.StatusFound) session.MakeRequest(t, req, http.StatusFound)
} }
@ -119,7 +124,7 @@ func TestLDAPUserSignin(t *testing.T) {
return return
} }
prepareTestEnv(t) prepareTestEnv(t)
addAuthSourceLDAP(t) addAuthSourceLDAP(t, "")
u := gitLDAPUsers[0] u := gitLDAPUsers[0]
@ -140,7 +145,7 @@ func TestLDAPUserSync(t *testing.T) {
return return
} }
prepareTestEnv(t) prepareTestEnv(t)
addAuthSourceLDAP(t) addAuthSourceLDAP(t, "")
models.SyncExternalUsers() models.SyncExternalUsers()
session := loginUser(t, "user1") session := loginUser(t, "user1")
@ -186,9 +191,41 @@ func TestLDAPUserSigninFailed(t *testing.T) {
return return
} }
prepareTestEnv(t) prepareTestEnv(t)
addAuthSourceLDAP(t) addAuthSourceLDAP(t, "")
u := otherLDAPUsers[0] u := otherLDAPUsers[0]
testLoginFailed(t, u.UserName, u.Password, i18n.Tr("en", "form.username_password_incorrect")) testLoginFailed(t, u.UserName, u.Password, i18n.Tr("en", "form.username_password_incorrect"))
} }
func TestLDAPUserSSHKeySync(t *testing.T) {
if skipLDAPTests() {
t.Skip()
return
}
prepareTestEnv(t)
addAuthSourceLDAP(t, "sshPublicKey")
models.SyncExternalUsers()
// Check if users has SSH keys synced
for _, u := range gitLDAPUsers {
if len(u.SSHKeys) == 0 {
continue
}
session := loginUserWithPassword(t, u.UserName, u.Password)
req := NewRequest(t, "GET", "/user/settings/keys")
resp := session.MakeRequest(t, req, http.StatusOK)
htmlDoc := NewHTMLParser(t, resp.Body)
divs := htmlDoc.doc.Find(".key.list .print.meta")
syncedKeys := make([]string, divs.Length())
for i := 0; i < divs.Length(); i++ {
syncedKeys[i] = strings.TrimSpace(divs.Eq(i).Text())
}
assert.ElementsMatch(t, u.SSHKeys, syncedKeys)
}
}

View File

@ -370,11 +370,19 @@ func (issue *Issue) HasLabel(labelID int64) bool {
func (issue *Issue) sendLabelUpdatedWebhook(doer *User) { func (issue *Issue) sendLabelUpdatedWebhook(doer *User) {
var err error var err error
if err = issue.loadRepo(x); err != nil {
log.Error(4, "loadRepo: %v", err)
return
}
if err = issue.loadPoster(x); err != nil {
log.Error(4, "loadPoster: %v", err)
return
}
mode, _ := AccessLevel(issue.Poster.ID, issue.Repo)
if issue.IsPull { if issue.IsPull {
if err = issue.loadRepo(x); err != nil {
log.Error(4, "loadRepo: %v", err)
return
}
if err = issue.loadPullRequest(x); err != nil { if err = issue.loadPullRequest(x); err != nil {
log.Error(4, "loadPullRequest: %v", err) log.Error(4, "loadPullRequest: %v", err)
return return
@ -390,6 +398,14 @@ func (issue *Issue) sendLabelUpdatedWebhook(doer *User) {
Repository: issue.Repo.APIFormat(AccessModeNone), Repository: issue.Repo.APIFormat(AccessModeNone),
Sender: doer.APIFormat(), Sender: doer.APIFormat(),
}) })
} else {
err = PrepareWebhooks(issue.Repo, HookEventIssues, &api.IssuePayload{
Action: api.HookIssueLabelUpdated,
Index: issue.Index,
Issue: issue.APIFormat(),
Repository: issue.Repo.APIFormat(mode),
Sender: doer.APIFormat(),
})
} }
if err != nil { if err != nil {
log.Error(4, "PrepareWebhooks [is_pull: %v]: %v", issue.IsPull, err) log.Error(4, "PrepareWebhooks [is_pull: %v]: %v", issue.IsPull, err)
@ -505,6 +521,11 @@ func (issue *Issue) ClearLabels(doer *User) (err error) {
return fmt.Errorf("Commit: %v", err) return fmt.Errorf("Commit: %v", err)
} }
if err = issue.loadPoster(x); err != nil {
return fmt.Errorf("loadPoster: %v", err)
}
mode, _ := AccessLevel(issue.Poster.ID, issue.Repo)
if issue.IsPull { if issue.IsPull {
err = issue.PullRequest.LoadIssue() err = issue.PullRequest.LoadIssue()
if err != nil { if err != nil {
@ -515,9 +536,17 @@ func (issue *Issue) ClearLabels(doer *User) (err error) {
Action: api.HookIssueLabelCleared, Action: api.HookIssueLabelCleared,
Index: issue.Index, Index: issue.Index,
PullRequest: issue.PullRequest.APIFormat(), PullRequest: issue.PullRequest.APIFormat(),
Repository: issue.Repo.APIFormat(AccessModeNone), Repository: issue.Repo.APIFormat(mode),
Sender: doer.APIFormat(), Sender: doer.APIFormat(),
}) })
} else {
err = PrepareWebhooks(issue.Repo, HookEventIssues, &api.IssuePayload{
Action: api.HookIssueLabelCleared,
Index: issue.Index,
Issue: issue.APIFormat(),
Repository: issue.Repo.APIFormat(mode),
Sender: doer.APIFormat(),
})
} }
if err != nil { if err != nil {
log.Error(4, "PrepareWebhooks [is_pull: %v]: %v", issue.IsPull, err) log.Error(4, "PrepareWebhooks [is_pull: %v]: %v", issue.IsPull, err)
@ -675,13 +704,14 @@ func (issue *Issue) ChangeStatus(doer *User, repo *Repository, isClosed bool) (e
return fmt.Errorf("Commit: %v", err) return fmt.Errorf("Commit: %v", err)
} }
mode, _ := AccessLevel(issue.Poster.ID, issue.Repo)
if issue.IsPull { if issue.IsPull {
// Merge pull request calls issue.changeStatus so we need to handle separately. // Merge pull request calls issue.changeStatus so we need to handle separately.
issue.PullRequest.Issue = issue issue.PullRequest.Issue = issue
apiPullRequest := &api.PullRequestPayload{ apiPullRequest := &api.PullRequestPayload{
Index: issue.Index, Index: issue.Index,
PullRequest: issue.PullRequest.APIFormat(), PullRequest: issue.PullRequest.APIFormat(),
Repository: repo.APIFormat(AccessModeNone), Repository: repo.APIFormat(mode),
Sender: doer.APIFormat(), Sender: doer.APIFormat(),
} }
if isClosed { if isClosed {
@ -690,6 +720,19 @@ func (issue *Issue) ChangeStatus(doer *User, repo *Repository, isClosed bool) (e
apiPullRequest.Action = api.HookIssueReOpened apiPullRequest.Action = api.HookIssueReOpened
} }
err = PrepareWebhooks(repo, HookEventPullRequest, apiPullRequest) err = PrepareWebhooks(repo, HookEventPullRequest, apiPullRequest)
} else {
apiIssue := &api.IssuePayload{
Index: issue.Index,
Issue: issue.APIFormat(),
Repository: repo.APIFormat(mode),
Sender: doer.APIFormat(),
}
if isClosed {
apiIssue.Action = api.HookIssueClosed
} else {
apiIssue.Action = api.HookIssueReOpened
}
err = PrepareWebhooks(repo, HookEventIssues, apiIssue)
} }
if err != nil { if err != nil {
log.Error(4, "PrepareWebhooks [is_pull: %v, is_closed: %v]: %v", issue.IsPull, isClosed, err) log.Error(4, "PrepareWebhooks [is_pull: %v, is_closed: %v]: %v", issue.IsPull, isClosed, err)
@ -723,6 +766,7 @@ func (issue *Issue) ChangeTitle(doer *User, title string) (err error) {
return err return err
} }
mode, _ := AccessLevel(issue.Poster.ID, issue.Repo)
if issue.IsPull { if issue.IsPull {
issue.PullRequest.Issue = issue issue.PullRequest.Issue = issue
err = PrepareWebhooks(issue.Repo, HookEventPullRequest, &api.PullRequestPayload{ err = PrepareWebhooks(issue.Repo, HookEventPullRequest, &api.PullRequestPayload{
@ -734,10 +778,24 @@ func (issue *Issue) ChangeTitle(doer *User, title string) (err error) {
}, },
}, },
PullRequest: issue.PullRequest.APIFormat(), PullRequest: issue.PullRequest.APIFormat(),
Repository: issue.Repo.APIFormat(AccessModeNone), Repository: issue.Repo.APIFormat(mode),
Sender: doer.APIFormat(), Sender: doer.APIFormat(),
}) })
} else {
err = PrepareWebhooks(issue.Repo, HookEventIssues, &api.IssuePayload{
Action: api.HookIssueEdited,
Index: issue.Index,
Changes: &api.ChangesPayload{
Title: &api.ChangesFromPayload{
From: oldTitle,
},
},
Issue: issue.APIFormat(),
Repository: issue.Repo.APIFormat(mode),
Sender: issue.Poster.APIFormat(),
})
} }
if err != nil { if err != nil {
log.Error(4, "PrepareWebhooks [is_pull: %v]: %v", issue.IsPull, err) log.Error(4, "PrepareWebhooks [is_pull: %v]: %v", issue.IsPull, err)
} else { } else {
@ -774,6 +832,7 @@ func (issue *Issue) ChangeContent(doer *User, content string) (err error) {
return fmt.Errorf("UpdateIssueCols: %v", err) return fmt.Errorf("UpdateIssueCols: %v", err)
} }
mode, _ := AccessLevel(issue.Poster.ID, issue.Repo)
if issue.IsPull { if issue.IsPull {
issue.PullRequest.Issue = issue issue.PullRequest.Issue = issue
err = PrepareWebhooks(issue.Repo, HookEventPullRequest, &api.PullRequestPayload{ err = PrepareWebhooks(issue.Repo, HookEventPullRequest, &api.PullRequestPayload{
@ -785,9 +844,22 @@ func (issue *Issue) ChangeContent(doer *User, content string) (err error) {
}, },
}, },
PullRequest: issue.PullRequest.APIFormat(), PullRequest: issue.PullRequest.APIFormat(),
Repository: issue.Repo.APIFormat(AccessModeNone), Repository: issue.Repo.APIFormat(mode),
Sender: doer.APIFormat(), Sender: doer.APIFormat(),
}) })
} else {
err = PrepareWebhooks(issue.Repo, HookEventIssues, &api.IssuePayload{
Action: api.HookIssueEdited,
Index: issue.Index,
Changes: &api.ChangesPayload{
Body: &api.ChangesFromPayload{
From: oldContent,
},
},
Issue: issue.APIFormat(),
Repository: issue.Repo.APIFormat(mode),
Sender: doer.APIFormat(),
})
} }
if err != nil { if err != nil {
log.Error(4, "PrepareWebhooks [is_pull: %v]: %v", issue.IsPull, err) log.Error(4, "PrepareWebhooks [is_pull: %v]: %v", issue.IsPull, err)
@ -980,6 +1052,19 @@ func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, assigneeIDs []in
log.Error(4, "MailParticipants: %v", err) log.Error(4, "MailParticipants: %v", err)
} }
mode, _ := AccessLevel(issue.Poster.ID, issue.Repo)
if err = PrepareWebhooks(repo, HookEventIssues, &api.IssuePayload{
Action: api.HookIssueOpened,
Index: issue.Index,
Issue: issue.APIFormat(),
Repository: repo.APIFormat(mode),
Sender: issue.Poster.APIFormat(),
}); err != nil {
log.Error(4, "PrepareWebhooks: %v", err)
} else {
go HookQueue.Add(issue.RepoID)
}
return nil return nil
} }

View File

@ -159,12 +159,16 @@ func (issue *Issue) changeAssignee(sess *xorm.Session, doer *User, assigneeID in
return fmt.Errorf("createAssigneeComment: %v", err) return fmt.Errorf("createAssigneeComment: %v", err)
} }
mode, _ := accessLevel(sess, doer.ID, issue.Repo)
if issue.IsPull { if issue.IsPull {
issue.PullRequest = &PullRequest{Issue: issue} if err = issue.loadPullRequest(sess); err != nil {
return fmt.Errorf("loadPullRequest: %v", err)
}
issue.PullRequest.Issue = issue
apiPullRequest := &api.PullRequestPayload{ apiPullRequest := &api.PullRequestPayload{
Index: issue.Index, Index: issue.Index,
PullRequest: issue.PullRequest.APIFormat(), PullRequest: issue.PullRequest.APIFormat(),
Repository: issue.Repo.APIFormat(AccessModeNone), Repository: issue.Repo.APIFormat(mode),
Sender: doer.APIFormat(), Sender: doer.APIFormat(),
} }
if removed { if removed {
@ -172,7 +176,23 @@ func (issue *Issue) changeAssignee(sess *xorm.Session, doer *User, assigneeID in
} else { } else {
apiPullRequest.Action = api.HookIssueAssigned apiPullRequest.Action = api.HookIssueAssigned
} }
if err := PrepareWebhooks(issue.Repo, HookEventPullRequest, apiPullRequest); err != nil { if err := prepareWebhooks(sess, issue.Repo, HookEventPullRequest, apiPullRequest); err != nil {
log.Error(4, "PrepareWebhooks [is_pull: %v, remove_assignee: %v]: %v", issue.IsPull, removed, err)
return nil
}
} else {
apiIssue := &api.IssuePayload{
Index: issue.Index,
Issue: issue.APIFormat(),
Repository: issue.Repo.APIFormat(mode),
Sender: doer.APIFormat(),
}
if removed {
apiIssue.Action = api.HookIssueUnassigned
} else {
apiIssue.Action = api.HookIssueAssigned
}
if err := prepareWebhooks(sess, issue.Repo, HookEventIssues, apiIssue); err != nil {
log.Error(4, "PrepareWebhooks [is_pull: %v, remove_assignee: %v]: %v", issue.IsPull, removed, err) log.Error(4, "PrepareWebhooks [is_pull: %v, remove_assignee: %v]: %v", issue.IsPull, removed, err)
return nil return nil
} }

View File

@ -612,6 +612,8 @@ func CreateIssueComment(doer *User, repo *Repository, issue *Issue, content stri
Sender: doer.APIFormat(), Sender: doer.APIFormat(),
}); err != nil { }); err != nil {
log.Error(2, "PrepareWebhooks [comment_id: %d]: %v", comment.ID, err) log.Error(2, "PrepareWebhooks [comment_id: %d]: %v", comment.ID, err)
} else {
go HookQueue.Add(repo.ID)
} }
return comment, nil return comment, nil
} }
@ -754,6 +756,8 @@ func UpdateComment(doer *User, c *Comment, oldContent string) error {
Sender: doer.APIFormat(), Sender: doer.APIFormat(),
}); err != nil { }); err != nil {
log.Error(2, "PrepareWebhooks [comment_id: %d]: %v", c.ID, err) log.Error(2, "PrepareWebhooks [comment_id: %d]: %v", c.ID, err)
} else {
go HookQueue.Add(c.Issue.Repo.ID)
} }
return nil return nil
@ -805,6 +809,8 @@ func DeleteComment(doer *User, comment *Comment) error {
Sender: doer.APIFormat(), Sender: doer.APIFormat(),
}); err != nil { }); err != nil {
log.Error(2, "PrepareWebhooks [comment_id: %d]: %v", comment.ID, err) log.Error(2, "PrepareWebhooks [comment_id: %d]: %v", comment.ID, err)
} else {
go HookQueue.Add(comment.Issue.Repo.ID)
} }
return nil return nil

View File

@ -402,6 +402,8 @@ func ChangeMilestoneAssign(issue *Issue, doer *User, oldMilestoneID int64) (err
} }
if err != nil { if err != nil {
log.Error(2, "PrepareWebhooks [is_pull: %v]: %v", issue.IsPull, err) log.Error(2, "PrepareWebhooks [is_pull: %v]: %v", issue.IsPull, err)
} else {
go HookQueue.Add(issue.RepoID)
} }
return nil return nil
} }

View File

@ -54,28 +54,30 @@ func newIssueUsers(e Engine, repo *Repository, issue *Issue) error {
func updateIssueAssignee(e *xorm.Session, issue *Issue, assigneeID int64) (removed bool, err error) { func updateIssueAssignee(e *xorm.Session, issue *Issue, assigneeID int64) (removed bool, err error) {
// Check if the user exists // Check if the user exists
_, err = GetUserByID(assigneeID) assignee, err := GetUserByID(assigneeID)
if err != nil { if err != nil {
return false, err return false, err
} }
// Check if the submitted user is already assigne, if yes delete him otherwise add him // Check if the submitted user is already assigne, if yes delete him otherwise add him
var toBeDeleted bool var i int
for _, assignee := range issue.Assignees { for i = 0; i < len(issue.Assignees); i++ {
if assignee.ID == assigneeID { if issue.Assignees[i].ID == assigneeID {
toBeDeleted = true
break break
} }
} }
assigneeIn := IssueAssignees{AssigneeID: assigneeID, IssueID: issue.ID} assigneeIn := IssueAssignees{AssigneeID: assigneeID, IssueID: issue.ID}
toBeDeleted := i < len(issue.Assignees)
if toBeDeleted { if toBeDeleted {
issue.Assignees = append(issue.Assignees[:i], issue.Assignees[i:]...)
_, err = e.Delete(assigneeIn) _, err = e.Delete(assigneeIn)
if err != nil { if err != nil {
return toBeDeleted, err return toBeDeleted, err
} }
} else { } else {
issue.Assignees = append(issue.Assignees, assignee)
_, err = e.Insert(assigneeIn) _, err = e.Insert(assigneeIn)
if err != nil { if err != nil {
return toBeDeleted, err return toBeDeleted, err

View File

@ -184,6 +184,8 @@ var migrations = []Migration{
NewMigration("add multiple assignees", addMultipleAssignees), NewMigration("add multiple assignees", addMultipleAssignees),
// v65 -> v66 // v65 -> v66
NewMigration("add u2f", addU2FReg), NewMigration("add u2f", addU2FReg),
// v66 -> v67
NewMigration("add login source id column for public_key table", addLoginSourceIDToPublicKeyTable),
} }
// Migrate database to current version // Migrate database to current version

22
models/migrations/v66.go Normal file
View File

@ -0,0 +1,22 @@
// Copyright 2017 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package migrations
import (
"fmt"
"github.com/go-xorm/xorm"
)
func addLoginSourceIDToPublicKeyTable(x *xorm.Engine) error {
type PublicKey struct {
LoginSourceID int64 `xorm:"NOT NULL DEFAULT 0"`
}
if err := x.Sync2(new(PublicKey)); err != nil {
return fmt.Errorf("Sync2: %v", err)
}
return nil
}

View File

@ -457,15 +457,18 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository, mergeStyle
log.Error(4, "LoadAttributes: %v", err) log.Error(4, "LoadAttributes: %v", err)
return nil return nil
} }
mode, _ := AccessLevel(doer.ID, pr.Issue.Repo)
if err = PrepareWebhooks(pr.Issue.Repo, HookEventPullRequest, &api.PullRequestPayload{ if err = PrepareWebhooks(pr.Issue.Repo, HookEventPullRequest, &api.PullRequestPayload{
Action: api.HookIssueClosed, Action: api.HookIssueClosed,
Index: pr.Index, Index: pr.Index,
PullRequest: pr.APIFormat(), PullRequest: pr.APIFormat(),
Repository: pr.Issue.Repo.APIFormat(AccessModeNone), Repository: pr.Issue.Repo.APIFormat(mode),
Sender: doer.APIFormat(), Sender: doer.APIFormat(),
}); err != nil { }); err != nil {
log.Error(4, "PrepareWebhooks: %v", err) log.Error(4, "PrepareWebhooks: %v", err)
return nil } else {
go HookQueue.Add(pr.Issue.Repo.ID)
} }
l, err := baseGitRepo.CommitsBetweenIDs(pr.MergedCommitID, pr.MergeBase) l, err := baseGitRepo.CommitsBetweenIDs(pr.MergedCommitID, pr.MergeBase)
@ -492,12 +495,14 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository, mergeStyle
After: mergeCommit.ID.String(), After: mergeCommit.ID.String(),
CompareURL: setting.AppURL + pr.BaseRepo.ComposeCompareURL(pr.MergeBase, pr.MergedCommitID), CompareURL: setting.AppURL + pr.BaseRepo.ComposeCompareURL(pr.MergeBase, pr.MergedCommitID),
Commits: ListToPushCommits(l).ToAPIPayloadCommits(pr.BaseRepo.HTMLURL()), Commits: ListToPushCommits(l).ToAPIPayloadCommits(pr.BaseRepo.HTMLURL()),
Repo: pr.BaseRepo.APIFormat(AccessModeNone), Repo: pr.BaseRepo.APIFormat(mode),
Pusher: pr.HeadRepo.MustOwner().APIFormat(), Pusher: pr.HeadRepo.MustOwner().APIFormat(),
Sender: doer.APIFormat(), Sender: doer.APIFormat(),
} }
if err = PrepareWebhooks(pr.BaseRepo, HookEventPush, p); err != nil { if err = PrepareWebhooks(pr.BaseRepo, HookEventPush, p); err != nil {
return fmt.Errorf("PrepareWebhooks: %v", err) log.Error(4, "PrepareWebhooks: %v", err)
} else {
go HookQueue.Add(pr.BaseRepo.ID)
} }
return nil return nil
} }
@ -782,16 +787,18 @@ func NewPullRequest(repo *Repository, pull *Issue, labelIDs []int64, uuids []str
pr.Issue = pull pr.Issue = pull
pull.PullRequest = pr pull.PullRequest = pr
mode, _ := AccessLevel(pull.Poster.ID, repo)
if err = PrepareWebhooks(repo, HookEventPullRequest, &api.PullRequestPayload{ if err = PrepareWebhooks(repo, HookEventPullRequest, &api.PullRequestPayload{
Action: api.HookIssueOpened, Action: api.HookIssueOpened,
Index: pull.Index, Index: pull.Index,
PullRequest: pr.APIFormat(), PullRequest: pr.APIFormat(),
Repository: repo.APIFormat(AccessModeNone), Repository: repo.APIFormat(mode),
Sender: pull.Poster.APIFormat(), Sender: pull.Poster.APIFormat(),
}); err != nil { }); err != nil {
log.Error(4, "PrepareWebhooks: %v", err) log.Error(4, "PrepareWebhooks: %v", err)
} else {
go HookQueue.Add(repo.ID)
} }
go HookQueue.Add(repo.ID)
return nil return nil
} }

View File

@ -207,6 +207,8 @@ func CreateRelease(gitRepo *git.Repository, rel *Release, attachmentUUIDs []stri
Sender: rel.Publisher.APIFormat(), Sender: rel.Publisher.APIFormat(),
}); err != nil { }); err != nil {
log.Error(2, "PrepareWebhooks: %v", err) log.Error(2, "PrepareWebhooks: %v", err)
} else {
go HookQueue.Add(rel.Repo.ID)
} }
} }
} }
@ -371,7 +373,7 @@ func SortReleases(rels []*Release) {
} }
// UpdateRelease updates information of a release. // UpdateRelease updates information of a release.
func UpdateRelease(gitRepo *git.Repository, rel *Release, attachmentUUIDs []string) (err error) { func UpdateRelease(doer *User, gitRepo *git.Repository, rel *Release, attachmentUUIDs []string) (err error) {
if err = createTag(gitRepo, rel); err != nil { if err = createTag(gitRepo, rel); err != nil {
return err return err
} }
@ -382,8 +384,25 @@ func UpdateRelease(gitRepo *git.Repository, rel *Release, attachmentUUIDs []stri
return err return err
} }
err = rel.loadAttributes(x)
if err != nil {
return err
}
err = addReleaseAttachments(rel.ID, attachmentUUIDs) err = addReleaseAttachments(rel.ID, attachmentUUIDs)
mode, _ := accessLevel(x, doer.ID, rel.Repo)
if err1 := PrepareWebhooks(rel.Repo, HookEventRelease, &api.ReleasePayload{
Action: api.HookReleaseUpdated,
Release: rel.APIFormat(),
Repository: rel.Repo.APIFormat(mode),
Sender: rel.Publisher.APIFormat(),
}); err1 != nil {
log.Error(2, "PrepareWebhooks: %v", err)
} else {
go HookQueue.Add(rel.Repo.ID)
}
return err return err
} }
@ -429,6 +448,18 @@ func DeleteReleaseByID(id int64, u *User, delTag bool) error {
} }
} }
mode, _ := accessLevel(x, u.ID, rel.Repo)
if err := PrepareWebhooks(rel.Repo, HookEventRelease, &api.ReleasePayload{
Action: api.HookReleaseDeleted,
Release: rel.APIFormat(),
Repository: rel.Repo.APIFormat(mode),
Sender: rel.Publisher.APIFormat(),
}); err != nil {
log.Error(2, "PrepareWebhooks: %v", err)
} else {
go HookQueue.Add(rel.Repo.ID)
}
return nil return nil
} }

View File

@ -1824,6 +1824,8 @@ func DeleteRepository(doer *User, uid, repoID int64) error {
&PullRequest{BaseRepoID: repoID}, &PullRequest{BaseRepoID: repoID},
&RepoUnit{RepoID: repoID}, &RepoUnit{RepoID: repoID},
&RepoRedirect{RedirectRepoID: repoID}, &RepoRedirect{RedirectRepoID: repoID},
&Webhook{RepoID: repoID},
&HookTask{RepoID: repoID},
); err != nil { ); err != nil {
return fmt.Errorf("deleteBeans: %v", err) return fmt.Errorf("deleteBeans: %v", err)
} }
@ -2460,11 +2462,13 @@ func ForkRepository(doer, u *User, oldRepo *Repository, name, desc string) (_ *R
mode, _ := AccessLevel(doer.ID, repo) mode, _ := AccessLevel(doer.ID, repo)
if err = PrepareWebhooks(oldRepo, HookEventFork, &api.ForkPayload{ if err = PrepareWebhooks(oldRepo, HookEventFork, &api.ForkPayload{
Forkee: repo.APIFormat(mode), Forkee: oldRepo.APIFormat(oldMode),
Repo: oldRepo.APIFormat(oldMode), Repo: repo.APIFormat(mode),
Sender: doer.APIFormat(), Sender: doer.APIFormat(),
}); err != nil { }); err != nil {
log.Error(2, "PrepareWebhooks [repo_id: %d]: %v", oldRepo.ID, err) log.Error(2, "PrepareWebhooks [repo_id: %d]: %v", oldRepo.ID, err)
} else {
go HookQueue.Add(oldRepo.ID)
} }
if err = repo.UpdateSize(); err != nil { if err = repo.UpdateSize(); err != nil {

View File

@ -152,6 +152,10 @@ const (
SearchOrderBySizeReverse = "size DESC" SearchOrderBySizeReverse = "size DESC"
SearchOrderByID = "id ASC" SearchOrderByID = "id ASC"
SearchOrderByIDReverse = "id DESC" SearchOrderByIDReverse = "id DESC"
SearchOrderByStars = "num_stars ASC"
SearchOrderByStarsReverse = "num_stars DESC"
SearchOrderByForks = "num_forks ASC"
SearchOrderByForksReverse = "num_forks DESC"
) )
// SearchRepositoryByName takes keyword and part of repository name to search, // SearchRepositoryByName takes keyword and part of repository name to search,

View File

@ -47,13 +47,14 @@ const (
// PublicKey represents a user or deploy SSH public key. // PublicKey represents a user or deploy SSH public key.
type PublicKey struct { type PublicKey struct {
ID int64 `xorm:"pk autoincr"` ID int64 `xorm:"pk autoincr"`
OwnerID int64 `xorm:"INDEX NOT NULL"` OwnerID int64 `xorm:"INDEX NOT NULL"`
Name string `xorm:"NOT NULL"` Name string `xorm:"NOT NULL"`
Fingerprint string `xorm:"NOT NULL"` Fingerprint string `xorm:"NOT NULL"`
Content string `xorm:"TEXT NOT NULL"` Content string `xorm:"TEXT NOT NULL"`
Mode AccessMode `xorm:"NOT NULL DEFAULT 2"` Mode AccessMode `xorm:"NOT NULL DEFAULT 2"`
Type KeyType `xorm:"NOT NULL DEFAULT 1"` Type KeyType `xorm:"NOT NULL DEFAULT 1"`
LoginSourceID int64 `xorm:"NOT NULL DEFAULT 0"`
CreatedUnix util.TimeStamp `xorm:"created"` CreatedUnix util.TimeStamp `xorm:"created"`
UpdatedUnix util.TimeStamp `xorm:"updated"` UpdatedUnix util.TimeStamp `xorm:"updated"`
@ -391,7 +392,7 @@ func addKey(e Engine, key *PublicKey) (err error) {
} }
// AddPublicKey adds new public key to database and authorized_keys file. // AddPublicKey adds new public key to database and authorized_keys file.
func AddPublicKey(ownerID int64, name, content string) (*PublicKey, error) { func AddPublicKey(ownerID int64, name, content string, LoginSourceID int64) (*PublicKey, error) {
log.Trace(content) log.Trace(content)
fingerprint, err := calcFingerprint(content) fingerprint, err := calcFingerprint(content)
@ -420,12 +421,13 @@ func AddPublicKey(ownerID int64, name, content string) (*PublicKey, error) {
} }
key := &PublicKey{ key := &PublicKey{
OwnerID: ownerID, OwnerID: ownerID,
Name: name, Name: name,
Fingerprint: fingerprint, Fingerprint: fingerprint,
Content: content, Content: content,
Mode: AccessModeWrite, Mode: AccessModeWrite,
Type: KeyTypeUser, Type: KeyTypeUser,
LoginSourceID: LoginSourceID,
} }
if err = addKey(sess, key); err != nil { if err = addKey(sess, key); err != nil {
return nil, fmt.Errorf("addKey: %v", err) return nil, fmt.Errorf("addKey: %v", err)
@ -471,6 +473,14 @@ func ListPublicKeys(uid int64) ([]*PublicKey, error) {
Find(&keys) Find(&keys)
} }
// ListPublicLdapSSHKeys returns a list of synchronized public ldap ssh keys belongs to given user and login source.
func ListPublicLdapSSHKeys(uid int64, LoginSourceID int64) ([]*PublicKey, error) {
keys := make([]*PublicKey, 0, 5)
return keys, x.
Where("owner_id = ? AND login_source_id = ?", uid, LoginSourceID).
Find(&keys)
}
// UpdatePublicKeyUpdated updates public key use time. // UpdatePublicKeyUpdated updates public key use time.
func UpdatePublicKeyUpdated(id int64) error { func UpdatePublicKeyUpdated(id int64) error {
// Check if key exists before update as affected rows count is unreliable // Check if key exists before update as affected rows count is unreliable

View File

@ -1272,7 +1272,7 @@ func GetUser(user *User) (bool, error) {
type SearchUserOptions struct { type SearchUserOptions struct {
Keyword string Keyword string
Type UserType Type UserType
OrderBy string OrderBy SearchOrderBy
Page int Page int
PageSize int // Can be smaller than or equal to setting.UI.ExplorePagingNum PageSize int // Can be smaller than or equal to setting.UI.ExplorePagingNum
IsActive util.OptionalBool IsActive util.OptionalBool
@ -1322,7 +1322,7 @@ func SearchUsers(opts *SearchUserOptions) (users []*User, _ int64, _ error) {
users = make([]*User, 0, opts.PageSize) users = make([]*User, 0, opts.PageSize)
return users, count, x.Where(cond). return users, count, x.Where(cond).
Limit(opts.PageSize, (opts.Page-1)*opts.PageSize). Limit(opts.PageSize, (opts.Page-1)*opts.PageSize).
OrderBy(opts.OrderBy). OrderBy(opts.OrderBy.String()).
Find(&users) Find(&users)
} }
@ -1356,6 +1356,119 @@ func GetWatchedRepos(userID int64, private bool) ([]*Repository, error) {
return repos, nil return repos, nil
} }
// deleteKeysMarkedForDeletion returns true if ssh keys needs update
func deleteKeysMarkedForDeletion(keys []string) (bool, error) {
// Start session
sess := x.NewSession()
defer sess.Close()
if err := sess.Begin(); err != nil {
return false, err
}
// Delete keys marked for deletion
var sshKeysNeedUpdate bool
for _, KeyToDelete := range keys {
key, err := SearchPublicKeyByContent(KeyToDelete)
if err != nil {
log.Error(4, "SearchPublicKeyByContent: %v", err)
continue
}
if err = deletePublicKeys(sess, key.ID); err != nil {
log.Error(4, "deletePublicKeys: %v", err)
continue
}
sshKeysNeedUpdate = true
}
if err := sess.Commit(); err != nil {
return false, err
}
return sshKeysNeedUpdate, nil
}
func addLdapSSHPublicKeys(s *LoginSource, usr *User, SSHPublicKeys []string) bool {
var sshKeysNeedUpdate bool
for _, sshKey := range SSHPublicKeys {
if strings.HasPrefix(strings.ToLower(sshKey), "ssh") {
sshKeyName := fmt.Sprintf("%s-%s", s.Name, sshKey[0:40])
if _, err := AddPublicKey(usr.ID, sshKeyName, sshKey, s.ID); err != nil {
log.Error(4, "addLdapSSHPublicKeys[%s]: Error adding LDAP Public SSH Key for user %s: %v", s.Name, usr.Name, err)
} else {
log.Trace("addLdapSSHPublicKeys[%s]: Added LDAP Public SSH Key for user %s", s.Name, usr.Name)
sshKeysNeedUpdate = true
}
} else {
log.Warn("addLdapSSHPublicKeys[%s]: Skipping invalid LDAP Public SSH Key for user %s: %v", s.Name, usr.Name, sshKey)
}
}
return sshKeysNeedUpdate
}
func synchronizeLdapSSHPublicKeys(s *LoginSource, SSHPublicKeys []string, usr *User) bool {
var sshKeysNeedUpdate bool
log.Trace("synchronizeLdapSSHPublicKeys[%s]: Handling LDAP Public SSH Key synchronization for user %s", s.Name, usr.Name)
// Get Public Keys from DB with current LDAP source
var giteaKeys []string
keys, err := ListPublicLdapSSHKeys(usr.ID, s.ID)
if err != nil {
log.Error(4, "synchronizeLdapSSHPublicKeys[%s]: Error listing LDAP Public SSH Keys for user %s: %v", s.Name, usr.Name, err)
}
for _, v := range keys {
giteaKeys = append(giteaKeys, v.OmitEmail())
}
// Get Public Keys from LDAP and skip duplicate keys
var ldapKeys []string
for _, v := range SSHPublicKeys {
ldapKey := strings.Join(strings.Split(v, " ")[:2], " ")
if !util.ExistsInSlice(ldapKey, ldapKeys) {
ldapKeys = append(ldapKeys, ldapKey)
}
}
// Check if Public Key sync is needed
if util.IsEqualSlice(giteaKeys, ldapKeys) {
log.Trace("synchronizeLdapSSHPublicKeys[%s]: LDAP Public Keys are already in sync for %s (LDAP:%v/DB:%v)", s.Name, usr.Name, len(ldapKeys), len(giteaKeys))
return false
}
log.Trace("synchronizeLdapSSHPublicKeys[%s]: LDAP Public Key needs update for user %s (LDAP:%v/DB:%v)", s.Name, usr.Name, len(ldapKeys), len(giteaKeys))
// Add LDAP Public SSH Keys that doesn't already exist in DB
var newLdapSSHKeys []string
for _, LDAPPublicSSHKey := range ldapKeys {
if !util.ExistsInSlice(LDAPPublicSSHKey, giteaKeys) {
newLdapSSHKeys = append(newLdapSSHKeys, LDAPPublicSSHKey)
}
}
if addLdapSSHPublicKeys(s, usr, newLdapSSHKeys) {
sshKeysNeedUpdate = true
}
// Mark LDAP keys from DB that doesn't exist in LDAP for deletion
var giteaKeysToDelete []string
for _, giteaKey := range giteaKeys {
if !util.ExistsInSlice(giteaKey, ldapKeys) {
log.Trace("synchronizeLdapSSHPublicKeys[%s]: Marking LDAP Public SSH Key for deletion for user %s: %v", s.Name, usr.Name, giteaKey)
giteaKeysToDelete = append(giteaKeysToDelete, giteaKey)
}
}
// Delete LDAP keys from DB that doesn't exist in LDAP
needUpd, err := deleteKeysMarkedForDeletion(giteaKeysToDelete)
if err != nil {
log.Error(4, "synchronizeLdapSSHPublicKeys[%s]: Error deleting LDAP Public SSH Keys marked for deletion for user %s: %v", s.Name, usr.Name, err)
}
if needUpd {
sshKeysNeedUpdate = true
}
return sshKeysNeedUpdate
}
// SyncExternalUsers is used to synchronize users with external authorization source // SyncExternalUsers is used to synchronize users with external authorization source
func SyncExternalUsers() { func SyncExternalUsers() {
if !taskStatusTable.StartIfNotRunning(syncExternalUsers) { if !taskStatusTable.StartIfNotRunning(syncExternalUsers) {
@ -1377,10 +1490,13 @@ func SyncExternalUsers() {
if !s.IsActived || !s.IsSyncEnabled { if !s.IsActived || !s.IsSyncEnabled {
continue continue
} }
if s.IsLDAP() { if s.IsLDAP() {
log.Trace("Doing: SyncExternalUsers[%s]", s.Name) log.Trace("Doing: SyncExternalUsers[%s]", s.Name)
var existingUsers []int64 var existingUsers []int64
var isAttributeSSHPublicKeySet = len(strings.TrimSpace(s.LDAP().AttributeSSHPublicKey)) > 0
var sshKeysNeedUpdate bool
// Find all users with this login type // Find all users with this login type
var users []User var users []User
@ -1389,7 +1505,6 @@ func SyncExternalUsers() {
Find(&users) Find(&users)
sr := s.LDAP().SearchEntries() sr := s.LDAP().SearchEntries()
for _, su := range sr { for _, su := range sr {
if len(su.Username) == 0 { if len(su.Username) == 0 {
continue continue
@ -1426,11 +1541,23 @@ func SyncExternalUsers() {
} }
err = CreateUser(usr) err = CreateUser(usr)
if err != nil { if err != nil {
log.Error(4, "SyncExternalUsers[%s]: Error creating user %s: %v", s.Name, su.Username, err) log.Error(4, "SyncExternalUsers[%s]: Error creating user %s: %v", s.Name, su.Username, err)
} else if isAttributeSSHPublicKeySet {
log.Trace("SyncExternalUsers[%s]: Adding LDAP Public SSH Keys for user %s", s.Name, usr.Name)
if addLdapSSHPublicKeys(s, usr, su.SSHPublicKey) {
sshKeysNeedUpdate = true
}
} }
} else if updateExisting { } else if updateExisting {
existingUsers = append(existingUsers, usr.ID) existingUsers = append(existingUsers, usr.ID)
// Synchronize SSH Public Key if that attribute is set
if isAttributeSSHPublicKeySet && synchronizeLdapSSHPublicKeys(s, su.SSHPublicKey, usr) {
sshKeysNeedUpdate = true
}
// Check if user data has changed // Check if user data has changed
if (len(s.LDAP().AdminFilter) > 0 && usr.IsAdmin != su.IsAdmin) || if (len(s.LDAP().AdminFilter) > 0 && usr.IsAdmin != su.IsAdmin) ||
strings.ToLower(usr.Email) != strings.ToLower(su.Mail) || strings.ToLower(usr.Email) != strings.ToLower(su.Mail) ||
@ -1455,6 +1582,11 @@ func SyncExternalUsers() {
} }
} }
// Rewrite authorized_keys file if LDAP Public SSH Key attribute is set and any key was added or removed
if sshKeysNeedUpdate {
RewriteAllPublicKeys()
}
// Deactivate users not present in LDAP // Deactivate users not present in LDAP
if updateExisting { if updateExisting {
for _, usr := range users { for _, usr := range users {

View File

@ -494,7 +494,14 @@ func (t *HookTask) AfterLoad() {
t.RequestInfo = &HookRequest{} t.RequestInfo = &HookRequest{}
if err := json.Unmarshal([]byte(t.RequestContent), t.RequestInfo); err != nil { if err := json.Unmarshal([]byte(t.RequestContent), t.RequestInfo); err != nil {
log.Error(3, "Unmarshal[%d]: %v", t.ID, err) log.Error(3, "Unmarshal RequestContent[%d]: %v", t.ID, err)
}
if len(t.ResponseContent) > 0 {
t.ResponseInfo = &HookResponse{}
if err := json.Unmarshal([]byte(t.ResponseContent), t.ResponseInfo); err != nil {
log.Error(3, "Unmarshal ResponseContent[%d]: %v", t.ID, err)
}
} }
} }
@ -665,6 +672,10 @@ func (t *HookTask) deliver() {
log.Trace("Hook delivery failed: %s", t.UUID) log.Trace("Hook delivery failed: %s", t.UUID)
} }
if err := UpdateHookTask(t); err != nil {
log.Error(4, "UpdateHookTask [%d]: %v", t.ID, err)
}
// Update webhook last delivery status. // Update webhook last delivery status.
w, err := GetWebhookByID(t.HookID) w, err := GetWebhookByID(t.HookID)
if err != nil { if err != nil {
@ -717,10 +728,6 @@ func DeliverHooks() {
// Update hook task status. // Update hook task status.
for _, t := range tasks { for _, t := range tasks {
t.deliver() t.deliver()
if err := UpdateHookTask(t); err != nil {
log.Error(4, "UpdateHookTask [%d]: %v", t.ID, err)
}
} }
// Start listening on new hook requests. // Start listening on new hook requests.
@ -741,10 +748,6 @@ func DeliverHooks() {
} }
for _, t := range tasks { for _, t := range tasks {
t.deliver() t.deliver()
if err := UpdateHookTask(t); err != nil {
log.Error(4, "UpdateHookTask [%d]: %v", t.ID, err)
continue
}
} }
} }
} }

View File

@ -43,7 +43,7 @@ func getDingtalkCreatePayload(p *api.CreatePayload) (*DingtalkPayload, error) {
Text: title, Text: title,
Title: title, Title: title,
HideAvatar: "0", HideAvatar: "0",
SingleTitle: fmt.Sprintf("view branch %s", refName), SingleTitle: fmt.Sprintf("view ref %s", refName),
SingleURL: p.Repo.HTMLURL + "/src/" + refName, SingleURL: p.Repo.HTMLURL + "/src/" + refName,
}, },
}, nil }, nil
@ -60,7 +60,7 @@ func getDingtalkDeletePayload(p *api.DeletePayload) (*DingtalkPayload, error) {
Text: title, Text: title,
Title: title, Title: title,
HideAvatar: "0", HideAvatar: "0",
SingleTitle: fmt.Sprintf("view branch %s", refName), SingleTitle: fmt.Sprintf("view ref %s", refName),
SingleURL: p.Repo.HTMLURL + "/src/" + refName, SingleURL: p.Repo.HTMLURL + "/src/" + refName,
}, },
}, nil }, nil
@ -153,23 +153,30 @@ func getDingtalkIssuesPayload(p *api.IssuePayload) (*DingtalkPayload, error) {
title = fmt.Sprintf("[%s] Issue unassigned: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title) title = fmt.Sprintf("[%s] Issue unassigned: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
text = p.Issue.Body text = p.Issue.Body
case api.HookIssueLabelUpdated: case api.HookIssueLabelUpdated:
title = fmt.Sprintf("[%s] Pull request labels updated: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title) title = fmt.Sprintf("[%s] Issue labels updated: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
text = p.Issue.Body text = p.Issue.Body
case api.HookIssueLabelCleared: case api.HookIssueLabelCleared:
title = fmt.Sprintf("[%s] Pull request labels cleared: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title) title = fmt.Sprintf("[%s] Issue labels cleared: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
text = p.Issue.Body text = p.Issue.Body
case api.HookIssueSynchronized: case api.HookIssueSynchronized:
title = fmt.Sprintf("[%s] Pull request synchronized: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title) title = fmt.Sprintf("[%s] Issue synchronized: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
text = p.Issue.Body
case api.HookIssueMilestoned:
title = fmt.Sprintf("[%s] Issue milestone: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
text = p.Issue.Body
case api.HookIssueDemilestoned:
title = fmt.Sprintf("[%s] Issue clear milestone: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
text = p.Issue.Body text = p.Issue.Body
} }
return &DingtalkPayload{ return &DingtalkPayload{
MsgType: "actionCard", MsgType: "actionCard",
ActionCard: dingtalk.ActionCard{ ActionCard: dingtalk.ActionCard{
Text: text, Text: title + "\r\n\r\n" + text,
//Markdown: "# " + title + "\n" + text,
Title: title, Title: title,
HideAvatar: "0", HideAvatar: "0",
SingleTitle: "view pull request", SingleTitle: "view issue",
SingleURL: p.Issue.URL, SingleURL: p.Issue.URL,
}, },
}, nil }, nil
@ -195,10 +202,10 @@ func getDingtalkIssueCommentPayload(p *api.IssueCommentPayload) (*DingtalkPayloa
return &DingtalkPayload{ return &DingtalkPayload{
MsgType: "actionCard", MsgType: "actionCard",
ActionCard: dingtalk.ActionCard{ ActionCard: dingtalk.ActionCard{
Text: content, Text: title + "\r\n\r\n" + content,
Title: title, Title: title,
HideAvatar: "0", HideAvatar: "0",
SingleTitle: "view pull request", SingleTitle: "view issue comment",
SingleURL: url, SingleURL: url,
}, },
}, nil }, nil
@ -243,12 +250,19 @@ func getDingtalkPullRequestPayload(p *api.PullRequestPayload) (*DingtalkPayload,
case api.HookIssueSynchronized: case api.HookIssueSynchronized:
title = fmt.Sprintf("[%s] Pull request synchronized: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title) title = fmt.Sprintf("[%s] Pull request synchronized: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title)
text = p.PullRequest.Body text = p.PullRequest.Body
case api.HookIssueMilestoned:
title = fmt.Sprintf("[%s] Pull request milestone: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title)
text = p.PullRequest.Body
case api.HookIssueDemilestoned:
title = fmt.Sprintf("[%s] Pull request clear milestone: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title)
text = p.PullRequest.Body
} }
return &DingtalkPayload{ return &DingtalkPayload{
MsgType: "actionCard", MsgType: "actionCard",
ActionCard: dingtalk.ActionCard{ ActionCard: dingtalk.ActionCard{
Text: text, Text: title + "\r\n\r\n" + text,
//Markdown: "# " + title + "\n" + text,
Title: title, Title: title,
HideAvatar: "0", HideAvatar: "0",
SingleTitle: "view pull request", SingleTitle: "view pull request",
@ -300,7 +314,34 @@ func getDingtalkReleasePayload(p *api.ReleasePayload) (*DingtalkPayload, error)
Text: title, Text: title,
Title: title, Title: title,
HideAvatar: "0", HideAvatar: "0",
SingleTitle: "view repository", SingleTitle: "view release",
SingleURL: url,
},
}, nil
case api.HookReleaseUpdated:
title = fmt.Sprintf("[%s] Release updated", p.Release.TagName)
url = p.Release.URL
return &DingtalkPayload{
MsgType: "actionCard",
ActionCard: dingtalk.ActionCard{
Text: title,
Title: title,
HideAvatar: "0",
SingleTitle: "view release",
SingleURL: url,
},
}, nil
case api.HookReleaseDeleted:
title = fmt.Sprintf("[%s] Release deleted", p.Release.TagName)
url = p.Release.URL
return &DingtalkPayload{
MsgType: "actionCard",
ActionCard: dingtalk.ActionCard{
Text: title,
Title: title,
HideAvatar: "0",
SingleTitle: "view release",
SingleURL: url, SingleURL: url,
}, },
}, nil }, nil

View File

@ -251,6 +251,14 @@ func getDiscordIssuesPayload(p *api.IssuePayload, meta *DiscordMeta) (*DiscordPa
title = fmt.Sprintf("[%s] Issue synchronized: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title) title = fmt.Sprintf("[%s] Issue synchronized: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
text = p.Issue.Body text = p.Issue.Body
color = warnColor color = warnColor
case api.HookIssueMilestoned:
title = fmt.Sprintf("[%s] Issue milestone: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
text = p.Issue.Body
color = warnColor
case api.HookIssueDemilestoned:
title = fmt.Sprintf("[%s] Issue clear milestone: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
text = p.Issue.Body
color = warnColor
} }
return &DiscordPayload{ return &DiscordPayload{
@ -362,6 +370,14 @@ func getDiscordPullRequestPayload(p *api.PullRequestPayload, meta *DiscordMeta)
title = fmt.Sprintf("[%s] Pull request synchronized: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title) title = fmt.Sprintf("[%s] Pull request synchronized: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title)
text = p.PullRequest.Body text = p.PullRequest.Body
color = warnColor color = warnColor
case api.HookIssueMilestoned:
title = fmt.Sprintf("[%s] Pull request milestone: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title)
text = p.PullRequest.Body
color = warnColor
case api.HookIssueDemilestoned:
title = fmt.Sprintf("[%s] Pull request clear milestone: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title)
text = p.PullRequest.Body
color = warnColor
} }
return &DiscordPayload{ return &DiscordPayload{
@ -422,6 +438,14 @@ func getDiscordReleasePayload(p *api.ReleasePayload, meta *DiscordMeta) (*Discor
title = fmt.Sprintf("[%s] Release created", p.Release.TagName) title = fmt.Sprintf("[%s] Release created", p.Release.TagName)
url = p.Release.URL url = p.Release.URL
color = successColor color = successColor
case api.HookReleaseUpdated:
title = fmt.Sprintf("[%s] Release updated", p.Release.TagName)
url = p.Release.URL
color = successColor
case api.HookReleaseDeleted:
title = fmt.Sprintf("[%s] Release deleted", p.Release.TagName)
url = p.Release.URL
color = successColor
} }
return &DiscordPayload{ return &DiscordPayload{

View File

@ -213,7 +213,17 @@ func getSlackIssueCommentPayload(p *api.IssueCommentPayload, slack *SlackMeta) (
func getSlackReleasePayload(p *api.ReleasePayload, slack *SlackMeta) (*SlackPayload, error) { func getSlackReleasePayload(p *api.ReleasePayload, slack *SlackMeta) (*SlackPayload, error) {
repoLink := SlackLinkFormatter(p.Repository.HTMLURL, p.Repository.Name) repoLink := SlackLinkFormatter(p.Repository.HTMLURL, p.Repository.Name)
refLink := SlackLinkFormatter(p.Repository.HTMLURL+"/src/"+p.Release.TagName, p.Release.TagName) refLink := SlackLinkFormatter(p.Repository.HTMLURL+"/src/"+p.Release.TagName, p.Release.TagName)
text := fmt.Sprintf("[%s] new release %s published by %s", repoLink, refLink, p.Sender.UserName) var text string
switch p.Action {
case api.HookReleasePublished:
text = fmt.Sprintf("[%s] new release %s published by %s", repoLink, refLink, p.Sender.UserName)
case api.HookReleaseUpdated:
text = fmt.Sprintf("[%s] new release %s updated by %s", repoLink, refLink, p.Sender.UserName)
case api.HookReleaseDeleted:
text = fmt.Sprintf("[%s] new release %s deleted by %s", repoLink, refLink, p.Sender.UserName)
}
return &SlackPayload{ return &SlackPayload{
Channel: slack.Channel, Channel: slack.Channel,
Text: text, Text: text,

View File

@ -24,6 +24,7 @@ type AuthenticationForm struct {
AttributeName string AttributeName string
AttributeSurname string AttributeSurname string
AttributeMail string AttributeMail string
AttributeSSHPublicKey string
AttributesInBind bool AttributesInBind bool
UsePagedSearch bool UsePagedSearch bool
SearchPageSize int SearchPageSize int

View File

@ -28,33 +28,35 @@ const (
// Source Basic LDAP authentication service // Source Basic LDAP authentication service
type Source struct { type Source struct {
Name string // canonical name (ie. corporate.ad) Name string // canonical name (ie. corporate.ad)
Host string // LDAP host Host string // LDAP host
Port int // port number Port int // port number
SecurityProtocol SecurityProtocol SecurityProtocol SecurityProtocol
SkipVerify bool SkipVerify bool
BindDN string // DN to bind with BindDN string // DN to bind with
BindPassword string // Bind DN password BindPassword string // Bind DN password
UserBase string // Base search path for users UserBase string // Base search path for users
UserDN string // Template for the DN of the user for simple auth UserDN string // Template for the DN of the user for simple auth
AttributeUsername string // Username attribute AttributeUsername string // Username attribute
AttributeName string // First name attribute AttributeName string // First name attribute
AttributeSurname string // Surname attribute AttributeSurname string // Surname attribute
AttributeMail string // E-mail attribute AttributeMail string // E-mail attribute
AttributesInBind bool // fetch attributes in bind context (not user) AttributesInBind bool // fetch attributes in bind context (not user)
SearchPageSize uint32 // Search with paging page size AttributeSSHPublicKey string // LDAP SSH Public Key attribute
Filter string // Query filter to validate entry SearchPageSize uint32 // Search with paging page size
AdminFilter string // Query filter to check if user is admin Filter string // Query filter to validate entry
Enabled bool // if this source is disabled AdminFilter string // Query filter to check if user is admin
Enabled bool // if this source is disabled
} }
// SearchResult : user data // SearchResult : user data
type SearchResult struct { type SearchResult struct {
Username string // Username Username string // Username
Name string // Name Name string // Name
Surname string // Surname Surname string // Surname
Mail string // E-mail address Mail string // E-mail address
IsAdmin bool // if user is administrator SSHPublicKey []string // SSH Public Key
IsAdmin bool // if user is administrator
} }
func (ls *Source) sanitizedUserQuery(username string) (string, bool) { func (ls *Source) sanitizedUserQuery(username string) (string, bool) {
@ -298,10 +300,10 @@ func (ls *Source) SearchEntries() []*SearchResult {
userFilter := fmt.Sprintf(ls.Filter, "*") userFilter := fmt.Sprintf(ls.Filter, "*")
log.Trace("Fetching attributes '%v', '%v', '%v', '%v' with filter %s and base %s", ls.AttributeUsername, ls.AttributeName, ls.AttributeSurname, ls.AttributeMail, userFilter, ls.UserBase) log.Trace("Fetching attributes '%v', '%v', '%v', '%v', '%v' with filter %s and base %s", ls.AttributeUsername, ls.AttributeName, ls.AttributeSurname, ls.AttributeMail, ls.AttributeSSHPublicKey, userFilter, ls.UserBase)
search := ldap.NewSearchRequest( search := ldap.NewSearchRequest(
ls.UserBase, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, userFilter, ls.UserBase, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, userFilter,
[]string{ls.AttributeUsername, ls.AttributeName, ls.AttributeSurname, ls.AttributeMail}, []string{ls.AttributeUsername, ls.AttributeName, ls.AttributeSurname, ls.AttributeMail, ls.AttributeSSHPublicKey},
nil) nil)
var sr *ldap.SearchResult var sr *ldap.SearchResult
@ -319,11 +321,12 @@ func (ls *Source) SearchEntries() []*SearchResult {
for i, v := range sr.Entries { for i, v := range sr.Entries {
result[i] = &SearchResult{ result[i] = &SearchResult{
Username: v.GetAttributeValue(ls.AttributeUsername), Username: v.GetAttributeValue(ls.AttributeUsername),
Name: v.GetAttributeValue(ls.AttributeName), Name: v.GetAttributeValue(ls.AttributeName),
Surname: v.GetAttributeValue(ls.AttributeSurname), Surname: v.GetAttributeValue(ls.AttributeSurname),
Mail: v.GetAttributeValue(ls.AttributeMail), Mail: v.GetAttributeValue(ls.AttributeMail),
IsAdmin: checkAdmin(l, ls, v.DN), SSHPublicKey: v.GetAttributeValues(ls.AttributeSSHPublicKey),
IsAdmin: checkAdmin(l, ls, v.DN),
} }
} }

View File

@ -371,7 +371,7 @@ func (f *MergePullRequestForm) Validate(ctx *macaron.Context, errs binding.Error
// NewReleaseForm form for creating release // NewReleaseForm form for creating release
type NewReleaseForm struct { type NewReleaseForm struct {
TagName string `binding:"Required"` TagName string `binding:"Required;GitRefName"`
Target string `form:"tag_target" binding:"Required"` Target string `form:"tag_target" binding:"Required"`
Title string `binding:"Required"` Title string `binding:"Required"`
Content string Content string

View File

@ -5,6 +5,6 @@ import (
) )
var ( var (
defaultLangs = strings.Split("en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,ja-JP,es-ES,pt-BR,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sr-SP,sv-SE,ko-KR", ",") defaultLangs = strings.Split("en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,uk-UA,ja-JP,es-ES,pt-BR,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sr-SP,sv-SE,ko-KR", ",")
defaultLangNames = strings.Split("English,简体中文,繁體中文(香港),繁體中文(台灣),Deutsch,français,Nederlands,latviešu,русский,日本語,español,português do Brasil,polski,български,italiano,suomi,Türkçe,čeština,српски,svenska,한국어", ",") defaultLangNames = strings.Split("English,简体中文,繁體中文(香港),繁體中文(台灣),Deutsch,français,Nederlands,latviešu,русский,Українська,日本語,español,português do Brasil,polski,български,italiano,suomi,Türkçe,čeština,српски,svenska,한국어", ",")
) )

View File

@ -136,10 +136,11 @@ var (
} }
LFS struct { LFS struct {
StartServer bool `ini:"LFS_START_SERVER"` StartServer bool `ini:"LFS_START_SERVER"`
ContentPath string `ini:"LFS_CONTENT_PATH"` ContentPath string `ini:"LFS_CONTENT_PATH"`
JWTSecretBase64 string `ini:"LFS_JWT_SECRET"` JWTSecretBase64 string `ini:"LFS_JWT_SECRET"`
JWTSecretBytes []byte `ini:"-"` JWTSecretBytes []byte `ini:"-"`
HTTPAuthExpiry time.Duration `ini:"LFS_HTTP_AUTH_EXPIRY"`
} }
// Security settings // Security settings
@ -828,6 +829,8 @@ func NewContext() {
LFS.ContentPath = filepath.Join(AppWorkPath, LFS.ContentPath) LFS.ContentPath = filepath.Join(AppWorkPath, LFS.ContentPath)
} }
LFS.HTTPAuthExpiry = sec.Key("LFS_HTTP_AUTH_EXPIRY").MustDuration(20 * time.Minute)
if LFS.StartServer { if LFS.StartServer {
if err := os.MkdirAll(LFS.ContentPath, 0700); err != nil { if err := os.MkdirAll(LFS.ContentPath, 0700); err != nil {
@ -947,7 +950,7 @@ func NewContext() {
AttachmentAllowedTypes = strings.Replace(sec.Key("ALLOWED_TYPES").MustString("image/jpeg,image/png,application/zip,application/gzip"), "|", ",", -1) AttachmentAllowedTypes = strings.Replace(sec.Key("ALLOWED_TYPES").MustString("image/jpeg,image/png,application/zip,application/gzip"), "|", ",", -1)
AttachmentMaxSize = sec.Key("MAX_SIZE").MustInt64(4) AttachmentMaxSize = sec.Key("MAX_SIZE").MustInt64(4)
AttachmentMaxFiles = sec.Key("MAX_FILES").MustInt(5) AttachmentMaxFiles = sec.Key("MAX_FILES").MustInt(5)
AttachmentEnabled = sec.Key("ENABLE").MustBool(true) AttachmentEnabled = sec.Key("ENABLED").MustBool(true)
TimeFormatKey := Cfg.Section("time").Key("FORMAT").MustString("RFC1123") TimeFormatKey := Cfg.Section("time").Key("FORMAT").MustString("RFC1123")
TimeFormat = map[string]string{ TimeFormat = map[string]string{

View File

@ -27,3 +27,32 @@ func IsSliceInt64Eq(a, b []int64) bool {
} }
return true return true
} }
// ExistsInSlice returns true if string exists in slice.
func ExistsInSlice(target string, slice []string) bool {
i := sort.Search(len(slice),
func(i int) bool { return slice[i] == target })
return i < len(slice)
}
// IsEqualSlice returns true if slices are equal.
func IsEqualSlice(target []string, source []string) bool {
if len(target) != len(source) {
return false
}
if (target == nil) != (source == nil) {
return false
}
sort.Strings(target)
sort.Strings(source)
for i, v := range target {
if v != source[i] {
return false
}
}
return true
}

View File

@ -7,6 +7,7 @@ package util
import ( import (
"net/url" "net/url"
"path" "path"
"strings"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
) )
@ -56,16 +57,25 @@ func Max(a, b int) int {
// URLJoin joins url components, like path.Join, but preserving contents // URLJoin joins url components, like path.Join, but preserving contents
func URLJoin(base string, elems ...string) string { func URLJoin(base string, elems ...string) string {
u, err := url.Parse(base) if !strings.HasSuffix(base, "/") {
base += "/"
}
baseURL, err := url.Parse(base)
if err != nil { if err != nil {
log.Error(4, "URLJoin: Invalid base URL %s", base) log.Error(4, "URLJoin: Invalid base URL %s", base)
return "" return ""
} }
joinArgs := make([]string, 0, len(elems)+1) joinedPath := path.Join(elems...)
joinArgs = append(joinArgs, u.Path) argURL, err := url.Parse(joinedPath)
joinArgs = append(joinArgs, elems...) if err != nil {
u.Path = path.Join(joinArgs...) log.Error(4, "URLJoin: Invalid arg %s", joinedPath)
return u.String() return ""
}
joinedURL := baseURL.ResolveReference(argURL).String()
if !baseURL.IsAbs() && !strings.HasPrefix(base, "/") {
return joinedURL[1:] // Removing leading '/' if needed
}
return joinedURL
} }
// Min min of two ints // Min min of two ints

View File

@ -30,6 +30,14 @@ func TestURLJoin(t *testing.T) {
"a", "b/c/"), "a", "b/c/"),
newTest("a/b/d", newTest("a/b/d",
"a/", "b/c/", "/../d/"), "a/", "b/c/", "/../d/"),
newTest("https://try.gitea.io/a/b/c#d",
"https://try.gitea.io", "a/b", "c#d"),
newTest("/a/b/d",
"/a/", "b/c/", "/../d/"),
newTest("/a/b/c",
"/a", "b/c/"),
newTest("/a/b/c#hash",
"/a", "b/c#hash"),
} { } {
assert.Equal(t, test.Expected, URLJoin(test.Base, test.Elements...)) assert.Equal(t, test.Expected, URLJoin(test.Base, test.Elements...))
} }

View File

@ -19,7 +19,7 @@ const (
) )
var ( var (
// GitRefNamePattern is regular expression wirh unallowed characters in git reference name // GitRefNamePattern is regular expression with unallowed characters in git reference name
GitRefNamePattern = regexp.MustCompile("[^\\d\\w-_\\./]") GitRefNamePattern = regexp.MustCompile("[^\\d\\w-_\\./]")
) )

View File

@ -59,7 +59,6 @@ test_git_failed=Неуспешно тестването на "git" команд
[home] [home]
password_holder=Парола password_holder=Парола
switch_dashboard_context=Превключи контекст на таблото switch_dashboard_context=Превключи контекст на таблото
my_repos=Моите хранилища
collaborative_repos=Съвместни хранилища collaborative_repos=Съвместни хранилища
my_orgs=Моите организации my_orgs=Моите организации
my_mirrors=Моите огледала my_mirrors=Моите огледала
@ -607,9 +606,7 @@ config.db_config=Настройки на базата данни
config.db_type=Тип config.db_type=Тип
config.db_host=Сървър config.db_host=Сървър
config.db_name=Име config.db_name=Име
config.db_ssl_mode_helper=(само за postgres)
config.db_path=Път config.db_path=Път
config.db_path_helper=(за "sqlite3" и "tidb")
config.service_config=Настройка на услугата config.service_config=Настройка на услугата
config.show_registration_button=Покажи бутон за регистрация config.show_registration_button=Покажи бутон за регистрация

View File

@ -59,7 +59,6 @@ test_git_failed=Chyba při testu příkazu 'git': %v
[home] [home]
password_holder=Heslo password_holder=Heslo
switch_dashboard_context=Přepnout kontext přehledu switch_dashboard_context=Přepnout kontext přehledu
my_repos=Mé repositáře
collaborative_repos=Společné repositáře collaborative_repos=Společné repositáře
my_orgs=Mé organizace my_orgs=Mé organizace
my_mirrors=Má zrcadla my_mirrors=Má zrcadla
@ -604,9 +603,7 @@ config.db_config=Nastavení databáze
config.db_type=Typ config.db_type=Typ
config.db_host=Server config.db_host=Server
config.db_name=Název config.db_name=Název
config.db_ssl_mode_helper=(pouze pro 'postgres')
config.db_path=Cesta config.db_path=Cesta
config.db_path_helper=(pro "sqlite3" a "tidb")
config.service_config=Nastavení služby config.service_config=Nastavení služby
config.show_registration_button=Ukázat tlačítko registrace config.show_registration_button=Ukázat tlačítko registrace

View File

@ -31,6 +31,18 @@ twofa=Zwei-Faktor-Authentifizierung
twofa_scratch=Zwei-Faktor-Einmalpasswort twofa_scratch=Zwei-Faktor-Einmalpasswort
passcode=PIN passcode=PIN
u2f_insert_key=Hardware-Sicherheitsschlüssel einstecken
u2f_sign_in=Drücke den Knopf auf deinem Sicherheitsschlüssel. Wenn deiner keinen Knopf hat, stecke ihn erneut ein.
u2f_press_button=Drücke den Knopf auf deinem Sicherheitsschlüssel…
u2f_use_twofa=Zwei-Faktor-Authentifizierung via Handy verwenden
u2f_error=Wir können deinen Hardware-Sicherheitsschlüssel nicht lesen!
u2f_unsupported_browser=Dein Browser unterstützt keine U2F-Geräte. Bitte benutze einen anderen Browser.
u2f_error_1=Ein unbekannter Fehler ist aufgetreten. Bitte versuche es erneut.
u2f_error_2=Stelle sicher, dass du einen verschlüsselte Verbindung (https://) benutzt und die richtige URL eingeben hast.
u2f_error_3=Der Server kann deine Anfrage nicht bearbeiten.
u2f_error_4=Dieser Sicherheitsschlüssel ist nicht berechtigt. Wenn du versuchst, einen neuen Sicherheitsschlüssel zu registrieren, stelle bitte sicher, dass du ihn nicht bereits registriert hast.
u2f_error_5=Das Zeitlimit wurde erreicht bevor dein Schlüssel gelesen werden konnte. Bitte lade die Seite neu.
u2f_reload=Neu laden
repository=Repository repository=Repository
organization=Organisation organization=Organisation
@ -156,7 +168,7 @@ no_reply_address_helper=Domain-Namen für Benutzer mit einer versteckten Emailad
uname_holder=E-Mail-Adresse oder Benutzername uname_holder=E-Mail-Adresse oder Benutzername
password_holder=Passwort password_holder=Passwort
switch_dashboard_context=Kontext der Übersichtsseite wechseln switch_dashboard_context=Kontext der Übersichtsseite wechseln
my_repos=Meine Repositories my_repos=Repositories
show_more_repos=Zeige mehr Repositories… show_more_repos=Zeige mehr Repositories…
collaborative_repos=Gemeinschaftliche Repositories collaborative_repos=Gemeinschaftliche Repositories
my_orgs=Meine Organisationen my_orgs=Meine Organisationen
@ -321,6 +333,7 @@ twofa=Zwei-Faktor-Authentifizierung
account_link=Verknüpfte Benutzerkonten account_link=Verknüpfte Benutzerkonten
organization=Organisationen organization=Organisationen
uid=Uid uid=Uid
u2f=Hardware-Sicherheitsschlüssel
public_profile=Öffentliches Profil public_profile=Öffentliches Profil
profile_desc=Deine E-Mail-Adresse wird für Benachrichtigungen und anderes verwendet. profile_desc=Deine E-Mail-Adresse wird für Benachrichtigungen und anderes verwendet.
@ -450,6 +463,13 @@ then_enter_passcode=Und gebe dann die angezeigte PIN der Anwendung ein:
passcode_invalid=Die PIN ist falsch. Probiere es erneut. passcode_invalid=Die PIN ist falsch. Probiere es erneut.
twofa_enrolled=Die Zwei-Faktor-Authentifizierung wurde für dein Konto aktiviert. Bewahre dein Einmalpasswort (%s) an einem sicheren Ort auf, da es nicht wieder angezeigt werden wird. twofa_enrolled=Die Zwei-Faktor-Authentifizierung wurde für dein Konto aktiviert. Bewahre dein Einmalpasswort (%s) an einem sicheren Ort auf, da es nicht wieder angezeigt werden wird.
u2f_desc=Hardware-Sicherheitsschlüssel sind Geräte, die kryptografische Schlüssel beinhalten. Diese können für die Zwei-Faktor-Authentifizierung verwendet werden. Der Sicherheitsschlüssel muss den <a href="https://fidoalliance.org/">FIDO U2F</a>-Standard unterstützen.
u2f_require_twofa=Du musst die Zwei-Faktor-Authentifizierung aktivieren, um Hardware-Sicherheitsschlüssel nutzen zu können.
u2f_register_key=Sicherheitsschlüssel hinzufügen
u2f_nickname=Nickname
u2f_press_button=Drücke den Knopf auf deinem Sicherheitsschlüssel, um diesen zu registrieren.
u2f_delete_key=Sicherheitsschlüssel entfernen
u2f_delete_key_desc=Wenn du den Sicherheitsschlüssel entfernst, kannst du dich nicht mehr mit diesem einloggen. Bist du sicher?
manage_account_links=Verknüpfte Accounts verwalten manage_account_links=Verknüpfte Accounts verwalten
manage_account_links_desc=Diese externen Accounts sind mit deinem Gitea-Account verknüpft. manage_account_links_desc=Diese externen Accounts sind mit deinem Gitea-Account verknüpft.
@ -673,6 +693,8 @@ issues.filter_sort.recentupdate=Kürzlich aktualisiert
issues.filter_sort.leastupdate=Am Längsten nicht aktualisiert issues.filter_sort.leastupdate=Am Längsten nicht aktualisiert
issues.filter_sort.mostcomment=Am meisten kommentiert issues.filter_sort.mostcomment=Am meisten kommentiert
issues.filter_sort.leastcomment=Am wenigsten kommentiert issues.filter_sort.leastcomment=Am wenigsten kommentiert
issues.filter_sort.mostforks=Meiste Forks
issues.filter_sort.fewestforks=Wenigste Forks
issues.action_open=Öffnen issues.action_open=Öffnen
issues.action_close=Schließen issues.action_close=Schließen
issues.action_label=Label issues.action_label=Label
@ -753,7 +775,7 @@ issues.due_date_form_update=Fälligkeitsdatum ändern
issues.due_date_form_remove=Fälligkeitsdatum löschen issues.due_date_form_remove=Fälligkeitsdatum löschen
issues.due_date_not_writer=Du musst Schreibrechte in diesem Repository haben, um das Fälligkeitsdatum zu ändern. issues.due_date_not_writer=Du musst Schreibrechte in diesem Repository haben, um das Fälligkeitsdatum zu ändern.
issues.due_date_not_set=Kein Fälligkeitsdatum gesetzt. issues.due_date_not_set=Kein Fälligkeitsdatum gesetzt.
issues.due_date_added=hat %s$2 das Fälligkeitsdatum %s$1 hinzugefügt issues.due_date_added=hat %[2]s das Fälligkeitsdatum %[1]s hinzugefügt
issues.due_date_modified=hat %[3]s das Fälligkeitsdatum von %[2]s zu %[1]s geändert issues.due_date_modified=hat %[3]s das Fälligkeitsdatum von %[2]s zu %[1]s geändert
issues.due_date_remove=hat %[2]s das Fälligkeitsdatum %[1]s entfernt issues.due_date_remove=hat %[2]s das Fälligkeitsdatum %[1]s entfernt
issues.due_date_overdue=Überfällig issues.due_date_overdue=Überfällig
@ -1011,7 +1033,7 @@ settings.event_issues_desc=Issue geöffnet, geschlossen, wieder geöffnet, bearb
settings.event_issue_comment=Issue-Kommentar settings.event_issue_comment=Issue-Kommentar
settings.event_issue_comment_desc=Issue-Kommentar angelegt, geändert oder gelöscht. settings.event_issue_comment_desc=Issue-Kommentar angelegt, geändert oder gelöscht.
settings.event_release=Release settings.event_release=Release
settings.event_release_desc=Release in Repository veröffentlicht. settings.event_release_desc=Release in einem Repository veröffentlicht, aktualisiert oder gelöscht.
settings.event_pull_request=Pull-Request settings.event_pull_request=Pull-Request
settings.event_pull_request_desc=Pull-Request geöffnet, geschlossen, wieder geöffnet, bearbeitet, zugewiesen, nicht zugewiesen, Label aktualisiert, Label gelöscht oder synchronisiert. settings.event_pull_request_desc=Pull-Request geöffnet, geschlossen, wieder geöffnet, bearbeitet, zugewiesen, nicht zugewiesen, Label aktualisiert, Label gelöscht oder synchronisiert.
settings.event_push=Push settings.event_push=Push
@ -1339,6 +1361,7 @@ repos.name=Name
repos.private=Privat repos.private=Privat
repos.watches=Beobachtungen repos.watches=Beobachtungen
repos.stars=Favoriten repos.stars=Favoriten
repos.forks=Forks
repos.issues=Issues repos.issues=Issues
repos.size=Größe repos.size=Größe
@ -1449,9 +1472,7 @@ config.db_host=Host
config.db_name=Name config.db_name=Name
config.db_user=Benutzername config.db_user=Benutzername
config.db_ssl_mode=SSL config.db_ssl_mode=SSL
config.db_ssl_mode_helper=(nur für "postgres")
config.db_path=Verzeichnis config.db_path=Verzeichnis
config.db_path_helper=(für "sqlite3" und "tidb")
config.service_config=Service-Konfiguration config.service_config=Service-Konfiguration
config.register_email_confirm=E-Mail-Bestätigung benötigt zum Registrieren config.register_email_confirm=E-Mail-Bestätigung benötigt zum Registrieren

View File

@ -168,7 +168,7 @@ no_reply_address_helper = Domain name for users with a hidden email address. For
uname_holder = Username or Email Address uname_holder = Username or Email Address
password_holder = Password password_holder = Password
switch_dashboard_context = Switch Dashboard Context switch_dashboard_context = Switch Dashboard Context
my_repos = My Repositories my_repos = Repositories
show_more_repos = Show more repositories… show_more_repos = Show more repositories…
collaborative_repos = Collaborative Repositories collaborative_repos = Collaborative Repositories
my_orgs = My Organizations my_orgs = My Organizations
@ -463,7 +463,7 @@ then_enter_passcode = And enter the passcode shown in the application:
passcode_invalid = The passcode is incorrect. Try again. passcode_invalid = The passcode is incorrect. Try again.
twofa_enrolled = Your account has been enrolled into two-factor authentication. Store your scratch token (%s) in a safe place as it is only shown once! twofa_enrolled = Your account has been enrolled into two-factor authentication. Store your scratch token (%s) in a safe place as it is only shown once!
u2f_desc = Security keys are hardware devices containing cryptograhic keys. They could be used for two factor authentication. The security key must support the <a href="https://fidoalliance.org/">FIDO U2F</a> standard. u2f_desc = Security keys are hardware devices containing cryptographic keys. They could be used for two factor authentication. The security key must support the <a href="https://fidoalliance.org/">FIDO U2F</a> standard.
u2f_require_twofa = Two-Factor-Authentication must be enrolled in order to use security keys. u2f_require_twofa = Two-Factor-Authentication must be enrolled in order to use security keys.
u2f_register_key = Add Security Key u2f_register_key = Add Security Key
u2f_nickname = Nickname u2f_nickname = Nickname
@ -693,6 +693,10 @@ issues.filter_sort.recentupdate = Recently updated
issues.filter_sort.leastupdate = Least recently updated issues.filter_sort.leastupdate = Least recently updated
issues.filter_sort.mostcomment = Most commented issues.filter_sort.mostcomment = Most commented
issues.filter_sort.leastcomment = Least commented issues.filter_sort.leastcomment = Least commented
issues.filter_sort.moststars = Most stars
issues.filter_sort.feweststars = Fewest stars
issues.filter_sort.mostforks = Most forks
issues.filter_sort.fewestforks = Fewest forks
issues.action_open = Open issues.action_open = Open
issues.action_close = Close issues.action_close = Close
issues.action_label = Label issues.action_label = Label
@ -1032,7 +1036,7 @@ settings.event_issues_desc = Issue opened, closed, reopened, edited, assigned, u
settings.event_issue_comment = Issue Comment settings.event_issue_comment = Issue Comment
settings.event_issue_comment_desc = Issue comment created, edited, or deleted. settings.event_issue_comment_desc = Issue comment created, edited, or deleted.
settings.event_release = Release settings.event_release = Release
settings.event_release_desc = Release published in a repository. settings.event_release_desc = Release published, updated or deleted in a repository.
settings.event_pull_request = Pull Request settings.event_pull_request = Pull Request
settings.event_pull_request_desc = Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared or synchronized. settings.event_pull_request_desc = Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared or synchronized.
settings.event_push = Push settings.event_push = Push
@ -1360,6 +1364,7 @@ repos.name = Name
repos.private = Private repos.private = Private
repos.watches = Watches repos.watches = Watches
repos.stars = Stars repos.stars = Stars
repos.forks = Forks
repos.issues = Issues repos.issues = Issues
repos.size = Size repos.size = Size
@ -1386,6 +1391,7 @@ auths.attribute_username_placeholder = Leave empty to use the username entered i
auths.attribute_name = First Name Attribute auths.attribute_name = First Name Attribute
auths.attribute_surname = Surname Attribute auths.attribute_surname = Surname Attribute
auths.attribute_mail = Email Attribute auths.attribute_mail = Email Attribute
auths.attribute_ssh_public_key = Public SSH Key Attribute
auths.attributes_in_bind = Fetch Attributes in Bind DN Context auths.attributes_in_bind = Fetch Attributes in Bind DN Context
auths.use_paged_search = Use Paged Search auths.use_paged_search = Use Paged Search
auths.search_page_size = Page Size auths.search_page_size = Page Size
@ -1470,9 +1476,7 @@ config.db_host = Host
config.db_name = Name config.db_name = Name
config.db_user = Username config.db_user = Username
config.db_ssl_mode = SSL config.db_ssl_mode = SSL
config.db_ssl_mode_helper = (for "postgres" only)
config.db_path = Path config.db_path = Path
config.db_path_helper = (for "sqlite3" and "tidb")
config.service_config = Service Configuration config.service_config = Service Configuration
config.register_email_confirm = Require Email Confirmation to Register config.register_email_confirm = Require Email Confirmation to Register

View File

@ -69,7 +69,6 @@ save_config_failed=Error al guardar la configuración: %v
[home] [home]
password_holder=Contraseña password_holder=Contraseña
switch_dashboard_context=Cambiar el contexto del Dashboard switch_dashboard_context=Cambiar el contexto del Dashboard
my_repos=Mis repositorios
collaborative_repos=Repositorios colaborativos collaborative_repos=Repositorios colaborativos
my_orgs=Mis organizaciones my_orgs=Mis organizaciones
my_mirrors=Mis réplicas my_mirrors=Mis réplicas
@ -742,9 +741,7 @@ config.ssh_minimum_key_sizes=Tamaños de clave mínimos
config.db_config=Configuración de la Base de Datos config.db_config=Configuración de la Base de Datos
config.db_type=Tipo config.db_type=Tipo
config.db_name=Nombre config.db_name=Nombre
config.db_ssl_mode_helper=(sólo para "postgres")
config.db_path=Ruta config.db_path=Ruta
config.db_path_helper=(para "sqlite3" y "tidb")
config.service_config=Configuración del servicio config.service_config=Configuración del servicio
config.show_registration_button=Mostrar Botón de Registro config.show_registration_button=Mostrar Botón de Registro

View File

@ -61,7 +61,6 @@ test_git_failed=Epäonnistui testata 'git' komentoa: %v
[home] [home]
password_holder=Salasana password_holder=Salasana
switch_dashboard_context=Vaihda kojelaudan kontekstia switch_dashboard_context=Vaihda kojelaudan kontekstia
my_repos=Reponi
collaborative_repos=Yhteistyö repot collaborative_repos=Yhteistyö repot
my_orgs=Organisaationi my_orgs=Organisaationi
my_mirrors=Peilini my_mirrors=Peilini
@ -586,9 +585,7 @@ config.db_config=Tietokannan asetukset
config.db_type=Tyyppi config.db_type=Tyyppi
config.db_host=Isäntä config.db_host=Isäntä
config.db_name=Nimi config.db_name=Nimi
config.db_ssl_mode_helper=(vain "postgres")
config.db_path=Polku config.db_path=Polku
config.db_path_helper=("sqlite3" ja "tidb")
config.service_config=Palvelu asetukset config.service_config=Palvelu asetukset
config.show_registration_button=Näytä rekisteröidy painike config.show_registration_button=Näytä rekisteröidy painike

View File

@ -70,7 +70,6 @@ save_config_failed=L'enregistrement de la configuration %v a échoué
[home] [home]
password_holder=Mot de passe password_holder=Mot de passe
switch_dashboard_context=Basculer le contexte du tableau de bord switch_dashboard_context=Basculer le contexte du tableau de bord
my_repos=Mes dépôts
collaborative_repos=Dépôts collaboratifs collaborative_repos=Dépôts collaboratifs
my_orgs=Mes organisations my_orgs=Mes organisations
my_mirrors=Mes miroirs my_mirrors=Mes miroirs
@ -819,9 +818,7 @@ config.db_config=Configuration de la base de données
config.db_type=Type config.db_type=Type
config.db_host=Hôte config.db_host=Hôte
config.db_name=Nom config.db_name=Nom
config.db_ssl_mode_helper=("postgres" uniquement)
config.db_path=Emplacement config.db_path=Emplacement
config.db_path_helper=(pour « sqlite3 » et « TIDB »)
config.service_config=Configuration du service config.service_config=Configuration du service
config.show_registration_button=Afficher le bouton d'enregistrement config.show_registration_button=Afficher le bouton d'enregistrement

View File

@ -71,7 +71,6 @@ save_config_failed=Hiba történt a konfiguráció mentése közben: %v
[home] [home]
password_holder=Jelszó password_holder=Jelszó
switch_dashboard_context=Műszerfal nézőpont váltás switch_dashboard_context=Műszerfal nézőpont váltás
my_repos=Tárolóim
show_more_repos=Több tároló mutatása… show_more_repos=Több tároló mutatása…
collaborative_repos=Együttműködési tárolók collaborative_repos=Együttműködési tárolók
my_orgs=Szervezeteim my_orgs=Szervezeteim
@ -836,9 +835,7 @@ config.db_config=Adatbázis Konfiguráció
config.db_type=Típus config.db_type=Típus
config.db_host=Kiszolgáló config.db_host=Kiszolgáló
config.db_name=Név config.db_name=Név
config.db_ssl_mode_helper=(csak "postgres"-nek)
config.db_path=Elérési út config.db_path=Elérési út
config.db_path_helper=("sqlite3" és "tidb"-nek)
config.service_config=Szolgáltatás konfiguráció config.service_config=Szolgáltatás konfiguráció
config.show_registration_button=Regisztráció gomb megjelenítése config.show_registration_button=Regisztráció gomb megjelenítése

View File

@ -70,7 +70,6 @@ save_config_failed=Gagal menyimpan konfigurasi: %v
[home] [home]
password_holder=Kata Sandi password_holder=Kata Sandi
switch_dashboard_context=Alihkan Dasbor Konteks switch_dashboard_context=Alihkan Dasbor Konteks
my_repos=Repositori Saya
collaborative_repos=Repositori Kolaboratif collaborative_repos=Repositori Kolaboratif
my_orgs=Organisasi Saya my_orgs=Organisasi Saya
my_mirrors=Duplikat Saya my_mirrors=Duplikat Saya
@ -808,9 +807,7 @@ config.ssh_minimum_key_sizes=Ukuran kunci minimum
config.db_config=Konfigurasi basis data config.db_config=Konfigurasi basis data
config.db_name=Nama config.db_name=Nama
config.db_ssl_mode_helper=(untuk "postgres" saja)
config.db_path=Jalur config.db_path=Jalur
config.db_path_helper=(untuk "sqlite3 dan "tidb")
config.service_config=Konfigurasi layanan config.service_config=Konfigurasi layanan
config.show_registration_button=Tampilkan tombol mendaftar config.show_registration_button=Tampilkan tombol mendaftar

View File

@ -70,7 +70,6 @@ save_config_failed=Salvataggio della configurazione non riuscito: %v
[home] [home]
password_holder=Password password_holder=Password
switch_dashboard_context=Cambia Dashboard Context switch_dashboard_context=Cambia Dashboard Context
my_repos=I miei Repository
collaborative_repos=Repository Condivisi collaborative_repos=Repository Condivisi
my_orgs=Le mie Organizzazioni my_orgs=Le mie Organizzazioni
my_mirrors=I miei Mirror my_mirrors=I miei Mirror
@ -639,9 +638,7 @@ config.ssh_minimum_key_sizes=Dimensioni minime della chiave
config.db_config=Configurazione Database config.db_config=Configurazione Database
config.db_type=Tipo config.db_type=Tipo
config.db_name=Nome config.db_name=Nome
config.db_ssl_mode_helper=(solo per "postgres")
config.db_path=Percorso config.db_path=Percorso
config.db_path_helper=(per "sqlite3" e "tidb")
config.service_config=Configurazione Servizio config.service_config=Configurazione Servizio
config.show_registration_button=Mostra Pulsane Registrazione config.show_registration_button=Mostra Pulsane Registrazione

View File

@ -71,7 +71,6 @@ save_config_failed=設定ファイルの保存に失敗しました: %v
[home] [home]
password_holder=パスワード password_holder=パスワード
switch_dashboard_context=ダッシュ ボードのコンテキストを切替 switch_dashboard_context=ダッシュ ボードのコンテキストを切替
my_repos=自分のリポジトリ
show_more_repos=リポジトリをさらに表示… show_more_repos=リポジトリをさらに表示…
collaborative_repos=共同リポジトリ collaborative_repos=共同リポジトリ
my_orgs=自分の組織 my_orgs=自分の組織
@ -834,9 +833,7 @@ config.db_config=データベースの構成
config.db_type=タイプ config.db_type=タイプ
config.db_host=ホスト config.db_host=ホスト
config.db_name=名前 config.db_name=名前
config.db_ssl_mode_helper=(「postgres」のみ
config.db_path=パス config.db_path=パス
config.db_path_helper=("sqlite3"および"tidb"のみ)
config.service_config=サービスの構成 config.service_config=サービスの構成
config.show_registration_button=登録ボタンを表示します。 config.show_registration_button=登録ボタンを表示します。

View File

@ -70,7 +70,6 @@ save_config_failed=설정을 저장할 수 없습니다: %v
[home] [home]
password_holder=비밀번호 password_holder=비밀번호
switch_dashboard_context=대시보드 컨텍스트 바꾸기 switch_dashboard_context=대시보드 컨텍스트 바꾸기
my_repos=내 저장소
collaborative_repos=협업 저장소 collaborative_repos=협업 저장소
my_orgs=내 조직 my_orgs=내 조직
my_mirrors=내 미러 저장소들 my_mirrors=내 미러 저장소들
@ -688,9 +687,7 @@ config.db_config=데이터베이스 설정
config.db_type=유형 config.db_type=유형
config.db_host=호스트 config.db_host=호스트
config.db_name=이름 config.db_name=이름
config.db_ssl_mode_helper=("postgres" 전용)
config.db_path=경로 config.db_path=경로
config.db_path_helper=("sqlite3" 및 "tidb"만)
config.service_config=서비스 설정 config.service_config=서비스 설정
config.show_registration_button=등록 버튼을 표시 config.show_registration_button=등록 버튼을 표시

View File

@ -56,7 +56,6 @@ confirm_password=Patvirtinkite slaptažodį
[home] [home]
password_holder=Slaptažodis password_holder=Slaptažodis
my_repos=Mano saugyklos
my_orgs=Mano organizacijos my_orgs=Mano organizacijos
my_mirrors=Mano veidrodžiai my_mirrors=Mano veidrodžiai
view_home=Rodyti %s view_home=Rodyti %s

View File

@ -71,7 +71,6 @@ save_config_failed=Neizdevās saglabāt konfigurāciju: %v
[home] [home]
password_holder=Parole password_holder=Parole
switch_dashboard_context=Mainīt infopaneļa kontekstu switch_dashboard_context=Mainīt infopaneļa kontekstu
my_repos=Mani repozitoriji
show_more_repos=Parādīt vairāk repozitorijus… show_more_repos=Parādīt vairāk repozitorijus…
collaborative_repos=Sadarbības repozitoriji collaborative_repos=Sadarbības repozitoriji
my_orgs=Manas organizācijas my_orgs=Manas organizācijas
@ -834,9 +833,7 @@ config.db_config=Datu bāzes konfigurācija
config.db_type=Veids config.db_type=Veids
config.db_host=Resursdators config.db_host=Resursdators
config.db_name=Nosaukums config.db_name=Nosaukums
config.db_ssl_mode_helper=(tikai PostgreSQL datu bāzei)
config.db_path=Ceļš config.db_path=Ceļš
config.db_path_helper=(priekš "sqlite3" and "tidb")
config.service_config=Pakalpojuma konfigurācija config.service_config=Pakalpojuma konfigurācija
config.show_registration_button=Rādīt reģistrēšanās pogu config.show_registration_button=Rādīt reģistrēšanās pogu

View File

@ -71,7 +71,6 @@ save_config_failed=Kan de configuratie niet opslaan: %v
[home] [home]
password_holder=Wachtwoord password_holder=Wachtwoord
switch_dashboard_context=Wissel voorpaginacontext switch_dashboard_context=Wissel voorpaginacontext
my_repos=Mijn repositories
show_more_repos=Toon meer repositories… show_more_repos=Toon meer repositories…
collaborative_repos=Gedeelde repositories collaborative_repos=Gedeelde repositories
my_orgs=Mijn organisaties my_orgs=Mijn organisaties
@ -785,9 +784,7 @@ config.db_config=Databaseconfiguratie
config.db_type=Type config.db_type=Type
config.db_host=Host config.db_host=Host
config.db_name=Naam config.db_name=Naam
config.db_ssl_mode_helper=(alleen voor "postgres")
config.db_path=Pad config.db_path=Pad
config.db_path_helper=(voor "sqlite3" en "tidb")
config.service_config=Serviceconfiguratie config.service_config=Serviceconfiguratie
config.show_registration_button=Registeren knop weergeven config.show_registration_button=Registeren knop weergeven

View File

@ -70,7 +70,6 @@ save_config_failed=Nie udało się zapisać konfiguracji: %v
[home] [home]
password_holder=Hasło password_holder=Hasło
switch_dashboard_context=Przełącz kontekst pulpitu switch_dashboard_context=Przełącz kontekst pulpitu
my_repos=Moje repozytoria
collaborative_repos=Wspólne repozytoria collaborative_repos=Wspólne repozytoria
my_orgs=Moje organizacje my_orgs=Moje organizacje
my_mirrors=Moje kopie lustrzane my_mirrors=Moje kopie lustrzane
@ -817,9 +816,7 @@ config.db_config=Konfiguracja bazy danych
config.db_type=Typ config.db_type=Typ
config.db_host=Serwer config.db_host=Serwer
config.db_name=Nazwa config.db_name=Nazwa
config.db_ssl_mode_helper=(tylko dla „postgres”)
config.db_path=Ścieżka config.db_path=Ścieżka
config.db_path_helper=(dla „sqlite3” i „tidb”)
config.service_config=Konfiguracja usługi config.service_config=Konfiguracja usługi
config.show_registration_button=Pokazuj przycisk rejestracji config.show_registration_button=Pokazuj przycisk rejestracji

View File

@ -31,6 +31,18 @@ twofa=Autenticação de dois fatores
twofa_scratch=Código de backup da autenticação de dois fatores twofa_scratch=Código de backup da autenticação de dois fatores
passcode=Senha passcode=Senha
u2f_insert_key=Insira sua chave de segurança
u2f_sign_in=Pressione o botão na sua chave de segurança. Se você não encontrar um botão, insira-o novamente.
u2f_press_button=Por favor, pressione o botão na sua chave de segurança...
u2f_use_twofa=Use um código de dois fatores no seu telefone
u2f_error=Não conseguimos ler sua chave de segurança!
u2f_unsupported_browser=Seu navegador não suporta chaves U2F. Por favor, tente outro navegador.
u2f_error_1=Ocorreu um erro desconhecido. Por favor, tente novamente.
u2f_error_2=Por favor, certifique-se de que você está usando uma conexão criptografada (https://) e visite a URL correta.
u2f_error_3=O servidor não pôde prosseguir com sua solicitação.
u2f_error_4=A chave apresentada não é elegível para esta solicitação. Se você tentar registrá-la, certifique-se de que a chave já não é registrada.
u2f_error_5=Tempo limite atingido antes de sua chave poder ser lida. Por favor, recarregue para tentar novamente.
u2f_reload=Recarregar
repository=Repositório repository=Repositório
organization=Organização organization=Organização
@ -156,7 +168,7 @@ no_reply_address_helper=Nome de domínio para usuários com um endereço de e-ma
uname_holder=Usuário ou e-mail uname_holder=Usuário ou e-mail
password_holder=Senha password_holder=Senha
switch_dashboard_context=Trocar contexto do painel de controle switch_dashboard_context=Trocar contexto do painel de controle
my_repos=Meus repositórios my_repos=Repositórios
show_more_repos=Mostrar mais repositórios… show_more_repos=Mostrar mais repositórios…
collaborative_repos=Repositórios colaborativos collaborative_repos=Repositórios colaborativos
my_orgs=Minhas organizações my_orgs=Minhas organizações
@ -321,6 +333,7 @@ twofa=Autenticação de dois fatores
account_link=Contas vinculadas account_link=Contas vinculadas
organization=Organizações organization=Organizações
uid=Uid uid=Uid
u2f=Chaves de segurança
public_profile=Perfil público public_profile=Perfil público
profile_desc=Seu endereço de e-mail será usado para notificações e outras operações. profile_desc=Seu endereço de e-mail será usado para notificações e outras operações.
@ -450,6 +463,13 @@ then_enter_passcode=E insira a senha mostrada no aplicativo:
passcode_invalid=Esse código de acesso é inválido. Tente novamente. passcode_invalid=Esse código de acesso é inválido. Tente novamente.
twofa_enrolled=Sua conta foi inscrita na autenticação de dois fatores. Armazene seu token de backup (%s) em um local seguro, pois ele é exibido apenas uma vez! twofa_enrolled=Sua conta foi inscrita na autenticação de dois fatores. Armazene seu token de backup (%s) em um local seguro, pois ele é exibido apenas uma vez!
u2f_desc=Chaves de segurança são dispositivos de hardware que contém chaves de criptografia. Elas podem ser usadas para autenticação de dois fatores. A chave de segurança deve suportar o padrão <a href="https://fidoalliance.org/">FIDO U2F</a>.
u2f_require_twofa=Autenticação de dois fatores deve estar inscrita para usar chaves de segurança.
u2f_register_key=Adicionar chave de segurança
u2f_nickname=Apelido
u2f_press_button=Pressione o botão na sua chave de segurança para registrá-la.
u2f_delete_key=Remover chave de segurança
u2f_delete_key_desc=Se você remover uma chave de segurança você não poderá mais acessar com ela. Tem certeza?
manage_account_links=Gerenciar contas vinculadas manage_account_links=Gerenciar contas vinculadas
manage_account_links_desc=Estas contas externas estão vinculadas a sua conta de Gitea. manage_account_links_desc=Estas contas externas estão vinculadas a sua conta de Gitea.
@ -673,6 +693,10 @@ issues.filter_sort.recentupdate=Mais recentemente atualizados
issues.filter_sort.leastupdate=Menos recentemente atualizados issues.filter_sort.leastupdate=Menos recentemente atualizados
issues.filter_sort.mostcomment=Mais comentados issues.filter_sort.mostcomment=Mais comentados
issues.filter_sort.leastcomment=Menos comentados issues.filter_sort.leastcomment=Menos comentados
issues.filter_sort.moststars=Mais estrelas
issues.filter_sort.feweststars=Menos estrelas
issues.filter_sort.mostforks=Mais forks
issues.filter_sort.fewestforks=Menos forks
issues.action_open=Abrir issues.action_open=Abrir
issues.action_close=Fechar issues.action_close=Fechar
issues.action_label=Etiqueta issues.action_label=Etiqueta
@ -753,9 +777,9 @@ issues.due_date_form_update=Modificar data limite
issues.due_date_form_remove=Remover data limite issues.due_date_form_remove=Remover data limite
issues.due_date_not_writer=Você deve ter permissão de escrita no repositório para atualizar a data limite de uma issue. issues.due_date_not_writer=Você deve ter permissão de escrita no repositório para atualizar a data limite de uma issue.
issues.due_date_not_set=Data limite não informada. issues.due_date_not_set=Data limite não informada.
issues.due_date_added=adicionou a data limite %s à %s issues.due_date_added=adicionou a data limite %s %s
issues.due_date_modified=modificou a data limite para %s ao invés de %s à %s issues.due_date_modified=modificou a data limite para %s ao invés de %s %s
issues.due_date_remove=removeu a data limite %s à %s issues.due_date_remove=removeu a data limite %s %s
issues.due_date_overdue=Em atraso issues.due_date_overdue=Em atraso
pulls.desc=Habilitar solicitações de merge e revisões de código. pulls.desc=Habilitar solicitações de merge e revisões de código.
@ -1011,7 +1035,7 @@ settings.event_issues_desc=Issue aberta, fechada, reaberta, editada, atribuída,
settings.event_issue_comment=Comentário da issue settings.event_issue_comment=Comentário da issue
settings.event_issue_comment_desc=Comentário da issue criado, editado ou excluído. settings.event_issue_comment_desc=Comentário da issue criado, editado ou excluído.
settings.event_release=Versão settings.event_release=Versão
settings.event_release_desc=Versão publicada em um repositório. settings.event_release_desc=Versão publicada, atualizada ou excluída em um repositório.
settings.event_pull_request=Pull request settings.event_pull_request=Pull request
settings.event_pull_request_desc=Pull request aberto, fechado, reaberto, atribuído, desatribuído, teve etiqueta atualizada ou limpada ou foi sincronizado. settings.event_pull_request_desc=Pull request aberto, fechado, reaberto, atribuído, desatribuído, teve etiqueta atualizada ou limpada ou foi sincronizado.
settings.event_push=Push settings.event_push=Push
@ -1339,6 +1363,7 @@ repos.name=Nome
repos.private=Privado repos.private=Privado
repos.watches=Observadores repos.watches=Observadores
repos.stars=Favoritos repos.stars=Favoritos
repos.forks=Forks
repos.issues=Issues repos.issues=Issues
repos.size=Tamanho repos.size=Tamanho
@ -1365,6 +1390,7 @@ auths.attribute_username_placeholder=Deixe em branco para usar o nome de usuári
auths.attribute_name=Atributo primeiro nome auths.attribute_name=Atributo primeiro nome
auths.attribute_surname=Atributo sobrenome auths.attribute_surname=Atributo sobrenome
auths.attribute_mail=Atributo e-mail auths.attribute_mail=Atributo e-mail
auths.attribute_ssh_public_key=Atributo de chave SSH pública
auths.attributes_in_bind=Buscar os atributos no contexto de Bind DN auths.attributes_in_bind=Buscar os atributos no contexto de Bind DN
auths.use_paged_search=Use a pesquisa paginada auths.use_paged_search=Use a pesquisa paginada
auths.search_page_size=Tamanho da página auths.search_page_size=Tamanho da página
@ -1449,9 +1475,7 @@ config.db_host=Servidor
config.db_name=Nome config.db_name=Nome
config.db_user=Nome de usuário config.db_user=Nome de usuário
config.db_ssl_mode=SSL config.db_ssl_mode=SSL
config.db_ssl_mode_helper=(apenas para "postgres")
config.db_path=Caminho config.db_path=Caminho
config.db_path_helper=(para "sqlite3" e "tidb")
config.service_config=Configuração do serviço config.service_config=Configuração do serviço
config.register_email_confirm=Exigir confirmação de e-mail para se cadastrar config.register_email_confirm=Exigir confirmação de e-mail para se cadastrar

File diff suppressed because it is too large Load Diff

View File

@ -59,7 +59,6 @@ test_git_failed=Команда 'git' није успела: %v
[home] [home]
password_holder=Лозинка password_holder=Лозинка
switch_dashboard_context=Пребаците контекст контролној панели switch_dashboard_context=Пребаците контекст контролној панели
my_repos=Моја спремишта
collaborative_repos=Заједничка спремишта collaborative_repos=Заједничка спремишта
my_orgs=Моје организације my_orgs=Моје организације
my_mirrors=Моја огледала my_mirrors=Моја огледала
@ -602,9 +601,7 @@ config.db_config=Конфигурација базе података
config.db_type=Тип config.db_type=Тип
config.db_host=Хост config.db_host=Хост
config.db_name=Име config.db_name=Име
config.db_ssl_mode_helper=(само за postgres)
config.db_path=Пут config.db_path=Пут
config.db_path_helper=(за "sqlite3" и "tidb")
config.service_config=Подешавања сервиса config.service_config=Подешавања сервиса
config.show_registration_button=Прикажи дугме за регистрацију config.show_registration_button=Прикажи дугме за регистрацију

View File

@ -70,7 +70,6 @@ save_config_failed=Misslyckades att spara konfigurationen: %v
[home] [home]
password_holder=Lösenord password_holder=Lösenord
switch_dashboard_context=Växla Visad Instrumentpanel switch_dashboard_context=Växla Visad Instrumentpanel
my_repos=Mina utvecklingskataloger
collaborative_repos=Kollaborativa Utvecklingskataloger collaborative_repos=Kollaborativa Utvecklingskataloger
my_orgs=Mina organisationer my_orgs=Mina organisationer
my_mirrors=Mina speglar my_mirrors=Mina speglar
@ -739,9 +738,7 @@ config.db_config=Databaskonfiguration
config.db_type=Typ config.db_type=Typ
config.db_host=Värd config.db_host=Värd
config.db_name=Namn config.db_name=Namn
config.db_ssl_mode_helper=(endast för "postgres")
config.db_path=Sökväg config.db_path=Sökväg
config.db_path_helper=(för "sqlite3" och "tidb")
config.service_config=Tjänstkonfiguration config.service_config=Tjänstkonfiguration
config.show_registration_button=Visa registreringsknapp config.show_registration_button=Visa registreringsknapp

View File

@ -70,7 +70,6 @@ save_config_failed=%v Yapılandırması kaydedilirken hata oluştu
[home] [home]
password_holder=Parola password_holder=Parola
switch_dashboard_context=Panoya Geçiş Yap switch_dashboard_context=Panoya Geçiş Yap
my_repos=Depolarım
collaborative_repos=Katkıya Açık Depolar collaborative_repos=Katkıya Açık Depolar
my_orgs=Organizasyonlarım my_orgs=Organizasyonlarım
my_mirrors=Yansılarım my_mirrors=Yansılarım
@ -803,9 +802,7 @@ config.db_config=Veritabanı Yapılandırması
config.db_type=Türü config.db_type=Türü
config.db_host=Sunucu config.db_host=Sunucu
config.db_name=İsim config.db_name=İsim
config.db_ssl_mode_helper=(sadece "postgres" için)
config.db_path=Yol config.db_path=Yol
config.db_path_helper=("sqlite3" ve "tidb" için)
config.service_config=Servis Yapılandırması config.service_config=Servis Yapılandırması
config.show_registration_button=Kaydolma Tuşunu Göster config.show_registration_button=Kaydolma Tuşunu Göster

View File

@ -31,6 +31,8 @@ twofa=Двофакторна авторизація
twofa_scratch=Двофакторний одноразовий пароль twofa_scratch=Двофакторний одноразовий пароль
passcode=Код доступу passcode=Код доступу
u2f_insert_key=Вставте ключ безпеки
u2f_reload=Оновити
repository=Репозиторій repository=Репозиторій
organization=Організація organization=Організація
@ -71,6 +73,7 @@ host=Хост
user=Ім'я кристувача user=Ім'я кристувача
password=Пароль password=Пароль
db_name=Ім'я бази даних db_name=Ім'я бази даних
db_helper=Примітка для користувачів MySQL: будь ласка, використовуйте InnoDB механізм зберігання і набір символів 'utf8_general_ci'.
ssl_mode=SSL ssl_mode=SSL
path=Шлях path=Шлях
sqlite_helper=Шлях до файлу для бази даних SQLite3 або TiDB. <br> Введіть абсолютний шлях, якщо ви запускаєте Gitea як сервіс. sqlite_helper=Шлях до файлу для бази даних SQLite3 або TiDB. <br> Введіть абсолютний шлях, якщо ви запускаєте Gitea як сервіс.
@ -105,8 +108,11 @@ mailer_user=SMTP Ім'я кристувача
mailer_password=SMTP Пароль mailer_password=SMTP Пароль
register_confirm=Потрібно підтвердити електронну пошту для реєстрації register_confirm=Потрібно підтвердити електронну пошту для реєстрації
mail_notify=Увімкнути сповіщення електронною поштою mail_notify=Увімкнути сповіщення електронною поштою
server_service_title=Сервер і налаштування зовнішніх служб
offline_mode=Увімкнути локальний режим offline_mode=Увімкнути локальний режим
offline_mode_popup=Відключити сторонні мережі доставки контенту і обслуговувати всі ресурси локально.
disable_gravatar=Вимкнути Gravatar disable_gravatar=Вимкнути Gravatar
disable_gravatar_popup=Відключити Gravatar і сторонні джерела аватарів. Якщо користувач не завантажить аватар локально то за замовчуванням буде використовуватися стандартний аватар.
federated_avatar_lookup=Увімкнути федеративні аватари federated_avatar_lookup=Увімкнути федеративні аватари
federated_avatar_lookup_popup=Увімкнути зовнішний Аватар за допомогою Libravatar. federated_avatar_lookup_popup=Увімкнути зовнішний Аватар за допомогою Libravatar.
disable_registration=Вимкнути самостійну реєстрацію disable_registration=Вимкнути самостійну реєстрацію
@ -116,6 +122,9 @@ openid_signin_popup=Увімкнути вхід за допомогою OpenID.
openid_signup=Увімкнути самостійну реєстрацію за допомогою OpenID openid_signup=Увімкнути самостійну реєстрацію за допомогою OpenID
enable_captcha=Увімкнути CAPTCHA enable_captcha=Увімкнути CAPTCHA
enable_captcha_popup=Вимагати перевірку CAPTCHA при самостійній реєстрації користувача. enable_captcha_popup=Вимагати перевірку CAPTCHA при самостійній реєстрації користувача.
require_sign_in_view=Вимагати авторизації для перегляду сторінок
require_sign_in_view_popup=Обмеження доступу до сторінки для користувачів, які виконали вхід. Відвідувачі побачать тільки сторінки входу і реєстрації.
admin_setting_desc=Створення облікового запису адміністратора необов'язково. Перший зареєстрований користувач автоматично стає адміністратором.
admin_title=Налаштування облікового запису адміністратора admin_title=Налаштування облікового запису адміністратора
admin_name=Ім'я кристувача Адміністратора admin_name=Ім'я кристувача Адміністратора
admin_password=Пароль admin_password=Пароль
@ -124,10 +133,13 @@ admin_email=Адреса електронної пошти
install_btn_confirm=Встановлення Gitea install_btn_confirm=Встановлення Gitea
test_git_failed=Не в змозі перевірити 'git' команду: %v test_git_failed=Не в змозі перевірити 'git' команду: %v
save_config_failed=Не в змозі зберегти конфігурацію: %v save_config_failed=Не в змозі зберегти конфігурацію: %v
invalid_admin_setting=Неприпустимі налаштування облікового запису адміністратора: %v
install_success=Ласкаво просимо! Дякуємо вам за вибір Gitea. Розважайтеся, і будьте обережні! install_success=Ласкаво просимо! Дякуємо вам за вибір Gitea. Розважайтеся, і будьте обережні!
invalid_log_root_path=Неприпустимий шлях для логів: %v
default_keep_email_private=Приховати адресу електронної пошти за замовчуванням default_keep_email_private=Приховати адресу електронної пошти за замовчуванням
default_keep_email_private_popup=Приховати адресу електронної пошти нових облікових записів за замовчуванням. default_keep_email_private_popup=Приховати адресу електронної пошти нових облікових записів за замовчуванням.
default_allow_create_organization=Дозволити створення організацій за замовчуванням default_allow_create_organization=Дозволити створення організацій за замовчуванням
default_allow_create_organization_popup=Дозволити новим обліковим записам користувачів створювати організації за замовчуванням.
default_enable_timetracking=Увімкнути відстеження часу за замовчуванням default_enable_timetracking=Увімкнути відстеження часу за замовчуванням
default_enable_timetracking_popup=Включити відстеження часу для нових репозиторіїв за замовчуванням. default_enable_timetracking_popup=Включити відстеження часу для нових репозиторіїв за замовчуванням.
no_reply_address=Прихований поштовий домен no_reply_address=Прихований поштовий домен
@ -135,8 +147,8 @@ no_reply_address=Прихований поштовий домен
[home] [home]
uname_holder=Ім'я користувача або Ел. пошта uname_holder=Ім'я користувача або Ел. пошта
password_holder=Пароль password_holder=Пароль
switch_dashboard_context=Змінити дошку switch_dashboard_context=Переключити контекст панелі управління
my_repos=Мої репозиторії my_repos=Репозиторії
show_more_repos=Показати більше репозиторіїв… show_more_repos=Показати більше репозиторіїв…
collaborative_repos=Спільні репозиторії collaborative_repos=Спільні репозиторії
my_orgs=Мої організації my_orgs=Мої організації
@ -281,28 +293,34 @@ twofa=Двофакторна авторизація
account_link=Прив'язані облікові записи account_link=Прив'язані облікові записи
organization=Організації organization=Організації
uid=Ідентифікатор Uid uid=Ідентифікатор Uid
u2f=Ключі безпеки
public_profile=Загальнодоступний профіль public_profile=Загальнодоступний профіль
profile_desc=Ваша адреса електронної пошти використовуватиметься для сповіщення та інших операцій.
full_name=Повне ім'я full_name=Повне ім'я
website=Веб-сайт website=Веб-сайт
location=Місцезнаходження location=Місцезнаходження
update_profile=Оновити профіль update_profile=Оновити профіль
update_profile_success=Профіль успішно оновлено. update_profile_success=Профіль успішно оновлено.
change_username=Ваше Ім'я кристувача було змінено.
continue=Продовжити continue=Продовжити
cancel=Відміна cancel=Відміна
language=Мова language=Мова
lookup_avatar_by_mail=Знайти Аватар за адресою електронної пошти
federated_avatar_lookup=Знайти зовнішній аватар federated_avatar_lookup=Знайти зовнішній аватар
enable_custom_avatar=Увімкнути користувацькі аватари enable_custom_avatar=Увімкнути користувацькі аватари
choose_new_avatar=Оберіть новий аватар choose_new_avatar=Оберіть новий аватар
update_avatar=Оновити аватар update_avatar=Оновити аватар
delete_current_avatar=Видалити поточний аватар delete_current_avatar=Видалити поточний аватар
uploaded_avatar_not_a_image=Завантажений файл не є зображенням.
update_avatar_success=Ваш аватар був змінений. update_avatar_success=Ваш аватар був змінений.
change_password=Оновити пароль change_password=Оновити пароль
old_password=Поточний пароль old_password=Поточний пароль
new_password=Новий пароль new_password=Новий пароль
retype_new_password=Введіть новий пароль ще раз retype_new_password=Введіть новий пароль ще раз
password_incorrect=Поточний пароль неправильний.
change_password_success=Ваш пароль був оновлений. Тепер увійдіть в систему, використовуючи новий пароль. change_password_success=Ваш пароль був оновлений. Тепер увійдіть в систему, використовуючи новий пароль.
password_change_disabled=Нелокальні акаунти не можуть змінити пароль через Gitea. password_change_disabled=Нелокальні акаунти не можуть змінити пароль через Gitea.
@ -312,8 +330,10 @@ email_desc=Ваша основна адреса електронної пошт
primary=Основний primary=Основний
primary_email=Зробити основним primary_email=Зробити основним
delete_email=Видалити delete_email=Видалити
email_deletion=Видалити адресу електронної пошти
add_new_email=Додати нову адресу електронної пошти add_new_email=Додати нову адресу електронної пошти
add_email=Додати адресу електронної пошти add_email=Додати адресу електронної пошти
add_email_confirmation_sent=Електронний лист із підтвердженням було відправлено на '%s', будь ласка, перевірте вашу поштову скриньку протягом наступних %s, щоб підтвердити адресу.
keep_email_private=Приховати адресу електронної пошти keep_email_private=Приховати адресу електронної пошти
keep_email_private_popup=Вашу адресу електронної пошти буде приховано від інших користувачів. keep_email_private_popup=Вашу адресу електронної пошти буде приховано від інших користувачів.
@ -324,13 +344,17 @@ ssh_helper=<strong>Потрібна допомога?</strong> Дивіться
gpg_helper=<strong> Потрібна допомога? </strong> Перегляньте посібник GitHub <a href="%s"> про GPG </a>. gpg_helper=<strong> Потрібна допомога? </strong> Перегляньте посібник GitHub <a href="%s"> про GPG </a>.
add_new_key=Додати SSH ключ add_new_key=Додати SSH ключ
add_new_gpg_key=Додати GPG ключ add_new_gpg_key=Додати GPG ключ
subkeys=Підключі
key_id=ID ключа key_id=ID ключа
key_name=Ім'я ключа key_name=Ім'я ключа
key_content=Зміст key_content=Зміст
add_key_success=SSH ключ '%s' додано.
delete_key=Видалити delete_key=Видалити
ssh_key_deletion=Видалити SSH ключ ssh_key_deletion=Видалити SSH ключ
gpg_key_deletion=Видалити GPG ключ gpg_key_deletion=Видалити GPG ключ
gpg_key_deletion_desc=Видалення GPG ключа скасовує перевірку підписаних ним комітів. Продовжити? gpg_key_deletion_desc=Видалення GPG ключа скасовує перевірку підписаних ним комітів. Продовжити?
ssh_key_deletion_success=SSH було видалено.
gpg_key_deletion_success=GPG було видалено.
add_on=Додано add_on=Додано
valid_until=Дійсний до valid_until=Дійсний до
valid_forever=Дійсний завжди valid_forever=Дійсний завжди
@ -350,17 +374,21 @@ unbind=Від'єднати
manage_access_token=Керування токенами доступу manage_access_token=Керування токенами доступу
generate_new_token=Згенерувати новий токен generate_new_token=Згенерувати новий токен
tokens_desc=Ці токени надають доступ до вашого облікового запису за допомогою Gitea API. tokens_desc=Ці токени надають доступ до вашого облікового запису за допомогою Gitea API.
new_token_desc=Додатки, що використовують токен, мають повний доступ до вашого облікового запису.
token_name=Ім'я токену token_name=Ім'я токену
generate_token=Згенерувати токен generate_token=Згенерувати токен
delete_token=Видалити delete_token=Видалити
access_token_deletion=Видалити токен доступу
twofa_disable=Вимкнути двофакторну автентифікацію twofa_disable=Вимкнути двофакторну автентифікацію
or_enter_secret=Або введіть секрет: %s or_enter_secret=Або введіть секрет: %s
u2f_nickname=Псевдонім
manage_account_links=Керування обліковими записами manage_account_links=Керування обліковими записами
remove_account_link=Видалити облікові записи remove_account_link=Видалити облікові записи
orgs_none=Ви не є учасником будь-якої організації.
delete_account=Видалити ваш обліковий запис delete_account=Видалити ваш обліковий запис
confirm_delete_account=Підтвердження видалення confirm_delete_account=Підтвердження видалення
@ -374,6 +402,7 @@ visiblity_helper=Зробити репозиторій приватним
clone_helper=Потрібна допомога у клонуванні? Відвідайте <a target="_blank" rel="noopener" href="%s">Допомогу</a>. clone_helper=Потрібна допомога у клонуванні? Відвідайте <a target="_blank" rel="noopener" href="%s">Допомогу</a>.
fork_repo=Форкнути репозиторій fork_repo=Форкнути репозиторій
fork_from=Форк з fork_from=Форк з
fork_visiblity_helper=Видимість форкнутого репозиторію змінити не можна.
repo_desc=Опис repo_desc=Опис
repo_lang=Мова repo_lang=Мова
repo_gitignore_helper=Виберіть шаблон .gitignore. repo_gitignore_helper=Виберіть шаблон .gitignore.
@ -388,22 +417,27 @@ mirror_interval=Інтервал дзеркалювання (доступні з
mirror_address=Клонування з URL-адреси mirror_address=Клонування з URL-адреси
mirror_last_synced=Остання синхронізація mirror_last_synced=Остання синхронізація
watchers=Спостерігачі watchers=Спостерігачі
stargazers=Зацікавлені
forks=Форки forks=Форки
pick_reaction=Залиште свою оцінку pick_reaction=Залиште свою оцінку
reactions_more=додати %d більше
form.reach_limit_of_creation=Ви досягли максимальної кількості %d створених репозиторіїв. form.reach_limit_of_creation=Ви досягли максимальної кількості %d створених репозиторіїв.
need_auth=Клонування авторизації need_auth=Клонувати з авторизацією
migrate_type=Тип міграції migrate_type=Тип міграції
migrate_type_helper=Даний репозиторій буде <span class="text blue">дзеркалом</span> migrate_type_helper=Даний репозиторій буде <span class="text blue">дзеркалом</span>
migrate_repo=Перенесення репозиторія migrate_repo=Перенести репозиторій
migrate.clone_address=Міграція / клонувати з URL-адреси migrate.clone_address=Міграція / клонувати з URL-адреси
migrate.clone_address_desc=URL-адреса HTTP(S) або Git "clone" існуючого репозиторія migrate.clone_address_desc=URL-адреса HTTP(S) або Git "clone" існуючого репозиторія
migrate.clone_local_path=або шлях до локального серверу
migrate.permission_denied=Вам не дозволено імпортувати локальні репозиторії.
migrate.failed=Міграція не вдалася: %v migrate.failed=Міграція не вдалася: %v
migrate.lfs_mirror_unsupported=Дзеркалювання LFS об'єктів не підтримується - використовуйте 'git lfs fetch --all' і 'git lfs push --all' вручну. migrate.lfs_mirror_unsupported=Дзеркалювання LFS об'єктів не підтримується - використовуйте 'git lfs fetch --all' і 'git lfs push --all' вручну.
mirror_from=дзеркало mirror_from=дзеркало
forked_from=форк від forked_from=форк від
fork_from_self=Ви не можете форкнути репозиторій, так як ви його власник.
copy_link=Копіювати copy_link=Копіювати
copy_link_error=Натисніть ⌘-C або Ctrl-C, щоб скопіювати copy_link_error=Натисніть ⌘-C або Ctrl-C, щоб скопіювати
copied=Скопійовано copied=Скопійовано
@ -432,7 +466,7 @@ pulls=Запити на злиття
labels=Мітки labels=Мітки
milestones=Етап milestones=Етап
commits=Коміти commits=Коміти
commit=Змина commit=Коміт
releases=Релізи releases=Релізи
file_raw=Неформатований file_raw=Неформатований
file_history=Історія file_history=Історія
@ -447,8 +481,10 @@ editor.edit_file=Редагування файлу
editor.preview_changes=Попередній перегляд змін editor.preview_changes=Попередній перегляд змін
editor.edit_this_file=Редагувати файл editor.edit_this_file=Редагувати файл
editor.must_be_on_a_branch=Ви повинні бути у гілці щоб зробити, або запропонувати зміни до цього файлу. editor.must_be_on_a_branch=Ви повинні бути у гілці щоб зробити, або запропонувати зміни до цього файлу.
editor.fork_before_edit=Необхідно зробити форк цього репозиторій, щоб внести або запропонувати зміни в цей файл.
editor.delete_this_file=Видалити файл editor.delete_this_file=Видалити файл
editor.must_have_write_access=Ви повинні мати доступ на запис щоб запропонувати зміни до цього файлу. editor.must_have_write_access=Ви повинні мати доступ на запис щоб запропонувати зміни до цього файлу.
editor.file_delete_success=Файл '%s' видалено.
editor.name_your_file=Дайте назву файлу… editor.name_your_file=Дайте назву файлу…
editor.or=або editor.or=або
editor.cancel_lower=Скасувати editor.cancel_lower=Скасувати
@ -463,7 +499,9 @@ editor.create_new_branch=Створити <strong>нову гілку</strong>
editor.new_branch_name_desc=Ім'я нової гілки… editor.new_branch_name_desc=Ім'я нової гілки…
editor.cancel=Відміна editor.cancel=Відміна
editor.branch_already_exists=Гілка '%s' вже присутня в репозиторії. editor.branch_already_exists=Гілка '%s' вже присутня в репозиторії.
editor.no_changes_to_show=Нема змін для показу.
editor.fail_to_update_file=Не вдалося оновити/створити файл '%s' через помилку: %v editor.fail_to_update_file=Не вдалося оновити/створити файл '%s' через помилку: %v
editor.add_subdir=Додати каталог…
editor.unable_to_upload_files=Не вдалося завантажити файли до '%s' через помилку: %v editor.unable_to_upload_files=Не вдалося завантажити файли до '%s' через помилку: %v
editor.upload_files_to_dir=Завантажувати файли до '%s' editor.upload_files_to_dir=Завантажувати файли до '%s'
@ -497,6 +535,7 @@ issues.new_label=Нова мітка
issues.new_label_placeholder=Назва мітки issues.new_label_placeholder=Назва мітки
issues.new_label_desc_placeholder=Опис issues.new_label_desc_placeholder=Опис
issues.create_label=Створити мітку issues.create_label=Створити мітку
issues.label_templates.title=Завантажити визначений набір міток
issues.label_templates.helper=Оберіть набір міток issues.label_templates.helper=Оберіть набір міток
issues.label_templates.fail_to_load_file=Не вдалося завантажити файл шаблона мітки '%s': %v issues.label_templates.fail_to_load_file=Не вдалося завантажити файл шаблона мітки '%s': %v
issues.add_label_at=додав(ла) мітку <div class="ui label" style="color: %s\; background-color: %s">%s</div> %s issues.add_label_at=додав(ла) мітку <div class="ui label" style="color: %s\; background-color: %s">%s</div> %s
@ -525,6 +564,7 @@ issues.filter_sort.recentupdate=Нещодавно оновлено
issues.filter_sort.leastupdate=Найдавніше оновлені issues.filter_sort.leastupdate=Найдавніше оновлені
issues.filter_sort.mostcomment=Найбільш коментовані issues.filter_sort.mostcomment=Найбільш коментовані
issues.filter_sort.leastcomment=Найменш коментовані issues.filter_sort.leastcomment=Найменш коментовані
issues.filter_sort.mostforks=Найбільше форків
issues.action_open=Відкрити issues.action_open=Відкрити
issues.action_close=Закрити issues.action_close=Закрити
issues.action_label=Мітка issues.action_label=Мітка
@ -536,7 +576,7 @@ issues.opened_by=%[1]s відкрито <a href="%[2]s">%[3]s</a>
issues.opened_by_fake=%[1]s відкрито %[2]s issues.opened_by_fake=%[1]s відкрито %[2]s
issues.previous=Попередній issues.previous=Попередній
issues.next=Далі issues.next=Далі
issues.open_title=Відкрити issues.open_title=Відкрито
issues.closed_title=Закрито issues.closed_title=Закрито
issues.num_comments=%d коментарів issues.num_comments=%d коментарів
issues.commented_at=`прокоментував(ла) <a href="#%s">%s</a>` issues.commented_at=`прокоментував(ла) <a href="#%s">%s</a>`
@ -550,6 +590,7 @@ issues.create_comment=Коментар
issues.closed_at=`закрито <a id="%[1]s" href="#%[1]s">%[2]s</a>` issues.closed_at=`закрито <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.reopened_at=`повторно відкрито <a id="%[1]s" href="#%[1]s">%[2]s</a>` issues.reopened_at=`повторно відкрито <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.commit_ref_at=`згадано цю проблему в коміті <a id="%[1]s" href="#%[1]s">%[2]s</a>` issues.commit_ref_at=`згадано цю проблему в коміті <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.poster=Автор
issues.collaborator=Співавтор issues.collaborator=Співавтор
issues.owner=Власник issues.owner=Власник
issues.sign_in_require_desc=<a href="%s">Підпишіться</a> щоб приєднатися до обговорення. issues.sign_in_require_desc=<a href="%s">Підпишіться</a> щоб приєднатися до обговорення.
@ -571,6 +612,7 @@ issues.label.filter_sort.by_size=Розмір
issues.label.filter_sort.reverse_by_size=Зворотний розмір issues.label.filter_sort.reverse_by_size=Зворотний розмір
issues.num_participants=%d учасників issues.num_participants=%d учасників
issues.attachment.open_tab=`Натисніть щоб побачити "%s" у новій вкладці` issues.attachment.open_tab=`Натисніть щоб побачити "%s" у новій вкладці`
issues.attachment.download=`Натисніть щоб завантажити "%s"`
issues.subscribe=Підписатися issues.subscribe=Підписатися
issues.unsubscribe=Відписатися issues.unsubscribe=Відписатися
issues.tracker=Відстеження часу issues.tracker=Відстеження часу
@ -586,12 +628,17 @@ issues.add_time_hours=Години
issues.add_time_minutes=Хвилини issues.add_time_minutes=Хвилини
issues.add_time_sum_to_small=Час не введено. issues.add_time_sum_to_small=Час не введено.
issues.cancel_tracking=Відміна issues.cancel_tracking=Відміна
issues.cancel_tracking_history=`скасував відстеження часу %s`
issues.time_spent_total=Загальний витрачений час issues.time_spent_total=Загальний витрачений час
issues.time_spent_from_all_authors=`Загальний витрачений час: %s` issues.time_spent_from_all_authors=`Загальний витрачений час: %s`
issues.due_date=Дата завершення issues.due_date=Дата завершення
issues.due_date_form=рррр-мм-дд
issues.due_date_form_add=Додати дату завершення issues.due_date_form_add=Додати дату завершення
issues.due_date_form_update=Оновити дату завершення
issues.due_date_form_remove=Видалити дату завершення issues.due_date_form_remove=Видалити дату завершення
issues.due_date_not_set=Термін виконання не встановлений. issues.due_date_not_set=Термін виконання не встановлений.
issues.due_date_added=додав(ла) дату завершення %s %s
issues.due_date_overdue=Прострочено
pulls.new=Новий запит на злиття pulls.new=Новий запит на злиття
pulls.compare_changes=Новий запит на злиття pulls.compare_changes=Новий запит на злиття
@ -610,8 +657,13 @@ pulls.reopen_to_merge=Будь ласка перевідкрийте цей за
pulls.merged=Злито pulls.merged=Злито
pulls.has_merged=Запит на злиття було об'єднано. pulls.has_merged=Запит на злиття було об'єднано.
pulls.can_auto_merge_desc=Цей запит можна об'єднати автоматично. pulls.can_auto_merge_desc=Цей запит можна об'єднати автоматично.
pulls.cannot_auto_merge_desc=Цей запит на злиття не може бути злитий автоматично через конфлікти.
pulls.cannot_auto_merge_helper=Злийте вручну для вирішення конфліктів.
pulls.no_merge_desc=Цей запити на злиття неможливо злити, оскільки всі параметри об'єднання репозиторія вимкнено.
pulls.no_merge_helper=Увімкніть параметри злиття в налаштуваннях репозиторія або злийте запити на злиття вручну.
pulls.merge_pull_request=Об'єднати запит на злиття pulls.merge_pull_request=Об'єднати запит на злиття
pulls.squash_merge_pull_request=Об'єднати і злити pulls.rebase_merge_pull_request=Зробити Rebase і злити
pulls.squash_merge_pull_request=Об'єднати (Squash) і злити
milestones.new=Новий етап milestones.new=Новий етап
milestones.open_tab=%d відкрито milestones.open_tab=%d відкрито
@ -629,6 +681,8 @@ milestones.edit=Редагувати етап
milestones.cancel=Відміна milestones.cancel=Відміна
milestones.modify=Оновити етап milestones.modify=Оновити етап
milestones.deletion=Видалити етап milestones.deletion=Видалити етап
milestones.filter_sort.most_issues=Найбільш проблем
milestones.filter_sort.least_issues=Найменш проблем
ext_wiki=Зов. Вікі ext_wiki=Зов. Вікі
@ -691,7 +745,7 @@ search.search_repo=Пошук репозиторію
settings=Налаштування settings=Налаштування
settings.options=Репозиторій settings.options=Репозиторій
settings.collaboration=Співробітники settings.collaboration=Співавтори
settings.collaboration.admin=Адміністратор settings.collaboration.admin=Адміністратор
settings.collaboration.write=Запис settings.collaboration.write=Запис
settings.collaboration.read=Читати settings.collaboration.read=Читати
@ -709,11 +763,15 @@ settings.use_internal_wiki=Використовувати вбудовані В
settings.use_external_wiki=Використовувати зовнішні Вікі settings.use_external_wiki=Використовувати зовнішні Вікі
settings.external_wiki_url=URL зовнішньої вікі settings.external_wiki_url=URL зовнішньої вікі
settings.issues_desc=Увімкнути відстеження проблем в репозиторію settings.issues_desc=Увімкнути відстеження проблем в репозиторію
settings.use_internal_issue_tracker=Використовувати вбудовану систему відстеження проблем
settings.external_tracker_url=URL зовнішньої системи відстеження проблем settings.external_tracker_url=URL зовнішньої системи відстеження проблем
settings.tracker_url_format=Формат URL зовнішнього трекера задач settings.tracker_url_format=Формат URL зовнішнього трекера задач
settings.tracker_issue_style.numeric=Цифровий settings.tracker_issue_style.numeric=Цифровий
settings.tracker_issue_style.alphanumeric=Буквено-цифровий settings.tracker_issue_style.alphanumeric=Буквено-цифровий
settings.enable_timetracker=Увімкнути відстеження часу settings.enable_timetracker=Увімкнути відстеження часу
settings.pulls_desc=Увімкнути запити на злиття в репозиторій
settings.pulls.ignore_whitespace=Ігнорувати пробіл у конфліктах
settings.pulls.allow_rebase_merge=Увімкнути Rebasing коміти перед злиттям
settings.pulls.allow_squash_commits=Увімкнути об'єднувати коміти перед злиттям settings.pulls.allow_squash_commits=Увімкнути об'єднувати коміти перед злиттям
settings.admin_settings=Налаштування адміністратора settings.admin_settings=Налаштування адміністратора
settings.admin_enable_health_check=Включити перевірки працездатності репозиторію (git fsck) settings.admin_enable_health_check=Включити перевірки працездатності репозиторію (git fsck)
@ -721,16 +779,22 @@ settings.danger_zone=Небезпечна зона
settings.new_owner_has_same_repo=Новий власник вже має репозиторій з такою назвою. Будь ласка, виберіть інше ім'я. settings.new_owner_has_same_repo=Новий власник вже має репозиторій з такою назвою. Будь ласка, виберіть інше ім'я.
settings.convert=Перетворити на звичайний репозиторій settings.convert=Перетворити на звичайний репозиторій
settings.convert_desc=Ви можете сконвертувати це дзеркало у звичайний репозиторій. Це не може бути скасовано. settings.convert_desc=Ви можете сконвертувати це дзеркало у звичайний репозиторій. Це не може бути скасовано.
settings.convert_confirm=Перетворити репозиторій
settings.transfer=Передати новому власнику settings.transfer=Передати новому власнику
settings.transfer_form_title=Введіть ім'я репозиторія як підтвердження:
settings.wiki_delete=Видалити вікі-дані settings.wiki_delete=Видалити вікі-дані
settings.confirm_wiki_delete=Видалити Вікі-дані settings.confirm_wiki_delete=Видалити Вікі-дані
settings.delete=Видалити цей репозиторій settings.delete=Видалити цей репозиторій
settings.delete_notices_1=- Цю операцію <strong>НЕ МОЖНА</strong> відмінити. settings.delete_notices_1=- Цю операцію <strong>НЕ МОЖНА</strong> відмінити.
settings.deletion_success=Репозиторій успішно видалено.
settings.update_settings_success=Налаштування репозиторію було оновлено. settings.update_settings_success=Налаштування репозиторію було оновлено.
settings.transfer_owner=Новий власник settings.transfer_owner=Новий власник
settings.make_transfer=Здіснити перенесення settings.make_transfer=Здіснити перенесення
settings.confirm_delete=Видалити репозиторій settings.confirm_delete=Видалити репозиторій
settings.add_collaborator=Додати співавтора
settings.add_collaborator_success=Додано співавтора.
settings.delete_collaborator=Видалити settings.delete_collaborator=Видалити
settings.collaborator_deletion=Видалити співавтора
settings.search_user_placeholder=Пошук користувача… settings.search_user_placeholder=Пошук користувача…
settings.add_webhook=Додати веб-хук settings.add_webhook=Додати веб-хук
settings.webhook_deletion=Видалити веб-хук settings.webhook_deletion=Видалити веб-хук
@ -744,12 +808,14 @@ settings.webhook.body=Тіло
settings.githook_name=Ім'я хуку settings.githook_name=Ім'я хуку
settings.githook_content=Зміст хука settings.githook_content=Зміст хука
settings.update_githook=Оновити хук settings.update_githook=Оновити хук
settings.payload_url=Цільова URL-адреса
settings.secret=Секрет settings.secret=Секрет
settings.slack_username=Ім'я кристувача settings.slack_username=Ім'я кристувача
settings.slack_icon_url=URL іконки settings.slack_icon_url=URL іконки
settings.discord_username=Ім'я кристувача settings.discord_username=Ім'я кристувача
settings.discord_icon_url=URL іконки settings.discord_icon_url=URL іконки
settings.slack_color=Колір settings.slack_color=Колір
settings.event_desc=Тригер:
settings.event_push_only=Push події settings.event_push_only=Push події
settings.event_send_everything=Всі події settings.event_send_everything=Всі події
settings.event_choose=Власні події… settings.event_choose=Власні події…
@ -758,19 +824,31 @@ settings.event_create_desc=Гілку або тег створено.
settings.event_delete=Видалити settings.event_delete=Видалити
settings.event_delete_desc=Гілку або мітку було видалено settings.event_delete_desc=Гілку або мітку було видалено
settings.event_fork=Форк settings.event_fork=Форк
settings.event_fork_desc=Репозиторій було форкнуто
settings.event_issues=Проблеми settings.event_issues=Проблеми
settings.event_issues_desc=Проблему відкрито, закрито, перевідкрито, відредаговано, призначено, відкріплено, змінено мітку, очищено мітку, створено етап, очищено етап.
settings.event_issue_comment=Коментар проблеми
settings.event_issue_comment_desc=Коментар проблеми створено, видалено чи відредаговано.
settings.event_release=Реліз settings.event_release=Реліз
settings.event_pull_request=Запити до злиття settings.event_pull_request=Запити до злиття
settings.event_pull_request_desc=Запит до злиття відкрито, закрито, перевідкрито, змінено, призначено, знято, мітку оновлено, мітку прибрано або синхронізовано.
settings.event_push=Push settings.event_push=Push
settings.event_push_desc=Git push до репозиторію.
settings.event_repository=Репозиторій settings.event_repository=Репозиторій
settings.event_repository_desc=Репозиторій створений або видалено. settings.event_repository_desc=Репозиторій створений або видалено.
settings.active=Додавати інформацію про події settings.active=Додавати інформацію про події
settings.add_hook_success=Веб-хук було додано.
settings.update_webhook=Оновити веб-хук settings.update_webhook=Оновити веб-хук
settings.update_hook_success=Веб-хук було оновлено.
settings.delete_webhook=Видалити веб-хук
settings.recent_deliveries=Недавні розсилки settings.recent_deliveries=Недавні розсилки
settings.hook_type=Тип хука settings.hook_type=Тип хука
settings.add_slack_hook_desc=Інтеграція <a href="%s">Slack</a> у ваш репозиторії.
settings.slack_token=Токен settings.slack_token=Токен
settings.slack_domain=Домен settings.slack_domain=Домен
settings.slack_channel=Канал settings.slack_channel=Канал
settings.add_discord_hook_desc=Інтеграція <a href="%s">Discord</a> у ваш репозиторії.
settings.add_dingtalk_hook_desc=Інтеграція <a href="%s">Dingtalk</a> у ваш репозиторії.
settings.deploy_keys=Ключі для розгортування settings.deploy_keys=Ключі для розгортування
settings.add_deploy_key=Додати ключ для розгортування settings.add_deploy_key=Додати ключ для розгортування
settings.is_writable=Увімкнути доступ для запису settings.is_writable=Увімкнути доступ для запису
@ -782,9 +860,11 @@ settings.protected_branch_can_push=Дозволити push?
settings.protected_branch_can_push_yes=Ви можете виконувати push settings.protected_branch_can_push_yes=Ви можете виконувати push
settings.protected_branch_can_push_no=Ви не можете виконувати push settings.protected_branch_can_push_no=Ви не можете виконувати push
settings.protect_whitelist_search_users=Пошук користувачів… settings.protect_whitelist_search_users=Пошук користувачів…
settings.protect_whitelist_search_teams=Пошук команд…
settings.add_protected_branch=Увімкнути захист settings.add_protected_branch=Увімкнути захист
settings.delete_protected_branch=Вимкнути захист settings.delete_protected_branch=Вимкнути захист
settings.choose_branch=Оберіть гілку… settings.choose_branch=Оберіть гілку…
settings.no_protected_branch=Немає захищених гілок.
diff.browse_source=Переглянути джерело diff.browse_source=Переглянути джерело
diff.parent=джерело diff.parent=джерело
@ -793,7 +873,9 @@ diff.show_diff_stats=Показати статистику Diff
diff.show_split_view=Розділений перегляд diff.show_split_view=Розділений перегляд
diff.show_unified_view=Об'єднаний перегляд diff.show_unified_view=Об'єднаний перегляд
diff.stats_desc=<strong> %d змінених файлів</strong> з <strong>%d додано</strong> та <strong>%d видалено</strong> diff.stats_desc=<strong> %d змінених файлів</strong> з <strong>%d додано</strong> та <strong>%d видалено</strong>
diff.bin=BIN
diff.view_file=Переглянути файл diff.view_file=Переглянути файл
diff.file_suppressed=Різницю між файлами не показано, бо вона завелика
diff.too_many_files=Деякі файли не було показано, через те що забагато файлів було змінено diff.too_many_files=Деякі файли не було показано, через те що забагато файлів було змінено
release.releases=Релізи release.releases=Релізи
@ -803,6 +885,7 @@ release.prerelease=Пре-реліз
release.stable=Стабільний release.stable=Стабільний
release.edit=редагувати release.edit=редагувати
release.ahead=<strong>%d</strong> комітів %s після цього релізу release.ahead=<strong>%d</strong> комітів %s після цього релізу
release.source_code=Код
release.tag_name=Назва тегу release.tag_name=Назва тегу
release.target=Ціль release.target=Ціль
release.tag_helper=Виберіть існуючий тег або створіть новий. release.tag_helper=Виберіть існуючий тег або створіть новий.
@ -821,10 +904,13 @@ release.delete_release=Видалити реліз
release.deletion=Видалити реліз release.deletion=Видалити реліз
release.downloads=Завантажити release.downloads=Завантажити
branch.name=Ім'я гілки
branch.search=Пошук гілок
branch.delete_head=Видалити branch.delete_head=Видалити
branch.delete=Видалити гілку '%s' branch.delete=Видалити гілку '%s'
branch.delete_html=Видалити гілку branch.delete_html=Видалити гілку
branch.create_from=з '%s' branch.create_from=з '%s'
branch.branch_already_exists=Гілка '%s' вже присутня в репозиторії.
branch.deleted_by=Видалено %s branch.deleted_by=Видалено %s
topic.manage_topics=Керувати тематичними мітками topic.manage_topics=Керувати тематичними мітками
@ -844,6 +930,7 @@ create_team=Створити команду
org_desc=Опис org_desc=Опис
team_name=Назва команди team_name=Назва команди
team_desc=Опис team_desc=Опис
team_name_helper=Назва команди має бути простою та зрозумілою.
team_permission_desc=Права доступу team_permission_desc=Права доступу
team_unit_desc=Дозволити доступ до розділів репозиторію team_unit_desc=Дозволити доступ до розділів репозиторію
@ -857,8 +944,10 @@ settings.update_settings=Оновити налаштування
settings.delete=Видалити організацію settings.delete=Видалити організацію
settings.delete_account=Видалити цю організацію settings.delete_account=Видалити цю організацію
settings.confirm_delete_account=Підтвердіть видалення settings.confirm_delete_account=Підтвердіть видалення
settings.delete_org_title=Видалити організацію
members.membership_visibility=Видимість учасника: members.membership_visibility=Видимість учасника:
members.public=Показувати
members.public_helper=зробити прихованим members.public_helper=зробити прихованим
members.private=Прихований members.private=Прихований
members.private_helper=зробити видимим members.private_helper=зробити видимим
@ -875,13 +964,22 @@ teams.leave=Покинути
teams.read_access=Доступ для читання teams.read_access=Доступ для читання
teams.write_access=Доступ на запис teams.write_access=Доступ на запис
teams.admin_access=Доступ адміністратора teams.admin_access=Доступ адміністратора
teams.no_desc=Ця команда не має опису
teams.settings=Налаштування teams.settings=Налаштування
teams.owners_permission_desc=Власник має повний доступ до <strong>усіх репозиторіїв</strong> та має <strong>права адміністратора</strong> організації.
teams.members=Учасники команди teams.members=Учасники команди
teams.update_settings=Оновити налаштування teams.update_settings=Оновити налаштування
teams.delete_team=Видалити команду
teams.add_team_member=Додати учасника команди teams.add_team_member=Додати учасника команди
teams.delete_team_title=Видалити команду
teams.read_permission_desc=Ця команда має доступ для <strong>читання</strong>: учасники можуть переглядати та клонувати репозиторії.
teams.write_permission_desc=Ця команда надає доступ на <strong>запис</strong>: учасники можуть отримувати й виконувати push команди до репозитрію. teams.write_permission_desc=Ця команда надає доступ на <strong>запис</strong>: учасники можуть отримувати й виконувати push команди до репозитрію.
teams.admin_permission_desc=Ця команда надає <strong>адміністраторський</strong> доступ: учасники можуть читати, виконувати push команди та додавати співробітників до репозиторію.
teams.repositories=Репозиторії команди
teams.search_repo_placeholder=Пошук репозиторію…
teams.add_team_repository=Додати репозиторій команди teams.add_team_repository=Додати репозиторій команди
teams.remove_repo=Видалити teams.remove_repo=Видалити
teams.add_nonexistent_repo=Ви намагаєтеся додати у репозиторій якого не існує. Будь ласка, спочатку створіть його.
[admin] [admin]
dashboard=Панель управління dashboard=Панель управління
@ -897,17 +995,25 @@ last_page=Остання
total=Разом: %d total=Разом: %d
dashboard.statistic=Підсумок dashboard.statistic=Підсумок
dashboard.operations=Технічне обслуговування
dashboard.system_status=Статус системи dashboard.system_status=Статус системи
dashboard.operation_name=Назва операції dashboard.operation_name=Назва операції
dashboard.operation_switch=Перемкнути dashboard.operation_switch=Перемкнути
dashboard.operation_run=Запустити dashboard.operation_run=Запустити
dashboard.delete_inactivate_accounts=Видалити всі неактивні облікові записи dashboard.delete_inactivate_accounts=Видалити всі неактивні облікові записи
dashboard.delete_inactivate_accounts_success=Усі неактивні облікові записи успішно видалено. dashboard.delete_inactivate_accounts_success=Усі неактивні облікові записи успішно видалено.
dashboard.delete_repo_archives=Видалити всі архіви репозиторіїв
dashboard.git_gc_repos_success=Всі репозиторії завершили збирання сміття. dashboard.git_gc_repos_success=Всі репозиторії завершили збирання сміття.
dashboard.server_uptime=Uptime серверу dashboard.server_uptime=Uptime серверу
dashboard.current_memory_usage=Поточне використання пам'яті dashboard.current_memory_usage=Поточне використання пам'яті
dashboard.total_memory_allocated=Виділено пам'яті загалом dashboard.total_memory_allocated=Виділено пам'яті загалом
dashboard.memory_obtained=Отримано пам'яті dashboard.memory_obtained=Отримано пам'яті
dashboard.current_heap_usage=Поточне використання динамічної пам'яті
dashboard.heap_memory_obtained=Отримано динамічної пам'яті
dashboard.heap_memory_idle=Не використовується динамічною пам'яттю
dashboard.heap_memory_in_use=Використовується динамічною пам'яттю
dashboard.heap_memory_released=Звільнено динамічної пам'яті
dashboard.heap_objects=Об'єктів динамічної пам'яті
dashboard.stack_memory_obtained=Зайнято пам'яті стеком dashboard.stack_memory_obtained=Зайнято пам'яті стеком
dashboard.mspan_structures_usage=Використання структур MSpan dashboard.mspan_structures_usage=Використання структур MSpan
dashboard.mspan_structures_obtained=Отримано структур MSpan dashboard.mspan_structures_obtained=Отримано структур MSpan
@ -953,11 +1059,13 @@ orgs.teams=Команди
orgs.members=Учасники orgs.members=Учасники
orgs.new_orga=Нова організація orgs.new_orga=Нова організація
repos.repo_manage_panel=Керування організаціями repos.repo_manage_panel=Керування репозиторіями
repos.owner=Власник repos.owner=Власник
repos.name=Назва repos.name=Назва
repos.private=Приватний repos.private=Приватний
repos.watches=Стежать
repos.stars=В обраному repos.stars=В обраному
repos.forks=Форки
repos.issues=Проблеми repos.issues=Проблеми
repos.size=Розмір repos.size=Розмір
@ -973,6 +1081,10 @@ auths.security_protocol=Протокол безпеки
auths.domain=Домен auths.domain=Домен
auths.host=Хост auths.host=Хост
auths.port=Порт auths.port=Порт
auths.user_base=База пошуку користувачів
auths.user_dn=DN користувача
auths.search_page_size=Розмір сторінки
auths.filter=Користувацький фільтр
auths.admin_filter=Фільтр адміністратора auths.admin_filter=Фільтр адміністратора
auths.smtp_auth=Тип автентифікації SMTP auths.smtp_auth=Тип автентифікації SMTP
auths.smtphost=SMTP хост auths.smtphost=SMTP хост
@ -980,6 +1092,8 @@ auths.smtpport=SMTP порт
auths.allowed_domains=Дозволені домени auths.allowed_domains=Дозволені домени
auths.enable_tls=Увімкнути TLS-шифрування auths.enable_tls=Увімкнути TLS-шифрування
auths.skip_tls_verify=Пропустити перевірку TLS auths.skip_tls_verify=Пропустити перевірку TLS
auths.pam_service_name=Ім'я служби PAM
auths.oauth2_provider=Постачальник OAuth2
auths.oauth2_clientSecret=Ключ клієнта auths.oauth2_clientSecret=Ключ клієнта
auths.oauth2_tokenURL=URL токену auths.oauth2_tokenURL=URL токену
auths.oauth2_authURL=URL авторизації auths.oauth2_authURL=URL авторизації
@ -1006,6 +1120,7 @@ config.app_ver=Версія Gitea
config.app_url=Базова URL-адреса Gitea config.app_url=Базова URL-адреса Gitea
config.custom_conf=Шлях до файлу конфігурації config.custom_conf=Шлях до файлу конфігурації
config.domain=Домен SSH сервера config.domain=Домен SSH сервера
config.offline_mode=Локальний режим
config.disable_router_log=Вимкнути логування роутеру config.disable_router_log=Вимкнути логування роутеру
config.run_user=Запуск від імені Користувача config.run_user=Запуск від імені Користувача
config.run_mode=Режим виконання config.run_mode=Режим виконання
@ -1033,9 +1148,7 @@ config.db_host=Хост
config.db_name=Ім'я config.db_name=Ім'я
config.db_user=Ім'я кристувача config.db_user=Ім'я кристувача
config.db_ssl_mode=SSL config.db_ssl_mode=SSL
config.db_ssl_mode_helper=(тільки для "postgres")
config.db_path=Шлях config.db_path=Шлях
config.db_path_helper=(для "sqlite3" і "tidb")
config.service_config=Конфігурація сервісу config.service_config=Конфігурація сервісу
config.register_email_confirm=Потрібно підтвердити електронну пошту для реєстрації config.register_email_confirm=Потрібно підтвердити електронну пошту для реєстрації
@ -1043,6 +1156,7 @@ config.disable_register=Вимкнути самостійну реєстраці
config.enable_openid_signup=Увімкнути самостійну реєстрацію за допомогою OpenID config.enable_openid_signup=Увімкнути самостійну реєстрацію за допомогою OpenID
config.enable_openid_signin=Увімкнути реєстрацію за допомогою OpenID config.enable_openid_signin=Увімкнути реєстрацію за допомогою OpenID
config.show_registration_button=Показувати кнопку "Реєстрація config.show_registration_button=Показувати кнопку "Реєстрація
config.require_sign_in_view=Вимагати авторизації для перегляду сторінок
config.mail_notify=Увімкнути сповіщення електронною поштою config.mail_notify=Увімкнути сповіщення електронною поштою
config.disable_key_size_check=Вимкнути перевірку мінімального розміру ключа config.disable_key_size_check=Вимкнути перевірку мінімального розміру ключа
config.enable_captcha=Увімкнути CAPTCHA config.enable_captcha=Увімкнути CAPTCHA
@ -1065,6 +1179,7 @@ config.mailer_user=Користувач
config.mailer_use_sendmail=Використовувати Sendmail config.mailer_use_sendmail=Використовувати Sendmail
config.mailer_sendmail_path=Шлях до Sendmail config.mailer_sendmail_path=Шлях до Sendmail
config.send_test_mail=Відправити тестового листа config.send_test_mail=Відправити тестового листа
config.test_mail_sent=Тестового листа було відправлено до '%s'.
config.oauth_config=Конфігурація OAuth config.oauth_config=Конфігурація OAuth
config.oauth_enabled=Увімкнено config.oauth_enabled=Увімкнено
@ -1124,19 +1239,20 @@ notices.type=Тип
notices.type_1=Репозиторій notices.type_1=Репозиторій
notices.desc=Опис notices.desc=Опис
notices.op=Оп. notices.op=Оп.
notices.delete_success=Сповіщення системи були видалені.
[action] [action]
create_repo=створено репозиторій <a href="%s">%s</a> create_repo=створив(ла) репозиторій <a href="%s">%s</a>
rename_repo=репозиторій перейменовано з <code>%[1]s</code> на <a href="%[2]s">%[3]s</a> rename_repo=репозиторій перейменовано з <code>%[1]s</code> на <a href="%[2]s">%[3]s</a>
commit_repo=виконав(ла) push в <a href="%[1]s/src/%[2]s">%[3]s</a> у <a href="%[1]s">%[4]s</a> commit_repo=виконав(ла) push в <a href="%[1]s/src/%[2]s">%[3]s</a> у <a href="%[1]s">%[4]s</a>
create_issue=`відкрив(ла) проблему <a href="%s/issues/%s">%s#%[2]s</a>` create_issue=`відкрив(ла) проблему <a href="%s/issues/%s">%s#%[2]s</a>`
close_issue=`закрито проблему <a href="%s/issues/%s">%s#%[2]s</a>` close_issue=`закрито проблему <a href="%s/issues/%s">%s#%[2]s</a>`
reopen_issue=`повторно відкрив(ла) проблему <a href="%s/issues/%s">%s#%[2]s</a>` reopen_issue=`повторно відкрив(ла) проблему <a href="%s/issues/%s">%s#%[2]s</a>`
create_pull_request=`створено запити на злиття <a href="%s/pulls/%s">%s#%[2]s</a>` create_pull_request=`створив(ла) запити на злиття <a href="%s/pulls/%s">%s#%[2]s</a>`
close_pull_request=`закрито запит на злиття <a href="%s/pulls/%s">%s#%[2]s</a>` close_pull_request=`закрив(ла) запит на злиття <a href="%s/pulls/%s">%s#%[2]s</a>`
reopen_pull_request=`повторно відкрито запит на злиття <a href="%s/pulls/%s">%s#%[2]s</a>` reopen_pull_request=`повторно відкрито запит на злиття <a href="%s/pulls/%s">%s#%[2]s</a>`
comment_issue=`прокоментував(ла) проблему <a href="%s/issues/%s">%s#%[2]s</a>` comment_issue=`прокоментував(ла) проблему <a href="%s/issues/%s">%s#%[2]s</a>`
merge_pull_request=апит на злиття злито <a href="%s/pulls/%s">%s#%[2]s</a>` merge_pull_request=лив(ла) запит на злиття <a href="%s/pulls/%s">%s#%[2]s</a>`
transfer_repo=перенесено репозиторій <code>%s</code> у <a href="%s">%s</a> transfer_repo=перенесено репозиторій <code>%s</code> у <a href="%s">%s</a>
push_tag=створив(ла) тег <a href="%s/src/%s">%[2]s</a> в <a href="%[1]s">%[3]s</a> push_tag=створив(ла) тег <a href="%s/src/%s">%[2]s</a> в <a href="%[1]s">%[3]s</a>
delete_tag=видалено мітку %[2]s з <a href="%[1]s">%[3]s</a> delete_tag=видалено мітку %[2]s з <a href="%[1]s">%[3]s</a>

View File

@ -1,7 +1,7 @@
app_desc=一款极易搭建的自助 Git 服务 app_desc=一款极易搭建的自助 Git 服务
home=首页 home=首页
dashboard=控制面板 dashboard=首页
explore=探索 explore=探索
help=帮助 help=帮助
sign_in=登录 sign_in=登录
@ -31,15 +31,27 @@ twofa=两步验证
twofa_scratch=两步验证口令 twofa_scratch=两步验证口令
passcode=验证码 passcode=验证码
u2f_insert_key=插入安全密钥
u2f_sign_in=按下安全密钥上的按钮。如果找不到按钮, 请重新插入。
u2f_press_button=请按下安全密钥上的按钮。
u2f_use_twofa=使用来自你手机中的两步验证码
u2f_error=没有找到你的安全密钥!
u2f_unsupported_browser=您的浏览器不支持 U2F 密钥。请尝试其他浏览器。
u2f_error_1=发生未知错误。请重试。
u2f_error_2=请确保您使用的是加密连接 (https://) 并访问正确的 URL。
u2f_error_3=服务器无法执行您的请求。
u2f_error_4=所提交的密钥不符合此请求。如果您尝试注册它, 请确保该密钥尚未注册。
u2f_error_5=在读取到密钥之前超时。请重新加载以重试。
u2f_reload=重新加载
repository=仓库 repository=仓库
organization=组织 organization=组织
mirror=镜像 mirror=镜像
new_repo=创建新的仓库 new_repo=创建仓库
new_migrate=迁移外部仓库 new_migrate=迁移外部仓库
new_mirror=创建新的镜像 new_mirror=创建新的镜像
new_fork=新的仓库Fork new_fork=新的仓库Fork
new_org=创建新的组织 new_org=创建组织
manage_org=管理我的组织 manage_org=管理我的组织
admin_panel=管理后台 admin_panel=管理后台
account_settings=帐户设置 account_settings=帐户设置
@ -156,7 +168,7 @@ no_reply_address_helper=具有隐藏电子邮件地址的用户的域名。例
uname_holder=登录名或电子邮箱地址 uname_holder=登录名或电子邮箱地址
password_holder=密码 password_holder=密码
switch_dashboard_context=切换控制面板用户 switch_dashboard_context=切换控制面板用户
my_repos=我的仓库 my_repos=仓库列表
show_more_repos=显示更多仓库… show_more_repos=显示更多仓库…
collaborative_repos=参与协作的仓库 collaborative_repos=参与协作的仓库
my_orgs=我的组织 my_orgs=我的组织
@ -321,6 +333,7 @@ twofa=两步验证
account_link=已绑定帐户 account_link=已绑定帐户
organization=组织 organization=组织
uid=用户 ID uid=用户 ID
u2f=安全密钥
public_profile=公开信息 public_profile=公开信息
profile_desc=您的电子邮件地址将用于通知和其他操作。 profile_desc=您的电子邮件地址将用于通知和其他操作。
@ -450,6 +463,13 @@ then_enter_passcode=并输入应用程序中显示的密码:
passcode_invalid=密码不正确。再试一次。 passcode_invalid=密码不正确。再试一次。
twofa_enrolled=你的账号已经启用了两步验证。请保存初始令牌(%s到一个安全的地方此令牌仅当前显示一次。 twofa_enrolled=你的账号已经启用了两步验证。请保存初始令牌(%s到一个安全的地方此令牌仅当前显示一次。
u2f_desc=安全密钥是包含加密算法的硬件设备。它们可以用于两步验证。安全密钥必须支持 <a href="https://fidoalliance.org/">FIDO U2F</a> 标准。
u2f_require_twofa=必须开启两步验证才能使用安全密钥。
u2f_register_key=添加安全密钥
u2f_nickname=昵称
u2f_press_button=按安全密钥上的按钮进行注册。
u2f_delete_key=移除安全密钥
u2f_delete_key_desc=如果移除安全密钥, 则无法再使用它登录。是否确定?
manage_account_links=管理绑定过的账号 manage_account_links=管理绑定过的账号
manage_account_links_desc=这些外部帐户已经绑定到您的 Gitea 帐户。 manage_account_links_desc=这些外部帐户已经绑定到您的 Gitea 帐户。
@ -673,6 +693,10 @@ issues.filter_sort.recentupdate=最近更新
issues.filter_sort.leastupdate=最少更新 issues.filter_sort.leastupdate=最少更新
issues.filter_sort.mostcomment=最多评论 issues.filter_sort.mostcomment=最多评论
issues.filter_sort.leastcomment=最少评论 issues.filter_sort.leastcomment=最少评论
issues.filter_sort.moststars=点赞由多到少
issues.filter_sort.feweststars=点赞由少到多
issues.filter_sort.mostforks=派生由多到少
issues.filter_sort.fewestforks=派生由少到多
issues.action_open=开启 issues.action_open=开启
issues.action_close=关闭 issues.action_close=关闭
issues.action_label=标签 issues.action_label=标签
@ -718,7 +742,7 @@ issues.label_deletion_desc=删除标签会将其从所有问题中删除。继
issues.label_deletion_success=该标签已被删除。 issues.label_deletion_success=该标签已被删除。
issues.label.filter_sort.alphabetically=按字母顺序排序 issues.label.filter_sort.alphabetically=按字母顺序排序
issues.label.filter_sort.reverse_alphabetically=按字母逆序排序 issues.label.filter_sort.reverse_alphabetically=按字母逆序排序
issues.label.filter_sort.by_size=大小 issues.label.filter_sort.by_size=从小到大
issues.label.filter_sort.reverse_by_size=从大到小 issues.label.filter_sort.reverse_by_size=从大到小
issues.num_participants=%d 名参与者 issues.num_participants=%d 名参与者
issues.attachment.open_tab=`在新的标签页中查看 '%s'` issues.attachment.open_tab=`在新的标签页中查看 '%s'`
@ -1011,7 +1035,7 @@ settings.event_issues_desc=工单被开启、关闭、重新开启、编辑、
settings.event_issue_comment=工单评论 settings.event_issue_comment=工单评论
settings.event_issue_comment_desc=工单评论被创建、编辑或删除 settings.event_issue_comment_desc=工单评论被创建、编辑或删除
settings.event_release=版本发布 settings.event_release=版本发布
settings.event_release_desc=仓库发布新的版本 settings.event_release_desc=发布、更新或删除版本时
settings.event_pull_request=合并请求 settings.event_pull_request=合并请求
settings.event_pull_request_desc=开启、关闭、重新开启、编辑、指派、取消指派、更新标签、清除标签或同步合并请求 settings.event_pull_request_desc=开启、关闭、重新开启、编辑、指派、取消指派、更新标签、清除标签或同步合并请求
settings.event_push=推送 settings.event_push=推送
@ -1226,14 +1250,14 @@ teams.remove_repo=移除仓库
teams.add_nonexistent_repo=您尝试添加到团队的仓库不存在,请先创建仓库! teams.add_nonexistent_repo=您尝试添加到团队的仓库不存在,请先创建仓库!
[admin] [admin]
dashboard=控制面板 dashboard=管理面板
users=帐户管理 users=帐户管理
organizations=组织管理 organizations=组织管理
repositories=仓库管理 repositories=仓库管理
authentication=认证源 authentication=认证源
config=应用配置 config=应用配置
notices=系统提示 notices=系统提示
monitor=应用监控面板 monitor=监控面板
first_page=首页 first_page=首页
last_page=末页 last_page=末页
total=总计:%d total=总计:%d
@ -1339,8 +1363,9 @@ repos.name=名称
repos.private=私有库 repos.private=私有库
repos.watches=关注数 repos.watches=关注数
repos.stars=点赞数 repos.stars=点赞数
repos.forks=派生数
repos.issues=工单数 repos.issues=工单数
repos.size=从小到 repos.size=
auths.auth_manage_panel=认证源管理 auths.auth_manage_panel=认证源管理
auths.new=添加认证源 auths.new=添加认证源
@ -1365,6 +1390,7 @@ auths.attribute_username_placeholder=置空将使用Gitea的用户名。
auths.attribute_name=名字属性 auths.attribute_name=名字属性
auths.attribute_surname=姓氏属性 auths.attribute_surname=姓氏属性
auths.attribute_mail=电子邮箱属性 auths.attribute_mail=电子邮箱属性
auths.attribute_ssh_public_key=SSH公钥属性
auths.attributes_in_bind=从 Bind DN 中拉取属性信息 auths.attributes_in_bind=从 Bind DN 中拉取属性信息
auths.use_paged_search=使用分页搜索 auths.use_paged_search=使用分页搜索
auths.search_page_size=分页大小 auths.search_page_size=分页大小
@ -1449,9 +1475,7 @@ config.db_host=主机
config.db_name=数据库名称 config.db_name=数据库名称
config.db_user=用户名 config.db_user=用户名
config.db_ssl_mode=SSL config.db_ssl_mode=SSL
config.db_ssl_mode_helper=(仅限 "postgres" 使用)
config.db_path=数据库路径 config.db_path=数据库路径
config.db_path_helper=(用于 "sqlite3" 和 "tidb"
config.service_config=服务配置 config.service_config=服务配置
config.register_email_confirm=需要电子邮件确认注册 config.register_email_confirm=需要电子邮件确认注册
@ -1534,11 +1558,11 @@ monitor.name=任务名称
monitor.schedule=任务安排 monitor.schedule=任务安排
monitor.next=下次执行时间 monitor.next=下次执行时间
monitor.previous=上次执行时间 monitor.previous=上次执行时间
monitor.execute_times=执行时 monitor.execute_times=执行时
monitor.process=运行中进程 monitor.process=运行中进程
monitor.desc=进程描述 monitor.desc=进程描述
monitor.start=开始时间 monitor.start=开始时间
monitor.execute_time=执行时 monitor.execute_time=执行时
notices.system_notice_list=系统提示管理 notices.system_notice_list=系统提示管理
notices.view_detail_header=查看提示详情 notices.view_detail_header=查看提示详情
@ -1550,7 +1574,7 @@ notices.delete_selected=删除选中项
notices.delete_all=删除所有提示 notices.delete_all=删除所有提示
notices.type=提示类型 notices.type=提示类型
notices.type_1=仓库 notices.type_1=仓库
notices.desc=进程描述 notices.desc=提示描述
notices.op=操作 notices.op=操作
notices.delete_success=系统通知已被删除。 notices.delete_success=系统通知已被删除。

View File

@ -67,7 +67,6 @@ save_config_failed=儲存設定失敗:%v
[home] [home]
password_holder=密碼 password_holder=密碼
switch_dashboard_context=切換控制面版用戶 switch_dashboard_context=切換控制面版用戶
my_repos=我的儲存庫
collaborative_repos=參與協作的儲存庫 collaborative_repos=參與協作的儲存庫
my_orgs=我的組織 my_orgs=我的組織
my_mirrors=我的鏡像 my_mirrors=我的鏡像
@ -738,9 +737,7 @@ config.db_config=資料庫設定
config.db_type=資料庫類型 config.db_type=資料庫類型
config.db_host=主機地址 config.db_host=主機地址
config.db_name=資料庫名稱 config.db_name=資料庫名稱
config.db_ssl_mode_helper=(僅限 "postgres" 使用)
config.db_path=資料庫路徑 config.db_path=資料庫路徑
config.db_path_helper=(用於 "sqlite3" 和 "tidb"
config.service_config=服務設定 config.service_config=服務設定
config.show_registration_button=顯示註冊按鈕 config.show_registration_button=顯示註冊按鈕

View File

@ -70,7 +70,6 @@ save_config_failed=儲存設定失敗:%v
[home] [home]
password_holder=密碼 password_holder=密碼
switch_dashboard_context=切換控制面版用戶 switch_dashboard_context=切換控制面版用戶
my_repos=我的儲存庫
collaborative_repos=參與協作的儲存庫 collaborative_repos=參與協作的儲存庫
my_orgs=我的組織 my_orgs=我的組織
my_mirrors=我的鏡像 my_mirrors=我的鏡像
@ -809,9 +808,7 @@ config.db_config=資料庫設定
config.db_type=資料庫類型 config.db_type=資料庫類型
config.db_host=主機地址 config.db_host=主機地址
config.db_name=資料庫名稱 config.db_name=資料庫名稱
config.db_ssl_mode_helper=(僅限 "postgres" 使用)
config.db_path=資料庫路徑 config.db_path=資料庫路徑
config.db_path_helper=(用於 "sqlite3" 和 "tidb"
config.service_config=服務設定 config.service_config=服務設定
config.show_registration_button=顯示註冊按鈕 config.show_registration_button=顯示註冊按鈕

View File

@ -1028,7 +1028,9 @@
} }
], ],
"responses": { "responses": {
"200": {} "200": {
"description": "success"
}
} }
} }
}, },
@ -1338,7 +1340,9 @@
} }
], ],
"responses": { "responses": {
"200": {} "200": {
"description": "success"
}
} }
} }
}, },
@ -3311,7 +3315,9 @@
} }
], ],
"responses": { "responses": {
"200": {} "200": {
"description": "success"
}
} }
} }
}, },
@ -5049,7 +5055,8 @@
"type": "string", "type": "string",
"description": "username of user", "description": "username of user",
"name": "username", "name": "username",
"in": "path" "in": "path",
"required": true
} }
], ],
"responses": { "responses": {
@ -5323,7 +5330,8 @@
"type": "string", "type": "string",
"description": "username of the user", "description": "username of the user",
"name": "username", "name": "username",
"in": "path" "in": "path",
"required": true
} }
], ],
"responses": { "responses": {
@ -7453,11 +7461,13 @@
"description": "AccessTokenList represents a list of API access token." "description": "AccessTokenList represents a list of API access token."
}, },
"Attachment": { "Attachment": {
"description": "Attachment",
"schema": { "schema": {
"$ref": "#/definitions/Attachment" "$ref": "#/definitions/Attachment"
} }
}, },
"AttachmentList": { "AttachmentList": {
"description": "AttachmentList",
"schema": { "schema": {
"type": "array", "type": "array",
"items": { "items": {
@ -7466,11 +7476,13 @@
} }
}, },
"Branch": { "Branch": {
"description": "Branch",
"schema": { "schema": {
"$ref": "#/definitions/Branch" "$ref": "#/definitions/Branch"
} }
}, },
"BranchList": { "BranchList": {
"description": "BranchList",
"schema": { "schema": {
"type": "array", "type": "array",
"items": { "items": {
@ -7479,11 +7491,13 @@
} }
}, },
"Comment": { "Comment": {
"description": "Comment",
"schema": { "schema": {
"$ref": "#/definitions/Comment" "$ref": "#/definitions/Comment"
} }
}, },
"CommentList": { "CommentList": {
"description": "CommentList",
"schema": { "schema": {
"type": "array", "type": "array",
"items": { "items": {
@ -7492,11 +7506,13 @@
} }
}, },
"DeployKey": { "DeployKey": {
"description": "DeployKey",
"schema": { "schema": {
"$ref": "#/definitions/DeployKey" "$ref": "#/definitions/DeployKey"
} }
}, },
"DeployKeyList": { "DeployKeyList": {
"description": "DeployKeyList",
"schema": { "schema": {
"type": "array", "type": "array",
"items": { "items": {
@ -7505,6 +7521,7 @@
} }
}, },
"EmailList": { "EmailList": {
"description": "EmailList",
"schema": { "schema": {
"type": "array", "type": "array",
"items": { "items": {
@ -7513,11 +7530,13 @@
} }
}, },
"GPGKey": { "GPGKey": {
"description": "GPGKey",
"schema": { "schema": {
"$ref": "#/definitions/GPGKey" "$ref": "#/definitions/GPGKey"
} }
}, },
"GPGKeyList": { "GPGKeyList": {
"description": "GPGKeyList",
"schema": { "schema": {
"type": "array", "type": "array",
"items": { "items": {
@ -7526,6 +7545,7 @@
} }
}, },
"Hook": { "Hook": {
"description": "Hook",
"schema": { "schema": {
"type": "array", "type": "array",
"items": { "items": {
@ -7534,6 +7554,7 @@
} }
}, },
"HookList": { "HookList": {
"description": "HookList",
"schema": { "schema": {
"type": "array", "type": "array",
"items": { "items": {
@ -7542,6 +7563,7 @@
} }
}, },
"Issue": { "Issue": {
"description": "Issue",
"schema": { "schema": {
"$ref": "#/definitions/Issue" "$ref": "#/definitions/Issue"
} }
@ -7552,6 +7574,7 @@
} }
}, },
"IssueList": { "IssueList": {
"description": "IssueList",
"schema": { "schema": {
"type": "array", "type": "array",
"items": { "items": {
@ -7560,11 +7583,13 @@
} }
}, },
"Label": { "Label": {
"description": "Label",
"schema": { "schema": {
"$ref": "#/definitions/Label" "$ref": "#/definitions/Label"
} }
}, },
"LabelList": { "LabelList": {
"description": "LabelList",
"schema": { "schema": {
"type": "array", "type": "array",
"items": { "items": {
@ -7576,11 +7601,13 @@
"description": "MarkdownRender is a rendered markdown document" "description": "MarkdownRender is a rendered markdown document"
}, },
"Milestone": { "Milestone": {
"description": "Milestone",
"schema": { "schema": {
"$ref": "#/definitions/Milestone" "$ref": "#/definitions/Milestone"
} }
}, },
"MilestoneList": { "MilestoneList": {
"description": "MilestoneList",
"schema": { "schema": {
"type": "array", "type": "array",
"items": { "items": {
@ -7589,11 +7616,13 @@
} }
}, },
"Organization": { "Organization": {
"description": "Organization",
"schema": { "schema": {
"$ref": "#/definitions/Organization" "$ref": "#/definitions/Organization"
} }
}, },
"OrganizationList": { "OrganizationList": {
"description": "OrganizationList",
"schema": { "schema": {
"type": "array", "type": "array",
"items": { "items": {
@ -7602,11 +7631,13 @@
} }
}, },
"PublicKey": { "PublicKey": {
"description": "PublicKey",
"schema": { "schema": {
"$ref": "#/definitions/PublicKey" "$ref": "#/definitions/PublicKey"
} }
}, },
"PublicKeyList": { "PublicKeyList": {
"description": "PublicKeyList",
"schema": { "schema": {
"type": "array", "type": "array",
"items": { "items": {
@ -7615,11 +7646,13 @@
} }
}, },
"PullRequest": { "PullRequest": {
"description": "PullRequest",
"schema": { "schema": {
"$ref": "#/definitions/PullRequest" "$ref": "#/definitions/PullRequest"
} }
}, },
"PullRequestList": { "PullRequestList": {
"description": "PullRequestList",
"schema": { "schema": {
"type": "array", "type": "array",
"items": { "items": {
@ -7628,11 +7661,13 @@
} }
}, },
"Release": { "Release": {
"description": "Release",
"schema": { "schema": {
"$ref": "#/definitions/Release" "$ref": "#/definitions/Release"
} }
}, },
"ReleaseList": { "ReleaseList": {
"description": "ReleaseList",
"schema": { "schema": {
"type": "array", "type": "array",
"items": { "items": {
@ -7641,11 +7676,13 @@
} }
}, },
"Repository": { "Repository": {
"description": "Repository",
"schema": { "schema": {
"$ref": "#/definitions/Repository" "$ref": "#/definitions/Repository"
} }
}, },
"RepositoryList": { "RepositoryList": {
"description": "RepositoryList",
"schema": { "schema": {
"type": "array", "type": "array",
"items": { "items": {
@ -7654,6 +7691,7 @@
} }
}, },
"SearchResults": { "SearchResults": {
"description": "SearchResults",
"schema": { "schema": {
"$ref": "#/definitions/SearchResults" "$ref": "#/definitions/SearchResults"
}, },
@ -7662,16 +7700,19 @@
} }
}, },
"ServerVersion": { "ServerVersion": {
"description": "ServerVersion",
"schema": { "schema": {
"$ref": "#/definitions/ServerVersion" "$ref": "#/definitions/ServerVersion"
} }
}, },
"Status": { "Status": {
"description": "Status",
"schema": { "schema": {
"$ref": "#/definitions/Status" "$ref": "#/definitions/Status"
} }
}, },
"StatusList": { "StatusList": {
"description": "StatusList",
"schema": { "schema": {
"type": "array", "type": "array",
"items": { "items": {
@ -7680,11 +7721,13 @@
} }
}, },
"Team": { "Team": {
"description": "Team",
"schema": { "schema": {
"$ref": "#/definitions/Team" "$ref": "#/definitions/Team"
} }
}, },
"TeamList": { "TeamList": {
"description": "TeamList",
"schema": { "schema": {
"type": "array", "type": "array",
"items": { "items": {
@ -7693,11 +7736,13 @@
} }
}, },
"TrackedTime": { "TrackedTime": {
"description": "TrackedTime",
"schema": { "schema": {
"$ref": "#/definitions/TrackedTime" "$ref": "#/definitions/TrackedTime"
} }
}, },
"TrackedTimeList": { "TrackedTimeList": {
"description": "TrackedTimeList",
"schema": { "schema": {
"type": "array", "type": "array",
"items": { "items": {
@ -7706,11 +7751,13 @@
} }
}, },
"User": { "User": {
"description": "User",
"schema": { "schema": {
"$ref": "#/definitions/User" "$ref": "#/definitions/User"
} }
}, },
"UserList": { "UserList": {
"description": "UserList",
"schema": { "schema": {
"type": "array", "type": "array",
"items": { "items": {
@ -7719,6 +7766,7 @@
} }
}, },
"WatchInfo": { "WatchInfo": {
"description": "WatchInfo",
"schema": { "schema": {
"$ref": "#/definitions/WatchInfo" "$ref": "#/definitions/WatchInfo"
} }
@ -7752,6 +7800,7 @@
"description": "APINotFound is a not found empty response" "description": "APINotFound is a not found empty response"
}, },
"parameterBodies": { "parameterBodies": {
"description": "parameterBodies",
"schema": { "schema": {
"$ref": "#/definitions/EditAttachmentOptions" "$ref": "#/definitions/EditAttachmentOptions"
}, },

View File

@ -15,10 +15,7 @@ File(s): /vendor/plugins/clipboard/clipboard.min.js
Version: 1.5.9 Version: 1.5.9
File(s): /vendor/plugins/gitgraph/gitgraph.js File(s): /vendor/plugins/gitgraph/gitgraph.js
Version: 9b492e8bf1ddf7908a4997b8f83fa38a809a9da3 Version: 745f604212e2abfe2f0a59169ea530857b46625c
File(s): /vendor/plugins/autolink/autolink.js
Version: 741f66f
File(s): /vendor/plugins/vue/vue.min.js File(s): /vendor/plugins/vue/vue.min.js
Version: 2.1.10 Version: 2.1.10
@ -50,6 +47,9 @@ Version: 1.10.1
File(s): /vendor/plugins/pdfjs/ File(s): /vendor/plugins/pdfjs/
Version: 1.4.20 Version: 1.4.20
File(s): /vendor/plugins/u2f/
Version: 1.0.8
File(s): /vendor/assets/font-awesome/fonts/ File(s): /vendor/assets/font-awesome/fonts/
Version: 4.6.0 Version: 4.6.0

View File

@ -45,11 +45,6 @@
<td><a href="https://github.com/bluef/gitgraph.js/blob/master/LICENSE">BSD 3-Clause</a></td> <td><a href="https://github.com/bluef/gitgraph.js/blob/master/LICENSE">BSD 3-Clause</a></td>
<td><a href="https://github.com/bluef/gitgraph.js">gitgraph.js-latest</a></td> <td><a href="https://github.com/bluef/gitgraph.js">gitgraph.js-latest</a></td>
</tr> </tr>
<tr>
<td><a href="/vendor/plugins/autolink/autolink.js">autolink.min.js</a></td>
<td><a href="https://github.com/egoist/autolink.js/blob/master/LICENSE">Expat</a></td>
<td><a href="https://github.com/egoist/autolink.js">autolink.js-latest</a></td>
</tr>
<tr> <tr>
<td><a href="/vendor/plugins/vue/vue.min.js">vue.min.js</a></td> <td><a href="/vendor/plugins/vue/vue.min.js">vue.min.js</a></td>
<td><a href="https://github.com/vuejs/vue/blob/dev/LICENSE">Expat</a></td> <td><a href="https://github.com/vuejs/vue/blob/dev/LICENSE">Expat</a></td>

View File

@ -126,7 +126,20 @@ var gitGraph = function (canvas, rawGraphList, config) {
!(row[i - 2] && row[i] === "_" && row[i - 2] === "|")) {} !(row[i - 2] && row[i] === "_" && row[i - 2] === "|")) {}
return i; return i;
} };
var findLineBreak = function (row) {
if (!row) {
return -1
}
var i = row.length;
while (i-- &&
!(row[i - 1] && row[i - 2] && row[i] === " " && row[i - 1] === "|" && row[i - 2] === "_")) {}
return i;
};
var genNewFlow = function () { var genNewFlow = function () {
var newId; var newId;
@ -138,21 +151,21 @@ var gitGraph = function (canvas, rawGraphList, config) {
return {id:newId, color:"#" + newId}; return {id:newId, color:"#" + newId};
}; };
//draw method //Draw methods
var drawLineRight = function (x, y, color) { var drawLine = function (moveX, moveY, lineX, lineY, color) {
ctx.strokeStyle = color; ctx.strokeStyle = color;
ctx.beginPath(); ctx.beginPath();
ctx.moveTo(x, y + config.unitSize / 2); ctx.moveTo(moveX, moveY);
ctx.lineTo(x + config.unitSize, y + config.unitSize / 2); ctx.lineTo(lineX, lineY);
ctx.stroke(); ctx.stroke();
}; };
var drawLineRight = function (x, y, color) {
drawLine(x, y + config.unitSize / 2, x + config.unitSize, y + config.unitSize / 2, color);
};
var drawLineUp = function (x, y, color) { var drawLineUp = function (x, y, color) {
ctx.strokeStyle = color; drawLine(x, y + config.unitSize / 2, x, y - config.unitSize / 2, color);
ctx.beginPath();
ctx.moveTo(x, y + config.unitSize / 2);
ctx.lineTo(x, y - config.unitSize / 2);
ctx.stroke();
}; };
var drawNode = function (x, y, color) { var drawNode = function (x, y, color) {
@ -166,37 +179,28 @@ var gitGraph = function (canvas, rawGraphList, config) {
}; };
var drawLineIn = function (x, y, color) { var drawLineIn = function (x, y, color) {
ctx.strokeStyle = color; drawLine(x + config.unitSize, y + config.unitSize / 2, x, y - config.unitSize / 2, color);
ctx.beginPath();
ctx.moveTo(x + config.unitSize, y + config.unitSize / 2);
ctx.lineTo(x, y - config.unitSize / 2);
ctx.stroke();
}; };
var drawLineOut = function (x, y, color) { var drawLineOut = function (x, y, color) {
ctx.strokeStyle = color; drawLine(x, y + config.unitSize / 2, x + config.unitSize, y - config.unitSize / 2, color);
ctx.beginPath();
ctx.moveTo(x, y + config.unitSize / 2);
ctx.lineTo(x + config.unitSize, y - config.unitSize / 2);
ctx.stroke();
}; };
var draw = function (graphList) { var draw = function (graphList) {
var colomn, colomnIndex, prevColomn, condenseIndex; var colomn, colomnIndex, prevColomn, condenseIndex, breakIndex = -1;
var x, y; var x, y;
var color; var color;
var nodePos, outPos; var nodePos;
var tempFlow; var tempFlow;
var prevRowLength = 0; var prevRowLength = 0;
var flowSwapPos = -1; var flowSwapPos = -1;
var lastLinePos; var lastLinePos;
var i, k, l; var i, l;
var condenseCurrentLength, condensePrevLength = 0, condenseNextLength = 0; var condenseCurrentLength, condensePrevLength = 0, condenseNextLength = 0;
var inlineIntersect = false; var inlineIntersect = false;
//initiate for first row //initiate color array for first row
for (i = 0, l = graphList[0].length; i < l; i++) { for (i = 0, l = graphList[0].length; i < l; i++) {
if (graphList[0][i] !== "_" && graphList[0][i] !== " ") { if (graphList[0][i] !== "_" && graphList[0][i] !== " ") {
flows.push(genNewFlow()); flows.push(genNewFlow());
@ -275,6 +279,7 @@ var gitGraph = function (canvas, rawGraphList, config) {
colomnIndex = 0; //reset index colomnIndex = 0; //reset index
condenseIndex = 0; condenseIndex = 0;
condensePrevLength = 0; condensePrevLength = 0;
breakIndex = -1; //reset break index
while (colomnIndex < currentRow.length) { while (colomnIndex < currentRow.length) {
colomn = currentRow[colomnIndex]; colomn = currentRow[colomnIndex];
@ -282,6 +287,18 @@ var gitGraph = function (canvas, rawGraphList, config) {
++condensePrevLength; ++condensePrevLength;
} }
//check and fix line break in next row
if (colomn === "/" && currentRow[colomnIndex - 1] && currentRow[colomnIndex - 1] === "|") {
if ((breakIndex = findLineBreak(nextRow)) !== -1) {
nextRow.splice(breakIndex, 1);
}
}
//if line break found replace all '/' with '|' after breakIndex in previous row
if (breakIndex !== - 1 && colomn === "/" && colomnIndex > breakIndex) {
currentRow[colomnIndex] = "|";
colomn = "|";
}
if (colomn === " " && if (colomn === " " &&
currentRow[colomnIndex + 1] && currentRow[colomnIndex + 1] &&
currentRow[colomnIndex + 1] === "_" && currentRow[colomnIndex + 1] === "_" &&
@ -294,7 +311,7 @@ var gitGraph = function (canvas, rawGraphList, config) {
colomn = "/"; colomn = "/";
} }
//create new flow only when no intersetc happened //create new flow only when no intersect happened
if (flowSwapPos === -1 && if (flowSwapPos === -1 &&
colomn === "/" && colomn === "/" &&
currentRow[colomnIndex - 1] && currentRow[colomnIndex - 1] &&
@ -415,4 +432,4 @@ var gitGraph = function (canvas, rawGraphList, config) {
init(); init();
draw(graphList); draw(graphList);
}; };
// @end-license // @end-license

View File

@ -97,24 +97,25 @@ func parseLDAPConfig(form auth.AuthenticationForm) *models.LDAPConfig {
} }
return &models.LDAPConfig{ return &models.LDAPConfig{
Source: &ldap.Source{ Source: &ldap.Source{
Name: form.Name, Name: form.Name,
Host: form.Host, Host: form.Host,
Port: form.Port, Port: form.Port,
SecurityProtocol: ldap.SecurityProtocol(form.SecurityProtocol), SecurityProtocol: ldap.SecurityProtocol(form.SecurityProtocol),
SkipVerify: form.SkipVerify, SkipVerify: form.SkipVerify,
BindDN: form.BindDN, BindDN: form.BindDN,
UserDN: form.UserDN, UserDN: form.UserDN,
BindPassword: form.BindPassword, BindPassword: form.BindPassword,
UserBase: form.UserBase, UserBase: form.UserBase,
AttributeUsername: form.AttributeUsername, AttributeUsername: form.AttributeUsername,
AttributeName: form.AttributeName, AttributeName: form.AttributeName,
AttributeSurname: form.AttributeSurname, AttributeSurname: form.AttributeSurname,
AttributeMail: form.AttributeMail, AttributeMail: form.AttributeMail,
AttributesInBind: form.AttributesInBind, AttributesInBind: form.AttributesInBind,
SearchPageSize: pageSize, AttributeSSHPublicKey: form.AttributeSSHPublicKey,
Filter: form.Filter, SearchPageSize: pageSize,
AdminFilter: form.AdminFilter, Filter: form.Filter,
Enabled: true, AdminFilter: form.AdminFilter,
Enabled: true,
}, },
} }
} }

View File

@ -51,6 +51,7 @@ func ListUserOrgs(ctx *context.APIContext) {
// in: path // in: path
// description: username of user // description: username of user
// type: string // type: string
// required: true
// responses: // responses:
// "200": // "200":
// "$ref": "#/responses/OrganizationList" // "$ref": "#/responses/OrganizationList"

View File

@ -36,7 +36,8 @@ func GetRawFile(ctx *context.APIContext) {
// type: string // type: string
// required: true // required: true
// responses: // responses:
// 200: // 200:
// description: success
if !ctx.Repo.HasAccess() { if !ctx.Repo.HasAccess() {
ctx.Status(404) ctx.Status(404)
return return
@ -85,7 +86,8 @@ func GetArchive(ctx *context.APIContext) {
// type: string // type: string
// required: true // required: true
// responses: // responses:
// 200: // 200:
// description: success
repoPath := models.RepoPath(ctx.Params(":username"), ctx.Params(":reponame")) repoPath := models.RepoPath(ctx.Params(":username"), ctx.Params(":reponame"))
gitRepo, err := git.OpenRepository(repoPath) gitRepo, err := git.OpenRepository(repoPath)
if err != nil { if err != nil {
@ -121,7 +123,8 @@ func GetEditorconfig(ctx *context.APIContext) {
// type: string // type: string
// required: true // required: true
// responses: // responses:
// 200: // 200:
// description: success
ec, err := ctx.Repo.GetEditorconfig() ec, err := ctx.Repo.GetEditorconfig()
if err != nil { if err != nil {
if git.IsErrNotExist(err) { if git.IsErrNotExist(err) {

View File

@ -171,7 +171,7 @@ func CreateRelease(ctx *context.APIContext, form api.CreateReleaseOption) {
rel.Repo = ctx.Repo.Repository rel.Repo = ctx.Repo.Repository
rel.Publisher = ctx.User rel.Publisher = ctx.User
if err = models.UpdateRelease(ctx.Repo.GitRepo, rel, nil); err != nil { if err = models.UpdateRelease(ctx.User, ctx.Repo.GitRepo, rel, nil); err != nil {
ctx.ServerError("UpdateRelease", err) ctx.ServerError("UpdateRelease", err)
return return
} }
@ -245,7 +245,7 @@ func EditRelease(ctx *context.APIContext, form api.EditReleaseOption) {
if form.IsPrerelease != nil { if form.IsPrerelease != nil {
rel.IsPrerelease = *form.IsPrerelease rel.IsPrerelease = *form.IsPrerelease
} }
if err := models.UpdateRelease(ctx.Repo.GitRepo, rel, nil); err != nil { if err := models.UpdateRelease(ctx.User, ctx.Repo.GitRepo, rel, nil); err != nil {
ctx.Error(500, "UpdateRelease", err) ctx.Error(500, "UpdateRelease", err)
return return
} }

View File

@ -8,60 +8,70 @@ import (
api "code.gitea.io/sdk/gitea" api "code.gitea.io/sdk/gitea"
) )
// Issue
// swagger:response Issue // swagger:response Issue
type swaggerResponseIssue struct { type swaggerResponseIssue struct {
// in:body // in:body
Body api.Issue `json:"body"` Body api.Issue `json:"body"`
} }
// IssueList
// swagger:response IssueList // swagger:response IssueList
type swaggerResponseIssueList struct { type swaggerResponseIssueList struct {
// in:body // in:body
Body []api.Issue `json:"body"` Body []api.Issue `json:"body"`
} }
// Comment
// swagger:response Comment // swagger:response Comment
type swaggerResponseComment struct { type swaggerResponseComment struct {
// in:body // in:body
Body api.Comment `json:"body"` Body api.Comment `json:"body"`
} }
// CommentList
// swagger:response CommentList // swagger:response CommentList
type swaggerResponseCommentList struct { type swaggerResponseCommentList struct {
// in:body // in:body
Body []api.Comment `json:"body"` Body []api.Comment `json:"body"`
} }
// Label
// swagger:response Label // swagger:response Label
type swaggerResponseLabel struct { type swaggerResponseLabel struct {
// in:body // in:body
Body api.Label `json:"body"` Body api.Label `json:"body"`
} }
// LabelList
// swagger:response LabelList // swagger:response LabelList
type swaggerResponseLabelList struct { type swaggerResponseLabelList struct {
// in:body // in:body
Body []api.Label `json:"body"` Body []api.Label `json:"body"`
} }
// Milestone
// swagger:response Milestone // swagger:response Milestone
type swaggerResponseMilestone struct { type swaggerResponseMilestone struct {
// in:body // in:body
Body api.Milestone `json:"body"` Body api.Milestone `json:"body"`
} }
// MilestoneList
// swagger:response MilestoneList // swagger:response MilestoneList
type swaggerResponseMilestoneList struct { type swaggerResponseMilestoneList struct {
// in:body // in:body
Body []api.Milestone `json:"body"` Body []api.Milestone `json:"body"`
} }
// TrackedTime
// swagger:response TrackedTime // swagger:response TrackedTime
type swaggerResponseTrackedTime struct { type swaggerResponseTrackedTime struct {
// in:body // in:body
Body api.TrackedTime `json:"body"` Body api.TrackedTime `json:"body"`
} }
// TrackedTimeList
// swagger:response TrackedTimeList // swagger:response TrackedTimeList
type swaggerResponseTrackedTimeList struct { type swaggerResponseTrackedTimeList struct {
// in:body // in:body

View File

@ -8,36 +8,42 @@ import (
api "code.gitea.io/sdk/gitea" api "code.gitea.io/sdk/gitea"
) )
// PublicKey
// swagger:response PublicKey // swagger:response PublicKey
type swaggerResponsePublicKey struct { type swaggerResponsePublicKey struct {
// in:body // in:body
Body api.PublicKey `json:"body"` Body api.PublicKey `json:"body"`
} }
// PublicKeyList
// swagger:response PublicKeyList // swagger:response PublicKeyList
type swaggerResponsePublicKeyList struct { type swaggerResponsePublicKeyList struct {
// in:body // in:body
Body []api.PublicKey `json:"body"` Body []api.PublicKey `json:"body"`
} }
// GPGKey
// swagger:response GPGKey // swagger:response GPGKey
type swaggerResponseGPGKey struct { type swaggerResponseGPGKey struct {
// in:body // in:body
Body api.GPGKey `json:"body"` Body api.GPGKey `json:"body"`
} }
// GPGKeyList
// swagger:response GPGKeyList // swagger:response GPGKeyList
type swaggerResponseGPGKeyList struct { type swaggerResponseGPGKeyList struct {
// in:body // in:body
Body []api.GPGKey `json:"body"` Body []api.GPGKey `json:"body"`
} }
// DeployKey
// swagger:response DeployKey // swagger:response DeployKey
type swaggerResponseDeployKey struct { type swaggerResponseDeployKey struct {
// in:body // in:body
Body api.DeployKey `json:"body"` Body api.DeployKey `json:"body"`
} }
// DeployKeyList
// swagger:response DeployKeyList // swagger:response DeployKeyList
type swaggerResponseDeployKeyList struct { type swaggerResponseDeployKeyList struct {
// in:body // in:body

View File

@ -8,6 +8,7 @@ import (
api "code.gitea.io/sdk/gitea" api "code.gitea.io/sdk/gitea"
) )
// ServerVersion
// swagger:response ServerVersion // swagger:response ServerVersion
type swaggerResponseServerVersion struct { type swaggerResponseServerVersion struct {
// in:body // in:body

View File

@ -12,6 +12,7 @@ import (
// not actually a response, just a hack to get go-swagger to include definitions // not actually a response, just a hack to get go-swagger to include definitions
// of the various XYZOption structs // of the various XYZOption structs
// parameterBodies
// swagger:response parameterBodies // swagger:response parameterBodies
type swaggerParameterBodies struct { type swaggerParameterBodies struct {
AddCollaboratorOption api.AddCollaboratorOption AddCollaboratorOption api.AddCollaboratorOption

View File

@ -8,24 +8,28 @@ import (
api "code.gitea.io/sdk/gitea" api "code.gitea.io/sdk/gitea"
) )
// Organization
// swagger:response Organization // swagger:response Organization
type swaggerResponseOrganization struct { type swaggerResponseOrganization struct {
// in:body // in:body
Body api.Organization `json:"body"` Body api.Organization `json:"body"`
} }
// OrganizationList
// swagger:response OrganizationList // swagger:response OrganizationList
type swaggerResponseOrganizationList struct { type swaggerResponseOrganizationList struct {
// in:body // in:body
Body []api.Organization `json:"body"` Body []api.Organization `json:"body"`
} }
// Team
// swagger:response Team // swagger:response Team
type swaggerResponseTeam struct { type swaggerResponseTeam struct {
// in:body // in:body
Body api.Team `json:"body"` Body api.Team `json:"body"`
} }
// TeamList
// swagger:response TeamList // swagger:response TeamList
type swaggerResponseTeamList struct { type swaggerResponseTeamList struct {
// in:body // in:body

View File

@ -8,95 +8,111 @@ import (
api "code.gitea.io/sdk/gitea" api "code.gitea.io/sdk/gitea"
) )
// Repository
// swagger:response Repository // swagger:response Repository
type swaggerResponseRepository struct { type swaggerResponseRepository struct {
// in:body // in:body
Body api.Repository `json:"body"` Body api.Repository `json:"body"`
} }
// RepositoryList
// swagger:response RepositoryList // swagger:response RepositoryList
type swaggerResponseRepositoryList struct { type swaggerResponseRepositoryList struct {
// in:body // in:body
Body []api.Repository `json:"body"` Body []api.Repository `json:"body"`
} }
// Branch
// swagger:response Branch // swagger:response Branch
type swaggerResponseBranch struct { type swaggerResponseBranch struct {
// in:body // in:body
Body api.Branch `json:"body"` Body api.Branch `json:"body"`
} }
// BranchList
// swagger:response BranchList // swagger:response BranchList
type swaggerResponseBranchList struct { type swaggerResponseBranchList struct {
// in:body // in:body
Body []api.Branch `json:"body"` Body []api.Branch `json:"body"`
} }
// Hook
// swagger:response Hook // swagger:response Hook
type swaggerResponseHook struct { type swaggerResponseHook struct {
// in:body // in:body
Body []api.Branch `json:"body"` Body []api.Branch `json:"body"`
} }
// HookList
// swagger:response HookList // swagger:response HookList
type swaggerResponseHookList struct { type swaggerResponseHookList struct {
// in:body // in:body
Body []api.Branch `json:"body"` Body []api.Branch `json:"body"`
} }
// Release
// swagger:response Release // swagger:response Release
type swaggerResponseRelease struct { type swaggerResponseRelease struct {
// in:body // in:body
Body api.Release `json:"body"` Body api.Release `json:"body"`
} }
// ReleaseList
// swagger:response ReleaseList // swagger:response ReleaseList
type swaggerResponseReleaseList struct { type swaggerResponseReleaseList struct {
// in:body // in:body
Body []api.Release `json:"body"` Body []api.Release `json:"body"`
} }
// PullRequest
// swagger:response PullRequest // swagger:response PullRequest
type swaggerResponsePullRequest struct { type swaggerResponsePullRequest struct {
// in:body // in:body
Body api.PullRequest `json:"body"` Body api.PullRequest `json:"body"`
} }
// PullRequestList
// swagger:response PullRequestList // swagger:response PullRequestList
type swaggerResponsePullRequestList struct { type swaggerResponsePullRequestList struct {
// in:body // in:body
Body []api.PullRequest `json:"body"` Body []api.PullRequest `json:"body"`
} }
// Status
// swagger:response Status // swagger:response Status
type swaggerResponseStatus struct { type swaggerResponseStatus struct {
// in:body // in:body
Body api.Status `json:"body"` Body api.Status `json:"body"`
} }
// StatusList
// swagger:response StatusList // swagger:response StatusList
type swaggerResponseStatusList struct { type swaggerResponseStatusList struct {
// in:body // in:body
Body []api.Status `json:"body"` Body []api.Status `json:"body"`
} }
// WatchInfo
// swagger:response WatchInfo // swagger:response WatchInfo
type swaggerResponseWatchInfo struct { type swaggerResponseWatchInfo struct {
// in:body // in:body
Body api.WatchInfo `json:"body"` Body api.WatchInfo `json:"body"`
} }
// SearchResults
// swagger:response SearchResults // swagger:response SearchResults
type swaggerResponseSearchResults struct { type swaggerResponseSearchResults struct {
Body api.SearchResults `json:"body"` Body api.SearchResults `json:"body"`
} }
// AttachmentList
// swagger:response AttachmentList // swagger:response AttachmentList
type swaggerResponseAttachmentList struct { type swaggerResponseAttachmentList struct {
//in: body //in: body
Body []api.Attachment `json:"body"` Body []api.Attachment `json:"body"`
} }
// Attachment
// swagger:response Attachment // swagger:response Attachment
type swaggerResponseAttachment struct { type swaggerResponseAttachment struct {
//in: body //in: body

View File

@ -8,18 +8,21 @@ import (
api "code.gitea.io/sdk/gitea" api "code.gitea.io/sdk/gitea"
) )
// User
// swagger:response User // swagger:response User
type swaggerResponseUser struct { type swaggerResponseUser struct {
// in:body // in:body
Body api.User `json:"body"` Body api.User `json:"body"`
} }
// UserList
// swagger:response UserList // swagger:response UserList
type swaggerResponseUserList struct { type swaggerResponseUserList struct {
// in:body // in:body
Body []api.User `json:"body"` Body []api.User `json:"body"`
} }
// EmailList
// swagger:response EmailList // swagger:response EmailList
type swaggerResponseEmailList struct { type swaggerResponseEmailList struct {
// in:body // in:body

View File

@ -129,7 +129,7 @@ func CreateUserPublicKey(ctx *context.APIContext, form api.CreateKeyOption, uid
return return
} }
key, err := models.AddPublicKey(uid, form.Title, content) key, err := models.AddPublicKey(uid, form.Title, content, 0)
if err != nil { if err != nil {
repo.HandleAddKeyError(ctx, err) repo.HandleAddKeyError(ctx, err)
return return

View File

@ -43,6 +43,7 @@ func GetWatchedRepos(ctx *context.APIContext) {
// type: string // type: string
// in: path // in: path
// description: username of the user // description: username of the user
// required: true
// responses: // responses:
// "200": // "200":
// "$ref": "#/responses/RepositoryList" // "$ref": "#/responses/RepositoryList"

View File

@ -104,6 +104,14 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) {
orderBy = models.SearchOrderBySizeReverse orderBy = models.SearchOrderBySizeReverse
case "size": case "size":
orderBy = models.SearchOrderBySize orderBy = models.SearchOrderBySize
case "moststars":
orderBy = models.SearchOrderByStarsReverse
case "feweststars":
orderBy = models.SearchOrderByStars
case "mostforks":
orderBy = models.SearchOrderByForksReverse
case "fewestforks":
orderBy = models.SearchOrderByForks
default: default:
ctx.Data["SortType"] = "recentupdate" ctx.Data["SortType"] = "recentupdate"
orderBy = models.SearchOrderByRecentUpdated orderBy = models.SearchOrderByRecentUpdated
@ -164,26 +172,26 @@ func RenderUserSearch(ctx *context.Context, opts *models.SearchUserOptions, tplN
users []*models.User users []*models.User
count int64 count int64
err error err error
orderBy string orderBy models.SearchOrderBy
) )
ctx.Data["SortType"] = ctx.Query("sort") ctx.Data["SortType"] = ctx.Query("sort")
switch ctx.Query("sort") { switch ctx.Query("sort") {
case "newest": case "newest":
orderBy = "id DESC" orderBy = models.SearchOrderByIDReverse
case "oldest": case "oldest":
orderBy = "id ASC" orderBy = models.SearchOrderByID
case "recentupdate": case "recentupdate":
orderBy = "updated_unix DESC" orderBy = models.SearchOrderByRecentUpdated
case "leastupdate": case "leastupdate":
orderBy = "updated_unix ASC" orderBy = models.SearchOrderByLeastUpdated
case "reversealphabetically": case "reversealphabetically":
orderBy = "name DESC" orderBy = models.SearchOrderByAlphabeticallyReverse
case "alphabetically": case "alphabetically":
orderBy = "name ASC" orderBy = models.SearchOrderByAlphabetically
default: default:
ctx.Data["SortType"] = "alphabetically" ctx.Data["SortType"] = "alphabetically"
orderBy = "name ASC" orderBy = models.SearchOrderByAlphabetically
} }
opts.Keyword = strings.Trim(ctx.Query("q"), " ") opts.Keyword = strings.Trim(ctx.Query("q"), " ")

View File

@ -197,7 +197,7 @@ func NewReleasePost(ctx *context.Context, form auth.NewReleaseForm) {
rel.PublisherID = ctx.User.ID rel.PublisherID = ctx.User.ID
rel.IsTag = false rel.IsTag = false
if err = models.UpdateRelease(ctx.Repo.GitRepo, rel, attachmentUUIDs); err != nil { if err = models.UpdateRelease(ctx.User, ctx.Repo.GitRepo, rel, attachmentUUIDs); err != nil {
ctx.Data["Err_TagName"] = true ctx.Data["Err_TagName"] = true
ctx.ServerError("UpdateRelease", err) ctx.ServerError("UpdateRelease", err)
return return
@ -276,7 +276,7 @@ func EditReleasePost(ctx *context.Context, form auth.EditReleaseForm) {
rel.Note = form.Content rel.Note = form.Content
rel.IsDraft = len(form.Draft) > 0 rel.IsDraft = len(form.Draft) > 0
rel.IsPrerelease = form.Prerelease rel.IsPrerelease = form.Prerelease
if err = models.UpdateRelease(ctx.Repo.GitRepo, rel, attachmentUUIDs); err != nil { if err = models.UpdateRelease(ctx.User, ctx.Repo.GitRepo, rel, attachmentUUIDs); err != nil {
ctx.ServerError("UpdateRelease", err) ctx.ServerError("UpdateRelease", err)
return return
} }

View File

@ -223,6 +223,10 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
var output bytes.Buffer var output bytes.Buffer
lines := strings.Split(fileContent, "\n") lines := strings.Split(fileContent, "\n")
//Remove blank line at the end of file
if len(lines) > 0 && lines[len(lines)-1] == "" {
lines = lines[:len(lines)-1]
}
for index, line := range lines { for index, line := range lines {
line = gotemplate.HTMLEscapeString(line) line = gotemplate.HTMLEscapeString(line)
if index != len(lines)-1 { if index != len(lines)-1 {

View File

@ -25,7 +25,7 @@ import (
const ( const (
tplHooks base.TplName = "repo/settings/webhook/base" tplHooks base.TplName = "repo/settings/webhook/base"
tplHookNew base.TplName = "repo/settings/webhook/new" tplHookNew base.TplName = "repo/settings/webhook/new"
tplOrgHookNew base.TplName = "org/settings/webhook/new" tplOrgHookNew base.TplName = "org/settings/hook_new"
) )
// Webhooks render web hooks list page // Webhooks render web hooks list page

Some files were not shown because too many files have changed in this diff Show More