mirror of
https://github.com/gogs/gogs.git
synced 2026-07-18 22:42:00 +02:00
Compare commits
79 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0ea0c5ec4f | ||
|
|
58f0c68151 | ||
|
|
12b5a76b0d | ||
|
|
a4452864ea | ||
|
|
d57be01485 | ||
|
|
d8738f5bfd | ||
|
|
9cf7f3e46f | ||
|
|
14aba3489e | ||
|
|
13bd16af92 | ||
|
|
922a6f13a3 | ||
|
|
9c91e27933 | ||
|
|
c2ca103d30 | ||
|
|
c18f67ac6a | ||
|
|
a5b0400be7 | ||
|
|
045f14fbd0 | ||
|
|
05d8664f15 | ||
|
|
52fdecf97b | ||
|
|
9c0f84cee8 | ||
|
|
414eb22ef9 | ||
|
|
a2f13eae55 | ||
|
|
2a931937a8 | ||
|
|
dfd6f8f7ab | ||
|
|
275464e7fb | ||
|
|
e2d370f0da | ||
|
|
4cb8bf1b75 | ||
|
|
5335e671be | ||
|
|
2d2d85bba4 | ||
|
|
9df6ce48c5 | ||
|
|
4d5911dbcf | ||
|
|
d57a2b908a | ||
|
|
2f228ddf31 | ||
|
|
1ca171dbe9 | ||
|
|
f6759a731a | ||
|
|
dfbda48afc | ||
|
|
260723e2cc | ||
|
|
1cbc5b49e3 | ||
|
|
f3358f5927 | ||
|
|
f946040fa9 | ||
|
|
434614506e | ||
|
|
7f2733fa1b | ||
|
|
edb7967dc7 | ||
|
|
c9901bbba5 | ||
|
|
4d930f3598 | ||
|
|
13e71acadf | ||
|
|
37ac743da7 | ||
|
|
c47a6c1510 | ||
|
|
94f9ff1ac9 | ||
|
|
97429a25ab | ||
|
|
9e89584cb4 | ||
|
|
ea80274229 | ||
|
|
42a556a082 | ||
|
|
a71a5bfeb4 | ||
|
|
6cee434b04 | ||
|
|
9d44cd79ee | ||
|
|
548440b48f | ||
|
|
8055a0bdac | ||
|
|
83c74878df | ||
|
|
d320915ad2 | ||
|
|
8e160edbd5 | ||
|
|
c0eaae200e | ||
|
|
79ae163296 | ||
|
|
7a91d7e776 | ||
|
|
6465adfe5c | ||
|
|
db14949209 | ||
|
|
ab4bc653ab | ||
|
|
ab4eacd15f | ||
|
|
7845075bd2 | ||
|
|
129638117f | ||
|
|
4438b7793b | ||
|
|
baaf6046a1 | ||
|
|
5418c2c5e4 | ||
|
|
c27038e392 | ||
|
|
51f15880d1 | ||
|
|
e721c5cf86 | ||
|
|
e3570ae45d | ||
|
|
2f27ee2232 | ||
|
|
dab74f21b7 | ||
|
|
9eef2e706c | ||
|
|
12403bdfb0 |
@@ -1,7 +1,6 @@
|
||||
[run]
|
||||
init_cmds = [
|
||||
#["grep", "-rn", "FIXME", "."],
|
||||
["make", "build-dev"],
|
||||
["make", "build-dev", "TAGS=sqlite"],
|
||||
["./gogs", "web"]
|
||||
]
|
||||
watch_all = true
|
||||
@@ -15,6 +14,6 @@ watch_exts = [".go"]
|
||||
ignore_files = [".+_test.go"]
|
||||
build_delay = 1500
|
||||
cmds = [
|
||||
["make", "build-dev"], # sqlite cert pam tidb
|
||||
["make", "build-dev", "TAGS=sqlite"], # cert pam tidb
|
||||
["./gogs", "web"]
|
||||
]
|
||||
@@ -1,20 +1,21 @@
|
||||
.git
|
||||
.git/
|
||||
.git/*
|
||||
.git/**
|
||||
conf
|
||||
conf/
|
||||
conf/*
|
||||
conf/**
|
||||
packager
|
||||
packager/
|
||||
packager/*
|
||||
packager/**
|
||||
scripts
|
||||
scripts/
|
||||
scripts/*
|
||||
scripts/**
|
||||
.github/
|
||||
.github/**
|
||||
config.codekit
|
||||
LICENSE
|
||||
Makefile
|
||||
.dockerignore
|
||||
*.yml
|
||||
*.md
|
||||
.bra.toml
|
||||
.editorconfig
|
||||
.gitignore
|
||||
.gopmfile
|
||||
config.codekit
|
||||
LICENSE
|
||||
Dockerfile*
|
||||
|
||||
4
.github/ISSUE_TEMPLATE.md
vendored
4
.github/ISSUE_TEMPLATE.md
vendored
@@ -11,6 +11,10 @@ For bug reports, please give the relevant info:
|
||||
- [ ] PostgreSQL
|
||||
- [ ] MySQL
|
||||
- [ ] SQLite
|
||||
- Can you reproduce the bug at http://try.gogs.io:
|
||||
- [ ] Yes
|
||||
- [ ] No
|
||||
- [ ] Not relevant
|
||||
- Log gist:
|
||||
|
||||
## Description
|
||||
|
||||
21
.gitignore
vendored
21
.gitignore
vendored
@@ -8,31 +8,12 @@ data/
|
||||
.idea/
|
||||
*.iml
|
||||
public/img/avatar/
|
||||
files/
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
_obj
|
||||
_test
|
||||
[568vq].out
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
_testmain.go
|
||||
*.exe
|
||||
*.exe~
|
||||
/gogs
|
||||
profile/
|
||||
__pycache__
|
||||
*.pem
|
||||
output*
|
||||
.brackets.json
|
||||
docker/fig.yml
|
||||
docker/docker/Dockerfile
|
||||
docker/docker/init_gogs.sh
|
||||
gogs.sublime-project
|
||||
gogs.sublime-workspace
|
||||
.tags*
|
||||
release
|
||||
/release
|
||||
|
||||
28
.gopmfile
28
.gopmfile
@@ -3,30 +3,30 @@ path = github.com/gogits/gogs
|
||||
|
||||
[deps]
|
||||
github.com/bradfitz/gomemcache = commit:fb1f79c
|
||||
github.com/codegangsta/cli = commit:5db7419
|
||||
github.com/codegangsta/cli = commit:a294348
|
||||
github.com/go-macaron/binding = commit:a68f342
|
||||
github.com/go-macaron/cache = commit:5617353
|
||||
github.com/go-macaron/captcha = commit:8aa5919
|
||||
github.com/go-macaron/csrf = commit:715bca0
|
||||
github.com/go-macaron/csrf = commit:546646c
|
||||
github.com/go-macaron/gzip = commit:cad1c65
|
||||
github.com/go-macaron/i18n = commit:d2d3329
|
||||
github.com/go-macaron/inject = commit:c5ab7bf
|
||||
github.com/go-macaron/session = commit:66031fc
|
||||
github.com/go-macaron/toolbox = commit:82b5115
|
||||
github.com/go-sql-driver/mysql = commit:1309049
|
||||
github.com/go-xorm/core = commit:9ddf4ee
|
||||
github.com/go-xorm/xorm = commit:e72082c
|
||||
github.com/go-sql-driver/mysql = commit:0f2db9e
|
||||
github.com/go-xorm/core = commit:5021584
|
||||
github.com/go-xorm/xorm = commit:1045aa0
|
||||
github.com/gogits/chardet = commit:2404f77725
|
||||
github.com/gogits/cron = commit:3abc0f8
|
||||
github.com/gogits/git-module = commit:a1c5096
|
||||
github.com/gogits/git-module = commit:76e8cce
|
||||
github.com/gogits/go-gogs-client = commit:d584b1e
|
||||
github.com/issue9/identicon = commit:f8c0d2c
|
||||
github.com/kardianos/minwinsvc = commit:cad6b2b
|
||||
github.com/klauspost/compress = commit:f962535
|
||||
github.com/klauspost/cpuid = commit:2c698c6
|
||||
github.com/klauspost/compress = commit:2d3d403
|
||||
github.com/klauspost/cpuid = commit:09cded8
|
||||
github.com/klauspost/crc32 = commit:19b0b33
|
||||
github.com/lib/pq = commit:69552e5
|
||||
github.com/mattn/go-sqlite3 = commit:09d5c45
|
||||
github.com/lib/pq = commit:165a352
|
||||
github.com/mattn/go-sqlite3 = commit:45f056c
|
||||
github.com/mcuadros/go-version = commit:d52711f
|
||||
github.com/microcosm-cc/bluemonday = commit:4ac6f27
|
||||
github.com/msteinert/pam = commit:02ccfbf
|
||||
@@ -39,11 +39,11 @@ github.com/Unknwon/cae = commit:7f5e046
|
||||
github.com/Unknwon/com = commit:28b053d
|
||||
github.com/Unknwon/i18n = commit:3b48b66
|
||||
github.com/Unknwon/paginater = commit:7748a72
|
||||
golang.org/x/net = commit:4599ae7
|
||||
golang.org/x/text = commit:07b9a78
|
||||
golang.org/x/crypto = commit:1f22c01
|
||||
golang.org/x/net = commit:a4bbce9
|
||||
golang.org/x/text = commit:a71fd10
|
||||
golang.org/x/crypto = commit:5dc8cb4
|
||||
gopkg.in/asn1-ber.v1 = commit:4e86f43
|
||||
gopkg.in/gomail.v2 = commit:fbb71dd
|
||||
gopkg.in/gomail.v2 = commit:5ceb8e6
|
||||
gopkg.in/ini.v1 = commit:776aa73
|
||||
gopkg.in/ldap.v2 = commit:07a7330
|
||||
gopkg.in/macaron.v1 = commit:b9eee38
|
||||
|
||||
@@ -4,7 +4,6 @@ go:
|
||||
- 1.4
|
||||
- 1.5
|
||||
- 1.6
|
||||
- tip
|
||||
|
||||
before_install:
|
||||
- sudo apt-get update -qq
|
||||
|
||||
@@ -2,7 +2,7 @@ FROM alpine:3.3
|
||||
MAINTAINER jp@roemer.im
|
||||
|
||||
# Install system utils & Gogs runtime dependencies
|
||||
ADD https://github.com/tianon/gosu/releases/download/1.6/gosu-amd64 /usr/sbin/gosu
|
||||
ADD https://github.com/tianon/gosu/releases/download/1.7/gosu-amd64 /usr/sbin/gosu
|
||||
RUN chmod +x /usr/sbin/gosu \
|
||||
&& apk --no-cache --no-progress add ca-certificates bash git linux-pam s6 curl openssh socat
|
||||
|
||||
|
||||
@@ -2,13 +2,12 @@ FROM hypriot/rpi-alpine-scratch:v3.2
|
||||
MAINTAINER jp@roemer.im, raxetul@gmail.com
|
||||
|
||||
# Install system utils & Gogs runtime dependencies
|
||||
ADD https://github.com/tianon/gosu/releases/download/1.6/gosu-armhf /usr/sbin/gosu
|
||||
RUN echo "http://dl-4.alpinelinux.org/alpine/v3.3/main/" | tee /etc/apk/repositories \
|
||||
ADD https://github.com/tianon/gosu/releases/download/1.7/gosu-armhf /usr/sbin/gosu
|
||||
RUN chmod +x /usr/sbin/gosu \
|
||||
&& echo "http://dl-4.alpinelinux.org/alpine/v3.3/main/" | tee /etc/apk/repositories \
|
||||
&& echo "http://dl-4.alpinelinux.org/alpine/v3.3/community/" | tee -a /etc/apk/repositories \
|
||||
&& echo "@edge http://dl-4.alpinelinux.org/alpine/edge/main" | tee -a /etc/apk/repositories \
|
||||
&& apk -U --no-progress upgrade \
|
||||
&& apk -U --no-progress add ca-certificates bash git linux-pam s6@edge curl openssh socat \
|
||||
&& chmod +x /usr/sbin/gosu
|
||||
&& apk -U --no-progress upgrade && rm -f /var/cache/apk/APKINDEX.* \
|
||||
&& apk --no-cache --no-progress add ca-certificates bash git linux-pam s6 curl openssh socat
|
||||
|
||||
ENV GOGS_CUSTOM /data/gogs
|
||||
|
||||
|
||||
6
Makefile
6
Makefile
@@ -53,3 +53,9 @@ clean-mac: clean
|
||||
|
||||
test:
|
||||
go test -cover -race ./...
|
||||
|
||||
fixme:
|
||||
grep -rnw "FIXME" routers models modules
|
||||
|
||||
todo:
|
||||
grep -rnw "TODO" routers models modules
|
||||
|
||||
23
README.md
23
README.md
@@ -1,9 +1,9 @@
|
||||
Gogs - Go Git Service [](https://travis-ci.org/gogits/gogs) [](https://quay.io/repository/gogs/gogs) [](https://crowdin.com/project/gogs) [](https://gitter.im/gogits/gogs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
Gogs - Go Git Service [](https://travis-ci.org/gogits/gogs) [](https://crowdin.com/project/gogs) [](https://gitter.im/gogits/gogs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
=====================
|
||||
|
||||

|
||||
|
||||
##### Current version: 0.8.43
|
||||
##### Current version: 0.9.0
|
||||
|
||||
| Web | UI | Preview |
|
||||
|:-------------:|:-------:|:-------:|
|
||||
@@ -11,15 +11,14 @@ Gogs - Go Git Service [|||
|
||||
||||
|
||||
|
||||
### NOTICES
|
||||
### Important Notes
|
||||
|
||||
1. :bangbang: You **MUST** **MUST** **MUST** read [CONTRIBUTING.md](https://github.com/gogits/gogs/blob/master/.github/CONTRIBUTING.md) for bug report and contributing code. :bangbang:
|
||||
2. **PLEASE** **PLEASE** **PLEASE** [ask questions](https://discuss.gogs.io/c/getting-help) on [the forum](https://discuss.gogs.io/). GitHub issue tracker only keeps **bugs** and **feature requests**, all other topics will be closed without reason.
|
||||
3. Due to testing purpose, data of [try.gogs.io](https://try.gogs.io) was reset in **Jan 28, 2015** and will reset multiple times after. Please do **NOT** put your important data on the site.
|
||||
4. The demo site [try.gogs.io](https://try.gogs.io) is running under `develop` branch.
|
||||
5. If you think there are vulnerabilities in the project, please talk privately to **u@gogs.io**. Thanks!
|
||||
6. If you're interested in using APIs, we have experimental support with [documentation](https://github.com/gogits/go-gogs-client/wiki).
|
||||
7. If your team/company is using Gogs and would like to put your logo on [our website](http://gogs.io), contact us by any means.
|
||||
1. **YOU MUST READ [Contributing Code](https://github.com/gogits/gogs/wiki/Contributing-Code) BEFORE STARTING TO WORK ON A PULL REQUEST**.
|
||||
2. Due to testing purpose, data of [try.gogs.io](https://try.gogs.io) was reset in **Jan 28, 2015** and will reset multiple times after. Please do **NOT** put your important data on the site.
|
||||
3. The demo site [try.gogs.io](https://try.gogs.io) is running under `develop` branch.
|
||||
4. If you think there are vulnerabilities in the project, please talk privately to **u@gogs.io**. Thanks!
|
||||
5. If you're interested in using APIs, we have experimental support with [documentation](https://github.com/gogits/go-gogs-client/wiki).
|
||||
6. If your team/company is using Gogs and would like to put your logo on [our website](http://gogs.io), contact us by any means.
|
||||
|
||||
[简体中文](README_ZH.md)
|
||||
|
||||
@@ -32,7 +31,7 @@ The goal of this project is to make the easiest, fastest, and most painless way
|
||||
- Please see the [Documentation](http://gogs.io/docs/intro) for common usages and change log.
|
||||
- See the [Trello Board](https://trello.com/b/uxAoeLUl/gogs-go-git-service) to follow the develop team.
|
||||
- Want to try it before doing anything else? Do it [online](https://try.gogs.io/gogs/gogs)!
|
||||
- Having trouble? Get help with [Troubleshooting](http://gogs.io/docs/intro/troubleshooting.html).
|
||||
- Having trouble? Get help with [Troubleshooting](http://gogs.io/docs/intro/troubleshooting.html) or [User Forum](https://discuss.gogs.io/).
|
||||
- Want to help with localization? Check out the [guide](http://gogs.io/docs/features/i18n.html)!
|
||||
|
||||
## Features
|
||||
@@ -50,7 +49,7 @@ The goal of this project is to make the easiest, fastest, and most painless way
|
||||
- Mail service
|
||||
- Administration panel
|
||||
- Supports MySQL, PostgreSQL, SQLite3 and [TiDB](https://github.com/pingcap/tidb) (experimental)
|
||||
- Multi-language support ([14 languages](https://crowdin.com/project/gogs))
|
||||
- Multi-language support ([15 languages](https://crowdin.com/project/gogs))
|
||||
|
||||
## System Requirements
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自
|
||||
- 有关基本用法和变更日志,请通过 [使用手册](http://gogs.io/docs/intro/) 查看。
|
||||
- 您可以到 [Trello Board](https://trello.com/b/uxAoeLUl/gogs-go-git-service) 跟随开发团队的脚步。
|
||||
- 想要先睹为快?直接去 [在线体验](https://try.gogs.io/gogs/gogs) 。
|
||||
- 使用过程中遇到问题?尝试从 [故障排查](http://gogs.io/docs/intro/troubleshooting.html) 页面获取帮助。
|
||||
- 使用过程中遇到问题?尝试从 [故障排查](http://gogs.io/docs/intro/troubleshooting.html) 页面或 [用户论坛](https://discuss.gogs.io/) 获取帮助。
|
||||
- 希望帮助多国语言界面的翻译吗?请立即访问 [详情页面](http://gogs.io/docs/features/i18n.html)!
|
||||
|
||||
## 功能特性
|
||||
@@ -30,7 +30,7 @@ Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自
|
||||
- 支持邮件服务
|
||||
- 支持后台管理面板
|
||||
- 支持 MySQL、PostgreSQL、SQLite3 和 [TiDB](https://github.com/pingcap/tidb)(实验性支持) 数据库
|
||||
- 支持多语言本地化([14 种语言]([more](https://crowdin.com/project/gogs)))
|
||||
- 支持多语言本地化([15 种语言]([more](https://crowdin.com/project/gogs)))
|
||||
|
||||
## 系统要求
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@ func runServ(c *cli.Context) {
|
||||
|
||||
setup("serv.log")
|
||||
|
||||
if setting.DisableSSH {
|
||||
if setting.SSH.Disabled {
|
||||
println("Gogs: SSH has been disabled")
|
||||
return
|
||||
}
|
||||
|
||||
35
cmd/web.go
35
cmd/web.go
@@ -7,7 +7,6 @@ package cmd
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
gotmpl "html/template"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/fcgi"
|
||||
@@ -79,16 +78,16 @@ func checkVersion() {
|
||||
|
||||
// Check dependency version.
|
||||
checkers := []VerChecker{
|
||||
{"github.com/go-xorm/xorm", func() string { return xorm.Version }, "0.4.4.1029"},
|
||||
{"github.com/go-xorm/xorm", func() string { return xorm.Version }, "0.5.2.0304"},
|
||||
{"github.com/go-macaron/binding", binding.Version, "0.2.1"},
|
||||
{"github.com/go-macaron/cache", cache.Version, "0.1.2"},
|
||||
{"github.com/go-macaron/csrf", csrf.Version, "0.0.3"},
|
||||
{"github.com/go-macaron/csrf", csrf.Version, "0.0.5"},
|
||||
{"github.com/go-macaron/i18n", i18n.Version, "0.2.0"},
|
||||
{"github.com/go-macaron/session", session.Version, "0.1.6"},
|
||||
{"github.com/go-macaron/toolbox", toolbox.Version, "0.1.0"},
|
||||
{"gopkg.in/ini.v1", ini.Version, "1.8.4"},
|
||||
{"gopkg.in/macaron.v1", macaron.Version, "0.8.0"},
|
||||
{"github.com/gogits/git-module", git.Version, "0.2.7"},
|
||||
{"github.com/gogits/git-module", git.Version, "0.2.9"},
|
||||
{"github.com/gogits/go-gogs-client", gogs.Version, "0.7.3"},
|
||||
}
|
||||
for _, c := range checkers {
|
||||
@@ -126,7 +125,7 @@ func newMacaron() *macaron.Macaron {
|
||||
))
|
||||
m.Use(macaron.Renderer(macaron.RenderOptions{
|
||||
Directory: path.Join(setting.StaticRootPath, "templates"),
|
||||
Funcs: []gotmpl.FuncMap{template.Funcs},
|
||||
Funcs: template.NewFuncMap(),
|
||||
IndentJSON: macaron.Env != macaron.PROD,
|
||||
}))
|
||||
|
||||
@@ -190,6 +189,8 @@ func runWeb(ctx *cli.Context) {
|
||||
|
||||
bindIgnErr := binding.BindIgnErr
|
||||
|
||||
// FIXME: not all routes need go through same middlewares.
|
||||
// Especially some AJAX requests, we can reduce middleware number to improve performance.
|
||||
// Routers.
|
||||
m.Get("/", ignSignIn, routers.Home)
|
||||
m.Get("/explore", ignSignIn, routers.Explore)
|
||||
@@ -217,6 +218,7 @@ func runWeb(ctx *cli.Context) {
|
||||
m.Get("", user.Settings)
|
||||
m.Post("", bindIgnErr(auth.UpdateProfileForm{}), user.SettingsPost)
|
||||
m.Post("/avatar", binding.MultipartForm(auth.UploadAvatarForm{}), user.SettingsAvatar)
|
||||
m.Post("/avatar/delete", user.SettingsDeleteAvatar)
|
||||
m.Combo("/email").Get(user.SettingsEmails).
|
||||
Post(bindIgnErr(auth.AddEmailForm{}), user.SettingsEmailPost)
|
||||
m.Post("/email/delete", user.DeleteEmail)
|
||||
@@ -250,6 +252,7 @@ func runWeb(ctx *cli.Context) {
|
||||
m.Group("/admin", func() {
|
||||
m.Get("", adminReq, admin.Dashboard)
|
||||
m.Get("/config", admin.Config)
|
||||
m.Post("/config/test_mail", admin.SendTestMail)
|
||||
m.Get("/monitor", admin.Monitor)
|
||||
|
||||
m.Group("/users", func() {
|
||||
@@ -330,7 +333,7 @@ func runWeb(ctx *cli.Context) {
|
||||
}
|
||||
|
||||
reqRepoAdmin := middleware.RequireRepoAdmin()
|
||||
reqRepoPusher := middleware.RequireRepoPusher()
|
||||
reqRepoWriter := middleware.RequireRepoWriter()
|
||||
|
||||
// ***** START: Organization *****
|
||||
m.Group("/org", func() {
|
||||
@@ -364,6 +367,7 @@ func runWeb(ctx *cli.Context) {
|
||||
m.Combo("").Get(org.Settings).
|
||||
Post(bindIgnErr(auth.UpdateOrgSettingForm{}), org.SettingsPost)
|
||||
m.Post("/avatar", binding.MultipartForm(auth.UploadAvatarForm{}), org.SettingsAvatar)
|
||||
m.Post("/avatar/delete", org.SettingsDeleteAvatar)
|
||||
|
||||
m.Group("/hooks", func() {
|
||||
m.Get("", org.Webhooks)
|
||||
@@ -398,7 +402,11 @@ func runWeb(ctx *cli.Context) {
|
||||
m.Group("/settings", func() {
|
||||
m.Combo("").Get(repo.Settings).
|
||||
Post(bindIgnErr(auth.RepoSettingForm{}), repo.SettingsPost)
|
||||
m.Combo("/collaboration").Get(repo.Collaboration).Post(repo.CollaborationPost)
|
||||
m.Group("/collaboration", func() {
|
||||
m.Combo("").Get(repo.Collaboration).Post(repo.CollaborationPost)
|
||||
m.Post("/access_mode", repo.ChangeCollaborationAccessMode)
|
||||
m.Post("/delete", repo.DeleteCollaboration)
|
||||
})
|
||||
|
||||
m.Group("/hooks", func() {
|
||||
m.Get("", repo.Webhooks)
|
||||
@@ -440,7 +448,7 @@ func runWeb(ctx *cli.Context) {
|
||||
m.Post("/label", repo.UpdateIssueLabel)
|
||||
m.Post("/milestone", repo.UpdateIssueMilestone)
|
||||
m.Post("/assignee", repo.UpdateIssueAssignee)
|
||||
}, reqRepoAdmin)
|
||||
}, reqRepoWriter)
|
||||
|
||||
m.Group("/:index", func() {
|
||||
m.Post("/title", repo.UpdateIssueTitle)
|
||||
@@ -452,7 +460,7 @@ func runWeb(ctx *cli.Context) {
|
||||
m.Post("/new", bindIgnErr(auth.CreateLabelForm{}), repo.NewLabel)
|
||||
m.Post("/edit", bindIgnErr(auth.CreateLabelForm{}), repo.UpdateLabel)
|
||||
m.Post("/delete", repo.DeleteLabel)
|
||||
}, reqRepoAdmin, middleware.RepoRef())
|
||||
}, reqRepoWriter, middleware.RepoRef())
|
||||
m.Group("/milestones", func() {
|
||||
m.Combo("/new").Get(repo.NewMilestone).
|
||||
Post(bindIgnErr(auth.CreateMilestoneForm{}), repo.NewMilestonePost)
|
||||
@@ -460,7 +468,7 @@ func runWeb(ctx *cli.Context) {
|
||||
m.Post("/:id/edit", bindIgnErr(auth.CreateMilestoneForm{}), repo.EditMilestonePost)
|
||||
m.Get("/:id/:action", repo.ChangeMilestonStatus)
|
||||
m.Post("/delete", repo.DeleteMilestone)
|
||||
}, reqRepoAdmin, middleware.RepoRef())
|
||||
}, reqRepoWriter, middleware.RepoRef())
|
||||
|
||||
m.Group("/releases", func() {
|
||||
m.Get("/new", repo.NewRelease)
|
||||
@@ -468,7 +476,7 @@ func runWeb(ctx *cli.Context) {
|
||||
m.Get("/edit/:tagname", repo.EditRelease)
|
||||
m.Post("/edit/:tagname", bindIgnErr(auth.EditReleaseForm{}), repo.EditReleasePost)
|
||||
m.Post("/delete", repo.DeleteRelease)
|
||||
}, reqRepoAdmin, middleware.RepoRef())
|
||||
}, reqRepoWriter, middleware.RepoRef())
|
||||
|
||||
m.Combo("/compare/*", repo.MustAllowPulls).Get(repo.CompareAndPullRequest).
|
||||
Post(bindIgnErr(auth.CreateIssueForm{}), repo.CompareAndPullRequestPost)
|
||||
@@ -494,7 +502,8 @@ func runWeb(ctx *cli.Context) {
|
||||
Post(bindIgnErr(auth.NewWikiForm{}), repo.NewWikiPost)
|
||||
m.Combo("/:page/_edit").Get(repo.EditWiki).
|
||||
Post(bindIgnErr(auth.NewWikiForm{}), repo.EditWikiPost)
|
||||
}, reqSignIn, reqRepoPusher)
|
||||
m.Post("/:page/delete", repo.DeleteWikiPagePost)
|
||||
}, reqSignIn, reqRepoWriter)
|
||||
}, repo.MustEnableWiki, middleware.RepoRef())
|
||||
|
||||
m.Get("/archive/*", repo.Download)
|
||||
@@ -502,7 +511,7 @@ func runWeb(ctx *cli.Context) {
|
||||
m.Group("/pulls/:index", func() {
|
||||
m.Get("/commits", middleware.RepoRef(), repo.ViewPullCommits)
|
||||
m.Get("/files", middleware.RepoRef(), repo.ViewPullFiles)
|
||||
m.Post("/merge", reqRepoAdmin, repo.MergePullRequest)
|
||||
m.Post("/merge", reqRepoWriter, repo.MergePullRequest)
|
||||
}, repo.MustAllowPulls)
|
||||
|
||||
m.Group("", func() {
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
Execute following command in ROOT directory when anything is changed:
|
||||
|
||||
$ go-bindata -o=modules/bindata/bindata.go -ignore="\\.DS_Store|README.md" -pkg=bindata conf/...
|
||||
|
||||
Add -debug flag to make life easier in development(somehow isn't working):
|
||||
|
||||
$ go-bindata -debug -o=modules/bindata/bindata.go -ignore="\\.DS_Store|README.md" -pkg=bindata conf/...
|
||||
$ make bindata
|
||||
35
conf/app.ini
35
conf/app.ini
@@ -63,9 +63,21 @@ LOCAL_ROOT_URL = http://localhost:%(HTTP_PORT)s/
|
||||
DISABLE_SSH = false
|
||||
; Whether use builtin SSH server or not.
|
||||
START_SSH_SERVER = false
|
||||
; Domain name to be exposed in clone URL
|
||||
SSH_DOMAIN = %(DOMAIN)s
|
||||
; Port number to be exposed in clone URL
|
||||
SSH_PORT = 22
|
||||
; Root path of SSH directory
|
||||
; Port number builtin SSH server listens on
|
||||
SSH_LISTEN_PORT = %(SSH_PORT)s
|
||||
; Root path of SSH directory, default is '~/.ssh', but you have to use '/home/git/.ssh'.
|
||||
SSH_ROOT_PATH =
|
||||
; Directory to create temporary files when test publick key using ssh-keygen,
|
||||
; default is system temporary directory.
|
||||
SSH_KEY_TEST_PATH =
|
||||
; Path to ssh-keygen, default is 'ssh-keygen' and let shell find out which one to call.
|
||||
SSH_KEYGEN_PATH = ssh-keygen
|
||||
; Indicate whether to check minimum key size with corresponding type
|
||||
MINIMUM_KEY_SIZE_CHECK = false
|
||||
; Disable CDN even in "prod" mode
|
||||
OFFLINE_MODE = false
|
||||
DISABLE_ROUTER_LOG = false
|
||||
@@ -86,6 +98,13 @@ ENABLE_GZIP = false
|
||||
; Landing page for non-logged users, can be "home" or "explore"
|
||||
LANDING_PAGE = home
|
||||
|
||||
; Define allowed algorithms and their minimum key length (use -1 to disable a type)
|
||||
[ssh.minimum_key_sizes]
|
||||
ED25519 = 256
|
||||
ECDSA = 256
|
||||
RSA = 2048
|
||||
DSA = 1024
|
||||
|
||||
[database]
|
||||
; Either "mysql", "postgres" or "sqlite3", it's your choice
|
||||
DB_TYPE = mysql
|
||||
@@ -196,8 +215,6 @@ GC_INTERVAL_TIME = 86400
|
||||
SESSION_LIFE_TIME = 86400
|
||||
|
||||
[picture]
|
||||
; The place to picture data, either "server" or "qiniu", default is "server"
|
||||
SERVICE = server
|
||||
AVATAR_UPLOAD_PATH = data/avatars
|
||||
; Chinese users can choose "duoshuo"
|
||||
; or a custom avatar source, like: http://cn.gravatar.com/avatar/
|
||||
@@ -312,9 +329,16 @@ MAX_GIT_DIFF_LINES = 10000
|
||||
; see more on http://git-scm.com/docs/git-gc/1.7.5
|
||||
GC_ARGS =
|
||||
|
||||
; Operation timeout in seconds
|
||||
[git.timeout]
|
||||
MIGRATE = 600
|
||||
MIRROR = 300
|
||||
CLONE = 300
|
||||
PULL = 300
|
||||
|
||||
[i18n]
|
||||
LANGS = en-US,zh-CN,zh-HK,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,ja-JP,es-ES,pt-BR,pl-PL,bg-BG,it-IT
|
||||
NAMES = English,简体中文,繁體中文,Deutsch,Français,Nederlands,Latviešu,Русский,日本語,Español,Português do Brasil,Polski,български,Italiano
|
||||
LANGS = en-US,zh-CN,zh-HK,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,ja-JP,es-ES,pt-BR,pl-PL,bg-BG,it-IT,fi-FI
|
||||
NAMES = English,简体中文,繁體中文,Deutsch,Français,Nederlands,Latviešu,Русский,日本語,Español,Português do Brasil,Polski,български,Italiano,Suomalainen
|
||||
|
||||
; Used for datetimepicker
|
||||
[i18n.datelang]
|
||||
@@ -332,6 +356,7 @@ pt-BR = pt-BR
|
||||
pl-PL = pl
|
||||
bg-BG = bg
|
||||
it-IT = it
|
||||
fi-FI = fi
|
||||
|
||||
; Extension mapping to highlight class
|
||||
; e.g. .toml=ini
|
||||
|
||||
@@ -12,33 +12,43 @@ Andrey Nering <andrey AT nering DOT com DOT br>
|
||||
Andrey Solomatin <toadron AT yandex DOT ru>
|
||||
Antoine GIRARD <sapk AT sapk DOT fr>
|
||||
Arthur Aslanyan <arthur DOT e DOT aslanyan AT gmail DOT com>
|
||||
Aurelien Darragon <aurelien DOT darragon AT gmail DOT com>
|
||||
Barış Arda Yılmaz <ardayilmazgamer AT gmail DOT com>
|
||||
Christoph Kisfeld <christoph DOT kisfeld AT gmail DOT com>
|
||||
Cysioland
|
||||
Daniel Speichert <daniel AT speichert DOT pl>
|
||||
David Yzaguirre <dvdyzag AT gmail DOT com>
|
||||
Dmitriy Nogay <me AT catwhocode DOT ga>
|
||||
Enrico Testori hypertesto AT gmail DOT com
|
||||
Ezequiel Gonzalez Rial <gonrial AT gmail DOT com>
|
||||
Gregor Santner <gdev AT live DOT de>
|
||||
Hamid Feizabadi <hamidfzm AT gmail DOT com>
|
||||
Huimin Wang <wanghm2009 AT hotmail DOT co DOT jp>
|
||||
ilko <kontact-mr.k AT outlook DOT com">
|
||||
Ilya Makarov
|
||||
Robin Hübner <profan AT prfn DOT se>
|
||||
Jamie Mansfield <dev AT jamierocks DOT uk>
|
||||
Jean THOMAS <contact AT tibounise DOT com>
|
||||
Juraj Bubniak <contact AT jbub DOT eu>
|
||||
Lafriks <lafriks AT gmail DOT com>
|
||||
Lauri Ojansivu <x AT xet7 DOT org>
|
||||
Luc Stepniewski <luc AT stepniewski DOT fr>
|
||||
Luca Kröger <l DOT kroeger01 AT gmail DOT com>
|
||||
Marc Schiller <marc AT schiller DOT im>
|
||||
Marvin Menzerath <github AT marvin-menzerath DOT de>
|
||||
Michael Härtl <haertl DOT mike AT gmail DOT com>
|
||||
Miguel de la Cruz <miguel AT mcrx DOT me>
|
||||
Mikhail Burdin <xdshot9000 AT gmail DOT com>
|
||||
Morten Sørensen <klim8d AT gmail DOT com>
|
||||
Muhammad Fawwaz Orabi <mfawwaz93 AT gmail DOT com>
|
||||
Nakao Takamasa <at.mattenn AT gmail DOT com>
|
||||
Natan Albuquerque <natanalbuquerque5 AT gmail DOT com>
|
||||
Odilon Junior <odilon DOT junior93 AT gmail DOT com>
|
||||
SeongJae Park <sj38 DOT park AT gmail DOT com>
|
||||
Thomas Fanninger <gogs DOT thomas AT fanninger DOT at>
|
||||
Tilmann Bach <tilmann AT outlook DOT com>
|
||||
Toni Villena Jiménez <tonivj5 AT gmail DOT com>
|
||||
Vladimir Jigulin mogaika AT yandex DOT ru
|
||||
Vladimir Vissoultchev <wqweto AT gmail DOT com>
|
||||
YJSoft <yjsoft AT yjsoft DOT pe DOT kr>
|
||||
Łukasz Jan Niemier <lukasz AT niemier DOT pl>
|
||||
|
||||
@@ -221,8 +221,6 @@ still_own_repo=Вашият профил притежава поне едно х
|
||||
still_has_org=Вашият профил все още участва в поне една организация. Първо трябва да напуснете или изтриете Вашите участия в организациите.
|
||||
org_still_own_repo=Тази организация все още притежава хранилище. Първо трябва да го изтриете или да го прехвърлите на друга организация.
|
||||
|
||||
still_own_user=Това удостоверяване се използва от поне един потребител. Моля премахнете потребителите към него и опитайте отново.
|
||||
|
||||
target_branch_not_exist=Целевият клон не съществува.
|
||||
|
||||
[user]
|
||||
@@ -264,11 +262,10 @@ continue=Продължи
|
||||
cancel=Отказ
|
||||
|
||||
enable_custom_avatar=Разреши потребителски аватар
|
||||
enable_custom_avatar_helper=Без зареждане от Gravatar
|
||||
choose_new_avatar=Избор на нов аватар
|
||||
update_avatar=Запази настройките на аватара
|
||||
delete_current_avatar=Изтрий аватар
|
||||
uploaded_avatar_not_a_image=Каченият файл не е изображение.
|
||||
no_custom_avatar_available=Невъзможно използване на външен аватар, защото не е активирано.
|
||||
update_avatar_success=Настройките на аватара са запазени успешно.
|
||||
|
||||
change_password=Промяна на собствената парола
|
||||
@@ -479,7 +476,7 @@ issues.closed_at=`затвори <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.reopened_at=`повторно отвори <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.commit_ref_at=`посочи тази задача от ревизия <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.poster=Участник
|
||||
issues.admin=Администратор
|
||||
issues.collaborator=Сътрудник
|
||||
issues.owner=Притежател
|
||||
issues.sign_up_for_free=Регистрирай се безплатно
|
||||
issues.sign_in_require_desc=за да се включите в този разговор. Вече имате профил? <a href="%s">Влезте, за да коментирате</a>
|
||||
@@ -560,6 +557,8 @@ wiki.save_page=Запис на страница
|
||||
wiki.last_commit_info=%s редактира тази страница %s
|
||||
wiki.edit_page_button=Редакция
|
||||
wiki.new_page_button=Нова страница
|
||||
wiki.delete_page_button=Изтрий страница
|
||||
wiki.delete_page_notice_1=Това ще изтрие страница <code>"%s"</code>. Моля, бъдете сигурни.
|
||||
wiki.page_already_exists=Страница със същото име вече съществува.
|
||||
wiki.pages=Страници
|
||||
wiki.last_updated=Последна модификация на %s
|
||||
@@ -595,6 +594,10 @@ settings.transfer_desc=Прехвърля това хранилище на др
|
||||
settings.transfer_notices_1=- Вие ще загубите достъп, ако новият притежател е индивидуален потребител.
|
||||
settings.transfer_notices_2=- Вие ще запазите достъпа си, ако новият притежател е организация и ако вие сте един от притежателите ѝ.
|
||||
settings.transfer_form_title=Моля въведете следната информация за да потвърдите операцията:
|
||||
settings.wiki_delete=Изтриване на данни на уики
|
||||
settings.wiki_delete_desc=След като изтриете данни за уики, няма връщане назад. Моля, бъдете сигурни.
|
||||
settings.wiki_delete_notices_1=- Това ще изтрие и ще деактивира уики за %s
|
||||
settings.wiki_deletion_success=Данните за уики на това хранилище са изтрити успешно.
|
||||
settings.delete=Изтрий това хранилище
|
||||
settings.delete_desc=След като изтриете хранилището, няма връщане назад. Моля, бъдете сигурни.
|
||||
settings.delete_notices_1=- Тази операция <strong>НЕ МОЖЕ</strong> да бъде отменена в последствие.
|
||||
@@ -610,6 +613,9 @@ settings.transfer_succeed=Притежанието на хранилището
|
||||
settings.confirm_delete=Потвърди изтриването
|
||||
settings.add_collaborator=Добави нов сътрудник
|
||||
settings.add_collaborator_success=Добавен е нов сътрудник.
|
||||
settings.delete_collaborator=Премахни
|
||||
settings.collaborator_deletion=Премахване на сътрудник
|
||||
settings.collaborator_deletion_desc=Този потребител няма да има достъп на сътрудник до хранилището след изтриването. Желаете ли да продължите?
|
||||
settings.remove_collaborator_success=Сътрудникът е премахнат.
|
||||
settings.search_user_placeholder=Име на потребител...
|
||||
settings.org_not_allowed_to_be_collaborator=Невъзможно добавяне на организация като сътрудник.
|
||||
@@ -944,6 +950,7 @@ auths.update=Запази настройки за удостоверяване
|
||||
auths.delete=Изтриване на това удостоверяване
|
||||
auths.delete_auth_title=Изтрий удостоверяването
|
||||
auths.delete_auth_desc=Това удостоверяване ще бъде изтрито. Желаете ли да продължите?
|
||||
auths.still_in_used=Това удостоверяване все още се използва от някои потребители. Моля изтрийте ги или ги конвертирайте до друг тип на влизане първо.
|
||||
auths.deletion_success=Удостоверяването е изтрито успешно!
|
||||
|
||||
config.server_config=Сървърни настройки
|
||||
@@ -960,6 +967,19 @@ config.static_file_root_path=Път към статични файлове
|
||||
config.log_file_root_path=Път към журнал
|
||||
config.script_type=Тип на скрипта
|
||||
config.reverse_auth_user=Потребителско име при обратно удостоверяване
|
||||
|
||||
config.ssh_config=SSH конфигурация
|
||||
config.ssh_enabled=Активен
|
||||
config.ssh_start_builtin_server=Стартирай вграден сървър
|
||||
config.ssh_domain=Домейн
|
||||
config.ssh_port=Порт
|
||||
config.ssh_listen_port=Порт за слушане
|
||||
config.ssh_root_path=Основен път
|
||||
config.ssh_key_test_path=Път до ключове
|
||||
config.ssh_keygen_path=Път до генератор ('ssh-keygen')
|
||||
config.ssh_minimum_key_size_check=Проверка за минимален размер на ключове
|
||||
config.ssh_minimum_key_sizes=Минимален размер на ключове
|
||||
|
||||
config.db_config=Настройки на базата данни
|
||||
config.db_type=Тип
|
||||
config.db_host=Сървър
|
||||
@@ -989,6 +1009,9 @@ config.mailer_disable_helo=Изключи HELO
|
||||
config.mailer_name=Име
|
||||
config.mailer_host=Сървър
|
||||
config.mailer_user=Потребител
|
||||
config.send_test_mail=Изпрати тестово писмо
|
||||
config.test_mail_failed=Невъзможно изпращане на тестово писмо до '%s': %v
|
||||
config.test_mail_sent=Тестово писмо беше изпратено до '%s'.
|
||||
config.oauth_config=OAuth конфигурация
|
||||
config.oauth_enabled=Активна
|
||||
config.cache_config=Конфигурация на кеша
|
||||
@@ -1040,9 +1063,11 @@ create_repo=създаде хранилище <a href="%s"> %s</a>
|
||||
rename_repo=преименува хранилище от <code>%[1]s</code> на <a href="%[2]s">%[3]s</a>
|
||||
commit_repo=предаде към <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>`
|
||||
close_issue=`closed issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
reopen_issue=`reopened 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>`
|
||||
create_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>`
|
||||
comment_issue=`коментира задача <a href="%s/issues/%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>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -221,8 +221,6 @@ still_own_repo = Your account still has ownership over at least one repository,
|
||||
still_has_org = Your account still has membership in at least one organization, you have to leave or delete your memberships first.
|
||||
org_still_own_repo = This organization still has ownership of repositories, you must delete or transfer them first.
|
||||
|
||||
still_own_user = This authentication is still in use by at least one user, please remove them from the authentication and try again.
|
||||
|
||||
target_branch_not_exist = Target branch does not exist.
|
||||
|
||||
[user]
|
||||
@@ -264,11 +262,10 @@ continue = Continue
|
||||
cancel = Cancel
|
||||
|
||||
enable_custom_avatar = Enable Custom Avatar
|
||||
enable_custom_avatar_helper = Disable fetch from Gravatar
|
||||
choose_new_avatar = Choose new avatar
|
||||
update_avatar = Update Avatar Setting
|
||||
delete_current_avatar = Delete Current Avatar
|
||||
uploaded_avatar_not_a_image = Uploaded file is not a image.
|
||||
no_custom_avatar_available = No custom avatar available, cannot enable it.
|
||||
update_avatar_success = Your avatar setting has been updated successfully.
|
||||
|
||||
change_password = Change Password
|
||||
@@ -479,7 +476,7 @@ issues.closed_at = `closed <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.reopened_at = `reopened <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.commit_ref_at = `referenced this issue from a commit <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.poster = Poster
|
||||
issues.admin = Admin
|
||||
issues.collaborator = Collaborator
|
||||
issues.owner = Owner
|
||||
issues.sign_up_for_free = Sign up for free
|
||||
issues.sign_in_require_desc = to join this conversation. Already have an account? <a href="%s">Sign in to comment</a>
|
||||
@@ -560,6 +557,8 @@ wiki.save_page = Save Page
|
||||
wiki.last_commit_info = %s edited this page %s
|
||||
wiki.edit_page_button = Edit
|
||||
wiki.new_page_button = New Page
|
||||
wiki.delete_page_button = Delete Page
|
||||
wiki.delete_page_notice_1 = This will delete the page <code>"%s"</code>. Please be certain.
|
||||
wiki.page_already_exists = Wiki page with same name already exists.
|
||||
wiki.pages = Pages
|
||||
wiki.last_updated = Last updated %s
|
||||
@@ -595,6 +594,10 @@ settings.transfer_desc = Transfer this repository to another user or to an organ
|
||||
settings.transfer_notices_1 = - You will lose access if new owner is a individual user.
|
||||
settings.transfer_notices_2 = - You will conserve access if new owner is an organization and if you're one of the owners.
|
||||
settings.transfer_form_title = Please enter following information to confirm your operation:
|
||||
settings.wiki_delete = Erase Wiki Data
|
||||
settings.wiki_delete_desc = Once you erase wiki data there is no going back. Please be certain.
|
||||
settings.wiki_delete_notices_1 = - This will delete and disable the wiki for %s
|
||||
settings.wiki_deletion_success = Repository wiki data have been erased successfully.
|
||||
settings.delete = Delete This Repository
|
||||
settings.delete_desc = Once you delete a repository, there is no going back. Please be certain.
|
||||
settings.delete_notices_1 = - This operation <strong>CANNOT</strong> be undone.
|
||||
@@ -610,6 +613,9 @@ settings.transfer_succeed = Repository ownership has been transferred successful
|
||||
settings.confirm_delete = Confirm Deletion
|
||||
settings.add_collaborator = Add New Collaborator
|
||||
settings.add_collaborator_success = New collaborator has been added.
|
||||
settings.delete_collaborator = Delete
|
||||
settings.collaborator_deletion = Collaborator Deletion
|
||||
settings.collaborator_deletion_desc = This user will no longer have collaboration access to this repository after deletion. Do you want to continue?
|
||||
settings.remove_collaborator_success = Collaborator has been removed.
|
||||
settings.search_user_placeholder = Search user...
|
||||
settings.org_not_allowed_to_be_collaborator = Organization is not allowed to be added as a collaborator.
|
||||
@@ -944,6 +950,7 @@ auths.update = Update Authentication Setting
|
||||
auths.delete = Delete This Authentication
|
||||
auths.delete_auth_title = Authentication Deletion
|
||||
auths.delete_auth_desc = This authentication is going to be deleted, do you want to continue?
|
||||
auths.still_in_used = This authentication is still used by some users, please delete or convert these users to another login type first.
|
||||
auths.deletion_success = Authentication has been deleted successfully!
|
||||
|
||||
config.server_config = Server Configuration
|
||||
@@ -960,6 +967,19 @@ config.static_file_root_path = Static File Root Path
|
||||
config.log_file_root_path = Log File Root Path
|
||||
config.script_type = Script Type
|
||||
config.reverse_auth_user = Reverse Authentication User
|
||||
|
||||
config.ssh_config = SSH Configuration
|
||||
config.ssh_enabled = Enabled
|
||||
config.ssh_start_builtin_server = Start Builtin Server
|
||||
config.ssh_domain = Domain
|
||||
config.ssh_port = Port
|
||||
config.ssh_listen_port = Listen Port
|
||||
config.ssh_root_path = Root Path
|
||||
config.ssh_key_test_path = Key Test Path
|
||||
config.ssh_keygen_path = Keygen ('ssh-keygen') Path
|
||||
config.ssh_minimum_key_size_check = Minimum Key Size Check
|
||||
config.ssh_minimum_key_sizes = Minimum Key Sizes
|
||||
|
||||
config.db_config = Database Configuration
|
||||
config.db_type = Type
|
||||
config.db_host = Host
|
||||
@@ -989,6 +1009,9 @@ config.mailer_disable_helo = Disable HELO
|
||||
config.mailer_name = Name
|
||||
config.mailer_host = Host
|
||||
config.mailer_user = User
|
||||
config.send_test_mail = Send Test Email
|
||||
config.test_mail_failed = Fail to send test email to '%s': %v
|
||||
config.test_mail_sent = Test email has been sent to '%s'.
|
||||
config.oauth_config = OAuth Configuration
|
||||
config.oauth_enabled = Enabled
|
||||
config.cache_config = Cache Configuration
|
||||
@@ -1043,6 +1066,8 @@ create_issue = `opened issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
close_issue = `closed issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
reopen_issue = `reopened issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
create_pull_request = `created pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
close_pull_request = `closed pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
reopen_pull_request = `reopened pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
comment_issue = `commented on issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
merge_pull_request = `merged pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
transfer_repo = transfered repository <code>%s</code> to <a href="%s">%s</a>
|
||||
|
||||
@@ -8,7 +8,7 @@ sign_in=Iniciar sesión
|
||||
sign_out=Cerrar sesión
|
||||
sign_up=Suscripción
|
||||
register=Registro
|
||||
website=Página Web
|
||||
website=Página web
|
||||
version=Versión
|
||||
page=Página
|
||||
template=Plantilla
|
||||
@@ -27,9 +27,9 @@ repository=Repositorio
|
||||
organization=Organización
|
||||
mirror=Mirror
|
||||
new_repo=Nuevo repositorio
|
||||
new_migrate=Nueva Migración
|
||||
new_migrate=Nueva migración
|
||||
new_mirror=Nueva réplica
|
||||
new_fork=Nuevo Fork del Repositorio
|
||||
new_fork=Nuevo fork del repositorio
|
||||
new_org=Nueva organización
|
||||
manage_org=Administrar organizaciones
|
||||
admin_panel=Panel de administración
|
||||
@@ -89,8 +89,8 @@ app_url_helper=Esto afecta a las URLs para clonar por HTTP/HTTPS y a algunos cor
|
||||
log_root_path=Ruta del registro
|
||||
log_root_path_helper=Directorio donde almacenar los registros.
|
||||
|
||||
optional_title=Configuración Opcional
|
||||
email_title=Configuración del Servicio de Correo
|
||||
optional_title=Configuración opcional
|
||||
email_title=Configuración del servicio de correo
|
||||
smtp_host=SMTP Host
|
||||
smtp_from=Desde
|
||||
smtp_from_helper=Remitente del email, RFC 5322. Puede ser solamente una dirección de correo electrónico, o estar en el formato "Nombre" <email@example.com>.
|
||||
@@ -98,10 +98,10 @@ mailer_user=Remitente del Correo Electrónico
|
||||
mailer_password=Contraseña del Remitente
|
||||
register_confirm=Habilitar la Confirmación en el Registro
|
||||
mail_notify=Habilitar las Notificaciones de Correo
|
||||
server_service_title=Configuración de Servidor y Otros Servicios
|
||||
server_service_title=Configuración del servidor y otros servicios
|
||||
offline_mode=Activar el modo Sin Conexión
|
||||
offline_mode_popup=Desactivar el CDN incluso en el modo de producción, todos los recursos se servirán localmente.
|
||||
disable_gravatar=Desactivar el Servicio Gravatar
|
||||
disable_gravatar=Desactivar el servicio Gravatar
|
||||
disable_gravatar_popup=Desactivar Gravatar y cualquier otra fuente personalizada. Todos los avatares deben ser cargados por los usuarios o en su defecto se mostrará el avatar predeterminado.
|
||||
disable_registration=Desactivar Auto-Registro
|
||||
disable_registration_popup=Desactivar auto-registro del usuario, solo el administrador podrá crear cuentas nuevas.
|
||||
@@ -110,7 +110,7 @@ enable_captcha_popup=Requiere validar la captcha para el auto-registro de usuari
|
||||
require_sign_in_view=Activar el Inicio de Sesión obligatorio para Ver Páginas
|
||||
require_sign_in_view_popup=Solo los usuarios logados pueden ver páginas, los visitantes anónimos solo podrán ver las páginas de login/registro.
|
||||
admin_setting_desc=No es necesario crear una cuenta de administrador ahora mismo, el usuario que tenga ID=1 obtendrá privilegios de administrador automáticamente.
|
||||
admin_title=Configuración de la Cuenta de Administrador
|
||||
admin_title=Configuración de la cuenta de administrador
|
||||
admin_name=Nombre de usuario
|
||||
admin_password=Contraseña
|
||||
confirm_password=Confirmar Contraseña
|
||||
@@ -131,7 +131,7 @@ uname_holder=Nombre de usuario o correo electrónico
|
||||
password_holder=Contraseña
|
||||
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_mirrors=Mis réplicas
|
||||
view_home=Ver %s
|
||||
@@ -221,8 +221,6 @@ still_own_repo=Tu cuenta es la propietaria de uno o más repositorios, tienes qu
|
||||
still_has_org=Tu cuenta es miembro de una o más organizaciones, tienes que abandonarlas o eliminarlas primero.
|
||||
org_still_own_repo=Esta organización es dueña de uno o más repositorios, tienes que eliminarlos o transferirlos primero.
|
||||
|
||||
still_own_user=Esta autenticación está en uso por algunos usuarios, debes moverlos y antes de eliminarla.
|
||||
|
||||
target_branch_not_exist=La rama de destino no existe
|
||||
|
||||
[user]
|
||||
@@ -250,25 +248,24 @@ orgs=Organizaciones
|
||||
delete=Eliminar cuenta
|
||||
uid=UUID
|
||||
|
||||
public_profile=Perfil Público
|
||||
public_profile=Perfil público
|
||||
profile_desc=Tu correo electrónico es público y será usado para todas las notificaciones relacionadas con cualquier cuenta y cualquier operación hecha a través de la web.
|
||||
password_username_disabled=Los usuarios que no son locales no tienen permitido cambiar su nombre de usuario.
|
||||
full_name=Nombre Completo
|
||||
website=Página Web
|
||||
full_name=Nombre completo
|
||||
website=Página web
|
||||
location=Localización
|
||||
update_profile=Actualizar Perfil
|
||||
update_profile=Actualizar perfil
|
||||
update_profile_success=Tu perfil se ha actualizado correctamente.
|
||||
change_username=Nombre de usuario modificado
|
||||
change_username_prompt=Este cambio afectará a los enlaces que hacen referencia a su cuenta.
|
||||
continue=Continuar
|
||||
cancel=Cancelar
|
||||
|
||||
enable_custom_avatar=Activar Avatar Personalizado
|
||||
enable_custom_avatar_helper=Activa esto para desactivar los avatares de Gravatar
|
||||
enable_custom_avatar=Activar avatar personalizado
|
||||
choose_new_avatar=Selecciona nuevo avatar
|
||||
update_avatar=Actualizar Configuración del Avatar
|
||||
update_avatar=Actualizar configuración del avatar
|
||||
delete_current_avatar=Eliminar avatar
|
||||
uploaded_avatar_not_a_image=El archivo enviado no es una imagen.
|
||||
no_custom_avatar_available=No hay ningún avatar personalizado disponible, no se puede habilitar.
|
||||
update_avatar_success=La configuración de tu avatar se ha actualizado correctamente.
|
||||
|
||||
change_password=Cambiar contraseña
|
||||
@@ -341,7 +338,7 @@ owner=Propietario
|
||||
repo_name=Nombre del repositorio
|
||||
repo_name_helper=Los grandes nombres de repositorios son cortos, memorables y <strong>únicos</strong>.
|
||||
visibility=Visibilidad
|
||||
visiblity_helper=Este repositorio es <span class="ui red text">Privado</span>
|
||||
visiblity_helper=Este repositorio es <span class="ui red text">privado</span>
|
||||
visiblity_helper_forced=El administrador web ha obligado a todos los repositorios nuevos a ser <span class="ui red text"> privados</span>
|
||||
visiblity_fork_helper=(Este cambio afectará a todos los forks)
|
||||
clone_helper=¿Necesitas ayuda con el clone? ¡Consulta la <a target="_blank" href="%s">Ayuda</a>!
|
||||
@@ -356,7 +353,7 @@ license_helper=Selecciona un fichero de licencia
|
||||
readme=Readme
|
||||
readme_helper=Seleccione una plantilla de archivo readme
|
||||
auto_init=Inicializar los archivos seleccionados y plantillas de este repositorio
|
||||
create_repo=Crear Repositorio
|
||||
create_repo=Crear repositorio
|
||||
default_branch=Rama por defecto
|
||||
mirror_interval=Intervalo de la réplica (en horas)
|
||||
mirror_address=Dirección de la réplica
|
||||
@@ -369,11 +366,11 @@ form.reach_limit_of_creation=El propietario ha alcanzado el límite máximo de %
|
||||
form.name_reserved=El nombre del repositorio '%s' está reservado.
|
||||
form.name_pattern_not_allowed=El patrón del nombre del repositorio '%s' no está permitido.
|
||||
|
||||
need_auth=Requiere Autorización
|
||||
migrate_type=Tipo de Migración
|
||||
need_auth=Requiere autorización
|
||||
migrate_type=Tipo de migración
|
||||
migrate_type_helper=Este repositorio será una <span class="text blue">réplica</span>
|
||||
migrate_repo=Migrar Repositorio
|
||||
migrate.clone_address=Clonar Dirección
|
||||
migrate.clone_address=Clonar dirección
|
||||
migrate.clone_address_desc=Puede ser una URL HTTP/HTTPS/GIT o una ruta local del servidor.
|
||||
migrate.permission_denied=No te está permitido importar repositorios locales.
|
||||
migrate.invalid_local_path=Rutal local inválida, no existe o no es un directorio.
|
||||
@@ -425,7 +422,7 @@ commits.date=Fecha
|
||||
commits.older=Anterior
|
||||
commits.newer=Posterior
|
||||
|
||||
issues.new=Nueva Incidencia
|
||||
issues.new=Nueva incidencia
|
||||
issues.new.labels=Etiquetas
|
||||
issues.new.no_label=Sin etiquetas
|
||||
issues.new.clear_labels=Limpiar etiquetas
|
||||
@@ -469,17 +466,17 @@ issues.open_title=Abierta
|
||||
issues.closed_title=Cerrada
|
||||
issues.num_comments=%d comentarios
|
||||
issues.commented_at=`comentada <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.no_content=Aun no existe contenido.
|
||||
issues.no_content=Aún no existe contenido.
|
||||
issues.close_issue=Cerrar
|
||||
issues.close_comment_issue=Comentar y cerrar
|
||||
issues.reopen_issue=Reabrir
|
||||
issues.reopen_comment_issue=Comentar y reabrir
|
||||
issues.create_comment=Comentar
|
||||
issues.closed_at=`cerrada <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.reopened_at=`reabierta <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.closed_at=`cerró <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.reopened_at=`reabrió <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.commit_ref_at=`mencionada esta incidencia en un commit <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.poster=Autor
|
||||
issues.admin=Administrador
|
||||
issues.collaborator=Colaborador
|
||||
issues.owner=Propietario
|
||||
issues.sign_up_for_free=Registro gratuito
|
||||
issues.sign_in_require_desc=para unirse a esta conversación. ¿Ya dispone de una cuenta? <a href="%s">Inicie sesión para comentar</a>
|
||||
@@ -513,7 +510,7 @@ pulls.merged_title_desc=fusionados %[1]d commits de <code>%[2]s</code> en <code>
|
||||
pulls.tab_conversation=Conversación
|
||||
pulls.tab_commits=Commits
|
||||
pulls.tab_files=Archivos modificados
|
||||
pulls.reopen_to_merge=Por favor reabra este pull request para proceder con la operación de fusionado.
|
||||
pulls.reopen_to_merge=Por favor reabra este Pull Request para proceder con la operación de fusionado.
|
||||
pulls.merged=Fuisionado
|
||||
pulls.has_merged=¡Este pull request se ha completado con éxito!
|
||||
pulls.data_broken=Los datos de este pull request ya no están disponibles porque se ha eliminado la información del fork.
|
||||
@@ -560,6 +557,8 @@ wiki.save_page=Guardar página
|
||||
wiki.last_commit_info=%s editó esta página %s
|
||||
wiki.edit_page_button=Editar
|
||||
wiki.new_page_button=Nueva página
|
||||
wiki.delete_page_button=Eliminar página
|
||||
wiki.delete_page_notice_1=Esto eliminará la página <code>"%s"</code>. Por favor, asegúrate de que es lo que quieres.
|
||||
wiki.page_already_exists=Ya existe una página con el mismo nombre.
|
||||
wiki.pages=Páginas
|
||||
wiki.last_updated=Última actualización %s
|
||||
@@ -595,6 +594,10 @@ settings.transfer_desc=Transferir este repositorio a otro usuario u organizació
|
||||
settings.transfer_notices_1=- Perderá el permiso de acceso si el nuevo propietario es otro usuario.
|
||||
settings.transfer_notices_2=- Conservará el privilegio de acceso si el nuevo propietario es una organización y usted es uno de los propietarios de dicha organización.
|
||||
settings.transfer_form_title=Por favor introduzca esta información para confirmar la operación:
|
||||
settings.wiki_delete=Eliminar datos de la wiki
|
||||
settings.wiki_delete_desc=Una vez borrados los datos de la wiki no habrá vuelta atrás. Por favor, asegúrate de que es lo que quieres.
|
||||
settings.wiki_delete_notices_1=- Esto eliminará y deshabilitará la wiki para %s
|
||||
settings.wiki_deletion_success=Los datos de la wiki del repositorio han sido borrados correctamente.
|
||||
settings.delete=Eliminar este repositorio
|
||||
settings.delete_desc=Una vez has eliminado un repositorio, no hay vuelta atrás. Por favor, asegúrate de que es lo que quieres.
|
||||
settings.delete_notices_1=- Esta operación <strong>NO PUEDE</strong> revertirse.
|
||||
@@ -608,9 +611,12 @@ settings.transfer_owner=Nuevo Propietario
|
||||
settings.make_transfer=Transferir
|
||||
settings.transfer_succeed=La propiedad del repositorio ha sido transferida exitosamente.
|
||||
settings.confirm_delete=Confirmar eliminación
|
||||
settings.add_collaborator=Añadir Nuevo Colaborador
|
||||
settings.add_collaborator_success=Se ha añadido el nuevo colaborador.
|
||||
settings.remove_collaborator_success=Se ha eliminado el colaborador.
|
||||
settings.add_collaborator=Añadir nuevo colaborador
|
||||
settings.add_collaborator_success=El nuevo colaborador ha sido añadido.
|
||||
settings.delete_collaborator=Eliminar
|
||||
settings.collaborator_deletion=Eliminar colaborador
|
||||
settings.collaborator_deletion_desc=Este usuario no podrá colaborar en este repositorio tras eliminarlo. ¿Desea continuar?
|
||||
settings.remove_collaborator_success=El colaborador ha sido eliminado.
|
||||
settings.search_user_placeholder=Buscar usuario...
|
||||
settings.org_not_allowed_to_be_collaborator=Las organizaciones no tiene permitido ser añadidas como colaboradores.
|
||||
settings.user_is_org_member=El usuario es miembro de la organización, no puede ser añadido como colaborador.
|
||||
@@ -634,7 +640,7 @@ settings.githook_content=Contenido del Hook
|
||||
settings.update_githook=Actualizar Hook
|
||||
settings.add_webhook_desc=Enviaremos una petición <code>POST</code> a la siguiente URL con los detalles de cualquier evento suscrito. También puedes especificar qué formato de datos te gustaría recibir (JSON, <code>x-www-form-urlencoded</code>, <em>etc</em>). Puedes encontrar más información en la <a target="_blank" href="%s">Guía de Webhooks</a>.
|
||||
settings.payload_url=URL de Payload
|
||||
settings.content_type=Tipo de Contenido
|
||||
settings.content_type=Tipo de contenido
|
||||
settings.secret=Secreto
|
||||
settings.slack_username=Nombre de usuario
|
||||
settings.slack_icon_url=URL de icono
|
||||
@@ -715,8 +721,8 @@ release.tag_name_already_exist=Ya existe una Release con esta etiqueta.
|
||||
release.downloads=Descargas
|
||||
|
||||
[org]
|
||||
org_name_holder=Nombre de la Organización
|
||||
org_full_name_holder=Nombre de la organización
|
||||
org_name_holder=Nombre de la organización
|
||||
org_full_name_holder=Nombre completo de la organización
|
||||
org_name_helper=Los grandes nombres de organizaciones son cortos y memorables.
|
||||
create_org=Crear Organización
|
||||
repo_updated=Actualizado
|
||||
@@ -725,9 +731,9 @@ invite_someone=Invitar a alguien
|
||||
teams=Equipos
|
||||
lower_members=miembros
|
||||
lower_repositories=repositorios
|
||||
create_new_team=Crear un Nuevo Equipo
|
||||
create_new_team=Crear un nuevo equipo
|
||||
org_desc=Descripción
|
||||
team_name=Nombre del Equipo
|
||||
team_name=Nombre del equipo
|
||||
team_desc=Descripción
|
||||
team_name_helper=Utiliza este nombre para mencionar a este equipo en las conversaciones.
|
||||
team_desc_helper=¿En qué consiste este equipo?
|
||||
@@ -738,8 +744,8 @@ form.name_pattern_not_allowed=El patrón de nombre de la organización '%s' no e
|
||||
|
||||
settings=Configuración
|
||||
settings.options=Opciones
|
||||
settings.full_name=Nombre Completo
|
||||
settings.website=Página Web
|
||||
settings.full_name=Nombre completo
|
||||
settings.website=Página web
|
||||
settings.location=Localización
|
||||
settings.update_settings=Actualizar configuración
|
||||
settings.update_setting_success=La configuración de la organización se ha actualizado correctamente.
|
||||
@@ -772,24 +778,24 @@ teams.read_access=Acceso de Lectura
|
||||
teams.read_access_helper=Este equipo podrá ver y clonar sus repositorios.
|
||||
teams.write_access=Acceso de Escritura
|
||||
teams.write_access_helper=Este equipo podrá leer sus repositorios, así como hacer push en ellos.
|
||||
teams.admin_access=Acceso de Administrador
|
||||
teams.admin_access=Acceso de administrador
|
||||
teams.admin_access_helper=Este equipo podrá hacer push/pull en sus repositorios, así como añadir colaboradores a ellos.
|
||||
teams.no_desc=Este equipo no tiene descripción
|
||||
teams.settings=Configuración
|
||||
teams.owners_permission_desc=Los propietarios tienen acceso completo a <strong>todos los repositorios</strong> y tienen <strong>derechos de administración</strong> en la organización.
|
||||
teams.members=Miembros del Equipo
|
||||
teams.members=Miembros del equipo
|
||||
teams.update_settings=Actualizar configuración
|
||||
teams.delete_team=Borrar este Equipo
|
||||
teams.add_team_member=Añadir Miembro al Equipo
|
||||
teams.delete_team_title=Eliminar Equipo
|
||||
teams.delete_team=Eliminar este equipo
|
||||
teams.add_team_member=Añadir miembro al equipo
|
||||
teams.delete_team_title=Eliminar equipo
|
||||
teams.delete_team_desc=Este equipo va a ser eliminado, ¿seguro que quieres continuar? Los miembros de este equipo pueden perder acceso a algunos repositorios.
|
||||
teams.delete_team_success=El Equipo se ha eliminado correctamente.
|
||||
teams.delete_team_success=El equipo ha sido eliminado correctamente.
|
||||
teams.read_permission_desc=Este equipo tiene permisos de <strong>Lectura</strong>: sus miembros pueden ver y clonar los repositorios del equipo.
|
||||
teams.write_permission_desc=Este equipo tiene permisos de <strong>Escritura</strong>: sus miembros pueden leer y hacer push a los repositorios del equipo.
|
||||
teams.admin_permission_desc=Este equipo tiene permisos de <strong>Administración</strong>: sus miembros pueden leer, hacer push y añadir colaboradores a los repositorios del equipo.
|
||||
teams.repositories=Repositorios del Equipo
|
||||
teams.repositories=Repositorios del equipo
|
||||
teams.search_repo_placeholder=Buscar repositorio...
|
||||
teams.add_team_repository=Añadir Repositorio al Equipo
|
||||
teams.add_team_repository=Añadir repositorio al equipo
|
||||
teams.remove_repo=Eliminar
|
||||
teams.add_nonexistent_repo=El repositorio que estás intentando añadir no existe, por favor, créalo primero.
|
||||
|
||||
@@ -810,7 +816,7 @@ dashboard.statistic=Estadísticas
|
||||
dashboard.operations=Operaciones
|
||||
dashboard.system_status=Estado del Monitor del Sistema
|
||||
dashboard.statistic_info=La base de datos de Gogs contiene <b>%d</b> usuarios, <b>%d</b> organizaciones, <b>%d</b> claves públicas, <b>%d</b> repositorios, <b>%d</b> vigilados, <b>%d</b> destacados, <b>%d</b> acciones, <b>%d</b> accesos, <b>%d</b> incidencias, <b>%d</b> comentarios, <b>%d</b> cuentas de redes sociales, <b>%d</b> seguidores, <b>%d</b> mirrors, <b>%d</b> releases, <b>%d</b> fuentes de login, <b>%d</b> webhooks, <b>%d</b> milestones, <b>%d</b> etiquetas, <b>%d</b> hooks, <b>%d</b> equipos, <b>%d</b> tareas actualizadas, <b>%d</b> adjuntos.
|
||||
dashboard.operation_name=Nombre de la Operación
|
||||
dashboard.operation_name=Nombre de la operación
|
||||
dashboard.operation_switch=Interruptor
|
||||
dashboard.operation_run=Ejecutar
|
||||
dashboard.clean_unbind_oauth=Limpiar solicitudes de OAuth sin confirmar
|
||||
@@ -835,7 +841,7 @@ dashboard.current_goroutine=Gorutinas actuales
|
||||
dashboard.current_memory_usage=Uso de memoria actual
|
||||
dashboard.total_memory_allocated=Total de Memoria Reservada
|
||||
dashboard.memory_obtained=Memoria Obtenida
|
||||
dashboard.pointer_lookup_times=Tiempos de Búsqueda de Punteros
|
||||
dashboard.pointer_lookup_times=Tiempos de búsqueda de punteros
|
||||
dashboard.memory_allocate_times=Tiempos de Reserva de Memoria
|
||||
dashboard.memory_free_times=Tiempos de Liberado de Memoria
|
||||
dashboard.current_heap_usage=Uso de Heap actual
|
||||
@@ -872,7 +878,7 @@ users.new_success=La cuenta '%s' ha sido creada con éxito.
|
||||
users.edit=Editar
|
||||
users.auth_source=Fuente de Autenticación
|
||||
users.local=Local
|
||||
users.auth_login_name=Nombre de Inicio de Sesión de Autenticación
|
||||
users.auth_login_name=Nombre de Inicio de sesión de autenticación
|
||||
users.password_helper=Deje el campo vacío si no desea cambiar la contraseña.
|
||||
users.update_profile_success=El perfil de la cuenta se ha actualizado correctamente.
|
||||
users.edit_account=Editar Cuenta
|
||||
@@ -907,31 +913,31 @@ auths.name=Nombre
|
||||
auths.type=Tipo
|
||||
auths.enabled=Activo
|
||||
auths.updated=Actualizado
|
||||
auths.auth_type=Tipo de Autenticación
|
||||
auths.auth_name=Nombre de Autenticación
|
||||
auths.auth_type=Tipo de autenticación
|
||||
auths.auth_name=Nombre de autenticación
|
||||
auths.domain=Dominio
|
||||
auths.host=Host
|
||||
auths.port=Puerto
|
||||
auths.bind_dn=Bind DN
|
||||
auths.bind_password=Contraseña Bind
|
||||
auths.bind_password_helper=Advertencia: La contraseña se almacena como texto plano. No utilice una cuenta con privilegios elevados.
|
||||
auths.user_base=Base de Búsqueda de Usuarios
|
||||
auths.user_base=Base de búsqueda de usuarios
|
||||
auths.user_dn=DN de Usuario
|
||||
auths.attribute_username=Atributo de nombre de usuario
|
||||
auths.attribute_username_placeholder=Dejar vacío para usar el campo de inicio de sesión como nombre de usuario.
|
||||
auths.attribute_name=Atributo nombre
|
||||
auths.attribute_surname=Atributo apellido
|
||||
auths.attribute_mail=Atributo correo electrónico
|
||||
auths.attributes_in_bind=Fetch attributes in Bind DN context
|
||||
auths.filter=Filtro de Usuario
|
||||
auths.admin_filter=Filtro de Aministrador
|
||||
auths.attributes_in_bind=Buscar atributos en el contexto del Bind DN
|
||||
auths.filter=Filtro de usuario
|
||||
auths.admin_filter=Filtro de aministrador
|
||||
auths.ms_ad_sa=Ms Ad SA
|
||||
auths.smtp_auth=Tipo de Autenticación SMTP
|
||||
auths.smtp_auth=Tipo de autenticación SMTP
|
||||
auths.smtphost=SMTP Host
|
||||
auths.smtpport=Puerto SMTP
|
||||
auths.allowed_domains=Dominios Permitidos
|
||||
auths.allowed_domains_helper=Deje el campo vacío si no desea restringir ningún dominio. Para restringir más de uno, separe los dominios con una coma ','.
|
||||
auths.enable_tls=Habilitar Cifrado TLS
|
||||
auths.enable_tls=Habilitar cifrado TLS
|
||||
auths.skip_tls_verify=Omitir la verificación TLS
|
||||
auths.pam_service_name=Nombre del Servicio PAM
|
||||
auths.enable_auto_register=Hablilitar Auto-Registro
|
||||
@@ -944,9 +950,10 @@ auths.update=Actualizar la configuración de autenticación
|
||||
auths.delete=Eliminar Autenticación
|
||||
auths.delete_auth_title=Borrado de autenticación
|
||||
auths.delete_auth_desc=Esta autenticación será eliminada. ¿Deseas continuar?
|
||||
auths.still_in_used=Este método de autentificación aún es utilizado por algunos usuarios, por favor elimine o convierta estos usuarios a otro tipo de autentificación.
|
||||
auths.deletion_success=¡La autenticación ha sido eliminada con éxito!
|
||||
|
||||
config.server_config=Configuración del Servidor
|
||||
config.server_config=Configuración del servidor
|
||||
config.app_name=Nombre de la Aplicación
|
||||
config.app_ver=Versión de la Aplicación
|
||||
config.app_url=URL de la Aplicación
|
||||
@@ -960,16 +967,29 @@ config.static_file_root_path=Ruta de los Ficheros Estáticos
|
||||
config.log_file_root_path=Ruta de los Ficheros de Log
|
||||
config.script_type=Tipo de Script
|
||||
config.reverse_auth_user=Autenticación Inversa de Usuario
|
||||
|
||||
config.ssh_config=Configuración SSH
|
||||
config.ssh_enabled=Habilitado
|
||||
config.ssh_start_builtin_server=Iniciar servidor integrado
|
||||
config.ssh_domain=Dominio
|
||||
config.ssh_port=Puerto
|
||||
config.ssh_listen_port=Puerto de escucha
|
||||
config.ssh_root_path=Ruta raíz
|
||||
config.ssh_key_test_path=Ruta de la clave de prueba
|
||||
config.ssh_keygen_path=Ruta del generador de claves ('ssh-keygen')
|
||||
config.ssh_minimum_key_size_check=Tamaño mínimo de la clave de verificación
|
||||
config.ssh_minimum_key_sizes=Tamaños de clave mínimos
|
||||
|
||||
config.db_config=Configuración de la Base de Datos
|
||||
config.db_type=Tipo
|
||||
config.db_host=Host
|
||||
config.db_name=Nombre
|
||||
config.db_user=Usuario
|
||||
config.db_ssl_mode=Modo SSL
|
||||
config.db_ssl_mode_helper=(solo para "postgres")
|
||||
config.db_ssl_mode_helper=(sólo para "postgres")
|
||||
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.register_email_confirm=Solicitar Confirmación por Correo Electrónico
|
||||
config.disable_register=Deshabilitar el Registro
|
||||
config.show_registration_button=Mostrar Botón de Registro
|
||||
@@ -983,12 +1003,15 @@ config.webhook_config=Configuración de Webhooks
|
||||
config.queue_length=Tamaño de Cola de Envío
|
||||
config.deliver_timeout=Timeout de Entrega
|
||||
config.skip_tls_verify=Omitir la Verificación TLS
|
||||
config.mailer_config=Configuración del Mailer
|
||||
config.mailer_config=Configuración del servidor de correo
|
||||
config.mailer_enabled=Activado
|
||||
config.mailer_disable_helo=Desactivar HELO
|
||||
config.mailer_name=Nombre
|
||||
config.mailer_host=Host
|
||||
config.mailer_user=Usuario
|
||||
config.send_test_mail=Enviar email de prueba
|
||||
config.test_mail_failed=Fallo al enviar el email de prueba a '%s': %v
|
||||
config.test_mail_sent=El email de prueba ha sido enviado a '%s'.
|
||||
config.oauth_config=Configuración OAuth
|
||||
config.oauth_enabled=Activado
|
||||
config.cache_config=Configuración de la Caché
|
||||
@@ -1040,9 +1063,11 @@ create_repo=creó el repositorio <a href="%s">%s</a>
|
||||
rename_repo=repositorio renombrado de <code>%[1]s</code> a <a href="%[2]s">%[3]s</a>
|
||||
commit_repo=hizo push a <a href="%[1]s/src/%[2]s">%[3]s</a> en <a href="%[1]s">%[4]s</a>
|
||||
create_issue=`incidencia abierta <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
close_issue=`cerró la incidencia <a href="%s/issues/%s">%s#%[2]s"</a>`
|
||||
close_issue=`cerró la incidencia <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
reopen_issue=`reabrió la incidencia <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
create_pull_request=`creado pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
close_pull_request=`cerró el pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
reopen_pull_request=`reabrió el pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
comment_issue=`comentó en la incidencia <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
merge_pull_request=`fusionado pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
transfer_repo=transfirió el repositorio <code>%s</code> a <a href="%s">%s</a>
|
||||
|
||||
1103
conf/locale/locale_fi-FI.ini
Executable file
1103
conf/locale/locale_fi-FI.ini
Executable file
File diff suppressed because it is too large
Load Diff
@@ -76,7 +76,7 @@ app_name=Nom de l'application
|
||||
app_name_helper=Inscrivez fièrement le nom de votre organisation ici !
|
||||
repo_path=Emplacement racine des dépôts
|
||||
repo_path_helper=Tous les dépôts Git distants seront sauvegardés ici.
|
||||
run_user=Entrer un utilisateur
|
||||
run_user=Utilisateur système
|
||||
run_user_helper=L'utilisateur doit avoir accès à la racine des dépôts et exécuter Gogs.
|
||||
domain=Domaine
|
||||
domain_helper=Cela affecte les doublons d'URL SSH.
|
||||
@@ -221,8 +221,6 @@ still_own_repo=Votre compte comporte toujours des propriétés du dépôt. Vous
|
||||
still_has_org=Votre compte contient toujours au moins une adhésion à une organisation, vous devez quitter ou supprimer votre adhésion.
|
||||
org_still_own_repo=Cette organisation comporte toujours des propriétés du dépôt. Vous devez d'abord les supprimer ou les transférer.
|
||||
|
||||
still_own_user=Cette authentification a déjà servi à d'autres utilisateurs. Veuillez les déplacer puis supprimez à nouveau.
|
||||
|
||||
target_branch_not_exist=La branche cible n'existe pas.
|
||||
|
||||
[user]
|
||||
@@ -230,8 +228,8 @@ change_avatar=Changez d'avatar via gravatar.com
|
||||
change_custom_avatar=Changez votre avatar dans les paramètres
|
||||
join_on=Inscrit le
|
||||
repositories=Dépôts
|
||||
activity=Activités publiques
|
||||
followers=Abonnés
|
||||
activity=Activité publique
|
||||
followers=abonnés
|
||||
starred=Votés
|
||||
following=Abonnements
|
||||
follow=Suivre
|
||||
@@ -264,15 +262,14 @@ continue=Continuer
|
||||
cancel=Annuler
|
||||
|
||||
enable_custom_avatar=Activer l'Avatar personnalisé
|
||||
enable_custom_avatar_helper=Cette option désactive l'affichage via Gravatar
|
||||
choose_new_avatar=Sélectionner un nouvel avatar
|
||||
update_avatar=Mettre à jour l'avatar
|
||||
delete_current_avatar=Delete Current Avatar
|
||||
uploaded_avatar_not_a_image=Le fichier téléchargé n'est pas une image.
|
||||
no_custom_avatar_available=Aucun avatar personnalisé disponible, activation impossible.
|
||||
update_avatar_success=Votre avatar a été mis à jour avec succès.
|
||||
|
||||
change_password=Modifier le Mot de Passe
|
||||
old_password=Mot de Passe actuel
|
||||
change_password=Modifier le mot de passe
|
||||
old_password=Mot de passe actuel
|
||||
new_password=Nouveau Mot de Passe
|
||||
retype_new_password=Retapez le nouveau mot de passe
|
||||
password_incorrect=Mot de passe actuel incorrect.
|
||||
@@ -288,10 +285,10 @@ delete_email=Supprimer
|
||||
email_deletion=Suppression de l'adresse mél
|
||||
email_deletion_desc=Supprimer cette adresse e-mail supprimera les informations associées à votre compte. Voulez-vous continuer ?
|
||||
email_deletion_success=L'adresse mél a été supprimée avec succès !
|
||||
add_new_email=Ajouter une nouvelle adresse courriel
|
||||
add_email=Ajouter un courriel
|
||||
add_new_email=Ajouter une nouvelle adresse e-mail
|
||||
add_email=Ajouter un e-mail
|
||||
add_email_confirmation_sent=Une nouvelle confirmation d'adresse e-mail a été envoyé à '%s', veuillez vérifier votre boîte de réception dans un délai de %d heures pour terminer le processus de confirmation.
|
||||
add_email_success=Votre courriel a été ajouté avec succès.
|
||||
add_email_success=Votre nouvelle adresse e-mail a été ajoutée avec succès.
|
||||
|
||||
manage_ssh_keys=Gérer les clés SSH
|
||||
add_key=Ajouter une Clé
|
||||
@@ -370,7 +367,7 @@ form.name_reserved=Le nom de dépôt '%s' est réservé.
|
||||
form.name_pattern_not_allowed=Motif '%s' interdit pour les noms de dépôt.
|
||||
|
||||
need_auth=Nécessite une Autorisation
|
||||
migrate_type=Type de Migration
|
||||
migrate_type=Type de migration
|
||||
migrate_type_helper=Ce dépôt sera un <span class="text blue"> miroir</span>
|
||||
migrate_repo=Migrer le dépôt
|
||||
migrate.clone_address=Adresse du clone
|
||||
@@ -405,7 +402,7 @@ tree=Aborescence
|
||||
filter_branch_and_tag=Filtrer une branche ou un tag
|
||||
branches=Branches
|
||||
tags=Tags
|
||||
issues=Problèmes
|
||||
issues=Tickets
|
||||
pulls=Pull Requests
|
||||
labels=Etiquettes
|
||||
milestones=Étapes
|
||||
@@ -425,7 +422,7 @@ commits.date=Date
|
||||
commits.older=Précédemment
|
||||
commits.newer=Récemment
|
||||
|
||||
issues.new=Nouveau Problème
|
||||
issues.new=Nouveau ticket
|
||||
issues.new.labels=Etiquettes
|
||||
issues.new.no_label=Pas d'étiquette
|
||||
issues.new.clear_labels=Effacer les étiquettes
|
||||
@@ -450,9 +447,9 @@ issues.filter_milestone_no_select=Aucun jalon sélectionné
|
||||
issues.filter_assignee=Assigné
|
||||
issues.filter_assginee_no_select=Pas d'assignataire selectionné
|
||||
issues.filter_type=Type
|
||||
issues.filter_type.all_issues=Tous les problèmes
|
||||
issues.filter_type.all_issues=Tous les tickets
|
||||
issues.filter_type.assigned_to_you=Qui vous sont assignés
|
||||
issues.filter_type.created_by_you=Créé(es) par vous
|
||||
issues.filter_type.created_by_you=Crées par vous
|
||||
issues.filter_type.mentioning_you=Vous mentionnant
|
||||
issues.filter_sort=Trier
|
||||
issues.filter_sort.latest=Plus récent
|
||||
@@ -479,7 +476,7 @@ issues.closed_at=`fermé à <a id="%[1]s"href="#%[1]s"> %[2]s"</a>`
|
||||
issues.reopened_at=`réouvert à <a id="%[1]s" href="#%[1]s"> %[2]s</a>`
|
||||
issues.commit_ref_at=`a référencé ce problème à partir d'un commit <a id="%[1]s" href="#%[1]s"> %[2]s</a>`
|
||||
issues.poster=Publier
|
||||
issues.admin=Admin
|
||||
issues.collaborator=Collaborator
|
||||
issues.owner=Propriétaire
|
||||
issues.sign_up_for_free=Inscrivez-vous gratuitement
|
||||
issues.sign_in_require_desc=pour rejoindre cette conversation. Vous avez déjà un compte ? <a href="%s">Connectez-vous commenter</a>
|
||||
@@ -489,12 +486,12 @@ issues.save=Enregistrer
|
||||
issues.label_title=Nom du Label
|
||||
issues.label_color=Couleur du Label
|
||||
issues.label_count=%d labels
|
||||
issues.label_open_issues=%d problèmes ouverts
|
||||
issues.label_open_issues=%d tickets ouverts
|
||||
issues.label_edit=Éditer
|
||||
issues.label_delete=Supprimer
|
||||
issues.label_modify=Modification du Label
|
||||
issues.label_deletion=Suppression du Label
|
||||
issues.label_deletion_desc=Cette opération supprimera également toutes les informations relatives aux problèmes. Voulez-vous continuer ?
|
||||
issues.label_deletion_desc=Cette opération supprimera également toutes les informations relatives aux tickets. Voulez-vous continuer ?
|
||||
issues.label_deletion_success=Label supprimé avec succès !
|
||||
issues.num_participants=%d Participants
|
||||
|
||||
@@ -531,7 +528,7 @@ milestones.closed=%s fermé
|
||||
milestones.no_due_date=Aucune date d'échéance
|
||||
milestones.open=Ouvrir
|
||||
milestones.close=Fermer
|
||||
milestones.new_subheader=Créez des jalons pour organiser vos problèmes.
|
||||
milestones.new_subheader=Créez des jalons pour organiser vos tickets.
|
||||
milestones.create=Créer un Jalon
|
||||
milestones.title=Titre
|
||||
milestones.desc=Description
|
||||
@@ -545,7 +542,7 @@ milestones.cancel=Annuler
|
||||
milestones.modify=Modifier le Jalon
|
||||
milestones.edit_success=Le Jalon '%s' a été modifié avec succès !
|
||||
milestones.deletion=Supprimer le Jalon
|
||||
milestones.deletion_desc=Supprimer ce Jalon effacera ses informations dans tous les problèmes relatifs. Voulez-vous continuer ?
|
||||
milestones.deletion_desc=Supprimer ce jalon effacera ses informations dans tous les tickets relatifs. Voulez-vous continuer ?
|
||||
milestones.deletion_success=Le Jalon a été supprimé avec succès !
|
||||
|
||||
wiki=Wiki
|
||||
@@ -560,6 +557,8 @@ wiki.save_page=Enregistrer la page
|
||||
wiki.last_commit_info=%s a édité cette page %s
|
||||
wiki.edit_page_button=Modifier
|
||||
wiki.new_page_button=Nouvelle Page
|
||||
wiki.delete_page_button=Delete Page
|
||||
wiki.delete_page_notice_1=This will delete the page <code>"%s"</code>. Please be certain.
|
||||
wiki.page_already_exists=Une page de wiki avec le même nom existe déjà.
|
||||
wiki.pages=Pages
|
||||
wiki.last_updated=Dernière mise à jour: %s
|
||||
@@ -587,7 +586,7 @@ settings.danger_zone=Zone de danger
|
||||
settings.new_owner_has_same_repo=Le nouveau propriétaire a déjà un dépôt nommé ainsi.
|
||||
settings.convert=Convertir en dépôt ordinaire
|
||||
settings.convert_desc=Vous pouvez convertir ce miroir en dépôt ordinaire. Cela ne peut pas être inversée.
|
||||
settings.convert_notices_1=- This operation will convert this repository mirror into a regular repository and cannot be undone.
|
||||
settings.convert_notices_1=- Cette opération va convertir ce dépôt miroir en un dépôt standard et ne peut être annulée.
|
||||
settings.convert_confirm=Confirmer la conversion
|
||||
settings.convert_succeed=Le dépôt a été converti avec succès en dépôt ordinaire.
|
||||
settings.transfer=Changer de propriétaire
|
||||
@@ -595,10 +594,14 @@ settings.transfer_desc=Transférer ce dépôt à un autre utilisateur ou une org
|
||||
settings.transfer_notices_1=-Vous perdrez l'accès si le nouveau propriétaire est un utilisateur individuel.
|
||||
settings.transfer_notices_2=- Vous conserverez l'accès si le nouveau propriétaire est une organisation et que vous y appartenez.
|
||||
settings.transfer_form_title=Veuillez recopier le texte suivant afin de confirmer votre opération :
|
||||
settings.wiki_delete=Erase Wiki Data
|
||||
settings.wiki_delete_desc=Once you erase wiki data there is no going back. Please be certain.
|
||||
settings.wiki_delete_notices_1=- This will delete and disable the wiki for %s
|
||||
settings.wiki_deletion_success=Repository wiki data have been erased successfully.
|
||||
settings.delete=Supprimer ce dépôt
|
||||
settings.delete_desc=Attention, cette action est action irréversible. Soyez sûr de vous.
|
||||
settings.delete_notices_1=- Cette opération <strong>ne peut pas </strong> être annulée.
|
||||
settings.delete_notices_2=- Cette opération supprimera définitivement le dépôt, y compris les données Git, les issues, les commentaires et les accès des collaborateurs.
|
||||
settings.delete_notices_2=- Cette opération supprimera définitivement le dépôt, y compris les données Git, les tickets, les commentaires et les accès des collaborateurs.
|
||||
settings.delete_notices_fork_1=- Si ce dépôt est public, tous les forks vont devenir indépendant après sa suppression.
|
||||
settings.delete_notices_fork_2=-Si ce dépôt est privé, tous les forks seront supprimés en même temps.
|
||||
settings.delete_notices_fork_3=-Si vous souhaitez conserver tous les forks après suppression, veuillez tout d'abord modifier la visibilité de ce dépôt en public.
|
||||
@@ -610,9 +613,12 @@ settings.transfer_succeed=Le contrôle du dépôt a été transféré avec succ
|
||||
settings.confirm_delete=Confirmer la suppression
|
||||
settings.add_collaborator=Ajouter un collaborateur
|
||||
settings.add_collaborator_success=Nouveau collaborateur ajouté.
|
||||
settings.delete_collaborator=Delete
|
||||
settings.collaborator_deletion=Collaborator Deletion
|
||||
settings.collaborator_deletion_desc=This user will no longer have collaboration access to this repository after deletion. Do you want to continue?
|
||||
settings.remove_collaborator_success=Collaborateur supprimé.
|
||||
settings.search_user_placeholder=Rechercher un utilisateur...
|
||||
settings.org_not_allowed_to_be_collaborator=Organization is not allowed to be added as a collaborator.
|
||||
settings.org_not_allowed_to_be_collaborator=Une organisation n'est pas autorisée à être ajoutée en tant que collaborateur.
|
||||
settings.user_is_org_member=Cet utilisateur ne peut pas être ajouté en tant que collaborateur car il fait partie d'une organisation.
|
||||
settings.add_webhook=Ajouter un Webhook
|
||||
settings.hooks_desc=Les Webhooks sont des déclencheurs de POST HTTP . Lorsque qu'un événement se produit dans Gogs, une notification sera envoyée vers l'hôte cible préalablement spécifié. Apprenez-en davantage dans le <a target="_blank" href="%s">Guide des Webhooks</a>.
|
||||
@@ -809,7 +815,7 @@ total=Total : %d
|
||||
dashboard.statistic=Statistiques
|
||||
dashboard.operations=Opérations
|
||||
dashboard.system_status=État du système
|
||||
dashboard.statistic_info=La base de données Gogs contient <b>%d</b> utilisateurs, <b>%d</b> organisations, <b>%d</b> clés publiques, <b>%d</b> dépôts, <b>%d</b> surveillances de dépôts, <b>%d</b> votes, <b>%d</b> actions, <b>%d</b> accès, <b>%d</b> problèmes, <b>%d</b> commentaires, <b>%d</b> comptes de réseaux sociaux, <b>%d</b> abonnements, <b>%d</b> miroirs, <b>%d</b> versions, <b>%d</b> connexions d'origine, <b>%d</b> webhooks, <b>%d</b> versions, <b>%d</b> labels, <b>%d</b> tâches hook, <b>%d</b> équipes, <b>%d</b> tâches de mise à jour, <b>%d</b> fichiers.
|
||||
dashboard.statistic_info=La base de données Gogs contient <b>%d</b> utilisateurs, <b>%d</b> organisations, <b>%d</b> clés publiques, <b>%d</b> dépôts, <b>%d</b> surveillances de dépôts, <b>%d</b> votes, <b>%d</b> actions, <b>%d</b> accès, <b>%d</b> tickets, <b>%d</b> commentaires, <b>%d</b> comptes de réseaux sociaux, <b>%d</b> abonnements, <b>%d</b> miroirs, <b>%d</b> versions, <b>%d</b> connexions d'origine, <b>%d</b> webhooks, <b>%d</b> versions, <b>%d</b> labels, <b>%d</b> tâches hook, <b>%d</b> équipes, <b>%d</b> tâches de mise à jour, <b>%d</b> fichiers.
|
||||
dashboard.operation_name=Nom de l'Opération
|
||||
dashboard.operation_switch=Basculer
|
||||
dashboard.operation_run=Exécuter
|
||||
@@ -899,7 +905,7 @@ repos.name=Nom
|
||||
repos.private=Privé
|
||||
repos.watches=Suivi par
|
||||
repos.stars=Votes
|
||||
repos.issues=Problèmes
|
||||
repos.issues=Tickets
|
||||
|
||||
auths.auth_manage_panel=Panel d'administration des authentifications
|
||||
auths.new=Ajouter une nouvelle source d'authentification
|
||||
@@ -922,7 +928,7 @@ auths.attribute_username_placeholder=Laisser vide pour utiliser la valeur du for
|
||||
auths.attribute_name=Attribut du prénom
|
||||
auths.attribute_surname=Attribut du nom de famille
|
||||
auths.attribute_mail=Attribut de l'e-mail
|
||||
auths.attributes_in_bind=Fetch attributes in Bind DN context
|
||||
auths.attributes_in_bind=Aller chercher les attributs dans le contexte de liaison DN
|
||||
auths.filter=Filtre utilisateur
|
||||
auths.admin_filter=Filtre administrateur
|
||||
auths.ms_ad_sa=Ms Ad SA
|
||||
@@ -944,6 +950,7 @@ auths.update=Mettre à jour les paramètres d'authentifications
|
||||
auths.delete=Supprimer cette authentification
|
||||
auths.delete_auth_title=Suppression de l'authentification
|
||||
auths.delete_auth_desc=Cette authentification va être supprimée. voulez-vous continuer ?
|
||||
auths.still_in_used=This authentication is still used by some users, please delete or convert these users to another login type first.
|
||||
auths.deletion_success=L'authentification a été supprimée avec succès !
|
||||
|
||||
config.server_config=Configuration du Serveur
|
||||
@@ -953,13 +960,26 @@ config.app_url=URL de l'application
|
||||
config.domain=Domaine
|
||||
config.offline_mode=Mode hors-ligne
|
||||
config.disable_router_log=Désactiver la Journalisation du Routeur
|
||||
config.run_user=Entrer un Utilisateur
|
||||
config.run_user=Utilisateur système
|
||||
config.run_mode=Mode d'Éxécution
|
||||
config.repo_root_path=Emplacement des Dépôts
|
||||
config.static_file_root_path=Chemin statique des fichiers racines
|
||||
config.log_file_root_path=Emplacement Racine du Fichier Journal
|
||||
config.script_type=Type de Script
|
||||
config.reverse_auth_user=Annuler l'Authentification de l'Utilisateur
|
||||
|
||||
config.ssh_config=Configuration SSH
|
||||
config.ssh_enabled=Activé
|
||||
config.ssh_start_builtin_server=Démarrer le serveur intégré
|
||||
config.ssh_domain=Domaine
|
||||
config.ssh_port=Port
|
||||
config.ssh_listen_port=Port d'écoute
|
||||
config.ssh_root_path=Emplacement racine
|
||||
config.ssh_key_test_path=Emplacement de test des clés
|
||||
config.ssh_keygen_path=Chemin vers le générateur de clefs ("ssh-keygen")
|
||||
config.ssh_minimum_key_size_check=Minimum Key Size Check
|
||||
config.ssh_minimum_key_sizes=Tailles de clé minimales
|
||||
|
||||
config.db_config=Configuration de la Base de Données
|
||||
config.db_type=Type
|
||||
config.db_host=Hôte
|
||||
@@ -970,11 +990,11 @@ config.db_ssl_mode_helper=("postgres" uniquement)
|
||||
config.db_path=Emplacement
|
||||
config.db_path_helper=(pour « sqlite3 » et « TIDB »)
|
||||
config.service_config=Configuration du Service
|
||||
config.register_email_confirm=Nécessite une confirmation par courriel
|
||||
config.register_email_confirm=Nécessite une confirmation par e-mail
|
||||
config.disable_register=Désactiver les inscriptions
|
||||
config.show_registration_button=Afficher le bouton d'enregistrement
|
||||
config.require_sign_in_view=Connexion obligatoire pour visualiser
|
||||
config.mail_notify=Mailer les Notifications
|
||||
config.mail_notify=Notifier par mail
|
||||
config.disable_key_size_check=Désactiver la vérification de la taille de clé minimale
|
||||
config.enable_captcha=Activez le Captcha
|
||||
config.active_code_lives=Limites de Code Actif
|
||||
@@ -983,12 +1003,15 @@ config.webhook_config=Configuration Webhook
|
||||
config.queue_length=Longueur de la file d'attente
|
||||
config.deliver_timeout=Expiration d'Envoi
|
||||
config.skip_tls_verify=Ne pas vérifier TLS
|
||||
config.mailer_config=Configuration du Maileur
|
||||
config.mailer_config=Configuration du service de mail
|
||||
config.mailer_enabled=Activé
|
||||
config.mailer_disable_helo=Désactiver HELO
|
||||
config.mailer_name=Nom
|
||||
config.mailer_host=Hôte
|
||||
config.mailer_user=Utilisateur
|
||||
config.send_test_mail=Envoyer courriel de Test
|
||||
config.test_mail_failed=Impossible d'envoyer un e-mail de test à '%s': %v
|
||||
config.test_mail_sent=Un e-mail de test à été envoyé à '%s'.
|
||||
config.oauth_config=Configuration OAuth
|
||||
config.oauth_enabled=Activé
|
||||
config.cache_config=Configuration du Cache
|
||||
@@ -1040,9 +1063,11 @@ create_repo=a créé le dépôt <a href="%s">%s</a>
|
||||
rename_repo=rebaptisé le dépôt de <code>%[1]s</code> à <a href="%[2]s">%[3]s</a>
|
||||
commit_repo=a soumis à <a href="%[1]s/src/%[2]s">%[3]s</a> sur <a href="%[1]s">%[4]s</a>
|
||||
create_issue=`a ouvert un problème <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
close_issue=`closed issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
reopen_issue=`reopened issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
close_issue=`tickets clos <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
reopen_issue=`tickets ré-ouverts <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
create_pull_request=`pull request créée le <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
close_pull_request=`closed pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
reopen_pull_request=`reopened pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
comment_issue=`a commenté le problème <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
merge_pull_request=`pull request fusionné le <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
transfer_repo=a transféré le dépôt <code>%s</code> à <a href="%s">%s</a>
|
||||
|
||||
@@ -38,7 +38,7 @@ settings=Impostazioni
|
||||
your_profile=Il tuo profilo
|
||||
your_settings=Impostazioni
|
||||
|
||||
activities=Activities
|
||||
activities=Attivitá
|
||||
pull_requests=Pull Request
|
||||
issues=Problemi
|
||||
|
||||
@@ -86,8 +86,8 @@ http_port=Porta HTTP
|
||||
http_port_helper=Porta di ascolto dell'applicazione.
|
||||
app_url=URL Applicazione
|
||||
app_url_helper=Questo influisce sugli URL per il clonaggio via HTTP/HTTPS e da qualche parte nella posta elettronica.
|
||||
log_root_path=Log Path
|
||||
log_root_path_helper=Directory to write log files to.
|
||||
log_root_path=Percorso dei log
|
||||
log_root_path_helper=Directory in cui scrivere i file di log.
|
||||
|
||||
optional_title=Impostazioni Facoltative
|
||||
email_title=Impostazioni E-mail
|
||||
@@ -221,8 +221,6 @@ still_own_repo=Il tuo account possiede ancora almeno un repository, dovete prima
|
||||
still_has_org=Il tuo account è ancora associato ad almeno un'organizzazione, disassociarsi prima.
|
||||
org_still_own_repo=Questa organizzazione ha ancora la proprietà del repository, dovete cancellarla o trasferirli prima.
|
||||
|
||||
still_own_user=Questa autenticazione è ancora in uso da almeno un utente, per favore rimuovili dall'autenticazione e riprova.
|
||||
|
||||
target_branch_not_exist=Il ramo (branch) di destinazione non esiste.
|
||||
|
||||
[user]
|
||||
@@ -264,11 +262,10 @@ continue=Continua
|
||||
cancel=Annulla
|
||||
|
||||
enable_custom_avatar=Abilita avatar personalizzato
|
||||
enable_custom_avatar_helper=Seleziona per disabilitare il fetch da Gravatar
|
||||
choose_new_avatar=Scegli un nuovo avatar
|
||||
update_avatar=Aggiorna le impostazioni avatar
|
||||
delete_current_avatar=Delete Current Avatar
|
||||
uploaded_avatar_not_a_image=Il file caricato non è un'immagine.
|
||||
no_custom_avatar_available=Nessun avatar personalizzato disponibile, impossibile abilitarlo.
|
||||
update_avatar_success=Le tue impostazioni avatar sono state aggiornate con successo.
|
||||
|
||||
change_password=Cambia Password
|
||||
@@ -479,7 +476,7 @@ issues.closed_at=`closed <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.reopened_at=`reopened <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.commit_ref_at=`referenced this issue from a commit <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.poster=Autore
|
||||
issues.admin=Amministratore
|
||||
issues.collaborator=Collaborator
|
||||
issues.owner=Proprietario
|
||||
issues.sign_up_for_free=Registrati gratuitamente
|
||||
issues.sign_in_require_desc=to join this conversation. Already have an account? <a href="%s">Sign in to comment</a>
|
||||
@@ -496,7 +493,7 @@ issues.label_modify=Modifica Etichetta
|
||||
issues.label_deletion=Elimina Etichetta
|
||||
issues.label_deletion_desc=Eliminare l'etichetta rimuovera le sue informazioni in tutti i problemi correlati. Vuoi continuare?
|
||||
issues.label_deletion_success=Etichetta eliminata con successo!
|
||||
issues.num_participants=%d Participants
|
||||
issues.num_participants=%d Partecipanti
|
||||
|
||||
pulls.new=Nuova Pull Request
|
||||
pulls.compare_changes=Confronta le modifiche
|
||||
@@ -511,13 +508,13 @@ pulls.create=Crea Pull Request
|
||||
pulls.title_desc=wants to merge %[1]d commits from <code>%[2]s</code> into <code>%[3]s</code>
|
||||
pulls.merged_title_desc=merged %[1]d commits from <code>%[2]s</code> into <code>%[3]s</code> %[4]s
|
||||
pulls.tab_conversation=Conversazione
|
||||
pulls.tab_commits=Commits
|
||||
pulls.tab_commits=Commit
|
||||
pulls.tab_files=File modificati
|
||||
pulls.reopen_to_merge=Riapri questa pull request per effettuare il merge.
|
||||
pulls.merged=Merged
|
||||
pulls.has_merged=This pull request has been merged successfully!
|
||||
pulls.data_broken=Data of this pull request has been broken due to deletion of fork information.
|
||||
pulls.is_checking=The conflict checking is still in progress, please refresh page in few moments.
|
||||
pulls.is_checking=Il controllo dei conflitti è ancora in corso, per favore aggiorna pagina tra qualche istante.
|
||||
pulls.can_auto_merge_desc=This pull request can be merged automatically.
|
||||
pulls.cannot_auto_merge_desc=This pull request can't be merged automatically because there are conflicts.
|
||||
pulls.cannot_auto_merge_helper=Effettua il merge manualmente per risolvere i conflitti.
|
||||
@@ -560,6 +557,8 @@ wiki.save_page=Salva pagina
|
||||
wiki.last_commit_info=%s ha modificato questa pagina %s
|
||||
wiki.edit_page_button=Modifica
|
||||
wiki.new_page_button=Nuova pagina
|
||||
wiki.delete_page_button=Delete Page
|
||||
wiki.delete_page_notice_1=This will delete the page <code>"%s"</code>. Please be certain.
|
||||
wiki.page_already_exists=Esiste già una pagina Wiki con questo stesso nome.
|
||||
wiki.pages=Pagine
|
||||
wiki.last_updated=Ultimo aggiornamento: %s
|
||||
@@ -588,13 +587,17 @@ settings.new_owner_has_same_repo=Il nuovo proprietario ha già un repository con
|
||||
settings.convert=Convert To Regular Repository
|
||||
settings.convert_desc=You can convert this mirror to a regular repository. This cannot be reversed.
|
||||
settings.convert_notices_1=- This operation will convert this repository mirror into a regular repository and cannot be undone.
|
||||
settings.convert_confirm=Confirm Conversion
|
||||
settings.convert_confirm=Conferma la conversione
|
||||
settings.convert_succeed=Repository has been converted to regular type successfully.
|
||||
settings.transfer=Trasferisci proprietà
|
||||
settings.transfer_desc=Trasferisci questa repository a un altro utente o a un'organizzazione nella quale hai diritti d'amministratore.
|
||||
settings.transfer_notices_1=- You will lose access if new owner is a individual user.
|
||||
settings.transfer_notices_2=- You will conserve access if new owner is an organization and if you're one of the owners.
|
||||
settings.transfer_form_title=Per favore inserisci le informazioni seguenti per confermare l'operazione:
|
||||
settings.wiki_delete=Erase Wiki Data
|
||||
settings.wiki_delete_desc=Once you erase wiki data there is no going back. Please be certain.
|
||||
settings.wiki_delete_notices_1=- This will delete and disable the wiki for %s
|
||||
settings.wiki_deletion_success=Repository wiki data have been erased successfully.
|
||||
settings.delete=Elimina questo repository
|
||||
settings.delete_desc=Una volta che hai cancellato il repository, non puoi tornare indietro. Si prega di fare attenzione.
|
||||
settings.delete_notices_1=-Questa operazione <strong>NON PUÒ</strong> essere annullata.
|
||||
@@ -610,9 +613,12 @@ settings.transfer_succeed=Proprietà del repository trasferita con successo.
|
||||
settings.confirm_delete=Conferma eliminazione
|
||||
settings.add_collaborator=Aggiungi nuovo collaboratore
|
||||
settings.add_collaborator_success=Il nuovo collaboratore è stato aggiunto.
|
||||
settings.delete_collaborator=Delete
|
||||
settings.collaborator_deletion=Collaborator Deletion
|
||||
settings.collaborator_deletion_desc=This user will no longer have collaboration access to this repository after deletion. Do you want to continue?
|
||||
settings.remove_collaborator_success=Il collaboratore è stato rimosso.
|
||||
settings.search_user_placeholder=Cerca utente...
|
||||
settings.org_not_allowed_to_be_collaborator=Organization is not allowed to be added as a collaborator.
|
||||
settings.org_not_allowed_to_be_collaborator=Un'organizzazione non può essere aggiunta come collaboratore.
|
||||
settings.user_is_org_member=L'utente è un membro dell'organizzazione che non può essere aggiunto come collaboratore.
|
||||
settings.add_webhook=Aggiungi Webhook
|
||||
settings.hooks_desc=I Webhooks sono molto simili a un basilare evento trigger HTTP POST. Ogni volta che qualcosa si verifica in Gogs, tratteremo la notifica all'host di destinazione specificato. Ulteriori informazioni in questa <a target="_blank" href="%s">Guida ai Webhooks</a>.
|
||||
@@ -638,12 +644,12 @@ settings.content_type=Content Type
|
||||
settings.secret=Secret
|
||||
settings.slack_username=Username
|
||||
settings.slack_icon_url=URL icona
|
||||
settings.slack_color=Color
|
||||
settings.slack_color=Colore
|
||||
settings.event_desc=Quali eventi dovrebbero innescare questo webhook?
|
||||
settings.event_push_only=Solo l'evento <code>push</code>.
|
||||
settings.event_send_everything=I need <strong>everything</strong>.
|
||||
settings.event_choose=Let me choose what I need.
|
||||
settings.event_create=Create
|
||||
settings.event_create=Crea
|
||||
settings.event_create_desc=Branch, or tag created
|
||||
settings.event_push=Push
|
||||
settings.event_push_desc=Git push to a repository
|
||||
@@ -716,7 +722,7 @@ release.downloads=Download
|
||||
|
||||
[org]
|
||||
org_name_holder=Nome dell'Organizzazione
|
||||
org_full_name_holder=Organization Full Name
|
||||
org_full_name_holder=Nome completo dell'organizzazione
|
||||
org_name_helper=Le migliori organizzazioni hanno nomi brevi e memorabili.
|
||||
create_org=Crea Organizzazione
|
||||
repo_updated=Aggiornato
|
||||
@@ -802,8 +808,8 @@ authentication=Autenticazioni
|
||||
config=Configurazione
|
||||
notices=Avvisi di sistema
|
||||
monitor=Monitoraggio
|
||||
first_page=First
|
||||
last_page=Last
|
||||
first_page=Prima
|
||||
last_page=Ultima
|
||||
total=Totale: %d
|
||||
|
||||
dashboard.statistic=Statistiche
|
||||
@@ -929,7 +935,7 @@ auths.ms_ad_sa=Ms Ad SA
|
||||
auths.smtp_auth=SMTP Authentication Type
|
||||
auths.smtphost=Host SMTP
|
||||
auths.smtpport=Porta SMTP
|
||||
auths.allowed_domains=Allowed Domains
|
||||
auths.allowed_domains=Domini consentiti
|
||||
auths.allowed_domains_helper=Leave it empty to not restrict any domains. Multiple domains should be separated by comma ','.
|
||||
auths.enable_tls=Abilitare Crittografia TLS
|
||||
auths.skip_tls_verify=Salta verifica TLS
|
||||
@@ -944,6 +950,7 @@ auths.update=Update Authentication Setting
|
||||
auths.delete=Delete This Authentication
|
||||
auths.delete_auth_title=Authentication Deletion
|
||||
auths.delete_auth_desc=This authentication is going to be deleted, do you want to continue?
|
||||
auths.still_in_used=This authentication is still used by some users, please delete or convert these users to another login type first.
|
||||
auths.deletion_success=Authentication has been deleted successfully!
|
||||
|
||||
config.server_config=Configurazione Server
|
||||
@@ -960,6 +967,19 @@ config.static_file_root_path=Percorso Root del File Statico
|
||||
config.log_file_root_path=Percorso Root del File di Log
|
||||
config.script_type=Tipo di Script
|
||||
config.reverse_auth_user=Autenticazione Utente Inversa
|
||||
|
||||
config.ssh_config=Configurazione SSH
|
||||
config.ssh_enabled=Enabled
|
||||
config.ssh_start_builtin_server=Start Builtin Server
|
||||
config.ssh_domain=Domain
|
||||
config.ssh_port=Porta
|
||||
config.ssh_listen_port=Porta in ascolto
|
||||
config.ssh_root_path=Root Path
|
||||
config.ssh_key_test_path=Key Test Path
|
||||
config.ssh_keygen_path=Keygen ('ssh-keygen') Path
|
||||
config.ssh_minimum_key_size_check=Minimum Key Size Check
|
||||
config.ssh_minimum_key_sizes=Minimum Key Sizes
|
||||
|
||||
config.db_config=Configurazione Database
|
||||
config.db_type=Tipo
|
||||
config.db_host=Host
|
||||
@@ -968,7 +988,7 @@ config.db_user=Utente
|
||||
config.db_ssl_mode=Modalità SSL
|
||||
config.db_ssl_mode_helper=(solo per "postgres")
|
||||
config.db_path=Percorso
|
||||
config.db_path_helper=(for "sqlite3" and "tidb")
|
||||
config.db_path_helper=(per "sqlite3" e "tidb")
|
||||
config.service_config=Configurazione Servizio
|
||||
config.register_email_confirm=Richiedono Conferma dell'Email
|
||||
config.disable_register=Disabilita Registrazione
|
||||
@@ -989,6 +1009,9 @@ config.mailer_disable_helo=Disattiva HELO
|
||||
config.mailer_name=Nome
|
||||
config.mailer_host=Host
|
||||
config.mailer_user=Utente
|
||||
config.send_test_mail=Invia email di test
|
||||
config.test_mail_failed=Fail to send test email to '%s': %v
|
||||
config.test_mail_sent=Test email has been sent to '%s'.
|
||||
config.oauth_config=Configurazione OAuth
|
||||
config.oauth_enabled=Attivo
|
||||
config.cache_config=Configurazione Cache
|
||||
@@ -1024,10 +1047,10 @@ monitor.execute_time=Tempo di Esecuzione
|
||||
notices.system_notice_list=Avvisi di Sistema
|
||||
notices.view_detail_header=View Notice Detail
|
||||
notices.actions=Actions
|
||||
notices.select_all=Select All
|
||||
notices.deselect_all=Deselect All
|
||||
notices.inverse_selection=Inverse Selection
|
||||
notices.delete_selected=Delete Selected
|
||||
notices.select_all=Seleziona tutto
|
||||
notices.deselect_all=Deseleziona tutto
|
||||
notices.inverse_selection=Inverti selezione
|
||||
notices.delete_selected=Elimina selezionati
|
||||
notices.delete_all=Delete All Notices
|
||||
notices.type=Tipo
|
||||
notices.type_1=Repository
|
||||
@@ -1043,6 +1066,8 @@ create_issue=`ha aperto il problema <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
close_issue=`closed issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
reopen_issue=`reopened issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
create_pull_request=`creata pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
close_pull_request=`closed pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
reopen_pull_request=`reopened pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
comment_issue=`ha commentato il problema <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
merge_pull_request=`merged pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
transfer_repo=ha trasferito il repository <code>%s</code> a <a href="%s">%s</a>
|
||||
|
||||
@@ -221,8 +221,6 @@ still_own_repo=アカウント所有のリポジトリがあり、リポジト
|
||||
still_has_org=アカウントはまだ組織のメンバーであり、組織から退出するか削除する必要があります。
|
||||
org_still_own_repo=この組織はまだリポジトリの所有しています、リポジトリを削除または転送する必要があります。
|
||||
|
||||
still_own_user=この認証はまだ一部のユーザーによって使用されています。一部のユーザを移動させてから、もう一度削除してください。
|
||||
|
||||
target_branch_not_exist=ターゲットブランチが存在しない
|
||||
|
||||
[user]
|
||||
@@ -264,11 +262,10 @@ continue=続行
|
||||
cancel=キャンセル
|
||||
|
||||
enable_custom_avatar=カスタムのアバターを有効にする
|
||||
enable_custom_avatar_helper=Gravatarからのフェッチを無効にするのを、有効にします
|
||||
choose_new_avatar=新しいアバターを選択
|
||||
update_avatar=アバターの設定を更新
|
||||
delete_current_avatar=Delete Current Avatar
|
||||
uploaded_avatar_not_a_image=アップロードされたファイルは画像ではない。
|
||||
no_custom_avatar_available=利用可能なカスタム アバターがないため、有効にできません。
|
||||
update_avatar_success=あなたのアバターの設定が更新されました。
|
||||
|
||||
change_password=パスワードを変更
|
||||
@@ -479,7 +476,7 @@ issues.closed_at=`closed <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.reopened_at=`reopened <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.commit_ref_at=`referenced this issue from a commit <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.poster=ポスター
|
||||
issues.admin=アドミン
|
||||
issues.collaborator=Collaborator
|
||||
issues.owner=オーナー
|
||||
issues.sign_up_for_free=無料でサインアップ
|
||||
issues.sign_in_require_desc=to join this conversation. Already have an account? <a href="%s">Sign in to comment</a>
|
||||
@@ -560,6 +557,8 @@ wiki.save_page=ページを保存
|
||||
wiki.last_commit_info=%s このページを編集 %s
|
||||
wiki.edit_page_button=編集
|
||||
wiki.new_page_button=新規ページ
|
||||
wiki.delete_page_button=Delete Page
|
||||
wiki.delete_page_notice_1=This will delete the page <code>"%s"</code>. Please be certain.
|
||||
wiki.page_already_exists=既に同じ名前のWiki ページが存在します。
|
||||
wiki.pages=ページ
|
||||
wiki.last_updated=最終更新 %s
|
||||
@@ -595,12 +594,16 @@ settings.transfer_desc=リポジトリをあなたが管理者権限を持って
|
||||
settings.transfer_notices_1=-新しい所有者が個人ユーザーの場合、あなたがアクセスできなくなります。
|
||||
settings.transfer_notices_2=- You will conserve access if new owner is an organization and if you're one of the owners.
|
||||
settings.transfer_form_title=操作を確認するために、以下の情報を入力してください。
|
||||
settings.wiki_delete=Erase Wiki Data
|
||||
settings.wiki_delete_desc=Once you erase wiki data there is no going back. Please be certain.
|
||||
settings.wiki_delete_notices_1=- This will delete and disable the wiki for %s
|
||||
settings.wiki_deletion_success=Repository wiki data have been erased successfully.
|
||||
settings.delete=このリポジトリを削除
|
||||
settings.delete_desc=リポジトリを削除すると元に戻せません。確実に確認してください。
|
||||
settings.delete_notices_1=-この操作は<strong>元に戻せません</strong> 。
|
||||
settings.delete_notices_2=- This operation will permanently delete the everything of this repository, including Git data, issues, comments and accesses of collaborators.
|
||||
settings.delete_notices_fork_1=- If this repository is public, all forks will become independent after deletion.
|
||||
settings.delete_notices_fork_2=- If this repository is private, all forks will be removed at the same time.
|
||||
settings.delete_notices_fork_2=もしプライペートリポジトリの場合、全てのフォークも同時に削除されます。
|
||||
settings.delete_notices_fork_3=- If you want to keep all forks after deletion, please change visibility of this repository to public first.
|
||||
settings.deletion_success=Repository has been deleted successfully!
|
||||
settings.update_settings_success=リポジトリ オプションが更新されました。
|
||||
@@ -610,9 +613,12 @@ settings.transfer_succeed=リポジトリの所有権は正常に転送されま
|
||||
settings.confirm_delete=削除の確認
|
||||
settings.add_collaborator=新しい共同編集者を追加
|
||||
settings.add_collaborator_success=新しい共同編集者が追加されました。
|
||||
settings.delete_collaborator=Delete
|
||||
settings.collaborator_deletion=Collaborator Deletion
|
||||
settings.collaborator_deletion_desc=This user will no longer have collaboration access to this repository after deletion. Do you want to continue?
|
||||
settings.remove_collaborator_success=共同編集者が削除されました。
|
||||
settings.search_user_placeholder=Search users
|
||||
settings.org_not_allowed_to_be_collaborator=Organization is not allowed to be added as a collaborator.
|
||||
settings.org_not_allowed_to_be_collaborator=組織を共同編集者として追加することはできません。
|
||||
settings.user_is_org_member=ユーザーは組織の一員なので、共同編集者として追加することはできません。
|
||||
settings.add_webhook=Webhook を追加
|
||||
settings.hooks_desc=Webhooksは、Gogsで特定のイベントの発生時に指定された外部サービスに通知を許可します。イベントが発生すると、それぞれ指定されたUrlに、POSTリクエストが送られます。詳細はこちらのの <a target="_blank"href="%s"> Webhooks ガイド</a>をご覧ください。
|
||||
@@ -677,7 +683,7 @@ diff.parent=親
|
||||
diff.commit=コミット
|
||||
diff.data_not_available=差分データは利用できません。
|
||||
diff.show_diff_stats=差分情報を表示
|
||||
diff.show_split_view=Split View
|
||||
diff.show_split_view=分割表示
|
||||
diff.show_unified_view=Unified View
|
||||
diff.stats_desc=共有<strong>%d 個のファイルを変更した</strong>、<strong>%d 個の追加</strong> と <strong>%d 個の削除</strong>を含む
|
||||
diff.bin=BIN
|
||||
@@ -709,7 +715,7 @@ release.save_draft=下書きを保存
|
||||
release.edit_release=リリースを編集
|
||||
release.delete_release=このリリースを削除
|
||||
release.deletion=リリースの削除
|
||||
release.deletion_desc=Deleting this release will delete the corresponding Git tag. Do you want to continue?
|
||||
release.deletion_desc=このリリースを削除すると、対応するGitのタグも削除されます。よろしいですか?
|
||||
release.deletion_success=リリースが正常に削除されました。
|
||||
release.tag_name_already_exist=このタグ名には既にリリースが存在します。
|
||||
release.downloads=Downloads
|
||||
@@ -944,6 +950,7 @@ auths.update=認証設定を更新
|
||||
auths.delete=この認証を削除
|
||||
auths.delete_auth_title=認証削除
|
||||
auths.delete_auth_desc=認証を削除します、継続しますか?
|
||||
auths.still_in_used=This authentication is still used by some users, please delete or convert these users to another login type first.
|
||||
auths.deletion_success=認証が正常に削除されました。
|
||||
|
||||
config.server_config=サーバーの構成
|
||||
@@ -960,6 +967,19 @@ config.static_file_root_path=静的ファイルのルートパス
|
||||
config.log_file_root_path=ログ ファイルのルート パス
|
||||
config.script_type=スクリプトの種類
|
||||
config.reverse_auth_user=リバース認証ユーザ
|
||||
|
||||
config.ssh_config=SSH Configuration
|
||||
config.ssh_enabled=Enabled
|
||||
config.ssh_start_builtin_server=Start Builtin Server
|
||||
config.ssh_domain=Domain
|
||||
config.ssh_port=Port
|
||||
config.ssh_listen_port=Listen Port
|
||||
config.ssh_root_path=Root Path
|
||||
config.ssh_key_test_path=Key Test Path
|
||||
config.ssh_keygen_path=Keygen ('ssh-keygen') Path
|
||||
config.ssh_minimum_key_size_check=Minimum Key Size Check
|
||||
config.ssh_minimum_key_sizes=Minimum Key Sizes
|
||||
|
||||
config.db_config=データベースの構成
|
||||
config.db_type=タイプ
|
||||
config.db_host=ホスト
|
||||
@@ -989,6 +1009,9 @@ config.mailer_disable_helo=HELOコマンド無効
|
||||
config.mailer_name=名前
|
||||
config.mailer_host=ホスト
|
||||
config.mailer_user=ユーザ
|
||||
config.send_test_mail=Send Test Email
|
||||
config.test_mail_failed=Fail to send test email to '%s': %v
|
||||
config.test_mail_sent=Test email has been sent to '%s'.
|
||||
config.oauth_config=OAuth 構成
|
||||
config.oauth_enabled=Enabled
|
||||
config.cache_config=キャッシュの構成
|
||||
@@ -1043,6 +1066,8 @@ create_issue=`問題 <a href="%s/issues/%s">%s#%[2]s</a> を開きました`
|
||||
close_issue=`closed issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
reopen_issue=`reopened issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
create_pull_request=`プルリクエスト <a href="%s/pulls/%s"> %s[2]s</a>を作成`
|
||||
close_pull_request=`closed pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
reopen_pull_request=`reopened pull request <a href="%s/pulls/%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>をマージしました`
|
||||
transfer_repo=リポジトリ <code>%s</code> を <a href="%s">%s</a> へ転送しました
|
||||
|
||||
@@ -38,7 +38,7 @@ settings=Iestatījumi
|
||||
your_profile=Tavs profils
|
||||
your_settings=Tavi iestatījumi
|
||||
|
||||
activities=Activities
|
||||
activities=Aktivitāte
|
||||
pull_requests=Izmaiņu pieprasījumi
|
||||
issues=Problēmas
|
||||
|
||||
@@ -65,7 +65,7 @@ db_name=Datu bāzes nosaukums
|
||||
db_helper=Nepieciešams izmantot MySQL INNODB dzini ar rakstzīmju kopu utf8_general_ci.
|
||||
ssl_mode=SSL režīms
|
||||
path=Ceļš
|
||||
sqlite_helper=The file path of SQLite3 or TiDB database. <br>Please use absolute path when you start as service.
|
||||
sqlite_helper=SQLite3 vai TiDB datu bāzēs faila ceļš.<br>Izmantojiet absolūto ceļu, startējot kā servisu.
|
||||
err_empty_db_path=Nepieciešams norādīt SQLite3 vai TiDB datu bāzes atrašanās vietu.
|
||||
err_invalid_tidb_name=TiDB datu bāzes nosaukums nevar saturēt simbolus "." un "-".
|
||||
no_admin_and_disable_registration=Reģistrāciju nevar atslēgt, kamēr nav izveidots administratora konts.
|
||||
@@ -86,8 +86,8 @@ http_port=HTTP ports
|
||||
http_port_helper=Porta numurs pēc kura lietojumprogrammai būs iespējams pieslēgties.
|
||||
app_url=Lietotnes URL
|
||||
app_url_helper=Tas ietekmē HTTP/HTTPS klonēšanas URL un e-pasta saturā izsūtītās saites.
|
||||
log_root_path=Log Path
|
||||
log_root_path_helper=Directory to write log files to.
|
||||
log_root_path=Žurnalizēšanas direktorija
|
||||
log_root_path_helper=Direktorija, kurā tiks glabāti žurnāla faili.
|
||||
|
||||
optional_title=Neobligātie iestatījumi
|
||||
email_title=E-pasta pakalpojuma iestatījumi
|
||||
@@ -124,7 +124,7 @@ run_user_not_match=Izpildes lietotājs nav pašreizējais lietotājs: %s -> %s
|
||||
save_config_failed=Neizdevās saglabāt konfigurāciju: %v
|
||||
invalid_admin_setting=Nekorekts admin konta iestatījums: %v
|
||||
install_success=Laipni lūdzam! Mēs priecājamies, ka Jūs izvēlaties Gogs, patīkamu lietošanu!
|
||||
invalid_log_root_path=Log root path is invalid: %v
|
||||
invalid_log_root_path=Norādītā žurnalizēšanas direktorija ir kļūdaina: %v
|
||||
|
||||
[home]
|
||||
uname_holder=Lietotājvārds vai e-pasts
|
||||
@@ -221,8 +221,6 @@ still_own_repo=Jūsu esat vismaz viena repozitorija īpašnieks, tos sākumā ir
|
||||
still_has_org=Jūsu esat vismaz vienas organizācijas biedrs, sākumā nepieciešams pamest vai izdzēst šo organizāciju.
|
||||
org_still_own_repo=Šī organizācija ir vismaz viena repozitorija īpašnieks, tos sākumā ir nepieciešams izdzēst vai nomainīt to īpašnieku.
|
||||
|
||||
still_own_user=Šo autentifikāciju joprojām izmanto vismaz viens lietotājs, nepieciešams šiem lietotājiem nomainīt autentifikācijas veidu vai tos izdzēst.
|
||||
|
||||
target_branch_not_exist=Mērķa atzars neeksistē
|
||||
|
||||
[user]
|
||||
@@ -264,11 +262,10 @@ continue=Turpināt
|
||||
cancel=Atcelt
|
||||
|
||||
enable_custom_avatar=Iespējot maināmu profila attēlu
|
||||
enable_custom_avatar_helper=Iespējojiet šo, lai atslēgtu profilu attēlu ņemšanu no gravatar.com
|
||||
choose_new_avatar=Izvēlēties jaunu profila attēlu
|
||||
update_avatar=Saglabāt profila bildi
|
||||
delete_current_avatar=Delete Current Avatar
|
||||
uploaded_avatar_not_a_image=Augšupielādētais fails nav attēls.
|
||||
no_custom_avatar_available=Nav iespējams mainīt profila bildi.
|
||||
update_avatar_success=Jūsu profila bilde tika veiksmīgi saglabāta.
|
||||
|
||||
change_password=Mainīt paroli
|
||||
@@ -479,7 +476,7 @@ issues.closed_at=`aizvērts <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.reopened_at=`atvērts atkārtoti <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.commit_ref_at=`pieminēja šo problēmu revīzijā <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.poster=Autors
|
||||
issues.admin=Administrators
|
||||
issues.collaborator=Collaborator
|
||||
issues.owner=Īpašnieks
|
||||
issues.sign_up_for_free=Pievienojieties
|
||||
issues.sign_in_require_desc=, lai piedalītos diskusijā. Jau ir konts? <a href="%s">Pierakstieties, lai komentētu</a>
|
||||
@@ -496,7 +493,7 @@ issues.label_modify=Etiķetes labošana
|
||||
issues.label_deletion=Etiķetes dzēšana
|
||||
issues.label_deletion_desc=Dzēšot šo etiķeti, tā tiks noņemta no visām saistītajām problēmām. Vai vēlaties turpināt?
|
||||
issues.label_deletion_success=Etiķete tika veiksmīgi izdzēsta!
|
||||
issues.num_participants=%d Participants
|
||||
issues.num_participants=%d dalībnieki
|
||||
|
||||
pulls.new=Jauns izmaiņu pieprasījums
|
||||
pulls.compare_changes=Salīdzināt izmaiņas
|
||||
@@ -560,6 +557,8 @@ wiki.save_page=Saglabāt lapu
|
||||
wiki.last_commit_info=%s laboja lapu %s
|
||||
wiki.edit_page_button=Labot
|
||||
wiki.new_page_button=Jauna lapa
|
||||
wiki.delete_page_button=Delete Page
|
||||
wiki.delete_page_notice_1=This will delete the page <code>"%s"</code>. Please be certain.
|
||||
wiki.page_already_exists=Vikivietnes lapa ar šādu nosaukumu jau eksistē.
|
||||
wiki.pages=Lapas
|
||||
wiki.last_updated=Pēdējo reizi labota %s
|
||||
@@ -585,16 +584,20 @@ settings.tracker_url_format_desc=Jūs varat izmantot <code>{user}{repo}{index}</
|
||||
settings.pulls_desc=Iespējot izmaiņu pieprasījumus lai saņemtu publiskus ieguldījumus
|
||||
settings.danger_zone=Bīstamā zona
|
||||
settings.new_owner_has_same_repo=Jaunajam īpašniekam jau ir repozitorijs ar šādu nosaukumu.
|
||||
settings.convert=Convert To Regular Repository
|
||||
settings.convert_desc=You can convert this mirror to a regular repository. This cannot be reversed.
|
||||
settings.convert_notices_1=- This operation will convert this repository mirror into a regular repository and cannot be undone.
|
||||
settings.convert_confirm=Confirm Conversion
|
||||
settings.convert_succeed=Repository has been converted to regular type successfully.
|
||||
settings.convert=Konvertēt uz parastu repozitoriju
|
||||
settings.convert_desc=Šo spoguli ir iespējams konvertēt par parastu repozitoriju. Šī ir neatgriezeniska darbība.
|
||||
settings.convert_notices_1=- Šī darbība konvertēs šo repozitoriju par parastu repozitoriju un to nebūs iespējams atcelt.
|
||||
settings.convert_confirm=Apstiprināt konvertēšanu
|
||||
settings.convert_succeed=Repozitorijs tika veiksmīgi konvertēts uz parastu repozitoriju.
|
||||
settings.transfer=Mainīt īpašnieku
|
||||
settings.transfer_desc=Mainīt šī repozitorija īpašnieku uz citu lietotāju vai organizāciju, kurai Jums ir administratora tiesībs.
|
||||
settings.transfer_notices_1=- Jūs pazaudēsiet piekļuvi, ja jaunais īpašnieks ir lietotājs.
|
||||
settings.transfer_notices_2=- Jūs saglabāsiet piekļuvi, ja jaunais īpašnieks ir organizācija un Jūs esat viens no tās īpašniekiem.
|
||||
settings.transfer_form_title=Lūdzu, ievadiet sekojošu informāciju, lai apstiprinātu šo darbību:
|
||||
settings.wiki_delete=Erase Wiki Data
|
||||
settings.wiki_delete_desc=Once you erase wiki data there is no going back. Please be certain.
|
||||
settings.wiki_delete_notices_1=- This will delete and disable the wiki for %s
|
||||
settings.wiki_deletion_success=Repository wiki data have been erased successfully.
|
||||
settings.delete=Dzēst šo repozitoriju
|
||||
settings.delete_desc=Dzēšot repozitoriju, tā datus vairs nebūs iespējams atgūt. Pirms dzēšanas pārliecinieites vai patiešām vēlaties to darīt.
|
||||
settings.delete_notices_1=- Šī darbība ir <strong>NEATGRIEZENISKA</strong>.
|
||||
@@ -610,9 +613,12 @@ settings.transfer_succeed=Repozitorija īpašnieks ir veiksmīgi nomainīts.
|
||||
settings.confirm_delete=Apstiprināt dzēšanu
|
||||
settings.add_collaborator=Pievienot jaunu līdzstrādnieku
|
||||
settings.add_collaborator_success=Jauns līdzstrādnieks ir pievienots.
|
||||
settings.delete_collaborator=Delete
|
||||
settings.collaborator_deletion=Collaborator Deletion
|
||||
settings.collaborator_deletion_desc=This user will no longer have collaboration access to this repository after deletion. Do you want to continue?
|
||||
settings.remove_collaborator_success=Līdzstrādnieks tika noņemts.
|
||||
settings.search_user_placeholder=Meklēt lietotāju...
|
||||
settings.org_not_allowed_to_be_collaborator=Organization is not allowed to be added as a collaborator.
|
||||
settings.org_not_allowed_to_be_collaborator=Organizāciju nav atļauts pievienot kā līdzstrādnieku.
|
||||
settings.user_is_org_member=Lietotājs ir organizācijas biedrs, kas nevar tikt pievienots kā līdzstrādnieks.
|
||||
settings.add_webhook=Pievienot tīmekļa āķi
|
||||
settings.hooks_desc=Tīmekļa āķi ļauj paziņot ārējiem servisiem par noteiktiem notikomiem, kas notiek Git servisā. Kad iestāsies kāds notikums, katram ārējā servisa URL tiks nosūtīts POST pieprasījums. Lai uzzinātu sīkāk skatieties <a target="_blank" href="%s">Tīmekļa āķu rokasgrāmatā</a>.
|
||||
@@ -827,8 +833,8 @@ dashboard.resync_all_sshkeys=Pārrakstīt '.ssh/authorized_keys' failu (brīdin
|
||||
dashboard.resync_all_sshkeys_success=Visas publiskās atslēgas tika veiksmīgi pārrakstītas.
|
||||
dashboard.resync_all_update_hooks=Pārrakstīt visu repozitoriju izmaiņu āķus (nepieciešams, ja tiek mainīta konfigurācijas faila atrašanās vieta)
|
||||
dashboard.resync_all_update_hooks_success=Visu repozitoriju izmaiņu āķi tika veiksmīgi pārrakstīti.
|
||||
dashboard.reinit_missing_repos=Reinitialize all repository records that lost Git files
|
||||
dashboard.reinit_missing_repos_success=All repository records that lost Git files have been reinitialized successfully.
|
||||
dashboard.reinit_missing_repos=Atkārtoti inicializēt visus repozitorija ierakstus, kam trūkst Git failu
|
||||
dashboard.reinit_missing_repos_success=Visi repozitorija ieraksti, kam trūkst Git faili, tika atkārtoti inicializēti.
|
||||
|
||||
dashboard.server_uptime=Servera darbības laiks
|
||||
dashboard.current_goroutine=Izmantotās Gorutīnas
|
||||
@@ -922,7 +928,7 @@ auths.attribute_username_placeholder=Atstājiet tukšu, lai izmantotu lietotājv
|
||||
auths.attribute_name=Vārda atribūts
|
||||
auths.attribute_surname=Uzvārda atribūts
|
||||
auths.attribute_mail=E-pasta atribūts
|
||||
auths.attributes_in_bind=Fetch attributes in Bind DN context
|
||||
auths.attributes_in_bind=Nolasīt atribūtus no saistīšanas DN konteksta
|
||||
auths.filter=Lietotāju filts
|
||||
auths.admin_filter=Administratoru filtrs
|
||||
auths.ms_ad_sa=MS Ad SA
|
||||
@@ -944,6 +950,7 @@ auths.update=Mainīt autentifikācijas iestatījumus
|
||||
auths.delete=Dzēst šo autentifikāciju
|
||||
auths.delete_auth_title=Autentifikācijas dzēšana
|
||||
auths.delete_auth_desc=Šī autentifikācija tiks dzēsta, vai vēlaties turpināt?
|
||||
auths.still_in_used=This authentication is still used by some users, please delete or convert these users to another login type first.
|
||||
auths.deletion_success=Autentifikācija tika veiksmīgi izdzēsta!
|
||||
|
||||
config.server_config=Servera konfigurācija
|
||||
@@ -960,6 +967,19 @@ config.static_file_root_path=Statisko failu atrašanās vieta
|
||||
config.log_file_root_path=Žurnalizēšanas failu glabāšanas vieta
|
||||
config.script_type=Skripta veids
|
||||
config.reverse_auth_user=Reversā lietotāja autentifikācija
|
||||
|
||||
config.ssh_config=SSH konfigurācija
|
||||
config.ssh_enabled=Iespējots
|
||||
config.ssh_start_builtin_server=Startēt iebūvēto serveri
|
||||
config.ssh_domain=Domēns
|
||||
config.ssh_port=Ports
|
||||
config.ssh_listen_port=Klausīšanās ports
|
||||
config.ssh_root_path=Saknes ceļš
|
||||
config.ssh_key_test_path=Atslēgu pārbaudes ceļš
|
||||
config.ssh_keygen_path=Keygen ('ssh-keygen') ceļš
|
||||
config.ssh_minimum_key_size_check=Minimālā atslēgas lieluma pārbaude
|
||||
config.ssh_minimum_key_sizes=Minimālais atslēgas lielums
|
||||
|
||||
config.db_config=Datu bāzes konfigurācija
|
||||
config.db_type=Veids
|
||||
config.db_host=Resursdators
|
||||
@@ -989,6 +1009,9 @@ config.mailer_disable_helo=Atspējot HELO
|
||||
config.mailer_name=Nosaukums
|
||||
config.mailer_host=Resursdators
|
||||
config.mailer_user=Lietotājs
|
||||
config.send_test_mail=Nosūtīt pārbaudes e-pastu
|
||||
config.test_mail_failed=Neizdevās nosūtīt pārbaudes e-pasta vēstuli uz '%s': %v
|
||||
config.test_mail_sent=Pārbaudes e-pasta vēstule tika nosūtīta uz '%s'.
|
||||
config.oauth_config=OAuth konfigurācija
|
||||
config.oauth_enabled=Iespējota
|
||||
config.cache_config=Kešatmiņas konfigurācija
|
||||
@@ -1040,9 +1063,11 @@ create_repo=izveidoja repozitoriju <a href="%s">%s</a>
|
||||
rename_repo=pārsauca repozitoriju no <code>%[1]s</code> uz <a href="%[2]s">%[3]s</a>
|
||||
commit_repo=veica izmaiņu nosūtīšanu atzaram <a href="%[1]s/src/%[2]s">%[3]s</a> repozitorijā <a href="%[1]s">%[4]s</a>
|
||||
create_issue=`reģistrēja problēmu <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
close_issue=`closed issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
reopen_issue=`reopened issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
close_issue=`slēdza problēmu <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
reopen_issue=`atkārtoti atvēra problēmu <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
create_pull_request=`izveidoja izmaiņu pieprasījumu <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
close_pull_request=`closed pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
reopen_pull_request=`reopened pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
comment_issue=`pievienoja komentāru problēmai <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
merge_pull_request=`sapludināja izmaiņu pieprasījumu <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
transfer_repo=mainīja repozitorija <code>%s</code> īpašnieku uz <a href="%s">%s</a>
|
||||
|
||||
@@ -5,9 +5,9 @@ dashboard=Dashboard
|
||||
explore=Verkennen
|
||||
help=Help
|
||||
sign_in=Inloggen
|
||||
sign_out=Afmelden
|
||||
sign_out=Uitloggen
|
||||
sign_up=Aanmelden
|
||||
register=Registreer
|
||||
register=Registreren
|
||||
website=Website
|
||||
version=Versie
|
||||
page=Pagina
|
||||
@@ -26,10 +26,10 @@ captcha=CAPTCHA
|
||||
repository=Repository
|
||||
organization=Organisatie
|
||||
mirror=Spiegel
|
||||
new_repo=Nieuwe repositorie
|
||||
new_repo=Nieuwe repository
|
||||
new_migrate=Nieuwe migratie
|
||||
new_mirror=Nieuwe Kopie
|
||||
new_fork=Nieuwe vork Repository
|
||||
new_fork=Nieuwe Fork
|
||||
new_org=Nieuwe organisatie
|
||||
manage_org=Beheer organisaties
|
||||
admin_panel=Adminpaneel
|
||||
@@ -38,15 +38,15 @@ settings=Instellingen
|
||||
your_profile=Uw profiel
|
||||
your_settings=Uw instellingen
|
||||
|
||||
activities=Activities
|
||||
pull_requests=Pull-aanvragen
|
||||
activities=Activiteiten
|
||||
pull_requests=Pull requests
|
||||
issues=Kwesties
|
||||
|
||||
cancel=Annuleer
|
||||
cancel=Annuleren
|
||||
|
||||
[search]
|
||||
search=Zoeken...
|
||||
repository=Opslagplaats
|
||||
repository=Repository
|
||||
user=Gebruiker
|
||||
issue=Probleem
|
||||
code=Code
|
||||
@@ -56,7 +56,7 @@ install=Installatie
|
||||
title=Installatiestappen voor de eerste keer opstarten
|
||||
docker_helper=Als u gebruik maakt Gogs binnen Docker, lees dan de <a target="_blank" href="%s">richtlijnen</a> voordat u iets veranderen op deze pagina!
|
||||
requite_db_desc=Gogs vereist MySQL, PostgreSQL, SQite3 of TiDB.
|
||||
db_title=Database instellingen
|
||||
db_title=Database-instellingen
|
||||
db_type=Database-type
|
||||
host=Host
|
||||
user=Gebruikersnaam
|
||||
@@ -65,7 +65,7 @@ db_name=Database naam
|
||||
db_helper=Gebruik InnoDB engine met utf8_general_ci karakterset voor MySQL.
|
||||
ssl_mode=SSL-modus
|
||||
path=Pad
|
||||
sqlite_helper=The file path of SQLite3 or TiDB database. <br>Please use absolute path when you start as service.
|
||||
sqlite_helper=Het pad van de SQLite3- of TiDB-database.<br>Als u Gogs start als een service, geef dan een absoluut pad op.
|
||||
err_empty_db_path=SQLite3 of TiDB databankpad mag niet leeg.
|
||||
err_invalid_tidb_name=TiDB databank naam niet tekens kunnen "." en "-".
|
||||
no_admin_and_disable_registration=Je kunt niet de registratie uit te schakelen zonder een beheerders account.
|
||||
@@ -86,8 +86,8 @@ http_port=HTTP-poort
|
||||
http_port_helper=Poortnummer waar het programma naar luistert.
|
||||
app_url=Applicatie URL
|
||||
app_url_helper=Dit heeft invloed op de HTTP/HTTPS kloon urls en de urls die in de email worden gebruikt
|
||||
log_root_path=Log Path
|
||||
log_root_path_helper=Directory to write log files to.
|
||||
log_root_path=Log-pad
|
||||
log_root_path_helper=Directory waar logbestanden opgeslagen worden.
|
||||
|
||||
optional_title=Optionele instellingen
|
||||
email_title=E-mail service instellingen
|
||||
@@ -124,7 +124,7 @@ run_user_not_match=De uitvoerende gebruiker is niet de huidig gebruiker: %s -> %
|
||||
save_config_failed=Kan de configuratie niet opslaan: %v
|
||||
invalid_admin_setting=Uw admin-instellingen zijn niet geldig: %v
|
||||
install_success=Welkom! Wij zijn veheugd dat u voor Gogs heeft gekozen, veel plezier en tot ziens
|
||||
invalid_log_root_path=Log root path is invalid: %v
|
||||
invalid_log_root_path=Ongeldig log-pad: %v
|
||||
|
||||
[home]
|
||||
uname_holder=Gebruikersnaam of e-mail
|
||||
@@ -221,8 +221,6 @@ still_own_repo=Uw account heeft nog een eigendom op een repositorie. U moet deze
|
||||
still_has_org=Uw account nog steeds lidmaatschap van organisatie, u hebt naar links of hen eerst verwijderen.
|
||||
org_still_own_repo=De organisatie heeft nog eigendomen op repositories. U moet deze eerst verwijderen of overdragen.
|
||||
|
||||
still_own_user=Deze authenticatie methode wordt nog gebruikt door sommige gebruikers. U moet hen eerst verplaatsen of verwijderen.
|
||||
|
||||
target_branch_not_exist=Doel branch bestaat niet
|
||||
|
||||
[user]
|
||||
@@ -264,11 +262,10 @@ continue=Doorgaan
|
||||
cancel=Annuleren
|
||||
|
||||
enable_custom_avatar=Aangepaste avatar inschakelen
|
||||
enable_custom_avatar_helper=Avatar niet ophalen van Gravatar
|
||||
choose_new_avatar=Kies een nieuwe avatar
|
||||
update_avatar=Avatar instelling bijwerken
|
||||
delete_current_avatar=Delete Current Avatar
|
||||
uploaded_avatar_not_a_image=Geüpload bestand is geen afbeelding.
|
||||
no_custom_avatar_available=Geen aangepaste avatar beschikbaar, kan niet worden ingeschakeld.
|
||||
update_avatar_success=Instellingen voor avatar succesvol bijgewerkt.
|
||||
|
||||
change_password=Verander wachtwoord
|
||||
@@ -345,9 +342,9 @@ visiblity_helper=Deze repositorie is <span class="ui red text">privaat</span>
|
||||
visiblity_helper_forced=Sitebeheerder heeft alle nieuwe repositories gedwongen <span class="ui red text">privé</span> te zijn
|
||||
visiblity_fork_helper=(Verandering van deze waarde zal van invloed zijn op alle forks)
|
||||
clone_helper=De behoeftehulp van klonen? Bezoek <a target="_blank" href="%s"> helpen</a>!
|
||||
fork_repo=Vork Repository
|
||||
fork_repo=Repository forken
|
||||
fork_from=Afsplitsing van
|
||||
fork_visiblity_helper=Gevorkte repository wijzigen zijn bereik potentiële kopers niet
|
||||
fork_visiblity_helper=U kunt de zichtbaarheid van een geforkte repository niet aanpassen.
|
||||
repo_desc=Omschrijving
|
||||
repo_lang=Taal
|
||||
repo_lang_helper=Selecteer .gitignore bestanden
|
||||
@@ -434,7 +431,7 @@ issues.new.no_milestone=Geen mijlpaal
|
||||
issues.new.clear_milestone=Verwijder mijlpaal
|
||||
issues.new.open_milestone=Open mijlpalen
|
||||
issues.new.closed_milestone=Gesloten mijlpalen
|
||||
issues.new.assignee=Verantwoordelijke
|
||||
issues.new.assignee=Toegewezen aan
|
||||
issues.new.clear_assignee=Verwijder verantwoordelijke
|
||||
issues.new.no_assignee=Geen verantwoordelijke
|
||||
issues.create=Maak probleem
|
||||
@@ -479,7 +476,7 @@ issues.closed_at=`gesloten om <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.reopened_at=`heropend om <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.commit_ref_at='verwees naar dit probleem vanuit een commit <a id="%[1]s" href="#%[1]s"> %[2]s'</a>
|
||||
issues.poster=Poster
|
||||
issues.admin=Admin
|
||||
issues.collaborator=Collaborator
|
||||
issues.owner=Eigenaar
|
||||
issues.sign_up_for_free=Gratis aanmelden
|
||||
issues.sign_in_require_desc=om deel te nemen in deze conversatie. Heeft u al een account? <a href="%s">Meld u aan om te reageren</a>
|
||||
@@ -516,10 +513,10 @@ pulls.tab_files=Bestanden gewijzigd
|
||||
pulls.reopen_to_merge=Heropen deze pull request aub om een een merge actie uit te voeren.
|
||||
pulls.merged=Samengevoegd
|
||||
pulls.has_merged=Dit pull-request is samengevoegd!
|
||||
pulls.data_broken=Data of this pull request has been broken due to deletion of fork information.
|
||||
pulls.data_broken=Omdat informatie over de fork is verwijderd, zijn de gegevens van dit pull-request niet beschikbaar.
|
||||
pulls.is_checking=Controle van conflicten is nog bezig, ververs deze pagina in enkele ogenblikken.
|
||||
pulls.can_auto_merge_desc=Dit pull-request kan automatisch samengevoegd worden.
|
||||
pulls.cannot_auto_merge_desc=This pull request can't be merged automatically because there are conflicts.
|
||||
pulls.cannot_auto_merge_desc=Dit pull-request kan niet worden gemerged omdat er conflicten zijn.
|
||||
pulls.cannot_auto_merge_helper=Please merge manually in order to resolve the conflicts.
|
||||
pulls.merge_pull_request=Samenvoegen van pull verzoek
|
||||
pulls.open_unmerged_pull_exists=`You can't perform reopen operation because there is already an open pull request (#%d) from same repository with same merge information and is waiting for merging.`
|
||||
@@ -550,7 +547,7 @@ milestones.deletion_success=Mijlpaal is met succes verwijderd!
|
||||
|
||||
wiki=Wiki
|
||||
wiki.welcome=Welkom op de Wiki!
|
||||
wiki.welcome_desc=Wiki is the place where you would like to document your project together and make it better.
|
||||
wiki.welcome_desc=In een wiki kunnen gebruikers samen een project documenteren en bediscussiëren.
|
||||
wiki.create_first_page=Maak de eerste pagina
|
||||
wiki.page=Pagina
|
||||
wiki.filter_page=Filter pagina
|
||||
@@ -560,41 +557,47 @@ wiki.save_page=Pagina opslaan
|
||||
wiki.last_commit_info=%s heeft deze pagina aangepast %s
|
||||
wiki.edit_page_button=Bewerken
|
||||
wiki.new_page_button=Nieuwe pagina
|
||||
wiki.page_already_exists=Wiki page with same name already exists.
|
||||
wiki.pages=Pages
|
||||
wiki.last_updated=Last updated %s
|
||||
wiki.delete_page_button=Delete Page
|
||||
wiki.delete_page_notice_1=This will delete the page <code>"%s"</code>. Please be certain.
|
||||
wiki.page_already_exists=Er bestaat al een wiki-pagina met deze naam.
|
||||
wiki.pages=Pagina’s
|
||||
wiki.last_updated=Laatst bijgewerkt: %s
|
||||
|
||||
settings=Instellingen
|
||||
settings.options=Opties
|
||||
settings.collaboration=Samenwerking
|
||||
settings.hooks=Webhooks
|
||||
settings.githooks=Git haken
|
||||
settings.githooks=Git-hooks
|
||||
settings.basic_settings=Basis instellingen
|
||||
settings.site=Officiële site
|
||||
settings.update_settings=Instellingen bewerken
|
||||
settings.change_reponame_prompt=This change will affect how links relate to the repository.
|
||||
settings.advanced_settings=Geavanceerde opties
|
||||
settings.wiki_desc=Enable wiki to allow people write documents
|
||||
settings.use_external_wiki=Use external wiki
|
||||
settings.external_wiki_url=External Wiki URL
|
||||
settings.external_wiki_url_desc=Visitors will be redirected to URL when they click on the tab.
|
||||
settings.issues_desc=Enable builtin lightweight issue tracker
|
||||
settings.use_external_issue_tracker=Use external issue tracker
|
||||
settings.tracker_url_format=External Issue Tracker URL Format
|
||||
settings.use_external_wiki=Externe wiki gebruiken
|
||||
settings.external_wiki_url=Externe wiki-URL
|
||||
settings.external_wiki_url_desc=Bezoekers worden doorgestuurd naar de URL als ze op het tabblad klikken.
|
||||
settings.issues_desc=Ingebouwde compacte issuetracker inschakelen
|
||||
settings.use_external_issue_tracker=Externe issuetracker gebruiken
|
||||
settings.tracker_url_format=URL-formaat externe issuetracker
|
||||
settings.tracker_url_format_desc=You can use placeholder <code>{user} {repo} {index}</code> for user name, repository name and issue index.
|
||||
settings.pulls_desc=Enable pull requests to accept public contributions
|
||||
settings.danger_zone=Gevaren zone
|
||||
settings.new_owner_has_same_repo=De nieuwe eigenaar heeft al een repositorie met deze naam
|
||||
settings.convert=Convert To Regular Repository
|
||||
settings.convert_desc=You can convert this mirror to a regular repository. This cannot be reversed.
|
||||
settings.convert=Converteren naar gewone repository
|
||||
settings.convert_desc=U kunt deze mirror converteren naar een gewone repository. Dit kan niet ongedaan worden gemaakt.
|
||||
settings.convert_notices_1=- This operation will convert this repository mirror into a regular repository and cannot be undone.
|
||||
settings.convert_confirm=Confirm Conversion
|
||||
settings.convert_succeed=Repository has been converted to regular type successfully.
|
||||
settings.convert_confirm=Conversie bevestigen
|
||||
settings.convert_succeed=Deze repository is geconverteerd naar een normale repository.
|
||||
settings.transfer=Eigendom overdragen
|
||||
settings.transfer_desc=Draag deze repo over aan een andere gebruiker of een organisatie waar u beheerders rechten heeft.
|
||||
settings.transfer_notices_1=- You will lose access if new owner is a individual user.
|
||||
settings.transfer_notices_2=- You will conserve access if new owner is an organization and if you're one of the owners.
|
||||
settings.transfer_form_title=Please enter following information to confirm your operation:
|
||||
settings.wiki_delete=Erase Wiki Data
|
||||
settings.wiki_delete_desc=Once you erase wiki data there is no going back. Please be certain.
|
||||
settings.wiki_delete_notices_1=- This will delete and disable the wiki for %s
|
||||
settings.wiki_deletion_success=Repository wiki data have been erased successfully.
|
||||
settings.delete=Verwijder deze repositorie
|
||||
settings.delete_desc=Als u eenmaal een repositorie verwijderd is er geen weg terug. Gelieve zeker te zijn van uw acties.
|
||||
settings.delete_notices_1=- This operation <strong>CANNOT</strong> be undone.
|
||||
@@ -610,6 +613,9 @@ settings.transfer_succeed=Eigendom repositorie succesvol overgedragen
|
||||
settings.confirm_delete=Bevestig verwijdering
|
||||
settings.add_collaborator=Nieuwe medewerker toevoegen
|
||||
settings.add_collaborator_success=medewerker is toegevoegd.
|
||||
settings.delete_collaborator=Delete
|
||||
settings.collaborator_deletion=Collaborator Deletion
|
||||
settings.collaborator_deletion_desc=This user will no longer have collaboration access to this repository after deletion. Do you want to continue?
|
||||
settings.remove_collaborator_success=medewerker is verwijderd.
|
||||
settings.search_user_placeholder=Zoek gebruiker...
|
||||
settings.org_not_allowed_to_be_collaborator=Organization is not allowed to be added as a collaborator.
|
||||
@@ -618,8 +624,8 @@ settings.add_webhook=Webhook toevoegen
|
||||
settings.hooks_desc=Webhooks dat de externe diensten om kennisgevingen te ontvangen wanneer bepaalde gebeurtenissen op Gogs plaatsvinden. Wanneer de opgegeven gebeurtenissen plaatsvinden, sturen we een POST-aanvraag naar elk van de URL's die u opgeeft. Meer informatie vindt u in onze <a target="_blank" href="%s"> Webhooks gids</a>.
|
||||
settings.webhook_deletion=Webhook verwijderen
|
||||
settings.webhook_deletion_desc=Delete this webhook will remove its information and all delivery history. Do you want to continue?
|
||||
settings.webhook_deletion_success=Webhook has been deleted successfully!
|
||||
settings.webhook.test_delivery=Test Delivery
|
||||
settings.webhook_deletion_success=Webhook is succesvol verwijderd!
|
||||
settings.webhook.test_delivery=Test-bezorging
|
||||
settings.webhook.test_delivery_desc=Send a fake push event delivery to test your webhook settings
|
||||
settings.webhook.test_delivery_success=Test webhook has been added to delivery queue. It may take few seconds before it shows up in the delivery history.
|
||||
settings.webhook.request=Verzoek
|
||||
@@ -692,31 +698,31 @@ release.edit=bewerken
|
||||
release.ahead=<strong>%d</strong> aanpassingen aan %s sinds deze versie
|
||||
release.source_code=Broncode
|
||||
release.new_subheader=Publish releases to iterate product.
|
||||
release.edit_subheader=Detailed change log can help users understand what has been improved.
|
||||
release.edit_subheader=Een gedetailleerd changelog helpt gebruikers te begrijpen wat er is verbeterd in deze release.
|
||||
release.tag_name=Tagnaam
|
||||
release.target=Doel
|
||||
release.tag_helper=Kies een bestaande tag, of creëer een nieuwe tag bij publiceren.
|
||||
release.title=Titel
|
||||
release.content=Content
|
||||
release.content=Inhoud
|
||||
release.write=Schrijf
|
||||
release.preview=Voorbeeld
|
||||
release.loading=Laden...
|
||||
release.prerelease_desc=Dit is een beta-versie
|
||||
release.prerelease_helper=Wij wijzen u erop dat deze release is niet geschikt voor productie doeleinden.
|
||||
release.cancel=Cancel
|
||||
release.cancel=Annuleren
|
||||
release.publish=Release publiceren
|
||||
release.save_draft=Concept opslaan
|
||||
release.edit_release=Release bewerken
|
||||
release.delete_release=Delete This Release
|
||||
release.deletion=Release Deletion
|
||||
release.delete_release=Deze release verwijderen
|
||||
release.deletion=Release verwijderen
|
||||
release.deletion_desc=Deleting this release will delete the corresponding Git tag. Do you want to continue?
|
||||
release.deletion_success=Release has been deleted successfully!
|
||||
release.deletion_success=Release is verwijderd!
|
||||
release.tag_name_already_exist=Versie met deze naam bestaat al.
|
||||
release.downloads=Downloads
|
||||
|
||||
[org]
|
||||
org_name_holder=Organisatienaam
|
||||
org_full_name_holder=Organization Full Name
|
||||
org_full_name_holder=Volledige naam organisatie
|
||||
org_name_helper=Een goede organisatienaam is kort en memorabel.
|
||||
create_org=Nieuwe organisatie aanmaken
|
||||
repo_updated=Geupdate
|
||||
@@ -758,7 +764,7 @@ members.public=Openbaar
|
||||
members.public_helper=maak prive
|
||||
members.private=Prive
|
||||
members.private_helper=maak openbaar
|
||||
members.member_role=Member Role:
|
||||
members.member_role=Rol van lid:
|
||||
members.owner=Eigenaar
|
||||
members.member=Lid
|
||||
members.remove=Verwijderen
|
||||
@@ -788,10 +794,10 @@ teams.read_permission_desc=Dit team heeft <strong>Lees</strong> rechten : leden
|
||||
teams.write_permission_desc=Dit team heeft <strong>Schrijf</strong> rechten : leden kunnen repositories lezen en push aanvragen verwerken.
|
||||
teams.admin_permission_desc=Dit team heeft <strong>Beheerders</strong> rechten : leden kunnen repositories lezen en push aanvragen verwerken en medewerkers toevoegen.
|
||||
teams.repositories=Teamrepositories
|
||||
teams.search_repo_placeholder=Search repository...
|
||||
teams.search_repo_placeholder=Repository zoeken...
|
||||
teams.add_team_repository=Nieuwe teamrepositorie aanmaken
|
||||
teams.remove_repo=Verwijder
|
||||
teams.add_nonexistent_repo=De opslagplaats die u probeert toe te voegen niet bestaat, kunt u het eerst aanmaken.
|
||||
teams.add_nonexistent_repo=De opslagplaats die u probeert toe te voegen bestaat niet: maak deze eerst aan.
|
||||
|
||||
[admin]
|
||||
dashboard=Dashboard
|
||||
@@ -802,9 +808,9 @@ authentication=Autenticaties
|
||||
config=Configuratie
|
||||
notices=Systeem aankondigingen
|
||||
monitor=Bijhouden
|
||||
first_page=First
|
||||
last_page=Last
|
||||
total=Total: %d
|
||||
first_page=Eerste
|
||||
last_page=Laatste
|
||||
total=Totaal: %d
|
||||
|
||||
dashboard.statistic=Statistieken
|
||||
dashboard.operations=Bewerkingen
|
||||
@@ -867,12 +873,12 @@ users.activated=Geactiveerd
|
||||
users.admin=Admin
|
||||
users.repos=Repos
|
||||
users.created=Aangemaakt
|
||||
users.send_register_notify=Send Registration Notification To User
|
||||
users.new_success=New account '%s' has been created successfully.
|
||||
users.send_register_notify=Stuur notificatie voor registratie naar gebruiker
|
||||
users.new_success=Nieuw account '%s' is aangemaakt.
|
||||
users.edit=Bewerken
|
||||
users.auth_source=Authentication Source
|
||||
users.auth_source=Authenticatiebron
|
||||
users.local=Lokaal
|
||||
users.auth_login_name=Authentication Login Name
|
||||
users.auth_login_name=Authenticatie-loginnaam
|
||||
users.password_helper=Leave it empty to remain unchanged.
|
||||
users.update_profile_success=Profiel is succesvol bijgewerkt.
|
||||
users.edit_account=Bewerk account
|
||||
@@ -881,12 +887,12 @@ users.max_repo_creation_desc=(Set -1 to use global default limit)
|
||||
users.is_activated=Dit account is geactiveerd
|
||||
users.is_admin=Dit account heeft beheerdersrechten
|
||||
users.allow_git_hook=Deze account beschikt over machtigingen voor het maken van Git haken
|
||||
users.allow_import_local=This account has permissions to import local repositories
|
||||
users.allow_import_local=Dit account mag lokale repositories importeren
|
||||
users.update_profile=Account profiel bijwerken
|
||||
users.delete_account=Dit account verwijderen
|
||||
users.still_own_repo=Dit account is nog steeds eigendom van een repositorie. U moet deze repositorie eerst verwijderen of overdragen.
|
||||
users.still_has_org=Deze account nog steeds lidmaatschap van organisatie, u hebt naar links of hen eerst verwijderen.
|
||||
users.deletion_success=Account has been deleted successfully!
|
||||
users.deletion_success=Het account is verwijderd!
|
||||
|
||||
orgs.org_manage_panel=Organisaties beheren
|
||||
orgs.name=Naam
|
||||
@@ -902,13 +908,13 @@ repos.stars=Sterren
|
||||
repos.issues=Kwesties
|
||||
|
||||
auths.auth_manage_panel=Authentication Manage Panel
|
||||
auths.new=Add New Source
|
||||
auths.new=Nieuwe bron toevoegen
|
||||
auths.name=Naam
|
||||
auths.type=Type
|
||||
auths.enabled=Ingeschakeld
|
||||
auths.updated=Bijgewerkt
|
||||
auths.auth_type=Authentication Type
|
||||
auths.auth_name=Authentication Name
|
||||
auths.auth_type=Authenticatietype
|
||||
auths.auth_name=Authenticatienaam
|
||||
auths.domain=Domein
|
||||
auths.host=Host
|
||||
auths.port=Poort
|
||||
@@ -923,16 +929,16 @@ auths.attribute_name=Voornaam attribuut
|
||||
auths.attribute_surname=Achternaam attribuut
|
||||
auths.attribute_mail=E-mail attribuut
|
||||
auths.attributes_in_bind=Fetch attributes in Bind DN context
|
||||
auths.filter=User Filter
|
||||
auths.admin_filter=Admin Filter
|
||||
auths.filter=Gebruikersfilter
|
||||
auths.admin_filter=Beheerdersfilter
|
||||
auths.ms_ad_sa=MS Ad SA
|
||||
auths.smtp_auth=SMTP Authentication Type
|
||||
auths.smtp_auth=SMTP-authenticatietype
|
||||
auths.smtphost=SMTP host
|
||||
auths.smtpport=SMTP poort
|
||||
auths.allowed_domains=Allowed Domains
|
||||
auths.allowed_domains=Toegelaten domeinen
|
||||
auths.allowed_domains_helper=Leave it empty to not restrict any domains. Multiple domains should be separated by comma ','.
|
||||
auths.enable_tls=Activeer TLS-encryptie
|
||||
auths.skip_tls_verify=Skip TLS Verify
|
||||
auths.skip_tls_verify=TLS-verificatie overslaan
|
||||
auths.pam_service_name=PAM servicenaam
|
||||
auths.enable_auto_register=Activeer automatische registratie
|
||||
auths.tips=Tips
|
||||
@@ -940,10 +946,11 @@ auths.edit=Edit Authentication Setting
|
||||
auths.activated=Deze autorisatiemethode is geactiveerd
|
||||
auths.new_success=New authentication '%s' has been added successfully.
|
||||
auths.update_success=Authentication setting has been updated successfully.
|
||||
auths.update=Update Authentication Setting
|
||||
auths.delete=Delete This Authentication
|
||||
auths.update=Authenticatie-instellingen bijwerken
|
||||
auths.delete=Deze authenticatiewijze verwijderen
|
||||
auths.delete_auth_title=Authentication Deletion
|
||||
auths.delete_auth_desc=This authentication is going to be deleted, do you want to continue?
|
||||
auths.still_in_used=This authentication is still used by some users, please delete or convert these users to another login type first.
|
||||
auths.deletion_success=Authentication has been deleted successfully!
|
||||
|
||||
config.server_config=Serverconfiguratie
|
||||
@@ -960,6 +967,19 @@ config.static_file_root_path=Statische bestanden basis pad
|
||||
config.log_file_root_path=Log bestand basis pad
|
||||
config.script_type=Script type
|
||||
config.reverse_auth_user=Omgekeerde verificatie gebruiker
|
||||
|
||||
config.ssh_config=SSH-configuratie
|
||||
config.ssh_enabled=Ingeschakeld
|
||||
config.ssh_start_builtin_server=Ingebouwde server starten
|
||||
config.ssh_domain=Domein
|
||||
config.ssh_port=Poort
|
||||
config.ssh_listen_port=Luister op poort
|
||||
config.ssh_root_path=Root-pad
|
||||
config.ssh_key_test_path=Pad voor key-tests
|
||||
config.ssh_keygen_path=Pad van keygen ('ssh-keygen')
|
||||
config.ssh_minimum_key_size_check=Controleer minimale key-lengte
|
||||
config.ssh_minimum_key_sizes=Minimale key-lengtes
|
||||
|
||||
config.db_config=Databaseconfiguratie
|
||||
config.db_type=Type
|
||||
config.db_host=Host
|
||||
@@ -968,15 +988,15 @@ config.db_user=Gebruiker
|
||||
config.db_ssl_mode=SSL modus
|
||||
config.db_ssl_mode_helper=(alleen voor "postgres")
|
||||
config.db_path=Pad
|
||||
config.db_path_helper=(for "sqlite3" and "tidb")
|
||||
config.db_path_helper=(voor "sqlite3" en "tidb")
|
||||
config.service_config=Serviceconfiguratie
|
||||
config.register_email_confirm=E-mailbevestiging registreren
|
||||
config.disable_register=Registratie uitgeschakeld
|
||||
config.show_registration_button=Registeren knop weergeven
|
||||
config.require_sign_in_view=Inloggen vereist om te kunnen inzien
|
||||
config.mail_notify=E-mailnotificaties
|
||||
config.disable_key_size_check=Disable Minimum Key Size Check
|
||||
config.enable_captcha=Enable Captcha
|
||||
config.disable_key_size_check=Controle op key-lengte uitschakelen
|
||||
config.enable_captcha=CAPTCHA inschakelen
|
||||
config.active_code_lives=Actieve Code leven
|
||||
config.reset_password_code_lives=Reset wachtwoord Code leven
|
||||
config.webhook_config=Webhook configuratie
|
||||
@@ -989,6 +1009,9 @@ config.mailer_disable_helo=Schakel HELO uit
|
||||
config.mailer_name=Naam
|
||||
config.mailer_host=Host
|
||||
config.mailer_user=Gebruiker
|
||||
config.send_test_mail=Testbericht verzenden
|
||||
config.test_mail_failed=Verzending van een testmail naar '%s' is mislukt: %v
|
||||
config.test_mail_sent=Test-email is verstuurd naar '%s'.
|
||||
config.oauth_config=OAuth-configuratie
|
||||
config.oauth_enabled=Ingeschakeld
|
||||
config.cache_config=Cache-configuratie
|
||||
@@ -1023,11 +1046,11 @@ monitor.execute_time=Uitvoertijd
|
||||
|
||||
notices.system_notice_list=Systeem aankondigingen
|
||||
notices.view_detail_header=View Notice Detail
|
||||
notices.actions=Actions
|
||||
notices.select_all=Select All
|
||||
notices.deselect_all=Deselect All
|
||||
notices.inverse_selection=Inverse Selection
|
||||
notices.delete_selected=Delete Selected
|
||||
notices.actions=Acties
|
||||
notices.select_all=Alles selecteren
|
||||
notices.deselect_all=Alles deselecteren
|
||||
notices.inverse_selection=Selectie omkeren
|
||||
notices.delete_selected=Selectie verwijderen
|
||||
notices.delete_all=Delete All Notices
|
||||
notices.type=Type
|
||||
notices.type_1=Opslagplaats
|
||||
@@ -1043,11 +1066,13 @@ create_issue=`opende issue in <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
close_issue=`closed issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
reopen_issue=`reopened issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
create_pull_request=`created pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
close_pull_request=`closed pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
reopen_pull_request=`reopened pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
comment_issue=`reactie op issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
merge_pull_request=`merged pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
transfer_repo=repositorie verplaatst naar <code>%s</code> naar <a href="%s">%s</a>
|
||||
push_tag=geduwd label <a href="%s/src/%s"> %[2]s</a> naar <a href="%[1]s"> %[3]s</a>
|
||||
compare_commits=View comparison for these %d commits
|
||||
compare_commits=Toon vergelijking voor deze %d commits
|
||||
|
||||
[tool]
|
||||
ago=geleden
|
||||
|
||||
@@ -221,8 +221,6 @@ still_own_repo=Twoje konto dalej posiada przynajmniej jedno repozytorium, które
|
||||
still_has_org=Twoje konto dalej posiada członkostwo w przynajmniej jednej organizacji, którą musisz najpierw opuścić.
|
||||
org_still_own_repo=Ta organizacja dalej jest właścicielem repozytorium, które musisz usunąć bądź przekazać.
|
||||
|
||||
still_own_user=To uwierzytelnienie dalej jest używane przez kilku użytkowników, których musisz z niego usunąć i spróbować ponownie.
|
||||
|
||||
target_branch_not_exist=Gałąź docelowa nie istnieje.
|
||||
|
||||
[user]
|
||||
@@ -264,11 +262,10 @@ continue=Kontynuuj
|
||||
cancel=Anuluj
|
||||
|
||||
enable_custom_avatar=Włącz niestandardowe awatary
|
||||
enable_custom_avatar_helper=Wyłącz pobieranie z Gravatar
|
||||
choose_new_avatar=Wybierz nowy avatar
|
||||
update_avatar=Zaktualizuj ustawienia awatara
|
||||
delete_current_avatar=Delete Current Avatar
|
||||
uploaded_avatar_not_a_image=Załadowany plik nie jest obrazem.
|
||||
no_custom_avatar_available=Własny avatar niedostępny, nie można go włączyć.
|
||||
update_avatar_success=Ustawienia awatarów zostały pomyślnie zaktualizowane.
|
||||
|
||||
change_password=Zmień hasło
|
||||
@@ -479,7 +476,7 @@ issues.closed_at=`zamyka <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.reopened_at=`otwiera ponownie <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.commit_ref_at=`wspomina ten problem w commicie <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.poster=Autor
|
||||
issues.admin=Admin
|
||||
issues.collaborator=Collaborator
|
||||
issues.owner=Właściciel
|
||||
issues.sign_up_for_free=Zarejestruj się za darmo
|
||||
issues.sign_in_require_desc=do przyłączenia się do tej rozmowy. Masz już konto? <a href="%s">Zaloguj się by komentować</a>
|
||||
@@ -560,6 +557,8 @@ wiki.save_page=Zapisz stronę
|
||||
wiki.last_commit_info=%s edytuje tę stronę %s
|
||||
wiki.edit_page_button=Edytuj
|
||||
wiki.new_page_button=Nowa strona
|
||||
wiki.delete_page_button=Delete Page
|
||||
wiki.delete_page_notice_1=This will delete the page <code>"%s"</code>. Please be certain.
|
||||
wiki.page_already_exists=Strona Wiki o tej samej nazwie już istnieje.
|
||||
wiki.pages=Strony
|
||||
wiki.last_updated=Ostatnia aktualizacja %s
|
||||
@@ -595,6 +594,10 @@ settings.transfer_desc=Przenieś to repozytorium do innego użytkownika lub orga
|
||||
settings.transfer_notices_1=- Stracisz dostęp jeśli nowy właściciel jest indywidualnym użytkownikiem.
|
||||
settings.transfer_notices_2=- Zachowasz dostęp jeśli nowym właścicielem jest organizacja, której jesteś współwłaścicielem.
|
||||
settings.transfer_form_title=Proszę wpisz co następuje w celu potwierdzenia operacji:
|
||||
settings.wiki_delete=Erase Wiki Data
|
||||
settings.wiki_delete_desc=Once you erase wiki data there is no going back. Please be certain.
|
||||
settings.wiki_delete_notices_1=- This will delete and disable the wiki for %s
|
||||
settings.wiki_deletion_success=Repository wiki data have been erased successfully.
|
||||
settings.delete=Usuń to repozytorium
|
||||
settings.delete_desc=Po usunięciu repozytorium nie ma odwrotu. Upewnij się, że tego chcesz.
|
||||
settings.delete_notices_1=- Ta operacja <strong>NIE MOŻE</strong> zostać cofnięta.
|
||||
@@ -610,6 +613,9 @@ settings.transfer_succeed=Własność repozytorium została przeniesiona pomyśl
|
||||
settings.confirm_delete=Potwierdź usunięcie
|
||||
settings.add_collaborator=Dodaj nowego współpracownika
|
||||
settings.add_collaborator_success=Został dodany nowy współpracownik.
|
||||
settings.delete_collaborator=Delete
|
||||
settings.collaborator_deletion=Collaborator Deletion
|
||||
settings.collaborator_deletion_desc=This user will no longer have collaboration access to this repository after deletion. Do you want to continue?
|
||||
settings.remove_collaborator_success=Współpracownik został usunięty.
|
||||
settings.search_user_placeholder=Szukaj użytkownika...
|
||||
settings.org_not_allowed_to_be_collaborator=Organization is not allowed to be added as a collaborator.
|
||||
@@ -944,6 +950,7 @@ auths.update=Aktualizuj ustawienia uwierzytelniania
|
||||
auths.delete=Usuń to uwierzytelnienie
|
||||
auths.delete_auth_title=Usunięcie uwierzytelnienia
|
||||
auths.delete_auth_desc=To uwierzytelnienie zostanie usunięte, czy chcesz kontynuować?
|
||||
auths.still_in_used=This authentication is still used by some users, please delete or convert these users to another login type first.
|
||||
auths.deletion_success=Uwierzytelnienie zostało usunięte pomyślnie!
|
||||
|
||||
config.server_config=Konfiguracja serwera
|
||||
@@ -960,6 +967,19 @@ config.static_file_root_path=Ścieżka plików statycznych
|
||||
config.log_file_root_path=Ścieżka plików dziennika
|
||||
config.script_type=Typ skryptu
|
||||
config.reverse_auth_user=Użytkownik dostarczony przez odwrotne proxy
|
||||
|
||||
config.ssh_config=SSH Configuration
|
||||
config.ssh_enabled=Enabled
|
||||
config.ssh_start_builtin_server=Start Builtin Server
|
||||
config.ssh_domain=Domain
|
||||
config.ssh_port=Port
|
||||
config.ssh_listen_port=Listen Port
|
||||
config.ssh_root_path=Root Path
|
||||
config.ssh_key_test_path=Key Test Path
|
||||
config.ssh_keygen_path=Keygen ('ssh-keygen') Path
|
||||
config.ssh_minimum_key_size_check=Minimum Key Size Check
|
||||
config.ssh_minimum_key_sizes=Minimum Key Sizes
|
||||
|
||||
config.db_config=Konfiguracja bazy danych
|
||||
config.db_type=Typ
|
||||
config.db_host=Host
|
||||
@@ -989,6 +1009,9 @@ config.mailer_disable_helo=Wyłącz HELO
|
||||
config.mailer_name=Nazwa
|
||||
config.mailer_host=Host
|
||||
config.mailer_user=Użytkownik
|
||||
config.send_test_mail=Send Test Email
|
||||
config.test_mail_failed=Fail to send test email to '%s': %v
|
||||
config.test_mail_sent=Test email has been sent to '%s'.
|
||||
config.oauth_config=Konfiguracja OAuth
|
||||
config.oauth_enabled=Aktywne
|
||||
config.cache_config=Konfiguracja cache
|
||||
@@ -1043,6 +1066,8 @@ create_issue=`zgłasza problem <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
close_issue=`closed issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
reopen_issue=`reopened issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
create_pull_request=`tworzy pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
close_pull_request=`closed pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
reopen_pull_request=`reopened pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
comment_issue=`komentuje problem <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
merge_pull_request=`scala pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
transfer_repo=przenosi repozytorium <code>%s</code> do <a href="%s">%s</a>
|
||||
|
||||
@@ -20,7 +20,7 @@ signed_in_as=Você é
|
||||
username=Usuário
|
||||
email=E-mail
|
||||
password=Senha
|
||||
re_type=Redigite
|
||||
re_type=Digite novamente
|
||||
captcha=Captcha
|
||||
|
||||
repository=Repositório
|
||||
@@ -57,7 +57,7 @@ title=Etapas de instalação para primeira execução
|
||||
docker_helper=Se você está rodando o Gogs dentro do Docker, por favor leia os <a target="_blank" href="%s">Guias</a> cuidadosamente antes de mudar qualquer coisa nesta página!
|
||||
requite_db_desc=Gogs requer MySQL, PostgreSQL, SQLite3 ou TiDB.
|
||||
db_title=Configurações de Banco de Dados
|
||||
db_type=Banco de bados
|
||||
db_type=Tipo do Banco de Dados
|
||||
host=Host
|
||||
user=Usuário
|
||||
password=Senha
|
||||
@@ -221,8 +221,6 @@ still_own_repo=Sua conta ainda tem propriedade do repositório, você tem que ex
|
||||
still_has_org=Sua conta ainda faz parte da organização, você deve sair ou excluí-la primeiro.
|
||||
org_still_own_repo=Esta organização ainda tem a propriedade do repositório, você deve excluir ou transferí-la primeiro.
|
||||
|
||||
still_own_user=Esta autenticação ainda é usada por alguns usuários, você deve movê-los e depois apagar novamente.
|
||||
|
||||
target_branch_not_exist=O branch de destino não existe.
|
||||
|
||||
[user]
|
||||
@@ -264,11 +262,10 @@ continue=Continuar
|
||||
cancel=Cancelar
|
||||
|
||||
enable_custom_avatar=Habilitar Avatar Customizado
|
||||
enable_custom_avatar_helper=Habilite para desativar a busca no Gravatar
|
||||
choose_new_avatar=Escolha um novo avatar
|
||||
update_avatar=Atualizar configuração de Avatar
|
||||
delete_current_avatar=Delete Current Avatar
|
||||
uploaded_avatar_not_a_image=O arquivo enviado não é uma imagem.
|
||||
no_custom_avatar_available=Nenhum avatar personalizado disponível, não pode habilitá-lo.
|
||||
update_avatar_success=Sua configuração de avatar foi atualizada com sucesso.
|
||||
|
||||
change_password=Mudança de senha
|
||||
@@ -479,7 +476,7 @@ issues.closed_at=`fechado em <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.reopened_at=`reaberto em <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.commit_ref_at=`citou este problema em um commit <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.poster=Autor
|
||||
issues.admin=Administrador
|
||||
issues.collaborator=Collaborator
|
||||
issues.owner=Proprietário
|
||||
issues.sign_up_for_free=Cadastre-se gratuitamente
|
||||
issues.sign_in_require_desc=para participar nesta conversa. Já tem uma conta? <a href="%s">Faça login para comentar</a>
|
||||
@@ -560,6 +557,8 @@ wiki.save_page=Salvar página
|
||||
wiki.last_commit_info=%s editou esta página %s
|
||||
wiki.edit_page_button=Editar
|
||||
wiki.new_page_button=Nova página
|
||||
wiki.delete_page_button=Delete Page
|
||||
wiki.delete_page_notice_1=This will delete the page <code>"%s"</code>. Please be certain.
|
||||
wiki.page_already_exists=já existe uma página de wiki com o mesmo nome.
|
||||
wiki.pages=Páginas
|
||||
wiki.last_updated=Última atualização %s
|
||||
@@ -595,6 +594,10 @@ settings.transfer_desc=Transferir este repositório para outro usuário ou para
|
||||
settings.transfer_notices_1=- Você vai perder acesso se o novo dono for um usuário individual.
|
||||
settings.transfer_notices_2=- Você vai continuar tendo acesso se o novo dono é uma organização e você é um dos membros.
|
||||
settings.transfer_form_title=Informe a seguinte informação para confirmar a sua operação:
|
||||
settings.wiki_delete=Erase Wiki Data
|
||||
settings.wiki_delete_desc=Once you erase wiki data there is no going back. Please be certain.
|
||||
settings.wiki_delete_notices_1=- This will delete and disable the wiki for %s
|
||||
settings.wiki_deletion_success=Repository wiki data have been erased successfully.
|
||||
settings.delete=Deletar Este Repositório
|
||||
settings.delete_desc=Uma vez que você deleta um repositório, não tem volta. Por favor, tenha certeza.
|
||||
settings.delete_notices_1=-Esta operação <strong>NÃO PODERÁ</strong> ser desfeita.
|
||||
@@ -610,9 +613,12 @@ settings.transfer_succeed=A posse do repositório foi transferido com sucesso.
|
||||
settings.confirm_delete=Confirmar Deleção
|
||||
settings.add_collaborator=Adicionar um Novo Colaborador
|
||||
settings.add_collaborator_success=O novo colaborador foi adicionado.
|
||||
settings.delete_collaborator=Delete
|
||||
settings.collaborator_deletion=Collaborator Deletion
|
||||
settings.collaborator_deletion_desc=This user will no longer have collaboration access to this repository after deletion. Do you want to continue?
|
||||
settings.remove_collaborator_success=O colaborador foi removido.
|
||||
settings.search_user_placeholder=Pesquisar usuário...
|
||||
settings.org_not_allowed_to_be_collaborator=Organization is not allowed to be added as a collaborator.
|
||||
settings.org_not_allowed_to_be_collaborator=Organização não tem permissão para ser adicionada como um colaborador.
|
||||
settings.user_is_org_member=O usuário é um membro da organização que não pode ser adicionado como um colaborador.
|
||||
settings.add_webhook=Adicionar Webhook
|
||||
settings.hooks_desc=Hooks da web ou Webhooks permitem serviços externos serem notificados quando certos eventos acontecem no Gogs. Quando acontecem os eventos especificados, enviaremos uma solicitação POST para cada uma das URLs que você fornecer. Saiba mais no nosso <a target="_blank" href="%s"> Guia de Webhooks</a>.
|
||||
@@ -922,7 +928,7 @@ auths.attribute_username_placeholder=Deixe vazio para usar o valor do campo de f
|
||||
auths.attribute_name=Atributo primeiro nome
|
||||
auths.attribute_surname=Atributo sobrenome
|
||||
auths.attribute_mail=Atributo e-mail
|
||||
auths.attributes_in_bind=Fetch attributes in Bind DN context
|
||||
auths.attributes_in_bind=Buscar os atributos no contexto de Bind DN
|
||||
auths.filter=Filtro de usuário
|
||||
auths.admin_filter=Filtro de administrador
|
||||
auths.ms_ad_sa=Ms Ad SA
|
||||
@@ -944,6 +950,7 @@ auths.update=Atualizar a configuração da autenticação
|
||||
auths.delete=Excluir esta autenticação
|
||||
auths.delete_auth_title=Exclusão da autenticação
|
||||
auths.delete_auth_desc=Esta autenticação esta prestes a ser deletada, deseja continuar?
|
||||
auths.still_in_used=This authentication is still used by some users, please delete or convert these users to another login type first.
|
||||
auths.deletion_success=Autenticação deletada com sucesso!
|
||||
|
||||
config.server_config=Configuração do Servidor
|
||||
@@ -960,6 +967,19 @@ config.static_file_root_path=Caminho Raiz para Arquivo Estático
|
||||
config.log_file_root_path=Caminho Raiz para Arquivo de Log
|
||||
config.script_type=Tipo de Script
|
||||
config.reverse_auth_user=Usuário de Autenticação Reversa
|
||||
|
||||
config.ssh_config=Configuração de SSH
|
||||
config.ssh_enabled=Habilitado
|
||||
config.ssh_start_builtin_server=Iniciar servidor embutido
|
||||
config.ssh_domain=Domínio
|
||||
config.ssh_port=Porta
|
||||
config.ssh_listen_port=Porta de escuta
|
||||
config.ssh_root_path=Caminho da raiz
|
||||
config.ssh_key_test_path=Caminho da chave de teste
|
||||
config.ssh_keygen_path=Caminho do keygen ('ssh-keygen')
|
||||
config.ssh_minimum_key_size_check=Verificar tamanho mínimo da chave
|
||||
config.ssh_minimum_key_sizes=Tamanhos mínimos da chave
|
||||
|
||||
config.db_config=Configuração do Banco de Dados
|
||||
config.db_type=Tipo
|
||||
config.db_host=Host
|
||||
@@ -989,6 +1009,9 @@ config.mailer_disable_helo=Desabilitar HELO
|
||||
config.mailer_name=Nome
|
||||
config.mailer_host=Host
|
||||
config.mailer_user=Usuário
|
||||
config.send_test_mail=Enviar email de teste
|
||||
config.test_mail_failed=Falha ao enviar o email de teste para '%s': %v
|
||||
config.test_mail_sent=O email de teste foi enviado para '%s'.
|
||||
config.oauth_config=Configuração do OAuth
|
||||
config.oauth_enabled=Habilitado
|
||||
config.cache_config=Configuração de Cache
|
||||
@@ -1040,9 +1063,11 @@ create_repo=repositório criado <a href="%s"> %s</a>
|
||||
rename_repo=renomeou o o repositório <code>%[1]s</code> para <a href="%[2]s">%[3]s</a>
|
||||
commit_repo=pushed para <a href="%[1]s/src/%[2]s">%[3]s</a> em <a href="%[1]s">%[4]s</a>
|
||||
create_issue=`questão aberta <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
close_issue=`closed issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
reopen_issue=`reopened issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
close_issue=`questão fechada <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
reopen_issue=`questão reaberta <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
create_pull_request=`criou o pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
close_pull_request=`closed pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
reopen_pull_request=`reopened pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
comment_issue=`comentou sobre a questão <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
merge_pull_request=`mesclou o pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
transfer_repo=repositório transferido de <code>%s</code> para <a href="%s">%s</a>
|
||||
|
||||
@@ -20,8 +20,8 @@ signed_in_as=Вы вошли как
|
||||
username=Имя пользователя
|
||||
email=Эл. почта
|
||||
password=Пароль
|
||||
re_type=Повтор
|
||||
captcha=Captcha
|
||||
re_type=Введите повторно
|
||||
captcha=Капча
|
||||
|
||||
repository=Репозиторий
|
||||
organization=Организация
|
||||
@@ -29,9 +29,9 @@ mirror=Зеркало
|
||||
new_repo=Новый репозиторий
|
||||
new_migrate=Новая Миграция
|
||||
new_mirror=Новое зеркало
|
||||
new_fork=Новый проект из репозитория
|
||||
new_fork=Новое ответвление репозитория
|
||||
new_org=Новая организация
|
||||
manage_org=Управление организацией
|
||||
manage_org=Управление организациями
|
||||
admin_panel=Панель администратора
|
||||
account_settings=Настройки аккаунта
|
||||
settings=Настройки
|
||||
@@ -132,7 +132,7 @@ password_holder=Пароль
|
||||
switch_dashboard_context=Переключить контекст панели управления
|
||||
my_repos=Мои репозитории
|
||||
collaborative_repos=Совместные репозитории
|
||||
my_orgs=Моя Организация
|
||||
my_orgs=Мои организации
|
||||
my_mirrors=Мои зеркала
|
||||
view_home=Показать %s
|
||||
|
||||
@@ -153,7 +153,7 @@ forget_password=Забыли пароль?
|
||||
sign_up_now=Нужен аккаунт? Зарегистрируйтесь.
|
||||
confirmation_mail_sent_prompt=Новое письмо для подтверждения было направлено на <b>%s</b>, пожалуйста, проверьте ваш почтовый ящик в течение %d часов для завершения регистрации.
|
||||
active_your_account=Активируйте свой аккаунт
|
||||
resent_limit_prompt=Вы слишком часто отправляете письмо с активацией. Подождите 3 минуты, пожалуйста.
|
||||
resent_limit_prompt=Извините, вы уже запросили активацию по электронной почте недавно. Пожалуйста, подождите 3 минуты, а затем повторите попытку.
|
||||
has_unconfirmed_mail=Здравствуйте, %s! У вас есть неподтвержденный адрес электронной почты (<b>%s</b>). Если вам не приходило письмо с подтверждением или нужно выслать новое письмо, нажмите на кнопку ниже.
|
||||
resend_mail=Нажмите здесь, чтобы переотправить активационное письмо
|
||||
email_not_associate=Этот адрес электронной почты не связан ни с одной учетной записью.
|
||||
@@ -195,23 +195,23 @@ size_error=` должен быть размер %s.`
|
||||
min_size_error=«должен содержать по крайней мере %s символов.»
|
||||
max_size_error=` должен содержать максимум %s символов.`
|
||||
email_error=«не является адресом электронной почты.»
|
||||
url_error=«не является допустимым URL-адресом.»
|
||||
include_error=` должен содержать '%s'`
|
||||
url_error=` не является допустимым URL-адресом.`
|
||||
include_error=` должен содержать '%s'.`
|
||||
unknown_error=Неизвестная ошибка:
|
||||
captcha_incorrect=CAPTCHA не совпадает.
|
||||
password_not_match=Пароль и подтверждение пароля не совпадают.
|
||||
captcha_incorrect=Капча не пройдена.
|
||||
password_not_match=Пароли не совпадают.
|
||||
|
||||
username_been_taken=Имя пользователя уже принято.
|
||||
repo_name_been_taken=Имя репозитория уже принято.
|
||||
org_name_been_taken=Название организации было уже принято.
|
||||
team_name_been_taken=Название команды было уже принято.
|
||||
username_been_taken=Имя пользователя занято.
|
||||
repo_name_been_taken=Имя репозитория занято.
|
||||
org_name_been_taken=Название организации занято.
|
||||
team_name_been_taken=Название команды занято.
|
||||
email_been_used=Адрес электронной почты уже используется.
|
||||
username_password_incorrect=Имя пользователя или пароль не правильный.
|
||||
enterred_invalid_repo_name=Пожалуйста, убедитесь, что введенно правильное имя хранилища.
|
||||
enterred_invalid_repo_name=Пожалуйста, убедитесь, что введено правильное имя репозитория.
|
||||
enterred_invalid_owner_name=Убедитесь, что введенное имя владельца верное.
|
||||
enterred_invalid_password=Убедитесь, что введенный пароль верен.
|
||||
user_not_exist=Данный пользователь не существует.
|
||||
last_org_owner=Удаляемый пользователь является последним в команде владельцев. Должен быть хотя бы один владелец.
|
||||
last_org_owner=Удаление последнего пользователя из команды владельцев невозможно, поскольку всегда должен быть хотя бы один владелец в любой организации.
|
||||
|
||||
invalid_ssh_key=К сожалению, мы не смогли проверить ваш SSH-ключ: %s
|
||||
unable_verify_ssh_key=Gogs не может проверить ваш SSH-ключ, но мы допускаем, что он действителен. Пожалуйста, удостоверьтесь самостоятельно, что ключ действителен.
|
||||
@@ -221,8 +221,6 @@ still_own_repo=На вашем аккаунте все еще остается
|
||||
still_has_org=Вы находитесь в организации, сперва Вам необходимо покинуть ее или удалить.
|
||||
org_still_own_repo=Данная организация все еще является владельцем репозиториев, необходимо удалить или переместить их в начале.
|
||||
|
||||
still_own_user=Эта проверка подлинности по-прежнему используется некоторыми пользователями, вы должны переместить их и затем снова удалить.
|
||||
|
||||
target_branch_not_exist=Целевая ветка не существует
|
||||
|
||||
[user]
|
||||
@@ -264,11 +262,10 @@ continue=Далее
|
||||
cancel=Отмена
|
||||
|
||||
enable_custom_avatar=Включить собственный аватар
|
||||
enable_custom_avatar_helper=Включите эту опцию, чтоб отключить загрузку с Gravatar
|
||||
choose_new_avatar=Выбрать новый аватар
|
||||
update_avatar=Обновить настройку аватара
|
||||
delete_current_avatar=Удалить текущий аватар
|
||||
uploaded_avatar_not_a_image=Загружаемый файл не является изображением.
|
||||
no_custom_avatar_available=Собственный аватар недоступен, включить его невозможно.
|
||||
update_avatar_success=Настройка вашего аватара обновлена успешно.
|
||||
|
||||
change_password=Сменить пароль
|
||||
@@ -326,7 +323,7 @@ token_name=Имя маркера
|
||||
generate_token=Генерировать маркер
|
||||
generate_token_succees=Успешно создан новый токен доступа! Пожалуйста сделайте копию вашего нового токена персонального доступа. Вы не сможете увидеть его снова!
|
||||
delete_token=Удалить
|
||||
access_token_deletion=Удаление персонального токена доступа
|
||||
access_token_deletion=Удаление личного токена доступа
|
||||
access_token_deletion_desc=Удаление этого персонального токена доступа приведет к удалению всех связанных прав доступа к приложению. Вы хотите продолжить?
|
||||
delete_token_success=Персональный токен доступа успешно удален! Не забудьте изменить настройки вашего приложения.
|
||||
|
||||
@@ -343,7 +340,7 @@ repo_name_helper=Лучшие названия репозиториев коро
|
||||
visibility=Видимость
|
||||
visiblity_helper=<span class="ui red text">Личный</span> репозиторий
|
||||
visiblity_helper_forced=Все новые репозитории являются <span class="ui red text">Личными</span> по желанию администратора сайта
|
||||
visiblity_fork_helper=(Изменение этого значения затронет все форки)
|
||||
visiblity_fork_helper=(Изменение этого значения затронет все ответвления)
|
||||
clone_helper=Нужна помощь в клонировании? Посетите страницу <a target="_blank" href="%s">помощи</a>!
|
||||
fork_repo=Ответвить репозиторий
|
||||
fork_from=Ответвление от
|
||||
@@ -363,7 +360,7 @@ mirror_address=Адрес зеркала
|
||||
mirror_address_desc=Укажите необходимые учетные данные в адрес.
|
||||
watchers=Наблюдатели
|
||||
stargazers=Звездочеты
|
||||
forks=Форки
|
||||
forks=Ответвления
|
||||
|
||||
form.reach_limit_of_creation=У владельца достигнут максимальный предел в %d создаваемых репозиториев.
|
||||
form.name_reserved=Имя репозитория '%s' зарезервировано.
|
||||
@@ -380,8 +377,8 @@ migrate.invalid_local_path=Недопустимый локальный путь.
|
||||
migrate.failed=Миграция не удалась: %v
|
||||
|
||||
mirror_from=зеркало из
|
||||
forked_from=форк от
|
||||
fork_from_self=Вы не можете форкнуть репозитарий, так как Вы уже его владелец!
|
||||
forked_from=ответвлено от
|
||||
fork_from_self=Вы не можете ответвить репозиторий, так как Вы уже его владелец!
|
||||
copy_link=Скопировать
|
||||
copy_link_success=Скопировано!
|
||||
copy_link_error=Нажмите ⌘-C или Ctrl-C для копирования
|
||||
@@ -479,7 +476,7 @@ issues.closed_at=`закрыл <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.reopened_at=`открыл снова <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.commit_ref_at=`упомянул эту задачу в коммите <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.poster=Автор
|
||||
issues.admin=Администратор
|
||||
issues.collaborator=Соавтор
|
||||
issues.owner=Владелец
|
||||
issues.sign_up_for_free=Зарегистрируйтесь бесплатно
|
||||
issues.sign_in_require_desc=чтобы присоединиться к обсуждению. Уже есть аккаунт? <a href="%s">Войдите чтобы прокомментировать</a>
|
||||
@@ -506,7 +503,7 @@ pulls.compare_compare=сравнить
|
||||
pulls.filter_branch=Фильтр по ветке
|
||||
pulls.no_results=Результатов не найдено.
|
||||
pulls.nothing_to_compare=Нечего сравнивать, родительская и текущая ветка одинаковые.
|
||||
pulls.has_pull_request=`Уже существует пулл-реквест между двумя целями <a href="%[1]s/pulls/%[3]d">%[2]s#%[3]d</a>`
|
||||
pulls.has_pull_request=`Уже существует запрос на слияние между двумя целями: <a href="%[1]s/pulls/%[3]d">%[2]s#%[3]d</a>`
|
||||
pulls.create=Создать запрос на слияние
|
||||
pulls.title_desc=хочет смерджить %[1]d коммит(ов) из <code>%[2]s</code> в <code>%[3]s</code>
|
||||
pulls.merged_title_desc=слито %[1]d коммит(ов) из <code>%[2]s</code> в <code>%[3]s</code> %[4]s
|
||||
@@ -516,7 +513,7 @@ pulls.tab_files=Измененные файлы
|
||||
pulls.reopen_to_merge=Пожалуйста снова откройте этот запрос для слияния.
|
||||
pulls.merged=Слито
|
||||
pulls.has_merged=Слияние этого запроса успешно завершено!
|
||||
pulls.data_broken=Содержимое этого пулл-реквеста было нарушено, вследствии удаления или клонирования информации.
|
||||
pulls.data_broken=Содержимое этого запроса было нарушено вследствие удаления информации ответвления.
|
||||
pulls.is_checking=Продолжается проверка конфликтов, пожалуйста обновите страницу несколько позже.
|
||||
pulls.can_auto_merge_desc=Этот запрос на слияние может быть объединён автоматически.
|
||||
pulls.cannot_auto_merge_desc=Этот запрос на слияние не может быть объединён автоматически.
|
||||
@@ -550,7 +547,7 @@ milestones.deletion_success=Контрольная точка успешно у
|
||||
|
||||
wiki=Вики
|
||||
wiki.welcome=Добро пожаловать в Вики!
|
||||
wiki.welcome_desc=Вики это место, где вы хотели бы документировать проект вместе и сделать его лучше.
|
||||
wiki.welcome_desc=Вики это место, где вы можете документировать проект вместе и сделать его лучше.
|
||||
wiki.create_first_page=Создать первую страницу
|
||||
wiki.page=Страница
|
||||
wiki.filter_page=Фильтр страницы
|
||||
@@ -560,6 +557,8 @@ wiki.save_page=Сохранить страницу
|
||||
wiki.last_commit_info=%s редактировал эту страницу %s
|
||||
wiki.edit_page_button=Редактировать
|
||||
wiki.new_page_button=Новая страница
|
||||
wiki.delete_page_button=Удалить страницу
|
||||
wiki.delete_page_notice_1=Будьте внимательны! Это приведет к удалению страницы <code>«%s»</code>.
|
||||
wiki.page_already_exists=Вики-страница с таким именем уже существует.
|
||||
wiki.pages=Страницы
|
||||
wiki.last_updated=Последнее обновление %s
|
||||
@@ -576,7 +575,7 @@ settings.change_reponame_prompt=Это изменение повлияет на
|
||||
settings.advanced_settings=Расширенные настройки
|
||||
settings.wiki_desc=Включить Вики, чтобы позволить людям писать документы
|
||||
settings.use_external_wiki=Использовать внешнюю Wiki
|
||||
settings.external_wiki_url=URL-адрес внешней вики
|
||||
settings.external_wiki_url=URL-адрес внешней Вики
|
||||
settings.external_wiki_url_desc=Посетители будут перенаправлены на URL-адрес, когда они кликнут по вкладке.
|
||||
settings.issues_desc=Включить встроенную, легковесную систему отслеживания ошибок
|
||||
settings.use_external_issue_tracker=Использовать внешнюю систему отслеживания ошибок
|
||||
@@ -595,13 +594,17 @@ settings.transfer_desc=Передать репозиторий другому п
|
||||
settings.transfer_notices_1=- Вы можете потерять доступ, если новый владелец является отдельным пользователем.
|
||||
settings.transfer_notices_2=- Вы сохраните доступ, если новым владельцем станет организация, владельцем которой вы являетесь.
|
||||
settings.transfer_form_title=Введите сопутствующую информацию для подтверждения операции:
|
||||
settings.wiki_delete=Стереть данные Вики
|
||||
settings.wiki_delete_desc=Будьте внимательны! Как только вы удалите Вики — пути назад не будет.
|
||||
settings.wiki_delete_notices_1=-Это будет удалено и отключит Вики для %s
|
||||
settings.wiki_deletion_success=Данные Вики успешно стерты.
|
||||
settings.delete=Удалить этот репозиторий
|
||||
settings.delete_desc=Как только вы удалите репозиторий — пути назад не будет. Удостоверьтесь, что вам это точно нужно.
|
||||
settings.delete_desc=Будьте внимательны! Как только вы удалите репозиторий — пути назад не будет.
|
||||
settings.delete_notices_1=- Эта операция <strong>НЕ МОЖЕТ</strong> быть отменена.
|
||||
settings.delete_notices_2=- Эта операция навсегда удалит всё из этого репозитория, включая данные Git, связанные с ним задачи, комментарии и права доступа для сотрудников.
|
||||
settings.delete_notices_fork_1=- Если данный репозиторий является публичным, все склонированные репозитории останутся независимыми, после его удаления.
|
||||
settings.delete_notices_fork_2=- Если данный репозиторий является приватным, все его форки будут удалены вместе с ним.
|
||||
settings.delete_notices_fork_3=- Если вы хотите сохранить все форки после удаления репозитория, то сначала сделайте его публичным.
|
||||
settings.delete_notices_fork_2=- Если данный репозиторий является приватным, все его ответвления будут удалены вместе с ним.
|
||||
settings.delete_notices_fork_3=- Если вы хотите сохранить все ответвления после удаления репозитория, то сначала сделайте его публичным.
|
||||
settings.deletion_success=Репозиторий был успешно удалён!
|
||||
settings.update_settings_success=Настройка репозитория обновлена успешно.
|
||||
settings.transfer_owner=Новый владелец
|
||||
@@ -610,6 +613,9 @@ settings.transfer_succeed=Владение репозиторием было у
|
||||
settings.confirm_delete=Подтвердить удаление
|
||||
settings.add_collaborator=Добавить нового соавтора
|
||||
settings.add_collaborator_success=Был добавлен новый соавтор.
|
||||
settings.delete_collaborator=Удалить
|
||||
settings.collaborator_deletion=Удаление соавтора
|
||||
settings.collaborator_deletion_desc=Этот пользователь больше не будет иметь доступа для совместной работы в этом репозитории после удаления. Вы хотите продолжить?
|
||||
settings.remove_collaborator_success=Соавтор был удален.
|
||||
settings.search_user_placeholder=Поиск пользователя...
|
||||
settings.org_not_allowed_to_be_collaborator=Организации не могут быть добавлены как соавторы.
|
||||
@@ -686,7 +692,7 @@ diff.view_file=Просмотреть файл
|
||||
release.releases=Релизы
|
||||
release.new_release=Новый релиз
|
||||
release.draft=Черновик
|
||||
release.prerelease=Предрелиз
|
||||
release.prerelease=Пре-релиз
|
||||
release.stable=Стабильный
|
||||
release.edit=Редактировать
|
||||
release.ahead=<strong>%d</strong> коммитов %s начиная с этого релиза
|
||||
@@ -709,9 +715,9 @@ release.save_draft=Сохранить черновик
|
||||
release.edit_release=Редактировать релиз
|
||||
release.delete_release=Удалить этот релиз
|
||||
release.deletion=Удаление релиза
|
||||
release.deletion_desc=Удаление данного релиза так же удалит все относящиеся к нему Git теги. Продолжить?
|
||||
release.deletion_desc=Удаление этого релиза удалит соответствующую Git метку. Вы хотите продолжить?
|
||||
release.deletion_success=Релиз был успешно удален!
|
||||
release.tag_name_already_exist=Релиз с этим именем тега уже существует.
|
||||
release.tag_name_already_exist=Релиз с этим именем метки уже существует.
|
||||
release.downloads=Загрузки
|
||||
|
||||
[org]
|
||||
@@ -944,6 +950,7 @@ auths.update=Обновить параметры аутентификации
|
||||
auths.delete=Удалить этот канал аутентификации
|
||||
auths.delete_auth_title=Удаление канала аутентификации
|
||||
auths.delete_auth_desc=Этот канал аутентификации будет удален. Вы уверены что хотите продолжить?
|
||||
auths.still_in_used=Эта проверка подлинности до сих пор используется некоторыми пользователями, удалите или преобразуйте этих пользователей в другой тип входа в систему.
|
||||
auths.deletion_success=Канал аутентификации успешно удален!
|
||||
|
||||
config.server_config=Конфигурация сервера
|
||||
@@ -960,6 +967,19 @@ config.static_file_root_path=Статичный путь до файла
|
||||
config.log_file_root_path=Путь до папки с логами
|
||||
config.script_type=Тип сценария
|
||||
config.reverse_auth_user=Заголовок с именем пользователя для авторизации на reverse proxy
|
||||
|
||||
config.ssh_config=Конфигурация SSH
|
||||
config.ssh_enabled=Включено
|
||||
config.ssh_start_builtin_server=Запустить встроенный сервер
|
||||
config.ssh_domain=Домен
|
||||
config.ssh_port=Порт
|
||||
config.ssh_listen_port=Прослушиваемый порт
|
||||
config.ssh_root_path=Корневой путь
|
||||
config.ssh_key_test_path=Путь к тестовому ключу
|
||||
config.ssh_keygen_path=Путь к генератору ключей ('ssh-keygen')
|
||||
config.ssh_minimum_key_size_check=Минимальный размер ключа проверки
|
||||
config.ssh_minimum_key_sizes=Минимальные размеры ключа
|
||||
|
||||
config.db_config=Конфигурация базы данных
|
||||
config.db_type=Тип
|
||||
config.db_host=Хост
|
||||
@@ -989,6 +1009,9 @@ config.mailer_disable_helo=Отключить HELO
|
||||
config.mailer_name=Имя
|
||||
config.mailer_host=Сервер
|
||||
config.mailer_user=Пользователь
|
||||
config.send_test_mail=Отправить тестовое письмо
|
||||
config.test_mail_failed=Не удалось отправить тестовое письмо «%s»: %v
|
||||
config.test_mail_sent=Тестовое письмо было отправлено «%s».
|
||||
config.oauth_config=Конфигурация OAuth
|
||||
config.oauth_enabled=Включено
|
||||
config.cache_config=Настройки кеша
|
||||
@@ -1042,7 +1065,9 @@ commit_repo=запушил(а) <a href="%[1]s/src/%[2]s">%[3]s</a> в <a href="%
|
||||
create_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>`
|
||||
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>`
|
||||
reopen_pull_request=`открыл снова запрос на слияние <a href="%s/pulls/%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>`
|
||||
transfer_repo=перенес репозиторий <code>%s</code> в <a href="%s">%s</a>
|
||||
|
||||
@@ -221,8 +221,6 @@ still_own_repo=您的帐户仍然是某些仓库的拥有者,您必须先转
|
||||
still_has_org=您的帐户仍旧是某些组织的成员,您必须先离开或删除组织。
|
||||
org_still_own_repo=该组织仍然是某些仓库的拥有者,您必须先转移或删除它们才能执行删除组织操作!
|
||||
|
||||
still_own_user=该授权认证依旧被部分用户使用,请先删除该部分用户后再试!
|
||||
|
||||
target_branch_not_exist=目标分支不存在。
|
||||
|
||||
[user]
|
||||
@@ -264,11 +262,10 @@ continue=继续操作
|
||||
cancel=取消操作
|
||||
|
||||
enable_custom_avatar=启动自定义头像
|
||||
enable_custom_avatar_helper=激活该选项来禁止从 Gravatar 获取头像
|
||||
choose_new_avatar=选择新的头像
|
||||
update_avatar=更新头像设置
|
||||
delete_current_avatar=删除当前头像
|
||||
uploaded_avatar_not_a_image=上传的文件不是一张图片!
|
||||
no_custom_avatar_available=未上传过自定义头像,无法激活该选项。
|
||||
update_avatar_success=您的头像设置更新成功!
|
||||
|
||||
change_password=修改密码
|
||||
@@ -479,7 +476,7 @@ issues.closed_at=`于 <a id="%[1]s" href="#%[1]s">%[2]s</a> 关闭`
|
||||
issues.reopened_at=`于 <a id="%[1]s" href="#%[1]s">%[2]s</a> 重新开启`
|
||||
issues.commit_ref_at=`在代码提交 <a id="%[1]s" href="#%[1]s">%[2]s</a> 中引用了该工单`
|
||||
issues.poster=发布者
|
||||
issues.admin=管理员
|
||||
issues.collaborator=协作者
|
||||
issues.owner=所有者
|
||||
issues.sign_up_for_free=免费注册
|
||||
issues.sign_in_require_desc=并加入到对话中来。如果您已经注册,可以直接 <a href="%s">登录并评论</a>
|
||||
@@ -560,6 +557,8 @@ wiki.save_page=保存页面
|
||||
wiki.last_commit_info=%s 于 %s 修改了此页面
|
||||
wiki.edit_page_button=修改
|
||||
wiki.new_page_button=新的页面
|
||||
wiki.delete_page_button=删除页面
|
||||
wiki.delete_page_notice_1=此操作将删除页面 <code>"%s"</code>,请三思而后行。
|
||||
wiki.page_already_exists=相同名称的 Wiki 页面已经存在。
|
||||
wiki.pages=所有页面
|
||||
wiki.last_updated=最后更新于 %s
|
||||
@@ -595,6 +594,10 @@ settings.transfer_desc=您可以将仓库转移至您拥有管理员权限的帐
|
||||
settings.transfer_notices_1=- 如果您将仓库转移给个人用户,您将会丢失操作权限。
|
||||
settings.transfer_notices_2=- 如果您将仓库转移给您是所有者的组织,您的操作权限将被保留。
|
||||
settings.transfer_form_title=请输入以下信息以确认您的操作:
|
||||
settings.wiki_delete=清除 Wiki 数据
|
||||
settings.wiki_delete_desc=清除 Wiki 数据操作不可逆转,请三思而后行。
|
||||
settings.wiki_delete_notices_1=- 此操作将会清除并禁用仓库 %s 的 Wiki
|
||||
settings.wiki_deletion_success=仓库 Wiki 数据清除成功!
|
||||
settings.delete=删除本仓库
|
||||
settings.delete_desc=删除仓库操作不可逆转,请三思而后行。
|
||||
settings.delete_notices_1=- 此操作 <strong>不可以</strong> 被回滚。
|
||||
@@ -610,6 +613,9 @@ settings.transfer_succeed=仓库所有权转移成功!
|
||||
settings.confirm_delete=确认删除仓库
|
||||
settings.add_collaborator=增加新的协作者
|
||||
settings.add_collaborator_success=成功添加新的协作者!
|
||||
settings.delete_collaborator=删除
|
||||
settings.collaborator_deletion=删除协作者
|
||||
settings.collaborator_deletion_desc=此用户被删除后将不再拥有相关的协作权限。是否继续?
|
||||
settings.remove_collaborator_success=被操作的协作者已经被收回权限!
|
||||
settings.search_user_placeholder=搜索用户...
|
||||
settings.org_not_allowed_to_be_collaborator=组织不允许被添加为仓库协作者!
|
||||
@@ -944,6 +950,7 @@ auths.update=更新认证设置
|
||||
auths.delete=删除该认证
|
||||
auths.delete_auth_title=删除认证操作
|
||||
auths.delete_auth_desc=该认证将被删除。是否继续?
|
||||
auths.still_in_used=此认证仍旧与一些用户有关联,请先删除或者将这些用户转换为其它登录类型。
|
||||
auths.deletion_success=授权源删除成功!
|
||||
|
||||
config.server_config=服务器配置
|
||||
@@ -960,6 +967,19 @@ config.static_file_root_path=静态文件根目录
|
||||
config.log_file_root_path=日志文件根目录
|
||||
config.script_type=脚本类型
|
||||
config.reverse_auth_user=反向代理认证
|
||||
|
||||
config.ssh_config=SSH 配置
|
||||
config.ssh_enabled=启用服务
|
||||
config.ssh_start_builtin_server=启用内置服务
|
||||
config.ssh_domain=域名
|
||||
config.ssh_port=端口
|
||||
config.ssh_listen_port=监听端口
|
||||
config.ssh_root_path=根目录
|
||||
config.ssh_key_test_path=密钥测试路径
|
||||
config.ssh_keygen_path=密钥生成器('ssh-keygen')路径
|
||||
config.ssh_minimum_key_size_check=密钥最小长度检查
|
||||
config.ssh_minimum_key_sizes=密钥最小长度限制
|
||||
|
||||
config.db_config=数据库配置
|
||||
config.db_type=数据库类型
|
||||
config.db_host=主机地址
|
||||
@@ -989,6 +1009,9 @@ config.mailer_disable_helo=禁用 HELO 操作
|
||||
config.mailer_name=发送者名称
|
||||
config.mailer_host=邮件主机地址
|
||||
config.mailer_user=发送者帐号
|
||||
config.send_test_mail=发送测试邮件
|
||||
config.test_mail_failed=发送测试邮件至 '%s' 时失败:%v
|
||||
config.test_mail_sent=测试邮件已经发送至 '%s'。
|
||||
config.oauth_config=社交帐号配置
|
||||
config.oauth_enabled=启用服务
|
||||
config.cache_config=Cache 配置
|
||||
@@ -1043,6 +1066,8 @@ create_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>`
|
||||
create_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>`
|
||||
comment_issue=`评论了工单 <a href="%s/issues/%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>
|
||||
|
||||
@@ -221,8 +221,6 @@ still_own_repo=您的帳戶仍然是某些倉庫的擁有者,您必須先轉
|
||||
still_has_org=您的帳戶仍舊是某些組織的成員,您必須先離開或刪除組織。
|
||||
org_still_own_repo=該組織仍然是某些倉庫的擁有者,您必須先轉移或刪除它們才能執行刪除組織操作!
|
||||
|
||||
still_own_user=該授權認證依舊被部分用戶使用,請先刪除該部分用戶後再試!
|
||||
|
||||
target_branch_not_exist=目標分支不存在
|
||||
|
||||
[user]
|
||||
@@ -264,11 +262,10 @@ continue=繼續操作
|
||||
cancel=取消操作
|
||||
|
||||
enable_custom_avatar=啟動自定義頭像
|
||||
enable_custom_avatar_helper=激活該選項來禁止從 Gravatar 獲取頭像
|
||||
choose_new_avatar=選擇新的頭像
|
||||
update_avatar=更新頭像設置
|
||||
delete_current_avatar=Delete Current Avatar
|
||||
uploaded_avatar_not_a_image=上傳的文件不是一張圖片!
|
||||
no_custom_avatar_available=沒有任何自定義頭像,無法激活該選項。
|
||||
update_avatar_success=您的頭像設置更新成功!
|
||||
|
||||
change_password=修改密碼
|
||||
@@ -479,7 +476,7 @@ issues.closed_at=`於 <a id="%[1]s" href="#%[1]s">%[2]s</a> 關閉`
|
||||
issues.reopened_at=`於 <a id="%[1]s" href="#%[1]s">%[2]s</a> 重新開啟`
|
||||
issues.commit_ref_at=`在代碼提交 <a id="%[1]s" href="#%[1]s">%[2]s</a> 中引用了該問題`
|
||||
issues.poster=發佈者
|
||||
issues.admin=管理員
|
||||
issues.collaborator=Collaborator
|
||||
issues.owner=所有者
|
||||
issues.sign_up_for_free=免費註冊
|
||||
issues.sign_in_require_desc=及加入到對話當中。如果您已經註冊,可以直接 <a href="%s">登錄及評論</a>
|
||||
@@ -560,6 +557,8 @@ wiki.save_page=保存頁面
|
||||
wiki.last_commit_info=%s 於 %s 修改了此頁面
|
||||
wiki.edit_page_button=修改
|
||||
wiki.new_page_button=新的頁面
|
||||
wiki.delete_page_button=Delete Page
|
||||
wiki.delete_page_notice_1=This will delete the page <code>"%s"</code>. Please be certain.
|
||||
wiki.page_already_exists=相同名稱的 Wiki 頁面已經存在。
|
||||
wiki.pages=所有頁面
|
||||
wiki.last_updated=最後更新於 %s
|
||||
@@ -595,6 +594,10 @@ settings.transfer_desc=您可以將倉庫轉移至您擁有管理員權限的帳
|
||||
settings.transfer_notices_1=- 如果您將倉庫轉移給個人用戶,您將會丟失操作權限。
|
||||
settings.transfer_notices_2=- 如果您將倉庫轉移給您是所有者的組織,您的操作權限將被保留。
|
||||
settings.transfer_form_title=請輸入以下信息以確認您的操作:
|
||||
settings.wiki_delete=Erase Wiki Data
|
||||
settings.wiki_delete_desc=Once you erase wiki data there is no going back. Please be certain.
|
||||
settings.wiki_delete_notices_1=- This will delete and disable the wiki for %s
|
||||
settings.wiki_deletion_success=Repository wiki data have been erased successfully.
|
||||
settings.delete=刪除本倉庫
|
||||
settings.delete_desc=刪除倉庫操作不可逆轉,請三思而後行。
|
||||
settings.delete_notices_1=- 此操作 <strong>不可以</strong> 被回滾。
|
||||
@@ -610,6 +613,9 @@ settings.transfer_succeed=倉庫所有權轉移成功!
|
||||
settings.confirm_delete=確認刪除倉庫
|
||||
settings.add_collaborator=增加新的協作者
|
||||
settings.add_collaborator_success=成功添加新的協作者!
|
||||
settings.delete_collaborator=Delete
|
||||
settings.collaborator_deletion=Collaborator Deletion
|
||||
settings.collaborator_deletion_desc=This user will no longer have collaboration access to this repository after deletion. Do you want to continue?
|
||||
settings.remove_collaborator_success=被操作的協作者已經被收回權限!
|
||||
settings.search_user_placeholder=搜索用戶...
|
||||
settings.org_not_allowed_to_be_collaborator=Organization is not allowed to be added as a collaborator.
|
||||
@@ -944,6 +950,7 @@ auths.update=更新認證設置
|
||||
auths.delete=刪除該認證
|
||||
auths.delete_auth_title=刪除認證操作
|
||||
auths.delete_auth_desc=該認證將被刪除。是否繼續?
|
||||
auths.still_in_used=This authentication is still used by some users, please delete or convert these users to another login type first.
|
||||
auths.deletion_success=認證源刪除成功!
|
||||
|
||||
config.server_config=服務器配置
|
||||
@@ -960,6 +967,19 @@ config.static_file_root_path=靜態文件根目錄
|
||||
config.log_file_root_path=日志文件根目錄
|
||||
config.script_type=腳本類型
|
||||
config.reverse_auth_user=反向代理認證
|
||||
|
||||
config.ssh_config=SSH Configuration
|
||||
config.ssh_enabled=Enabled
|
||||
config.ssh_start_builtin_server=Start Builtin Server
|
||||
config.ssh_domain=Domain
|
||||
config.ssh_port=Port
|
||||
config.ssh_listen_port=Listen Port
|
||||
config.ssh_root_path=Root Path
|
||||
config.ssh_key_test_path=Key Test Path
|
||||
config.ssh_keygen_path=Keygen ('ssh-keygen') Path
|
||||
config.ssh_minimum_key_size_check=Minimum Key Size Check
|
||||
config.ssh_minimum_key_sizes=Minimum Key Sizes
|
||||
|
||||
config.db_config=數據庫配置
|
||||
config.db_type=數據庫類型
|
||||
config.db_host=主機地址
|
||||
@@ -989,6 +1009,9 @@ config.mailer_disable_helo=禁用 HELO 操作
|
||||
config.mailer_name=發送者名稱
|
||||
config.mailer_host=郵件主機地址
|
||||
config.mailer_user=發送者帳號
|
||||
config.send_test_mail=Send Test Email
|
||||
config.test_mail_failed=Fail to send test email to '%s': %v
|
||||
config.test_mail_sent=Test email has been sent to '%s'.
|
||||
config.oauth_config=社交帳號配置
|
||||
config.oauth_enabled=啟用服務
|
||||
config.cache_config=Cache 配置
|
||||
@@ -1043,6 +1066,8 @@ create_issue=`創建了問題 <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
close_issue=`closed issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
reopen_issue=`reopened issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
create_pull_request=`創建了合併請求 <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
close_pull_request=`closed pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
reopen_pull_request=`reopened pull request <a href="%s/pulls/%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>`
|
||||
transfer_repo=將儲存庫 <code>%s</code> 轉移至 <a href="%s">%s</a>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# Docker for Gogs
|
||||
|
||||
Visit [Docker Hub](https://hub.docker.com/r/gogs/gogs/) or [Quay](https://quay.io/repository/gogs/gogs) see all available tags.
|
||||
Visit [Docker Hub](https://hub.docker.com/r/gogs/gogs/) see all available tags.
|
||||
|
||||
## Usage
|
||||
|
||||
To keep your data out of Docker container, we do a volume(`/var/gogs` -> `/data`) here, and you can change it based on your situation.
|
||||
To keep your data out of Docker container, we do a volume (`/var/gogs` -> `/data`) here, and you can change it based on your situation.
|
||||
|
||||
```
|
||||
# Pull image from Docker Hub.
|
||||
@@ -64,10 +64,10 @@ Most of settings are obvious and easy to understand, but there are some settings
|
||||
|
||||
- **Repository Root Path**: keep it as default value `/home/git/gogs-repositories` because `start.sh` already made a symbolic link for you.
|
||||
- **Run User**: keep it as default value `git` because `start.sh` already setup a user with name `git`.
|
||||
- **Domain**: fill in with Docker container IP(e.g. `192.168.99.100`). But if you want to access your Gogs instance from a different physical machine, please fill in with the hostname or IP address of the Docker host machine.
|
||||
- **Domain**: fill in with Docker container IP (e.g. `192.168.99.100`). But if you want to access your Gogs instance from a different physical machine, please fill in with the hostname or IP address of the Docker host machine.
|
||||
- **SSH Port**: Use the exposed port from Docker container. For example, your SSH server listens on `22` inside Docker, but you expose it by `10022:22`, then use `10022` for this value. **Builtin SSH server is not recommended inside Docker Container**
|
||||
- **HTTP Port**: Use port you want Gogs to listen on inside Docker container. For example, your Gogs listens on `3000` inside Docker, and you expose it by `10080:3000`, but you still use `3000` for this value.
|
||||
- **Application URL**: Use combination of **Domain** and **exposed HTTP Port** values(e.g. `http://192.168.99.100:10080/`).
|
||||
- **Application URL**: Use combination of **Domain** and **exposed HTTP Port** values (e.g. `http://192.168.99.100:10080/`).
|
||||
|
||||
Full documentation of application settings can be found [here](http://gogs.io/docs/advanced/configuration_cheat_sheet.html).
|
||||
|
||||
@@ -88,4 +88,4 @@ Steps to upgrade Gogs with Docker:
|
||||
|
||||
## Known Issues
|
||||
|
||||
- `.dockerignore` seems to be ignored during Docker Hub Automated build
|
||||
- The docker container can not currently be build on Raspberry 1 (armv6l) as our base image `alpine` does not have a `go` package available for this platform.
|
||||
|
||||
@@ -7,7 +7,7 @@ export GOPATH=/tmp/go
|
||||
export PATH=${PATH}:${GOPATH}/bin
|
||||
|
||||
# Install build deps
|
||||
apk -U --no-progress add --virtual build-deps linux-pam-dev go gcc musl-dev
|
||||
apk --no-cache --no-progress add --virtual build-deps linux-pam-dev go gcc musl-dev
|
||||
|
||||
# Init go environment to build Gogs
|
||||
mkdir -p ${GOPATH}/src/github.com/gogits/
|
||||
|
||||
2
gogs.go
2
gogs.go
@@ -17,7 +17,7 @@ import (
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
const APP_VER = "0.8.43.0223"
|
||||
const APP_VER = "0.9.0.0306"
|
||||
|
||||
func init() {
|
||||
runtime.GOMAXPROCS(runtime.NumCPU())
|
||||
|
||||
@@ -13,11 +13,11 @@ import (
|
||||
type AccessMode int
|
||||
|
||||
const (
|
||||
ACCESS_MODE_NONE AccessMode = iota
|
||||
ACCESS_MODE_READ
|
||||
ACCESS_MODE_WRITE
|
||||
ACCESS_MODE_ADMIN
|
||||
ACCESS_MODE_OWNER
|
||||
ACCESS_MODE_NONE AccessMode = iota // 0
|
||||
ACCESS_MODE_READ // 1
|
||||
ACCESS_MODE_WRITE // 2
|
||||
ACCESS_MODE_ADMIN // 3
|
||||
ACCESS_MODE_OWNER // 4
|
||||
)
|
||||
|
||||
// Access represents the highest access level of a user to the repository. The only access type
|
||||
@@ -151,15 +151,14 @@ func (repo *Repository) refreshAccesses(e Engine, accessMap map[int64]AccessMode
|
||||
return nil
|
||||
}
|
||||
|
||||
// FIXME: should be able to have read-only access.
|
||||
// Give all collaborators write access.
|
||||
// refreshCollaboratorAccesses retrieves repository collaborations with their access modes.
|
||||
func (repo *Repository) refreshCollaboratorAccesses(e Engine, accessMap map[int64]AccessMode) error {
|
||||
collaborators, err := repo.getCollaborators(e)
|
||||
collaborations, err := repo.getCollaborations(e)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getCollaborators: %v", err)
|
||||
return fmt.Errorf("getCollaborations: %v", err)
|
||||
}
|
||||
for _, c := range collaborators {
|
||||
accessMap[c.Id] = ACCESS_MODE_WRITE
|
||||
for _, c := range collaborations {
|
||||
accessMap[c.UserID] = c.Mode
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -41,6 +41,8 @@ const (
|
||||
ACTION_MERGE_PULL_REQUEST // 11
|
||||
ACTION_CLOSE_ISSUE // 12
|
||||
ACTION_REOPEN_ISSUE // 13
|
||||
ACTION_CLOSE_PULL_REQUEST // 14
|
||||
ACTION_REOPEN_PULL_REQUEST // 15
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -368,7 +370,7 @@ func updateIssuesCommit(u *User, repo *Repository, repoUserName, repoName string
|
||||
continue
|
||||
}
|
||||
|
||||
if err = issue.ChangeStatus(u, true); err != nil {
|
||||
if err = issue.ChangeStatus(u, repo, true); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -408,7 +410,7 @@ func updateIssuesCommit(u *User, repo *Repository, repoUserName, repoName string
|
||||
continue
|
||||
}
|
||||
|
||||
if err = issue.ChangeStatus(u, false); err != nil {
|
||||
if err = issue.ChangeStatus(u, repo, false); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
511
models/issue.go
511
models/issue.go
@@ -218,7 +218,8 @@ func (i *Issue) ReadBy(uid int64) error {
|
||||
return UpdateIssueUserByRead(uid, i.ID)
|
||||
}
|
||||
|
||||
func (i *Issue) changeStatus(e *xorm.Session, doer *User, isClosed bool) (err error) {
|
||||
func (i *Issue) changeStatus(e *xorm.Session, doer *User, repo *Repository, isClosed bool) (err error) {
|
||||
// Nothing should be performed if current status is same as target status
|
||||
if i.IsClosed == isClosed {
|
||||
return nil
|
||||
}
|
||||
@@ -230,7 +231,7 @@ func (i *Issue) changeStatus(e *xorm.Session, doer *User, isClosed bool) (err er
|
||||
return err
|
||||
}
|
||||
|
||||
// Update labels.
|
||||
// Update issue count of labels
|
||||
if err = i.getLabels(e); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -245,28 +246,28 @@ func (i *Issue) changeStatus(e *xorm.Session, doer *User, isClosed bool) (err er
|
||||
}
|
||||
}
|
||||
|
||||
// Update milestone.
|
||||
// Update issue count of milestone
|
||||
if err = changeMilestoneIssueStats(e, i); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// New action comment.
|
||||
if _, err = createStatusComment(e, doer, i.Repo, i); err != nil {
|
||||
// New action comment
|
||||
if _, err = createStatusComment(e, doer, repo, i); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ChangeStatus changes issue status to open/closed.
|
||||
func (i *Issue) ChangeStatus(doer *User, isClosed bool) (err error) {
|
||||
// ChangeStatus changes issue status to open or closed.
|
||||
func (i *Issue) ChangeStatus(doer *User, repo *Repository, isClosed bool) (err error) {
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = i.changeStatus(sess, doer, isClosed); err != nil {
|
||||
if err = i.changeStatus(sess, doer, repo, isClosed); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -297,20 +298,19 @@ func newIssue(e *xorm.Session, repo *Repository, issue *Issue, labelIDs []int64,
|
||||
return err
|
||||
}
|
||||
|
||||
var label *Label
|
||||
for _, id := range labelIDs {
|
||||
if id == 0 {
|
||||
continue
|
||||
if len(labelIDs) > 0 {
|
||||
// During the session, SQLite3 dirver cannot handle retrieve objects after update something.
|
||||
// So we have to get all needed labels first.
|
||||
labels := make([]*Label, 0, len(labelIDs))
|
||||
if err = e.In("id", labelIDs).Find(&labels); err != nil {
|
||||
return fmt.Errorf("find all labels: %v", err)
|
||||
}
|
||||
|
||||
label, err = getLabelByID(e, id)
|
||||
if err != nil {
|
||||
return err
|
||||
for _, label := range labels {
|
||||
if err = issue.addLabel(e, label); err != nil {
|
||||
return fmt.Errorf("addLabel: %v", err)
|
||||
}
|
||||
}
|
||||
if err = issue.addLabel(e, label); err != nil {
|
||||
return fmt.Errorf("addLabel: %v", err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if issue.MilestoneID > 0 {
|
||||
@@ -860,7 +860,7 @@ func UpdateIssue(issue *Issue) error {
|
||||
return updateIssue(x, issue)
|
||||
}
|
||||
|
||||
// updateIssueCols updates specific fields of given issue.
|
||||
// updateIssueCols only updates values of specific columns for given issue.
|
||||
func updateIssueCols(e Engine, issue *Issue, cols ...string) error {
|
||||
_, err := e.Id(issue.ID).Cols(cols...).Update(issue)
|
||||
return err
|
||||
@@ -934,213 +934,6 @@ func UpdateIssueUsersByMentions(uids []int64, iid int64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// .____ ___. .__
|
||||
// | | _____ \_ |__ ____ | |
|
||||
// | | \__ \ | __ \_/ __ \| |
|
||||
// | |___ / __ \| \_\ \ ___/| |__
|
||||
// |_______ (____ /___ /\___ >____/
|
||||
// \/ \/ \/ \/
|
||||
|
||||
// Label represents a label of repository for issues.
|
||||
type Label struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
RepoID int64 `xorm:"INDEX"`
|
||||
Name string
|
||||
Color string `xorm:"VARCHAR(7)"`
|
||||
NumIssues int
|
||||
NumClosedIssues int
|
||||
NumOpenIssues int `xorm:"-"`
|
||||
IsChecked bool `xorm:"-"`
|
||||
}
|
||||
|
||||
// CalOpenIssues calculates the open issues of label.
|
||||
func (m *Label) CalOpenIssues() {
|
||||
m.NumOpenIssues = m.NumIssues - m.NumClosedIssues
|
||||
}
|
||||
|
||||
// NewLabel creates new label of repository.
|
||||
func NewLabel(l *Label) error {
|
||||
_, err := x.Insert(l)
|
||||
return err
|
||||
}
|
||||
|
||||
func getLabelByID(e Engine, id int64) (*Label, error) {
|
||||
if id <= 0 {
|
||||
return nil, ErrLabelNotExist{id}
|
||||
}
|
||||
|
||||
l := &Label{ID: id}
|
||||
has, err := x.Get(l)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if !has {
|
||||
return nil, ErrLabelNotExist{l.ID}
|
||||
}
|
||||
return l, nil
|
||||
}
|
||||
|
||||
// GetLabelByID returns a label by given ID.
|
||||
func GetLabelByID(id int64) (*Label, error) {
|
||||
return getLabelByID(x, id)
|
||||
}
|
||||
|
||||
// GetLabelsByRepoID returns all labels that belong to given repository by ID.
|
||||
func GetLabelsByRepoID(repoID int64) ([]*Label, error) {
|
||||
labels := make([]*Label, 0, 10)
|
||||
return labels, x.Where("repo_id=?", repoID).Find(&labels)
|
||||
}
|
||||
|
||||
func getLabelsByIssueID(e Engine, issueID int64) ([]*Label, error) {
|
||||
issueLabels, err := getIssueLabels(e, issueID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("getIssueLabels: %v", err)
|
||||
}
|
||||
|
||||
var label *Label
|
||||
labels := make([]*Label, 0, len(issueLabels))
|
||||
for idx := range issueLabels {
|
||||
label, err = getLabelByID(e, issueLabels[idx].LabelID)
|
||||
if err != nil && !IsErrLabelNotExist(err) {
|
||||
return nil, fmt.Errorf("getLabelByID: %v", err)
|
||||
}
|
||||
labels = append(labels, label)
|
||||
}
|
||||
return labels, nil
|
||||
}
|
||||
|
||||
// GetLabelsByIssueID returns all labels that belong to given issue by ID.
|
||||
func GetLabelsByIssueID(issueID int64) ([]*Label, error) {
|
||||
return getLabelsByIssueID(x, issueID)
|
||||
}
|
||||
|
||||
func updateLabel(e Engine, l *Label) error {
|
||||
_, err := e.Id(l.ID).AllCols().Update(l)
|
||||
return err
|
||||
}
|
||||
|
||||
// UpdateLabel updates label information.
|
||||
func UpdateLabel(l *Label) error {
|
||||
return updateLabel(x, l)
|
||||
}
|
||||
|
||||
// DeleteLabel delete a label of given repository.
|
||||
func DeleteLabel(repoID, labelID int64) error {
|
||||
l, err := GetLabelByID(labelID)
|
||||
if err != nil {
|
||||
if IsErrLabelNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err = x.Where("label_id=?", labelID).Delete(new(IssueLabel)); err != nil {
|
||||
return err
|
||||
} else if _, err = sess.Delete(l); err != nil {
|
||||
return err
|
||||
}
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
// .___ .____ ___. .__
|
||||
// | | ______ ________ __ ____ | | _____ \_ |__ ____ | |
|
||||
// | |/ ___// ___/ | \_/ __ \| | \__ \ | __ \_/ __ \| |
|
||||
// | |\___ \ \___ \| | /\ ___/| |___ / __ \| \_\ \ ___/| |__
|
||||
// |___/____ >____ >____/ \___ >_______ (____ /___ /\___ >____/
|
||||
// \/ \/ \/ \/ \/ \/ \/
|
||||
|
||||
// IssueLabel represetns an issue-lable relation.
|
||||
type IssueLabel struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
IssueID int64 `xorm:"UNIQUE(s)"`
|
||||
LabelID int64 `xorm:"UNIQUE(s)"`
|
||||
}
|
||||
|
||||
func hasIssueLabel(e Engine, issueID, labelID int64) bool {
|
||||
has, _ := e.Where("issue_id=? AND label_id=?", issueID, labelID).Get(new(IssueLabel))
|
||||
return has
|
||||
}
|
||||
|
||||
// HasIssueLabel returns true if issue has been labeled.
|
||||
func HasIssueLabel(issueID, labelID int64) bool {
|
||||
return hasIssueLabel(x, issueID, labelID)
|
||||
}
|
||||
|
||||
func newIssueLabel(e *xorm.Session, issue *Issue, label *Label) (err error) {
|
||||
if _, err = e.Insert(&IssueLabel{
|
||||
IssueID: issue.ID,
|
||||
LabelID: label.ID,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
label.NumIssues++
|
||||
if issue.IsClosed {
|
||||
label.NumClosedIssues++
|
||||
}
|
||||
return updateLabel(e, label)
|
||||
}
|
||||
|
||||
// NewIssueLabel creates a new issue-label relation.
|
||||
func NewIssueLabel(issue *Issue, label *Label) (err error) {
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = newIssueLabel(sess, issue, label); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
func getIssueLabels(e Engine, issueID int64) ([]*IssueLabel, error) {
|
||||
issueLabels := make([]*IssueLabel, 0, 10)
|
||||
return issueLabels, e.Where("issue_id=?", issueID).Asc("label_id").Find(&issueLabels)
|
||||
}
|
||||
|
||||
// GetIssueLabels returns all issue-label relations of given issue by ID.
|
||||
func GetIssueLabels(issueID int64) ([]*IssueLabel, error) {
|
||||
return getIssueLabels(x, issueID)
|
||||
}
|
||||
|
||||
func deleteIssueLabel(e *xorm.Session, issue *Issue, label *Label) (err error) {
|
||||
if _, err = e.Delete(&IssueLabel{
|
||||
IssueID: issue.ID,
|
||||
LabelID: label.ID,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
label.NumIssues--
|
||||
if issue.IsClosed {
|
||||
label.NumClosedIssues--
|
||||
}
|
||||
return updateLabel(e, label)
|
||||
}
|
||||
|
||||
// DeleteIssueLabel deletes issue-label relation.
|
||||
func DeleteIssueLabel(issue *Issue, label *Label) (err error) {
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = deleteIssueLabel(sess, issue, label); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
// _____ .__.__ __
|
||||
// / \ |__| | ____ _______/ |_ ____ ____ ____
|
||||
// / \ / \| | | _/ __ \ / ___/\ __\/ _ \ / \_/ __ \
|
||||
@@ -1451,270 +1244,6 @@ func DeleteMilestoneByID(id int64) error {
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
// _________ __
|
||||
// \_ ___ \ ____ _____ _____ ____ _____/ |_
|
||||
// / \ \/ / _ \ / \ / \_/ __ \ / \ __\
|
||||
// \ \___( <_> ) Y Y \ Y Y \ ___/| | \ |
|
||||
// \______ /\____/|__|_| /__|_| /\___ >___| /__|
|
||||
// \/ \/ \/ \/ \/
|
||||
|
||||
// CommentType defines whether a comment is just a simple comment, an action (like close) or a reference.
|
||||
type CommentType int
|
||||
|
||||
const (
|
||||
// Plain comment, can be associated with a commit (CommitId > 0) and a line (Line > 0)
|
||||
COMMENT_TYPE_COMMENT CommentType = iota
|
||||
COMMENT_TYPE_REOPEN
|
||||
COMMENT_TYPE_CLOSE
|
||||
|
||||
// References.
|
||||
COMMENT_TYPE_ISSUE_REF
|
||||
// Reference from a commit (not part of a pull request)
|
||||
COMMENT_TYPE_COMMIT_REF
|
||||
// Reference from a comment
|
||||
COMMENT_TYPE_COMMENT_REF
|
||||
// Reference from a pull request
|
||||
COMMENT_TYPE_PULL_REF
|
||||
)
|
||||
|
||||
type CommentTag int
|
||||
|
||||
const (
|
||||
COMMENT_TAG_NONE CommentTag = iota
|
||||
COMMENT_TAG_POSTER
|
||||
COMMENT_TAG_ADMIN
|
||||
COMMENT_TAG_OWNER
|
||||
)
|
||||
|
||||
// Comment represents a comment in commit and issue page.
|
||||
type Comment struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
Type CommentType
|
||||
PosterID int64
|
||||
Poster *User `xorm:"-"`
|
||||
IssueID int64 `xorm:"INDEX"`
|
||||
CommitID int64
|
||||
Line int64
|
||||
Content string `xorm:"TEXT"`
|
||||
RenderedContent string `xorm:"-"`
|
||||
Created time.Time `xorm:"CREATED"`
|
||||
|
||||
// Reference issue in commit message
|
||||
CommitSHA string `xorm:"VARCHAR(40)"`
|
||||
|
||||
Attachments []*Attachment `xorm:"-"`
|
||||
|
||||
// For view issue page.
|
||||
ShowTag CommentTag `xorm:"-"`
|
||||
}
|
||||
|
||||
func (c *Comment) AfterSet(colName string, _ xorm.Cell) {
|
||||
var err error
|
||||
switch colName {
|
||||
case "id":
|
||||
c.Attachments, err = GetAttachmentsByCommentID(c.ID)
|
||||
if err != nil {
|
||||
log.Error(3, "GetAttachmentsByCommentID[%d]: %v", c.ID, err)
|
||||
}
|
||||
|
||||
case "poster_id":
|
||||
c.Poster, err = GetUserByID(c.PosterID)
|
||||
if err != nil {
|
||||
if IsErrUserNotExist(err) {
|
||||
c.PosterID = -1
|
||||
c.Poster = NewFakeUser()
|
||||
} else {
|
||||
log.Error(3, "GetUserByID[%d]: %v", c.ID, err)
|
||||
}
|
||||
}
|
||||
case "created":
|
||||
c.Created = regulateTimeZone(c.Created)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Comment) AfterDelete() {
|
||||
_, err := DeleteAttachmentsByComment(c.ID, true)
|
||||
|
||||
if err != nil {
|
||||
log.Info("Could not delete files for comment %d on issue #%d: %s", c.ID, c.IssueID, err)
|
||||
}
|
||||
}
|
||||
|
||||
// HashTag returns unique hash tag for comment.
|
||||
func (c *Comment) HashTag() string {
|
||||
return "issuecomment-" + com.ToStr(c.ID)
|
||||
}
|
||||
|
||||
// EventTag returns unique event hash tag for comment.
|
||||
func (c *Comment) EventTag() string {
|
||||
return "event-" + com.ToStr(c.ID)
|
||||
}
|
||||
|
||||
func createComment(e *xorm.Session, u *User, repo *Repository, issue *Issue, commitID, line int64, cmtType CommentType, content, commitSHA string, uuids []string) (_ *Comment, err error) {
|
||||
comment := &Comment{
|
||||
PosterID: u.Id,
|
||||
Type: cmtType,
|
||||
IssueID: issue.ID,
|
||||
CommitID: commitID,
|
||||
Line: line,
|
||||
Content: content,
|
||||
CommitSHA: commitSHA,
|
||||
}
|
||||
if _, err = e.Insert(comment); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Compose comment action, could be plain comment, close or reopen issue.
|
||||
// This object will be used to notify watchers in the end of function.
|
||||
act := &Action{
|
||||
ActUserID: u.Id,
|
||||
ActUserName: u.Name,
|
||||
ActEmail: u.Email,
|
||||
Content: fmt.Sprintf("%d|%s", issue.Index, strings.Split(content, "\n")[0]),
|
||||
RepoID: repo.ID,
|
||||
RepoUserName: repo.Owner.Name,
|
||||
RepoName: repo.Name,
|
||||
IsPrivate: repo.IsPrivate,
|
||||
}
|
||||
|
||||
// Check comment type.
|
||||
switch cmtType {
|
||||
case COMMENT_TYPE_COMMENT:
|
||||
act.OpType = ACTION_COMMENT_ISSUE
|
||||
|
||||
if _, err = e.Exec("UPDATE `issue` SET num_comments=num_comments+1 WHERE id=?", issue.ID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Check attachments.
|
||||
attachments := make([]*Attachment, 0, len(uuids))
|
||||
for _, uuid := range uuids {
|
||||
attach, err := getAttachmentByUUID(e, uuid)
|
||||
if err != nil {
|
||||
if IsErrAttachmentNotExist(err) {
|
||||
continue
|
||||
}
|
||||
return nil, fmt.Errorf("getAttachmentByUUID[%s]: %v", uuid, err)
|
||||
}
|
||||
attachments = append(attachments, attach)
|
||||
}
|
||||
|
||||
for i := range attachments {
|
||||
attachments[i].IssueID = issue.ID
|
||||
attachments[i].CommentID = comment.ID
|
||||
// No assign value could be 0, so ignore AllCols().
|
||||
if _, err = e.Id(attachments[i].ID).Update(attachments[i]); err != nil {
|
||||
return nil, fmt.Errorf("update attachment[%d]: %v", attachments[i].ID, err)
|
||||
}
|
||||
}
|
||||
|
||||
case COMMENT_TYPE_REOPEN:
|
||||
act.OpType = ACTION_REOPEN_ISSUE
|
||||
|
||||
if issue.IsPull {
|
||||
_, err = e.Exec("UPDATE `repository` SET num_closed_pulls=num_closed_pulls-1 WHERE id=?", repo.ID)
|
||||
} else {
|
||||
_, err = e.Exec("UPDATE `repository` SET num_closed_issues=num_closed_issues-1 WHERE id=?", repo.ID)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case COMMENT_TYPE_CLOSE:
|
||||
act.OpType = ACTION_CLOSE_ISSUE
|
||||
|
||||
if issue.IsPull {
|
||||
_, err = e.Exec("UPDATE `repository` SET num_closed_pulls=num_closed_pulls+1 WHERE id=?", repo.ID)
|
||||
} else {
|
||||
_, err = e.Exec("UPDATE `repository` SET num_closed_issues=num_closed_issues+1 WHERE id=?", repo.ID)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Notify watchers for whatever action comes in.
|
||||
if err = notifyWatchers(e, act); err != nil {
|
||||
return nil, fmt.Errorf("notifyWatchers: %v", err)
|
||||
}
|
||||
|
||||
return comment, nil
|
||||
}
|
||||
|
||||
func createStatusComment(e *xorm.Session, doer *User, repo *Repository, issue *Issue) (*Comment, error) {
|
||||
cmtType := COMMENT_TYPE_CLOSE
|
||||
if !issue.IsClosed {
|
||||
cmtType = COMMENT_TYPE_REOPEN
|
||||
}
|
||||
return createComment(e, doer, repo, issue, 0, 0, cmtType, "", "", nil)
|
||||
}
|
||||
|
||||
// CreateComment creates comment of issue or commit.
|
||||
func CreateComment(doer *User, repo *Repository, issue *Issue, commitID, line int64, cmtType CommentType, content, commitSHA string, attachments []string) (comment *Comment, err error) {
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
if err = sess.Begin(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
comment, err = createComment(sess, doer, repo, issue, commitID, line, cmtType, content, commitSHA, attachments)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return comment, sess.Commit()
|
||||
}
|
||||
|
||||
// CreateIssueComment creates a plain issue comment.
|
||||
func CreateIssueComment(doer *User, repo *Repository, issue *Issue, content string, attachments []string) (*Comment, error) {
|
||||
return CreateComment(doer, repo, issue, 0, 0, COMMENT_TYPE_COMMENT, content, "", attachments)
|
||||
}
|
||||
|
||||
// CreateRefComment creates a commit reference comment to issue.
|
||||
func CreateRefComment(doer *User, repo *Repository, issue *Issue, content, commitSHA string) error {
|
||||
if len(commitSHA) == 0 {
|
||||
return fmt.Errorf("cannot create reference with empty commit SHA")
|
||||
}
|
||||
|
||||
// Check if same reference from same commit has already existed.
|
||||
has, err := x.Get(&Comment{
|
||||
Type: COMMENT_TYPE_COMMIT_REF,
|
||||
IssueID: issue.ID,
|
||||
CommitSHA: commitSHA,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("check reference comment: %v", err)
|
||||
} else if has {
|
||||
return nil
|
||||
}
|
||||
|
||||
_, err = CreateComment(doer, repo, issue, 0, 0, COMMENT_TYPE_COMMIT_REF, content, commitSHA, nil)
|
||||
return err
|
||||
}
|
||||
|
||||
// GetCommentByID returns the comment by given ID.
|
||||
func GetCommentByID(id int64) (*Comment, error) {
|
||||
c := new(Comment)
|
||||
has, err := x.Id(id).Get(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if !has {
|
||||
return nil, ErrCommentNotExist{id}
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// GetCommentsByIssueID returns all comments of issue by given ID.
|
||||
func GetCommentsByIssueID(issueID int64) ([]*Comment, error) {
|
||||
comments := make([]*Comment, 0, 10)
|
||||
return comments, x.Where("issue_id=?", issueID).Asc("created").Find(&comments)
|
||||
}
|
||||
|
||||
// UpdateComment updates information of comment.
|
||||
func UpdateComment(c *Comment) error {
|
||||
_, err := x.Id(c.ID).AllCols().Update(c)
|
||||
return err
|
||||
}
|
||||
|
||||
// Attachment represent a attachment of issue/comment/release.
|
||||
type Attachment struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
|
||||
312
models/issue_comment.go
Normal file
312
models/issue_comment.go
Normal file
@@ -0,0 +1,312 @@
|
||||
// Copyright 2016 The Gogs 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 models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Unknwon/com"
|
||||
"github.com/go-xorm/xorm"
|
||||
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
)
|
||||
|
||||
// CommentType defines whether a comment is just a simple comment, an action (like close) or a reference.
|
||||
type CommentType int
|
||||
|
||||
const (
|
||||
// Plain comment, can be associated with a commit (CommitID > 0) and a line (LineNum > 0)
|
||||
COMMENT_TYPE_COMMENT CommentType = iota
|
||||
COMMENT_TYPE_REOPEN
|
||||
COMMENT_TYPE_CLOSE
|
||||
|
||||
// References.
|
||||
COMMENT_TYPE_ISSUE_REF
|
||||
// Reference from a commit (not part of a pull request)
|
||||
COMMENT_TYPE_COMMIT_REF
|
||||
// Reference from a comment
|
||||
COMMENT_TYPE_COMMENT_REF
|
||||
// Reference from a pull request
|
||||
COMMENT_TYPE_PULL_REF
|
||||
)
|
||||
|
||||
type CommentTag int
|
||||
|
||||
const (
|
||||
COMMENT_TAG_NONE CommentTag = iota
|
||||
COMMENT_TAG_POSTER
|
||||
COMMENT_TAG_WRITER
|
||||
COMMENT_TAG_OWNER
|
||||
)
|
||||
|
||||
// Comment represents a comment in commit and issue page.
|
||||
type Comment struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
Type CommentType
|
||||
PosterID int64
|
||||
Poster *User `xorm:"-"`
|
||||
IssueID int64 `xorm:"INDEX"`
|
||||
CommitID int64
|
||||
Line int64
|
||||
Content string `xorm:"TEXT"`
|
||||
RenderedContent string `xorm:"-"`
|
||||
Created time.Time `xorm:"CREATED"`
|
||||
|
||||
// Reference issue in commit message
|
||||
CommitSHA string `xorm:"VARCHAR(40)"`
|
||||
|
||||
Attachments []*Attachment `xorm:"-"`
|
||||
|
||||
// For view issue page.
|
||||
ShowTag CommentTag `xorm:"-"`
|
||||
}
|
||||
|
||||
func (c *Comment) AfterSet(colName string, _ xorm.Cell) {
|
||||
var err error
|
||||
switch colName {
|
||||
case "id":
|
||||
c.Attachments, err = GetAttachmentsByCommentID(c.ID)
|
||||
if err != nil {
|
||||
log.Error(3, "GetAttachmentsByCommentID[%d]: %v", c.ID, err)
|
||||
}
|
||||
|
||||
case "poster_id":
|
||||
c.Poster, err = GetUserByID(c.PosterID)
|
||||
if err != nil {
|
||||
if IsErrUserNotExist(err) {
|
||||
c.PosterID = -1
|
||||
c.Poster = NewFakeUser()
|
||||
} else {
|
||||
log.Error(3, "GetUserByID[%d]: %v", c.ID, err)
|
||||
}
|
||||
}
|
||||
case "created":
|
||||
c.Created = regulateTimeZone(c.Created)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Comment) AfterDelete() {
|
||||
_, err := DeleteAttachmentsByComment(c.ID, true)
|
||||
|
||||
if err != nil {
|
||||
log.Info("Could not delete files for comment %d on issue #%d: %s", c.ID, c.IssueID, err)
|
||||
}
|
||||
}
|
||||
|
||||
// HashTag returns unique hash tag for comment.
|
||||
func (c *Comment) HashTag() string {
|
||||
return "issuecomment-" + com.ToStr(c.ID)
|
||||
}
|
||||
|
||||
// EventTag returns unique event hash tag for comment.
|
||||
func (c *Comment) EventTag() string {
|
||||
return "event-" + com.ToStr(c.ID)
|
||||
}
|
||||
|
||||
func createComment(e *xorm.Session, opts *CreateCommentOptions) (_ *Comment, err error) {
|
||||
comment := &Comment{
|
||||
Type: opts.Type,
|
||||
PosterID: opts.Doer.Id,
|
||||
IssueID: opts.Issue.ID,
|
||||
CommitID: opts.CommitID,
|
||||
CommitSHA: opts.CommitSHA,
|
||||
Line: opts.LineNum,
|
||||
Content: opts.Content,
|
||||
}
|
||||
if _, err = e.Insert(comment); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Compose comment action, could be plain comment, close or reopen issue/pull request.
|
||||
// This object will be used to notify watchers in the end of function.
|
||||
act := &Action{
|
||||
ActUserID: opts.Doer.Id,
|
||||
ActUserName: opts.Doer.Name,
|
||||
ActEmail: opts.Doer.Email,
|
||||
Content: fmt.Sprintf("%d|%s", opts.Issue.Index, strings.Split(opts.Content, "\n")[0]),
|
||||
RepoID: opts.Repo.ID,
|
||||
RepoUserName: opts.Repo.Owner.Name,
|
||||
RepoName: opts.Repo.Name,
|
||||
IsPrivate: opts.Repo.IsPrivate,
|
||||
}
|
||||
|
||||
// Check comment type.
|
||||
switch opts.Type {
|
||||
case COMMENT_TYPE_COMMENT:
|
||||
act.OpType = ACTION_COMMENT_ISSUE
|
||||
|
||||
if _, err = e.Exec("UPDATE `issue` SET num_comments=num_comments+1 WHERE id=?", opts.Issue.ID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Check attachments
|
||||
attachments := make([]*Attachment, 0, len(opts.Attachments))
|
||||
for _, uuid := range opts.Attachments {
|
||||
attach, err := getAttachmentByUUID(e, uuid)
|
||||
if err != nil {
|
||||
if IsErrAttachmentNotExist(err) {
|
||||
continue
|
||||
}
|
||||
return nil, fmt.Errorf("getAttachmentByUUID[%s]: %v", uuid, err)
|
||||
}
|
||||
attachments = append(attachments, attach)
|
||||
}
|
||||
|
||||
for i := range attachments {
|
||||
attachments[i].IssueID = opts.Issue.ID
|
||||
attachments[i].CommentID = comment.ID
|
||||
// No assign value could be 0, so ignore AllCols().
|
||||
if _, err = e.Id(attachments[i].ID).Update(attachments[i]); err != nil {
|
||||
return nil, fmt.Errorf("update attachment[%d]: %v", attachments[i].ID, err)
|
||||
}
|
||||
}
|
||||
|
||||
case COMMENT_TYPE_REOPEN:
|
||||
act.OpType = ACTION_REOPEN_ISSUE
|
||||
if opts.Issue.IsPull {
|
||||
act.OpType = ACTION_REOPEN_PULL_REQUEST
|
||||
}
|
||||
|
||||
if opts.Issue.IsPull {
|
||||
_, err = e.Exec("UPDATE `repository` SET num_closed_pulls=num_closed_pulls-1 WHERE id=?", opts.Repo.ID)
|
||||
} else {
|
||||
_, err = e.Exec("UPDATE `repository` SET num_closed_issues=num_closed_issues-1 WHERE id=?", opts.Repo.ID)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
case COMMENT_TYPE_CLOSE:
|
||||
act.OpType = ACTION_CLOSE_ISSUE
|
||||
if opts.Issue.IsPull {
|
||||
act.OpType = ACTION_CLOSE_PULL_REQUEST
|
||||
}
|
||||
|
||||
if opts.Issue.IsPull {
|
||||
_, err = e.Exec("UPDATE `repository` SET num_closed_pulls=num_closed_pulls+1 WHERE id=?", opts.Repo.ID)
|
||||
} else {
|
||||
_, err = e.Exec("UPDATE `repository` SET num_closed_issues=num_closed_issues+1 WHERE id=?", opts.Repo.ID)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Notify watchers for whatever action comes in
|
||||
if err = notifyWatchers(e, act); err != nil {
|
||||
return nil, fmt.Errorf("notifyWatchers: %v", err)
|
||||
}
|
||||
|
||||
return comment, nil
|
||||
}
|
||||
|
||||
func createStatusComment(e *xorm.Session, doer *User, repo *Repository, issue *Issue) (*Comment, error) {
|
||||
cmtType := COMMENT_TYPE_CLOSE
|
||||
if !issue.IsClosed {
|
||||
cmtType = COMMENT_TYPE_REOPEN
|
||||
}
|
||||
return createComment(e, &CreateCommentOptions{
|
||||
Type: cmtType,
|
||||
Doer: doer,
|
||||
Repo: repo,
|
||||
Issue: issue,
|
||||
})
|
||||
}
|
||||
|
||||
type CreateCommentOptions struct {
|
||||
Type CommentType
|
||||
Doer *User
|
||||
Repo *Repository
|
||||
Issue *Issue
|
||||
|
||||
CommitID int64
|
||||
CommitSHA string
|
||||
LineNum int64
|
||||
Content string
|
||||
Attachments []string // UUIDs of attachments
|
||||
}
|
||||
|
||||
// CreateComment creates comment of issue or commit.
|
||||
func CreateComment(opts *CreateCommentOptions) (comment *Comment, err error) {
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
if err = sess.Begin(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
comment, err = createComment(sess, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return comment, sess.Commit()
|
||||
}
|
||||
|
||||
// CreateIssueComment creates a plain issue comment.
|
||||
func CreateIssueComment(doer *User, repo *Repository, issue *Issue, content string, attachments []string) (*Comment, error) {
|
||||
return CreateComment(&CreateCommentOptions{
|
||||
Type: COMMENT_TYPE_COMMENT,
|
||||
Doer: doer,
|
||||
Repo: repo,
|
||||
Issue: issue,
|
||||
Content: content,
|
||||
Attachments: attachments,
|
||||
})
|
||||
}
|
||||
|
||||
// CreateRefComment creates a commit reference comment to issue.
|
||||
func CreateRefComment(doer *User, repo *Repository, issue *Issue, content, commitSHA string) error {
|
||||
if len(commitSHA) == 0 {
|
||||
return fmt.Errorf("cannot create reference with empty commit SHA")
|
||||
}
|
||||
|
||||
// Check if same reference from same commit has already existed.
|
||||
has, err := x.Get(&Comment{
|
||||
Type: COMMENT_TYPE_COMMIT_REF,
|
||||
IssueID: issue.ID,
|
||||
CommitSHA: commitSHA,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("check reference comment: %v", err)
|
||||
} else if has {
|
||||
return nil
|
||||
}
|
||||
|
||||
_, err = CreateComment(&CreateCommentOptions{
|
||||
Type: COMMENT_TYPE_COMMIT_REF,
|
||||
Doer: doer,
|
||||
Repo: repo,
|
||||
Issue: issue,
|
||||
CommitSHA: commitSHA,
|
||||
Content: content,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
// GetCommentByID returns the comment by given ID.
|
||||
func GetCommentByID(id int64) (*Comment, error) {
|
||||
c := new(Comment)
|
||||
has, err := x.Id(id).Get(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if !has {
|
||||
return nil, ErrCommentNotExist{id}
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// GetCommentsByIssueID returns all comments of issue by given ID.
|
||||
func GetCommentsByIssueID(issueID int64) ([]*Comment, error) {
|
||||
comments := make([]*Comment, 0, 10)
|
||||
return comments, x.Where("issue_id=?", issueID).Asc("created").Find(&comments)
|
||||
}
|
||||
|
||||
// UpdateComment updates information of comment.
|
||||
func UpdateComment(c *Comment) error {
|
||||
_, err := x.Id(c.ID).AllCols().Update(c)
|
||||
return err
|
||||
}
|
||||
234
models/issue_label.go
Normal file
234
models/issue_label.go
Normal file
@@ -0,0 +1,234 @@
|
||||
// Copyright 2016 The Gogs 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 models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"html/template"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/go-xorm/xorm"
|
||||
)
|
||||
|
||||
// Label represents a label of repository for issues.
|
||||
type Label struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
RepoID int64 `xorm:"INDEX"`
|
||||
Name string
|
||||
Color string `xorm:"VARCHAR(7)"`
|
||||
NumIssues int
|
||||
NumClosedIssues int
|
||||
NumOpenIssues int `xorm:"-"`
|
||||
IsChecked bool `xorm:"-"`
|
||||
}
|
||||
|
||||
// CalOpenIssues calculates the open issues of label.
|
||||
func (m *Label) CalOpenIssues() {
|
||||
m.NumOpenIssues = m.NumIssues - m.NumClosedIssues
|
||||
}
|
||||
|
||||
// ForegroundColor calculates the text color for labels based
|
||||
// on their background color.
|
||||
func (l *Label) ForegroundColor() template.CSS {
|
||||
if strings.HasPrefix(l.Color, "#") {
|
||||
if color, err := strconv.ParseUint(l.Color[1:], 16, 64); err == nil {
|
||||
r := float32(0xFF & (color >> 16))
|
||||
g := float32(0xFF & (color >> 8))
|
||||
b := float32(0xFF & color)
|
||||
luminance := (0.2126*r + 0.7152*g + 0.0722*b) / 255
|
||||
|
||||
if luminance < 0.5 {
|
||||
return template.CSS("#fff")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// default to black
|
||||
return template.CSS("#000")
|
||||
}
|
||||
|
||||
// NewLabel creates new label of repository.
|
||||
func NewLabel(l *Label) error {
|
||||
_, err := x.Insert(l)
|
||||
return err
|
||||
}
|
||||
|
||||
func getLabelByID(e Engine, id int64) (*Label, error) {
|
||||
if id <= 0 {
|
||||
return nil, ErrLabelNotExist{id}
|
||||
}
|
||||
|
||||
l := &Label{ID: id}
|
||||
has, err := x.Get(l)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if !has {
|
||||
return nil, ErrLabelNotExist{l.ID}
|
||||
}
|
||||
return l, nil
|
||||
}
|
||||
|
||||
// GetLabelByID returns a label by given ID.
|
||||
func GetLabelByID(id int64) (*Label, error) {
|
||||
return getLabelByID(x, id)
|
||||
}
|
||||
|
||||
// GetLabelsByRepoID returns all labels that belong to given repository by ID.
|
||||
func GetLabelsByRepoID(repoID int64) ([]*Label, error) {
|
||||
labels := make([]*Label, 0, 10)
|
||||
return labels, x.Where("repo_id=?", repoID).Find(&labels)
|
||||
}
|
||||
|
||||
func getLabelsByIssueID(e Engine, issueID int64) ([]*Label, error) {
|
||||
issueLabels, err := getIssueLabels(e, issueID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("getIssueLabels: %v", err)
|
||||
}
|
||||
|
||||
var label *Label
|
||||
labels := make([]*Label, 0, len(issueLabels))
|
||||
for idx := range issueLabels {
|
||||
label, err = getLabelByID(e, issueLabels[idx].LabelID)
|
||||
if err != nil && !IsErrLabelNotExist(err) {
|
||||
return nil, fmt.Errorf("getLabelByID: %v", err)
|
||||
}
|
||||
labels = append(labels, label)
|
||||
}
|
||||
return labels, nil
|
||||
}
|
||||
|
||||
// GetLabelsByIssueID returns all labels that belong to given issue by ID.
|
||||
func GetLabelsByIssueID(issueID int64) ([]*Label, error) {
|
||||
return getLabelsByIssueID(x, issueID)
|
||||
}
|
||||
|
||||
func updateLabel(e Engine, l *Label) error {
|
||||
_, err := e.Id(l.ID).AllCols().Update(l)
|
||||
return err
|
||||
}
|
||||
|
||||
// UpdateLabel updates label information.
|
||||
func UpdateLabel(l *Label) error {
|
||||
return updateLabel(x, l)
|
||||
}
|
||||
|
||||
// DeleteLabel delete a label of given repository.
|
||||
func DeleteLabel(repoID, labelID int64) error {
|
||||
l, err := GetLabelByID(labelID)
|
||||
if err != nil {
|
||||
if IsErrLabelNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err = x.Where("label_id=?", labelID).Delete(new(IssueLabel)); err != nil {
|
||||
return err
|
||||
} else if _, err = sess.Delete(l); err != nil {
|
||||
return err
|
||||
}
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
// .___ .____ ___. .__
|
||||
// | | ______ ________ __ ____ | | _____ \_ |__ ____ | |
|
||||
// | |/ ___// ___/ | \_/ __ \| | \__ \ | __ \_/ __ \| |
|
||||
// | |\___ \ \___ \| | /\ ___/| |___ / __ \| \_\ \ ___/| |__
|
||||
// |___/____ >____ >____/ \___ >_______ (____ /___ /\___ >____/
|
||||
// \/ \/ \/ \/ \/ \/ \/
|
||||
|
||||
// IssueLabel represetns an issue-lable relation.
|
||||
type IssueLabel struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
IssueID int64 `xorm:"UNIQUE(s)"`
|
||||
LabelID int64 `xorm:"UNIQUE(s)"`
|
||||
}
|
||||
|
||||
func hasIssueLabel(e Engine, issueID, labelID int64) bool {
|
||||
has, _ := e.Where("issue_id=? AND label_id=?", issueID, labelID).Get(new(IssueLabel))
|
||||
return has
|
||||
}
|
||||
|
||||
// HasIssueLabel returns true if issue has been labeled.
|
||||
func HasIssueLabel(issueID, labelID int64) bool {
|
||||
return hasIssueLabel(x, issueID, labelID)
|
||||
}
|
||||
|
||||
func newIssueLabel(e *xorm.Session, issue *Issue, label *Label) (err error) {
|
||||
if _, err = e.Insert(&IssueLabel{
|
||||
IssueID: issue.ID,
|
||||
LabelID: label.ID,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
label.NumIssues++
|
||||
if issue.IsClosed {
|
||||
label.NumClosedIssues++
|
||||
}
|
||||
return updateLabel(e, label)
|
||||
}
|
||||
|
||||
// NewIssueLabel creates a new issue-label relation.
|
||||
func NewIssueLabel(issue *Issue, label *Label) (err error) {
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = newIssueLabel(sess, issue, label); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
func getIssueLabels(e Engine, issueID int64) ([]*IssueLabel, error) {
|
||||
issueLabels := make([]*IssueLabel, 0, 10)
|
||||
return issueLabels, e.Where("issue_id=?", issueID).Asc("label_id").Find(&issueLabels)
|
||||
}
|
||||
|
||||
// GetIssueLabels returns all issue-label relations of given issue by ID.
|
||||
func GetIssueLabels(issueID int64) ([]*IssueLabel, error) {
|
||||
return getIssueLabels(x, issueID)
|
||||
}
|
||||
|
||||
func deleteIssueLabel(e *xorm.Session, issue *Issue, label *Label) (err error) {
|
||||
if _, err = e.Delete(&IssueLabel{
|
||||
IssueID: issue.ID,
|
||||
LabelID: label.ID,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
label.NumIssues--
|
||||
if issue.IsClosed {
|
||||
label.NumClosedIssues--
|
||||
}
|
||||
return updateLabel(e, label)
|
||||
}
|
||||
|
||||
// DeleteIssueLabel deletes issue-label relation.
|
||||
func DeleteIssueLabel(issue *Issue, label *Label) (err error) {
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = deleteIssueLabel(sess, issue, label); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
}
|
||||
@@ -1054,13 +1054,11 @@ func RemoveOrgRepo(orgID, repoID int64) error {
|
||||
// GetUserRepositories gets all repositories of an organization,
|
||||
// that the user with the given userID has access to.
|
||||
func (org *User) GetUserRepositories(userID int64) (err error) {
|
||||
teams := make([]*Team, 0, 10)
|
||||
if err = x.Cols("`team`.id").
|
||||
Where("`team_user`.org_id=?", org.Id).
|
||||
And("`team_user`.uid=?", userID).
|
||||
Join("INNER", "`team_user`", "`team_user`.team_id=`team`.id").
|
||||
Find(&teams); err != nil {
|
||||
return fmt.Errorf("GetUserRepositories: get teams: %v", err)
|
||||
teams := make([]*Team, 0, org.NumTeams)
|
||||
if err = x.Sql(`SELECT team.id FROM team
|
||||
INNER JOIN team_user ON team_user.team_id = team.id
|
||||
WHERE team_user.org_id = ? AND team_user.uid = ?`, org.Id, userID).Find(&teams); err != nil {
|
||||
return fmt.Errorf("get teams: %v", err)
|
||||
}
|
||||
|
||||
teamIDs := make([]string, len(teams))
|
||||
@@ -1072,19 +1070,15 @@ func (org *User) GetUserRepositories(userID int64) (err error) {
|
||||
teamIDs = append(teamIDs, "-1") // there is no repo with id=-1
|
||||
}
|
||||
|
||||
// Due to a bug in xorm using IN() together with OR() is impossible.
|
||||
// As a workaround, we have to build the IN statement on our own, until this is fixed.
|
||||
// https://github.com/go-xorm/xorm/issues/342
|
||||
|
||||
if err = x.Cols("`repository`.*").
|
||||
Join("INNER", "`team_repo`", "`team_repo`.repo_id=`repository`.id").
|
||||
Where("`repository`.owner_id=?", org.Id).
|
||||
And("`repository`.is_private=?", false).
|
||||
Or("`team_repo`.team_id=(?)", strings.Join(teamIDs, ",")).
|
||||
GroupBy("`repository`.id").
|
||||
Find(&org.Repos); err != nil {
|
||||
return fmt.Errorf("GetUserRepositories: get repositories: %v", err)
|
||||
repos := make([]*Repository, 0, 5)
|
||||
if err = x.Sql(`SELECT repository.* FROM repository
|
||||
INNER JOIN team_repo ON team_repo.repo_id = repository.id
|
||||
WHERE (repository.owner_id = ? AND repository.is_private = ?) OR team_repo.team_id IN (?)
|
||||
GROUP BY repository.id`,
|
||||
org.Id, false, strings.Join(teamIDs, ",")).Find(&repos); err != nil {
|
||||
return fmt.Errorf("get repositories: %v", err)
|
||||
}
|
||||
org.Repos = repos
|
||||
|
||||
// FIXME: should I change this value inside method,
|
||||
// or only in location of caller where it's really needed?
|
||||
@@ -1095,12 +1089,12 @@ func (org *User) GetUserRepositories(userID int64) (err error) {
|
||||
// GetTeams returns all teams that belong to organization,
|
||||
// and that the user has joined.
|
||||
func (org *User) GetUserTeams(userID int64) error {
|
||||
if err := x.Cols("`team`.*").
|
||||
Where("`team_user`.org_id=?", org.Id).
|
||||
And("`team_user`.uid=?", userID).
|
||||
Join("INNER", "`team_user`", "`team_user`.team_id=`team`.id").
|
||||
Find(&org.Teams); err != nil {
|
||||
return fmt.Errorf("GetUserTeams: %v", err)
|
||||
teams := make([]*Team, 0, 5)
|
||||
if err := x.Sql(`SELECT team.* FROM team
|
||||
INNER JOIN team_user ON team_user.team_id = team.id
|
||||
WHERE team_user.org_id = ? AND team_user.uid = ?`,
|
||||
org.Id, userID).Find(&teams); err != nil {
|
||||
return fmt.Errorf("get teams: %v", err)
|
||||
}
|
||||
|
||||
// FIXME: should I change this value inside method,
|
||||
|
||||
@@ -138,7 +138,7 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository) (err error
|
||||
return err
|
||||
}
|
||||
|
||||
if err = pr.Issue.changeStatus(sess, doer, true); err != nil {
|
||||
if err = pr.Issue.changeStatus(sess, doer, pr.Issue.Repo, true); err != nil {
|
||||
return fmt.Errorf("Issue.changeStatus: %v", err)
|
||||
}
|
||||
|
||||
@@ -484,10 +484,9 @@ func (pr *PullRequest) UpdatePatch() (err error) {
|
||||
|
||||
// PushToBaseRepo pushes commits from branches of head repository to
|
||||
// corresponding branches of base repository.
|
||||
// FIXME: could fail after user force push head repo, should we always force push here?
|
||||
// FIXME: Only push branches that are actually updates?
|
||||
func (pr *PullRequest) PushToBaseRepo() (err error) {
|
||||
log.Trace("PushToBaseRepo[%[1]d]: pushing commits to base repo 'refs/pull/%[1]d/head'", pr.ID)
|
||||
log.Trace("PushToBaseRepo[%d]: pushing commits to base repo 'refs/pull/%d/head'", pr.BaseRepoID, pr.Index)
|
||||
|
||||
headRepoPath := pr.HeadRepo.RepoPath()
|
||||
headGitRepo, err := git.OpenRepository(headRepoPath)
|
||||
@@ -502,7 +501,12 @@ func (pr *PullRequest) PushToBaseRepo() (err error) {
|
||||
// Make sure to remove the remote even if the push fails
|
||||
defer headGitRepo.RemoveRemote(tmpRemoteName)
|
||||
|
||||
if err = git.Push(headRepoPath, tmpRemoteName, fmt.Sprintf("%s:refs/pull/%d/head", pr.HeadBranch, pr.Index)); err != nil {
|
||||
headFile := fmt.Sprintf("refs/pull/%d/head", pr.Index)
|
||||
|
||||
// Remove head in case there is a conflict.
|
||||
os.Remove(path.Join(pr.BaseRepo.RepoPath(), headFile))
|
||||
|
||||
if err = git.Push(headRepoPath, tmpRemoteName, fmt.Sprintf("%s:%s", pr.HeadBranch, headFile)); err != nil {
|
||||
return fmt.Errorf("Push: %v", err)
|
||||
}
|
||||
|
||||
|
||||
193
models/repo.go
193
models/repo.go
@@ -27,7 +27,7 @@ import (
|
||||
"github.com/mcuadros/go-version"
|
||||
"gopkg.in/ini.v1"
|
||||
|
||||
"github.com/gogits/git-module"
|
||||
git "github.com/gogits/git-module"
|
||||
api "github.com/gogits/go-gogs-client"
|
||||
|
||||
"github.com/gogits/gogs/modules/bindata"
|
||||
@@ -184,6 +184,11 @@ type Repository struct {
|
||||
|
||||
func (repo *Repository) AfterSet(colName string, _ xorm.Cell) {
|
||||
switch colName {
|
||||
case "default_branch":
|
||||
// FIXME: use models migration to solve all at once.
|
||||
if len(repo.DefaultBranch) == 0 {
|
||||
repo.DefaultBranch = "master"
|
||||
}
|
||||
case "num_closed_issues":
|
||||
repo.NumOpenIssues = repo.NumIssues - repo.NumClosedIssues
|
||||
case "num_closed_pulls":
|
||||
@@ -241,6 +246,14 @@ func (repo *Repository) ComposeMetas() map[string]string {
|
||||
return repo.ExternalMetas
|
||||
}
|
||||
|
||||
// DeleteWiki removes the actual and local copy of repository wiki.
|
||||
func (repo *Repository) DeleteWiki() {
|
||||
wikiPaths := []string{repo.WikiPath(), repo.LocalWikiPath()}
|
||||
for _, wikiPath := range wikiPaths {
|
||||
RemoveAllWithNotice("Delete repository wiki", wikiPath)
|
||||
}
|
||||
}
|
||||
|
||||
// GetAssignees returns all users that have write access of repository.
|
||||
func (repo *Repository) GetAssignees() (_ []*User, err error) {
|
||||
if err = repo.GetOwner(); err != nil {
|
||||
@@ -313,6 +326,10 @@ func (repo *Repository) RepoLink() string {
|
||||
return setting.AppSubUrl + "/" + repo.MustOwner().Name + "/" + repo.Name
|
||||
}
|
||||
|
||||
func (repo *Repository) RepoRelLink() string {
|
||||
return "/" + repo.MustOwner().Name + "/" + repo.Name
|
||||
}
|
||||
|
||||
func (repo *Repository) ComposeCompareURL(oldCommitID, newCommitID string) string {
|
||||
return fmt.Sprintf("%s/%s/compare/%s...%s", repo.MustOwner().Name, repo.Name, oldCommitID, newCommitID)
|
||||
}
|
||||
@@ -367,11 +384,16 @@ func (repo *Repository) LocalCopyPath() string {
|
||||
|
||||
func updateLocalCopy(repoPath, localPath string) error {
|
||||
if !com.IsExist(localPath) {
|
||||
if err := git.Clone(repoPath, localPath, git.CloneRepoOptions{}); err != nil {
|
||||
if err := git.Clone(repoPath, localPath, git.CloneRepoOptions{
|
||||
Timeout: time.Duration(setting.Git.Timeout.Clone) * time.Second,
|
||||
}); err != nil {
|
||||
return fmt.Errorf("Clone: %v", err)
|
||||
}
|
||||
} else {
|
||||
if err := git.Pull(localPath, true); err != nil {
|
||||
if err := git.Pull(localPath, git.PullRemoteOptions{
|
||||
All: true,
|
||||
Timeout: time.Duration(setting.Git.Timeout.Pull) * time.Second,
|
||||
}); err != nil {
|
||||
return fmt.Errorf("Pull: %v", err)
|
||||
}
|
||||
}
|
||||
@@ -457,10 +479,10 @@ func (repo *Repository) cloneLink(isWiki bool) *CloneLink {
|
||||
|
||||
repo.Owner = repo.MustOwner()
|
||||
cl := new(CloneLink)
|
||||
if setting.SSHPort != 22 {
|
||||
cl.SSH = fmt.Sprintf("ssh://%s@%s:%d/%s/%s.git", setting.RunUser, setting.SSHDomain, setting.SSHPort, repo.Owner.Name, repoName)
|
||||
if setting.SSH.Port != 22 {
|
||||
cl.SSH = fmt.Sprintf("ssh://%s@%s:%d/%s/%s.git", setting.RunUser, setting.SSH.Domain, setting.SSH.Port, repo.Owner.Name, repoName)
|
||||
} else {
|
||||
cl.SSH = fmt.Sprintf("%s@%s:%s/%s.git", setting.RunUser, setting.SSHDomain, repo.Owner.Name, repoName)
|
||||
cl.SSH = fmt.Sprintf("%s@%s:%s/%s.git", setting.RunUser, setting.SSH.Domain, repo.Owner.Name, repoName)
|
||||
}
|
||||
cl.HTTPS = fmt.Sprintf("%s%s/%s.git", setting.AppUrl, repo.Owner.Name, repoName)
|
||||
return cl
|
||||
@@ -652,11 +674,36 @@ func MigrateRepository(u *User, opts MigrateRepoOptions) (*Repository, error) {
|
||||
if err = git.Clone(opts.RemoteAddr, repoPath, git.CloneRepoOptions{
|
||||
Mirror: true,
|
||||
Quiet: true,
|
||||
Timeout: 10 * time.Minute,
|
||||
Timeout: time.Duration(setting.Git.Timeout.Migrate) * time.Second,
|
||||
}); err != nil {
|
||||
return repo, fmt.Errorf("Clone: %v", err)
|
||||
}
|
||||
|
||||
// Check if repository is empty.
|
||||
_, stderr, err := com.ExecCmdDir(repoPath, "git", "log", "-1")
|
||||
if err != nil {
|
||||
if strings.Contains(stderr, "fatal: bad default revision 'HEAD'") {
|
||||
repo.IsBare = true
|
||||
} else {
|
||||
return repo, fmt.Errorf("check bare: %v - %s", err, stderr)
|
||||
}
|
||||
}
|
||||
|
||||
if !repo.IsBare {
|
||||
// Try to get HEAD branch and set it as default branch.
|
||||
gitRepo, err := git.OpenRepository(repoPath)
|
||||
if err != nil {
|
||||
return repo, fmt.Errorf("OpenRepository: %v", err)
|
||||
}
|
||||
headBranch, err := gitRepo.GetHEADBranch()
|
||||
if err != nil {
|
||||
return repo, fmt.Errorf("GetHEADBranch: %v", err)
|
||||
}
|
||||
if headBranch != nil {
|
||||
repo.DefaultBranch = headBranch.Name
|
||||
}
|
||||
}
|
||||
|
||||
if opts.IsMirror {
|
||||
if _, err = x.InsertOne(&Mirror{
|
||||
RepoID: repo.ID,
|
||||
@@ -691,31 +738,6 @@ func CleanUpMigrateInfo(repo *Repository, repoPath string) (*Repository, error)
|
||||
return repo, fmt.Errorf("save config file: %v", err)
|
||||
}
|
||||
|
||||
// Check if repository is empty.
|
||||
_, stderr, err := com.ExecCmdDir(repoPath, "git", "log", "-1")
|
||||
if err != nil {
|
||||
if strings.Contains(stderr, "fatal: bad default revision 'HEAD'") {
|
||||
repo.IsBare = true
|
||||
} else {
|
||||
return repo, fmt.Errorf("check bare: %v - %s", err, stderr)
|
||||
}
|
||||
}
|
||||
|
||||
// Try to get HEAD branch and set it as default branch.
|
||||
gitRepo, err := git.OpenRepository(repoPath)
|
||||
if err != nil {
|
||||
log.Error(4, "OpenRepository: %v", err)
|
||||
return repo, nil
|
||||
}
|
||||
headBranch, err := gitRepo.GetHEADBranch()
|
||||
if err != nil {
|
||||
log.Error(4, "GetHEADBranch: %v", err)
|
||||
return repo, nil
|
||||
}
|
||||
if headBranch != nil {
|
||||
repo.DefaultBranch = headBranch.Name
|
||||
}
|
||||
|
||||
return repo, UpdateRepository(repo, false)
|
||||
}
|
||||
|
||||
@@ -1330,10 +1352,7 @@ func DeleteRepository(uid, repoID int64) error {
|
||||
repoPath := repo.repoPath(sess)
|
||||
RemoveAllWithNotice("Delete repository files", repoPath)
|
||||
|
||||
wikiPaths := []string{repo.WikiPath(), repo.LocalWikiPath()}
|
||||
for _, wikiPath := range wikiPaths {
|
||||
RemoveAllWithNotice("Delete repository wiki", wikiPath)
|
||||
}
|
||||
repo.DeleteWiki()
|
||||
|
||||
// Remove attachment files.
|
||||
for i := range attachmentPaths {
|
||||
@@ -1610,7 +1629,8 @@ func MirrorUpdate() {
|
||||
}
|
||||
|
||||
repoPath := m.Repo.RepoPath()
|
||||
if _, stderr, err := process.ExecDir(10*time.Minute,
|
||||
if _, stderr, err := process.ExecDir(
|
||||
time.Duration(setting.Git.Timeout.Mirror)*time.Second,
|
||||
repoPath, fmt.Sprintf("MirrorUpdate: %s", repoPath),
|
||||
"git", "remote", "update", "--prune"); err != nil {
|
||||
desc := fmt.Sprintf("Fail to update mirror repository(%s): %s", repoPath, stderr)
|
||||
@@ -1776,105 +1796,6 @@ func CheckRepoStats() {
|
||||
// ***** END: Repository.NumForks *****
|
||||
}
|
||||
|
||||
// _________ .__ .__ ___. __ .__
|
||||
// \_ ___ \ ____ | | | | _____ \_ |__ ________________ _/ |_|__| ____ ____
|
||||
// / \ \/ / _ \| | | | \__ \ | __ \ / _ \_ __ \__ \\ __\ |/ _ \ / \
|
||||
// \ \___( <_> ) |_| |__/ __ \| \_\ ( <_> ) | \// __ \| | | ( <_> ) | \
|
||||
// \______ /\____/|____/____(____ /___ /\____/|__| (____ /__| |__|\____/|___| /
|
||||
// \/ \/ \/ \/ \/
|
||||
|
||||
// A Collaboration is a relation between an individual and a repository
|
||||
type Collaboration struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
RepoID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
|
||||
UserID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
|
||||
Created time.Time `xorm:"CREATED"`
|
||||
}
|
||||
|
||||
// Add collaborator and accompanying access
|
||||
func (repo *Repository) AddCollaborator(u *User) error {
|
||||
collaboration := &Collaboration{
|
||||
RepoID: repo.ID,
|
||||
UserID: u.Id,
|
||||
}
|
||||
|
||||
has, err := x.Get(collaboration)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if has {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err = repo.GetOwner(); err != nil {
|
||||
return fmt.Errorf("GetOwner: %v", err)
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err = sess.InsertOne(collaboration); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if repo.Owner.IsOrganization() {
|
||||
err = repo.recalculateTeamAccesses(sess, 0)
|
||||
} else {
|
||||
err = repo.recalculateAccesses(sess)
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("recalculateAccesses 'team=%v': %v", repo.Owner.IsOrganization(), err)
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
func (repo *Repository) getCollaborators(e Engine) ([]*User, error) {
|
||||
collaborations := make([]*Collaboration, 0)
|
||||
if err := e.Find(&collaborations, &Collaboration{RepoID: repo.ID}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
users := make([]*User, len(collaborations))
|
||||
for i, c := range collaborations {
|
||||
user, err := getUserByID(e, c.UserID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
users[i] = user
|
||||
}
|
||||
return users, nil
|
||||
}
|
||||
|
||||
// GetCollaborators returns the collaborators for a repository
|
||||
func (repo *Repository) GetCollaborators() ([]*User, error) {
|
||||
return repo.getCollaborators(x)
|
||||
}
|
||||
|
||||
// Delete collaborator and accompanying access
|
||||
func (repo *Repository) DeleteCollaborator(u *User) (err error) {
|
||||
collaboration := &Collaboration{
|
||||
RepoID: repo.ID,
|
||||
UserID: u.Id,
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if has, err := sess.Delete(collaboration); err != nil || has == 0 {
|
||||
return err
|
||||
} else if err = repo.recalculateAccesses(sess); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
// __ __ __ .__
|
||||
// / \ / \_____ _/ |_ ____ | |__
|
||||
// \ \/\/ /\__ \\ __\/ ___\| | \
|
||||
|
||||
161
models/repo_collaboration.go
Normal file
161
models/repo_collaboration.go
Normal file
@@ -0,0 +1,161 @@
|
||||
// Copyright 2016 The Gogs 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 models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Collaboration represent the relation between an individual and a repository.
|
||||
type Collaboration struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
RepoID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
|
||||
UserID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
|
||||
Mode AccessMode `xorm:"DEFAULT 2 NOT NULL"`
|
||||
Created time.Time `xorm:"CREATED"`
|
||||
}
|
||||
|
||||
func (c *Collaboration) ModeName() string {
|
||||
switch c.Mode {
|
||||
case ACCESS_MODE_READ:
|
||||
return "Read"
|
||||
case ACCESS_MODE_WRITE:
|
||||
return "Write"
|
||||
case ACCESS_MODE_ADMIN:
|
||||
return "Admin"
|
||||
}
|
||||
return "Undefined"
|
||||
}
|
||||
|
||||
// AddCollaborator adds new collaboration relation between an individual and a repository.
|
||||
func (repo *Repository) AddCollaborator(u *User) error {
|
||||
collaboration := &Collaboration{
|
||||
RepoID: repo.ID,
|
||||
UserID: u.Id,
|
||||
}
|
||||
|
||||
has, err := x.Get(collaboration)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if has {
|
||||
return nil
|
||||
}
|
||||
collaboration.Mode = ACCESS_MODE_WRITE
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err = sess.InsertOne(collaboration); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if repo.Owner.IsOrganization() {
|
||||
err = repo.recalculateTeamAccesses(sess, 0)
|
||||
} else {
|
||||
err = repo.recalculateAccesses(sess)
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("recalculateAccesses 'team=%v': %v", repo.Owner.IsOrganization(), err)
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
func (repo *Repository) getCollaborations(e Engine) ([]*Collaboration, error) {
|
||||
collaborations := make([]*Collaboration, 0)
|
||||
return collaborations, e.Find(&collaborations, &Collaboration{RepoID: repo.ID})
|
||||
}
|
||||
|
||||
// Collaborator represents a user with collaboration details.
|
||||
type Collaborator struct {
|
||||
*User
|
||||
Collaboration *Collaboration
|
||||
}
|
||||
|
||||
func (repo *Repository) getCollaborators(e Engine) ([]*Collaborator, error) {
|
||||
collaborations, err := repo.getCollaborations(e)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("getCollaborations: %v", err)
|
||||
}
|
||||
|
||||
collaborators := make([]*Collaborator, len(collaborations))
|
||||
for i, c := range collaborations {
|
||||
user, err := getUserByID(e, c.UserID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
collaborators[i] = &Collaborator{
|
||||
User: user,
|
||||
Collaboration: c,
|
||||
}
|
||||
}
|
||||
return collaborators, nil
|
||||
}
|
||||
|
||||
// GetCollaborators returns the collaborators for a repository
|
||||
func (repo *Repository) GetCollaborators() ([]*Collaborator, error) {
|
||||
return repo.getCollaborators(x)
|
||||
}
|
||||
|
||||
// ChangeCollaborationAccessMode sets new access mode for the collaboration.
|
||||
func (repo *Repository) ChangeCollaborationAccessMode(uid int64, mode AccessMode) error {
|
||||
// Discard invalid input
|
||||
if mode <= ACCESS_MODE_NONE || mode > ACCESS_MODE_OWNER {
|
||||
return nil
|
||||
}
|
||||
|
||||
collaboration := &Collaboration{
|
||||
RepoID: repo.ID,
|
||||
UserID: uid,
|
||||
}
|
||||
has, err := x.Get(collaboration)
|
||||
if err != nil {
|
||||
return fmt.Errorf("get collaboration: %v", err)
|
||||
} else if !has {
|
||||
return nil
|
||||
}
|
||||
|
||||
collaboration.Mode = mode
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err = sess.Id(collaboration.ID).AllCols().Update(collaboration); err != nil {
|
||||
return fmt.Errorf("update collaboration: %v", err)
|
||||
} else if _, err = sess.Exec("UPDATE access SET mode = ? WHERE user_id = ? AND repo_id = ?", mode, uid, repo.ID); err != nil {
|
||||
return fmt.Errorf("update access table: %v", err)
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
// DeleteCollaboration removes collaboration relation between the user and repository.
|
||||
func (repo *Repository) DeleteCollaboration(uid int64) (err error) {
|
||||
collaboration := &Collaboration{
|
||||
RepoID: repo.ID,
|
||||
UserID: uid,
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if has, err := sess.Delete(collaboration); err != nil || has == 0 {
|
||||
return err
|
||||
} else if err = repo.recalculateAccesses(sess); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
}
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math/big"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
@@ -78,19 +79,18 @@ func (key *PublicKey) GetAuthorizedString() string {
|
||||
func extractTypeFromBase64Key(key string) (string, error) {
|
||||
b, err := base64.StdEncoding.DecodeString(key)
|
||||
if err != nil || len(b) < 4 {
|
||||
return "", errors.New("Invalid key format")
|
||||
return "", fmt.Errorf("Invalid key format: %v", err)
|
||||
}
|
||||
|
||||
keyLength := int(binary.BigEndian.Uint32(b))
|
||||
|
||||
if len(b) < 4+keyLength {
|
||||
return "", errors.New("Invalid key format")
|
||||
return "", fmt.Errorf("Invalid key format: not enough length")
|
||||
}
|
||||
|
||||
return string(b[4 : 4+keyLength]), nil
|
||||
}
|
||||
|
||||
// parseKeyString parses any key string in openssh or ssh2 format to clean openssh string (rfc4253)
|
||||
// parseKeyString parses any key string in OpenSSH or SSH2 format to clean OpenSSH string (RFC4253)
|
||||
func parseKeyString(content string) (string, error) {
|
||||
// Transform all legal line endings to a single "\n"
|
||||
s := strings.Replace(strings.Replace(strings.TrimSpace(content), "\r\n", "\n", -1), "\r", "\n", -1)
|
||||
@@ -153,8 +153,115 @@ func parseKeyString(content string) (string, error) {
|
||||
return keyType + " " + keyContent + " " + keyComment, nil
|
||||
}
|
||||
|
||||
// writeTmpKeyFile writes key content to a temporary file
|
||||
// and returns the name of that file, along with any possible errors.
|
||||
func writeTmpKeyFile(content string) (string, error) {
|
||||
tmpFile, err := ioutil.TempFile(setting.SSH.KeyTestPath, "gogs_keytest")
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("TempFile: %v", err)
|
||||
}
|
||||
defer tmpFile.Close()
|
||||
|
||||
if _, err = tmpFile.WriteString(content); err != nil {
|
||||
return "", fmt.Errorf("tmpFile.WriteString: %v", err)
|
||||
}
|
||||
return tmpFile.Name(), nil
|
||||
}
|
||||
|
||||
// SSHKeyGenParsePublicKey extracts key type and length using ssh-keygen.
|
||||
func SSHKeyGenParsePublicKey(key string) (string, int, error) {
|
||||
// The ssh-keygen in Windows does not print key type, so no need go further.
|
||||
if setting.IsWindows {
|
||||
return "", 0, nil
|
||||
}
|
||||
|
||||
tmpName, err := writeTmpKeyFile(key)
|
||||
if err != nil {
|
||||
return "", 0, fmt.Errorf("writeTmpKeyFile: %v", err)
|
||||
}
|
||||
defer os.Remove(tmpName)
|
||||
|
||||
stdout, stderr, err := process.Exec("SSHKeyGenParsePublicKey", setting.SSH.KeygenPath, "-lf", tmpName)
|
||||
if err != nil {
|
||||
return "", 0, fmt.Errorf("Fail to parse public key: %s - %s", err, stderr)
|
||||
}
|
||||
if strings.Contains(stdout, "is not a public key file") {
|
||||
return "", 0, ErrKeyUnableVerify{stdout}
|
||||
}
|
||||
|
||||
fields := strings.Split(stdout, " ")
|
||||
if len(fields) < 4 {
|
||||
return "", 0, fmt.Errorf("Invalid public key line: %s", stdout)
|
||||
}
|
||||
|
||||
keyType := strings.Trim(fields[len(fields)-1], "()\r\n")
|
||||
return strings.ToLower(keyType), com.StrTo(fields[0]).MustInt(), nil
|
||||
}
|
||||
|
||||
// SSHNativeParsePublicKey extracts the key type and length using the golang SSH library.
|
||||
// NOTE: ed25519 is not supported.
|
||||
func SSHNativeParsePublicKey(keyLine string) (string, int, error) {
|
||||
fields := strings.Fields(keyLine)
|
||||
if len(fields) < 2 {
|
||||
return "", 0, fmt.Errorf("not enough fields in public key line: %s", string(keyLine))
|
||||
}
|
||||
|
||||
raw, err := base64.StdEncoding.DecodeString(fields[1])
|
||||
if err != nil {
|
||||
return "", 0, err
|
||||
}
|
||||
|
||||
pkey, err := ssh.ParsePublicKey(raw)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "ssh: unknown key algorithm") {
|
||||
return "", 0, ErrKeyUnableVerify{err.Error()}
|
||||
}
|
||||
return "", 0, fmt.Errorf("ssh.ParsePublicKey: %v", err)
|
||||
}
|
||||
|
||||
// The ssh library can parse the key, so next we find out what key exactly we have.
|
||||
switch pkey.Type() {
|
||||
case ssh.KeyAlgoDSA:
|
||||
rawPub := struct {
|
||||
Name string
|
||||
P, Q, G, Y *big.Int
|
||||
}{}
|
||||
if err := ssh.Unmarshal(pkey.Marshal(), &rawPub); err != nil {
|
||||
return "", 0, err
|
||||
}
|
||||
// as per https://bugzilla.mindrot.org/show_bug.cgi?id=1647 we should never
|
||||
// see dsa keys != 1024 bit, but as it seems to work, we will not check here
|
||||
return "dsa", rawPub.P.BitLen(), nil // use P as per crypto/dsa/dsa.go (is L)
|
||||
case ssh.KeyAlgoRSA:
|
||||
rawPub := struct {
|
||||
Name string
|
||||
E *big.Int
|
||||
N *big.Int
|
||||
}{}
|
||||
if err := ssh.Unmarshal(pkey.Marshal(), &rawPub); err != nil {
|
||||
return "", 0, err
|
||||
}
|
||||
return "rsa", rawPub.N.BitLen(), nil // use N as per crypto/rsa/rsa.go (is bits)
|
||||
case ssh.KeyAlgoECDSA256:
|
||||
return "ecdsa", 256, nil
|
||||
case ssh.KeyAlgoECDSA384:
|
||||
return "ecdsa", 384, nil
|
||||
case ssh.KeyAlgoECDSA521:
|
||||
return "ecdsa", 521, nil
|
||||
case "ssh-ed25519": // TODO replace with ssh constant when available
|
||||
return "ed25519", 256, nil
|
||||
}
|
||||
return "", 0, fmt.Errorf("Unsupported key length detection for type: %s", pkey.Type())
|
||||
}
|
||||
|
||||
// CheckPublicKeyString checks if the given public key string is recognized by SSH.
|
||||
//
|
||||
// The function returns the actual public key line on success.
|
||||
func CheckPublicKeyString(content string) (_ string, err error) {
|
||||
if setting.SSH.Disabled {
|
||||
return "", errors.New("SSH is disabled")
|
||||
}
|
||||
|
||||
content, err = parseKeyString(content)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -168,22 +275,29 @@ func CheckPublicKeyString(content string) (_ string, err error) {
|
||||
// remove any unnecessary whitespace now
|
||||
content = strings.TrimSpace(content)
|
||||
|
||||
fields := strings.Fields(content)
|
||||
if len(fields) < 2 {
|
||||
return "", errors.New("too less fields")
|
||||
var (
|
||||
keyType string
|
||||
length int
|
||||
)
|
||||
if setting.SSH.StartBuiltinServer {
|
||||
keyType, length, err = SSHNativeParsePublicKey(content)
|
||||
} else {
|
||||
keyType, length, err = SSHKeyGenParsePublicKey(content)
|
||||
}
|
||||
|
||||
key, err := base64.StdEncoding.DecodeString(fields[1])
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("StdEncoding.DecodeString: %v", err)
|
||||
}
|
||||
pkey, err := ssh.ParsePublicKey([]byte(key))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("ParsePublicKey: %v", err)
|
||||
}
|
||||
log.Trace("Key type: %s", pkey.Type())
|
||||
log.Trace("Key info [native: %v]: %s-%d", setting.SSH.StartBuiltinServer, keyType, length)
|
||||
|
||||
return content, nil
|
||||
if !setting.SSH.MinimumKeySizeCheck {
|
||||
return content, nil
|
||||
}
|
||||
if minLen, found := setting.SSH.MinimumKeySizes[keyType]; found && length >= minLen {
|
||||
return content, nil
|
||||
} else if found && length < minLen {
|
||||
return "", fmt.Errorf("Key length is not enough: got %d, needs %d", length, minLen)
|
||||
}
|
||||
return "", fmt.Errorf("Key type is not allowed: %s", keyType)
|
||||
}
|
||||
|
||||
// saveAuthorizedKeyFile writes SSH key content to authorized_keys file.
|
||||
@@ -191,7 +305,7 @@ func saveAuthorizedKeyFile(keys ...*PublicKey) error {
|
||||
sshOpLocker.Lock()
|
||||
defer sshOpLocker.Unlock()
|
||||
|
||||
fpath := filepath.Join(setting.SSHRootPath, "authorized_keys")
|
||||
fpath := filepath.Join(setting.SSH.RootPath, "authorized_keys")
|
||||
f, err := os.OpenFile(fpath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -247,7 +361,7 @@ func addKey(e Engine, key *PublicKey) (err error) {
|
||||
}
|
||||
stdout, stderr, err := process.Exec("AddPublicKey", "ssh-keygen", "-lf", tmpPath)
|
||||
if err != nil {
|
||||
return errors.New("ssh-keygen -lf: " + stderr)
|
||||
return fmt.Errorf("'ssh-keygen -lf %s' failed with error '%s': %s", tmpPath, err, stderr)
|
||||
} else if len(stdout) < 2 {
|
||||
return errors.New("not enough output for calculating fingerprint: " + stdout)
|
||||
}
|
||||
@@ -259,7 +373,7 @@ func addKey(e Engine, key *PublicKey) (err error) {
|
||||
}
|
||||
|
||||
// Don't need to rewrite this file if builtin SSH server is enabled.
|
||||
if setting.StartSSHServer {
|
||||
if setting.SSH.StartBuiltinServer {
|
||||
return nil
|
||||
}
|
||||
return saveAuthorizedKeyFile(key)
|
||||
@@ -267,6 +381,7 @@ func addKey(e Engine, key *PublicKey) (err error) {
|
||||
|
||||
// AddPublicKey adds new public key to database and authorized_keys file.
|
||||
func AddPublicKey(ownerID int64, name, content string) (*PublicKey, error) {
|
||||
log.Trace(content)
|
||||
if err := checkKeyContent(content); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -408,12 +523,12 @@ func deletePublicKey(e *xorm.Session, keyID int64) error {
|
||||
}
|
||||
|
||||
// Don't need to rewrite this file if builtin SSH server is enabled.
|
||||
if setting.StartSSHServer {
|
||||
if setting.SSH.StartBuiltinServer {
|
||||
return nil
|
||||
}
|
||||
|
||||
fpath := filepath.Join(setting.SSHRootPath, "authorized_keys")
|
||||
tmpPath := filepath.Join(setting.SSHRootPath, "authorized_keys.tmp")
|
||||
fpath := filepath.Join(setting.SSH.RootPath, "authorized_keys")
|
||||
tmpPath := fpath + ".tmp"
|
||||
if err = rewriteAuthorizedKeys(key, fpath, tmpPath); err != nil {
|
||||
return err
|
||||
} else if err = os.Remove(fpath); err != nil {
|
||||
@@ -455,7 +570,8 @@ func RewriteAllPublicKeys() error {
|
||||
sshOpLocker.Lock()
|
||||
defer sshOpLocker.Unlock()
|
||||
|
||||
tmpPath := filepath.Join(setting.SSHRootPath, "authorized_keys.tmp")
|
||||
fpath := filepath.Join(setting.SSH.RootPath, "authorized_keys")
|
||||
tmpPath := fpath + ".tmp"
|
||||
f, err := os.OpenFile(tmpPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -471,7 +587,6 @@ func RewriteAllPublicKeys() error {
|
||||
return err
|
||||
}
|
||||
|
||||
fpath := filepath.Join(setting.SSHRootPath, "authorized_keys")
|
||||
if com.IsExist(fpath) {
|
||||
if err = os.Remove(fpath); err != nil {
|
||||
return err
|
||||
|
||||
45
models/ssh_key_test.go
Normal file
45
models/ssh_key_test.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
func init() {
|
||||
setting.NewContext()
|
||||
}
|
||||
|
||||
func Test_SSHParsePublicKey(t *testing.T) {
|
||||
testKeys := map[string]struct {
|
||||
typeName string
|
||||
length int
|
||||
content string
|
||||
}{
|
||||
"dsa-1024": {"dsa", 1024, "ssh-dss AAAAB3NzaC1kc3MAAACBAOChCC7lf6Uo9n7BmZ6M8St19PZf4Tn59NriyboW2x/DZuYAz3ibZ2OkQ3S0SqDIa0HXSEJ1zaExQdmbO+Ux/wsytWZmCczWOVsaszBZSl90q8UnWlSH6P+/YA+RWJm5SFtuV9PtGIhyZgoNuz5kBQ7K139wuQsecdKktISwTakzAAAAFQCzKsO2JhNKlL+wwwLGOcLffoAmkwAAAIBpK7/3xvduajLBD/9vASqBQIHrgK2J+wiQnIb/Wzy0UsVmvfn8A+udRbBo+csM8xrSnlnlJnjkJS3qiM5g+eTwsLIV1IdKPEwmwB+VcP53Cw6lSyWyJcvhFb0N6s08NZysLzvj0N+ZC/FnhKTLzIyMtkHf/IrPCwlM+pV/M/96YgAAAIEAqQcGn9CKgzgPaguIZooTAOQdvBLMI5y0bQjOW6734XOpqQGf/Kra90wpoasLKZjSYKNPjE+FRUOrStLrxcNs4BeVKhy2PYTRnybfYVk1/dmKgH6P1YSRONsGKvTsH6c5IyCRG0ncCgYeF8tXppyd642982daopE7zQ/NPAnJfag= nocomment"},
|
||||
"rsa-1024": {"rsa", 1024, "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDAu7tvIvX6ZHrRXuZNfkR3XLHSsuCK9Zn3X58lxBcQzuo5xZgB6vRwwm/QtJuF+zZPtY5hsQILBLmF+BZ5WpKZp1jBeSjH2G7lxet9kbcH+kIVj0tPFEoyKI9wvWqIwC4prx/WVk2wLTJjzBAhyNxfEq7C9CeiX9pQEbEqJfkKCQ== nocomment\n"},
|
||||
"rsa-2048": {"rsa", 2048, "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDMZXh+1OBUwSH9D45wTaxErQIN9IoC9xl7MKJkqvTvv6O5RR9YW/IK9FbfjXgXsppYGhsCZo1hFOOsXHMnfOORqu/xMDx4yPuyvKpw4LePEcg4TDipaDFuxbWOqc/BUZRZcXu41QAWfDLrInwsltWZHSeG7hjhpacl4FrVv9V1pS6Oc5Q1NxxEzTzuNLS/8diZrTm/YAQQ/+B+mzWI3zEtF4miZjjAljWd1LTBPvU23d29DcBmmFahcZ441XZsTeAwGxG/Q6j8NgNXj9WxMeWwxXV2jeAX/EBSpZrCVlCQ1yJswT6xCp8TuBnTiGWYMBNTbOZvPC4e0WI2/yZW/s5F nocomment"},
|
||||
"ecdsa-256": {"ecdsa", 256, "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFQacN3PrOll7PXmN5B/ZNVahiUIqI05nbBlZk1KXsO3d06ktAWqbNflv2vEmA38bTFTfJ2sbn2B5ksT52cDDbA= nocomment"},
|
||||
"ecdsa-384": {"ecdsa", 384, "ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBINmioV+XRX1Fm9Qk2ehHXJ2tfVxW30ypUWZw670Zyq5GQfBAH6xjygRsJ5wWsHXBsGYgFUXIHvMKVAG1tpw7s6ax9oA+dJOJ7tj+vhn8joFqT+sg3LYHgZkHrfqryRasQ== nocomment"},
|
||||
"ecdsa-521": {"ecdsa", 521, "ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBACGt3UG3EzRwNOI17QR84l6PgiAcvCE7v6aXPj/SC6UWKg4EL8vW9ZBcdYL9wzs4FZXh4MOV8jAzu3KRWNTwb4k2wFNUpGOt7l28MztFFEtH5BDDrtAJSPENPy8pvPLMfnPg5NhvWycqIBzNcHipem5wSJFN5PdpNOC2xMrPWKNqj+ZjQ== nocomment"},
|
||||
}
|
||||
|
||||
Convey("Parse public keys in both native and ssh-keygen", t, func() {
|
||||
for name, key := range testKeys {
|
||||
fmt.Println("\nTesting key:", name)
|
||||
|
||||
keyTypeN, lengthN, errN := SSHNativeParsePublicKey(key.content)
|
||||
So(errN, ShouldBeNil)
|
||||
So(keyTypeN, ShouldEqual, key.typeName)
|
||||
So(lengthN, ShouldEqual, key.length)
|
||||
|
||||
keyTypeK, lengthK, errK := SSHKeyGenParsePublicKey(key.content)
|
||||
So(errK, ShouldBeNil)
|
||||
So(keyTypeK, ShouldEqual, key.typeName)
|
||||
So(lengthK, ShouldEqual, key.length)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -346,23 +346,34 @@ func (u *User) UploadAvatar(data []byte) error {
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
// DeleteAvatar deletes the user's custom avatar.
|
||||
func (u *User) DeleteAvatar() error {
|
||||
log.Trace("DeleteAvatar[%d]: %s", u.Id, u.CustomAvatarPath())
|
||||
os.Remove(u.CustomAvatarPath())
|
||||
|
||||
u.UseCustomAvatar = false
|
||||
if err := UpdateUser(u); err != nil {
|
||||
return fmt.Errorf("UpdateUser: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsAdminOfRepo returns true if user has admin or higher access of repository.
|
||||
func (u *User) IsAdminOfRepo(repo *Repository) bool {
|
||||
if err := repo.GetOwner(); err != nil {
|
||||
log.Error(3, "GetOwner: %v", err)
|
||||
return false
|
||||
has, err := HasAccess(u, repo, ACCESS_MODE_ADMIN)
|
||||
if err != nil {
|
||||
log.Error(3, "HasAccess: %v", err)
|
||||
}
|
||||
return has
|
||||
}
|
||||
|
||||
if repo.Owner.IsOrganization() {
|
||||
has, err := HasAccess(u, repo, ACCESS_MODE_ADMIN)
|
||||
if err != nil {
|
||||
log.Error(3, "HasAccess: %v", err)
|
||||
return false
|
||||
}
|
||||
return has
|
||||
// IsWriterOfRepo returns true if user has write access to given repository.
|
||||
func (u *User) IsWriterOfRepo(repo *Repository) bool {
|
||||
has, err := HasAccess(u, repo, ACCESS_MODE_WRITE)
|
||||
if err != nil {
|
||||
log.Error(3, "HasAccess: %v", err)
|
||||
}
|
||||
|
||||
return repo.IsOwnedBy(u.Id)
|
||||
return has
|
||||
}
|
||||
|
||||
// IsOrganization returns true if user is actually a organization.
|
||||
@@ -614,7 +625,7 @@ func ChangeUserName(u *User, newUserName string) (err error) {
|
||||
}
|
||||
|
||||
func updateUser(e Engine, u *User) error {
|
||||
// Organization does not need e-mail.
|
||||
// Organization does not need email
|
||||
if !u.IsOrganization() {
|
||||
u.Email = strings.ToLower(u.Email)
|
||||
has, err := e.Where("id!=?", u.Id).And("type=?", u.Type).And("email=?", u.Email).Get(new(User))
|
||||
@@ -631,16 +642,9 @@ func updateUser(e Engine, u *User) error {
|
||||
}
|
||||
|
||||
u.LowerName = strings.ToLower(u.Name)
|
||||
|
||||
if len(u.Location) > 255 {
|
||||
u.Location = u.Location[:255]
|
||||
}
|
||||
if len(u.Website) > 255 {
|
||||
u.Website = u.Website[:255]
|
||||
}
|
||||
if len(u.Description) > 255 {
|
||||
u.Description = u.Description[:255]
|
||||
}
|
||||
u.Location = base.TruncateString(u.Location, 255)
|
||||
u.Website = base.TruncateString(u.Website, 255)
|
||||
u.Description = base.TruncateString(u.Description, 255)
|
||||
|
||||
u.FullName = markdown.Sanitizer.Sanitize(u.FullName)
|
||||
_, err := e.Id(u.Id).AllCols().Update(u)
|
||||
|
||||
@@ -7,12 +7,12 @@ package models
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"net/url"
|
||||
|
||||
"github.com/Unknwon/com"
|
||||
|
||||
@@ -116,6 +116,23 @@ func (repo *Repository) UpdateLocalWiki() error {
|
||||
return updateLocalCopy(repo.WikiPath(), repo.LocalWikiPath())
|
||||
}
|
||||
|
||||
// discardLocalWikiChanges discards local commits make sure
|
||||
// it is even to remote branch when local copy exists.
|
||||
func discardLocalWikiChanges(localPath string) error {
|
||||
if !com.IsExist(localPath) {
|
||||
return nil
|
||||
}
|
||||
// No need to check if nothing in the repository.
|
||||
if !git.IsBranchExist(localPath, "master") {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := git.ResetHEAD(localPath, true, "origin/master"); err != nil {
|
||||
return fmt.Errorf("ResetHEAD: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// updateWikiPage adds new page to repository wiki.
|
||||
func (repo *Repository) updateWikiPage(doer *User, oldTitle, title, content, message string, isNew bool) (err error) {
|
||||
wikiWorkingPool.CheckIn(com.ToStr(repo.ID))
|
||||
@@ -126,18 +143,9 @@ func (repo *Repository) updateWikiPage(doer *User, oldTitle, title, content, mes
|
||||
}
|
||||
|
||||
localPath := repo.LocalWikiPath()
|
||||
|
||||
// Discard local commits make sure even to remote when local copy exists.
|
||||
if com.IsExist(localPath) {
|
||||
// No need to check if nothing in the repository.
|
||||
if git.IsBranchExist(localPath, "master") {
|
||||
if err = git.ResetHEAD(localPath, true, "origin/master"); err != nil {
|
||||
return fmt.Errorf("Reset: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err = repo.UpdateLocalWiki(); err != nil {
|
||||
if err = discardLocalWikiChanges(localPath); err != nil {
|
||||
return fmt.Errorf("discardLocalWikiChanges: %v", err)
|
||||
} else if err = repo.UpdateLocalWiki(); err != nil {
|
||||
return fmt.Errorf("UpdateLocalWiki: %v", err)
|
||||
}
|
||||
|
||||
@@ -178,3 +186,31 @@ func (repo *Repository) AddWikiPage(doer *User, title, content, message string)
|
||||
func (repo *Repository) EditWikiPage(doer *User, oldTitle, title, content, message string) error {
|
||||
return repo.updateWikiPage(doer, oldTitle, title, content, message, false)
|
||||
}
|
||||
|
||||
func (repo *Repository) DeleteWikiPage(doer *User, title string) (err error) {
|
||||
wikiWorkingPool.CheckIn(com.ToStr(repo.ID))
|
||||
defer wikiWorkingPool.CheckOut(com.ToStr(repo.ID))
|
||||
|
||||
localPath := repo.LocalWikiPath()
|
||||
if err = discardLocalWikiChanges(localPath); err != nil {
|
||||
return fmt.Errorf("discardLocalWikiChanges: %v", err)
|
||||
} else if err = repo.UpdateLocalWiki(); err != nil {
|
||||
return fmt.Errorf("UpdateLocalWiki: %v", err)
|
||||
}
|
||||
|
||||
title = ToWikiPageName(strings.Replace(title, "/", " ", -1))
|
||||
filename := path.Join(localPath, title+".md")
|
||||
os.Remove(filename)
|
||||
|
||||
message := "Delete page '" + title + "'"
|
||||
|
||||
if err = git.AddChanges(localPath, true); err != nil {
|
||||
return fmt.Errorf("AddChanges: %v", err)
|
||||
} else if err = git.CommitChanges(localPath, message, doer.NewGitSig()); err != nil {
|
||||
return fmt.Errorf("CommitChanges: %v", err)
|
||||
} else if err = git.Push(localPath, "origin", "master"); err != nil {
|
||||
return fmt.Errorf("Push: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -464,6 +464,15 @@ func EllipsisString(str string, length int) string {
|
||||
return str[:length-3] + "..."
|
||||
}
|
||||
|
||||
// TruncateString returns a truncated string with given limit,
|
||||
// it returns input string if length is not reached limit.
|
||||
func TruncateString(str string, limit int) string {
|
||||
if len(str) < limit {
|
||||
return str
|
||||
}
|
||||
return str[:limit]
|
||||
}
|
||||
|
||||
// StringsToInt64s converts a slice of string to a slice of int64.
|
||||
func StringsToInt64s(strs []string) []int64 {
|
||||
ints := make([]int64, len(strs))
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,68 +0,0 @@
|
||||
// Copyright 2014 The Gogs 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 log
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/go-xorm/xorm"
|
||||
)
|
||||
|
||||
type Log struct {
|
||||
Id int64
|
||||
Level int
|
||||
Msg string `xorm:"TEXT"`
|
||||
}
|
||||
|
||||
// DatabaseWriter implements LoggerInterface and is used to log into database.
|
||||
type DatabaseWriter struct {
|
||||
Driver string `json:"driver"`
|
||||
Conn string `json:"conn"`
|
||||
Level int `json:"level"`
|
||||
x *xorm.Engine
|
||||
}
|
||||
|
||||
func NewDatabase() LoggerInterface {
|
||||
return &DatabaseWriter{Level: TRACE}
|
||||
}
|
||||
|
||||
// init database writer with json config.
|
||||
// config like:
|
||||
// {
|
||||
// "driver": "mysql"
|
||||
// "conn":"root:root@tcp(127.0.0.1:3306)/gogs?charset=utf8",
|
||||
// "level": 0
|
||||
// }
|
||||
// connection string is based on xorm.
|
||||
func (d *DatabaseWriter) Init(jsonconfig string) (err error) {
|
||||
if err = json.Unmarshal([]byte(jsonconfig), d); err != nil {
|
||||
return err
|
||||
}
|
||||
d.x, err = xorm.NewEngine(d.Driver, d.Conn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return d.x.Sync(new(Log))
|
||||
}
|
||||
|
||||
// write message in database writer.
|
||||
func (d *DatabaseWriter) WriteMsg(msg string, skip, level int) error {
|
||||
if level < d.Level {
|
||||
return nil
|
||||
}
|
||||
|
||||
_, err := d.x.Insert(&Log{Level: level, Msg: msg})
|
||||
return err
|
||||
}
|
||||
|
||||
func (_ *DatabaseWriter) Flush() {
|
||||
}
|
||||
|
||||
func (_ *DatabaseWriter) Destroy() {
|
||||
}
|
||||
|
||||
func init() {
|
||||
Register("database", NewDatabase)
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/gomail.v2"
|
||||
"gopkg.in/macaron.v1"
|
||||
|
||||
"github.com/gogits/gogs/models"
|
||||
@@ -183,3 +184,7 @@ func SendCollaboratorMail(r macaron.Render, u, doer *models.User, repo *models.R
|
||||
SendAsync(msg)
|
||||
return nil
|
||||
}
|
||||
|
||||
func SendTestMail(email string) error {
|
||||
return gomail.Send(&Sender{}, NewMessage([]string{email}, "Gogs Test Email!", "Gogs Test Email!").Message)
|
||||
}
|
||||
|
||||
@@ -109,17 +109,12 @@ func Toggle(options *ToggleOptions) macaron.Handler {
|
||||
}
|
||||
}
|
||||
|
||||
// Try auto-signin when not signed in.
|
||||
if !options.SignOutRequire && !ctx.IsSigned && !auth.IsAPIPath(ctx.Req.URL.Path) {
|
||||
succeed, err := AutoSignIn(ctx)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "AutoSignIn", err)
|
||||
return
|
||||
} else if succeed {
|
||||
log.Trace("Auto-login succeed: %s", ctx.Session.Get("uname"))
|
||||
ctx.Redirect(setting.AppSubUrl + ctx.Req.RequestURI)
|
||||
return
|
||||
}
|
||||
// Auto-signin info is provided and has not signed in.
|
||||
if !options.SignOutRequire && !ctx.IsSigned && !auth.IsAPIPath(ctx.Req.URL.Path) &&
|
||||
len(ctx.GetCookie(setting.CookieUserName)) > 0 {
|
||||
ctx.SetCookie("redirect_to", url.QueryEscape(setting.AppSubUrl+ctx.Req.RequestURI), 0, setting.AppSubUrl)
|
||||
ctx.Redirect(setting.AppSubUrl + "/user/login")
|
||||
return
|
||||
}
|
||||
|
||||
if options.AdminRequire {
|
||||
|
||||
@@ -84,12 +84,12 @@ func (r *RepoContext) IsAdmin() bool {
|
||||
return r.AccessMode >= models.ACCESS_MODE_ADMIN
|
||||
}
|
||||
|
||||
// IsPusher returns true if current user has write or higher access of repository.
|
||||
func (r *RepoContext) IsPusher() bool {
|
||||
// IsWriter returns true if current user has write or higher access of repository.
|
||||
func (r *RepoContext) IsWriter() bool {
|
||||
return r.AccessMode >= models.ACCESS_MODE_WRITE
|
||||
}
|
||||
|
||||
// Return if the current user has read access for this repository
|
||||
// HasAccess returns true if the current user has at least read access for this repository
|
||||
func (r *RepoContext) HasAccess() bool {
|
||||
return r.AccessMode >= models.ACCESS_MODE_READ
|
||||
}
|
||||
|
||||
@@ -32,25 +32,6 @@ func RetrieveBaseRepo(ctx *Context, repo *models.Repository) {
|
||||
ctx.Handle(500, "BaseRepo.GetOwner", err)
|
||||
return
|
||||
}
|
||||
|
||||
bsaeRepo := repo.BaseRepo
|
||||
baseGitRepo, err := git.OpenRepository(models.RepoPath(bsaeRepo.Owner.Name, bsaeRepo.Name))
|
||||
if err != nil {
|
||||
ctx.Handle(500, "OpenRepository", err)
|
||||
return
|
||||
}
|
||||
if len(bsaeRepo.DefaultBranch) > 0 && baseGitRepo.IsBranchExist(bsaeRepo.DefaultBranch) {
|
||||
ctx.Data["BaseDefaultBranch"] = bsaeRepo.DefaultBranch
|
||||
} else {
|
||||
baseBranches, err := baseGitRepo.GetBranches()
|
||||
if err != nil {
|
||||
ctx.Handle(500, "GetBranches", err)
|
||||
return
|
||||
}
|
||||
if len(baseBranches) > 0 {
|
||||
ctx.Data["BaseDefaultBranch"] = baseBranches[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func RepoAssignment(args ...bool) macaron.Handler {
|
||||
@@ -154,6 +135,13 @@ func RepoAssignment(args ...bool) macaron.Handler {
|
||||
ctx.Data["Tags"] = tags
|
||||
ctx.Repo.Repository.NumTags = len(tags)
|
||||
|
||||
ctx.Data["Title"] = owner.Name + "/" + repo.Name
|
||||
ctx.Data["Repository"] = repo
|
||||
ctx.Data["Owner"] = ctx.Repo.Repository.Owner
|
||||
ctx.Data["IsRepositoryOwner"] = ctx.Repo.IsOwner()
|
||||
ctx.Data["IsRepositoryAdmin"] = ctx.Repo.IsAdmin()
|
||||
ctx.Data["IsRepositoryWriter"] = ctx.Repo.IsWriter()
|
||||
|
||||
if repo.IsFork {
|
||||
RetrieveBaseRepo(ctx, repo)
|
||||
if ctx.Written() {
|
||||
@@ -161,15 +149,26 @@ func RepoAssignment(args ...bool) macaron.Handler {
|
||||
}
|
||||
}
|
||||
|
||||
ctx.Data["Title"] = owner.Name + "/" + repo.Name
|
||||
ctx.Data["Repository"] = repo
|
||||
ctx.Data["Owner"] = ctx.Repo.Repository.Owner
|
||||
ctx.Data["IsRepositoryOwner"] = ctx.Repo.IsOwner()
|
||||
ctx.Data["IsRepositoryAdmin"] = ctx.Repo.IsAdmin()
|
||||
ctx.Data["IsRepositoryPusher"] = ctx.Repo.IsPusher()
|
||||
ctx.Data["CanPullRequest"] = ctx.Repo.IsAdmin() && repo.BaseRepo != nil && repo.BaseRepo.AllowsPulls()
|
||||
// People who have push access and propose a new pull request.
|
||||
if ctx.Repo.IsWriter() {
|
||||
// Pull request is allowed if this is a fork repository
|
||||
// and base repository accepts pull requests.
|
||||
if repo.BaseRepo != nil {
|
||||
if repo.BaseRepo.AllowsPulls() {
|
||||
ctx.Data["CanPullRequest"] = true
|
||||
ctx.Data["BaseRepo"] = repo.BaseRepo
|
||||
}
|
||||
} else {
|
||||
// Or, this is repository accepts pull requests between branches.
|
||||
if repo.AllowsPulls() {
|
||||
ctx.Data["CanPullRequest"] = true
|
||||
ctx.Data["BaseRepo"] = repo
|
||||
ctx.Data["IsBetweenBranches"] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctx.Data["DisableSSH"] = setting.DisableSSH
|
||||
ctx.Data["DisableSSH"] = setting.SSH.Disabled
|
||||
ctx.Data["CloneLink"] = repo.CloneLink()
|
||||
ctx.Data["WikiCloneLink"] = repo.WikiCloneLink()
|
||||
|
||||
@@ -337,16 +336,16 @@ func RepoRef() macaron.Handler {
|
||||
|
||||
func RequireRepoAdmin() macaron.Handler {
|
||||
return func(ctx *Context) {
|
||||
if !ctx.Repo.IsAdmin() {
|
||||
if !ctx.IsSigned || (!ctx.Repo.IsAdmin() && !ctx.User.IsAdmin) {
|
||||
ctx.Handle(404, ctx.Req.RequestURI, nil)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func RequireRepoPusher() macaron.Handler {
|
||||
func RequireRepoWriter() macaron.Handler {
|
||||
return func(ctx *Context) {
|
||||
if !ctx.Repo.IsPusher() {
|
||||
if !ctx.IsSigned || (!ctx.Repo.IsWriter() && !ctx.User.IsAdmin) {
|
||||
ctx.Handle(404, ctx.Req.RequestURI, nil)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -61,11 +61,6 @@ var (
|
||||
Domain string
|
||||
HttpAddr, HttpPort string
|
||||
LocalURL string
|
||||
DisableSSH bool
|
||||
StartSSHServer bool
|
||||
SSHDomain string
|
||||
SSHPort int
|
||||
SSHRootPath string
|
||||
OfflineMode bool
|
||||
DisableRouterLog bool
|
||||
CertFile, KeyFile string
|
||||
@@ -73,6 +68,19 @@ var (
|
||||
EnableGzip bool
|
||||
LandingPageUrl LandingPage
|
||||
|
||||
SSH struct {
|
||||
Disabled bool `ini:"DISABLE_SSH"`
|
||||
StartBuiltinServer bool `ini:"START_SSH_SERVER"`
|
||||
Domain string `ini:"SSH_DOMAIN"`
|
||||
Port int `ini:"SSH_PORT"`
|
||||
ListenPort int `ini:"SSH_LISTEN_PORT"`
|
||||
RootPath string `ini:"SSH_ROOT_PATH"`
|
||||
KeyTestPath string `ini:"SSH_KEY_TEST_PATH"`
|
||||
KeygenPath string `ini:"SSH_KEYGEN_PATH"`
|
||||
MinimumKeySizeCheck bool `ini:"-"`
|
||||
MinimumKeySizes map[string]int `ini:"-"`
|
||||
}
|
||||
|
||||
// Security settings
|
||||
InstallLock bool
|
||||
SecretKey string
|
||||
@@ -123,7 +131,6 @@ var (
|
||||
}
|
||||
|
||||
// Picture settings
|
||||
PictureService string
|
||||
AvatarUploadPath string
|
||||
GravatarSource string
|
||||
DisableGravatar bool
|
||||
@@ -155,6 +162,12 @@ var (
|
||||
Git struct {
|
||||
MaxGitDiffLines int
|
||||
GcArgs []string `delim:" "`
|
||||
Timeout struct {
|
||||
Migrate int
|
||||
Mirror int
|
||||
Clone int
|
||||
Pull int
|
||||
} `ini:"git.timeout"`
|
||||
}
|
||||
|
||||
// Cron tasks
|
||||
@@ -318,16 +331,6 @@ func NewContext() {
|
||||
HttpAddr = sec.Key("HTTP_ADDR").MustString("0.0.0.0")
|
||||
HttpPort = sec.Key("HTTP_PORT").MustString("3000")
|
||||
LocalURL = sec.Key("LOCAL_ROOT_URL").MustString("http://localhost:" + HttpPort + "/")
|
||||
DisableSSH = sec.Key("DISABLE_SSH").MustBool()
|
||||
if !DisableSSH {
|
||||
StartSSHServer = sec.Key("START_SSH_SERVER").MustBool()
|
||||
}
|
||||
SSHDomain = sec.Key("SSH_DOMAIN").MustString(Domain)
|
||||
SSHPort = sec.Key("SSH_PORT").MustInt(22)
|
||||
SSHRootPath = sec.Key("SSH_ROOT_PATH").MustString(path.Join(homeDir, ".ssh"))
|
||||
if err := os.MkdirAll(SSHRootPath, 0700); err != nil {
|
||||
log.Fatal(4, "Fail to create '%s': %v", SSHRootPath, err)
|
||||
}
|
||||
OfflineMode = sec.Key("OFFLINE_MODE").MustBool()
|
||||
DisableRouterLog = sec.Key("DISABLE_ROUTER_LOG").MustBool()
|
||||
StaticRootPath = sec.Key("STATIC_ROOT_PATH").MustString(workDir)
|
||||
@@ -340,6 +343,39 @@ func NewContext() {
|
||||
LandingPageUrl = LANDING_PAGE_HOME
|
||||
}
|
||||
|
||||
SSH.RootPath = path.Join(homeDir, ".ssh")
|
||||
SSH.KeyTestPath = os.TempDir()
|
||||
if err = Cfg.Section("server").MapTo(&SSH); err != nil {
|
||||
log.Fatal(4, "Fail to map SSH settings: %v", err)
|
||||
}
|
||||
// When disable SSH, start builtin server value is ignored.
|
||||
if SSH.Disabled {
|
||||
SSH.StartBuiltinServer = false
|
||||
}
|
||||
|
||||
if !SSH.Disabled && !SSH.StartBuiltinServer {
|
||||
if err := os.MkdirAll(SSH.RootPath, 0700); err != nil {
|
||||
log.Fatal(4, "Fail to create '%s': %v", SSH.RootPath, err)
|
||||
} else if err = os.MkdirAll(SSH.KeyTestPath, 0644); err != nil {
|
||||
log.Fatal(4, "Fail to create '%s': %v", SSH.KeyTestPath, err)
|
||||
}
|
||||
|
||||
if !filepath.IsAbs(SSH.KeygenPath) {
|
||||
if _, err := exec.LookPath(SSH.KeygenPath); err != nil {
|
||||
log.Fatal(4, "Fail to test '%s' command: %v (forgotten install?)", SSH.KeygenPath, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SSH.MinimumKeySizeCheck = sec.Key("MINIMUM_KEY_SIZE_CHECK").MustBool()
|
||||
SSH.MinimumKeySizes = map[string]int{}
|
||||
minimumKeySizes := Cfg.Section("ssh.minimum_key_sizes").Keys()
|
||||
for _, key := range minimumKeySizes {
|
||||
if key.MustInt() != -1 {
|
||||
SSH.MinimumKeySizes[strings.ToLower(key.Name())] = key.MustInt()
|
||||
}
|
||||
}
|
||||
|
||||
sec = Cfg.Section("security")
|
||||
InstallLock = sec.Key("INSTALL_LOCK").MustBool()
|
||||
SecretKey = sec.Key("SECRET_KEY").String()
|
||||
@@ -411,7 +447,6 @@ func NewContext() {
|
||||
ThemeColorMetaTag = sec.Key("THEME_COLOR_META_TAG").MustString("#ff5343")
|
||||
|
||||
sec = Cfg.Section("picture")
|
||||
PictureService = sec.Key("SERVICE").In("server", []string{"server"})
|
||||
AvatarUploadPath = sec.Key("AVATAR_UPLOAD_PATH").MustString(path.Join(AppDataPath, "avatars"))
|
||||
forcePathSeparator(AvatarUploadPath)
|
||||
if !filepath.IsAbs(AvatarUploadPath) {
|
||||
|
||||
@@ -22,86 +22,88 @@ import (
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
var Funcs template.FuncMap = map[string]interface{}{
|
||||
"GoVer": func() string {
|
||||
return strings.Title(runtime.Version())
|
||||
},
|
||||
"UseHTTPS": func() bool {
|
||||
return strings.HasPrefix(setting.AppUrl, "https")
|
||||
},
|
||||
"AppName": func() string {
|
||||
return setting.AppName
|
||||
},
|
||||
"AppSubUrl": func() string {
|
||||
return setting.AppSubUrl
|
||||
},
|
||||
"AppUrl": func() string {
|
||||
return setting.AppUrl
|
||||
},
|
||||
"AppVer": func() string {
|
||||
return setting.AppVer
|
||||
},
|
||||
"AppDomain": func() string {
|
||||
return setting.Domain
|
||||
},
|
||||
"DisableGravatar": func() bool {
|
||||
return setting.DisableGravatar
|
||||
},
|
||||
"LoadTimes": func(startTime time.Time) string {
|
||||
return fmt.Sprint(time.Since(startTime).Nanoseconds()/1e6) + "ms"
|
||||
},
|
||||
"AvatarLink": base.AvatarLink,
|
||||
"Safe": Safe,
|
||||
"Str2html": Str2html,
|
||||
"TimeSince": base.TimeSince,
|
||||
"RawTimeSince": base.RawTimeSince,
|
||||
"FileSize": base.FileSize,
|
||||
"Subtract": base.Subtract,
|
||||
"Add": func(a, b int) int {
|
||||
return a + b
|
||||
},
|
||||
"ActionIcon": ActionIcon,
|
||||
"DateFmtLong": func(t time.Time) string {
|
||||
return t.Format(time.RFC1123Z)
|
||||
},
|
||||
"DateFmtShort": func(t time.Time) string {
|
||||
return t.Format("Jan 02, 2006")
|
||||
},
|
||||
"List": List,
|
||||
"Mail2Domain": func(mail string) string {
|
||||
if !strings.Contains(mail, "@") {
|
||||
return "try.gogs.io"
|
||||
}
|
||||
func NewFuncMap() []template.FuncMap {
|
||||
return []template.FuncMap{map[string]interface{}{
|
||||
"GoVer": func() string {
|
||||
return strings.Title(runtime.Version())
|
||||
},
|
||||
"UseHTTPS": func() bool {
|
||||
return strings.HasPrefix(setting.AppUrl, "https")
|
||||
},
|
||||
"AppName": func() string {
|
||||
return setting.AppName
|
||||
},
|
||||
"AppSubUrl": func() string {
|
||||
return setting.AppSubUrl
|
||||
},
|
||||
"AppUrl": func() string {
|
||||
return setting.AppUrl
|
||||
},
|
||||
"AppVer": func() string {
|
||||
return setting.AppVer
|
||||
},
|
||||
"AppDomain": func() string {
|
||||
return setting.Domain
|
||||
},
|
||||
"DisableGravatar": func() bool {
|
||||
return setting.DisableGravatar
|
||||
},
|
||||
"LoadTimes": func(startTime time.Time) string {
|
||||
return fmt.Sprint(time.Since(startTime).Nanoseconds()/1e6) + "ms"
|
||||
},
|
||||
"AvatarLink": base.AvatarLink,
|
||||
"Safe": Safe,
|
||||
"Str2html": Str2html,
|
||||
"TimeSince": base.TimeSince,
|
||||
"RawTimeSince": base.RawTimeSince,
|
||||
"FileSize": base.FileSize,
|
||||
"Subtract": base.Subtract,
|
||||
"Add": func(a, b int) int {
|
||||
return a + b
|
||||
},
|
||||
"ActionIcon": ActionIcon,
|
||||
"DateFmtLong": func(t time.Time) string {
|
||||
return t.Format(time.RFC1123Z)
|
||||
},
|
||||
"DateFmtShort": func(t time.Time) string {
|
||||
return t.Format("Jan 02, 2006")
|
||||
},
|
||||
"List": List,
|
||||
"Mail2Domain": func(mail string) string {
|
||||
if !strings.Contains(mail, "@") {
|
||||
return "try.gogs.io"
|
||||
}
|
||||
|
||||
return strings.SplitN(mail, "@", 2)[1]
|
||||
},
|
||||
"SubStr": func(str string, start, length int) string {
|
||||
if len(str) == 0 {
|
||||
return ""
|
||||
}
|
||||
end := start + length
|
||||
if length == -1 {
|
||||
end = len(str)
|
||||
}
|
||||
if len(str) < end {
|
||||
return str
|
||||
}
|
||||
return str[start:end]
|
||||
},
|
||||
"DiffTypeToStr": DiffTypeToStr,
|
||||
"DiffLineTypeToStr": DiffLineTypeToStr,
|
||||
"Sha1": Sha1,
|
||||
"ShortSha": base.ShortSha,
|
||||
"MD5": base.EncodeMD5,
|
||||
"ActionContent2Commits": ActionContent2Commits,
|
||||
"ToUtf8": ToUtf8,
|
||||
"EscapePound": func(str string) string {
|
||||
return strings.Replace(strings.Replace(str, "%", "%25", -1), "#", "%23", -1)
|
||||
},
|
||||
"RenderCommitMessage": RenderCommitMessage,
|
||||
"ThemeColorMetaTag": func() string {
|
||||
return setting.ThemeColorMetaTag
|
||||
},
|
||||
return strings.SplitN(mail, "@", 2)[1]
|
||||
},
|
||||
"SubStr": func(str string, start, length int) string {
|
||||
if len(str) == 0 {
|
||||
return ""
|
||||
}
|
||||
end := start + length
|
||||
if length == -1 {
|
||||
end = len(str)
|
||||
}
|
||||
if len(str) < end {
|
||||
return str
|
||||
}
|
||||
return str[start:end]
|
||||
},
|
||||
"DiffTypeToStr": DiffTypeToStr,
|
||||
"DiffLineTypeToStr": DiffLineTypeToStr,
|
||||
"Sha1": Sha1,
|
||||
"ShortSha": base.ShortSha,
|
||||
"MD5": base.EncodeMD5,
|
||||
"ActionContent2Commits": ActionContent2Commits,
|
||||
"ToUtf8": ToUtf8,
|
||||
"EscapePound": func(str string) string {
|
||||
return strings.Replace(strings.Replace(str, "%", "%25", -1), "#", "%23", -1)
|
||||
},
|
||||
"RenderCommitMessage": RenderCommitMessage,
|
||||
"ThemeColorMetaTag": func() string {
|
||||
return setting.ThemeColorMetaTag
|
||||
},
|
||||
}}
|
||||
}
|
||||
|
||||
func Safe(raw string) template.HTML {
|
||||
@@ -233,7 +235,7 @@ func ActionIcon(opType int) string {
|
||||
return "repo"
|
||||
case 5, 9: // Commit repository
|
||||
return "git-commit"
|
||||
case 6, 13: // Create and reopen issue
|
||||
case 6: // Create issue
|
||||
return "issue-opened"
|
||||
case 7: // New pull request
|
||||
return "git-pull-request"
|
||||
@@ -241,8 +243,10 @@ func ActionIcon(opType int) string {
|
||||
return "comment"
|
||||
case 11: // Merge pull request
|
||||
return "git-merge"
|
||||
case 12: // Close issue
|
||||
case 12, 14: // Close issue or pull request
|
||||
return "issue-closed"
|
||||
case 13, 15: // Reopen issue or pull request
|
||||
return "issue-reopened"
|
||||
default:
|
||||
return "invalid type"
|
||||
}
|
||||
|
||||
@@ -20,15 +20,6 @@
|
||||
"outputPathIsOutsideProject": 0,
|
||||
"outputPathIsSetByUser": 0
|
||||
},
|
||||
"\/css\/gogs.min.css": {
|
||||
"fileType": 16,
|
||||
"ignore": 1,
|
||||
"ignoreWasSetByUser": 0,
|
||||
"inputAbbreviatedPath": "\/css\/gogs.min.css",
|
||||
"outputAbbreviatedPath": "No Output Path",
|
||||
"outputPathIsOutsideProject": 0,
|
||||
"outputPathIsSetByUser": 0
|
||||
},
|
||||
"\/css\/semantic-2.1.8.min.css": {
|
||||
"fileType": 16,
|
||||
"ignore": 0,
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
background-size: contain;
|
||||
}
|
||||
body {
|
||||
font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif, '微软雅黑';
|
||||
font-family: "Helvetica Neue", "Microsoft YaHei", Arial, Helvetica, sans-serif !important;
|
||||
background-color: #fff;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
@@ -104,6 +104,9 @@ code.wrap {
|
||||
.ui.container.fluid.padded {
|
||||
padding: 0 10px 0 10px;
|
||||
}
|
||||
.ui.form .ui.button {
|
||||
font-weight: normal;
|
||||
}
|
||||
.ui .text.red {
|
||||
color: #d95c5c !important;
|
||||
}
|
||||
@@ -234,6 +237,10 @@ code.wrap {
|
||||
.ui.status.buttons .octicon {
|
||||
margin-right: 4px;
|
||||
}
|
||||
.ui.inline.delete-button {
|
||||
padding: 8px 15px;
|
||||
font-weight: normal;
|
||||
}
|
||||
.overflow.menu .items {
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
@@ -395,30 +402,30 @@ footer .container .links > *:first-child {
|
||||
background: inherit !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
.markdown {
|
||||
.markdown:not(code) {
|
||||
overflow: hidden;
|
||||
font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.6 !important;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.markdown.file-view {
|
||||
.markdown:not(code).file-view {
|
||||
padding: 2em 2em 2em !important;
|
||||
}
|
||||
.markdown > *:first-child {
|
||||
.markdown:not(code) > *:first-child {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
.markdown > *:last-child {
|
||||
.markdown:not(code) > *:last-child {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
.markdown a:not([href]) {
|
||||
.markdown:not(code) a:not([href]) {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
.markdown .absent {
|
||||
.markdown:not(code) .absent {
|
||||
color: #c00;
|
||||
}
|
||||
.markdown .anchor {
|
||||
.markdown:not(code) .anchor {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
@@ -427,217 +434,217 @@ footer .container .links > *:first-child {
|
||||
padding-left: 30px;
|
||||
margin-left: -30px;
|
||||
}
|
||||
.markdown .anchor:focus {
|
||||
.markdown:not(code) .anchor:focus {
|
||||
outline: none;
|
||||
}
|
||||
.markdown h1,
|
||||
.markdown h2,
|
||||
.markdown h3,
|
||||
.markdown h4,
|
||||
.markdown h5,
|
||||
.markdown h6 {
|
||||
.markdown:not(code) h1,
|
||||
.markdown:not(code) h2,
|
||||
.markdown:not(code) h3,
|
||||
.markdown:not(code) h4,
|
||||
.markdown:not(code) h5,
|
||||
.markdown:not(code) h6 {
|
||||
position: relative;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 16px;
|
||||
font-weight: bold;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.markdown h1:first-of-type,
|
||||
.markdown h2:first-of-type,
|
||||
.markdown h3:first-of-type,
|
||||
.markdown h4:first-of-type,
|
||||
.markdown h5:first-of-type,
|
||||
.markdown h6:first-of-type {
|
||||
.markdown:not(code) h1:first-of-type,
|
||||
.markdown:not(code) h2:first-of-type,
|
||||
.markdown:not(code) h3:first-of-type,
|
||||
.markdown:not(code) h4:first-of-type,
|
||||
.markdown:not(code) h5:first-of-type,
|
||||
.markdown:not(code) h6:first-of-type {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
.markdown h1 .octicon-link,
|
||||
.markdown h2 .octicon-link,
|
||||
.markdown h3 .octicon-link,
|
||||
.markdown h4 .octicon-link,
|
||||
.markdown h5 .octicon-link,
|
||||
.markdown h6 .octicon-link {
|
||||
.markdown:not(code) h1 .octicon-link,
|
||||
.markdown:not(code) h2 .octicon-link,
|
||||
.markdown:not(code) h3 .octicon-link,
|
||||
.markdown:not(code) h4 .octicon-link,
|
||||
.markdown:not(code) h5 .octicon-link,
|
||||
.markdown:not(code) h6 .octicon-link {
|
||||
display: none;
|
||||
color: #000;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.markdown h1:hover .anchor,
|
||||
.markdown h2:hover .anchor,
|
||||
.markdown h3:hover .anchor,
|
||||
.markdown h4:hover .anchor,
|
||||
.markdown h5:hover .anchor,
|
||||
.markdown h6:hover .anchor {
|
||||
.markdown:not(code) h1:hover .anchor,
|
||||
.markdown:not(code) h2:hover .anchor,
|
||||
.markdown:not(code) h3:hover .anchor,
|
||||
.markdown:not(code) h4:hover .anchor,
|
||||
.markdown:not(code) h5:hover .anchor,
|
||||
.markdown:not(code) h6:hover .anchor {
|
||||
padding-left: 8px;
|
||||
margin-left: -30px;
|
||||
text-decoration: none;
|
||||
}
|
||||
.markdown h1:hover .anchor .octicon-link,
|
||||
.markdown h2:hover .anchor .octicon-link,
|
||||
.markdown h3:hover .anchor .octicon-link,
|
||||
.markdown h4:hover .anchor .octicon-link,
|
||||
.markdown h5:hover .anchor .octicon-link,
|
||||
.markdown h6:hover .anchor .octicon-link {
|
||||
.markdown:not(code) h1:hover .anchor .octicon-link,
|
||||
.markdown:not(code) h2:hover .anchor .octicon-link,
|
||||
.markdown:not(code) h3:hover .anchor .octicon-link,
|
||||
.markdown:not(code) h4:hover .anchor .octicon-link,
|
||||
.markdown:not(code) h5:hover .anchor .octicon-link,
|
||||
.markdown:not(code) h6:hover .anchor .octicon-link {
|
||||
display: inline-block;
|
||||
}
|
||||
.markdown h1 tt,
|
||||
.markdown h1 code,
|
||||
.markdown h2 tt,
|
||||
.markdown h2 code,
|
||||
.markdown h3 tt,
|
||||
.markdown h3 code,
|
||||
.markdown h4 tt,
|
||||
.markdown h4 code,
|
||||
.markdown h5 tt,
|
||||
.markdown h5 code,
|
||||
.markdown h6 tt,
|
||||
.markdown h6 code {
|
||||
.markdown:not(code) h1 tt,
|
||||
.markdown:not(code) h1 code,
|
||||
.markdown:not(code) h2 tt,
|
||||
.markdown:not(code) h2 code,
|
||||
.markdown:not(code) h3 tt,
|
||||
.markdown:not(code) h3 code,
|
||||
.markdown:not(code) h4 tt,
|
||||
.markdown:not(code) h4 code,
|
||||
.markdown:not(code) h5 tt,
|
||||
.markdown:not(code) h5 code,
|
||||
.markdown:not(code) h6 tt,
|
||||
.markdown:not(code) h6 code {
|
||||
font-size: inherit;
|
||||
}
|
||||
.markdown h1 {
|
||||
.markdown:not(code) h1 {
|
||||
padding-bottom: 0.3em;
|
||||
font-size: 2.25em;
|
||||
line-height: 1.2;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
.markdown h1 .anchor {
|
||||
.markdown:not(code) h1 .anchor {
|
||||
line-height: 1;
|
||||
}
|
||||
.markdown h2 {
|
||||
.markdown:not(code) h2 {
|
||||
padding-bottom: 0.3em;
|
||||
font-size: 1.75em;
|
||||
line-height: 1.225;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
.markdown h2 .anchor {
|
||||
.markdown:not(code) h2 .anchor {
|
||||
line-height: 1;
|
||||
}
|
||||
.markdown h3 {
|
||||
.markdown:not(code) h3 {
|
||||
font-size: 1.5em;
|
||||
line-height: 1.43;
|
||||
}
|
||||
.markdown h3 .anchor {
|
||||
.markdown:not(code) h3 .anchor {
|
||||
line-height: 1.2;
|
||||
}
|
||||
.markdown h4 {
|
||||
.markdown:not(code) h4 {
|
||||
font-size: 1.25em;
|
||||
}
|
||||
.markdown h4 .anchor {
|
||||
.markdown:not(code) h4 .anchor {
|
||||
line-height: 1.2;
|
||||
}
|
||||
.markdown h5 {
|
||||
.markdown:not(code) h5 {
|
||||
font-size: 1em;
|
||||
}
|
||||
.markdown h5 .anchor {
|
||||
.markdown:not(code) h5 .anchor {
|
||||
line-height: 1.1;
|
||||
}
|
||||
.markdown h6 {
|
||||
.markdown:not(code) h6 {
|
||||
font-size: 1em;
|
||||
color: #777;
|
||||
}
|
||||
.markdown h6 .anchor {
|
||||
.markdown:not(code) h6 .anchor {
|
||||
line-height: 1.1;
|
||||
}
|
||||
.markdown p,
|
||||
.markdown blockquote,
|
||||
.markdown ul,
|
||||
.markdown ol,
|
||||
.markdown dl,
|
||||
.markdown table,
|
||||
.markdown pre {
|
||||
.markdown:not(code) p,
|
||||
.markdown:not(code) blockquote,
|
||||
.markdown:not(code) ul,
|
||||
.markdown:not(code) ol,
|
||||
.markdown:not(code) dl,
|
||||
.markdown:not(code) table,
|
||||
.markdown:not(code) pre {
|
||||
margin-top: 0;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.markdown blockquote {
|
||||
.markdown:not(code) blockquote {
|
||||
margin-left: 0;
|
||||
}
|
||||
.markdown hr {
|
||||
.markdown:not(code) hr {
|
||||
height: 4px;
|
||||
padding: 0;
|
||||
margin: 16px 0;
|
||||
background-color: #e7e7e7;
|
||||
border: 0 none;
|
||||
}
|
||||
.markdown ul,
|
||||
.markdown ol {
|
||||
.markdown:not(code) ul,
|
||||
.markdown:not(code) ol {
|
||||
padding-left: 2em;
|
||||
}
|
||||
.markdown ul.no-list,
|
||||
.markdown ol.no-list {
|
||||
.markdown:not(code) ul.no-list,
|
||||
.markdown:not(code) ol.no-list {
|
||||
padding: 0;
|
||||
list-style-type: none;
|
||||
}
|
||||
.markdown ul ul,
|
||||
.markdown ul ol,
|
||||
.markdown ol ol,
|
||||
.markdown ol ul {
|
||||
.markdown:not(code) ul ul,
|
||||
.markdown:not(code) ul ol,
|
||||
.markdown:not(code) ol ol,
|
||||
.markdown:not(code) ol ul {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.markdown ol ol,
|
||||
.markdown ul ol {
|
||||
.markdown:not(code) ol ol,
|
||||
.markdown:not(code) ul ol {
|
||||
list-style-type: lower-roman;
|
||||
}
|
||||
.markdown li > p {
|
||||
.markdown:not(code) li > p {
|
||||
margin-top: 16px;
|
||||
}
|
||||
.markdown dl {
|
||||
.markdown:not(code) dl {
|
||||
padding: 0;
|
||||
}
|
||||
.markdown dl dt {
|
||||
.markdown:not(code) dl dt {
|
||||
padding: 0;
|
||||
margin-top: 16px;
|
||||
font-size: 1em;
|
||||
font-style: italic;
|
||||
font-weight: bold;
|
||||
}
|
||||
.markdown dl dd {
|
||||
.markdown:not(code) dl dd {
|
||||
padding: 0 16px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.markdown blockquote {
|
||||
.markdown:not(code) blockquote {
|
||||
padding: 0 15px;
|
||||
color: #777;
|
||||
border-left: 4px solid #ddd;
|
||||
}
|
||||
.markdown blockquote > :first-child {
|
||||
.markdown:not(code) blockquote > :first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
.markdown blockquote > :last-child {
|
||||
.markdown:not(code) blockquote > :last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.markdown table {
|
||||
.markdown:not(code) table {
|
||||
display: block;
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
word-break: normal;
|
||||
word-break: keep-all;
|
||||
}
|
||||
.markdown table th {
|
||||
.markdown:not(code) table th {
|
||||
font-weight: bold;
|
||||
}
|
||||
.markdown table th,
|
||||
.markdown table td {
|
||||
.markdown:not(code) table th,
|
||||
.markdown:not(code) table td {
|
||||
padding: 6px 13px !important;
|
||||
border: 1px solid #ddd !important;
|
||||
}
|
||||
.markdown table tr {
|
||||
.markdown:not(code) table tr {
|
||||
background-color: #fff;
|
||||
border-top: 1px solid #ccc;
|
||||
}
|
||||
.markdown table tr:nth-child(2n) {
|
||||
.markdown:not(code) table tr:nth-child(2n) {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
.markdown img {
|
||||
.markdown:not(code) img {
|
||||
max-width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.markdown .emoji {
|
||||
.markdown:not(code) .emoji {
|
||||
max-width: none;
|
||||
}
|
||||
.markdown span.frame {
|
||||
.markdown:not(code) span.frame {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
}
|
||||
.markdown span.frame > span {
|
||||
.markdown:not(code) span.frame > span {
|
||||
display: block;
|
||||
float: left;
|
||||
width: auto;
|
||||
@@ -646,69 +653,69 @@ footer .container .links > *:first-child {
|
||||
overflow: hidden;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
.markdown span.frame span img {
|
||||
.markdown:not(code) span.frame span img {
|
||||
display: block;
|
||||
float: left;
|
||||
}
|
||||
.markdown span.frame span span {
|
||||
.markdown:not(code) span.frame span span {
|
||||
display: block;
|
||||
padding: 5px 0 0;
|
||||
clear: both;
|
||||
color: #333;
|
||||
}
|
||||
.markdown span.align-center {
|
||||
.markdown:not(code) span.align-center {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
clear: both;
|
||||
}
|
||||
.markdown span.align-center > span {
|
||||
.markdown:not(code) span.align-center > span {
|
||||
display: block;
|
||||
margin: 13px auto 0;
|
||||
overflow: hidden;
|
||||
text-align: center;
|
||||
}
|
||||
.markdown span.align-center span img {
|
||||
.markdown:not(code) span.align-center span img {
|
||||
margin: 0 auto;
|
||||
text-align: center;
|
||||
}
|
||||
.markdown span.align-right {
|
||||
.markdown:not(code) span.align-right {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
clear: both;
|
||||
}
|
||||
.markdown span.align-right > span {
|
||||
.markdown:not(code) span.align-right > span {
|
||||
display: block;
|
||||
margin: 13px 0 0;
|
||||
overflow: hidden;
|
||||
text-align: right;
|
||||
}
|
||||
.markdown span.align-right span img {
|
||||
.markdown:not(code) span.align-right span img {
|
||||
margin: 0;
|
||||
text-align: right;
|
||||
}
|
||||
.markdown span.float-left {
|
||||
.markdown:not(code) span.float-left {
|
||||
display: block;
|
||||
float: left;
|
||||
margin-right: 13px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.markdown span.float-left span {
|
||||
.markdown:not(code) span.float-left span {
|
||||
margin: 13px 0 0;
|
||||
}
|
||||
.markdown span.float-right {
|
||||
.markdown:not(code) span.float-right {
|
||||
display: block;
|
||||
float: right;
|
||||
margin-left: 13px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.markdown span.float-right > span {
|
||||
.markdown:not(code) span.float-right > span {
|
||||
display: block;
|
||||
margin: 13px auto 0;
|
||||
overflow: hidden;
|
||||
text-align: right;
|
||||
}
|
||||
.markdown code,
|
||||
.markdown tt {
|
||||
.markdown:not(code) code,
|
||||
.markdown:not(code) tt {
|
||||
padding: 0;
|
||||
padding-top: 0.2em;
|
||||
padding-bottom: 0.2em;
|
||||
@@ -717,21 +724,21 @@ footer .container .links > *:first-child {
|
||||
background-color: rgba(0, 0, 0, 0.04);
|
||||
border-radius: 3px;
|
||||
}
|
||||
.markdown code:before,
|
||||
.markdown code:after,
|
||||
.markdown tt:before,
|
||||
.markdown tt:after {
|
||||
.markdown:not(code) code:before,
|
||||
.markdown:not(code) code:after,
|
||||
.markdown:not(code) tt:before,
|
||||
.markdown:not(code) tt:after {
|
||||
letter-spacing: -0.2em;
|
||||
content: "\00a0";
|
||||
}
|
||||
.markdown code br,
|
||||
.markdown tt br {
|
||||
.markdown:not(code) code br,
|
||||
.markdown:not(code) tt br {
|
||||
display: none;
|
||||
}
|
||||
.markdown del code {
|
||||
.markdown:not(code) del code {
|
||||
text-decoration: inherit;
|
||||
}
|
||||
.markdown pre > code {
|
||||
.markdown:not(code) pre > code {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-size: 100%;
|
||||
@@ -740,11 +747,11 @@ footer .container .links > *:first-child {
|
||||
background: transparent;
|
||||
border: 0;
|
||||
}
|
||||
.markdown .highlight {
|
||||
.markdown:not(code) .highlight {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.markdown .highlight pre,
|
||||
.markdown pre {
|
||||
.markdown:not(code) .highlight pre,
|
||||
.markdown:not(code) pre {
|
||||
padding: 16px;
|
||||
overflow: auto;
|
||||
font-size: 85%;
|
||||
@@ -752,15 +759,15 @@ footer .container .links > *:first-child {
|
||||
background-color: #f7f7f7;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.markdown .highlight pre {
|
||||
.markdown:not(code) .highlight pre {
|
||||
margin-bottom: 0;
|
||||
word-break: normal;
|
||||
}
|
||||
.markdown pre {
|
||||
.markdown:not(code) pre {
|
||||
word-wrap: normal;
|
||||
}
|
||||
.markdown pre code,
|
||||
.markdown pre tt {
|
||||
.markdown:not(code) pre code,
|
||||
.markdown:not(code) pre tt {
|
||||
display: inline;
|
||||
max-width: initial;
|
||||
padding: 0;
|
||||
@@ -771,13 +778,13 @@ footer .container .links > *:first-child {
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
}
|
||||
.markdown pre code:before,
|
||||
.markdown pre code:after,
|
||||
.markdown pre tt:before,
|
||||
.markdown pre tt:after {
|
||||
.markdown:not(code) pre code:before,
|
||||
.markdown:not(code) pre code:after,
|
||||
.markdown:not(code) pre tt:before,
|
||||
.markdown:not(code) pre tt:after {
|
||||
content: normal;
|
||||
}
|
||||
.markdown kbd {
|
||||
.markdown:not(code) kbd {
|
||||
display: inline-block;
|
||||
padding: 3px 5px;
|
||||
font-size: 11px;
|
||||
@@ -790,11 +797,11 @@ footer .container .links > *:first-child {
|
||||
border-radius: 3px;
|
||||
box-shadow: inset 0 -1px 0 #bbb;
|
||||
}
|
||||
.markdown input[type="checkbox"] {
|
||||
.markdown:not(code) input[type="checkbox"] {
|
||||
vertical-align: middle !important;
|
||||
}
|
||||
.markdown .csv-data td,
|
||||
.markdown .csv-data th {
|
||||
.markdown:not(code) .csv-data td,
|
||||
.markdown:not(code) .csv-data th {
|
||||
padding: 5px;
|
||||
overflow: hidden;
|
||||
font-size: 12px;
|
||||
@@ -802,16 +809,16 @@ footer .container .links > *:first-child {
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.markdown .csv-data .blob-num {
|
||||
.markdown:not(code) .csv-data .blob-num {
|
||||
padding: 10px 8px 9px;
|
||||
text-align: right;
|
||||
background: #fff;
|
||||
border: 0;
|
||||
}
|
||||
.markdown .csv-data tr {
|
||||
.markdown:not(code) .csv-data tr {
|
||||
border-top: 0;
|
||||
}
|
||||
.markdown .csv-data th {
|
||||
.markdown:not(code) .csv-data th {
|
||||
font-weight: bold;
|
||||
background: #f8f8f8;
|
||||
border-top: 0;
|
||||
@@ -1460,8 +1467,33 @@ footer .container .links > *:first-child {
|
||||
.repository.view.issue .comment-list .comment .content > .bottom.segment {
|
||||
background: #f3f4f5;
|
||||
}
|
||||
.repository.view.issue .comment-list .comment .content > .bottom.segment .ui.images::after {
|
||||
clear: both;
|
||||
content: ' ';
|
||||
display: block;
|
||||
}
|
||||
.repository.view.issue .comment-list .comment .content > .bottom.segment a {
|
||||
display: block;
|
||||
float: left;
|
||||
margin: 5px;
|
||||
padding: 5px;
|
||||
height: 150px;
|
||||
border: solid 1px #eee;
|
||||
border-radius: 3px;
|
||||
max-width: 150px;
|
||||
background-color: #fff;
|
||||
}
|
||||
.repository.view.issue .comment-list .comment .content > .bottom.segment a:before {
|
||||
content: ' ';
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.repository.view.issue .comment-list .comment .content > .bottom.segment .ui.image {
|
||||
max-height: 150px;
|
||||
max-height: 100%;
|
||||
width: auto;
|
||||
margin: 0;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.repository.view.issue .comment-list .comment .ui.form .field:first-child {
|
||||
clear: none;
|
||||
@@ -1576,6 +1608,9 @@ footer .container .links > *:first-child {
|
||||
.repository .label.list .item a.open-issues {
|
||||
margin-right: 30px;
|
||||
}
|
||||
.repository .label.list .item .ui.label {
|
||||
font-size: 1em;
|
||||
}
|
||||
.repository .milestone.list {
|
||||
list-style: none;
|
||||
padding-top: 15px;
|
||||
@@ -1956,10 +1991,11 @@ footer .container .links > *:first-child {
|
||||
.repository.settings.collaboration .collaborator.list {
|
||||
padding: 0;
|
||||
}
|
||||
.repository.settings.collaboration .collaborator.list .item {
|
||||
padding: 10px 20px;
|
||||
.repository.settings.collaboration .collaborator.list > .item {
|
||||
margin: 0;
|
||||
line-height: 2em;
|
||||
}
|
||||
.repository.settings.collaboration .collaborator.list .item:not(:last-child) {
|
||||
.repository.settings.collaboration .collaborator.list > .item:not(:last-child) {
|
||||
border-bottom: 1px solid #DDD;
|
||||
}
|
||||
.repository.settings.collaboration #repo-collab-form #search-user-box .results {
|
||||
@@ -2551,6 +2587,9 @@ footer .container .links > *:first-child {
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.admin.config #test-mail-btn {
|
||||
margin-left: 5px;
|
||||
}
|
||||
.explore {
|
||||
padding-top: 15px;
|
||||
padding-bottom: 80px;
|
||||
|
||||
1
public/css/gogs.min.css
vendored
1
public/css/gogs.min.css
vendored
File diff suppressed because one or more lines are too long
@@ -18,7 +18,7 @@ function initCommentPreviewTab($form) {
|
||||
var $preview_tab = $form.find('.tab.segment[data-tab="' + $tab_menu.data('preview') + '"]');
|
||||
$preview_tab.html(data);
|
||||
emojify.run($preview_tab[0]);
|
||||
$('pre code', $preview_tab[0]).each(function(i, block) {
|
||||
$('pre code', $preview_tab[0]).each(function (i, block) {
|
||||
hljs.highlightBlock(block);
|
||||
});
|
||||
}
|
||||
@@ -322,8 +322,7 @@ function initRepository() {
|
||||
};
|
||||
$('#edit-title').click(editTitleToggle);
|
||||
$('#cancel-edit-title').click(editTitleToggle);
|
||||
$('#save-edit-title').click(editTitleToggle).
|
||||
click(function () {
|
||||
$('#save-edit-title').click(editTitleToggle).click(function () {
|
||||
if ($edit_input.val().length == 0 ||
|
||||
$edit_input.val() == $issue_title.text()) {
|
||||
$edit_input.val($issue_title.text());
|
||||
@@ -385,7 +384,7 @@ function initRepository() {
|
||||
} else {
|
||||
$render_content.html(data.content);
|
||||
emojify.run($render_content[0]);
|
||||
$('pre code', $render_content[0]).each(function(i, block) {
|
||||
$('pre code', $render_content[0]).each(function (i, block) {
|
||||
hljs.highlightBlock(block);
|
||||
});
|
||||
}
|
||||
@@ -459,6 +458,20 @@ function initRepository() {
|
||||
}
|
||||
}
|
||||
|
||||
function initRepositoryCollaboration(){
|
||||
console.log('initRepositoryCollaboration');
|
||||
|
||||
// Change collaborator access mode
|
||||
$('.access-mode.menu .item').click(function(){
|
||||
var $menu = $(this).parent();
|
||||
$.post($menu.data('url'), {
|
||||
"_csrf": csrf,
|
||||
"uid": $menu.data('uid'),
|
||||
"mode": $(this).data('value')
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
function initWiki() {
|
||||
if ($('.repository.wiki').length == 0) {
|
||||
return;
|
||||
@@ -521,10 +534,8 @@ function initOrganization() {
|
||||
}
|
||||
}
|
||||
|
||||
function initUser() {
|
||||
if ($('.user').length == 0) {
|
||||
return;
|
||||
}
|
||||
function initUserSettings() {
|
||||
console.log('initUserSettings');
|
||||
|
||||
// Options
|
||||
if ($('.user.settings.profile').length > 0) {
|
||||
@@ -796,10 +807,7 @@ $(document).ready(function () {
|
||||
|
||||
// Show exact time
|
||||
$('.time-since').each(function () {
|
||||
$(this).addClass('poping up').
|
||||
attr('data-content', $(this).attr('title')).
|
||||
attr('data-variation', 'inverted tiny').
|
||||
attr('title', '');
|
||||
$(this).addClass('poping up').attr('data-content', $(this).attr('title')).attr('data-variation', 'inverted tiny').attr('title', '');
|
||||
});
|
||||
|
||||
// Semantic UI modules.
|
||||
@@ -878,7 +886,10 @@ $(document).ready(function () {
|
||||
img_dir: suburl + '/img/emoji',
|
||||
ignore_emoticons: true
|
||||
});
|
||||
emojify.run();
|
||||
var hasEmoji = document.getElementsByClassName('has-emoji');
|
||||
for (var i = 0; i < hasEmoji.length; i++) {
|
||||
emojify.run(hasEmoji[i]);
|
||||
}
|
||||
|
||||
// Clipboard JS
|
||||
var clipboard = new Clipboard('.clipboard');
|
||||
@@ -925,6 +936,14 @@ $(document).ready(function () {
|
||||
$('.show-modal.button').click(function () {
|
||||
$($(this).data('modal')).modal('show');
|
||||
});
|
||||
$('.delete-post.button').click(function(){
|
||||
var $this = $(this);
|
||||
$.post($this.data('request-url'),{
|
||||
"_csrf": csrf
|
||||
}).done(function(){
|
||||
window.location.href = $this.data('done-url');
|
||||
});
|
||||
});
|
||||
|
||||
// Set anchor.
|
||||
$('.markdown').each(function () {
|
||||
@@ -950,15 +969,26 @@ $(document).ready(function () {
|
||||
searchUsers();
|
||||
searchRepositories();
|
||||
|
||||
|
||||
initCommentForm();
|
||||
initInstall();
|
||||
initRepository();
|
||||
initWiki();
|
||||
initOrganization();
|
||||
initUser();
|
||||
initWebhook();
|
||||
initAdmin();
|
||||
|
||||
var routes = {
|
||||
'div.user.settings': initUserSettings,
|
||||
'div.repository.settings.collaboration': initRepositoryCollaboration
|
||||
};
|
||||
|
||||
var selector;
|
||||
for (selector in routes) {
|
||||
if ($(selector).length > 0) {
|
||||
routes[selector]();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$(window).load(function () {
|
||||
@@ -1050,11 +1080,12 @@ $(window).load(function () {
|
||||
case 'ssh':
|
||||
if ($('#repo-clone-ssh').click().length === 0) {
|
||||
$('#repo-clone-https').click();
|
||||
};
|
||||
}
|
||||
;
|
||||
break;
|
||||
default:
|
||||
$('#repo-clone-https').click();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -44,7 +44,7 @@
|
||||
padding: 20px;
|
||||
margin: 0;
|
||||
|
||||
dd{
|
||||
dd {
|
||||
margin-left: 240px;
|
||||
}
|
||||
dt {
|
||||
@@ -57,4 +57,10 @@
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
&.config {
|
||||
#test-mail-btn {
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@footer-margin: 40px;
|
||||
|
||||
body {
|
||||
font-family: 'Helvetica Neue',Arial,Helvetica,sans-serif,'微软雅黑';
|
||||
font-family: "Helvetica Neue", "Microsoft YaHei", Arial, Helvetica, sans-serif !important;
|
||||
background-color: #fff;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
@@ -109,6 +109,12 @@ pre, code {
|
||||
}
|
||||
}
|
||||
|
||||
&.form {
|
||||
.ui.button {
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.text {
|
||||
&.red {
|
||||
color: #d95c5c !important;
|
||||
@@ -260,6 +266,11 @@ pre, code {
|
||||
margin-right: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
&.inline.delete-button {
|
||||
padding: 8px 15px;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.overflow.menu {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.markdown {
|
||||
.markdown:not(code) {
|
||||
overflow: hidden;
|
||||
font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif;
|
||||
font-size: 16px;
|
||||
|
||||
@@ -413,8 +413,33 @@
|
||||
}
|
||||
> .bottom.segment {
|
||||
background: #f3f4f5;
|
||||
.ui.images::after {
|
||||
clear: both;
|
||||
content: ' ';
|
||||
display: block;
|
||||
}
|
||||
a {
|
||||
display: block;
|
||||
float: left;
|
||||
margin: 5px;
|
||||
padding: 5px;
|
||||
height: 150px;
|
||||
border: solid 1px #eee;
|
||||
border-radius: 3px;
|
||||
max-width: 150px;
|
||||
background-color: #fff;
|
||||
&:before {
|
||||
content:' ';
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
.ui.image {
|
||||
max-height: 150px;
|
||||
max-height: 100%;
|
||||
width: auto;
|
||||
margin: 0;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -528,6 +553,9 @@
|
||||
margin-right: 30px;
|
||||
}
|
||||
}
|
||||
.ui.label {
|
||||
font-size: 1em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -998,8 +1026,9 @@
|
||||
.collaborator.list {
|
||||
padding: 0;
|
||||
|
||||
.item {
|
||||
padding: 10px 20px;
|
||||
>.item {
|
||||
margin: 0;
|
||||
line-height: 2em;
|
||||
|
||||
&:not(:last-child) {
|
||||
border-bottom: 1px solid #DDD;
|
||||
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
"github.com/gogits/gogs/models"
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/gogits/gogs/modules/cron"
|
||||
"github.com/gogits/gogs/modules/mailer"
|
||||
"github.com/gogits/gogs/modules/middleware"
|
||||
"github.com/gogits/gogs/modules/process"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
@@ -174,6 +175,18 @@ func Dashboard(ctx *middleware.Context) {
|
||||
ctx.HTML(200, DASHBOARD)
|
||||
}
|
||||
|
||||
func SendTestMail(ctx *middleware.Context) {
|
||||
email := ctx.Query("email")
|
||||
// Send a test email to the user's email address and redirect back to Config
|
||||
if err := mailer.SendTestMail(email); err != nil {
|
||||
ctx.Flash.Error(ctx.Tr("admin.config.test_mail_failed", email, err))
|
||||
} else {
|
||||
ctx.Flash.Info(ctx.Tr("admin.config.test_mail_sent", email))
|
||||
}
|
||||
|
||||
ctx.Redirect(setting.AppSubUrl + "/admin/config")
|
||||
}
|
||||
|
||||
func Config(ctx *middleware.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("admin.config")
|
||||
ctx.Data["PageIsAdmin"] = true
|
||||
@@ -191,6 +204,8 @@ func Config(ctx *middleware.Context) {
|
||||
ctx.Data["ScriptType"] = setting.ScriptType
|
||||
ctx.Data["ReverseProxyAuthUser"] = setting.ReverseProxyAuthUser
|
||||
|
||||
ctx.Data["SSH"] = setting.SSH
|
||||
|
||||
ctx.Data["Service"] = setting.Service
|
||||
ctx.Data["DbCfg"] = models.DbCfg
|
||||
ctx.Data["Webhook"] = setting.Webhook
|
||||
@@ -207,7 +222,6 @@ func Config(ctx *middleware.Context) {
|
||||
|
||||
ctx.Data["SessionConfig"] = setting.SessionConfig
|
||||
|
||||
ctx.Data["PictureService"] = setting.PictureService
|
||||
ctx.Data["DisableGravatar"] = setting.DisableGravatar
|
||||
|
||||
type logger struct {
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/Unknwon/com"
|
||||
"github.com/go-xorm/core"
|
||||
|
||||
@@ -218,11 +220,13 @@ func DeleteAuthSource(ctx *middleware.Context) {
|
||||
if err = models.DeleteSource(source); err != nil {
|
||||
switch err {
|
||||
case models.ErrAuthenticationUserUsed:
|
||||
ctx.Flash.Error("form.still_own_user")
|
||||
ctx.Redirect(setting.AppSubUrl + "/admin/auths/" + ctx.Params(":authid"))
|
||||
ctx.Flash.Error(ctx.Tr("admin.auths.still_in_used"))
|
||||
default:
|
||||
ctx.Handle(500, "DeleteSource", err)
|
||||
ctx.Flash.Error(fmt.Sprintf("DeleteSource: %v", err))
|
||||
}
|
||||
ctx.JSON(200, map[string]interface{}{
|
||||
"redirect": setting.AppSubUrl + "/admin/auths/" + ctx.Params(":authid"),
|
||||
})
|
||||
return
|
||||
}
|
||||
log.Trace("Authentication deleted by admin(%s): %d", ctx.User.Name, source.ID)
|
||||
|
||||
@@ -88,9 +88,9 @@ func GlobalInit() {
|
||||
}
|
||||
checkRunMode()
|
||||
|
||||
if setting.StartSSHServer {
|
||||
ssh.Listen(setting.SSHPort)
|
||||
log.Info("SSH server started on :%v", setting.SSHPort)
|
||||
if setting.SSH.StartBuiltinServer {
|
||||
ssh.Listen(setting.SSH.ListenPort)
|
||||
log.Info("SSH server started on :%v", setting.SSH.ListenPort)
|
||||
}
|
||||
|
||||
// Build Sanitizer
|
||||
@@ -152,7 +152,7 @@ func Install(ctx *middleware.Context) {
|
||||
}
|
||||
|
||||
form.Domain = setting.Domain
|
||||
form.SSHPort = setting.SSHPort
|
||||
form.SSHPort = setting.SSH.Port
|
||||
form.HTTPPort = setting.HttpPort
|
||||
form.AppUrl = setting.AppUrl
|
||||
form.LogRootPath = setting.LogRootPath
|
||||
|
||||
@@ -96,6 +96,14 @@ func SettingsAvatar(ctx *middleware.Context, form auth.UploadAvatarForm) {
|
||||
ctx.Redirect(ctx.Org.OrgLink + "/settings")
|
||||
}
|
||||
|
||||
func SettingsDeleteAvatar(ctx *middleware.Context) {
|
||||
if err := ctx.Org.Organization.DeleteAvatar(); err != nil {
|
||||
ctx.Flash.Error(err.Error())
|
||||
}
|
||||
|
||||
ctx.Redirect(ctx.Org.OrgLink + "/settings")
|
||||
}
|
||||
|
||||
func SettingsDelete(ctx *middleware.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("org.settings")
|
||||
ctx.Data["PageIsSettingsDelete"] = true
|
||||
|
||||
@@ -273,7 +273,7 @@ func RetrieveRepoMilestonesAndAssignees(ctx *middleware.Context, repo *models.Re
|
||||
}
|
||||
|
||||
func RetrieveRepoMetas(ctx *middleware.Context, repo *models.Repository) []*models.Label {
|
||||
if !ctx.Repo.IsAdmin() {
|
||||
if !ctx.Repo.IsWriter() {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -356,7 +356,7 @@ func ValidateRepoMetas(ctx *middleware.Context, form auth.CreateIssueForm) ([]in
|
||||
return nil, 0, 0
|
||||
}
|
||||
|
||||
if !ctx.Repo.IsAdmin() {
|
||||
if !ctx.Repo.IsWriter() {
|
||||
return nil, 0, 0
|
||||
}
|
||||
|
||||
@@ -624,7 +624,7 @@ func ViewIssue(ctx *middleware.Context) {
|
||||
ctx.Data["Labels"] = labels
|
||||
|
||||
// Check milestone and assignee.
|
||||
if ctx.Repo.IsAdmin() {
|
||||
if ctx.Repo.IsWriter() {
|
||||
RetrieveRepoMilestonesAndAssignees(ctx, repo)
|
||||
if ctx.Written() {
|
||||
return
|
||||
@@ -664,8 +664,8 @@ func ViewIssue(ctx *middleware.Context) {
|
||||
if repo.IsOwnedBy(comment.PosterID) ||
|
||||
(repo.Owner.IsOrganization() && repo.Owner.IsOwnedBy(comment.PosterID)) {
|
||||
comment.ShowTag = models.COMMENT_TAG_OWNER
|
||||
} else if comment.Poster.IsAdminOfRepo(repo) {
|
||||
comment.ShowTag = models.COMMENT_TAG_ADMIN
|
||||
} else if comment.Poster.IsWriterOfRepo(repo) {
|
||||
comment.ShowTag = models.COMMENT_TAG_WRITER
|
||||
} else if comment.PosterID == issue.PosterID {
|
||||
comment.ShowTag = models.COMMENT_TAG_POSTER
|
||||
}
|
||||
@@ -688,7 +688,7 @@ func ViewIssue(ctx *middleware.Context) {
|
||||
ctx.Data["Participants"] = participants
|
||||
ctx.Data["NumParticipants"] = len(participants)
|
||||
ctx.Data["Issue"] = issue
|
||||
ctx.Data["IsIssueOwner"] = ctx.Repo.IsAdmin() || (ctx.IsSigned && issue.IsPoster(ctx.User.Id))
|
||||
ctx.Data["IsIssueOwner"] = ctx.Repo.IsWriter() || (ctx.IsSigned && (issue.IsPoster(ctx.User.Id) || ctx.User.IsAdmin))
|
||||
ctx.Data["SignInLink"] = setting.AppSubUrl + "/user/login"
|
||||
|
||||
ctx.Data["RequireHighlightJS"] = true
|
||||
@@ -715,7 +715,7 @@ func UpdateIssueTitle(ctx *middleware.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if !ctx.IsSigned || (ctx.User.Id != issue.PosterID && !ctx.Repo.IsAdmin()) {
|
||||
if !ctx.IsSigned || (ctx.User.Id != issue.PosterID && !ctx.Repo.IsWriter() && !ctx.User.IsAdmin) {
|
||||
ctx.Error(403)
|
||||
return
|
||||
}
|
||||
@@ -742,7 +742,7 @@ func UpdateIssueContent(ctx *middleware.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if !ctx.IsSigned || (ctx.User.Id != issue.PosterID && !ctx.Repo.IsAdmin()) {
|
||||
if !ctx.IsSigned || (ctx.User.Id != issue.PosterID && !ctx.Repo.IsWriter() && !ctx.User.IsAdmin) {
|
||||
ctx.Error(403)
|
||||
return
|
||||
}
|
||||
@@ -883,7 +883,7 @@ func NewComment(ctx *middleware.Context, form auth.CreateCommentForm) {
|
||||
var comment *models.Comment
|
||||
defer func() {
|
||||
// Check if issue admin/poster changes the status of issue.
|
||||
if (ctx.Repo.IsAdmin() || (ctx.IsSigned && issue.IsPoster(ctx.User.Id))) &&
|
||||
if (ctx.Repo.IsWriter() || (ctx.IsSigned && issue.IsPoster(ctx.User.Id))) &&
|
||||
(form.Status == "reopen" || form.Status == "close") &&
|
||||
!(issue.IsPull && issue.HasMerged) {
|
||||
|
||||
@@ -914,8 +914,7 @@ func NewComment(ctx *middleware.Context, form auth.CreateCommentForm) {
|
||||
if pr != nil {
|
||||
ctx.Flash.Info(ctx.Tr("repo.pulls.open_unmerged_pull_exists", pr.Index))
|
||||
} else {
|
||||
issue.Repo = ctx.Repo.Repository
|
||||
if err = issue.ChangeStatus(ctx.User, form.Status == "close"); err != nil {
|
||||
if err = issue.ChangeStatus(ctx.User, ctx.Repo.Repository, form.Status == "close"); err != nil {
|
||||
log.Error(4, "ChangeStatus: %v", err)
|
||||
} else {
|
||||
log.Trace("Issue [%d] status changed to closed: %v", issue.ID, issue.IsClosed)
|
||||
|
||||
@@ -414,9 +414,15 @@ func MergePullRequest(ctx *middleware.Context) {
|
||||
}
|
||||
|
||||
func ParseCompareInfo(ctx *middleware.Context) (*models.User, *models.Repository, *git.Repository, *git.PullRequestInfo, string, string) {
|
||||
// Get compare branch information.
|
||||
baseRepo := ctx.Repo.Repository
|
||||
|
||||
// Get compared branches information
|
||||
// format: <base branch>...[<head repo>:]<head branch>
|
||||
// base<-head: master...head:feature
|
||||
// same repo: master...feature
|
||||
infos := strings.Split(ctx.Params("*"), "...")
|
||||
if len(infos) != 2 {
|
||||
log.Trace("ParseCompareInfo[%d]: not enough compared branches information %s", baseRepo.ID, infos)
|
||||
ctx.Handle(404, "CompareAndPullRequest", nil)
|
||||
return nil, nil, nil, nil, "", ""
|
||||
}
|
||||
@@ -424,27 +430,39 @@ func ParseCompareInfo(ctx *middleware.Context) (*models.User, *models.Repository
|
||||
baseBranch := infos[0]
|
||||
ctx.Data["BaseBranch"] = baseBranch
|
||||
|
||||
var (
|
||||
headUser *models.User
|
||||
headBranch string
|
||||
isSameRepo bool
|
||||
err error
|
||||
)
|
||||
|
||||
// If there is no head repository, it means pull request between same repository.
|
||||
headInfos := strings.Split(infos[1], ":")
|
||||
if len(headInfos) != 2 {
|
||||
if len(headInfos) == 1 {
|
||||
isSameRepo = true
|
||||
headUser = ctx.Repo.Owner
|
||||
headBranch = headInfos[0]
|
||||
|
||||
} else if len(headInfos) == 2 {
|
||||
headUser, err = models.GetUserByName(headInfos[0])
|
||||
if err != nil {
|
||||
if models.IsErrUserNotExist(err) {
|
||||
ctx.Handle(404, "GetUserByName", nil)
|
||||
} else {
|
||||
ctx.Handle(500, "GetUserByName", err)
|
||||
}
|
||||
return nil, nil, nil, nil, "", ""
|
||||
}
|
||||
headBranch = headInfos[1]
|
||||
|
||||
} else {
|
||||
ctx.Handle(404, "CompareAndPullRequest", nil)
|
||||
return nil, nil, nil, nil, "", ""
|
||||
}
|
||||
headUsername := headInfos[0]
|
||||
headBranch := headInfos[1]
|
||||
ctx.Data["HeadBranch"] = headBranch
|
||||
|
||||
headUser, err := models.GetUserByName(headUsername)
|
||||
if err != nil {
|
||||
if models.IsErrUserNotExist(err) {
|
||||
ctx.Handle(404, "GetUserByName", nil)
|
||||
} else {
|
||||
ctx.Handle(500, "GetUserByName", err)
|
||||
}
|
||||
return nil, nil, nil, nil, "", ""
|
||||
}
|
||||
ctx.Data["HeadUser"] = headUser
|
||||
|
||||
repo := ctx.Repo.Repository
|
||||
ctx.Data["HeadBranch"] = headBranch
|
||||
ctx.Data["IsBetweenBranches"] = isSameRepo
|
||||
|
||||
// Check if base branch is valid.
|
||||
if !ctx.Repo.GitRepo.IsBranchExist(baseBranch) {
|
||||
@@ -452,16 +470,29 @@ func ParseCompareInfo(ctx *middleware.Context) (*models.User, *models.Repository
|
||||
return nil, nil, nil, nil, "", ""
|
||||
}
|
||||
|
||||
// Check if current user has fork of repository.
|
||||
headRepo, has := models.HasForkedRepo(headUser.Id, repo.ID)
|
||||
if !has || (!ctx.User.IsAdminOfRepo(headRepo) && !ctx.User.IsAdmin) {
|
||||
ctx.Handle(404, "HasForkedRepo", nil)
|
||||
// Check if current user has fork of repository or in the same repository.
|
||||
headRepo, has := models.HasForkedRepo(headUser.Id, baseRepo.ID)
|
||||
if !has && !isSameRepo {
|
||||
log.Trace("ParseCompareInfo[%d]: does not have fork or in same repository", baseRepo.ID)
|
||||
ctx.Handle(404, "ParseCompareInfo", nil)
|
||||
return nil, nil, nil, nil, "", ""
|
||||
}
|
||||
|
||||
headGitRepo, err := git.OpenRepository(models.RepoPath(headUser.Name, headRepo.Name))
|
||||
if err != nil {
|
||||
ctx.Handle(500, "OpenRepository", err)
|
||||
var headGitRepo *git.Repository
|
||||
if isSameRepo {
|
||||
headRepo = ctx.Repo.Repository
|
||||
headGitRepo = ctx.Repo.GitRepo
|
||||
} else {
|
||||
headGitRepo, err = git.OpenRepository(models.RepoPath(headUser.Name, headRepo.Name))
|
||||
if err != nil {
|
||||
ctx.Handle(500, "OpenRepository", err)
|
||||
return nil, nil, nil, nil, "", ""
|
||||
}
|
||||
}
|
||||
|
||||
if !ctx.User.IsWriterOfRepo(headRepo) && !ctx.User.IsAdmin {
|
||||
log.Trace("ParseCompareInfo[%d]: does not have write access or site admin", baseRepo.ID)
|
||||
ctx.Handle(404, "ParseCompareInfo", nil)
|
||||
return nil, nil, nil, nil, "", ""
|
||||
}
|
||||
|
||||
@@ -478,7 +509,7 @@ func ParseCompareInfo(ctx *middleware.Context) (*models.User, *models.Repository
|
||||
}
|
||||
ctx.Data["HeadBranches"] = headBranches
|
||||
|
||||
prInfo, err := headGitRepo.GetPullRequestInfo(models.RepoPath(repo.Owner.Name, repo.Name), baseBranch, headBranch)
|
||||
prInfo, err := headGitRepo.GetPullRequestInfo(models.RepoPath(baseRepo.Owner.Name, baseRepo.Name), baseBranch, headBranch)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "GetPullRequestInfo", err)
|
||||
return nil, nil, nil, nil, "", ""
|
||||
@@ -623,7 +654,7 @@ func CompareAndPullRequestPost(ctx *middleware.Context, form auth.CreateIssueFor
|
||||
return
|
||||
}
|
||||
|
||||
pull := &models.Issue{
|
||||
pullIssue := &models.Issue{
|
||||
RepoID: repo.ID,
|
||||
Index: repo.NextIssueIndex(),
|
||||
Name: form.Title,
|
||||
@@ -634,26 +665,32 @@ func CompareAndPullRequestPost(ctx *middleware.Context, form auth.CreateIssueFor
|
||||
IsPull: true,
|
||||
Content: form.Content,
|
||||
}
|
||||
if err := models.NewPullRequest(repo, pull, labelIDs, attachments, &models.PullRequest{
|
||||
pullRequest := &models.PullRequest{
|
||||
HeadRepoID: headRepo.ID,
|
||||
BaseRepoID: repo.ID,
|
||||
HeadUserName: headUser.Name,
|
||||
HeadBranch: headBranch,
|
||||
BaseBranch: baseBranch,
|
||||
HeadRepo: headRepo,
|
||||
BaseRepo: repo,
|
||||
MergeBase: prInfo.MergeBase,
|
||||
Type: models.PULL_REQUEST_GOGS,
|
||||
}, patch); err != nil {
|
||||
}
|
||||
if err := models.NewPullRequest(repo, pullIssue, labelIDs, attachments, pullRequest, patch); err != nil {
|
||||
ctx.Handle(500, "NewPullRequest", err)
|
||||
return
|
||||
} else if err := pullRequest.PushToBaseRepo(); err != nil {
|
||||
ctx.Handle(500, "PushToBaseRepo", err)
|
||||
return
|
||||
}
|
||||
|
||||
notifyWatchersAndMentions(ctx, pull)
|
||||
notifyWatchersAndMentions(ctx, pullIssue)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
|
||||
log.Trace("Pull request created: %d/%d", repo.ID, pull.ID)
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + com.ToStr(pull.Index))
|
||||
log.Trace("Pull request created: %d/%d", repo.ID, pullIssue.ID)
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + com.ToStr(pullIssue.Index))
|
||||
}
|
||||
|
||||
func TriggerTask(ctx *middleware.Context) {
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gogits/gogs/models"
|
||||
"github.com/gogits/gogs/modules/auth"
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
@@ -18,6 +20,29 @@ const (
|
||||
RELEASE_NEW base.TplName = "repo/release/new"
|
||||
)
|
||||
|
||||
// calReleaseNumCommitsBehind calculates given release has how many commits behind default branch.
|
||||
func calReleaseNumCommitsBehind(repoCtx *middleware.RepoContext, release *models.Release, countCache map[string]int64) error {
|
||||
// Fast return if release target is same as default branch.
|
||||
if repoCtx.BranchName == release.Target {
|
||||
release.NumCommitsBehind = repoCtx.CommitsCount - release.NumCommits
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get count if not exists
|
||||
if _, ok := countCache[release.Target]; !ok {
|
||||
commit, err := repoCtx.GitRepo.GetBranchCommit(repoCtx.BranchName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("GetBranchCommit: %v", err)
|
||||
}
|
||||
countCache[repoCtx.BranchName], err = commit.CommitsCount()
|
||||
if err != nil {
|
||||
return fmt.Errorf("CommitsCount: %v", err)
|
||||
}
|
||||
}
|
||||
release.NumCommitsBehind = countCache[repoCtx.BranchName] - release.NumCommits
|
||||
return nil
|
||||
}
|
||||
|
||||
func Releases(ctx *middleware.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("repo.release.releases")
|
||||
ctx.Data["PageIsReleaseList"] = true
|
||||
@@ -28,7 +53,7 @@ func Releases(ctx *middleware.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
rels, err := models.GetReleasesByRepoID(ctx.Repo.Repository.ID)
|
||||
releases, err := models.GetReleasesByRepoID(ctx.Repo.Repository.ID)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "GetReleasesByRepoID", err)
|
||||
return
|
||||
@@ -39,44 +64,29 @@ func Releases(ctx *middleware.Context) {
|
||||
|
||||
tags := make([]*models.Release, len(rawTags))
|
||||
for i, rawTag := range rawTags {
|
||||
for j, rel := range rels {
|
||||
if rel == nil || (rel.IsDraft && !ctx.Repo.IsOwner()) {
|
||||
for j, r := range releases {
|
||||
if r == nil || (r.IsDraft && !ctx.Repo.IsOwner()) {
|
||||
continue
|
||||
}
|
||||
if rel.TagName == rawTag {
|
||||
rel.Publisher, err = models.GetUserByID(rel.PublisherID)
|
||||
if r.TagName == rawTag {
|
||||
r.Publisher, err = models.GetUserByID(r.PublisherID)
|
||||
if err != nil {
|
||||
if models.IsErrUserNotExist(err) {
|
||||
rel.Publisher = models.NewFakeUser()
|
||||
r.Publisher = models.NewFakeUser()
|
||||
} else {
|
||||
ctx.Handle(500, "GetUserByID", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
// FIXME: duplicated code.
|
||||
// Get corresponding target if it's not the current branch.
|
||||
if ctx.Repo.BranchName != rel.Target {
|
||||
// Get count if not exists.
|
||||
if _, ok := countCache[rel.Target]; !ok {
|
||||
commit, err := ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.BranchName)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "GetBranchCommit", err)
|
||||
return
|
||||
}
|
||||
countCache[ctx.Repo.BranchName], err = commit.CommitsCount()
|
||||
if err != nil {
|
||||
ctx.Handle(500, "CommitsCount", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
rel.NumCommitsBehind = countCache[ctx.Repo.BranchName] - rel.NumCommits
|
||||
} else {
|
||||
rel.NumCommitsBehind = ctx.Repo.CommitsCount - rel.NumCommits
|
||||
|
||||
if err := calReleaseNumCommitsBehind(ctx.Repo, r, countCache); err != nil {
|
||||
ctx.Handle(500, "calReleaseNumCommitsBehind", err)
|
||||
return
|
||||
}
|
||||
|
||||
rel.Note = markdown.RenderString(rel.Note, ctx.Repo.RepoLink, ctx.Repo.Repository.ComposeMetas())
|
||||
tags[i] = rel
|
||||
rels[j] = nil // Mark as used.
|
||||
r.Note = markdown.RenderString(r.Note, ctx.Repo.RepoLink, ctx.Repo.Repository.ComposeMetas())
|
||||
tags[i] = r
|
||||
releases[j] = nil // Mark as used.
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -103,43 +113,28 @@ func Releases(ctx *middleware.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
for _, rel := range rels {
|
||||
if rel == nil {
|
||||
for _, r := range releases {
|
||||
if r == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
rel.Publisher, err = models.GetUserByID(rel.PublisherID)
|
||||
r.Publisher, err = models.GetUserByID(r.PublisherID)
|
||||
if err != nil {
|
||||
if models.IsErrUserNotExist(err) {
|
||||
rel.Publisher = models.NewFakeUser()
|
||||
r.Publisher = models.NewFakeUser()
|
||||
} else {
|
||||
ctx.Handle(500, "GetUserByID", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
// FIXME: duplicated code.
|
||||
// Get corresponding target if it's not the current branch.
|
||||
if ctx.Repo.BranchName != rel.Target {
|
||||
// Get count if not exists.
|
||||
if _, ok := countCache[rel.Target]; !ok {
|
||||
commit, err := ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.BranchName)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "GetBranchCommit", err)
|
||||
return
|
||||
}
|
||||
countCache[ctx.Repo.BranchName], err = commit.CommitsCount()
|
||||
if err != nil {
|
||||
ctx.Handle(500, "CommitsCount", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
rel.NumCommitsBehind = countCache[ctx.Repo.BranchName] - rel.NumCommits
|
||||
} else {
|
||||
rel.NumCommitsBehind = ctx.Repo.CommitsCount - rel.NumCommits
|
||||
|
||||
if err := calReleaseNumCommitsBehind(ctx.Repo, r, countCache); err != nil {
|
||||
ctx.Handle(500, "calReleaseNumCommitsBehind", err)
|
||||
return
|
||||
}
|
||||
|
||||
rel.Note = markdown.RenderString(rel.Note, ctx.Repo.RepoLink, ctx.Repo.Repository.ComposeMetas())
|
||||
tags = append(tags, rel)
|
||||
r.Note = markdown.RenderString(r.Note, ctx.Repo.RepoLink, ctx.Repo.Repository.ComposeMetas())
|
||||
tags = append(tags, r)
|
||||
}
|
||||
models.SortReleases(tags)
|
||||
ctx.Data["Releases"] = tags
|
||||
|
||||
@@ -142,6 +142,10 @@ func SettingsPost(ctx *middleware.Context, form auth.RepoSettingForm) {
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
|
||||
|
||||
case "convert":
|
||||
if !ctx.Repo.IsOwner() {
|
||||
ctx.Error(404)
|
||||
return
|
||||
}
|
||||
if repo.Name != form.RepoName {
|
||||
ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_repo_name"), SETTINGS_OPTIONS, nil)
|
||||
return
|
||||
@@ -172,6 +176,10 @@ func SettingsPost(ctx *middleware.Context, form auth.RepoSettingForm) {
|
||||
ctx.Redirect(setting.AppSubUrl + "/" + ctx.Repo.Owner.Name + "/" + repo.Name)
|
||||
|
||||
case "transfer":
|
||||
if !ctx.Repo.IsOwner() {
|
||||
ctx.Error(404)
|
||||
return
|
||||
}
|
||||
if repo.Name != form.RepoName {
|
||||
ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_repo_name"), SETTINGS_OPTIONS, nil)
|
||||
return
|
||||
@@ -205,7 +213,12 @@ func SettingsPost(ctx *middleware.Context, form auth.RepoSettingForm) {
|
||||
log.Trace("Repository transfered: %s/%s -> %s", ctx.Repo.Owner.Name, repo.Name, newOwner)
|
||||
ctx.Flash.Success(ctx.Tr("repo.settings.transfer_succeed"))
|
||||
ctx.Redirect(setting.AppSubUrl + "/" + newOwner + "/" + repo.Name)
|
||||
|
||||
case "delete":
|
||||
if !ctx.Repo.IsOwner() {
|
||||
ctx.Error(404)
|
||||
return
|
||||
}
|
||||
if repo.Name != form.RepoName {
|
||||
ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_repo_name"), SETTINGS_OPTIONS, nil)
|
||||
return
|
||||
@@ -226,6 +239,35 @@ func SettingsPost(ctx *middleware.Context, form auth.RepoSettingForm) {
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("repo.settings.deletion_success"))
|
||||
ctx.Redirect(ctx.Repo.Owner.DashboardLink())
|
||||
|
||||
case "delete-wiki":
|
||||
if !ctx.Repo.IsOwner() {
|
||||
ctx.Error(404)
|
||||
return
|
||||
}
|
||||
if repo.Name != form.RepoName {
|
||||
ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_repo_name"), SETTINGS_OPTIONS, nil)
|
||||
return
|
||||
}
|
||||
|
||||
if ctx.Repo.Owner.IsOrganization() {
|
||||
if !ctx.Repo.Owner.IsOwnedBy(ctx.User.Id) {
|
||||
ctx.Error(404)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
repo.DeleteWiki()
|
||||
log.Trace("Repository wiki deleted: %s/%s", ctx.Repo.Owner.Name, repo.Name)
|
||||
|
||||
repo.EnableWiki = false
|
||||
if err := models.UpdateRepository(repo, false); err != nil {
|
||||
ctx.Handle(500, "UpdateRepository", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("repo.settings.wiki_deletion_success"))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,30 +275,13 @@ func Collaboration(ctx *middleware.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("repo.settings")
|
||||
ctx.Data["PageIsSettingsCollaboration"] = true
|
||||
|
||||
// Delete collaborator.
|
||||
remove := strings.ToLower(ctx.Query("remove"))
|
||||
if len(remove) > 0 && remove != ctx.Repo.Owner.LowerName {
|
||||
u, err := models.GetUserByName(remove)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "GetUserByName", err)
|
||||
return
|
||||
}
|
||||
if err := ctx.Repo.Repository.DeleteCollaborator(u); err != nil {
|
||||
ctx.Handle(500, "DeleteCollaborator", err)
|
||||
return
|
||||
}
|
||||
ctx.Flash.Success(ctx.Tr("repo.settings.remove_collaborator_success"))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/settings/collaboration")
|
||||
return
|
||||
}
|
||||
|
||||
users, err := ctx.Repo.Repository.GetCollaborators()
|
||||
if err != nil {
|
||||
ctx.Handle(500, "GetCollaborators", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Data["Collaborators"] = users
|
||||
|
||||
ctx.HTML(200, COLLABORATION)
|
||||
}
|
||||
|
||||
@@ -308,6 +333,26 @@ func CollaborationPost(ctx *middleware.Context) {
|
||||
ctx.Redirect(setting.AppSubUrl + ctx.Req.URL.Path)
|
||||
}
|
||||
|
||||
func ChangeCollaborationAccessMode(ctx *middleware.Context) {
|
||||
if err := ctx.Repo.Repository.ChangeCollaborationAccessMode(
|
||||
ctx.QueryInt64("uid"),
|
||||
models.AccessMode(ctx.QueryInt("mode"))); err != nil {
|
||||
log.Error(4, "ChangeCollaborationAccessMode: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func DeleteCollaboration(ctx *middleware.Context) {
|
||||
if err := ctx.Repo.Repository.DeleteCollaboration(ctx.QueryInt64("id")); err != nil {
|
||||
ctx.Flash.Error("DeleteCollaboration: " + err.Error())
|
||||
} else {
|
||||
ctx.Flash.Success(ctx.Tr("repo.settings.remove_collaborator_success"))
|
||||
}
|
||||
|
||||
ctx.JSON(200, map[string]interface{}{
|
||||
"redirect": ctx.Repo.RepoLink + "/settings/collaboration",
|
||||
})
|
||||
}
|
||||
|
||||
func parseOwnerAndRepo(ctx *middleware.Context) (*models.User, *models.Repository) {
|
||||
owner, err := models.GetUserByName(ctx.Params(":username"))
|
||||
if err != nil {
|
||||
|
||||
@@ -256,3 +256,20 @@ func EditWikiPost(ctx *middleware.Context, form auth.NewWikiForm) {
|
||||
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/wiki/" + models.ToWikiPageURL(form.Title))
|
||||
}
|
||||
|
||||
func DeleteWikiPagePost(ctx *middleware.Context) {
|
||||
pageURL := ctx.Params(":page")
|
||||
if len(pageURL) == 0 {
|
||||
pageURL = "Home"
|
||||
}
|
||||
|
||||
pageName := models.ToWikiPageName(pageURL)
|
||||
if err := ctx.Repo.Repository.DeleteWikiPage(ctx.User, pageName); err != nil {
|
||||
ctx.Handle(500, "DeleteWikiPage", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.JSON(200, map[string]interface{}{
|
||||
"redirect": ctx.Repo.RepoLink + "/wiki/",
|
||||
})
|
||||
}
|
||||
|
||||
@@ -39,12 +39,13 @@ func Settings(ctx *middleware.Context) {
|
||||
ctx.HTML(200, SETTINGS_PROFILE)
|
||||
}
|
||||
|
||||
func handlerUsernameChange(ctx *middleware.Context, newName string) {
|
||||
func handleUsernameChange(ctx *middleware.Context, newName string) {
|
||||
// Non-local users are not allowed to change their username.
|
||||
if len(newName) == 0 || !ctx.User.IsLocal() {
|
||||
return
|
||||
}
|
||||
|
||||
// Check if user name has been changed.
|
||||
// Check if user name has been changed
|
||||
if ctx.User.LowerName != strings.ToLower(newName) {
|
||||
if err := models.ChangeUserName(ctx.User, newName); err != nil {
|
||||
switch {
|
||||
@@ -67,7 +68,8 @@ func handlerUsernameChange(ctx *middleware.Context, newName string) {
|
||||
}
|
||||
log.Trace("User name changed: %s -> %s", ctx.User.Name, newName)
|
||||
}
|
||||
// In case it's just a case change.
|
||||
|
||||
// In case it's just a case change
|
||||
ctx.User.Name = newName
|
||||
ctx.User.LowerName = strings.ToLower(newName)
|
||||
}
|
||||
@@ -81,7 +83,7 @@ func SettingsPost(ctx *middleware.Context, form auth.UpdateProfileForm) {
|
||||
return
|
||||
}
|
||||
|
||||
handlerUsernameChange(ctx, form.Name)
|
||||
handleUsernameChange(ctx, form.Name)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
@@ -98,7 +100,8 @@ func SettingsPost(ctx *middleware.Context, form auth.UpdateProfileForm) {
|
||||
ctx.Handle(500, "UpdateUser", err)
|
||||
return
|
||||
}
|
||||
log.Trace("User setting updated: %s", ctx.User.Name)
|
||||
|
||||
log.Trace("User settings updated: %s", ctx.User.Name)
|
||||
ctx.Flash.Success(ctx.Tr("settings.update_profile_success"))
|
||||
ctx.Redirect(setting.AppSubUrl + "/user/settings")
|
||||
}
|
||||
@@ -112,10 +115,11 @@ func UpdateAvatarSetting(ctx *middleware.Context, form auth.UploadAvatarForm, ct
|
||||
if err != nil {
|
||||
return fmt.Errorf("Avatar.Open: %v", err)
|
||||
}
|
||||
defer fr.Close()
|
||||
|
||||
data, err := ioutil.ReadAll(fr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("ReadAll: %v", err)
|
||||
return fmt.Errorf("ioutil.ReadAll: %v", err)
|
||||
}
|
||||
if _, ok := base.IsImageFile(data); !ok {
|
||||
return errors.New(ctx.Tr("settings.uploaded_avatar_not_a_image"))
|
||||
@@ -124,9 +128,12 @@ func UpdateAvatarSetting(ctx *middleware.Context, form auth.UploadAvatarForm, ct
|
||||
return fmt.Errorf("UploadAvatar: %v", err)
|
||||
}
|
||||
} else {
|
||||
// In case no avatar at all.
|
||||
if form.Enable && !com.IsFile(ctx.User.CustomAvatarPath()) {
|
||||
return errors.New(ctx.Tr("settings.no_custom_avatar_available"))
|
||||
// No avatar is uploaded but setting has been changed to enable,
|
||||
// generate a random one when needed.
|
||||
if form.Enable && !com.IsFile(ctxUser.CustomAvatarPath()) {
|
||||
if err := ctxUser.GenerateRandomAvatar(); err != nil {
|
||||
log.Error(4, "GenerateRandomAvatar[%d]: %v", ctxUser.Id, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,6 +154,14 @@ func SettingsAvatar(ctx *middleware.Context, form auth.UploadAvatarForm) {
|
||||
ctx.Redirect(setting.AppSubUrl + "/user/settings")
|
||||
}
|
||||
|
||||
func SettingsDeleteAvatar(ctx *middleware.Context) {
|
||||
if err := ctx.User.DeleteAvatar(); err != nil {
|
||||
ctx.Flash.Error(err.Error())
|
||||
}
|
||||
|
||||
ctx.Redirect(setting.AppSubUrl + "/user/settings")
|
||||
}
|
||||
|
||||
func SettingsPassword(ctx *middleware.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("settings")
|
||||
ctx.Data["PageIsSettingsPassword"] = true
|
||||
|
||||
@@ -1 +1 @@
|
||||
0.8.43.0223
|
||||
0.9.0.0306
|
||||
@@ -1,5 +1,5 @@
|
||||
{{template "base/head" .}}
|
||||
<div class="admin monitor">
|
||||
<div class="admin config">
|
||||
<div class="ui container">
|
||||
<div class="ui grid">
|
||||
{{template "admin/navbar" .}}
|
||||
@@ -22,12 +22,16 @@
|
||||
<dd><i class="fa fa{{if .OfflineMode}}-check{{end}}-square-o"></i></dd>
|
||||
<dt>{{.i18n.Tr "admin.config.disable_router_log"}}</dt>
|
||||
<dd><i class="fa fa{{if .DisableRouterLog}}-check{{end}}-square-o"></i></dd>
|
||||
|
||||
<div class="ui divider"></div>
|
||||
|
||||
<dt>{{.i18n.Tr "admin.config.run_user"}}</dt>
|
||||
<dd>{{.RunUser}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.run_mode"}}</dt>
|
||||
<dd>{{.RunMode}}</dd>
|
||||
|
||||
<div class="ui divider"></div>
|
||||
|
||||
<dt>{{.i18n.Tr "admin.config.repo_root_path"}}</dt>
|
||||
<dd>{{.RepoRootPath}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.static_file_root_path"}}</dt>
|
||||
@@ -41,6 +45,41 @@
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<h4 class="ui top attached header">
|
||||
{{.i18n.Tr "admin.config.ssh_config"}}
|
||||
</h4>
|
||||
<div class="ui attached table segment">
|
||||
<dl class="dl-horizontal admin-dl-horizontal">
|
||||
<dt>{{.i18n.Tr "admin.config.ssh_enabled"}}</dt>
|
||||
<dd><i class="fa fa{{if not .SSH.Disabled}}-check{{end}}-square-o"></i></dd>
|
||||
{{if not .SSH.Disabled}}
|
||||
<dt>{{.i18n.Tr "admin.config.ssh_start_builtin_server"}}</dt>
|
||||
<dd><i class="fa fa{{if .SSH.StartBuiltinServer}}-check{{end}}-square-o"></i></dd>
|
||||
<dt>{{.i18n.Tr "admin.config.ssh_domain"}}</dt>
|
||||
<dd>{{.SSH.Domain}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.ssh_port"}}</dt>
|
||||
<dd>{{.SSH.Port}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.ssh_listen_port"}}</dt>
|
||||
<dd>{{.SSH.ListenPort}}</dd>
|
||||
|
||||
{{if not .SSH.StartBuiltinServer}}
|
||||
<dt>{{.i18n.Tr "admin.config.ssh_root_path"}}</dt>
|
||||
<dd>{{.SSH.RootPath}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.ssh_key_test_path"}}</dt>
|
||||
<dd>{{.SSH.KeyTestPath}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.ssh_keygen_path"}}</dt>
|
||||
<dd>{{.SSH.KeygenPath}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.ssh_minimum_key_size_check"}}</dt>
|
||||
<dd><i class="fa fa{{if .SSH.MinimumKeySizeCheck}}-check{{end}}-square-o"></i></dd>
|
||||
{{if .SSH.MinimumKeySizeCheck}}
|
||||
<dt>{{.i18n.Tr "admin.config.ssh_minimum_key_sizes"}}</dt>
|
||||
<dd>{{.SSH.MinimumKeySizes}}</dd>
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<h4 class="ui top attached header">
|
||||
{{.i18n.Tr "admin.config.db_config"}}
|
||||
</h4>
|
||||
@@ -109,14 +148,25 @@
|
||||
<dl class="dl-horizontal admin-dl-horizontal">
|
||||
<dt>{{.i18n.Tr "admin.config.mailer_enabled"}}</dt>
|
||||
<dd><i class="fa fa{{if .MailerEnabled}}-check{{end}}-square-o"></i></dd>
|
||||
{{if .MailerEnabled}}<dt>{{.i18n.Tr "admin.config.mailer_name"}}</dt>
|
||||
<dd>{{.Mailer.Name}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.mailer_disable_helo"}}</dt>
|
||||
<dd><i class="fa fa{{if .Mailer.DisableHelo}}-check{{end}}-square-o"></i></dd>
|
||||
<dt>{{.i18n.Tr "admin.config.mailer_host"}}</dt>
|
||||
<dd>{{.Mailer.Host}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.mailer_user"}}</dt>
|
||||
<dd>{{.Mailer.User}}</dd>{{end}}
|
||||
{{if .MailerEnabled}}
|
||||
<dt>{{.i18n.Tr "admin.config.mailer_name"}}</dt>
|
||||
<dd>{{.Mailer.Name}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.mailer_disable_helo"}}</dt>
|
||||
<dd><i class="fa fa{{if .Mailer.DisableHelo}}-check{{end}}-square-o"></i></dd>
|
||||
<dt>{{.i18n.Tr "admin.config.mailer_host"}}</dt>
|
||||
<dd>{{.Mailer.Host}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.mailer_user"}}</dt>
|
||||
<dd>{{.Mailer.User}}</dd><br>
|
||||
<form class="ui form" action="{{AppSubUrl}}/admin/config/test_mail" method="post">
|
||||
{{.CsrfTokenHtml}}
|
||||
<div class="inline field ui left">
|
||||
<div class="ui input">
|
||||
<input type="email" name="email" required>
|
||||
</div>
|
||||
</div>
|
||||
<button class="ui green button" id="test-mail-btn">{{.i18n.Tr "admin.config.send_test_mail"}}</button>
|
||||
</form>
|
||||
{{end}}
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
@@ -161,8 +211,6 @@
|
||||
</h4>
|
||||
<div class="ui attached table segment">
|
||||
<dl class="dl-horizontal admin-dl-horizontal">
|
||||
<dt>{{.i18n.Tr "admin.config.picture_service"}}</dt>
|
||||
<dd>{{.PictureService}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.disable_gravatar"}}</dt>
|
||||
<dd><i class="fa fa{{if .DisableGravatar}}-check{{end}}-square-o"></i></dd>
|
||||
</dl>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<span class="text grey"><i class="octicon octicon-git-branch"></i> {{.NumForks}}</span>
|
||||
</div>
|
||||
</div>
|
||||
{{if .Description}}<p>{{.Description}}</p>{{end}}
|
||||
{{if .Description}}<p class="has-emoji">{{.Description}}</p>{{end}}
|
||||
<p class="time">{{$.i18n.Tr "org.repo_updated"}} {{TimeSince .Updated $.i18n.Lang}}</p>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
@@ -201,6 +201,43 @@
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{{else if eq .Lang "ru-RU"}}
|
||||
<div class="ui stackable middle very relaxed page grid">
|
||||
<div class="eight wide center column">
|
||||
<h1 class="hero ui icon header">
|
||||
<i class="octicon octicon-flame"></i> Простой в установке
|
||||
</h1>
|
||||
<p class="large">
|
||||
Просто <a target="_blank" href="http://gogs.io/docs/installation/install_from_binary.html">запустите исполняемый файл</a> для вашей платформы. Изпользуйте Gogs с <a target="_blank" href="https://github.com/gogits/gogs/tree/master/docker">Docker</a> или <a target="_blank" href="https://github.com/geerlingguy/ansible-vagrant-examples/tree/master/gogs">Vagrant</a>, или загрузите <a target="_blank" href="http://gogs.io/docs/installation/install_from_packages.html">пакет</a>.
|
||||
</p>
|
||||
</div>
|
||||
<div class="eight wide center column">
|
||||
<h1 class="hero ui icon header">
|
||||
<i class="octicon octicon-device-desktop"></i> Кроссплатформенный
|
||||
</h1>
|
||||
<p class="large">
|
||||
Gogs работает на любой операционной системе, которая может компилировать <a target="_blank" href="http://golang.org/">Go</a>: Windows, Mac OS X, Linux, ARM и т. д. Выбирайте, что вам больше нравится!
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui stackable middle very relaxed page grid">
|
||||
<div class="eight wide center column">
|
||||
<h1 class="hero ui icon header">
|
||||
<i class="octicon octicon-rocket"></i> Легковесный
|
||||
</h1>
|
||||
<p class="large">
|
||||
Gogs имеет низкие системные требования и может работать на недорогом Raspberry Pi. Экономьте энергию вашей машины!
|
||||
</p>
|
||||
</div>
|
||||
<div class="eight wide center column">
|
||||
<h1 class="hero ui icon header">
|
||||
<i class="octicon octicon-code"></i> Открытый исходный код
|
||||
</h1>
|
||||
<p class="large">
|
||||
Всё это на <a target="_blank" href="https://github.com/gogits/gogs/">GitHub</a>! Присоединяйтесь к нам, внося вклад, чтобы сделать этот проект еще лучше. Не бойтесь помогать!
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="ui stackable middle very relaxed page grid">
|
||||
<div class="eight wide center column">
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
|
||||
<div class="field">
|
||||
<button class="ui green button">{{$.i18n.Tr "settings.update_avatar"}}</button>
|
||||
<a class="ui red button delete-post" data-request-url="{{.Link}}/avatar/delete" data-done-url="{{.Link}}">{{$.i18n.Tr "settings.delete_current_avatar"}}</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
<img class="ui avatar image" src="{{AvatarLink .Author.Email}}" alt=""/> {{.Author.Name}}
|
||||
{{end}}
|
||||
</td>
|
||||
<td class="message collapsing">
|
||||
<td class="message collapsing has-emoji">
|
||||
<a rel="nofollow" class="ui sha label" href="{{AppSubUrl}}/{{$.Username}}/{{$.Reponame}}/commit/{{.ID}}">{{ShortSha .ID.String}}</a>
|
||||
{{RenderCommitMessage false .Summary $.RepoLink $.Repository.ComposeMetas}}
|
||||
</td>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<div class="divider"> / </div>
|
||||
<a href="{{$.RepoLink}}">{{.Name}}</a>
|
||||
{{if .IsMirror}}<div class="fork-flag">{{$.i18n.Tr "repo.mirror_from"}} <a target="_blank" href="{{$.Mirror.Address}}">{{$.Mirror.Address}}</a></div>{{end}}
|
||||
{{if .IsFork}}<div class="fork-flag">{{$.i18n.Tr "repo.forked_from"}} <a href="{{.BaseRepo.RepoLink}}">{{SubStr .BaseRepo.RepoLink 1 -1}}</a></div>{{end}}
|
||||
{{if .IsFork}}<div class="fork-flag">{{$.i18n.Tr "repo.forked_from"}} <a href="{{.BaseRepo.RepoLink}}">{{SubStr .BaseRepo.RepoRelLink 1 -1}}</a></div>{{end}}
|
||||
</div>
|
||||
|
||||
<div class="ui right">
|
||||
@@ -86,4 +86,4 @@
|
||||
{{else}}
|
||||
<div class="ui divider"></div>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,14 +3,13 @@
|
||||
{{template "repo/header" .}}
|
||||
<div class="ui container">
|
||||
<p id="repo-desc">
|
||||
{{if .Repository.DescriptionHtml}}<span class="description">{{.Repository.DescriptionHtml}}</span>{{else}}<span class="no-description text-italic">{{.i18n.Tr "repo.no_desc"}}</span>{{end}}
|
||||
{{if .Repository.DescriptionHtml}}<span class="description has-emoji">{{.Repository.DescriptionHtml}}</span>{{else}}<span class="no-description text-italic">{{.i18n.Tr "repo.no_desc"}}</span>{{end}}
|
||||
<a class="link" href="{{.Repository.Website}}">{{.Repository.Website}}</a>
|
||||
</p>
|
||||
<div class="ui secondary menu">
|
||||
{{if .CanPullRequest}}
|
||||
<div class="fitted item">
|
||||
{{ $baseRepo := .Repository.BaseRepo}}
|
||||
<a href="{{AppSubUrl}}/{{$baseRepo.Owner.Name}}/{{$baseRepo.Name}}/compare/{{$.BaseDefaultBranch}}...{{$.Owner.Name}}:{{$.BranchName}}">
|
||||
<a href="{{.BaseRepo.RepoLink}}/compare/{{.BaseRepo.DefaultBranch}}...{{if not .IsBetweenBranches}}{{$.Owner.Name}}:{{end}}{{$.BranchName}}">
|
||||
<button class="ui green small button"><i class="octicon octicon-git-compare"></i></button>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<div class="ui container">
|
||||
<div class="navbar">
|
||||
{{template "repo/issue/navbar" .}}
|
||||
{{if .IsRepositoryAdmin}}
|
||||
{{if .IsRepositoryWriter}}
|
||||
<div class="ui right">
|
||||
<div class="ui green new-label button">{{.i18n.Tr "repo.issues.new_label"}}</div>
|
||||
</div>
|
||||
@@ -39,8 +39,8 @@
|
||||
<div class="label list">
|
||||
{{range .Labels}}
|
||||
<li class="item">
|
||||
<div class="ui label" style="background-color: {{.Color}}"><i class="octicon octicon-tag"></i> {{.Name}}</div>
|
||||
{{if $.IsRepositoryAdmin}}
|
||||
<div class="ui label" style="color: {{.ForegroundColor}}; background-color: {{.Color}}"><i class="octicon octicon-tag"></i> {{.Name}}</div>
|
||||
{{if $.IsRepositoryWriter}}
|
||||
<a class="ui right delete-button" href="#" data-url="{{$.RepoLink}}/labels/delete" data-id="{{.ID}}"><i class="octicon octicon-trashcan"></i> {{$.i18n.Tr "repo.issues.label_delete"}}</a>
|
||||
<a class="ui right edit-label-button" href="#" data-id={{.ID}} data-title={{.Name}} data-color={{.Color}}><i class="octicon octicon-pencil"></i> {{$.i18n.Tr "repo.issues.label_edit"}}</a>
|
||||
{{end}}
|
||||
@@ -51,7 +51,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{if .IsRepositoryAdmin}}
|
||||
{{if .IsRepositoryWriter}}
|
||||
<div class="ui small basic delete modal">
|
||||
<div class="ui icon header">
|
||||
<i class="trash icon"></i>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
{{if .PageIsIssueList}}
|
||||
<a class="ui green button" href="{{.RepoLink}}/issues/new">{{.i18n.Tr "repo.issues.new"}}</a>
|
||||
{{else}}
|
||||
<a class="ui green button {{if not .HasForkedRepo}}disabled{{end}}" href="{{.RepoLink}}/compare/{{.BranchName}}...{{.SignedUserName}}:{{.BranchName}}">{{.i18n.Tr "repo.pulls.new"}}</a>
|
||||
<a class="ui green button {{if not (or .CanPullRequest .HasForkedRepo)}}disabled{{end}}" href="{{.RepoLink}}/compare/{{.Repository.DefaultBranch}}...{{if not (eq .Owner.Name .SignedUserName)}}{{.SignedUserName}}:{{end}}{{.BranchName}}">{{.i18n.Tr "repo.pulls.new"}}</a>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
@@ -102,10 +102,10 @@
|
||||
{{ $timeStr:= TimeSince .Created $.Lang }}
|
||||
<li class="item">
|
||||
<div class="ui {{if .IsRead}}black{{else}}green{{end}} label">#{{.Index}}</div>
|
||||
<a class="title" href="{{$.Link}}/{{.Index}}">{{.Name}}</a>
|
||||
<a class="title has-emoji" href="{{$.Link}}/{{.Index}}">{{.Name}}</a>
|
||||
|
||||
{{range .Labels}}
|
||||
<a class="ui label" href="{{$.Link}}?type={{$.ViewType}}&state={{$.State}}&labels={{.ID}}&milestone={{$.MilestoneID}}&assignee={{$.AssigneeID}}" style="background-color: {{.Color}}">{{.Name}}</a>
|
||||
<a class="ui label" href="{{$.Link}}?type={{$.ViewType}}&state={{$.State}}&labels={{.ID}}&milestone={{$.MilestoneID}}&assignee={{$.AssigneeID}}" style="color: {{.ForegroundColor}}; background-color: {{.Color}}">{{.Name}}</a>
|
||||
{{end}}
|
||||
|
||||
{{if .NumComments}}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<div class="ui container">
|
||||
<div class="navbar">
|
||||
{{template "repo/issue/navbar" .}}
|
||||
{{if and .IsRepositoryAdmin .PageIsEditMilestone}}
|
||||
{{if and .IsRepositoryWriter .PageIsEditMilestone}}
|
||||
<div class="ui right floated secondary menu">
|
||||
<a class="ui green button" href="{{$.RepoLink}}/milestones/new">{{.i18n.Tr "repo.milestones.new"}}</a>
|
||||
</div>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<div class="ui container">
|
||||
<div class="navbar">
|
||||
{{template "repo/issue/navbar" .}}
|
||||
{{if .IsRepositoryAdmin}}
|
||||
{{if .IsRepositoryWriter}}
|
||||
<div class="ui right">
|
||||
<a class="ui green button" href="{{$.Link}}/new">{{.i18n.Tr "repo.milestones.new"}}</a>
|
||||
</div>
|
||||
@@ -49,7 +49,7 @@
|
||||
<i class="octicon octicon-issue-closed"></i> {{$.i18n.Tr "repo.issues.close_tab" .NumClosedIssues}}
|
||||
</span>
|
||||
</div>
|
||||
{{if $.IsRepositoryAdmin}}
|
||||
{{if $.IsRepositoryWriter}}
|
||||
<div class="ui right operate">
|
||||
<a href="{{$.Link}}/{{.ID}}/edit" data-id={{.ID}} data-title={{.Name}}><i class="octicon octicon-pencil"></i> {{$.i18n.Tr "repo.issues.label_edit"}}</a>
|
||||
{{if .IsClosed}}
|
||||
@@ -93,7 +93,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{if .IsRepositoryAdmin}}
|
||||
{{if .IsRepositoryWriter}}
|
||||
<div class="ui small basic delete modal">
|
||||
<div class="ui icon header">
|
||||
<i class="trash icon"></i>
|
||||
|
||||
@@ -16,11 +16,13 @@
|
||||
{{if .Issue.IsPull}}
|
||||
{{template "repo/issue/view_title" .}}
|
||||
{{template "repo/pulls/tab_menu" .}}
|
||||
<div class="ui bottom attached tab pull segment active" data-tab="request-{{.ID}}">
|
||||
<div class="ui bottom attached tab pull segment active has-emoji" data-tab="request-{{.ID}}">
|
||||
{{template "repo/issue/view_content" .}}
|
||||
</div>
|
||||
{{else}}
|
||||
{{template "repo/issue/view_content" .}}
|
||||
<div class="has-emoji">
|
||||
{{template "repo/issue/view_content" .}}
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
{{if eq .ShowTag 1}}
|
||||
{{$.i18n.Tr "repo.issues.poster"}}
|
||||
{{else if eq .ShowTag 2}}
|
||||
{{$.i18n.Tr "repo.issues.admin"}}
|
||||
{{$.i18n.Tr "repo.issues.collaborator"}}
|
||||
{{else if eq .ShowTag 3}}
|
||||
{{$.i18n.Tr "repo.issues.owner"}}
|
||||
{{end}}
|
||||
@@ -165,7 +165,7 @@
|
||||
<span class="octicon octicon-check"></span>
|
||||
{{$.i18n.Tr "repo.pulls.can_auto_merge_desc"}}
|
||||
</div>
|
||||
{{if .IsRepositoryAdmin}}
|
||||
{{if .IsRepositoryWriter}}
|
||||
<div class="ui divider"></div>
|
||||
<div>
|
||||
<form class="ui form" action="{{.Link}}/merge" method="post">
|
||||
@@ -231,7 +231,7 @@
|
||||
|
||||
<div class="four wide column">
|
||||
<div class="ui segment metas">
|
||||
<div class="ui {{if not .IsRepositoryAdmin}}disabled{{end}} floating jump select-label dropdown">
|
||||
<div class="ui {{if not .IsRepositoryWriter}}disabled{{end}} floating jump select-label dropdown">
|
||||
<span class="text">
|
||||
<strong>{{.i18n.Tr "repo.issues.new.labels"}}</strong>
|
||||
<span class="octicon octicon-gear"></span>
|
||||
@@ -252,7 +252,7 @@
|
||||
|
||||
<div class="ui divider"></div>
|
||||
|
||||
<div class="ui {{if not .IsRepositoryAdmin}}disabled{{end}} floating jump select-milestone dropdown">
|
||||
<div class="ui {{if not .IsRepositoryWriter}}disabled{{end}} floating jump select-milestone dropdown">
|
||||
<span class="text">
|
||||
<strong>{{.i18n.Tr "repo.issues.new.milestone"}}</strong>
|
||||
<span class="octicon octicon-gear"></span>
|
||||
@@ -293,7 +293,7 @@
|
||||
<div class="ui divider"></div>
|
||||
|
||||
<input id="assignee_id" name="assignee_id" type="hidden" value="{{.assignee_id}}">
|
||||
<div class="ui {{if not .IsRepositoryAdmin}}disabled{{end}} floating jump select-assignee dropdown">
|
||||
<div class="ui {{if not .IsRepositoryWriter}}disabled{{end}} floating jump select-assignee dropdown">
|
||||
<span class="text">
|
||||
<strong>{{.i18n.Tr "repo.issues.new.assignee"}}</strong>
|
||||
<span class="octicon octicon-gear"></span>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div class="sixteen wide column title">
|
||||
<div class="ui grid">
|
||||
<h1 class="twelve wide column">
|
||||
<span class="index">#{{.Issue.Index}}</span> <span id="issue-title">{{.Issue.Name}}</span>
|
||||
<span class="index">#{{.Issue.Index}}</span> <span id="issue-title" class="has-emoji">{{.Issue.Name}}</span>
|
||||
<div id="edit-title-input" class="ui input" style="display: none">
|
||||
<input value="{{.Issue.Name}}">
|
||||
</div>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
</div>
|
||||
<div class="scrolling menu">
|
||||
{{range .Branches}}
|
||||
<div class="item {{if eq $.BaseBranch .}}selected{{end}}" data-url="{{$.RepoLink}}/compare/{{.}}...{{$.HeadUser.Name}}:{{$.HeadBranch}}">{{.}}</div>
|
||||
<div class="item {{if eq $.BaseBranch .}}selected{{end}}" data-url="{{$.RepoLink}}/compare/{{.}}...{{if not $.IsBetweenBranches}}{{$.HeadUser.Name}}:{{end}}{{$.HeadBranch}}">{{.}}</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
@@ -39,7 +39,7 @@
|
||||
</div>
|
||||
<div class="scrolling menu">
|
||||
{{range .HeadBranches}}
|
||||
<div class="{{if eq $.HeadBranch .}}selected{{end}} item" data-url="{{$.RepoLink}}/compare/{{$.BaseBranch}}...{{$.HeadUser.Name}}:{{.}}">{{.}}</div>
|
||||
<div class="{{if eq $.HeadBranch .}}selected{{end}} item" data-url="{{$.RepoLink}}/compare/{{$.BaseBranch}}...{{if not $.IsBetweenBranches}}{{$.HeadUser.Name}}:{{end}}{{.}}">{{.}}</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,16 +2,16 @@
|
||||
<a class="item {{if .PageIsPullConversation}}active{{end}}" href="{{.RepoLink}}/pulls/{{.Issue.Index}}">
|
||||
<span class="octicon octicon-comment-discussion"></span>
|
||||
{{$.i18n.Tr "repo.pulls.tab_conversation"}}
|
||||
<span class="ui label">{{.Issue.NumComments}}</span>
|
||||
<span class="ui {{if not .Issue.NumComments}}gray{{else}}blue{{end}} small label">{{.Issue.NumComments}}</span>
|
||||
</a>
|
||||
<a class="item {{if .PageIsPullCommits}}active{{end}}" {{if .NumCommits}}href="{{.RepoLink}}/pulls/{{.Issue.Index}}/commits"{{end}}>
|
||||
<span class="octicon octicon-git-commit"></span>
|
||||
{{$.i18n.Tr "repo.pulls.tab_commits"}}
|
||||
<span class="ui label">{{if .NumCommits}}{{.NumCommits}}{{else}}N/A{{end}}</span>
|
||||
<span class="ui {{if not .NumCommits}}gray{{else}}blue{{end}} small label">{{if .NumCommits}}{{.NumCommits}}{{else}}N/A{{end}}</span>
|
||||
</a>
|
||||
<a class="item {{if .PageIsPullFiles}}active{{end}}" {{if .NumFiles}}href="{{.RepoLink}}/pulls/{{.Issue.Index}}/files"{{end}}>
|
||||
<span class="octicon octicon-diff"></span>
|
||||
{{$.i18n.Tr "repo.pulls.tab_files"}}
|
||||
<span class="ui label">{{if .NumFiles}}{{.NumFiles}}{{else}}N/A{{end}}</span>
|
||||
<span class="ui {{if not .NumFiles}}gray{{else}}blue{{end}} small label">{{if .NumFiles}}{{.NumFiles}}{{else}}N/A{{end}}</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
{{template "base/alert" .}}
|
||||
<h2 class="ui header">
|
||||
{{.i18n.Tr "repo.release.releases"}}
|
||||
{{if .IsRepositoryAdmin}}
|
||||
{{if .IsRepositoryWriter}}
|
||||
<div class="ui right">
|
||||
<a class="ui small green button" href="{{$.RepoLink}}/releases/new">
|
||||
{{.i18n.Tr "repo.release.new_release"}}
|
||||
@@ -37,7 +37,7 @@
|
||||
{{if .PublisherID}}
|
||||
<h3>
|
||||
<a href="{{$.RepoLink}}/src/{{.TagName}}">{{.Title}}</a>
|
||||
{{if $.IsRepositoryAdmin}}<small>(<a href="{{$.RepoLink}}/releases/edit/{{.TagName}}" rel="nofollow">{{$.i18n.Tr "repo.release.edit"}}</a>)</small>{{end}}
|
||||
{{if $.IsRepositoryWriter}}<small>(<a href="{{$.RepoLink}}/releases/edit/{{.TagName}}" rel="nofollow">{{$.i18n.Tr "repo.release.edit"}}</a>)</small>{{end}}
|
||||
</h3>
|
||||
<p class="text grey">
|
||||
<span class="author">
|
||||
|
||||
@@ -11,14 +11,30 @@
|
||||
</h4>
|
||||
<div class="ui attached segment collaborator list">
|
||||
{{range .Collaborators}}
|
||||
<div class="item">
|
||||
{{if not (eq .Id $.Owner.Id)}}
|
||||
<a href="{{$.RepoLink}}/settings/collaboration?remove={{.Name}}" class="ui right text red"><i class="fa fa-times"></i></a>
|
||||
{{end}}
|
||||
<a href="{{AppSubUrl}}/{{.Name}}">
|
||||
<img class="ui avatar image" src="{{.AvatarLink}}">
|
||||
{{.DisplayName}}
|
||||
</a>
|
||||
<div class="item ui grid">
|
||||
<div class="ui five wide column">
|
||||
<a href="{{AppSubUrl}}/{{.Name}}">
|
||||
<img class="ui avatar image" src="{{.AvatarLink}}">
|
||||
{{.DisplayName}}
|
||||
</a>
|
||||
</div>
|
||||
<div class="ui eight wide column">
|
||||
<span class="octicon octicon-shield"></span>
|
||||
<div class="ui inline dropdown">
|
||||
<div class="text">{{.Collaboration.ModeName}}</div>
|
||||
<i class="dropdown icon"></i>
|
||||
<div class="access-mode menu" data-url="{{$.Link}}/access_mode" data-uid="{{.Id}}">
|
||||
<div class="item" data-text="Admin" data-value="3">Admin</div>
|
||||
<div class="item" data-text="Write" data-value="2">Write</div>
|
||||
<div class="item" data-text="Read" data-value="1">Read</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui two wide column">
|
||||
<button class="ui red tiny button inline text-thin delete-button" data-url="{{$.Link}}/delete" data-id="{{.Id}}">
|
||||
{{$.i18n.Tr "repo.settings.delete_collaborator"}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
@@ -40,4 +56,15 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ui small basic delete modal">
|
||||
<div class="ui icon header">
|
||||
<i class="trash icon"></i>
|
||||
{{.i18n.Tr "repo.settings.collaborator_deletion"}}
|
||||
</div>
|
||||
<div class="content">
|
||||
<p>{{.i18n.Tr "repo.settings.collaborator_deletion_desc"}}</p>
|
||||
</div>
|
||||
{{template "base/delete_modal_actions" .}}
|
||||
</div>
|
||||
{{template "base/footer" .}}
|
||||
|
||||
@@ -136,6 +136,7 @@
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{{if .IsRepositoryOwner}}
|
||||
<h4 class="ui top attached warning header">
|
||||
{{.i18n.Tr "repo.settings.danger_zone"}}
|
||||
</h4>
|
||||
@@ -163,6 +164,20 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{if .Repository.EnableWiki}}
|
||||
<div class="ui divider"></div>
|
||||
|
||||
<div class="item">
|
||||
<div class="ui right">
|
||||
<button class="ui basic red show-modal button" data-modal="#delete-wiki-modal">{{.i18n.Tr "repo.settings.wiki_delete"}}</button>
|
||||
</div>
|
||||
<div>
|
||||
<h5>{{.i18n.Tr "repo.settings.wiki_delete"}}</h5>
|
||||
<p>{{.i18n.Tr "repo.settings.wiki_delete_desc"}}</p>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
<div class="ui divider"></div>
|
||||
|
||||
<div class="item">
|
||||
@@ -175,111 +190,148 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{if .Repository.IsMirror}}
|
||||
<div class="ui small modal" id="convert-repo-modal">
|
||||
<div class="header">
|
||||
{{.i18n.Tr "repo.settings.convert"}}
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="ui warning message text left">
|
||||
{{.i18n.Tr "repo.settings.convert_notices_1" | Safe}}
|
||||
{{if .IsRepositoryOwner}}
|
||||
{{if .Repository.IsMirror}}
|
||||
<div class="ui small modal" id="convert-repo-modal">
|
||||
<div class="header">
|
||||
{{.i18n.Tr "repo.settings.convert"}}
|
||||
</div>
|
||||
<form class="ui form" action="{{.Link}}" method="post">
|
||||
{{.CsrfTokenHtml}}
|
||||
<input type="hidden" name="action" value="convert">
|
||||
<div class="field">
|
||||
<label>
|
||||
{{.i18n.Tr "repo.settings.transfer_form_title"}}
|
||||
<span class="text red">{{.Repository.Name}}</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="required field">
|
||||
<label for="repo_name">{{.i18n.Tr "repo.repo_name"}}</label>
|
||||
<input id="repo_name" name="repo_name" required>
|
||||
<div class="content">
|
||||
<div class="ui warning message text left">
|
||||
{{.i18n.Tr "repo.settings.convert_notices_1" | Safe}}
|
||||
</div>
|
||||
<form class="ui form" action="{{.Link}}" method="post">
|
||||
{{.CsrfTokenHtml}}
|
||||
<input type="hidden" name="action" value="convert">
|
||||
<div class="field">
|
||||
<label>
|
||||
{{.i18n.Tr "repo.settings.transfer_form_title"}}
|
||||
<span class="text red">{{.Repository.Name}}</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="required field">
|
||||
<label for="repo_name">{{.i18n.Tr "repo.repo_name"}}</label>
|
||||
<input id="repo_name" name="repo_name" required>
|
||||
</div>
|
||||
|
||||
<div class="text right actions">
|
||||
<div class="ui cancel button">{{.i18n.Tr "settings.cancel"}}</div>
|
||||
<button class="ui red button">{{.i18n.Tr "repo.settings.convert_confirm"}}</button>
|
||||
</div>
|
||||
</form>
|
||||
<div class="text right actions">
|
||||
<div class="ui cancel button">{{.i18n.Tr "settings.cancel"}}</div>
|
||||
<button class="ui red button">{{.i18n.Tr "repo.settings.convert_confirm"}}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
<div class="ui small modal" id="transfer-repo-modal">
|
||||
<div class="header">
|
||||
{{.i18n.Tr "repo.settings.transfer"}}
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="ui warning message text left">
|
||||
{{.i18n.Tr "repo.settings.transfer_notices_1" | Safe}} <br>
|
||||
{{.i18n.Tr "repo.settings.transfer_notices_2" | Safe}}
|
||||
</div>
|
||||
<form class="ui form" action="{{.Link}}" method="post">
|
||||
{{.CsrfTokenHtml}}
|
||||
<input type="hidden" name="action" value="transfer">
|
||||
<div class="field">
|
||||
<label>
|
||||
{{.i18n.Tr "repo.settings.transfer_form_title"}}
|
||||
<span class="text red">{{.Repository.Name}}</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="required field">
|
||||
<label for="repo_name">{{.i18n.Tr "repo.repo_name"}}</label>
|
||||
<input id="repo_name" name="repo_name" required>
|
||||
</div>
|
||||
<div class="required field">
|
||||
<label for="new_owner_name">{{.i18n.Tr "repo.settings.transfer_owner"}}</label>
|
||||
<input id="new_owner_name" name="new_owner_name" required>
|
||||
</div>
|
||||
|
||||
<div class="text right actions">
|
||||
<div class="ui cancel button">{{.i18n.Tr "settings.cancel"}}</div>
|
||||
<button class="ui red button">{{.i18n.Tr "repo.settings.make_transfer"}}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ui small modal" id="delete-repo-modal">
|
||||
<div class="header">
|
||||
{{.i18n.Tr "repo.settings.delete"}}
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="ui warning message text left">
|
||||
{{.i18n.Tr "repo.settings.delete_notices_1" | Safe}} <br>
|
||||
{{.i18n.Tr "repo.settings.delete_notices_2" | Safe}}
|
||||
{{if .Repository.NumForks}}<br>
|
||||
{{.i18n.Tr "repo.settings.delete_notices_fork_1" | Safe}} <br>
|
||||
{{.i18n.Tr "repo.settings.delete_notices_fork_2" | Safe}} <br>
|
||||
{{.i18n.Tr "repo.settings.delete_notices_fork_3" | Safe}}
|
||||
{{end}}
|
||||
</div>
|
||||
<form class="ui form" action="{{.Link}}" method="post">
|
||||
{{.CsrfTokenHtml}}
|
||||
<input type="hidden" name="action" value="delete">
|
||||
<div class="field">
|
||||
<label>
|
||||
{{.i18n.Tr "repo.settings.transfer_form_title"}}
|
||||
<span class="text red">{{.Repository.Name}}</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="required field">
|
||||
<label for="repo_name">{{.i18n.Tr "repo.repo_name"}}</label>
|
||||
<input id="repo_name" name="repo_name" required>
|
||||
</div>
|
||||
|
||||
<div class="text right actions">
|
||||
<div class="ui cancel button">{{.i18n.Tr "settings.cancel"}}</div>
|
||||
<button class="ui red button">{{.i18n.Tr "repo.settings.confirm_delete"}}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{if .Repository.EnableWiki}}
|
||||
<div class="ui small modal" id="delete-wiki-modal">
|
||||
<div class="header">
|
||||
{{.i18n.Tr "repo.settings.wiki-delete"}}
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="ui warning message text left">
|
||||
{{.i18n.Tr "repo.settings.delete_notices_1" | Safe}}<br>
|
||||
{{.i18n.Tr "repo.settings.wiki_delete_notices_1" .Repository.Name | Safe}}
|
||||
</div>
|
||||
<form class="ui form" action="{{.Link}}" method="post">
|
||||
{{.CsrfTokenHtml}}
|
||||
<input type="hidden" name="action" value="delete-wiki">
|
||||
<div class="field">
|
||||
<label>
|
||||
{{.i18n.Tr "repo.settings.transfer_form_title"}}
|
||||
<span class="text red">{{.Repository.Name}}</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="required field">
|
||||
<label for="repo_name">{{.i18n.Tr "repo.repo_name"}}</label>
|
||||
<input id="repo_name" name="repo_name" required>
|
||||
</div>
|
||||
|
||||
<div class="text right actions">
|
||||
<div class="ui cancel button">{{.i18n.Tr "settings.cancel"}}</div>
|
||||
<button class="ui red button">{{.i18n.Tr "repo.settings.confirm_delete"}}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
<div class="ui small modal" id="transfer-repo-modal">
|
||||
<div class="header">
|
||||
{{.i18n.Tr "repo.settings.transfer"}}
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="ui warning message text left">
|
||||
{{.i18n.Tr "repo.settings.transfer_notices_1" | Safe}} <br>
|
||||
{{.i18n.Tr "repo.settings.transfer_notices_2" | Safe}}
|
||||
</div>
|
||||
<form class="ui form" action="{{.Link}}" method="post">
|
||||
{{.CsrfTokenHtml}}
|
||||
<input type="hidden" name="action" value="transfer">
|
||||
<div class="field">
|
||||
<label>
|
||||
{{.i18n.Tr "repo.settings.transfer_form_title"}}
|
||||
<span class="text red">{{.Repository.Name}}</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="required field">
|
||||
<label for="repo_name">{{.i18n.Tr "repo.repo_name"}}</label>
|
||||
<input id="repo_name" name="repo_name" required>
|
||||
</div>
|
||||
<div class="required field">
|
||||
<label for="new_owner_name">{{.i18n.Tr "repo.settings.transfer_owner"}}</label>
|
||||
<input id="new_owner_name" name="new_owner_name" required>
|
||||
</div>
|
||||
|
||||
<div class="text right actions">
|
||||
<div class="ui cancel button">{{.i18n.Tr "settings.cancel"}}</div>
|
||||
<button class="ui red button">{{.i18n.Tr "repo.settings.make_transfer"}}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ui small modal" id="delete-repo-modal">
|
||||
<div class="header">
|
||||
{{.i18n.Tr "repo.settings.delete"}}
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="ui warning message text left">
|
||||
{{.i18n.Tr "repo.settings.delete_notices_1" | Safe}} <br>
|
||||
{{.i18n.Tr "repo.settings.delete_notices_2" | Safe}}
|
||||
{{if .Repository.NumForks}}<br>
|
||||
{{.i18n.Tr "repo.settings.delete_notices_fork_1" | Safe}} <br>
|
||||
{{.i18n.Tr "repo.settings.delete_notices_fork_2" | Safe}} <br>
|
||||
{{.i18n.Tr "repo.settings.delete_notices_fork_3" | Safe}}
|
||||
{{end}}
|
||||
</div>
|
||||
<form class="ui form" action="{{.Link}}" method="post">
|
||||
{{.CsrfTokenHtml}}
|
||||
<input type="hidden" name="action" value="delete">
|
||||
<div class="field">
|
||||
<label>
|
||||
{{.i18n.Tr "repo.settings.transfer_form_title"}}
|
||||
<span class="text red">{{.Repository.Name}}</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="required field">
|
||||
<label for="repo_name">{{.i18n.Tr "repo.repo_name"}}</label>
|
||||
<input id="repo_name" name="repo_name" required>
|
||||
</div>
|
||||
|
||||
<div class="text right actions">
|
||||
<div class="ui cancel button">{{.i18n.Tr "settings.cancel"}}</div>
|
||||
<button class="ui red button">{{.i18n.Tr "repo.settings.confirm_delete"}}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{{template "base/footer" .}}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
{{end}}
|
||||
</h4>
|
||||
<div class="ui attached table segment">
|
||||
<div class="file-view {{if .ReadmeExist}}markdown{{else if .IsFileText}}code-view{{end}}">
|
||||
<div class="file-view {{if .ReadmeExist}}markdown{{else if .IsFileText}}code-view{{end}} has-emoji">
|
||||
{{if .ReadmeExist}}
|
||||
{{if .FileContent}}{{.FileContent | Str2html}}{{end}}
|
||||
{{else if not .IsFileText}}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<strong>{{.LastCommit.Author.Name}}</strong>
|
||||
{{end}}
|
||||
<a rel="nofollow" class="ui sha label" href="{{.RepoLink}}/commit/{{.LastCommit.ID}}" rel="nofollow">{{ShortSha .LastCommit.ID.String}}</a>
|
||||
<span class="grey">{{RenderCommitMessage false .LastCommit.Summary .RepoLink $.Repository.ComposeMetas}}</span>
|
||||
<span class="grey has-emoji">{{RenderCommitMessage false .LastCommit.Summary .RepoLink $.Repository.ComposeMetas}}</span>
|
||||
</th>
|
||||
<th class="nine wide">
|
||||
</th>
|
||||
@@ -42,7 +42,7 @@
|
||||
<a href="{{EscapePound $.BranchLink}}/{{EscapePound $.TreePath}}{{EscapePound $entry.Name}}">{{$entry.Name}}</a>
|
||||
</td>
|
||||
{{end}}
|
||||
<td class="message collapsing">
|
||||
<td class="message collapsing has-emoji">
|
||||
<a rel="nofollow" class="ui sha label" href="{{AppSubUrl}}/{{$.Username}}/{{$.Reponame}}/commit/{{$commit.ID}}">{{ShortSha $commit.ID.String}}</a>
|
||||
{{RenderCommitMessage false $commit.Summary $.RepoLink $.Repository.ComposeMetas}}
|
||||
</td>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<span class="mega-octicon octicon-book"></span>
|
||||
<h2>{{.i18n.Tr "repo.wiki.welcome"}}</h2>
|
||||
<p>{{.i18n.Tr "repo.wiki.welcome_desc"}}</p>
|
||||
{{if .IsRepositoryPusher}}
|
||||
{{if .IsRepositoryWriter}}
|
||||
<a class="ui green button" href="{{.RepoLink}}/wiki/_new">{{.i18n.Tr "repo.wiki.create_first_page"}}</a>
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
@@ -41,22 +41,16 @@
|
||||
<button class="ui basic icon button poping up clipboard" id="clipboard-btn" data-original="{{.i18n.Tr "repo.copy_link"}}" data-success="{{.i18n.Tr "repo.copy_link_success"}}" data-error="{{.i18n.Tr "repo.copy_link_error"}}" data-content="{{.i18n.Tr "repo.copy_link"}}" data-variation="inverted tiny" data-clipboard-target="#repo-clone-url">
|
||||
<i class="octicon octicon-clippy"></i>
|
||||
</button>
|
||||
<div class="ui basic jump dropdown icon button">
|
||||
<i class="download icon"></i>
|
||||
<div class="menu">
|
||||
<a class="item" href="{{$.RepoLink}}/archive/{{EscapePound $.BranchName}}.zip"><i class="icon octicon octicon-file-zip"></i> ZIP</a>
|
||||
<a class="item" href="{{$.RepoLink}}/archive/{{EscapePound $.BranchName}}.tar.gz"><i class="icon octicon octicon-file-zip"></i> TAR.GZ</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui dividing header">
|
||||
{{.title}}
|
||||
{{if .IsRepositoryPusher}}
|
||||
{{if .IsRepositoryWriter}}
|
||||
<div class="ui right">
|
||||
<a class="ui small button" href="{{.RepoLink}}/wiki/{{.PageURL}}/_edit">{{.i18n.Tr "repo.wiki.edit_page_button"}}</a>
|
||||
<a class="ui green small button" href="{{.RepoLink}}/wiki/_new">{{.i18n.Tr "repo.wiki.new_page_button"}}</a>
|
||||
<a class="ui red small button delete-button" href="" data-url="{{.RepoLink}}/wiki/{{.PageURL}}/delete" data-id="{{.PageURL}}">{{.i18n.Tr "repo.wiki.delete_page_button"}}</a>
|
||||
</div>
|
||||
{{end}}
|
||||
<div class="ui sub header">
|
||||
@@ -69,4 +63,16 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ui small basic delete modal">
|
||||
<div class="ui icon header">
|
||||
<i class="trash icon"></i>
|
||||
{{.i18n.Tr "repo.wiki.delete_page_button"}}
|
||||
</div>
|
||||
<div class="content">
|
||||
<p>{{.i18n.Tr "repo.wiki.delete_page_notice_1" .title | Safe}}</p>
|
||||
</div>
|
||||
{{template "base/delete_modal_actions" .}}
|
||||
</div>
|
||||
|
||||
{{template "base/footer" .}}
|
||||
|
||||
@@ -37,6 +37,12 @@
|
||||
{{else if eq .GetOpType 13}}
|
||||
{{ $index := index .GetIssueInfos 0}}
|
||||
{{$.i18n.Tr "action.reopen_issue" .GetRepoLink $index .ShortRepoPath | Str2html}}
|
||||
{{else if eq .GetOpType 14}}
|
||||
{{ $index := index .GetIssueInfos 0}}
|
||||
{{$.i18n.Tr "action.close_pull_request" .GetRepoLink $index .ShortRepoPath | Str2html}}
|
||||
{{else if eq .GetOpType 15}}
|
||||
{{ $index := index .GetIssueInfos 0}}
|
||||
{{$.i18n.Tr "action.reopen_pull_request" .GetRepoLink $index .ShortRepoPath | Str2html}}
|
||||
{{end}}
|
||||
</p>
|
||||
{{if eq .GetOpType 5}}
|
||||
@@ -46,23 +52,23 @@
|
||||
{{ $repoLink := .GetRepoLink}}
|
||||
{{if $push.Commits}}
|
||||
{{range $push.Commits}}
|
||||
<li><img class="img-8" src="{{$push.AvatarLink .AuthorEmail}}"> <a class="commit-id" href="{{$repoLink}}/commit/{{.Sha1}}">{{ShortSha .Sha1}}</a> <span class="text truncate light grey">{{.Message}}</span></li>
|
||||
<li><img class="img-8" src="{{$push.AvatarLink .AuthorEmail}}"> <a class="commit-id" href="{{$repoLink}}/commit/{{.Sha1}}">{{ShortSha .Sha1}}</a> <span class="text truncate light grey has-emoji">{{.Message}}</span></li>
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{if and (gt $push.Len 1) $push.CompareUrl}}<li><a href="{{AppSubUrl}}/{{$push.CompareUrl}}">{{$.i18n.Tr "action.compare_commits" $push.Len}} »</a></li>{{end}}
|
||||
</ul>
|
||||
</div>
|
||||
{{else if eq .GetOpType 6}}
|
||||
<span class="text truncate issue title">{{index .GetIssueInfos 1}}</span>
|
||||
<span class="text truncate issue title has-emoji">{{index .GetIssueInfos 1}}</span>
|
||||
{{else if eq .GetOpType 7}}
|
||||
<p class="text light grey">{{index .GetIssueInfos 1}}</p>
|
||||
<span class="text truncate issue title has-emoji">{{index .GetIssueInfos 1}}</span>
|
||||
{{else if eq .GetOpType 10}}
|
||||
<span class="text truncate issue title">{{.GetIssueTitle}}</span>
|
||||
<p class="text light grey">{{index .GetIssueInfos 1}}</p>
|
||||
<span class="text truncate issue title has-emoji">{{.GetIssueTitle}}</span>
|
||||
<p class="text light grey has-emoji">{{index .GetIssueInfos 1}}</p>
|
||||
{{else if eq .GetOpType 11}}
|
||||
<p class="text light grey">{{index .GetIssueInfos 1}}</p>
|
||||
{{else if (or (eq .GetOpType 12) (eq .GetOpType 13))}}
|
||||
<span class="text truncate issue title">{{.GetIssueTitle}}</span>
|
||||
<p class="text light grey has-emoji">{{index .GetIssueInfos 1}}</p>
|
||||
{{else if (or (or (eq .GetOpType 12) (eq .GetOpType 13)) (or (eq .GetOpType 14) (eq .GetOpType 15)))}}
|
||||
<span class="text truncate issue title has-emoji">{{.GetIssueTitle}}</span>
|
||||
{{end}}
|
||||
<p class="text italic light grey">{{TimeSince .GetCreate $.i18n.Lang}}</p>
|
||||
</div>
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
{{ $timeStr:= TimeSince .Created $.Lang }}
|
||||
<li class="item">
|
||||
<div class="ui label">{{if not $.RepoID}}{{.Repo.Name}}{{end}}#{{.Index}}</div>
|
||||
<a class="title" href="{{AppSubUrl}}/{{.Repo.Owner.Name}}/{{.Repo.Name}}/issues/{{.Index}}">{{.Name}}</a>
|
||||
<a class="title has-emoji" href="{{AppSubUrl}}/{{.Repo.Owner.Name}}/{{.Repo.Name}}/issues/{{.Index}}">{{.Name}}</a>
|
||||
|
||||
{{if .NumComments}}
|
||||
<span class="comment ui right"><i class="octicon octicon-comment"></i> {{.NumComments}}</span>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user