Browse Source

Merge with dev branch and resolve conflicts

pull/946/head
Alexey Makhov 10 years ago
parent
commit
700213d2a6
  1. 1
      .gitignore
  2. 3
      .gopmfile
  3. 32
      CONTRIBUTING.md
  4. 7
      README.md
  5. 8
      README_ZH.md
  6. 9
      cmd/cert_stub.go
  7. 4
      cmd/dump.go
  8. 184
      cmd/fix.go
  9. 18
      cmd/serve.go
  10. 8
      cmd/update.go
  11. 7
      cmd/web.go
  12. 8
      conf/app.ini
  13. 1
      conf/locale/TRANSLATORS
  14. 25
      conf/locale/locale_de-DE.ini
  15. 15
      conf/locale/locale_en-US.ini
  16. 723
      conf/locale/locale_es-ES.ini
  17. 53
      conf/locale/locale_fr-CA.ini
  18. 25
      conf/locale/locale_ja-JP.ini
  19. 25
      conf/locale/locale_lv-LV.ini
  20. 25
      conf/locale/locale_nl-NL.ini
  21. 27
      conf/locale/locale_ru-RU.ini
  22. 25
      conf/locale/locale_zh-CN.ini
  23. 25
      conf/locale/locale_zh-HK.ini
  24. 3
      gogs.go
  25. 93
      models/action.go
  26. 8
      models/git_diff.go
  27. 26
      models/issue.go
  28. 11
      models/models.go
  29. 94
      models/org.go
  30. 4
      models/publickey.go
  31. 49
      models/repo.go
  32. 14
      models/webhook.go
  33. 8
      modules/asn1-ber/ber.go
  34. 7
      modules/base/markdown.go
  35. 2
      modules/cron/manager.go
  36. 5
      modules/middleware/auth.go
  37. 2
      modules/middleware/context.go
  38. 1
      modules/middleware/repo.go
  39. 39
      modules/setting/setting.go
  40. 17
      public/ng/css/gogs.css
  41. 167
      public/ng/less/gogs/markdown.less
  42. 14
      public/ng/less/gogs/repository.less
  43. 9
      routers/admin/admin.go
  44. 5
      routers/install.go
  45. 7
      routers/org/teams.go
  46. 4
      routers/repo/commit.go
  47. 54
      routers/repo/http.go
  48. 24
      routers/repo/issue.go
  49. 12
      routers/repo/view.go
  50. 2
      templates/.VERSION
  51. 8
      templates/admin/config.tmpl
  52. 5
      templates/admin/dashboard.tmpl
  53. 2
      templates/home.tmpl
  54. 2
      templates/ng/base/footer.tmpl
  55. 2
      templates/ng/base/header.tmpl
  56. 4
      templates/repo/diff.tmpl
  57. 8
      templates/repo/header.tmpl
  58. 2
      templates/user/auth/signin.tmpl
  59. 4
      templates/user/dashboard/feeds.tmpl

1
.gitignore vendored

@ -1,6 +1,7 @@
.DS_Store .DS_Store
*.db *.db
*.log *.log
log/
custom/ custom/
data/ data/
.vendor/ .vendor/

3
.gopmfile

@ -3,6 +3,7 @@ path = github.com/gogits/gogs
[deps] [deps]
github.com/beego/memcache = commit:2aea774416 github.com/beego/memcache = commit:2aea774416
github.com/bradfitz/gomemcache =
github.com/Unknwon/cae = commit:2e70a1351b github.com/Unknwon/cae = commit:2e70a1351b
github.com/Unknwon/com = commit:d9bcf409c8 github.com/Unknwon/com = commit:d9bcf409c8
github.com/Unknwon/i18n = commit:1e88666229 github.com/Unknwon/i18n = commit:1e88666229
@ -27,6 +28,8 @@ github.com/microcosm-cc/bluemonday =
github.com/nfnt/resize = commit:8f44931448 github.com/nfnt/resize = commit:8f44931448
github.com/russross/blackfriday = commit:05b8cefd6a github.com/russross/blackfriday = commit:05b8cefd6a
github.com/shurcooL/go = commit:48293cbc7a github.com/shurcooL/go = commit:48293cbc7a
golang.org/x/net =
golang.org/x/text =
gopkg.in/ini.v1 = commit:28ad8c408b gopkg.in/ini.v1 = commit:28ad8c408b
gopkg.in/redis.v2 = commit:e617904962 gopkg.in/redis.v2 = commit:e617904962

32
CONTRIBUTING.md

@ -2,7 +2,7 @@
> This guidelines sheet is forked from [CONTRIBUTING.md](https://github.com/drone/drone/blob/master/CONTRIBUTING.md). > This guidelines sheet is forked from [CONTRIBUTING.md](https://github.com/drone/drone/blob/master/CONTRIBUTING.md).
Gogs is not perfect and it has bugs, or incomplete features for rare cases. You're welcome to tell us or contribute some code. This document describles details about how can you contribute to Gogs project. Gogs is not perfect and it has bugs, or incomplete features for rare cases. You're welcome to tell us or contribute some code. This document describes details about how can you contribute to Gogs project.
## Contribution guidelines ## Contribution guidelines
@ -15,36 +15,30 @@ Depends on the situation, you will:
### Bug Report ### Bug Report
If you find or consider something is a bug, please create a issue on [GitHub](https://github.com/gogits/gogs/issues). To reduce unnecessary time wasting of interacting and waiting with team members, please use following form as template in the first place: If you find or consider something is a bug, please create a issue on [GitHub](https://github.com/gogits/gogs/issues). To reduce unnecessary time wasting of interacting and waiting with team members, please include following information in the first place with a comfortable form for you:
``` - Bug Description
- **Bug Description**: - Gogs Version
- **Gogs Version**: - Git Version
- **Git Version**: - System Type
- **System Type**: - Error Log
- **Error Log**: - Other information
- **Other information**:
```
Please take a moment to check that an issue on [GitHub](https://github.com/gogits/gogs/issues) doesn't already exist documenting your bug report or improvement proposal. If it does, it never hurts to add a quick "+1" or "I have this problem too". This will help prioritize the most common problems and requests. Please take a moment to check that an issue on [GitHub](https://github.com/gogits/gogs/issues) doesn't already exist documenting your bug report or improvement proposal. If it does, it never hurts to add a quick "+1" or "I have this problem too". This will help prioritize the most common problems and requests.
#### Bug Report Example #### Bug Report Example
- **Bug Description**: Crash when create repository with license| Gogs crashed when create repository with license, using v0.5.13.0207, SQLite3, Git 1.9.0, Ubuntu 12.04.
- **Gogs Version**: `v0.4.9.0901`
- **Git Version**: `1.9.0` Error log:
- **System Type**: `Ubuntu 12.04`
- **Error Log**:
``` ```
2014/09/01 07:21:49 [E] nil pointer 2014/09/01 07:21:49 [E] nil pointer
``` ```
- **Other information**: Use SQLite3 as database
### Feature Request ### Feature Request
There is no standard form of making a feature request, just try to describle the feature as clear as possible because team members may not have experience with the functionality you're talking about. There is no standard form of making a feature request, just try to describe the feature as clear as possible because team members may not have experience with the functionality you're talking about.
### Pull Request ### Pull Request
@ -54,7 +48,7 @@ We are always thrilled to receive pull requests, and do our best to process them
If your pull request is not accepted on the first try, don't be discouraged! If there's a problem with the implementation, hopefully you received feedback on what to improve. If your pull request is not accepted on the first try, don't be discouraged! If there's a problem with the implementation, hopefully you received feedback on what to improve.
We're trying very hard to keep Gogs lean and focused. We don't want it to do everything for everybody. This means that we might decide against incorporating a new feature. We're trying very hard to keep Gogs lean and focused. We don't want it to do everything for everybody. This means that we might decide against incorporating a new feature. We believe you do like to discuss with us first in [Gitter](https://gitter.im/gogits/gogs).
### Ask For Help ### Ask For Help

7
README.md

@ -7,12 +7,13 @@ Gogs(Go Git Service) is a painless self-hosted Git Service written in Go.
![Demo](http://gogs.qiniudn.com/gogs_demo.gif) ![Demo](http://gogs.qiniudn.com/gogs_demo.gif)
##### Current version: 0.5.12 Beta ##### Current version: 0.5.13 Beta
### NOTICES ### NOTICES
- Due to testing purpose, data of [try.gogs.io](https://try.gogs.io) has been reset in **Jan 28, 2015** and will reset multiple times after. Please do **NOT** put your important data on the site. - Due to testing purpose, data of [try.gogs.io](https://try.gogs.io) has been reset in **Jan 28, 2015** and will reset multiple times after. Please do **NOT** put your important data on the site.
- Demo site [try.gogs.io](https://try.gogs.io) is running under `dev` branch. - Demo site [try.gogs.io](https://try.gogs.io) is running under `dev` branch.
- You **MUST** read [CONTRIBUTING.md](CONTRIBUTING.md) before you start filing a issue or making a Pull Request.
- If you think there are vulnerabilities in the project, please talk private to **u@gogs.io**, thanks! - If you think there are vulnerabilities in the project, please talk private to **u@gogs.io**, thanks!
#### Other language version #### Other language version
@ -27,7 +28,7 @@ The goal of this project is to make the easiest, fastest and most painless way t
- Please see [Documentation](http://gogs.io/docs/intro/) for project design, known issues, and change log. - Please see [Documentation](http://gogs.io/docs/intro/) for project design, known issues, and change log.
- See [Trello Board](https://trello.com/b/uxAoeLUl/gogs-go-git-service) to follow the develop team. - See [Trello Board](https://trello.com/b/uxAoeLUl/gogs-go-git-service) to follow the develop team.
- Try it before anything? Do it [online](https://try.gogs.io/Unknown/gogs) or go down to **Installation -> Install from binary** section! - Try it before anything? Do it [online](https://try.gogs.io/unknwon/gogs) or go down to **Installation -> Install from binary** section!
- Having troubles? Get help from [Troubleshooting](http://gogs.io/docs/intro/troubleshooting.md). - Having troubles? Get help from [Troubleshooting](http://gogs.io/docs/intro/troubleshooting.md).
- Want to help on localization? Check out [Crowdin](https://crowdin.com/project/gogs)! - Want to help on localization? Check out [Crowdin](https://crowdin.com/project/gogs)!
@ -51,7 +52,7 @@ The goal of this project is to make the easiest, fastest and most painless way t
- Drone CI integration - Drone CI integration
- Supports MySQL, PostgreSQL and SQLite3 - Supports MySQL, PostgreSQL and SQLite3
- Social account login(GitHub, Google, QQ, Weibo) - Social account login(GitHub, Google, QQ, Weibo)
- Multi-language support([9 languages](https://crowdin.com/project/gogs)) - Multi-language support([10 languages](https://crowdin.com/project/gogs))
## System Requirements ## System Requirements

8
README_ZH.md

@ -1,11 +1,11 @@
Gogs - Go Git Service [![wercker status](https://app.wercker.com/status/ad0bdb0bc450ac6f09bc56b9640a50aa/s/ "wercker status")](https://app.wercker.com/project/bykey/ad0bdb0bc450ac6f09bc56b9640a50aa) [![Build Status](https://travis-ci.org/gogits/gogs.svg?branch=master)](https://travis-ci.org/gogits/gogs) Gogs - Go Git Service [![Build Status](https://travis-ci.org/gogits/gogs.svg?branch=master)](https://travis-ci.org/gogits/gogs)
===================== =====================
Gogs(Go Git Service) 是一个基于 Go 语言的自助 Git 服务。 Gogs(Go Git Service) 是一个基于 Go 语言的自助 Git 服务。
![Demo](http://gogs.qiniudn.com/gogs_demo.gif) ![Demo](http://gogs.qiniudn.com/gogs_demo.gif)
##### 当前版本:0.5.12 Beta ##### 当前版本:0.5.13 Beta
## 开发目的 ## 开发目的
@ -15,7 +15,7 @@ Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自
- 有关项目设计、已知问题和变更日志,请通过 [使用手册](http://gogs.io/docs/intro/) 查看。 - 有关项目设计、已知问题和变更日志,请通过 [使用手册](http://gogs.io/docs/intro/) 查看。
- 您可以到 [Trello Board](https://trello.com/b/uxAoeLUl/gogs-go-git-service) 跟随开发团队的脚步。 - 您可以到 [Trello Board](https://trello.com/b/uxAoeLUl/gogs-go-git-service) 跟随开发团队的脚步。
- 想要先睹为快?通过 [在线体验](https://try.gogs.io/Unknown/gogs) 或查看 **安装部署 -> 二进制安装** 小节。 - 想要先睹为快?通过 [在线体验](https://try.gogs.io/unknwon/gogs) 或查看 **安装部署 -> 二进制安装** 小节。
- 使用过程中遇到问题?尝试从 [故障排查](http://gogs.io/docs/intro/troubleshooting.md) 页面获取帮助。 - 使用过程中遇到问题?尝试从 [故障排查](http://gogs.io/docs/intro/troubleshooting.md) 页面获取帮助。
- 希望帮助多国语言界面的翻译吗?请立即访问 [Crowdin](https://crowdin.com/project/gogs)! - 希望帮助多国语言界面的翻译吗?请立即访问 [Crowdin](https://crowdin.com/project/gogs)!
@ -39,7 +39,7 @@ Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自
- Drone CI 持续部署集成 - Drone CI 持续部署集成
- 支持 MySQL、PostgreSQL 以及 SQLite3 数据库 - 支持 MySQL、PostgreSQL 以及 SQLite3 数据库
- 社交帐号登录(GitHub、Google、QQ、微博) - 社交帐号登录(GitHub、Google、QQ、微博)
- 多语言支持([9 种语言]([more](https://crowdin.com/project/gogs))) - 多语言支持([10 种语言]([more](https://crowdin.com/project/gogs)))
## 系统要求 ## 系统要求

9
cmd/cert_stub.go

@ -9,7 +9,6 @@ package cmd
import ( import (
"fmt" "fmt"
"os" "os"
"time"
"github.com/codegangsta/cli" "github.com/codegangsta/cli"
) )
@ -20,14 +19,6 @@ var CmdCert = cli.Command{
Description: `Generate a self-signed X.509 certificate for a TLS server. Description: `Generate a self-signed X.509 certificate for a TLS server.
Outputs to 'cert.pem' and 'key.pem' and will overwrite existing files.`, Outputs to 'cert.pem' and 'key.pem' and will overwrite existing files.`,
Action: runCert, Action: runCert,
Flags: []cli.Flag{
cli.StringFlag{"host", "", "Comma-separated hostnames and IPs to generate a certificate for", ""},
cli.StringFlag{"ecdsa-curve", "", "ECDSA curve to use to generate a key. Valid values are P224, P256, P384, P521", ""},
cli.IntFlag{"rsa-bits", 2048, "Size of RSA key to generate. Ignored if --ecdsa-curve is set", ""},
cli.StringFlag{"start-date", "", "Creation date formatted as Jan 1 15:04:05 2011", ""},
cli.DurationFlag{"duration", 365 * 24 * time.Hour, "Duration that certificate is valid for", ""},
cli.BoolFlag{"ca", "whether this cert should be its own Certificate Authority", ""},
},
} }
func runCert(ctx *cli.Context) { func runCert(ctx *cli.Context) {

4
cmd/dump.go

@ -25,11 +25,15 @@ var CmdDump = cli.Command{
It can be used for backup and capture Gogs server image to send to maintainer`, It can be used for backup and capture Gogs server image to send to maintainer`,
Action: runDump, Action: runDump,
Flags: []cli.Flag{ Flags: []cli.Flag{
cli.StringFlag{"config, c", "custom/conf/app.ini", "Custom configuration file path", ""},
cli.BoolFlag{"verbose, v", "show process details", ""}, cli.BoolFlag{"verbose, v", "show process details", ""},
}, },
} }
func runDump(ctx *cli.Context) { func runDump(ctx *cli.Context) {
if ctx.IsSet("config") {
setting.CustomConf = ctx.String("config")
}
setting.NewConfigContext() setting.NewConfigContext()
models.LoadModelsConfig() models.LoadModelsConfig()
models.SetEngine() models.SetEngine()

184
cmd/fix.go

@ -1,184 +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 cmd
import (
"bufio"
"fmt"
"io"
"io/ioutil"
"os"
"path"
"runtime"
"strings"
"github.com/Unknwon/com"
"github.com/codegangsta/cli"
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/setting"
)
var CmdFix = cli.Command{
Name: "fix",
Usage: "This command for upgrade from old version",
Action: runFix,
Subcommands: fixCommands,
Flags: []cli.Flag{},
}
func runFix(ctx *cli.Context) {
}
var fixCommands = []cli.Command{
{
Name: "location",
Usage: "Change Gogs app location",
Description: `Command location fixes location change of Gogs
gogs fix location <old Gogs path>
`,
Action: runFixLocation,
},
}
// rewriteAuthorizedKeys replaces old Gogs path to the new one.
func rewriteAuthorizedKeys(sshPath, oldPath, newPath string) error {
fr, err := os.Open(sshPath)
if err != nil {
return err
}
defer fr.Close()
tmpPath := sshPath + ".tmp"
fw, err := os.Create(tmpPath)
if err != nil {
return err
}
defer fw.Close()
oldPath = "command=\"" + oldPath + " serv"
newPath = "command=\"" + newPath + " serv"
buf := bufio.NewReader(fr)
for {
line, errRead := buf.ReadString('\n')
line = strings.TrimSpace(line)
if errRead != nil {
if errRead != io.EOF {
return errRead
}
// Reached end of file, if nothing to read then break,
// otherwise handle the last line.
if len(line) == 0 {
break
}
}
// Still finding the line, copy the line that currently read.
if _, err = fw.WriteString(strings.Replace(line, oldPath, newPath, 1) + "\n"); err != nil {
return err
}
if errRead == io.EOF {
break
}
}
if err = os.Remove(sshPath); err != nil {
return err
}
return os.Rename(tmpPath, sshPath)
}
func rewriteUpdateHook(path, appPath string) error {
if runtime.GOOS == "windows" {
rp := strings.NewReplacer("\\", "/")
appPath = "\"" + rp.Replace(appPath) + "\""
} else {
rp := strings.NewReplacer("\\", "/", " ", "\\ ")
appPath = rp.Replace(appPath)
}
if err := ioutil.WriteFile(path, []byte(fmt.Sprintf(models.TPL_UPDATE_HOOK,
setting.ScriptType, appPath)), os.ModePerm); err != nil {
return err
}
return nil
}
func walkDir(rootPath, recPath, appPath string, depth int) error {
depth++
if depth > 3 {
return nil
} else if depth == 3 {
if err := rewriteUpdateHook(path.Join(rootPath, "hooks/update"), appPath); err != nil {
return err
}
}
dir, err := os.Open(rootPath)
if err != nil {
return err
}
defer dir.Close()
fis, err := dir.Readdir(0)
if err != nil {
return err
}
for _, fi := range fis {
if strings.Contains(fi.Name(), ".DS_Store") {
continue
}
relPath := path.Join(recPath, fi.Name())
curPath := path.Join(rootPath, fi.Name())
if fi.IsDir() {
if err = walkDir(curPath, relPath, appPath, depth); err != nil {
return err
}
}
}
return nil
}
func runFixLocation(ctx *cli.Context) {
if len(ctx.Args()) != 1 {
fmt.Println("Incorrect arguments number, expect 1")
os.Exit(2)
}
execPath, _ := setting.ExecPath()
oldPath := ctx.Args().First()
fmt.Printf("Old location: %s\n", oldPath)
fmt.Println("This command should be executed in the new Gogs path")
fmt.Printf("Do you want to change Gogs app path from old location to:\n")
fmt.Printf("-> %s?\n", execPath)
fmt.Print("Press <enter> to continue, use <Ctrl+c> to exit.")
fmt.Scanln()
// Fix in authorized_keys file.
sshPath := path.Join(models.SSHPath, "authorized_keys")
if com.IsFile(sshPath) {
fmt.Printf("Fixing pathes in file: %s\n", sshPath)
if err := rewriteAuthorizedKeys(sshPath, oldPath, execPath); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
// Fix position in gogs-repositories.
setting.NewConfigContext()
fmt.Printf("Fixing pathes in repositories: %s\n", setting.RepoRootPath)
if err := walkDir(setting.RepoRootPath, "", execPath, 0); err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Println("Fix position finished!")
}

18
cmd/serve.go

@ -27,12 +27,20 @@ var CmdServ = cli.Command{
Usage: "This command should only be called by SSH shell", Usage: "This command should only be called by SSH shell",
Description: `Serv provide access auth for repositories`, Description: `Serv provide access auth for repositories`,
Action: runServ, Action: runServ,
Flags: []cli.Flag{}, Flags: []cli.Flag{
cli.StringFlag{"config, c", "custom/conf/app.ini", "Custom configuration file path", ""},
},
} }
func setup(logPath string) { func setup(logPath string) {
setting.NewConfigContext() setting.NewConfigContext()
log.NewGitLogger(filepath.Join(setting.LogRootPath, logPath)) log.NewGitLogger(filepath.Join(setting.LogRootPath, logPath))
if setting.DisableSSH {
println("Gogs: SSH has been disabled")
os.Exit(1)
}
models.LoadModelsConfig() models.LoadModelsConfig()
if models.UseSQLite3 { if models.UseSQLite3 {
@ -77,9 +85,15 @@ func In(b string, sl map[string]models.AccessType) bool {
} }
func runServ(k *cli.Context) { func runServ(k *cli.Context) {
if k.IsSet("config") {
setting.CustomConf = k.String("config")
}
setup("serv.log") setup("serv.log")
keys := strings.Split(os.Args[2], "-") if len(k.Args()) < 1 {
log.GitLogger.Fatal(2, "Not enough arguments")
}
keys := strings.Split(k.Args()[0], "-")
if len(keys) != 2 { if len(keys) != 2 {
println("Gogs: auth file format error") println("Gogs: auth file format error")
log.GitLogger.Fatal(2, "Invalid auth file format: %s", os.Args[2]) log.GitLogger.Fatal(2, "Invalid auth file format: %s", os.Args[2])

8
cmd/update.go

@ -11,6 +11,7 @@ import (
"github.com/gogits/gogs/models" "github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/setting"
) )
var CmdUpdate = cli.Command{ var CmdUpdate = cli.Command{
@ -18,10 +19,15 @@ var CmdUpdate = cli.Command{
Usage: "This command should only be called by SSH shell", Usage: "This command should only be called by SSH shell",
Description: `Update get pushed info and insert into database`, Description: `Update get pushed info and insert into database`,
Action: runUpdate, Action: runUpdate,
Flags: []cli.Flag{}, Flags: []cli.Flag{
cli.StringFlag{"config, c", "custom/conf/app.ini", "Custom configuration file path", ""},
},
} }
func runUpdate(c *cli.Context) { func runUpdate(c *cli.Context) {
if c.IsSet("config") {
setting.CustomConf = c.String("config")
}
cmd := os.Getenv("SSH_ORIGINAL_COMMAND") cmd := os.Getenv("SSH_ORIGINAL_COMMAND")
if cmd == "" { if cmd == "" {
return return

7
cmd/web.go

@ -55,6 +55,7 @@ and it takes care of all the other things for you`,
Action: runWeb, Action: runWeb,
Flags: []cli.Flag{ Flags: []cli.Flag{
cli.StringFlag{"port, p", "3000", "Temporary port number to prevent conflict", ""}, cli.StringFlag{"port, p", "3000", "Temporary port number to prevent conflict", ""},
cli.StringFlag{"config, c", "custom/conf/app.ini", "Custom configuration file path", ""},
}, },
} }
@ -165,9 +166,13 @@ func newMacaron() *macaron.Macaron {
} }
func runWeb(ctx *cli.Context) { func runWeb(ctx *cli.Context) {
routers.GlobalInit()
checkVersion() checkVersion()
if ctx.IsSet("config") {
setting.CustomConf = ctx.String("config")
}
routers.GlobalInit()
m := newMacaron() m := newMacaron()
reqSignIn := middleware.Toggle(&middleware.ToggleOptions{SignInRequire: true}) reqSignIn := middleware.Toggle(&middleware.ToggleOptions{SignInRequire: true})

8
conf/app.ini

@ -18,6 +18,8 @@ DOMAIN = localhost
ROOT_URL = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s/ ROOT_URL = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s/
HTTP_ADDR = HTTP_ADDR =
HTTP_PORT = 3000 HTTP_PORT = 3000
; Disable SSH feature when not available
DISABLE_SSH = false
SSH_PORT = 22 SSH_PORT = 22
; Disable CDN even in "prod" mode ; Disable CDN even in "prod" mode
OFFLINE_MODE = false OFFLINE_MODE = false
@ -87,6 +89,8 @@ ENABLE_REVERSE_PROXY_AUTO_REGISTERATION = false
TASK_INTERVAL = 1 TASK_INTERVAL = 1
; Deliver timeout in seconds ; Deliver timeout in seconds
DELIVER_TIMEOUT = 5 DELIVER_TIMEOUT = 5
; Allow insecure certification
SKIP_TLS_VERIFY = false
[mailer] [mailer]
ENABLED = false ENABLED = false
@ -278,5 +282,5 @@ INTERVAL = 24
ARGS = ARGS =
[i18n] [i18n]
LANGS = en-US,zh-CN,zh-HK,de-DE,fr-CA,nl-NL,lv-LV,ru-RU,ja-JP LANGS = en-US,zh-CN,zh-HK,de-DE,fr-CA,nl-NL,lv-LV,ru-RU,ja-JP,es-ES
NAMES = English,简体中文,繁體中文,Deutsch,Français,Nederlands,Latviešu,Русский,日本语 NAMES = English,简体中文,繁體中文,Deutsch,Français,Nederlands,Latviešu,Русский,日本语,Español

1
conf/locale/TRANSLATORS

@ -3,6 +3,7 @@
Akihiro YAGASAKI <yaggytter@momiage.com> Akihiro YAGASAKI <yaggytter@momiage.com>
Christoph Kisfeld <christoph.kisfeld@gmail.com> Christoph Kisfeld <christoph.kisfeld@gmail.com>
Huimin Wang <wanghm2009@hotmail.co.jp>
Thomas Fanninger <gogs.thomas@fanninger.at> Thomas Fanninger <gogs.thomas@fanninger.at>
Łukasz Jan Niemier <lukasz@niemier.pl> Łukasz Jan Niemier <lukasz@niemier.pl>
Lafriks <lafriks@gmail.com> Lafriks <lafriks@gmail.com>

25
conf/locale/locale_de-DE.ini

@ -59,6 +59,8 @@ run_user=Ausführender Benutzer
run_user_helper=Der Benutzer muss die Zugriffsberechtigung für das Repository Root-Verzeichnis haben und der ausführende Benutzer von Gogs sein. run_user_helper=Der Benutzer muss die Zugriffsberechtigung für das Repository Root-Verzeichnis haben und der ausführende Benutzer von Gogs sein.
domain=Domain domain=Domain
domain_helper=Dies hat Auswirkung auf die SSH clone URLs. domain_helper=Dies hat Auswirkung auf die SSH clone URLs.
http_port=HTTP Port
http_port_helper=Port number which application will listen on.
app_url=Anwendungs-URL app_url=Anwendungs-URL
app_url_helper=Dies hat Auswirkung auf die HTTP/HTTPS clone URLs und für die E-Mails. app_url_helper=Dies hat Auswirkung auf die HTTP/HTTPS clone URLs und für die E-Mails.
email_title=E-Mail-Service Einstellungen (optional) email_title=E-Mail-Service Einstellungen (optional)
@ -515,6 +517,11 @@ dashboard.delete_repo_archives=Alle Repository-Archive löschen
dashboard.delete_repo_archives_success=Alle Repositoriy-Archive wurden gelöscht. dashboard.delete_repo_archives_success=Alle Repositoriy-Archive wurden gelöscht.
dashboard.git_gc_repos=Führe Garbage Collection auf Repositories aus dashboard.git_gc_repos=Führe Garbage Collection auf Repositories aus
dashboard.git_gc_repos_success=Garbage Collection wurde auf allen Repositories erfolgreich ausgeführt. dashboard.git_gc_repos_success=Garbage Collection wurde auf allen Repositories erfolgreich ausgeführt.
dashboard.resync_all_sshkeys=Rewrite '.ssh/autorized_key' file (caution: non-Gogs keys will be lost)
dashboard.resync_all_sshkeys_success=All public keys have been rewritten successfully.
dashboard.resync_all_update_hooks=Rewrite all update hook of repositories (needed when custom config path is changed)
dashboard.resync_all_update_hooks_success=All repositories' update hook have been rewritten successfully.
dashboard.server_uptime=Server-Uptime dashboard.server_uptime=Server-Uptime
dashboard.current_goroutine=Aktuelle Goroutines dashboard.current_goroutine=Aktuelle Goroutines
dashboard.current_memory_usage=Aktuelle Speichernutzung dashboard.current_memory_usage=Aktuelle Speichernutzung
@ -634,6 +641,7 @@ config.db_path_helper=(nur für "sqlite3")
config.service_config=Service-Einstellungen config.service_config=Service-Einstellungen
config.register_email_confirm=E-Mail-Bestätigung bei Registrierung config.register_email_confirm=E-Mail-Bestätigung bei Registrierung
config.disable_register=Registrierung deaktivieren config.disable_register=Registrierung deaktivieren
config.show_registration_button=Show Register Button
config.require_sign_in_view=Ansehen erfordert Registrierung config.require_sign_in_view=Ansehen erfordert Registrierung
config.mail_notify=E-Mail-Benachrichtigung config.mail_notify=E-Mail-Benachrichtigung
config.enable_cache_avatar=Avatar-Cache aktivieren config.enable_cache_avatar=Avatar-Cache aktivieren
@ -689,8 +697,8 @@ notices.delete_success=System-Mitteilung erfolgreich gelöscht.
[action] [action]
create_repo=hat Repository <a href="%s/%s">%s</a> erstellt create_repo=hat Repository <a href="%s/%s">%s</a> erstellt
commit_repo=hat nach <a href="%s/%s/src/%s">%s</a> in <a href="%s/%s">%s</a> gepusht commit_repo=hat nach <a href="%s/%s/src/%s">%s</a> in <a href="%s/%s">%s</a> gepusht
create_issue=hat Issue <a href="%s/%s/issues/%s">%s#%s</a> eröffnet create_issue=`hat Issue <a href="%s/issues/%s">%[1]s#%[2]s</a> eröffnet`
comment_issue=hat Issue <a href="%s/%s/issues/%s">%s#%s</a> kommentiert comment_issue=`hat Issue <a href="%s/issues/%s">%[1]s#%[2]s</a> kommentiert`
transfer_repo=hat Repository <code>%s</code> transferiert an <a href="/%s%s">%s</a> transfer_repo=hat Repository <code>%s</code> transferiert an <a href="/%s%s">%s</a>
push_tag=hat nach <a href="%s/%s/src/%s">%s</a> in <a href="%s/%s">%s</a> gepusht push_tag=hat nach <a href="%s/%s/src/%s">%s</a> in <a href="%s/%s">%s</a> gepusht
compare_2_commits=Zeige Vergleich dieser 2 Commits compare_2_commits=Zeige Vergleich dieser 2 Commits
@ -716,16 +724,3 @@ years=%[2]s %[1]d Jahren
raw_seconds=Sekunden raw_seconds=Sekunden
raw_minutes=Minuten raw_minutes=Minuten

15
conf/locale/locale_en-US.ini

@ -67,7 +67,7 @@ email_title = E-mail Service Settings (Optional)
smtp_host = SMTP Host smtp_host = SMTP Host
mailer_user = Sender E-mail mailer_user = Sender E-mail
mailer_password = Sender Password mailer_password = Sender Password
notify_title = Notification Settings(Optional) notify_title = Notification Settings (Optional)
register_confirm = Enable Register Confirmation register_confirm = Enable Register Confirmation
mail_notify = Enable Mail Notification mail_notify = Enable Mail Notification
admin_title = Admin Account Settings admin_title = Admin Account Settings
@ -280,7 +280,7 @@ license_helper = Select a license file
init_readme = Initialize this repository with a README.md init_readme = Initialize this repository with a README.md
create_repo = Create Repository create_repo = Create Repository
default_branch = Default Branch default_branch = Default Branch
mirror_interval = Mirror Interval(hour) mirror_interval = Mirror Interval (hour)
goget_meta = Go-Get Meta goget_meta = Go-Get Meta
goget_meta_helper = This repository will be <span class="label label-blue label-radius">Go-Getable</span> goget_meta_helper = This repository will be <span class="label label-blue label-radius">Go-Getable</span>
@ -517,8 +517,11 @@ dashboard.delete_repo_archives = Delete all repositories archives
dashboard.delete_repo_archives_success = All repositories archives have been deleted successfully. dashboard.delete_repo_archives_success = All repositories archives have been deleted successfully.
dashboard.git_gc_repos = Do garbage collection on repositories dashboard.git_gc_repos = Do garbage collection on repositories
dashboard.git_gc_repos_success = All repositories have done garbage collection successfully. dashboard.git_gc_repos_success = All repositories have done garbage collection successfully.
dashboard.resync_all_sshkeys = Rewrite '.ssh/autorized_key' file(caution: non-Gogs keys will be lost) dashboard.resync_all_sshkeys = Rewrite '.ssh/autorized_key' file (caution: non-Gogs keys will be lost)
dashboard.resync_all_sshkeys_success = All public keys have been rewritten successfully. dashboard.resync_all_sshkeys_success = All public keys have been rewritten successfully.
dashboard.resync_all_update_hooks = Rewrite all update hook of repositories (needed when custom config path is changed)
dashboard.resync_all_update_hooks_success = All repositories' update hook have been rewritten successfully.
dashboard.server_uptime = Server Uptime dashboard.server_uptime = Server Uptime
dashboard.current_goroutine = Current Goroutines dashboard.current_goroutine = Current Goroutines
dashboard.current_memory_usage = Current Memory Usage dashboard.current_memory_usage = Current Memory Usage
@ -638,6 +641,7 @@ config.db_path_helper = (for "sqlite3" only)
config.service_config = Service Configuration config.service_config = Service Configuration
config.register_email_confirm = Require E-mail Confirmation config.register_email_confirm = Require E-mail Confirmation
config.disable_register = Disable Registration config.disable_register = Disable Registration
config.show_registration_button = Show Register Button
config.require_sign_in_view = Require Sign In View config.require_sign_in_view = Require Sign In View
config.mail_notify = Mail Notification config.mail_notify = Mail Notification
config.enable_cache_avatar = Enable Cache Avatar config.enable_cache_avatar = Enable Cache Avatar
@ -646,6 +650,7 @@ config.reset_password_code_lives = Reset Password Code Lives
config.webhook_config = Webhook Configuration config.webhook_config = Webhook Configuration
config.task_interval = Task Interval config.task_interval = Task Interval
config.deliver_timeout = Deliver Timeout config.deliver_timeout = Deliver Timeout
config.skip_tls_verify = Skip TLS Verify
config.mailer_config = Mailer Configuration config.mailer_config = Mailer Configuration
config.mailer_enabled = Enabled config.mailer_enabled = Enabled
config.mailer_name = Name config.mailer_name = Name
@ -693,8 +698,8 @@ notices.delete_success = System notice has been deleted successfully.
[action] [action]
create_repo = created repository <a href="%s/%s">%s</a> create_repo = created repository <a href="%s/%s">%s</a>
commit_repo = pushed to <a href="%s/%s/src/%s">%s</a> at <a href="%s/%s">%s</a> commit_repo = pushed to <a href="%s/%s/src/%s">%s</a> at <a href="%s/%s">%s</a>
create_issue = opened issue <a href="%s/%s/issues/%s">%s#%s</a> create_issue = `opened issue <a href="%s/issues/%s">%[1]s#%[2]s</a>`
comment_issue = commented on issue <a href="%s/%s/issues/%s">%s#%s</a> comment_issue = `commented on issue <a href="%s/issues/%s">%[1]s#%[2]s</a>`
transfer_repo = transfered repository <code>%s</code> to <a href="/%s%s">%s</a> transfer_repo = transfered repository <code>%s</code> to <a href="/%s%s">%s</a>
push_tag = pushed tag <a href="%s/%s/src/%s">%s</a> to <a href="%s/%s">%s</a> push_tag = pushed tag <a href="%s/%s/src/%s">%s</a> to <a href="%s/%s">%s</a>
compare_2_commits = View comparison for these 2 commits compare_2_commits = View comparison for these 2 commits

723
conf/locale/locale_es-ES.ini

@ -0,0 +1,723 @@
app_desc=Un servicio de Git auto alojado y sin complicaciones
home=Incio
dashboard=Panel de control
explore=Explorar
help=Ayuda
sign_in=Iniciar sesión
social_sign_in=Inicio de sesión social: 2° paso <small>cuenta de asociado</small>
sign_out=Cerrar sesión
sign_up=Suscripción
register=Registro
website=Pagina Web
version=Versión
page=Página
template=Plantilla
language=Lenguaje
username=Nombre de usuario
email=Correo electrónico
password=Contraseña
re_type=Ingrese de nuevo
captcha=Captcha
repository=Repositorio
organization=Organización
mirror=Espejo
new_repo=Nuevo repositorio
new_migrate=Nueva Migración
new_fork=Nuevo Fork del Repositorio
new_org=Nueva organización
manage_org=Administrar organizaciones
admin_panel=Panel de administración
account_settings=Configuraciones de la cuenta
settings=Configuraciones
news_feed=entrada de noticias
pull_requests=Solicitudes de retiro
issues=Publicaciones
cancel=Cancelar
[install]
install=Instalación
title=Pasos de la instalación por primera vez
requite_db_desc=Gogs necesita MySQL, PostgreSQL o SQLite3.
db_type=Tipo de base de datos
host=Anfitrión
user=Usuario
password=Contraseña
db_name=Nombre de la base de datos
db_helper=Por favor utilice el motor INNODB con la configuración de caracteres utf8_general_ci para MySQL.
ssl_mode=Modo SSL
path=Ruta
sqlite_helper=Ruta del archivo de la base de datos de SQLite3.
general_title=Configuraciones Generales de Gogs
repo_path=Ruta del repositorio de Raiz (Root)
repo_path_helper=Todos los repositorios remotos de Git se guardarán en este directorio.
run_user=Abrir el usuario
run_user_helper=El usuario necesita tener acceso a la Ruta Raíz del Repositorio y ejecutar Gogs.
domain=Dominio
domain_helper=Esto afecta a las URLs para clonar por SSH.
http_port=Puerto HTTP
http_port_helper=Puerto en el que escuchará la aplicación.
app_url=URL de la aplicación
app_url_helper=Esto afecta a las URLs para clonar por HTTP/HTTPS y a algunos correos electrónicos.
email_title=Configuración del Servicio de Correo (Opcional)
smtp_host=SMTP Host
mailer_user=Remitente del Correo Electrónico
mailer_password=Contraseña del Remitente
notify_title=Configuración de Notificaciones (Opcional)
register_confirm=Habilitar la Confirmación en el Registro
mail_notify=Habilitar las Notificaciones de Correo
admin_title=Configuración de la Cuenta de Administrador
admin_name=Nombre de usuario
admin_password=Contraseña
confirm_password=Confirmar Contraseña
admin_email=Correo electrónico
install_gogs=Instalar Gogs
test_git_failed=Fallo al probar el comando 'git': %v
sqlite3_not_available=Tu versión no soporta SQLite3, por favor descarga el binario oficial desde %s, NO la versión de gobuild.
invalid_db_setting=La configuración de la base de datos no es correcta: %v
invalid_repo_path=La ruta de la raíz del repositorio es inválida: %v
run_user_not_match=El usuario que está ejecutando la aplicación no es el usuario actual: %s -> %s
save_config_failed=Error al guardar la configuración: %v
invalid_admin_setting=La configuración de la cuenta de administración es inválida: %v
install_success=Bienvenido! Estamos encantados de que hayas escogido Gogs, diviértete y cuídate.
[home]
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
my_orgs=Mis Organizaciones
my_mirrors=Mis Mirrors
[explore]
repos=Repositorios
[auth]
create_new_account=Crear una Nueva Cuenta
register_hepler_msg=¿Ya tienes una cuenta? ¡Inicia sesión!
social_register_hepler_msg=¿Ya tienes una cuenta? ¡Enlázala!
disable_register_prompt=Lo sentimos, el registro está deshabilitado. Por favor, contacta con el administrador del sitio.
disable_register_mail=Lo sentimos. Los correos de Confirmación de Registro están deshabilitados.
remember_me=Recuérdame
forgot_password=He olvidado mi contraseña
forget_password=¿Has olvidado tu contraseña?
sign_up_now=¿Necesitas una cuenta? Regístrate ahora.
confirmation_mail_sent_prompt=Un nuevo correo de confirmación se ha enviado a <b>%s</b>. Por favor, comprueba tu bandeja de entrada en las siguientes %d horas para completar el proceso de registro.
sign_in_email=Inicia sesión con tu correo electrónico
active_your_account=Activa tu cuenta
resent_limit_prompt=Lo sentimos, estás solicitando el reenvío del mail de activación con demasiada frecuencia. Por favor, espera 3 minutos.
has_unconfirmed_mail=Hola %s, tu correo electrónico (<b>%s</b>) no está confirmado. Si no has recibido un correo de confirmación o necesitas que lo enviemos de nuevo, por favor, haz click en el siguiente botón.
resend_mail=Haz click aquí para reenviar tu correo electrónico de activación
email_not_associate=Esta dirección de correo electrónico no esta asociada a cuenta alguna.
send_reset_mail=Haga clic aquí para (re)enviar el correo para el restablecimiento de la contraseña
reset_password=Restablecer su contraseña
invalid_code=Lo sentimos, su código de confirmación ha expirado o no es valido.
reset_password_helper=Haga Clic aquí para restablecer su contraseña
password_too_short=La longitud de la contraseña no puede ser menor a 6.
[form]
UserName=Nombre de usuario
RepoName=Nombre del repositorio
Email=Dirección de correo electrónico
Password=Contraseña
Retype=Vuelva a escribir la contraseña
SSHTitle=Nombre de la Clave de SSH
HttpsUrl=HTTPS URL
PayloadUrl=URL de carga
TeamName=Nombre del equipo
AuthName=Nombre de autorización
AdminEmail=Correo electrónico del administrador
require_error=` no puede estar vacío.`
alpha_dash_error=` los caracteres deben ser Alfanumericos o dash(-_).`
alpha_dash_dot_error=` debe ser un caracter alfanumérivo válido, un guión alto o bajo (-_) o un signo de puntuación.`
min_size_error=` debe contener al menos %s caracteres.`
max_size_error=` debe contener como máximo %s caracteres.`
email_error=` no es una dirección de correo válida.`
url_error=` no es una URL válida.`
unknown_error=Error desconocido:
captcha_incorrect=El captcha no es válido.
password_not_match=La contraseña de confirmación no coincide.
username_been_taken=Ya existe un usuario con este nombre.
repo_name_been_taken=Ya existe un repositorio con este nombre.
org_name_been_taken=Ya existe una organización con este nombre.
team_name_been_taken=Ya existe un equipo con este nombre.
email_been_used=Esta dirección de correo electrónico ya está en uso.
ssh_key_been_used=Este nombre de clave pública ya está en uso.
illegal_username=Tu nombre de usuario contiene caracteres inválidos.
illegal_repo_name=El nombre del repositorio contiene caracteres inválidos.
illegal_org_name=El nombre de la organización contiene caracteres inválidos.
illegal_team_name=El nombre del equipo contiene caracteres inválidos.
username_password_incorrect=Nombre de usuario o contraseña incorrectos.
enterred_invalid_repo_name=Por favor, asegúrate de que has introducido correctamente el nombre del repositorio.
enterred_invalid_owner_name=Por favor, asegúrate de que has introducido correctamente el nombre del propietario.
enterred_invalid_password=Por favor, asegúrate de que has introducido correctamente tu contraseña.
user_not_exist=El usuario indicado no existe.
last_org_owner=El usuario que se intenta eliminar es el último miembro del equipo de propietarios. Debe existir otro propietario.
invalid_ssh_key=Lo sentimos, no somos capaces de verificar tu clave SSH: %s
unable_verify_ssh_key=Gogs no puede velificar tu clave SSH, pero asumimos que es válida. Por favor, asegúrate de que es así.
auth_failed=Error de autenticación: %v
still_own_repo=Tu cuenta es la propietaria de uno o más repositorios, tienes que borrarlos o transferirlos primero.
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]
change_avatar=Cambia tu avatar en gravatar.com
change_custom_avatar=Cambia tu avatar en la configuración
join_on=Registrado en
repositories=Repositorios
activity=Actividad pública
followers=Seguidores
starred=Destacados
following=Siguiendo
[settings]
profile=Perfil
password=Contraseña
ssh_keys=Claves SSH
social=Redes Sociales
applications=Aplicaciones
orgs=Organizaciones
delete=Eliminar Cuenta
uid=UUID
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.
full_name=Nombre Completo
website=Página Web
location=Localización
update_profile=Actualizar Perfil
update_profile_success=Tu perfil se ha actualizado correctamente.
change_username=Nombre de usuario modificado
change_username_desc=El nombre de usuario ha sido modificado, ¿quieres continuar? Esta acción afectará a todos los enlaces relacionados con tu cuenta.
continue=Continuar
cancel=Cancelar
enable_custom_avatar=Activar Avatar Personalizado
enable_custom_avatar_helper=Activa esto para desactivar los avatares de Gravatar
choose_new_avatar=Selecciona nuevo avatar
update_avatar=Actualizar Configuración del 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
old_password=Contraseña actual
new_password=Nueva contraseña
password_incorrect=Contraseña actual incorrecta.
change_password_success=La contraseña se ha modificado correctamente. Ya puedes iniciar sesión con tu nueva contraseña.
emails=Direcciones de correo electrónico
manage_emails=Gestionar direcciones de correo electrónico
email_desc=Tu dirección de correo principal se utilizará para las notificaciones y otras operaciones.
primary=Principal
primary_email=Marcar como principal
delete_email=Eliminar
add_new_email=Añadir nueva dirección de correo electrónico
add_email=Añadir correo electrónico
add_email_success=Tu nuevo correo electrónico se ha añadido correctamente.
manage_ssh_keys=Gestionar Claves SSH
add_key=Añadir Clave
ssh_desc=Esta es la lista de claves SSH asociadas con tu cuenta. Elimina cualquier clave que no reconozcas.
ssh_helper=<strong>¿Necesitas ayuda?</strong>. Consulta nuestra guía para <a href="%s">generar claves SSH</a> o solucionar <a href="%s">problemas comunes de SSH</a>.
add_new_key=Añadir clave SSH
key_name=Nombre de la Clave
key_content=Contenido
add_key_success=¡Se ha añadido una nueva clave SSH!
delete_key=Eliminar
add_on=Añadido en
last_used=Utilizado por última vez en
no_activity=No hay actividad reciente
manage_social=Gestionar Redes Sociales asociadas
social_desc=Esta es una lista de las Redes Sociales asociadas. Elimina cualquier vínculo que no reconozcas.
unbind=Desvincular
unbind_success=La Red Social ha sido desvinculada.
manage_access_token=Gestionar los Tokens de Acceso personales
generate_new_token=Generar nuevo Token
tokens_desc=Tokens generados que pueden ser usados para acceder al API de Gogs.
new_token_desc=Desde ahora, todos los tokens tendrán acceso completo a tu cuenta.
token_name=Nombre del Token
generate_token=Generar Token
generate_token_succees=¡Los nuevos tokens de acceso se han generado correctamente! Asegúrate de copiar tu nuevo token de acceso personal. ¡No podrás verlo de nuevo!
delete_token=Eliminar
delete_token_success=¡Los tokens de acceso personales se han eliminado correctamente! No olvides actualizar las aplicaciones que los usasen.
delete_account=Elimina tu cuenta
delete_prompt=La operación eliminará tu cuenta de forma permanente y ¡<strong>NO</strong> se puede deshacer!
confirm_delete_account=Confirmar Eliminación
delete_account_title=Eliminación de Cuenta
delete_account_desc=Esta cuenta se va a eliminar permanentemente, ¿quieres continuar?
[repo]
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="label label-red label-radius">Privado</span>
fork_repo=Hacer Fork del repositorio
fork_from=Crear un Fork desde
fork_visiblity_helper=No es posible cambiar la visibilidad de un Fork
repo_desc=Descripción
repo_lang=Idioma
repo_lang_helper=Selecciona un fichero .gitignore
license=Licencia
license_helper=Selecciona un fichero de licencia
init_readme=Crear este repositorio con un fichero README.md
create_repo=Crear Repositorio
default_branch=Rama por defecto
mirror_interval=Intervalo de mirror(en horas)
goget_meta=Go-Get Meta
goget_meta_helper=Este repositorio será <span class="label label-blue label-radius">Go-Getable</span>
need_auth=Requiere Autorización
migrate_type=Tipo de Migración
migrate_type_helper=Este repositorio será un <span class="label label-blue label-radius">Mirror</span>
migrate_repo=Migrar Repositorio
copy_link=Copiar
click_to_copy=Copiar al portapapeles
copied=Copiado correctamente
clone_helper=¿Necesitas ayuda con el clone? ¡Consulta la <a target="_blank" href="%s">Ayuda</a>!
unwatch=Dejar de vigilar
watch=Vigilar
unstar=Eliminar destacado
star=Destacar
fork=Fork
no_desc=Sin Descripción
quick_guide=Guía Rápida
clone_this_repo=Clonar este repositorio
create_new_repo_command=Crear un nuevo repositorio desde línea de comandos
push_exist_repo=Hacer Push de un repositorio existente desde línea de comandos
branch=Rama
tree=Árbol
branch_and_tags=Ramas y Etiquetas
branches=Ramas
tags=Etiquetas
issues=Incidencias
commits=Commits
releases=Releases
file_raw=Raw
file_history=Histórico
file_view_raw=Ver Raw
commits.commits=Commits
commits.search=Buscar Commits
commits.find=Buscar
commits.author=Autor
commits.message=Mensaje
commits.date=Fecha
commits.older=Anterior
commits.newer=Posterior
settings=Configuración
settings.options=Opciones
settings.collaboration=Colaboración
settings.hooks=Webhooks
settings.githooks=Git Hooks
settings.deploy_keys=Claves de Despliegue
settings.basic_settings=Configuración Básica
settings.danger_zone=Zona de Peligro
settings.site=Sitio Oficial
settings.update_settings=Actualizar Configuración
settings.change_reponame=Nombre del Repositorio Modificado
settings.change_reponame_desc=El nombre del repositorio ha sido modificado, ¿quieres continuar? Esto afectará a todos los enlaces relacionados con este repositorio.
settings.transfer=Transferir la Propiedad
settings.transfer_desc=Transferir este repositorio a otro usuario u organización donde tengas permisos de administración.
settings.new_owner_has_same_repo=El nuevo propietario tiene un repositorio con el mismo nombre.
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.transfer_notices=<p>- Perderás acceso si el nuevo propietario es un usuario individual.</p><p>- Seguirás teniendo acceso si el nuevo propietario es una organización y estás en el grupo de los propietarios.</p>
settings.update_settings_success=Las opciones del repositorio se han actualizado correctamente.
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.user_is_org_member=El usuario es miembro de la organización, no puede ser añadido como colaborador.
settings.add_webhook=Añadir Webhook
settings.hooks_desc=Los Webhooks permiten a servicios externos recibir notificaciones cuando sucedan ciertos eventos en Gogs. Cuando sucedan los eventos especificados, enviaremos una petición POST a cada una de las URLs indicadas. Para obtener más información, consulta nuestra <a target="_blank" href="%s">Guía de Webhooks</a>.
settings.githooks_desc=Los Git Hooks son una funcionalidad del propio Git, puedes editar los ficheros de los hooks soportados en la siguiente lista para aplicar operaciones personalizadas.
settings.githook_edit_desc=Si el hook no está activo, se mostrará contenido de ejemplo. Dejar el contenido vacío deshabilitará este hook.
settings.githook_name=Nombre del Hook
settings.githook_content=Contenido del Hook
settings.update_githook=Actualizar Hook
settings.remove_hook_success=El Webhook ha sido eliminado.
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.secret=Secreto
settings.event_desc=¿Qué eventos te gustaría que desencadenasen este webhook?
settings.event_push_only=Solo el evento <code>push</code>.
settings.active=Activo
settings.active_helper=Enviaremos detalles del evento cuando este hook se dispare.
settings.add_hook_success=Se ha añadido un nuevo webhook.
settings.update_webhook=Actualizar Webhook
settings.update_hook_success=Se ha actualizado el Webhook.
settings.delete_webhook=Borrar Webhook
settings.recent_deliveries=Envíos Recientes
settings.hook_type=Tipo de Hook
settings.add_slack_hook_desc=Añade integración con <a href="%s">Slack</a> a tu repositorio.
settings.slack_token=Token
settings.slack_domain=Dominio
settings.slack_channel=Canal
diff.browse_source=Explorar el Código
diff.parent=padre
diff.commit=commit
diff.data_not_available=Los datos del Diff no están disponibles.
diff.show_diff_stats=Mostrar Estadísticas de Diff
diff.stats_desc=Se han <strong>modificado %d ficheros</strong> con <strong>%d adiciones</strong> y <strong>%d borrados</strong>
diff.bin=BIN
diff.view_file=Ver Fichero
release.releases=Releases
release.new_release=Nueva Release
release.draft=Borrador
release.prerelease=Pre-Release
release.stable=Estable
release.edit=editar
release.ahead=<strong>%d</strong> commits en %s desde esta release
release.source_code=Código Fuente
release.tag_name=Nombre de la etiqueta
release.target=Destino
release.tag_helper=Escoge una etiqueta o crea una nueva al publicar.
release.release_title=Título de la Release
release.content_with_md=Contenido con formato <a href="%s">Markdown</a>
release.write=Escribir
release.preview=Vista Previa
release.content_placeholder=Escribe algo de contenido
release.loading=Cargando...
release.prerelease_desc=Esta es una pre-release
release.prerelease_helper=Esta release está marcada como no apta para producción.
release.publish=Publicar Release
release.save_draft=Guardar Borrador
release.edit_release=Editar Release
release.tag_name_already_exist=Ya existe una Release con esta etiqueta.
[org]
org_name_holder=Nombre de la Organización
org_name_helper=Los grandes nombres de organizaciones son cortos y memorables.
org_email_helper=Los correos electrónicos de las organizaciones reciben todas las notificaciones y confirmaciones.
create_org=Crear Organización
repo_updated=Actualizado
people=Personas
invite_someone=Invitar a alguien
teams=Equipos
lower_members=miembros
lower_repositories=repositorios
create_new_team=Crear un Nuevo Equipo
org_desc=Descripción
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?
team_permission_desc=¿Qué nivel de permisos debería tener este equipo?
settings=Configuración
settings.options=Opciones
settings.full_name=Nombre Completo
settings.website=Sitio Web
settings.location=Localización
settings.update_settings=Actualizar Configuración
settings.change_orgname=Nombre de la Organización Modificado
settings.change_orgname_desc=El nombre de la organización ha sido modificado, ¿quieres continuar? Esta acción afectará a todos los enlaces relacionados con esta organización.
settings.update_setting_success=La configuración de la Organización se ha actualizado correctamente.
settings.delete=Eliminar Organización
settings.delete_account=Eliminar esta Organización
settings.delete_prompt=Esta operación eliminará esta organización de manera permanente, y ¡<strong>NO PUEDE</strong> deshacerse!
settings.confirm_delete_account=Confirmar Eliminación
settings.delete_org_title=Eliminación de la Organización
settings.delete_org_desc=Esta organización se va a eliminar permanentemente, ¿quieres continuar?
settings.hooks_desc=Añadir webhooks que serán ejecutados para <strong>todos los repositorios</strong> de esta organización.
members.public=Público
members.public_helper=convertir en privado
members.private=Privado
members.private_helper=convertir en público
members.owner=Propietario
members.member=Miembro
members.conceal=Ocultar
members.remove=Eliminar
members.leave=Abandonar
members.invite_desc=Comienza a teclear un nombre de usuario para invitar a un nuevo miembro a %s:
members.invite_now=Invitar
teams.join=Unirse
teams.leave=Abandonar
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_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.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_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.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.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.
[admin]
dashboard=Dashboard
users=Usuarios
organizations=Organizaciones
repositories=Repositorios
authentication=Autenticaciones
config=Configuración
notices=Avisos del Sistema
monitor=Monitorización
prev=Anterior
next=Siguiente
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_switch=Interruptor
dashboard.operation_run=Ejecutar
dashboard.clean_unbind_oauth=Limpiar solicitudes de OAuth sin confirmar
dashboard.clean_unbind_oauth_success=Las solicitudes de OAuth sin confirmar se han eliminado correctamente.
dashboard.delete_inactivate_accounts=Eliminar todas las cuentas inactivas
dashboard.delete_inactivate_accounts_success=Todas las cuentas inactivas se han eliminado correctamente.
dashboard.delete_repo_archives=Eliminar todos los archivos de repositorios
dashboard.delete_repo_archives_success=Todos los archivos de repositorios se han eliminado correctamente.
dashboard.git_gc_repos=Ejecutar la recolección de basura en los repositorios
dashboard.git_gc_repos_success=Todos los repositorios han ejecutado correctamente el recolector de basuras.
dashboard.resync_all_sshkeys=Reescribir el fichero '.ssh/authorized_key'(atención: se perderán las claves que no pertenezcan a Gogs)
dashboard.resync_all_sshkeys_success=Todas las claves públicas se han reescrito correctamente.
dashboard.resync_all_update_hooks=Rewrite all update hook of repositories (needed when custom config path is changed)
dashboard.resync_all_update_hooks_success=All repositories' update hook have been rewritten successfully.
dashboard.server_uptime=Uptime del Servidor
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.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
dashboard.heap_memory_obtained=Memoria de Heap Obtenida
dashboard.heap_memory_idle=Memoria de Heap Inactiva
dashboard.heap_memory_in_use=Memoria de Heap en Uso
dashboard.heap_memory_released=Memoria de Heap Liberada
dashboard.heap_objects=Objetos en el Heap
dashboard.bootstrap_stack_usage=Uso de la Pila de Bootstrap
dashboard.stack_memory_obtained=Memoria de Pila Obtenida
dashboard.mspan_structures_usage=Uso de Estructuras MSpan
dashboard.mspan_structures_obtained=Estructuras MSpan Obtenidas
dashboard.mcache_structures_usage=Uso de estructuras MCache
dashboard.mcache_structures_obtained=Estructuras MCache Obtenidas
dashboard.profiling_bucket_hash_table_obtained=Profiling Bucket Hash Table Obtenido
dashboard.gc_metadata_obtained=Metadatos del Recolector de Basuras Obtenidos
dashboard.other_system_allocation_obtained=Otros Recursos del Sistema Asignados
dashboard.next_gc_recycle=Siguiente Reciclado del Recolector de Basuras
dashboard.last_gc_time=Tiempo desde el Último GC
dashboard.total_gc_time=Pausa Total por GC
dashboard.total_gc_pause=Pausa Total por GC
dashboard.last_gc_pause=Última Pausa por GC
dashboard.gc_times=GC Times
users.user_manage_panel=User Manage Panel
users.new_account=Create New Account
users.name=Name
users.activated=Activated
users.admin=Admin
users.repos=Repos
users.created=Created
users.edit=Edit
users.auth_source=Authorization Source
users.local=Local
users.auth_login_name=Authorization Login Name
users.update_profile_success=Account profile has been updated successfully.
users.edit_account=Editar Cuenta
users.is_activated=Esta cuenta está activada
users.is_admin=This account has administrator permissions
users.allow_git_hook=This account has permissions to create Git hooks
users.update_profile=Update Account Profile
users.delete_account=Delete This Account
users.still_own_repo=This account still have ownership of repository, you have to delete or transfer them first.
users.still_has_org=This account still have membership of organization, you have to left or delete them first.
orgs.org_manage_panel=Organization Manage Panel
orgs.name=Name
orgs.teams=Teams
orgs.members=Members
repos.repo_manage_panel=Repository Manage Panel
repos.owner=Owner
repos.name=Name
repos.private=Private
repos.watches=Watches
repos.stars=Stars
repos.issues=Issues
auths.auth_manage_panel=Authorization Manage Panel
auths.new=Add New Authorization Source
auths.name=Name
auths.type=Type
auths.enabled=Enabled
auths.updated=Updated
auths.auth_type=Authorization Type
auths.auth_name=Authorization Name
auths.domain=Domain
auths.host=Host
auths.port=Port
auths.base_dn=Base DN
auths.attributes=Search Attributes
auths.filter=Search Filter
auths.ms_ad_sa=Ms Ad SA
auths.smtp_auth=SMTP Authorization Type
auths.smtphost=SMTP Host
auths.smtpport=SMTP Port
auths.enable_tls=Enable TLS Encryption
auths.enable_auto_register=Enable Auto Registration
auths.tips=Consejos
auths.edit=Editar la Configuración de Autorización
auths.activated=Esta autenticación ha sido activada
auths.update_success=La Configuración de Autorización ha sido actualizada correctamente.
auths.update=Actualizar la Configuración de Autorización
auths.delete=Eliminar esta Autorización
auths.delete_auth_title=Eliminación de Autorización
auths.delete_auth_desc=Se va a eliminar esta autorización, ¿quieres continuar?
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
config.domain=Dominio
config.offline_mode=Modo Sin Conexión
config.disable_router_log=Deshabilitar Log del Router
config.run_user=Usuario de Ejecución
config.run_mode=Modo de Ejecución
config.repo_root_path=Ruta del Repositorio
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=Reverse Authentication User
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_path=Ruta
config.db_path_helper=(solo para "sqlite3")
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
config.require_sign_in_view=Solicitar la Vista de Inicio de Sesión
config.mail_notify=Notificación por Correo Electrónico
config.enable_cache_avatar=Activar la Caché de Avatar
config.active_code_lives=Active Code Lives
config.reset_password_code_lives=Reset Password Code Lives
config.webhook_config=Webhook Configuration
config.task_interval=Task Interval
config.deliver_timeout=Deliver Timeout
config.mailer_config=Mailer Configuration
config.mailer_enabled=Enabled
config.mailer_name=Name
config.mailer_host=Host
config.mailer_user=User
config.oauth_config=OAuth Configuration
config.oauth_enabled=Enabled
config.cache_config=Cache Configuration
config.cache_adapter=Cache Adapter
config.cache_interval=Cache Interval
config.cache_conn=Cache Connection
config.session_config=Session Configuration
config.session_provider=Session Provider
config.provider_config=Provider Config
config.cookie_name=Cookie Name
config.enable_set_cookie=Enable Set Cookie
config.gc_interval_time=GC Interval Time
config.session_life_time=Session Life Time
config.https_only=HTTPS Only
config.cookie_life_time=Cookie Life Time
config.picture_config=Picture Configuration
config.picture_service=Picture Service
config.disable_gravatar=Disable Gravatar
config.log_config=Log Configuration
config.log_mode=Log Mode
monitor.cron=Cron Tasks
monitor.name=Name
monitor.schedule=Schedule
monitor.next=Next Time
monitor.previous=Previous Time
monitor.execute_times=Execute Times
monitor.process=Running Processes
monitor.desc=Description
monitor.start=Start Time
monitor.execute_time=Execution Time
notices.system_notice_list=System Notices
notices.type=Type
notices.type_1=Repository
notices.desc=Description
notices.op=Op.
notices.delete_success=System notice has been deleted successfully.
[action]
create_repo=created repository <a href="%s/%s">%s</a>
commit_repo=pushed to <a href="%s/%s/src/%s">%s</a> at <a href="%s/%s">%s</a>
create_issue=`opened issue <a href="%s/issues/%s">%[1]s#%[2]s</a>`
comment_issue=`commented on issue <a href="%s/issues/%s">%[1]s#%[2]s</a>`
transfer_repo=transfered repository <code>%s</code> to <a href="/%s%s">%s</a>
push_tag=pushed tag <a href="%s/%s/src/%s">%s</a> to <a href="%s/%s">%s</a>
compare_2_commits=View comparison for these 2 commits
[tool]
ago=ago
from_now=from now
now=now
1s=1 second %s
1m=1 minute %s
1h=1 hour %s
1d=1 day %s
1w=1 week %s
1mon=1 month %s
1y=1 year %s
seconds=%d seconds %s
minutes=%d minutes %s
hours=%d hours %s
days=%d days %s
weeks=%d weeks %s
months=%d months %s
years=%d years %s
raw_seconds=seconds
raw_minutes=minutes

53
conf/locale/locale_fr-CA.ini

@ -59,9 +59,11 @@ run_user=Entrer un Utilisateur
run_user_helper=L'utilisateur doit avoir accès à la Racine du Référentiel et éxécuter Gogs. run_user_helper=L'utilisateur doit avoir accès à la Racine du Référentiel et éxécuter Gogs.
domain=Domaine domain=Domaine
domain_helper=Cela affecte les doublons d'URL SSH. domain_helper=Cela affecte les doublons d'URL SSH.
http_port=HTTP Port
http_port_helper=Port number which application will listen on.
app_url=URL de l'Application app_url=URL de l'Application
app_url_helper=Cela affecte les doublons d'URL HTTP/HTTPS et le contenu d'e-mail. app_url_helper=Cela affecte les doublons d'URL HTTP/HTTPS et le contenu d'e-mail.
email_title=E-mail Service Settings (Optional) email_title=Paramètres du Service de Messagerie (Facultatif)
smtp_host=Hôte SMTP smtp_host=Hôte SMTP
mailer_user=E-mail de l'Expéditeur mailer_user=E-mail de l'Expéditeur
mailer_password=Mot de Passe de l'Expéditeur mailer_password=Mot de Passe de l'Expéditeur
@ -109,7 +111,7 @@ confirmation_mail_sent_prompt=Un nouveau mail de confirmation à été envoyé
sign_in_email=Connexion avec l'E-mail sign_in_email=Connexion avec l'E-mail
active_your_account=Activer votre Compte active_your_account=Activer votre Compte
resent_limit_prompt=Désolé, vos tentatives d'activation sont trop fréquentes. Veuillez réessayer dans 3 minutes. resent_limit_prompt=Désolé, vos tentatives d'activation sont trop fréquentes. Veuillez réessayer dans 3 minutes.
has_unconfirmed_mail=Hi %s, you have an unconfirmed e-mail address <b>%s</b>). If you haven't received a confirmation e-mail or need to resend a new one, please click on the button below. has_unconfirmed_mail=Bonjour %s, votre adresse courriel (<b>%s</b>) n'a pas été confirmée. Si vous n'avez reçu aucun courriel de confirmation ou souhaitez renouveler l'envoi, appuyez sur le bouton ci-dessous.
resend_mail=Appuyez ici pour renvoyer un mail de confirmation resend_mail=Appuyez ici pour renvoyer un mail de confirmation
email_not_associate=Cette adresse e-mail n'est associée à aucun compte. email_not_associate=Cette adresse e-mail n'est associée à aucun compte.
send_reset_mail=Appuyez ici pour (r)envoyer le mail de réinitialisation du mot de passe send_reset_mail=Appuyez ici pour (r)envoyer le mail de réinitialisation du mot de passe
@ -192,7 +194,7 @@ delete=Supprimer le Compte
uid=ID d'Utilisateur uid=ID d'Utilisateur
public_profile=Profil Public public_profile=Profil Public
profile_desc=Your E-mail address is public and will be used for any account related notifications, and any web based operations made via the site. profile_desc=Votre adresse e-mail est publique et sera utilisée pour les notifications relatives au compte, ainsi que pour toute opération Web effectuée via le site.
full_name=Non Complet full_name=Non Complet
website=Site Web website=Site Web
location=Localisation location=Localisation
@ -217,15 +219,15 @@ new_password=Nouveau Mot de Passe
password_incorrect=Mot de passe actuel incorrect. password_incorrect=Mot de passe actuel incorrect.
change_password_success=Mot de passe modifié avec succès. Vous pouvez à présent vous connecter avec le nouveau mot de passe. change_password_success=Mot de passe modifié avec succès. Vous pouvez à présent vous connecter avec le nouveau mot de passe.
emails=E-mail Addresses emails=Adresses E-mail
manage_emails=Manage e-mail addresses manage_emails=Gérer les adresses e-mail
email_desc=Your primary e-mail address will be used for notifications and other operations. email_desc=Votre adresse e-mail principale sera utilisée pour les notifications et d'autres opérations.
primary=Primary primary=Principale
primary_email=Set as primary primary_email=Définir comme principale
delete_email=Delete delete_email=Supprimer
add_new_email=Add new e-mail address add_new_email=Ajouter une nouvelle adresse courriel
add_email=Add e-mail add_email=Ajouter un courriel
add_email_success=Your new E-mail address was successfully added. add_email_success=Votre courriel a été ajouté avec succès.
manage_ssh_keys=Gérer les clés SSH manage_ssh_keys=Gérer les clés SSH
add_key=Ajouter une Clé add_key=Ajouter une Clé
@ -417,7 +419,7 @@ release.tag_name_already_exist=Une publication avec ce nom de tag a déjà exist
[org] [org]
org_name_holder=Nom d'organisation org_name_holder=Nom d'organisation
org_name_helper=Idéalement, un nom d'organisation devrait être court et mémorable. org_name_helper=Idéalement, un nom d'organisation devrait être court et mémorable.
org_email_helper=Organization's E-mail receives all notifications and confirmations. org_email_helper=Le courriel de l'organisation recevra toutes les notifications et confirmations.
create_org=Créer une organisation create_org=Créer une organisation
repo_updated=Mis à jour repo_updated=Mis à jour
people=Contacts people=Contacts
@ -515,6 +517,11 @@ dashboard.delete_repo_archives=Supprimer toutes les archives de référentiels
dashboard.delete_repo_archives_success=Toutes les archives de référentiels ont été supprimés avec succès. dashboard.delete_repo_archives_success=Toutes les archives de référentiels ont été supprimés avec succès.
dashboard.git_gc_repos=Collecter les déchets des référentiels dashboard.git_gc_repos=Collecter les déchets des référentiels
dashboard.git_gc_repos_success=Tous les référentiels ont effectué la collecte avec succès. dashboard.git_gc_repos_success=Tous les référentiels ont effectué la collecte avec succès.
dashboard.resync_all_sshkeys=Rewrite '.ssh/autorized_key' file (caution: non-Gogs keys will be lost)
dashboard.resync_all_sshkeys_success=All public keys have been rewritten successfully.
dashboard.resync_all_update_hooks=Rewrite all update hook of repositories (needed when custom config path is changed)
dashboard.resync_all_update_hooks_success=All repositories' update hook have been rewritten successfully.
dashboard.server_uptime=Durée de Marche Serveur dashboard.server_uptime=Durée de Marche Serveur
dashboard.current_goroutine=Goroutines actuelles dashboard.current_goroutine=Goroutines actuelles
dashboard.current_memory_usage=Utilisation Mémoire actuelle dashboard.current_memory_usage=Utilisation Mémoire actuelle
@ -632,8 +639,9 @@ config.db_ssl_mode_helper=("postgres" uniquement)
config.db_path=Emplacement config.db_path=Emplacement
config.db_path_helper=("sqlite3" uniquement) config.db_path_helper=("sqlite3" uniquement)
config.service_config=Configuration du Service config.service_config=Configuration du Service
config.register_email_confirm=Require E-mail Confirmation config.register_email_confirm=Nécessite une confirmation par courriel
config.disable_register=Désactiver l'Enregistrement config.disable_register=Désactiver l'Enregistrement
config.show_registration_button=Show Register Button
config.require_sign_in_view=Connexion Obligatoire pour Visualiser config.require_sign_in_view=Connexion Obligatoire pour Visualiser
config.mail_notify=Mailer les Notifications config.mail_notify=Mailer les Notifications
config.enable_cache_avatar=Activer le Cache d'Avatar config.enable_cache_avatar=Activer le Cache d'Avatar
@ -689,8 +697,8 @@ notices.delete_success=Note système supprimée avec succès.
[action] [action]
create_repo=a crée le Référentiel <a href="%s/%s">%s</a> create_repo=a crée le Référentiel <a href="%s/%s">%s</a>
commit_repo=a soumis à <a href="%s/%s/src/%s">%s</a> chez <a href="%s/%s">%s</a> commit_repo=a soumis à <a href="%s/%s/src/%s">%s</a> chez <a href="%s/%s">%s</a>
create_issue=a ouvert un problème <a href="%s/%s/issues/%s">%s#%s</a> create_issue=`a ouvert un problème <a href="%s/issues/%s">%[1]s#%[2]s</a>`
comment_issue=a commenté le problème <a href="%s/%s/issues/%s">%s#%s</a> comment_issue=`a commenté le problème <a href="%s/issues/%s">%[1]s#%[2]s</a>`
transfer_repo=a transféré le Référentiel <code>%s</code> à <a href="/%s%s">%s</a> transfer_repo=a transféré le Référentiel <code>%s</code> à <a href="/%s%s">%s</a>
push_tag=a tagé <a href="%s/%s/src/%s">%s</a> à <a href="%s/%s">%s</a> push_tag=a tagé <a href="%s/%s/src/%s">%s</a> à <a href="%s/%s">%s</a>
compare_2_commits=Comparer ces 2 commissions compare_2_commits=Comparer ces 2 commissions
@ -716,16 +724,3 @@ years=%d ans %s
raw_seconds=secondes raw_seconds=secondes
raw_minutes=minutes raw_minutes=minutes

25
conf/locale/locale_ja-JP.ini

@ -59,6 +59,8 @@ run_user=実行ユーザ
run_user_helper=ユーザーはリポジトリ ルートパスへのアクセス、及びGogs を実行する権限を所有する必要があります。 run_user_helper=ユーザーはリポジトリ ルートパスへのアクセス、及びGogs を実行する権限を所有する必要があります。
domain=ドメイン domain=ドメイン
domain_helper=これはSSHクローンURLに影響する。 domain_helper=これはSSHクローンURLに影響する。
http_port=HTTP ポート
http_port_helper=アプリケーションが待ち受けするポート番号。
app_url=アプリケーションの URL app_url=アプリケーションの URL
app_url_helper=この設定は、HTTP / HTTPSのクローンURLおよび、一部のメールボックスへのリンクに影響を与えます。 app_url_helper=この設定は、HTTP / HTTPSのクローンURLおよび、一部のメールボックスへのリンクに影響を与えます。
email_title=E-mailサービス設定(Optional) email_title=E-mailサービス設定(Optional)
@ -515,6 +517,11 @@ dashboard.delete_repo_archives=リポジトリのすべてのアーカイブを
dashboard.delete_repo_archives_success=リポジトリのすべてのアーカイブが正常に削除されました。 dashboard.delete_repo_archives_success=リポジトリのすべてのアーカイブが正常に削除されました。
dashboard.git_gc_repos=リポジトリでのガベージコレクションを実行します。 dashboard.git_gc_repos=リポジトリでのガベージコレクションを実行します。
dashboard.git_gc_repos_success=すべてのリポジトリは正常にガベージ コレクションを行いました。 dashboard.git_gc_repos_success=すべてのリポジトリは正常にガベージ コレクションを行いました。
dashboard.resync_all_sshkeys='.ssh/ autorized_key' ファイルを再生成します。(警告:Gogsキー以外は失われます)
dashboard.resync_all_sshkeys_success=すべての公開鍵が正常に書き換えられました。
dashboard.resync_all_update_hooks=リポジトリの update フックをすべて再更新する(カスタムの設定パスが変更されたときに必要)
dashboard.resync_all_update_hooks_success=リポジトリの update フックがすべて正常に再更新されました。
dashboard.server_uptime=サーバーの稼働時間 dashboard.server_uptime=サーバーの稼働時間
dashboard.current_goroutine=現在のGoroutine dashboard.current_goroutine=現在のGoroutine
dashboard.current_memory_usage=現在のメモリ使用量 dashboard.current_memory_usage=現在のメモリ使用量
@ -634,6 +641,7 @@ config.db_path_helper=(「sqlite3」のみ)
config.service_config=サービスの構成 config.service_config=サービスの構成
config.register_email_confirm=電子メールの確認を必要 config.register_email_confirm=電子メールの確認を必要
config.disable_register=登録を無効にする config.disable_register=登録を無効にする
config.show_registration_button=登録ボタンを表示します。
config.require_sign_in_view=サインインを要求 config.require_sign_in_view=サインインを要求
config.mail_notify=メール通知 config.mail_notify=メール通知
config.enable_cache_avatar=アバターのキャッシュを有効にします。 config.enable_cache_avatar=アバターのキャッシュを有効にします。
@ -689,8 +697,8 @@ notices.delete_success=システム通知が正常に削除されました。
[action] [action]
create_repo=リポジトリ <a href="%s/%s"> %s</a>を作成しました create_repo=リポジトリ <a href="%s/%s"> %s</a>を作成しました
commit_repo=<a href="%s/%s">%s</a>を<a href="%s/%s/src/%s">%s</a>にプッシュしました commit_repo=<a href="%s/%s">%s</a>を<a href="%s/%s/src/%s">%s</a>にプッシュしました
create_issue=問題 <a href="%s/%s/issues/%s"> %s #%s</a> を開きました create_issue=`問題 <a href="%s/issues/%s">%[1]s#%[2]s</a> を開きました`
comment_issue=問題 <a href="%s/%s/issues/%s"> %s #%s</a> のコメント comment_issue=`問題 <a href="%s/issues/%s">%[1]s#%[2]s</a> のコメント`
transfer_repo=リポジトリ <code>%s</code> を <a href="/%s%s">%s</a> へ転送しました transfer_repo=リポジトリ <code>%s</code> を <a href="/%s%s">%s</a> へ転送しました
push_tag=<a href="%s/%s">%s</a> に タグ <a href="%s/%s/src/%s">%s</a> をプッシュしました push_tag=<a href="%s/%s">%s</a> に タグ <a href="%s/%s/src/%s">%s</a> をプッシュしました
compare_2_commits=これら 2 のコミットの比較を閲覧する compare_2_commits=これら 2 のコミットの比較を閲覧する
@ -716,16 +724,3 @@ years=%d 年 %s
raw_seconds= raw_seconds=
raw_minutes= raw_minutes=

25
conf/locale/locale_lv-LV.ini

@ -59,6 +59,8 @@ run_user=Izpildes lietotājs
run_user_helper=Lietotājam ir jābūt rakstīšanas tiesībām repozitorija saknes direktorijai un Gogs jābūt palaistam zem šī lietotāja. run_user_helper=Lietotājam ir jābūt rakstīšanas tiesībām repozitorija saknes direktorijai un Gogs jābūt palaistam zem šī lietotāja.
domain=Domēns domain=Domēns
domain_helper=Tas ietekmē SSH klonēšanas URL. domain_helper=Tas ietekmē SSH klonēšanas URL.
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=Lietotnes URL
app_url_helper=Tas ietekmē HTTP/HTTPS klonēšanas URL un e-pasta saturā izsūtītās saites. app_url_helper=Tas ietekmē HTTP/HTTPS klonēšanas URL un e-pasta saturā izsūtītās saites.
email_title=E-pasta pakalpojuma iestatījumi (neobligāti) email_title=E-pasta pakalpojuma iestatījumi (neobligāti)
@ -515,6 +517,11 @@ dashboard.delete_repo_archives=Dzēst visu repozitoriju arhīvus
dashboard.delete_repo_archives_success=Visu repozitoriju arhīvi tika veiksmīgi izdzēsti. dashboard.delete_repo_archives_success=Visu repozitoriju arhīvi tika veiksmīgi izdzēsti.
dashboard.git_gc_repos=Veikt repozitoriju datu sakārtošānu (git gc) dashboard.git_gc_repos=Veikt repozitoriju datu sakārtošānu (git gc)
dashboard.git_gc_repos_success=Datu sakārtošana visiem repozitorijiem veiksmīgi pabeigta. dashboard.git_gc_repos_success=Datu sakārtošana visiem repozitorijiem veiksmīgi pabeigta.
dashboard.resync_all_sshkeys=Pārrakstīt '.ssh/authorized_key' failu (brīdinājums: ne-Git atslēgas tiks pazaudētas)
dashboard.resync_all_sshkeys_success=Visas publiskās atslēgas tika veiksmīgi pārrakstītas.
dashboard.resync_all_update_hooks=Rewrite all update hook of repositories (needed when custom config path is changed)
dashboard.resync_all_update_hooks_success=All repositories' update hook have been rewritten successfully.
dashboard.server_uptime=Servera darbības laiks dashboard.server_uptime=Servera darbības laiks
dashboard.current_goroutine=Izmantotās Gorutīnas dashboard.current_goroutine=Izmantotās Gorutīnas
dashboard.current_memory_usage=Pašreiz izmantotā atmiņa dashboard.current_memory_usage=Pašreiz izmantotā atmiņa
@ -634,6 +641,7 @@ config.db_path_helper=(tikai Sqlite3 datu bāzei)
config.service_config=Pakalpojuma konfigurācija config.service_config=Pakalpojuma konfigurācija
config.register_email_confirm=Pieprasīt e-pasta apstiprināšanu config.register_email_confirm=Pieprasīt e-pasta apstiprināšanu
config.disable_register=Atspējot jaunu lietotāju reģistrāciju config.disable_register=Atspējot jaunu lietotāju reģistrāciju
config.show_registration_button=Rādīt reģistrēšanās pogu
config.require_sign_in_view=Nepieciešama autorizācija config.require_sign_in_view=Nepieciešama autorizācija
config.mail_notify=Pasta paziņojumi config.mail_notify=Pasta paziņojumi
config.enable_cache_avatar=Glabāt profila attēlus kešatmiņā config.enable_cache_avatar=Glabāt profila attēlus kešatmiņā
@ -689,8 +697,8 @@ notices.delete_success=Sistēmas paziņojums tika veiksmīgi izdzēsts.
[action] [action]
create_repo=izveidoja repozitoriju <a href="%s/%s">%s</a> create_repo=izveidoja repozitoriju <a href="%s/%s">%s</a>
commit_repo=veica izmaiņu nosūtīšanu atzaram <a href="%s/%s/src/%s">%s</a> repozitorijā <a href="%s/%s">%s</a> commit_repo=veica izmaiņu nosūtīšanu atzaram <a href="%s/%s/src/%s">%s</a> repozitorijā <a href="%s/%s">%s</a>
create_issue=reģistrēja problēmu <a href="%s/%s/issues/%s">%s#%s</a> create_issue=`reģistrēja problēmu <a href="%s/issues/%s">%[1]s#%[2]s</a>`
comment_issue=pievienoja komentāru problēmai <a href="%s/%s/issues/%s">%s#%s</a> comment_issue=`pievienoja komentāru problēmai <a href="%s/issues/%s">%[1]s#%[2]s</a>`
transfer_repo=mainīja repozitorija <code>%s</code> īpašnieku uz <a href="/%s%s">%s</a> transfer_repo=mainīja repozitorija <code>%s</code> īpašnieku uz <a href="/%s%s">%s</a>
push_tag=pievienoja tagu <a href="%s/%s/src/%s">%s</a> repozitorijam <a href="%s/%s">%s</a> push_tag=pievienoja tagu <a href="%s/%s/src/%s">%s</a> repozitorijam <a href="%s/%s">%s</a>
compare_2_commits=Veikt salīdzināšanu starp šīm 2 revīzijām compare_2_commits=Veikt salīdzināšanu starp šīm 2 revīzijām
@ -716,16 +724,3 @@ years=%d gadi %s
raw_seconds=sekundes raw_seconds=sekundes
raw_minutes=minūtes raw_minutes=minūtes

25
conf/locale/locale_nl-NL.ini

@ -59,6 +59,8 @@ run_user=Uitvoerende gebruikersnaam
run_user_helper=Deze gebruiker moet toegang hebben tot de git repositorie directorie en moet Gogs kunnen starten run_user_helper=Deze gebruiker moet toegang hebben tot de git repositorie directorie en moet Gogs kunnen starten
domain=Domein domain=Domein
domain_helper=Dit heeft invloed op de SSH kloon URLs domain_helper=Dit heeft invloed op de SSH kloon URLs
http_port=HTTP-poort
http_port_helper=Poortnummer waar het programma naar luistert.
app_url=Applicatie URL 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 app_url_helper=Dit heeft invloed op de HTTP/HTTPS kloon urls en de urls die in de email worden gebruikt
email_title=E-mail service instellingen (Optioneel) email_title=E-mail service instellingen (Optioneel)
@ -515,6 +517,11 @@ dashboard.delete_repo_archives=Verwijderen van alle repositories archieven
dashboard.delete_repo_archives_success=Alle repositories archieven hebben verwijderd. dashboard.delete_repo_archives_success=Alle repositories archieven hebben verwijderd.
dashboard.git_gc_repos=Garbage collectie uitvoeren dashboard.git_gc_repos=Garbage collectie uitvoeren
dashboard.git_gc_repos_success=Garbage collectie met succes uitgevoerd. dashboard.git_gc_repos_success=Garbage collectie met succes uitgevoerd.
dashboard.resync_all_sshkeys=Herschrijf '.ssh/authorized_keys' (Let op: alle sleutels die niet van Gogs zijn zullen verloren gaan!)
dashboard.resync_all_sshkeys_success=Alle publieke sleutels zijn herschreven.
dashboard.resync_all_update_hooks=Rewrite all update hook of repositories (needed when custom config path is changed)
dashboard.resync_all_update_hooks_success=All repositories' update hook have been rewritten successfully.
dashboard.server_uptime=Uptime server dashboard.server_uptime=Uptime server
dashboard.current_goroutine=Huidige Goroutines dashboard.current_goroutine=Huidige Goroutines
dashboard.current_memory_usage=Huidige geheugen gebruik dashboard.current_memory_usage=Huidige geheugen gebruik
@ -634,6 +641,7 @@ config.db_path_helper=(alleen voor "sqlite3")
config.service_config=Serviceconfiguratie config.service_config=Serviceconfiguratie
config.register_email_confirm=E-mailbevestiging registreren config.register_email_confirm=E-mailbevestiging registreren
config.disable_register=Registratie uitgeschakeld config.disable_register=Registratie uitgeschakeld
config.show_registration_button=Registeren knop weergeven
config.require_sign_in_view=Inloggen vereist om te kunnen inzien config.require_sign_in_view=Inloggen vereist om te kunnen inzien
config.mail_notify=E-mailnotificaties config.mail_notify=E-mailnotificaties
config.enable_cache_avatar=Avatar Cache inschakelen config.enable_cache_avatar=Avatar Cache inschakelen
@ -689,8 +697,8 @@ notices.delete_success=Systeem bericht is met succes verwijderd.
[action] [action]
create_repo=repositorie aangemaakt in <a href="%s/%s">%s</a> create_repo=repositorie aangemaakt in <a href="%s/%s">%s</a>
commit_repo=push update naar <a href="%s/%s/src/%s">%s</a> in <a href="%s/%s">%s</a commit_repo=push update naar <a href="%s/%s/src/%s">%s</a> in <a href="%s/%s">%s</a
create_issue=opende issue in <a href="%s/%s/issues/%s">%s#%s</a> create_issue=`opende issue in <a href="%s/issues/%s">%[1]s#%[2]s</a>`
comment_issue=reactie op issue <a href="%s/%s/issues/%s">%s#%s</a> comment_issue=`reactie op issue <a href="%s/issues/%s">%[1]s#%[2]s</a>`
transfer_repo=repositorie verplaatst naar <code>%s</code> naar <a href="/%s%s">%s</a> transfer_repo=repositorie verplaatst naar <code>%s</code> naar <a href="/%s%s">%s</a>
push_tag=geduwd label <a href="%s/%s/src/%s"> %s</a> naar <a href="%s/%s"> %s</a> push_tag=geduwd label <a href="%s/%s/src/%s"> %s</a> naar <a href="%s/%s"> %s</a>
compare_2_commits=Weergave vergelijking voor deze 2 commits compare_2_commits=Weergave vergelijking voor deze 2 commits
@ -716,16 +724,3 @@ years=%d jaren %s
raw_seconds=seconden raw_seconds=seconden
raw_minutes=minuten raw_minutes=minuten

27
conf/locale/locale_ru-RU.ini

@ -59,6 +59,8 @@ run_user=Пользователь
run_user_helper=У пользователя должен быть доступ к пути к корню репозитория и к запуску Gogs. run_user_helper=У пользователя должен быть доступ к пути к корню репозитория и к запуску Gogs.
domain=Домен domain=Домен
domain_helper=This affects SSH clone URLs. domain_helper=This affects SSH clone URLs.
http_port=HTTP Port
http_port_helper=Port number which application will listen on.
app_url=URL приложения app_url=URL приложения
app_url_helper=This affects HTTP/HTTPS clone URL and somewhere in e-mail. app_url_helper=This affects HTTP/HTTPS clone URL and somewhere in e-mail.
email_title=Настройки службы электронной почты (опционально) email_title=Настройки службы электронной почты (опционально)
@ -278,7 +280,7 @@ license_helper=Выберите файл лицензии
init_readme=Создать репозиторий с файлом README.md init_readme=Создать репозиторий с файлом README.md
create_repo=Создание репозитория create_repo=Создание репозитория
default_branch=Ветка по умолчанию default_branch=Ветка по умолчанию
mirror_interval=Mirror Interval(hour) mirror_interval=Mirror Interval (hour)
goget_meta=Go-Get Meta goget_meta=Go-Get Meta
goget_meta_helper=This repository will be <span class="label label-blue label-radius">Go-Getable</span> goget_meta_helper=This repository will be <span class="label label-blue label-radius">Go-Getable</span>
@ -515,6 +517,11 @@ dashboard.delete_repo_archives=Удаление всех архивов репо
dashboard.delete_repo_archives_success=Все архивы репозиториев были успешно удалены. dashboard.delete_repo_archives_success=Все архивы репозиториев были успешно удалены.
dashboard.git_gc_repos=Выполнить сборку мусора на репозиториях dashboard.git_gc_repos=Выполнить сборку мусора на репозиториях
dashboard.git_gc_repos_success=Сборка мусора на всех репозиториях успешно выполнена. dashboard.git_gc_repos_success=Сборка мусора на всех репозиториях успешно выполнена.
dashboard.resync_all_sshkeys=Rewrite '.ssh/autorized_key' file (caution: non-Gogs keys will be lost)
dashboard.resync_all_sshkeys_success=All public keys have been rewritten successfully.
dashboard.resync_all_update_hooks=Rewrite all update hook of repositories (needed when custom config path is changed)
dashboard.resync_all_update_hooks_success=All repositories' update hook have been rewritten successfully.
dashboard.server_uptime=Время непрерывной работы сервера dashboard.server_uptime=Время непрерывной работы сервера
dashboard.current_goroutine=Current Goroutines dashboard.current_goroutine=Current Goroutines
dashboard.current_memory_usage=Текущее использование памяти dashboard.current_memory_usage=Текущее использование памяти
@ -634,6 +641,7 @@ config.db_path_helper=(for "sqlite3" only)
config.service_config=Service Configuration config.service_config=Service Configuration
config.register_email_confirm=Require E-mail Confirmation config.register_email_confirm=Require E-mail Confirmation
config.disable_register=Отключить регистрацию config.disable_register=Отключить регистрацию
config.show_registration_button=Show Register Button
config.require_sign_in_view=Для просмотра необходима авторизация config.require_sign_in_view=Для просмотра необходима авторизация
config.mail_notify=Почтовые уведомления config.mail_notify=Почтовые уведомления
config.enable_cache_avatar=Кешировать аватар config.enable_cache_avatar=Кешировать аватар
@ -689,8 +697,8 @@ notices.delete_success=System notice has been deleted successfully.
[action] [action]
create_repo=создан репозиторий <a href="%s/%s"> %s</a> create_repo=создан репозиторий <a href="%s/%s"> %s</a>
commit_repo=pushed to <a href="%s/%s/src/%s">%s</a> at <a href="%s/%s">%s</a> commit_repo=pushed to <a href="%s/%s/src/%s">%s</a> at <a href="%s/%s">%s</a>
create_issue=opened issue <a href="%s/%s/issues/%s">%s#%s</a> create_issue=`opened issue <a href="%s/issues/%s">%[1]s#%[2]s</a>`
comment_issue=commented on issue <a href="%s/%s/issues/%s">%s#%s</a> comment_issue=`commented on issue <a href="%s/issues/%s">%[1]s#%[2]s</a>`
transfer_repo=transfered repository <code>%s</code> to <a href="/%s%s">%s</a> transfer_repo=transfered repository <code>%s</code> to <a href="/%s%s">%s</a>
push_tag=pushed tag <a href="%s/%s/src/%s">%s</a> to <a href="%s/%s">%s</a> push_tag=pushed tag <a href="%s/%s/src/%s">%s</a> to <a href="%s/%s">%s</a>
compare_2_commits=View comparison for these 2 commits compare_2_commits=View comparison for these 2 commits
@ -716,16 +724,3 @@ years=%d years %s
raw_seconds=seconds raw_seconds=seconds
raw_minutes=minutes raw_minutes=minutes

25
conf/locale/locale_zh-CN.ini

@ -59,6 +59,8 @@ run_user=运行系统用户
run_user_helper=该用户必须具有对仓库根目录和运行 Gogs 的操作权限。 run_user_helper=该用户必须具有对仓库根目录和运行 Gogs 的操作权限。
domain=域名 domain=域名
domain_helper=该设置影响 SSH 克隆地址。 domain_helper=该设置影响 SSH 克隆地址。
http_port=HTTP 端口号
http_port_helper=应用监听的端口号
app_url=应用 URL app_url=应用 URL
app_url_helper=该设置影响 HTTP/HTTPS 克隆地址和一些邮箱中的链接。 app_url_helper=该设置影响 HTTP/HTTPS 克隆地址和一些邮箱中的链接。
email_title=邮件服务设置(可选) email_title=邮件服务设置(可选)
@ -515,6 +517,11 @@ dashboard.delete_repo_archives=删除所有仓库存档
dashboard.delete_repo_archives_success=所有仓库存档清除成功! dashboard.delete_repo_archives_success=所有仓库存档清除成功!
dashboard.git_gc_repos=对仓库进行垃圾回收 dashboard.git_gc_repos=对仓库进行垃圾回收
dashboard.git_gc_repos_success=所有仓库垃圾回收成功! dashboard.git_gc_repos_success=所有仓库垃圾回收成功!
dashboard.resync_all_sshkeys=重新生成 '.ssh/autorized_key' 文件(警告:不是 Gogs 的密钥也会被删除)
dashboard.resync_all_sshkeys_success=所有公钥重新生成成功!
dashboard.resync_all_update_hooks=重新生成所有仓库的 Update 钩子(用于自定义配置文件被修改)
dashboard.resync_all_update_hooks_success=所有仓库的 Update 钩子重新生成成功!
dashboard.server_uptime=服务运行时间 dashboard.server_uptime=服务运行时间
dashboard.current_goroutine=当前 Goroutines 数量 dashboard.current_goroutine=当前 Goroutines 数量
dashboard.current_memory_usage=当前内存使用量 dashboard.current_memory_usage=当前内存使用量
@ -634,6 +641,7 @@ config.db_path_helper=(仅限 "sqlite3" 使用)
config.service_config=服务配置 config.service_config=服务配置
config.register_email_confirm=注册邮件确认 config.register_email_confirm=注册邮件确认
config.disable_register=关闭注册功能 config.disable_register=关闭注册功能
config.show_registration_button=显示注册按钮
config.require_sign_in_view=强制登录浏览 config.require_sign_in_view=强制登录浏览
config.mail_notify=邮件通知提醒 config.mail_notify=邮件通知提醒
config.enable_cache_avatar=开启缓存头像 config.enable_cache_avatar=开启缓存头像
@ -689,8 +697,8 @@ notices.delete_success=系统提示删除成功!
[action] [action]
create_repo=创建了仓库 <a href="%s/%s">%s</a> create_repo=创建了仓库 <a href="%s/%s">%s</a>
commit_repo=推送了 <a href="%s/%s/src/%s">%s</a> 分支的代码到 <a href="%s/%s">%s</a> commit_repo=推送了 <a href="%s/%s/src/%s">%s</a> 分支的代码到 <a href="%s/%s">%s</a>
create_issue=创建了工单 <a href="%s/%s/issues/%s">%s#%s</a> create_issue=`创建了工单 <a href="%s/issues/%s">%[1]s#%[2]s</a>`
comment_issue=评论了工单 <a href="%s/%s/issues/%s">%s#%s</a> comment_issue=`评论了工单 <a href="%s/issues/%s">%[1]s#%[2]s</a>`
transfer_repo=将仓库 <code>%s</code> 转移至 <a href="/%s%s">%s</a> transfer_repo=将仓库 <code>%s</code> 转移至 <a href="/%s%s">%s</a>
push_tag=推送了标签 <a href="%s/%s/src/%s">%s</a> 到 <a href="%s/%s">%s</a> push_tag=推送了标签 <a href="%s/%s/src/%s">%s</a> 到 <a href="%s/%s">%s</a>
compare_2_commits=查看 2 次提交的内容对比 compare_2_commits=查看 2 次提交的内容对比
@ -716,16 +724,3 @@ years=%d 年%s
raw_seconds= raw_seconds=
raw_minutes=分钟 raw_minutes=分钟

25
conf/locale/locale_zh-HK.ini

@ -59,6 +59,8 @@ run_user=執行系統用戶
run_user_helper=該用戶必須具有對倉庫根目錄和執行 Gogs 的操作權限。 run_user_helper=該用戶必須具有對倉庫根目錄和執行 Gogs 的操作權限。
domain=域名 domain=域名
domain_helper=該設置影響 SSH 複製地址。 domain_helper=該設置影響 SSH 複製地址。
http_port=HTTP 端口號
http_port_helper=應用監聽的端口號
app_url=應用 URL app_url=應用 URL
app_url_helper=該設置影響 HTTP/HTTPS 複製地址和一些郵箱中的連結。 app_url_helper=該設置影響 HTTP/HTTPS 複製地址和一些郵箱中的連結。
email_title=電子郵件服務設定(可選) email_title=電子郵件服務設定(可選)
@ -512,6 +514,11 @@ dashboard.delete_repo_archives=刪除所有倉庫存檔
dashboard.delete_repo_archives_success=所有倉庫存檔清除成功! dashboard.delete_repo_archives_success=所有倉庫存檔清除成功!
dashboard.git_gc_repos=對倉庫進行垃圾回收 dashboard.git_gc_repos=對倉庫進行垃圾回收
dashboard.git_gc_repos_success=所有倉庫的垃圾回收已成功完成! dashboard.git_gc_repos_success=所有倉庫的垃圾回收已成功完成!
dashboard.resync_all_sshkeys=重新生成 '.ssh/autorized_key' 文件(警告:不是 Gogs 的密鑰也會被刪除)
dashboard.resync_all_sshkeys_success=所有公鑰重新生成成功!
dashboard.resync_all_update_hooks=Rewrite all update hook of repositories (needed when custom config path is changed)
dashboard.resync_all_update_hooks_success=All repositories' update hook have been rewritten successfully.
dashboard.server_uptime=服務執行時間 dashboard.server_uptime=服務執行時間
dashboard.current_goroutine=當前 Goroutines 數量 dashboard.current_goroutine=當前 Goroutines 數量
dashboard.current_memory_usage=當前內存使用量 dashboard.current_memory_usage=當前內存使用量
@ -631,6 +638,7 @@ config.db_path_helper=(僅限 "sqlite3" 使用)
config.service_config=服務配置 config.service_config=服務配置
config.register_email_confirm=註冊電子郵件確認 config.register_email_confirm=註冊電子郵件確認
config.disable_register=關閉註冊功能 config.disable_register=關閉註冊功能
config.show_registration_button=顯示註冊按鈕
config.require_sign_in_view=強制登錄瀏覽 config.require_sign_in_view=強制登錄瀏覽
config.mail_notify=郵件通知提醒 config.mail_notify=郵件通知提醒
config.enable_cache_avatar=開啟緩存頭像 config.enable_cache_avatar=開啟緩存頭像
@ -686,8 +694,8 @@ notices.delete_success=系統提示刪除成功!
[action] [action]
create_repo=創建了倉庫 <a href="%s/%s">%s</a> create_repo=創建了倉庫 <a href="%s/%s">%s</a>
commit_repo=推送了 <a href="%s/%s/src/%s">%s</a> 分支的代碼到 <a href="%s/%s">%s</a> commit_repo=推送了 <a href="%s/%s/src/%s">%s</a> 分支的代碼到 <a href="%s/%s">%s</a>
create_issue=創建了問題 <a href="%s/%s/issues/%s">%s#%s</a> create_issue=`創建了問題 <a href="%s/issues/%s">%[1]s#%[2]s</a>`
comment_issue=評論了問題 <a href="%s/%s/issues/%s">%s#%s</a> comment_issue=`評論了問題 <a href="%s/issues/%s">%[1]s#%[2]s</a>`
transfer_repo=將倉庫 <code>%s</code> 轉移至 <a href="/%s%s">%s</a> transfer_repo=將倉庫 <code>%s</code> 轉移至 <a href="/%s%s">%s</a>
push_tag=推送了標籤 <a href="%s/%s/src/%s">%s</a> 到 <a href="%s/%s">%s</a> push_tag=推送了標籤 <a href="%s/%s/src/%s">%s</a> 到 <a href="%s/%s">%s</a>
compare_2_commits=查看 2 次提交的內容對比 compare_2_commits=查看 2 次提交的內容對比
@ -713,16 +721,3 @@ years=%d 年%s
raw_seconds= raw_seconds=
raw_minutes=分鐘 raw_minutes=分鐘

3
gogs.go

@ -17,7 +17,7 @@ import (
"github.com/gogits/gogs/modules/setting" "github.com/gogits/gogs/modules/setting"
) )
const APP_VER = "0.5.12.0204 Beta" const APP_VER = "0.5.13.0212 Beta"
func init() { func init() {
runtime.GOMAXPROCS(runtime.NumCPU()) runtime.GOMAXPROCS(runtime.NumCPU())
@ -33,7 +33,6 @@ func main() {
cmd.CmdWeb, cmd.CmdWeb,
cmd.CmdServ, cmd.CmdServ,
cmd.CmdUpdate, cmd.CmdUpdate,
cmd.CmdFix,
cmd.CmdDump, cmd.CmdDump,
cmd.CmdCert, cmd.CmdCert,
} }

93
models/action.go

@ -42,14 +42,21 @@ var (
var ( var (
// Same as Github. See https://help.github.com/articles/closing-issues-via-commit-messages // Same as Github. See https://help.github.com/articles/closing-issues-via-commit-messages
IssueCloseKeywords = []string{"close", "closes", "closed", "fix", "fixes", "fixed", "resolve", "resolves", "resolved"} IssueCloseKeywords = []string{"close", "closes", "closed", "fix", "fixes", "fixed", "resolve", "resolves", "resolved"}
IssueCloseKeywordsPat *regexp.Regexp IssueReopenKeywords = []string{"reopen", "reopens", "reopened"}
IssueReferenceKeywordsPat *regexp.Regexp
IssueCloseKeywordsPat, IssueReopenKeywordsPat *regexp.Regexp
IssueReferenceKeywordsPat *regexp.Regexp
) )
func assembleKeywordsPattern(words []string) string {
return fmt.Sprintf(`(?i)(?:%s) \S+`, strings.Join(words, "|"))
}
func init() { func init() {
IssueCloseKeywordsPat = regexp.MustCompile(fmt.Sprintf(`(?i)(?:%s) \S+`, strings.Join(IssueCloseKeywords, "|"))) IssueCloseKeywordsPat = regexp.MustCompile(assembleKeywordsPattern(IssueCloseKeywords))
IssueReferenceKeywordsPat = regexp.MustCompile(fmt.Sprintf(`(?i)(?:) \S+`)) IssueReopenKeywordsPat = regexp.MustCompile(assembleKeywordsPattern(IssueReopenKeywords))
IssueReferenceKeywordsPat = regexp.MustCompile(`(?i)(?:)(^| )\S+`)
} }
// Action represents user operation type and other information to repository., // Action represents user operation type and other information to repository.,
@ -92,7 +99,7 @@ func (a Action) GetRepoName() string {
} }
func (a Action) GetRepoLink() string { func (a Action) GetRepoLink() string {
return path.Join(a.RepoUserName, a.RepoName) return path.Join(setting.AppSubUrl, a.RepoUserName, a.RepoName)
} }
func (a Action) GetBranch() string { func (a Action) GetBranch() string {
@ -113,13 +120,11 @@ func (a Action) GetIssueInfos() []string {
func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, commits []*base.PushCommit) error { func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, commits []*base.PushCommit) error {
for _, c := range commits { for _, c := range commits {
references := IssueReferenceKeywordsPat.FindAllString(c.Message, -1) for _, ref := range IssueReferenceKeywordsPat.FindAllString(c.Message, -1) {
for _, ref := range references {
ref := ref[strings.IndexByte(ref, byte(' '))+1:] ref := ref[strings.IndexByte(ref, byte(' '))+1:]
ref = strings.TrimRightFunc(ref, func(c rune) bool { ref = strings.TrimRightFunc(ref, func(c rune) bool {
return !unicode.IsDigit(c) return !unicode.IsDigit(c)
}) })
if len(ref) == 0 { if len(ref) == 0 {
continue continue
@ -129,33 +134,29 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
if ref[0] == '#' { if ref[0] == '#' {
ref = fmt.Sprintf("%s/%s%s", repoUserName, repoName, ref) ref = fmt.Sprintf("%s/%s%s", repoUserName, repoName, ref)
} else if strings.Contains(ref, "/") == false { } else if strings.Contains(ref, "/") == false {
// We don't support User#ID syntax yet // FIXME: We don't support User#ID syntax yet
// return ErrNotImplemented // return ErrNotImplemented
continue continue
} }
issue, err := GetIssueByRef(ref) issue, err := GetIssueByRef(ref)
if err != nil { if err != nil {
return err return err
} }
url := fmt.Sprintf("%s/%s/%s/commit/%s", setting.AppSubUrl, repoUserName, repoName, c.Sha1) url := fmt.Sprintf("%s/%s/%s/commit/%s", setting.AppSubUrl, repoUserName, repoName, c.Sha1)
message := fmt.Sprintf(`<a href="%s">%s</a>`, url, c.Message) message := fmt.Sprintf(`<a href="%s">%s</a>`, url, c.Message)
if _, err = CreateComment(userId, issue.RepoId, issue.Id, "", "", COMMENT_TYPE_COMMIT, message, nil); err != nil {
if _, err = CreateComment(userId, issue.RepoId, issue.Id, "", "", COMMIT, message, nil); err != nil {
return err return err
} }
} }
closes := IssueCloseKeywordsPat.FindAllString(c.Message, -1) for _, ref := range IssueCloseKeywordsPat.FindAllString(c.Message, -1) {
for _, ref := range closes {
ref := ref[strings.IndexByte(ref, byte(' '))+1:] ref := ref[strings.IndexByte(ref, byte(' '))+1:]
ref = strings.TrimRightFunc(ref, func(c rune) bool { ref = strings.TrimRightFunc(ref, func(c rune) bool {
return !unicode.IsDigit(c) return !unicode.IsDigit(c)
}) })
if len(ref) == 0 { if len(ref) == 0 {
continue continue
@ -172,7 +173,6 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
} }
issue, err := GetIssueByRef(ref) issue, err := GetIssueByRef(ref)
if err != nil { if err != nil {
return err return err
} }
@ -181,7 +181,6 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
if issue.IsClosed { if issue.IsClosed {
continue continue
} }
issue.IsClosed = true issue.IsClosed = true
if err = UpdateIssue(issue); err != nil { if err = UpdateIssue(issue); err != nil {
@ -195,14 +194,60 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
} }
// If commit happened in the referenced repository, it means the issue can be closed. // If commit happened in the referenced repository, it means the issue can be closed.
if _, err = CreateComment(userId, repoId, issue.Id, "", "", CLOSE, "", nil); err != nil { if _, err = CreateComment(userId, repoId, issue.Id, "", "", COMMENT_TYPE_CLOSE, "", nil); err != nil {
return err return err
} }
} }
} }
} for _, ref := range IssueReopenKeywordsPat.FindAllString(c.Message, -1) {
ref := ref[strings.IndexByte(ref, byte(' '))+1:]
ref = strings.TrimRightFunc(ref, func(c rune) bool {
return !unicode.IsDigit(c)
})
if len(ref) == 0 {
continue
}
// Add repo name if missing
if ref[0] == '#' {
ref = fmt.Sprintf("%s/%s%s", repoUserName, repoName, ref)
} else if strings.Contains(ref, "/") == false {
// We don't support User#ID syntax yet
// return ErrNotImplemented
continue
}
issue, err := GetIssueByRef(ref)
if err != nil {
return err
}
if issue.RepoId == repoId {
if !issue.IsClosed {
continue
}
issue.IsClosed = false
if err = UpdateIssue(issue); err != nil {
return err
} else if err = UpdateIssueUserPairsByStatus(issue.Id, issue.IsClosed); err != nil {
return err
}
if err = ChangeMilestoneIssueStats(issue); err != nil {
return err
}
// If commit happened in the referenced repository, it means the issue can be closed.
if _, err = CreateComment(userId, repoId, issue.Id, 0, 0, COMMENT_TYPE_REOPEN, "", nil); err != nil {
return err
}
}
}
}
return nil return nil
} }

8
models/git_diff.go

@ -60,6 +60,8 @@ type DiffFile struct {
Index int Index int
Addition, Deletion int Addition, Deletion int
Type int Type int
IsCreated bool
IsDeleted bool
IsBin bool IsBin bool
Sections []*DiffSection Sections []*DiffSection
} }
@ -181,10 +183,16 @@ func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff
switch { switch {
case strings.HasPrefix(scanner.Text(), "new file"): case strings.HasPrefix(scanner.Text(), "new file"):
curFile.Type = DIFF_FILE_ADD curFile.Type = DIFF_FILE_ADD
curFile.IsDeleted = false
curFile.IsCreated = true
case strings.HasPrefix(scanner.Text(), "deleted"): case strings.HasPrefix(scanner.Text(), "deleted"):
curFile.Type = DIFF_FILE_DEL curFile.Type = DIFF_FILE_DEL
curFile.IsCreated = false
curFile.IsDeleted = true
case strings.HasPrefix(scanner.Text(), "index"): case strings.HasPrefix(scanner.Text(), "index"):
curFile.Type = DIFF_FILE_CHANGE curFile.Type = DIFF_FILE_CHANGE
curFile.IsCreated = false
curFile.IsDeleted = false
} }
if curFile.Type > 0 { if curFile.Type > 0 {
break break

26
models/issue.go

@ -859,22 +859,16 @@ type CommentType int
const ( const (
// Plain comment, can be associated with a commit (CommitId > 0) and a line (Line > 0) // Plain comment, can be associated with a commit (CommitId > 0) and a line (Line > 0)
COMMENT CommentType = iota COMMENT_TYPE_COMMENT CommentType = iota
COMMENT_TYPE_REOPEN
// Reopen action COMMENT_TYPE_CLOSE
REOPEN
// Close action
CLOSE
// Reference from another issue
ISSUE
// References.
COMMENT_TYPE_ISSUE
// Reference from some commit (not part of a pull request) // Reference from some commit (not part of a pull request)
COMMIT COMMENT_TYPE_COMMIT
// Reference from some pull request // Reference from some pull request
PULL COMMENT_TYPE_PULL
) )
// Comment represents a comment in commit and issue page. // Comment represents a comment in commit and issue page.
@ -908,7 +902,7 @@ func CreateComment(userId, repoId, issueId int64, commitId, line string, cmtType
// Check comment type. // Check comment type.
switch cmtType { switch cmtType {
case COMMENT: case COMMENT_TYPE_COMMENT:
rawSql := "UPDATE `issue` SET num_comments = num_comments + 1 WHERE id = ?" rawSql := "UPDATE `issue` SET num_comments = num_comments + 1 WHERE id = ?"
if _, err := sess.Exec(rawSql, issueId); err != nil { if _, err := sess.Exec(rawSql, issueId); err != nil {
sess.Rollback() sess.Rollback()
@ -929,13 +923,13 @@ func CreateComment(userId, repoId, issueId int64, commitId, line string, cmtType
return nil, err return nil, err
} }
} }
case REOPEN: case COMMENT_TYPE_REOPEN:
rawSql := "UPDATE `repository` SET num_closed_issues = num_closed_issues - 1 WHERE id = ?" rawSql := "UPDATE `repository` SET num_closed_issues = num_closed_issues - 1 WHERE id = ?"
if _, err := sess.Exec(rawSql, repoId); err != nil { if _, err := sess.Exec(rawSql, repoId); err != nil {
sess.Rollback() sess.Rollback()
return nil, err return nil, err
} }
case CLOSE: case COMMENT_TYPE_CLOSE:
rawSql := "UPDATE `repository` SET num_closed_issues = num_closed_issues + 1 WHERE id = ?" rawSql := "UPDATE `repository` SET num_closed_issues = num_closed_issues + 1 WHERE id = ?"
if _, err := sess.Exec(rawSql, repoId); err != nil { if _, err := sess.Exec(rawSql, repoId); err != nil {
sess.Rollback() sess.Rollback()

11
models/models.go

@ -15,7 +15,7 @@ import (
"github.com/go-xorm/xorm" "github.com/go-xorm/xorm"
_ "github.com/lib/pq" _ "github.com/lib/pq"
"github.com/gogits/gogs/models/migrations" // "github.com/gogits/gogs/models/migrations"
"github.com/gogits/gogs/modules/setting" "github.com/gogits/gogs/modules/setting"
) )
@ -23,7 +23,10 @@ import (
type Engine interface { type Engine interface {
Delete(interface{}) (int64, error) Delete(interface{}) (int64, error)
Exec(string, ...interface{}) (sql.Result, error) Exec(string, ...interface{}) (sql.Result, error)
Get(interface{}) (bool, error)
Insert(...interface{}) (int64, error) Insert(...interface{}) (int64, error)
Id(interface{}) *xorm.Session
Where(string, ...interface{}) *xorm.Session
} }
var ( var (
@ -133,9 +136,9 @@ func NewEngine() (err error) {
return err return err
} }
if err = migrations.Migrate(x); err != nil { // if err = migrations.Migrate(x); err != nil {
return err // return err
} // }
if err = x.StoreEngine("InnoDB").Sync2(tables...); err != nil { if err = x.StoreEngine("InnoDB").Sync2(tables...); err != nil {
return fmt.Errorf("sync database struct error: %v\n", err) return fmt.Errorf("sync database struct error: %v\n", err)

94
models/org.go

@ -12,7 +12,6 @@ import (
"strings" "strings"
"github.com/Unknwon/com" "github.com/Unknwon/com"
"github.com/go-xorm/xorm"
"github.com/gogits/gogs/modules/base" "github.com/gogits/gogs/modules/base"
) )
@ -391,7 +390,7 @@ func RemoveOrgUser(orgId, uid int64) error {
return err return err
} }
for _, t := range ts { for _, t := range ts {
if err = removeTeamMemberWithSess(org.Id, t.Id, u.Id, sess); err != nil { if err = removeTeamMember(sess, org.Id, t.Id, u.Id); err != nil {
return err return err
} }
} }
@ -486,18 +485,18 @@ func (t *Team) RemoveMember(uid int64) error {
} }
// addAccessWithAuthorize inserts or updates access with given mode. // addAccessWithAuthorize inserts or updates access with given mode.
func addAccessWithAuthorize(sess *xorm.Session, access *Access, mode AccessType) error { func addAccessWithAuthorize(e Engine, access *Access, mode AccessType) error {
has, err := x.Get(access) has, err := e.Get(access)
if err != nil { if err != nil {
return fmt.Errorf("fail to get access: %v", err) return fmt.Errorf("fail to get access: %v", err)
} }
access.Mode = mode access.Mode = mode
if has { if has {
if _, err = sess.Id(access.Id).Update(access); err != nil { if _, err = e.Id(access.Id).Update(access); err != nil {
return fmt.Errorf("fail to update access: %v", err) return fmt.Errorf("fail to update access: %v", err)
} }
} else { } else {
if _, err = sess.Insert(access); err != nil { if _, err = e.Insert(access); err != nil {
return fmt.Errorf("fail to insert access: %v", err) return fmt.Errorf("fail to insert access: %v", err)
} }
} }
@ -536,7 +535,7 @@ func (t *Team) AddRepository(repo *Repository) (err error) {
mode := AuthorizeToAccessType(t.Authorize) mode := AuthorizeToAccessType(t.Authorize)
for _, u := range t.Members { for _, u := range t.Members {
auth, err := GetHighestAuthorize(t.OrgId, u.Id, repo.Id, t.Id) auth, err := getHighestAuthorize(sess, t.OrgId, u.Id, repo.Id, t.Id)
if err != nil { if err != nil {
sess.Rollback() sess.Rollback()
return err return err
@ -552,7 +551,7 @@ func (t *Team) AddRepository(repo *Repository) (err error) {
return err return err
} }
} }
if err = WatchRepo(u.Id, repo.Id, true); err != nil { if err = watchRepo(sess, u.Id, repo.Id, true); err != nil {
sess.Rollback() sess.Rollback()
return err return err
} }
@ -593,7 +592,7 @@ func (t *Team) RemoveRepository(repoId int64) error {
// Remove access to team members. // Remove access to team members.
for _, u := range t.Members { for _, u := range t.Members {
auth, err := GetHighestAuthorize(t.OrgId, u.Id, repo.Id, t.Id) auth, err := getHighestAuthorize(sess, t.OrgId, u.Id, repo.Id, t.Id)
if err != nil { if err != nil {
sess.Rollback() sess.Rollback()
return err return err
@ -607,7 +606,7 @@ func (t *Team) RemoveRepository(repoId int64) error {
if _, err = sess.Delete(access); err != nil { if _, err = sess.Delete(access); err != nil {
sess.Rollback() sess.Rollback()
return fmt.Errorf("fail to delete access: %v", err) return fmt.Errorf("fail to delete access: %v", err)
} else if err = WatchRepo(u.Id, repo.Id, false); err != nil { } else if err = watchRepo(sess, u.Id, repo.Id, false); err != nil {
sess.Rollback() sess.Rollback()
return err return err
} }
@ -678,10 +677,9 @@ func GetTeam(orgId int64, name string) (*Team, error) {
return t, nil return t, nil
} }
// GetTeamById returns team by given ID. func getTeamById(e Engine, teamId int64) (*Team, error) {
func GetTeamById(teamId int64) (*Team, error) {
t := new(Team) t := new(Team)
has, err := x.Id(teamId).Get(t) has, err := e.Id(teamId).Get(t)
if err != nil { if err != nil {
return nil, err return nil, err
} else if !has { } else if !has {
@ -690,9 +688,13 @@ func GetTeamById(teamId int64) (*Team, error) {
return t, nil return t, nil
} }
// GetHighestAuthorize returns highest repository authorize level for given user and team. // GetTeamById returns team by given ID.
func GetHighestAuthorize(orgId, uid, repoId, teamId int64) (AuthorizeType, error) { func GetTeamById(teamId int64) (*Team, error) {
ts, err := GetUserTeams(orgId, uid) return getTeamById(x, teamId)
}
func getHighestAuthorize(e Engine, orgId, uid, repoId, teamId int64) (AuthorizeType, error) {
ts, err := getUserTeams(e, orgId, uid)
if err != nil { if err != nil {
return 0, err return 0, err
} }
@ -714,6 +716,11 @@ func GetHighestAuthorize(orgId, uid, repoId, teamId int64) (AuthorizeType, error
return auth, nil return auth, nil
} }
// GetHighestAuthorize returns highest repository authorize level for given user and team.
func GetHighestAuthorize(orgId, uid, repoId, teamId int64) (AuthorizeType, error) {
return getHighestAuthorize(x, orgId, uid, repoId, teamId)
}
// UpdateTeam updates information of team. // UpdateTeam updates information of team.
func UpdateTeam(t *Team, authChanged bool) (err error) { func UpdateTeam(t *Team, authChanged bool) (err error) {
if !IsLegalName(t.Name) { if !IsLegalName(t.Name) {
@ -866,10 +873,14 @@ type TeamUser struct {
TeamId int64 TeamId int64
} }
func isTeamMember(e Engine, orgId, teamId, uid int64) bool {
has, _ := e.Where("uid=?", uid).And("org_id=?", orgId).And("team_id=?", teamId).Get(new(TeamUser))
return has
}
// IsTeamMember returns true if given user is a member of team. // IsTeamMember returns true if given user is a member of team.
func IsTeamMember(orgId, teamId, uid int64) bool { func IsTeamMember(orgId, teamId, uid int64) bool {
has, _ := x.Where("uid=?", uid).And("org_id=?", orgId).And("team_id=?", teamId).Get(new(TeamUser)) return isTeamMember(x, orgId, teamId, uid)
return has
} }
// GetTeamMembers returns all members in given team of organization. // GetTeamMembers returns all members in given team of organization.
@ -879,17 +890,16 @@ func GetTeamMembers(orgId, teamId int64) ([]*User, error) {
return us, err return us, err
} }
// GetUserTeams returns all teams that user belongs to in given organization. func getUserTeams(e Engine, orgId, uid int64) ([]*Team, error) {
func GetUserTeams(orgId, uid int64) ([]*Team, error) {
tus := make([]*TeamUser, 0, 5) tus := make([]*TeamUser, 0, 5)
if err := x.Where("uid=?", uid).And("org_id=?", orgId).Find(&tus); err != nil { if err := e.Where("uid=?", uid).And("org_id=?", orgId).Find(&tus); err != nil {
return nil, err return nil, err
} }
ts := make([]*Team, len(tus)) ts := make([]*Team, len(tus))
for i, tu := range tus { for i, tu := range tus {
t := new(Team) t := new(Team)
has, err := x.Id(tu.TeamId).Get(t) has, err := e.Id(tu.TeamId).Get(t)
if err != nil { if err != nil {
return nil, err return nil, err
} else if !has { } else if !has {
@ -900,6 +910,11 @@ func GetUserTeams(orgId, uid int64) ([]*Team, error) {
return ts, nil return ts, nil
} }
// GetUserTeams returns all teams that user belongs to in given organization.
func GetUserTeams(orgId, uid int64) ([]*Team, error) {
return getUserTeams(x, orgId, uid)
}
// AddTeamMember adds new member to given team of given organization. // AddTeamMember adds new member to given team of given organization.
func AddTeamMember(orgId, teamId, uid int64) error { func AddTeamMember(orgId, teamId, uid int64) error {
if IsTeamMember(orgId, teamId, uid) { if IsTeamMember(orgId, teamId, uid) {
@ -956,7 +971,7 @@ func AddTeamMember(orgId, teamId, uid int64) error {
// Give access to team repositories. // Give access to team repositories.
mode := AuthorizeToAccessType(t.Authorize) mode := AuthorizeToAccessType(t.Authorize)
for _, repo := range t.Repos { for _, repo := range t.Repos {
auth, err := GetHighestAuthorize(t.OrgId, u.Id, repo.Id, teamId) auth, err := getHighestAuthorize(sess, t.OrgId, u.Id, repo.Id, teamId)
if err != nil { if err != nil {
sess.Rollback() sess.Rollback()
return err return err
@ -993,13 +1008,13 @@ func AddTeamMember(orgId, teamId, uid int64) error {
return sess.Commit() return sess.Commit()
} }
func removeTeamMemberWithSess(orgId, teamId, uid int64, sess *xorm.Session) error { func removeTeamMember(e Engine, orgId, teamId, uid int64) error {
if !IsTeamMember(orgId, teamId, uid) { if !isTeamMember(e, orgId, teamId, uid) {
return nil return nil
} }
// Get team and its repositories. // Get team and its repositories.
t, err := GetTeamById(teamId) t, err := getTeamById(e, teamId)
if err != nil { if err != nil {
return err return err
} }
@ -1033,19 +1048,16 @@ func removeTeamMemberWithSess(orgId, teamId, uid int64, sess *xorm.Session) erro
TeamId: teamId, TeamId: teamId,
} }
if _, err := sess.Delete(tu); err != nil { if _, err := e.Delete(tu); err != nil {
sess.Rollback()
return err return err
} else if _, err = sess.Id(t.Id).AllCols().Update(t); err != nil { } else if _, err = e.Id(t.Id).AllCols().Update(t); err != nil {
sess.Rollback()
return err return err
} }
// Delete access to team repositories. // Delete access to team repositories.
for _, repo := range t.Repos { for _, repo := range t.Repos {
auth, err := GetHighestAuthorize(t.OrgId, u.Id, repo.Id, teamId) auth, err := getHighestAuthorize(e, t.OrgId, u.Id, repo.Id, teamId)
if err != nil { if err != nil {
sess.Rollback()
return err return err
} }
@ -1055,17 +1067,14 @@ func removeTeamMemberWithSess(orgId, teamId, uid int64, sess *xorm.Session) erro
} }
// Delete access if this is the last team user belongs to. // Delete access if this is the last team user belongs to.
if auth == 0 { if auth == 0 {
if _, err = sess.Delete(access); err != nil { if _, err = e.Delete(access); err != nil {
sess.Rollback()
return fmt.Errorf("fail to delete access: %v", err) return fmt.Errorf("fail to delete access: %v", err)
} else if err = WatchRepo(u.Id, repo.Id, false); err != nil { } else if err = watchRepo(e, u.Id, repo.Id, false); err != nil {
sess.Rollback()
return err return err
} }
} else if auth < t.Authorize { } else if auth < t.Authorize {
// Downgrade authorize level. // Downgrade authorize level.
if err = addAccessWithAuthorize(sess, access, AuthorizeToAccessType(auth)); err != nil { if err = addAccessWithAuthorize(e, access, AuthorizeToAccessType(auth)); err != nil {
sess.Rollback()
return err return err
} }
} }
@ -1073,17 +1082,15 @@ func removeTeamMemberWithSess(orgId, teamId, uid int64, sess *xorm.Session) erro
// This must exist. // This must exist.
ou := new(OrgUser) ou := new(OrgUser)
_, err = sess.Where("uid=?", uid).And("org_id=?", org.Id).Get(ou) _, err = e.Where("uid=?", uid).And("org_id=?", org.Id).Get(ou)
if err != nil { if err != nil {
sess.Rollback()
return err return err
} }
ou.NumTeams-- ou.NumTeams--
if t.IsOwnerTeam() { if t.IsOwnerTeam() {
ou.IsOwner = false ou.IsOwner = false
} }
if _, err = sess.Id(ou.Id).AllCols().Update(ou); err != nil { if _, err = e.Id(ou.Id).AllCols().Update(ou); err != nil {
sess.Rollback()
return err return err
} }
return nil return nil
@ -1096,7 +1103,8 @@ func RemoveTeamMember(orgId, teamId, uid int64) error {
if err := sess.Begin(); err != nil { if err := sess.Begin(); err != nil {
return err return err
} }
if err := removeTeamMemberWithSess(orgId, teamId, uid, sess); err != nil { if err := removeTeamMember(sess, orgId, teamId, uid); err != nil {
sess.Rollback()
return err return err
} }
return sess.Commit() return sess.Commit()

4
models/publickey.go

@ -29,7 +29,7 @@ import (
const ( const (
// "### autogenerated by gitgos, DO NOT EDIT\n" // "### autogenerated by gitgos, DO NOT EDIT\n"
_TPL_PUBLICK_KEY = `command="%s serv key-%d",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty %s` + "\n" _TPL_PUBLICK_KEY = `command="%s serv key-%d --config='%s'",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty %s` + "\n"
) )
var ( var (
@ -98,7 +98,7 @@ func (k *PublicKey) OmitEmail() string {
// GetAuthorizedString generates and returns formatted public key string for authorized_keys file. // GetAuthorizedString generates and returns formatted public key string for authorized_keys file.
func (key *PublicKey) GetAuthorizedString() string { func (key *PublicKey) GetAuthorizedString() string {
return fmt.Sprintf(_TPL_PUBLICK_KEY, appPath, key.Id, key.Content) return fmt.Sprintf(_TPL_PUBLICK_KEY, appPath, key.Id, setting.CustomConf, key.Content)
} }
var ( var (

49
models/repo.go

@ -30,7 +30,7 @@ import (
) )
const ( const (
TPL_UPDATE_HOOK = "#!/usr/bin/env %s\n%s update $1 $2 $3\n" _TPL_UPDATE_HOOK = "#!/usr/bin/env %s\n%s update $1 $2 $3 --config='%s'\n"
) )
var ( var (
@ -247,8 +247,8 @@ func (repo *Repository) CloneLink() (cl CloneLink, err error) {
if err = repo.GetOwner(); err != nil { if err = repo.GetOwner(); err != nil {
return cl, err return cl, err
} }
if setting.SshPort != 22 { if setting.SSHPort != 22 {
cl.SSH = fmt.Sprintf("ssh://%s@%s:%d/%s/%s.git", setting.RunUser, setting.Domain, setting.SshPort, repo.Owner.LowerName, repo.LowerName) cl.SSH = fmt.Sprintf("ssh://%s@%s:%d/%s/%s.git", setting.RunUser, setting.Domain, setting.SSHPort, repo.Owner.LowerName, repo.LowerName)
} else { } else {
cl.SSH = fmt.Sprintf("%s@%s:%s/%s.git", setting.RunUser, setting.Domain, repo.Owner.LowerName, repo.LowerName) cl.SSH = fmt.Sprintf("%s@%s:%s/%s.git", setting.RunUser, setting.Domain, repo.Owner.LowerName, repo.LowerName)
} }
@ -357,13 +357,16 @@ func MigrateRepository(u *User, name, desc string, private, mirror bool, url str
os.RemoveAll(repoPath) os.RemoveAll(repoPath)
} }
// this command could for both migrate and mirror // FIXME: this command could for both migrate and mirror
_, stderr, err := process.ExecTimeout(10*time.Minute, _, stderr, err := process.ExecTimeout(10*time.Minute,
fmt.Sprintf("MigrateRepository: %s", repoPath), fmt.Sprintf("MigrateRepository: %s", repoPath),
"git", "clone", "--mirror", "--bare", url, repoPath) "git", "clone", "--mirror", "--bare", url, repoPath)
if err != nil { if err != nil {
return repo, errors.New("git clone: " + stderr) return repo, fmt.Errorf("git clone --mirror --bare: %v", stderr)
} else if err = createUpdateHook(repoPath); err != nil {
return repo, fmt.Errorf("create update hook: %v", err)
} }
return repo, UpdateRepository(repo) return repo, UpdateRepository(repo)
} }
@ -402,15 +405,9 @@ func initRepoCommit(tmpPath string, sig *git.Signature) (err error) {
return nil return nil
} }
func createHookUpdate(hookPath, content string) error { func createUpdateHook(repoPath string) error {
pu, err := os.OpenFile(hookPath, os.O_CREATE|os.O_WRONLY, 0777) return ioutil.WriteFile(path.Join(repoPath, "hooks/update"),
if err != nil { []byte(fmt.Sprintf(_TPL_UPDATE_HOOK, setting.ScriptType, "\""+appPath+"\"", setting.CustomConf)), 0777)
return err
}
defer pu.Close()
_, err = pu.WriteString(content)
return err
} }
// InitRepository initializes README and .gitignore if needed. // InitRepository initializes README and .gitignore if needed.
@ -422,9 +419,7 @@ func initRepository(f string, u *User, repo *Repository, initReadme bool, repoLa
return err return err
} }
// hook/post-update if err := createUpdateHook(repoPath); err != nil {
if err := createHookUpdate(filepath.Join(repoPath, "hooks", "update"),
fmt.Sprintf(TPL_UPDATE_HOOK, setting.ScriptType, "\""+appPath+"\"")); err != nil {
return err return err
} }
@ -1174,6 +1169,18 @@ func DeleteRepositoryArchives() error {
}) })
} }
// RewriteRepositoryUpdateHook rewrites all repositories' update hook.
func RewriteRepositoryUpdateHook() error {
return x.Where("id > 0").Iterate(new(Repository),
func(idx int, bean interface{}) error {
repo := bean.(*Repository)
if err := repo.GetOwner(); err != nil {
return err
}
return createUpdateHook(RepoPath(repo.Owner.Name, repo.Name))
})
}
var ( var (
// Prevent duplicate tasks. // Prevent duplicate tasks.
isMirrorUpdating = false isMirrorUpdating = false
@ -1289,7 +1296,7 @@ func IsWatching(uid, repoId int64) bool {
return has return has
} }
func watchRepoWithEngine(e Engine, uid, repoId int64, watch bool) (err error) { func watchRepo(e Engine, uid, repoId int64, watch bool) (err error) {
if watch { if watch {
if IsWatching(uid, repoId) { if IsWatching(uid, repoId) {
return nil return nil
@ -1312,7 +1319,7 @@ func watchRepoWithEngine(e Engine, uid, repoId int64, watch bool) (err error) {
// Watch or unwatch repository. // Watch or unwatch repository.
func WatchRepo(uid, repoId int64, watch bool) (err error) { func WatchRepo(uid, repoId int64, watch bool) (err error) {
return watchRepoWithEngine(x, uid, repoId, watch) return watchRepo(x, uid, repoId, watch)
} }
// GetWatchers returns all watchers of given repository. // GetWatchers returns all watchers of given repository.
@ -1500,14 +1507,14 @@ func ForkRepository(u *User, oldRepo *Repository, name, desc string) (*Repositor
log.Error(4, "GetMembers: %v", err) log.Error(4, "GetMembers: %v", err)
} else { } else {
for _, u := range t.Members { for _, u := range t.Members {
if err = watchRepoWithEngine(sess, u.Id, repo.Id, true); err != nil { if err = watchRepo(sess, u.Id, repo.Id, true); err != nil {
log.Error(4, "WatchRepo2: %v", err) log.Error(4, "WatchRepo2: %v", err)
} }
} }
} }
} }
} else { } else {
if err = watchRepoWithEngine(sess, u.Id, repo.Id, true); err != nil { if err = watchRepo(sess, u.Id, repo.Id, true); err != nil {
log.Error(4, "WatchRepo3: %v", err) log.Error(4, "WatchRepo3: %v", err)
} }
} }

14
models/webhook.go

@ -5,6 +5,7 @@
package models package models
import ( import (
"crypto/tls"
"encoding/json" "encoding/json"
"errors" "errors"
"io/ioutil" "io/ioutil"
@ -307,13 +308,14 @@ func DeliverHooks() {
defer func() { isShooting = false }() defer func() { isShooting = false }()
tasks := make([]*HookTask, 0, 10) tasks := make([]*HookTask, 0, 10)
timeout := time.Duration(setting.WebhookDeliverTimeout) * time.Second timeout := time.Duration(setting.Webhook.DeliverTimeout) * time.Second
x.Where("is_delivered=?", false).Iterate(new(HookTask), x.Where("is_delivered=?", false).Iterate(new(HookTask),
func(idx int, bean interface{}) error { func(idx int, bean interface{}) error {
t := bean.(*HookTask) t := bean.(*HookTask)
req := httplib.Post(t.Url).SetTimeout(timeout, timeout). req := httplib.Post(t.Url).SetTimeout(timeout, timeout).
Header("X-Gogs-Delivery", t.Uuid). Header("X-Gogs-Delivery", t.Uuid).
Header("X-Gogs-Event", string(t.EventType)) Header("X-Gogs-Event", string(t.EventType)).
SetTLSClientConfig(&tls.Config{InsecureSkipVerify: setting.Webhook.SkipTLSVerify})
switch t.ContentType { switch t.ContentType {
case JSON: case JSON:
@ -329,7 +331,7 @@ func DeliverHooks() {
case GOGS: case GOGS:
{ {
if _, err := req.Response(); err != nil { if _, err := req.Response(); err != nil {
log.Error(4, "Delivery: %v", err) log.Error(5, "Delivery: %v", err)
} else { } else {
t.IsSucceed = true t.IsSucceed = true
} }
@ -337,15 +339,15 @@ func DeliverHooks() {
case SLACK: case SLACK:
{ {
if res, err := req.Response(); err != nil { if res, err := req.Response(); err != nil {
log.Error(4, "Delivery: %v", err) log.Error(5, "Delivery: %v", err)
} else { } else {
defer res.Body.Close() defer res.Body.Close()
contents, err := ioutil.ReadAll(res.Body) contents, err := ioutil.ReadAll(res.Body)
if err != nil { if err != nil {
log.Error(4, "%s", err) log.Error(5, "%s", err)
} else { } else {
if string(contents) != "ok" { if string(contents) != "ok" {
log.Error(4, "slack failed with: %s", string(contents)) log.Error(5, "slack failed with: %s", string(contents))
} else { } else {
t.IsSucceed = true t.IsSucceed = true
} }

8
modules/asn1-ber/ber.go

@ -256,11 +256,11 @@ func ReadPacket(reader io.Reader) (*Packet, error) {
} }
func DecodeString(data []byte) (ret string) { func DecodeString(data []byte) (ret string) {
for _, c := range data { // for _, c := range data {
ret += fmt.Sprintf("%c", c) // ret += fmt.Sprintf("%c", c)
} // }
return return string(data)
} }
func DecodeInteger(data []byte) (ret uint64) { func DecodeInteger(data []byte) (ret uint64) {

7
modules/base/markdown.go

@ -106,7 +106,7 @@ func (options *CustomRender) Image(out *bytes.Buffer, link []byte, title []byte,
} }
var ( var (
MentionPattern = regexp.MustCompile(`@[0-9a-zA-Z_]{1,}`) MentionPattern = regexp.MustCompile(`(\s|^)@[0-9a-zA-Z_]+`)
commitPattern = regexp.MustCompile(`(\s|^)https?.*commit/[0-9a-zA-Z]+(#+[0-9a-zA-Z-]*)?`) commitPattern = regexp.MustCompile(`(\s|^)https?.*commit/[0-9a-zA-Z]+(#+[0-9a-zA-Z-]*)?`)
issueFullPattern = regexp.MustCompile(`(\s|^)https?.*issues/[0-9]+(#+[0-9a-zA-Z-]*)?`) issueFullPattern = regexp.MustCompile(`(\s|^)https?.*issues/[0-9]+(#+[0-9a-zA-Z-]*)?`)
issueIndexPattern = regexp.MustCompile(`( |^)#[0-9]+`) issueIndexPattern = regexp.MustCompile(`( |^)#[0-9]+`)
@ -128,6 +128,7 @@ func RenderSpecialLink(rawBytes []byte, urlPrefix string) []byte {
if !inCodeBlock && !bytes.HasPrefix(line, tab) { if !inCodeBlock && !bytes.HasPrefix(line, tab) {
ms := MentionPattern.FindAll(line, -1) ms := MentionPattern.FindAll(line, -1)
for _, m := range ms { for _, m := range ms {
m = bytes.TrimSpace(m)
line = bytes.Replace(line, m, line = bytes.Replace(line, m,
[]byte(fmt.Sprintf(`<a href="%s/%s">%s</a>`, setting.AppSubUrl, m[1:], m)), -1) []byte(fmt.Sprintf(`<a href="%s/%s">%s</a>`, setting.AppSubUrl, m[1:], m)), -1)
} }
@ -177,8 +178,8 @@ func RenderSha1CurrentPattern(rawBytes []byte, urlPrefix string) []byte {
func RenderIssueIndexPattern(rawBytes []byte, urlPrefix string) []byte { func RenderIssueIndexPattern(rawBytes []byte, urlPrefix string) []byte {
ms := issueIndexPattern.FindAll(rawBytes, -1) ms := issueIndexPattern.FindAll(rawBytes, -1)
for _, m := range ms { for _, m := range ms {
rawBytes = bytes.Replace(rawBytes, m, []byte(fmt.Sprintf( rawBytes = bytes.Replace(rawBytes, m, []byte(fmt.Sprintf(`<a href="%s/issues/%s">%s</a>`,
`<a href="%s/issues/%s">%s</a>`, urlPrefix, m[1:], m)), -1) urlPrefix, strings.TrimPrefix(string(m[1:]), "#"), m)), -1)
} }
return rawBytes return rawBytes
} }

2
modules/cron/manager.go

@ -15,7 +15,7 @@ var c = New()
func NewCronContext() { func NewCronContext() {
c.AddFunc("Update mirrors", "@every 1h", models.MirrorUpdate) c.AddFunc("Update mirrors", "@every 1h", models.MirrorUpdate)
c.AddFunc("Deliver hooks", fmt.Sprintf("@every %dm", setting.WebhookTaskInterval), models.DeliverHooks) c.AddFunc("Deliver hooks", fmt.Sprintf("@every %dm", setting.Webhook.TaskInterval), models.DeliverHooks)
if setting.Git.Fsck.Enable { if setting.Git.Fsck.Enable {
c.AddFunc("Repository health check", fmt.Sprintf("@every %dh", setting.Git.Fsck.Interval), models.GitFsck) c.AddFunc("Repository health check", fmt.Sprintf("@every %dh", setting.Git.Fsck.Interval), models.GitFsck)
} }

5
modules/middleware/auth.go

@ -6,7 +6,6 @@ package middleware
import ( import (
"net/url" "net/url"
"strings"
"github.com/Unknwon/macaron" "github.com/Unknwon/macaron"
"github.com/macaron-contrib/csrf" "github.com/macaron-contrib/csrf"
@ -50,10 +49,6 @@ func Toggle(options *ToggleOptions) macaron.Handler {
if options.SignInRequire { if options.SignInRequire {
if !ctx.IsSigned { if !ctx.IsSigned {
// Ignore watch repository operation.
if strings.HasSuffix(ctx.Req.RequestURI, "watch") {
return
}
ctx.SetCookie("redirect_to", url.QueryEscape(setting.AppSubUrl+ctx.Req.RequestURI), 0, setting.AppSubUrl) ctx.SetCookie("redirect_to", url.QueryEscape(setting.AppSubUrl+ctx.Req.RequestURI), 0, setting.AppSubUrl)
ctx.Redirect(setting.AppSubUrl + "/user/login") ctx.Redirect(setting.AppSubUrl + "/user/login")
return return

2
modules/middleware/context.go

@ -192,6 +192,8 @@ func Contexter() macaron.Handler {
ctx.Data["CsrfToken"] = x.GetToken() ctx.Data["CsrfToken"] = x.GetToken()
ctx.Data["CsrfTokenHtml"] = template.HTML(`<input type="hidden" name="_csrf" value="` + x.GetToken() + `">`) ctx.Data["CsrfTokenHtml"] = template.HTML(`<input type="hidden" name="_csrf" value="` + x.GetToken() + `">`)
ctx.Data["ShowRegistrationButton"] = setting.Service.ShowRegistrationButton
c.Map(ctx) c.Map(ctx)
} }
} }

1
modules/middleware/repo.go

@ -386,6 +386,7 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
ctx.Data["IsRepositoryOwner"] = ctx.Repo.IsOwner ctx.Data["IsRepositoryOwner"] = ctx.Repo.IsOwner
ctx.Data["IsRepositoryTrueOwner"] = ctx.Repo.IsTrueOwner ctx.Data["IsRepositoryTrueOwner"] = ctx.Repo.IsTrueOwner
ctx.Data["DisableSSH"] = setting.DisableSSH
ctx.Repo.CloneLink, err = repo.CloneLink() ctx.Repo.CloneLink, err = repo.CloneLink()
if err != nil { if err != nil {
ctx.Handle(500, "CloneLink", err) ctx.Handle(500, "CloneLink", err)

39
modules/setting/setting.go

@ -50,7 +50,8 @@ var (
Protocol Scheme Protocol Scheme
Domain string Domain string
HttpAddr, HttpPort string HttpAddr, HttpPort string
SshPort int DisableSSH bool
SSHPort int
OfflineMode bool OfflineMode bool
DisableRouterLog bool DisableRouterLog bool
CertFile, KeyFile string CertFile, KeyFile string
@ -67,8 +68,11 @@ var (
ReverseProxyAuthUser string ReverseProxyAuthUser string
// Webhook settings. // Webhook settings.
WebhookTaskInterval int Webhook struct {
WebhookDeliverTimeout int TaskInterval int
DeliverTimeout int
SkipTLSVerify bool
}
// Repository settings. // Repository settings.
RepoRootPath string RepoRootPath string
@ -124,6 +128,7 @@ var (
Cfg *ini.File Cfg *ini.File
ConfRootPath string ConfRootPath string
CustomPath string // Custom directory path. CustomPath string // Custom directory path.
CustomConf string
ProdMode bool ProdMode bool
RunUser string RunUser string
IsWindows bool IsWindows bool
@ -172,13 +177,16 @@ func NewConfigContext() {
CustomPath = path.Join(workDir, "custom") CustomPath = path.Join(workDir, "custom")
} }
cfgPath := path.Join(CustomPath, "conf/app.ini") if len(CustomConf) == 0 {
if com.IsFile(cfgPath) { CustomConf = path.Join(CustomPath, "conf/app.ini")
if err = Cfg.Append(cfgPath); err != nil { }
log.Fatal(4, "Fail to load custom 'conf/app.ini': %v", err)
if com.IsFile(CustomConf) {
if err = Cfg.Append(CustomConf); err != nil {
log.Fatal(4, "Fail to load custom conf '%s': %v", CustomConf, err)
} }
} else { } else {
log.Warn("No custom 'conf/app.ini' found, ignore this if you're running first time") log.Warn("Custom config (%s) not found, ignore this if you're running first time", CustomConf)
} }
Cfg.NameMapper = ini.AllCapsUnderscore Cfg.NameMapper = ini.AllCapsUnderscore
@ -209,7 +217,8 @@ func NewConfigContext() {
Domain = sec.Key("DOMAIN").MustString("localhost") Domain = sec.Key("DOMAIN").MustString("localhost")
HttpAddr = sec.Key("HTTP_ADDR").MustString("0.0.0.0") HttpAddr = sec.Key("HTTP_ADDR").MustString("0.0.0.0")
HttpPort = sec.Key("HTTP_PORT").MustString("3000") HttpPort = sec.Key("HTTP_PORT").MustString("3000")
SshPort = sec.Key("SSH_PORT").MustInt(22) DisableSSH = sec.Key("DISABLE_SSH").MustBool()
SSHPort = sec.Key("SSH_PORT").MustInt(22)
OfflineMode = sec.Key("OFFLINE_MODE").MustBool() OfflineMode = sec.Key("OFFLINE_MODE").MustBool()
DisableRouterLog = sec.Key("DISABLE_ROUTER_LOG").MustBool() DisableRouterLog = sec.Key("DISABLE_ROUTER_LOG").MustBool()
StaticRootPath = sec.Key("STATIC_ROOT_PATH").MustString(workDir) StaticRootPath = sec.Key("STATIC_ROOT_PATH").MustString(workDir)
@ -231,7 +240,7 @@ func NewConfigContext() {
ReverseProxyAuthUser = sec.Key("REVERSE_PROXY_AUTHENTICATION_USER").MustString("X-WEBAUTH-USER") ReverseProxyAuthUser = sec.Key("REVERSE_PROXY_AUTHENTICATION_USER").MustString("X-WEBAUTH-USER")
sec = Cfg.Section("attachment") sec = Cfg.Section("attachment")
AttachmentPath = sec.Key("PATH").MustString("data/attachments") AttachmentPath = path.Join(workDir, sec.Key("PATH").MustString("data/attachments"))
AttachmentAllowedTypes = sec.Key("ALLOWED_TYPES").MustString("image/jpeg|image/png") AttachmentAllowedTypes = sec.Key("ALLOWED_TYPES").MustString("image/jpeg|image/png")
AttachmentMaxSize = sec.Key("MAX_SIZE").MustInt64(32) AttachmentMaxSize = sec.Key("MAX_SIZE").MustInt64(32)
AttachmentMaxFiles = sec.Key("MAX_FILES").MustInt(10) AttachmentMaxFiles = sec.Key("MAX_FILES").MustInt(10)
@ -288,7 +297,7 @@ func NewConfigContext() {
sec = Cfg.Section("picture") sec = Cfg.Section("picture")
PictureService = sec.Key("SERVICE").In("server", []string{"server"}) PictureService = sec.Key("SERVICE").In("server", []string{"server"})
AvatarUploadPath = sec.Key("AVATAR_UPLOAD_PATH").MustString("data/avatars") AvatarUploadPath = path.Join(workDir, sec.Key("AVATAR_UPLOAD_PATH").MustString("data/avatars"))
os.MkdirAll(AvatarUploadPath, os.ModePerm) os.MkdirAll(AvatarUploadPath, os.ModePerm)
switch sec.Key("GRAVATAR_SOURCE").MustString("gravatar") { switch sec.Key("GRAVATAR_SOURCE").MustString("gravatar") {
case "duoshuo": case "duoshuo":
@ -311,6 +320,7 @@ func NewConfigContext() {
var Service struct { var Service struct {
RegisterEmailConfirm bool RegisterEmailConfirm bool
DisableRegistration bool DisableRegistration bool
ShowRegistrationButton bool
RequireSignInView bool RequireSignInView bool
EnableCacheAvatar bool EnableCacheAvatar bool
EnableNotifyMail bool EnableNotifyMail bool
@ -324,6 +334,7 @@ func newService() {
Service.ActiveCodeLives = Cfg.Section("service").Key("ACTIVE_CODE_LIVE_MINUTES").MustInt(180) Service.ActiveCodeLives = Cfg.Section("service").Key("ACTIVE_CODE_LIVE_MINUTES").MustInt(180)
Service.ResetPwdCodeLives = Cfg.Section("service").Key("RESET_PASSWD_CODE_LIVE_MINUTES").MustInt(180) Service.ResetPwdCodeLives = Cfg.Section("service").Key("RESET_PASSWD_CODE_LIVE_MINUTES").MustInt(180)
Service.DisableRegistration = Cfg.Section("service").Key("DISABLE_REGISTRATION").MustBool() Service.DisableRegistration = Cfg.Section("service").Key("DISABLE_REGISTRATION").MustBool()
Service.ShowRegistrationButton = Cfg.Section("service").Key("SHOW_REGISTRATION_BUTTON").MustBool(!Service.DisableRegistration)
Service.RequireSignInView = Cfg.Section("service").Key("REQUIRE_SIGNIN_VIEW").MustBool() Service.RequireSignInView = Cfg.Section("service").Key("REQUIRE_SIGNIN_VIEW").MustBool()
Service.EnableCacheAvatar = Cfg.Section("service").Key("ENABLE_CACHE_AVATAR").MustBool() Service.EnableCacheAvatar = Cfg.Section("service").Key("ENABLE_CACHE_AVATAR").MustBool()
Service.EnableReverseProxyAuth = Cfg.Section("service").Key("ENABLE_REVERSE_PROXY_AUTHENTICATION").MustBool() Service.EnableReverseProxyAuth = Cfg.Section("service").Key("ENABLE_REVERSE_PROXY_AUTHENTICATION").MustBool()
@ -500,8 +511,10 @@ func newNotifyMailService() {
} }
func newWebhookService() { func newWebhookService() {
WebhookTaskInterval = Cfg.Section("webhook").Key("TASK_INTERVAL").MustInt(1) sec := Cfg.Section("webhook")
WebhookDeliverTimeout = Cfg.Section("webhook").Key("DELIVER_TIMEOUT").MustInt(5) Webhook.TaskInterval = sec.Key("TASK_INTERVAL").MustInt(1)
Webhook.DeliverTimeout = sec.Key("DELIVER_TIMEOUT").MustInt(5)
Webhook.SkipTLSVerify = sec.Key("SKIP_TLS_VERIFY").MustBool()
} }
func NewServices() { func NewServices() {

17
public/ng/css/gogs.css

@ -367,6 +367,9 @@ img.avatar-100 {
.markdown table tr:nth-child(2n) { .markdown table tr:nth-child(2n) {
background-color: #F8F8F8; background-color: #F8F8F8;
} }
.markdown p {
margin: 20px 0;
}
.markdown a { .markdown a {
color: #428BCA; color: #428BCA;
} }
@ -1066,6 +1069,9 @@ The register and sign-in page style
#repo-header-download-drop .btn > i { #repo-header-download-drop .btn > i {
margin-right: 6px; margin-right: 6px;
} }
#repo-header-download-drop input {
cursor: default;
}
#repo-header-download-drop button, #repo-header-download-drop button,
#repo-header-download-drop input { #repo-header-download-drop input {
font-size: 11px; font-size: 11px;
@ -1218,6 +1224,9 @@ The register and sign-in page style
#repo-files-table { #repo-files-table {
margin-bottom: 20px; margin-bottom: 20px;
} }
#repo-files-table .sha .label {
font-family: Monaco, Menlo, Consolas, "Courier New", monospace;
}
#repo-files-table th, #repo-files-table th,
#repo-files-table td { #repo-files-table td {
text-align: left; text-align: left;
@ -1660,6 +1669,14 @@ The register and sign-in page style
background-color: #E0E0E0 !important; background-color: #E0E0E0 !important;
border-color: #ADADAD !important; border-color: #ADADAD !important;
} }
.diff-file-box .code-diff tbody tr.tag-code td.selected-line,
.diff-file-box .code-diff tbody tr.tag-code td.selected-line pre {
background-color: #ffffdd !important;
}
.diff-file-box .code-diff tbody tr.same-code td.selected-line,
.diff-file-box .code-diff tbody tr.same-code td.selected-line pre {
background-color: #ffffdd !important;
}
.diff-file-box .code-diff tbody tr.del-code td, .diff-file-box .code-diff tbody tr.del-code td,
.diff-file-box .code-diff tbody tr.del-code pre { .diff-file-box .code-diff tbody tr.del-code pre {
background-color: #ffe2dd !important; background-color: #ffe2dd !important;

167
public/ng/less/gogs/markdown.less

@ -1,88 +1,91 @@
.markdown { .markdown {
background-color: white; background-color: white;
font-size: 16px; font-size: 16px;
line-height: 24px; line-height: 24px;
.markdown-body { .markdown-body {
padding-left: 24px; padding-left: 24px;
padding-right: 16px; padding-right: 16px;
} }
h5, h5,
h6 { h6 {
font-size: 1em; font-size: 1em;
} }
ul { ul {
padding: 10px 0 0 15px; padding: 10px 0 0 15px;
li {
list-style: inside;
}
}
ol li {
list-style: decimal inside;
}
li { li {
line-height: 1.6; list-style: inside;
margin-top: 6px; }
&:first-child { }
margin-top: 0; ol li {
} list-style: decimal inside;
} }
li {
line-height: 1.6;
margin-top: 6px;
&:first-child {
margin-top: 0;
}
}
code {
padding: 0.2em 0.5em;
margin: 0;
background-color: rgba(0,0,0,0.04);
border-radius: 3px;
}
>pre {
font-size: 14px;
line-height: 1.6;
overflow: auto;
border: 1px solid #ddd;
border-radius: .25em;
margin: 5px 0;
padding: 10px;
background-color: #f8f8f8;
code { code {
padding: 0.2em 0.5em; padding: 0;
margin: 0; background-color: inherit;
background-color: rgba(0,0,0,0.04); }
border-radius: 3px; }
} img {
>pre { padding: 10px 0;
font-size: 14px; max-width: 100%;
line-height: 1.6; }
overflow: auto; blockquote {
border: 1px solid #ddd; border-left: 4px solid #ddd;
border-radius: .25em; margin-bottom: 16px;
margin: 5px 0; p {
padding: 10px; font-size: 14px;
background-color: #f8f8f8; padding: 5px 15px;
code { color: #777;
padding: 0; }
background-color: inherit; }
} table {
} display: block;
img { width: 100%;
padding: 10px 0; overflow: auto;
max-width: 100%; word-break: normal;
} margin: 15px 0;
blockquote { border-collapse: collapse;
border-left: 4px solid #ddd; border-spacing: 0;
margin-bottom: 16px; display: block;
p { th {
font-size: 14px; font-weight: 700;
padding: 5px 15px; }
color: #777; th, td {
} border: 1px solid #DDD;
} padding: 6px 13px !important;
table { }
display: block; tr {
width: 100%; background-color: #FFF;
overflow: auto; border-top: 1px solid #CCC;
word-break: normal; &:nth-child(2n) {
margin: 15px 0; background-color: #F8F8F8;
border-collapse: collapse; }
border-spacing: 0; }
display: block; }
th { p {
font-weight: 700; margin: 20px 0;
} }
th, td {
border: 1px solid #DDD;
padding: 6px 13px !important;
}
tr {
background-color: #FFF;
border-top: 1px solid #CCC;
&:nth-child(2n) {
background-color: #F8F8F8;
}
}
}
} }
.markdown a { .markdown a {
color: #428BCA; color: #428BCA;

14
public/ng/less/gogs/repository.less

@ -81,6 +81,9 @@
.btn>i { .btn>i {
margin-right: 6px; margin-right: 6px;
} }
input {
cursor: default;
}
button, input { button, input {
font-size: 11px; font-size: 11px;
} }
@ -247,6 +250,9 @@
} }
#repo-files-table { #repo-files-table {
margin-bottom: 20px; margin-bottom: 20px;
.sha .label {
font-family: Monaco,Menlo,Consolas,"Courier New",monospace;
}
th, td { th, td {
text-align: left; text-align: left;
line-height: 32px; line-height: 32px;
@ -688,6 +694,14 @@
background-color: #E0E0E0 !important; background-color: #E0E0E0 !important;
border-color: #ADADAD !important; border-color: #ADADAD !important;
} }
td.selected-line, td.selected-line pre {
background-color: #ffffdd !important;
}
}
&.same-code {
td.selected-line, td.selected-line pre {
background-color: #ffffdd !important;
}
} }
&.del-code { &.del-code {
td, pre { td, pre {

9
routers/admin/admin.go

@ -119,6 +119,7 @@ const (
CLEAN_REPO_ARCHIVES CLEAN_REPO_ARCHIVES
GIT_GC_REPOS GIT_GC_REPOS
SYNC_SSH_AUTHORIZED_KEY SYNC_SSH_AUTHORIZED_KEY
SYNC_REPOSITORY_UPDATE_HOOK
) )
func Dashboard(ctx *middleware.Context) { func Dashboard(ctx *middleware.Context) {
@ -148,6 +149,9 @@ func Dashboard(ctx *middleware.Context) {
case SYNC_SSH_AUTHORIZED_KEY: case SYNC_SSH_AUTHORIZED_KEY:
success = ctx.Tr("admin.dashboard.resync_all_sshkeys_success") success = ctx.Tr("admin.dashboard.resync_all_sshkeys_success")
err = models.RewriteAllPublicKeys() err = models.RewriteAllPublicKeys()
case SYNC_REPOSITORY_UPDATE_HOOK:
success = ctx.Tr("admin.dashboard.resync_all_update_hooks_success")
err = models.RewriteRepositoryUpdateHook()
} }
if err != nil { if err != nil {
@ -184,11 +188,8 @@ func Config(ctx *middleware.Context) {
ctx.Data["ReverseProxyAuthUser"] = setting.ReverseProxyAuthUser ctx.Data["ReverseProxyAuthUser"] = setting.ReverseProxyAuthUser
ctx.Data["Service"] = setting.Service ctx.Data["Service"] = setting.Service
ctx.Data["DbCfg"] = models.DbCfg ctx.Data["DbCfg"] = models.DbCfg
ctx.Data["Webhook"] = setting.Webhook
ctx.Data["WebhookTaskInterval"] = setting.WebhookTaskInterval
ctx.Data["WebhookDeliverTimeout"] = setting.WebhookDeliverTimeout
ctx.Data["MailerEnabled"] = false ctx.Data["MailerEnabled"] = false
if setting.MailService != nil { if setting.MailService != nil {

5
routers/install.go

@ -9,6 +9,7 @@ import (
"os" "os"
"os/exec" "os/exec"
"path" "path"
"path/filepath"
"strings" "strings"
"github.com/Unknwon/com" "github.com/Unknwon/com"
@ -221,8 +222,8 @@ func InstallPost(ctx *middleware.Context, form auth.InstallForm) {
cfg.Section("security").Key("INSTALL_LOCK").SetValue("true") cfg.Section("security").Key("INSTALL_LOCK").SetValue("true")
cfg.Section("security").Key("SECRET_KEY").SetValue(base.GetRandomString(15)) cfg.Section("security").Key("SECRET_KEY").SetValue(base.GetRandomString(15))
os.MkdirAll("custom/conf", os.ModePerm) os.MkdirAll(filepath.Dir(setting.CustomConf), os.ModePerm)
if err := cfg.SaveTo(path.Join(setting.CustomPath, "conf/app.ini")); err != nil { if err := cfg.SaveTo(setting.CustomConf); err != nil {
ctx.RenderWithErr(ctx.Tr("install.save_config_failed", err), INSTALL, &form) ctx.RenderWithErr(ctx.Tr("install.save_config_failed", err), INSTALL, &form)
return return
} }

7
routers/org/teams.go

@ -138,11 +138,8 @@ func TeamsRepoAction(ctx *middleware.Context) {
} }
if err != nil { if err != nil {
log.Error(3, "Action(%s): %v", ctx.Params(":action"), err) log.Error(3, "Action(%s): '%s' %v", ctx.Params(":action"), ctx.Org.Team.Name, err)
ctx.JSON(200, map[string]interface{}{ ctx.Handle(500, "TeamsRepoAction", err)
"ok": false,
"err": err.Error(),
})
return return
} }
ctx.Redirect(ctx.Org.OrgLink + "/teams/" + ctx.Org.Team.LowerName + "/repositories") ctx.Redirect(ctx.Org.OrgLink + "/teams/" + ctx.Org.Team.LowerName + "/repositories")

4
routers/repo/commit.go

@ -288,6 +288,9 @@ func Diff(ctx *middleware.Context) {
ctx.Data["Comments"] = commentsMap ctx.Data["Comments"] = commentsMap
ctx.Data["DiffNotAvailable"] = diff.NumFiles() == 0 ctx.Data["DiffNotAvailable"] = diff.NumFiles() == 0
ctx.Data["SourcePath"] = setting.AppSubUrl + "/" + path.Join(userName, repoName, "src", commitId) ctx.Data["SourcePath"] = setting.AppSubUrl + "/" + path.Join(userName, repoName, "src", commitId)
if (commit.ParentCount() > 0) {
ctx.Data["BeforeSourcePath"] = setting.AppSubUrl + "/" + path.Join(userName, repoName, "src", parents[0])
}
ctx.Data["RawPath"] = setting.AppSubUrl + "/" + path.Join(userName, repoName, "raw", commitId) ctx.Data["RawPath"] = setting.AppSubUrl + "/" + path.Join(userName, repoName, "raw", commitId)
ctx.HTML(200, DIFF) ctx.HTML(200, DIFF)
} }
@ -351,6 +354,7 @@ func CompareDiff(ctx *middleware.Context) {
ctx.Data["Diff"] = diff ctx.Data["Diff"] = diff
ctx.Data["DiffNotAvailable"] = diff.NumFiles() == 0 ctx.Data["DiffNotAvailable"] = diff.NumFiles() == 0
ctx.Data["SourcePath"] = setting.AppSubUrl + "/" + path.Join(userName, repoName, "src", afterCommitId) ctx.Data["SourcePath"] = setting.AppSubUrl + "/" + path.Join(userName, repoName, "src", afterCommitId)
ctx.Data["BeforeSourcePath"] = setting.AppSubUrl + "/" + path.Join(userName, repoName, "src", beforeCommitId)
ctx.Data["RawPath"] = setting.AppSubUrl + "/" + path.Join(userName, repoName, "raw", afterCommitId) ctx.Data["RawPath"] = setting.AppSubUrl + "/" + path.Join(userName, repoName, "raw", afterCommitId)
ctx.HTML(200, DIFF) ctx.HTML(200, DIFF)
} }

54
routers/repo/http.go

@ -73,11 +73,14 @@ func Http(ctx *middleware.Context) {
return return
} }
// only public pull don't need auth // Only public pull don't need auth.
isPublicPull := !repo.IsPrivate && isPull isPublicPull := !repo.IsPrivate && isPull
var askAuth = !isPublicPull || setting.Service.RequireSignInView var (
var authUser *models.User askAuth = !isPublicPull || setting.Service.RequireSignInView
var authUsername, passwd string authUser *models.User
authUsername string
authPasswd string
)
// check access // check access
if askAuth { if askAuth {
@ -90,12 +93,13 @@ func Http(ctx *middleware.Context) {
auths := strings.Fields(baHead) auths := strings.Fields(baHead)
// currently check basic auth // currently check basic auth
// TODO: support digit auth // TODO: support digit auth
// FIXME: middlewares/context.go did basic auth check already // FIXME: middlewares/context.go did basic auth check already,
// maybe could use that one.
if len(auths) != 2 || auths[0] != "Basic" { if len(auths) != 2 || auths[0] != "Basic" {
ctx.Handle(401, "no basic auth and digit auth", nil) ctx.Handle(401, "no basic auth and digit auth", nil)
return return
} }
authUsername, passwd, err = base.BasicAuthDecode(auths[1]) authUsername, authPasswd, err = base.BasicAuthDecode(auths[1])
if err != nil { if err != nil {
ctx.Handle(401, "no basic auth and digit auth", nil) ctx.Handle(401, "no basic auth and digit auth", nil)
return return
@ -103,15 +107,33 @@ func Http(ctx *middleware.Context) {
authUser, err = models.GetUserByName(authUsername) authUser, err = models.GetUserByName(authUsername)
if err != nil { if err != nil {
ctx.Handle(401, "no basic auth and digit auth", nil) if err != models.ErrUserNotExist {
return ctx.Handle(500, "GetUserByName", err)
} return
}
newUser := &models.User{Passwd: passwd, Salt: authUser.Salt} // Assume username now is a token.
newUser.EncodePasswd() token, err := models.GetAccessTokenBySha(authUsername)
if authUser.Passwd != newUser.Passwd { if err != nil {
ctx.Handle(401, "no basic auth and digit auth", nil) if err == models.ErrAccessTokenNotExist {
return ctx.Handle(401, "invalid token", nil)
} else {
ctx.Handle(500, "GetAccessTokenBySha", err)
}
return
}
authUser, err = models.GetUserById(token.Uid)
if err != nil {
ctx.Handle(500, "GetUserById", err)
return
}
authUsername = authUser.Name
} else {
// Check user's password when username is correctly presented.
if !authUser.ValidtePassword(authPasswd) {
ctx.Handle(401, "invalid password", nil)
return
}
} }
if !isPublicPull { if !isPublicPull {
@ -139,9 +161,7 @@ func Http(ctx *middleware.Context) {
} }
} }
var f func(rpc string, input []byte) var f = func(rpc string, input []byte) {
f = func(rpc string, input []byte) {
if rpc == "receive-pack" { if rpc == "receive-pack" {
var lastLine int64 = 0 var lastLine int64 = 0

24
routers/repo/issue.go

@ -424,7 +424,7 @@ func ViewIssue(ctx *middleware.Context) {
} }
comments[i].Poster = u comments[i].Poster = u
if comments[i].Type == models.COMMENT { if comments[i].Type == models.COMMENT_TYPE_COMMENT {
comments[i].Content = string(base.RenderMarkdown([]byte(comments[i].Content), ctx.Repo.RepoLink)) comments[i].Content = string(base.RenderMarkdown([]byte(comments[i].Content), ctx.Repo.RepoLink))
} }
} }
@ -774,9 +774,9 @@ func Comment(ctx *middleware.Context) {
} }
} }
cmtType := models.CLOSE cmtType := models.COMMENT_TYPE_CLOSE
if !issue.IsClosed { if !issue.IsClosed {
cmtType = models.REOPEN cmtType = models.COMMENT_TYPE_REOPEN
} }
if _, err = models.CreateComment(ctx.User.Id, ctx.Repo.Repository.Id, issue.Id, "", "", cmtType, "", nil); err != nil { if _, err = models.CreateComment(ctx.User.Id, ctx.Repo.Repository.Id, issue.Id, "", "", cmtType, "", nil); err != nil {
@ -795,7 +795,7 @@ func Comment(ctx *middleware.Context) {
if len(content) > 0 || len(ctx.Req.MultipartForm.File["attachments"]) > 0 { if len(content) > 0 || len(ctx.Req.MultipartForm.File["attachments"]) > 0 {
switch ctx.Params(":action") { switch ctx.Params(":action") {
case "new": case "new":
if comment, err = models.CreateComment(ctx.User.Id, ctx.Repo.Repository.Id, issue.Id, "", "", models.COMMENT, content, nil); err != nil { if comment, err = models.CreateComment(ctx.User.Id, ctx.Repo.Repository.Id, issue.Id, "", "", models.COMMENT_TYPE_COMMENT, content, nil); err != nil {
send(500, nil, err) send(500, nil, err)
return return
} }
@ -1122,18 +1122,18 @@ func IssueGetAttachment(ctx *middleware.Context) {
// testing route handler for new issue ui page // testing route handler for new issue ui page
// todo : move to Issue() function // todo : move to Issue() function
func Issues2(ctx *middleware.Context){ func Issues2(ctx *middleware.Context) {
ctx.HTML(200,"repo/issue2/list") ctx.HTML(200, "repo/issue2/list")
} }
func PullRequest2(ctx *middleware.Context){ func PullRequest2(ctx *middleware.Context) {
ctx.HTML(200,"repo/pr2/list") ctx.HTML(200, "repo/pr2/list")
} }
func Labels2(ctx *middleware.Context){ func Labels2(ctx *middleware.Context) {
ctx.HTML(200,"repo/issue2/labels") ctx.HTML(200, "repo/issue2/labels")
} }
func Milestones2(ctx *middleware.Context){ func Milestones2(ctx *middleware.Context) {
ctx.HTML(200,"repo/milestone2/list") ctx.HTML(200, "repo/milestone2/list")
} }

12
routers/repo/view.go

@ -127,7 +127,6 @@ func Home(ctx *middleware.Context) {
entries.Sort() entries.Sort()
files := make([][]interface{}, 0, len(entries)) files := make([][]interface{}, 0, len(entries))
for _, te := range entries { for _, te := range entries {
if te.Type != git.COMMIT { if te.Type != git.COMMIT {
c, err := ctx.Repo.Commit.GetCommitOfRelPath(filepath.Join(treePath, te.Name())) c, err := ctx.Repo.Commit.GetCommitOfRelPath(filepath.Join(treePath, te.Name()))
@ -151,16 +150,6 @@ func Home(ctx *middleware.Context) {
files = append(files, []interface{}{te, git.NewSubModuleFile(c, sm.Url, te.Id.String())}) files = append(files, []interface{}{te, git.NewSubModuleFile(c, sm.Url, te.Id.String())})
} }
} }
// Render issue index links.
for _, f := range files {
switch c := f[1].(type) {
case *git.Commit:
c.CommitMessage = c.CommitMessage
case *git.SubModuleFile:
c.CommitMessage = c.CommitMessage
}
}
ctx.Data["Files"] = files ctx.Data["Files"] = files
var readmeFile *git.Blob var readmeFile *git.Blob
@ -208,7 +197,6 @@ func Home(ctx *middleware.Context) {
} }
lastCommit := ctx.Repo.Commit lastCommit := ctx.Repo.Commit
lastCommit.CommitMessage = string(base.RenderIssueIndexPattern([]byte(lastCommit.CommitMessage), ctx.Repo.RepoLink))
if len(treePath) > 0 { if len(treePath) > 0 {
c, err := ctx.Repo.Commit.GetCommitOfRelPath(treePath) c, err := ctx.Repo.Commit.GetCommitOfRelPath(treePath)
if err != nil { if err != nil {

2
templates/.VERSION

@ -1 +1 @@
0.5.12.0204 Beta 0.5.13.0212 Beta

8
templates/admin/config.tmpl

@ -78,6 +78,8 @@
<dd><i class="fa fa{{if .Service.RegisterEmailConfirm}}-check{{end}}-square-o"></i></dd> <dd><i class="fa fa{{if .Service.RegisterEmailConfirm}}-check{{end}}-square-o"></i></dd>
<dt>{{.i18n.Tr "admin.config.disable_register"}}</dt> <dt>{{.i18n.Tr "admin.config.disable_register"}}</dt>
<dd><i class="fa fa{{if .Service.DisableRegistration}}-check{{end}}-square-o"></i></dd> <dd><i class="fa fa{{if .Service.DisableRegistration}}-check{{end}}-square-o"></i></dd>
<dt>{{.i18n.Tr "admin.config.show_registration_button"}}</dt>
<dd><i class="fa fa{{if .Service.ShowRegistrationButton}}-check{{end}}-square-o"></i></dd>
<dt>{{.i18n.Tr "admin.config.require_sign_in_view"}}</dt> <dt>{{.i18n.Tr "admin.config.require_sign_in_view"}}</dt>
<dd><i class="fa fa{{if .Service.RequireSignInView}}-check{{end}}-square-o"></i></dd> <dd><i class="fa fa{{if .Service.RequireSignInView}}-check{{end}}-square-o"></i></dd>
<dt>{{.i18n.Tr "admin.config.mail_notify"}}</dt> <dt>{{.i18n.Tr "admin.config.mail_notify"}}</dt>
@ -100,9 +102,11 @@
<div class="panel-body"> <div class="panel-body">
<dl class="dl-horizontal admin-dl-horizontal"> <dl class="dl-horizontal admin-dl-horizontal">
<dt>{{.i18n.Tr "admin.config.task_interval"}}</dt> <dt>{{.i18n.Tr "admin.config.task_interval"}}</dt>
<dd>{{.WebhookTaskInterval}} {{.i18n.Tr "tool.raw_minutes"}}</dd> <dd>{{.Webhook.TaskInterval}} {{.i18n.Tr "tool.raw_minutes"}}</dd>
<dt>{{.i18n.Tr "admin.config.deliver_timeout"}}</dt> <dt>{{.i18n.Tr "admin.config.deliver_timeout"}}</dt>
<dd>{{.WebhookDeliverTimeout}} {{.i18n.Tr "tool.raw_seconds"}}</dd> <dd>{{.Webhook.DeliverTimeout}} {{.i18n.Tr "tool.raw_seconds"}}</dd>
<dt>{{.i18n.Tr "admin.config.skip_tls_verify"}}</dt>
<dd><i class="fa fa{{if .Webhook.SkipTLSVerify}}-check{{end}}-square-o"></i></dd>
</dl> </dl>
</div> </div>
</div> </div>

5
templates/admin/dashboard.tmpl

@ -52,7 +52,10 @@
<td>{{.i18n.Tr "admin.dashboard.resync_all_sshkeys"}}</td> <td>{{.i18n.Tr "admin.dashboard.resync_all_sshkeys"}}</td>
<td><i class="fa fa-caret-square-o-right"></i> <a href="{{AppSubUrl}}/admin?op=5">{{.i18n.Tr "admin.dashboard.operation_run"}}</a></td> <td><i class="fa fa-caret-square-o-right"></i> <a href="{{AppSubUrl}}/admin?op=5">{{.i18n.Tr "admin.dashboard.operation_run"}}</a></td>
</tr> </tr>
<tr>
<td>{{.i18n.Tr "admin.dashboard.resync_all_update_hooks"}}</td>
<td><i class="fa fa-caret-square-o-right"></i> <a href="{{AppSubUrl}}/admin?op=6">{{.i18n.Tr "admin.dashboard.operation_run"}}</a></td>
</tr>
</tbody> </tbody>
</table> </table>
</div> </div>

2
templates/home.tmpl

@ -14,7 +14,9 @@
<input class="ipt ipt-large" name="password" type="password" placeholder="{{.i18n.Tr "home.password_holder"}}"/> <input class="ipt ipt-large" name="password" type="password" placeholder="{{.i18n.Tr "home.password_holder"}}"/>
<input name="from" type="hidden" value="home"> <input name="from" type="hidden" value="home">
<button class="btn btn-black btn-large">{{.i18n.Tr "sign_in"}}</button> <button class="btn btn-black btn-large">{{.i18n.Tr "sign_in"}}</button>
{{if .ShowRegistrationButton}}
<button class="btn btn-green btn-large" id="register-button">{{.i18n.Tr "register"}}</button> <button class="btn btn-green btn-large" id="register-button">{{.i18n.Tr "register"}}</button>
{{end}}
</form> </form>
<div id="promo-social" class="social-buttons"> <div id="promo-social" class="social-buttons">
{{template "ng/base/social" .}} {{template "ng/base/social" .}}

2
templates/ng/base/footer.tmpl

@ -1,7 +1,7 @@
</div> </div>
<footer id="footer"> <footer id="footer">
<div class="container clear"> <div class="container clear">
<p class="left" id="footer-rights">© 2014 GoGits · {{.i18n.Tr "version"}}: {{AppVer}} · {{.i18n.Tr "page"}}: <strong>{{LoadTimes .PageStartTime}}</strong> · <p class="left" id="footer-rights">© 2015 GoGits · {{.i18n.Tr "version"}}: {{AppVer}} · {{.i18n.Tr "page"}}: <strong>{{LoadTimes .PageStartTime}}</strong> ·
{{.i18n.Tr "template"}}: <strong>{{call .TmplLoadTimes}}</strong></p> {{.i18n.Tr "template"}}: <strong>{{call .TmplLoadTimes}}</strong></p>
<div class="right" id="footer-links"> <div class="right" id="footer-links">

2
templates/ng/base/header.tmpl

@ -49,10 +49,12 @@
<li class="right" id="header-nav-sign-in"> <li class="right" id="header-nav-sign-in">
<a href="{{AppSubUrl}}/user/login" title="Sign In"><i class="octicon octicon-sign-in"></i> {{.i18n.Tr "sign_in"}}</a> <a href="{{AppSubUrl}}/user/login" title="Sign In"><i class="octicon octicon-sign-in"></i> {{.i18n.Tr "sign_in"}}</a>
</li> </li>
{{if .ShowRegistrationButton}}
<li class="right"> <li class="right">
<a href="{{AppSubUrl}}/user/sign_up" title="Account Settings"><i class="octicon octicon-person-add"></i> {{.i18n.Tr "register"}}</a> <a href="{{AppSubUrl}}/user/sign_up" title="Account Settings"><i class="octicon octicon-person-add"></i> {{.i18n.Tr "register"}}</a>
</li> </li>
{{end}} {{end}}
{{end}}
{{end}} {{end}}
</ul> </ul>
</header> </header>

4
templates/repo/diff.tmpl

@ -89,7 +89,11 @@
{{$.i18n.Tr "repo.diff.bin"}} {{$.i18n.Tr "repo.diff.bin"}}
{{end}} {{end}}
</div> </div>
{{if $file.IsDeleted}}
<a class="btn btn-gray btn-header btn-radius text-black pull-right" rel="nofollow" href="{{$.BeforeSourcePath}}/{{.Name}}">{{$.i18n.Tr "repo.diff.view_file"}}</a>
{{else}}
<a class="btn btn-gray btn-header btn-radius text-black pull-right" rel="nofollow" href="{{$.SourcePath}}/{{.Name}}">{{$.i18n.Tr "repo.diff.view_file"}}</a> <a class="btn btn-gray btn-header btn-radius text-black pull-right" rel="nofollow" href="{{$.SourcePath}}/{{.Name}}">{{$.i18n.Tr "repo.diff.view_file"}}</a>
{{end}}
<span class="file">{{$file.Name}}</span> <span class="file">{{$file.Name}}</span>
</div> </div>
{{$isImage := (call $.IsImageFile $file.Name)}} {{$isImage := (call $.IsImageFile $file.Name)}}

8
templates/repo/header.tmpl

@ -18,9 +18,11 @@
</a> </a>
<div id="repo-header-download-drop" class="drop-down"> <div id="repo-header-download-drop" class="drop-down">
<div id="repo-clone" class="clear"> <div id="repo-clone" class="clear">
<button class="btn btn-blue left left btn-left-radius" id="repo-clone-ssh" data-link="{{$.CloneLink.SSH}}">SSH</button> {{if not $.DisableSSH}}
<button class="btn btn-gray left" id="repo-clone-https" data-link="{{$.CloneLink.HTTPS}}">HTTPS</button> <button class="btn btn-blue left btn-left-radius" id="repo-clone-ssh" data-link="{{$.CloneLink.SSH}}">SSH</button>
<input id="repo-clone-url" class="ipt ipt-disabled left" value="{{$.CloneLink.SSH}}" readonly /> {{end}}
<button class="btn {{if $.DisableSSH}}btn-blue{{else}}btn-gray{{end}} left" id="repo-clone-https" data-link="{{$.CloneLink.HTTPS}}">HTTPS</button>
<input id="repo-clone-url" class="ipt ipt-disabled left" value="{{if $.DisableSSH}}{{$.CloneLink.HTTPS}}{{else}}{{$.CloneLink.SSH}}{{end}}" onclick="this.select();" readonly />
<button id="repo-clone-copy" class="btn btn-black left btn-right-radius" data-copy-val="val" data-copy-from="#repo-clone-url" original-title="{{$.i18n.Tr "repo.click_to_copy"}}" data-original-title="{{$.i18n.Tr "repo.click_to_copy"}}" data-after-title="{{$.i18n.Tr "repo.copied"}}">{{$.i18n.Tr "repo.copy_link"}}</button> <button id="repo-clone-copy" class="btn btn-black left btn-right-radius" data-copy-val="val" data-copy-from="#repo-clone-url" original-title="{{$.i18n.Tr "repo.click_to_copy"}}" data-original-title="{{$.i18n.Tr "repo.click_to_copy"}}" data-after-title="{{$.i18n.Tr "repo.copied"}}">{{$.i18n.Tr "repo.copy_link"}}</button>
<p class="text-center" id="repo-clone-help">{{$.i18n.Tr "repo.clone_helper" "http://git-scm.com/book/en/Git-Basics-Getting-a-Git-Repository" | Str2html}}</p> <p class="text-center" id="repo-clone-help">{{$.i18n.Tr "repo.clone_helper" "http://git-scm.com/book/en/Git-Basics-Getting-a-Git-Repository" | Str2html}}</p>
<hr/> <hr/>

2
templates/user/auth/signin.tmpl

@ -26,10 +26,12 @@
<button class="btn btn-green btn-large btn-radius">{{.i18n.Tr "sign_in"}}</button>&nbsp;&nbsp;&nbsp;&nbsp; <button class="btn btn-green btn-large btn-radius">{{.i18n.Tr "sign_in"}}</button>&nbsp;&nbsp;&nbsp;&nbsp;
{{if not .IsSocialLogin}}<a href="{{AppSubUrl}}/user/forget_password">{{.i18n.Tr "auth.forget_password"}}</a>{{end}} {{if not .IsSocialLogin}}<a href="{{AppSubUrl}}/user/forget_password">{{.i18n.Tr "auth.forget_password"}}</a>{{end}}
</div> </div>
{{if .ShowRegistrationButton}}
<div class="field"> <div class="field">
<label></label> <label></label>
<a href="{{AppSubUrl}}/user/sign_up">{{.i18n.Tr "auth.sign_up_now" | Str2html}}</a> <a href="{{AppSubUrl}}/user/sign_up">{{.i18n.Tr "auth.sign_up_now" | Str2html}}</a>
</div> </div>
{{end}}
{{if and (not .IsSocialLogin) .OauthEnabled}} {{if and (not .IsSocialLogin) .OauthEnabled}}
<hr/> <hr/>
<div id="sign-social" class="text-center social-buttons"> <div id="sign-social" class="text-center social-buttons">

4
templates/user/dashboard/feeds.tmpl

@ -12,14 +12,14 @@
{{$.i18n.Tr "action.commit_repo" AppSubUrl .GetRepoLink .GetBranch .GetBranch AppSubUrl .GetRepoLink .GetRepoLink | Str2html}} {{$.i18n.Tr "action.commit_repo" AppSubUrl .GetRepoLink .GetBranch .GetBranch AppSubUrl .GetRepoLink .GetRepoLink | Str2html}}
{{else if eq .GetOpType 6}} {{else if eq .GetOpType 6}}
{{ $index := index .GetIssueInfos 0}} {{ $index := index .GetIssueInfos 0}}
{{$.i18n.Tr "action.create_issue" AppSubUrl .GetRepoLink $index .GetRepoLink $index | Str2html}} {{$.i18n.Tr "action.create_issue" .GetRepoLink $index | Str2html}}
{{else if eq .GetOpType 8}} {{else if eq .GetOpType 8}}
{{$.i18n.Tr "action.transfer_repo" .GetContent AppSubUrl .GetRepoLink .GetRepoLink | Str2html}} {{$.i18n.Tr "action.transfer_repo" .GetContent AppSubUrl .GetRepoLink .GetRepoLink | Str2html}}
{{else if eq .GetOpType 9}} {{else if eq .GetOpType 9}}
{{$.i18n.Tr "action.push_tag" AppSubUrl .GetRepoLink .GetBranch .GetBranch AppSubUrl .GetRepoLink .GetRepoLink | Str2html}} {{$.i18n.Tr "action.push_tag" AppSubUrl .GetRepoLink .GetBranch .GetBranch AppSubUrl .GetRepoLink .GetRepoLink | Str2html}}
{{else if eq .GetOpType 10}} {{else if eq .GetOpType 10}}
{{ $index := index .GetIssueInfos 0}} {{ $index := index .GetIssueInfos 0}}
{{$.i18n.Tr "action.comment_issue" AppSubUrl .GetRepoLink $index .GetRepoLink $index | Str2html}} {{$.i18n.Tr "action.comment_issue" .GetRepoLink $index | Str2html}}
{{end}} {{end}}
</p> </p>
{{if eq .GetOpType 5}} {{if eq .GetOpType 5}}

Loading…
Cancel
Save