summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--.gopmfile3
-rw-r--r--CONTRIBUTING.md34
-rw-r--r--README.md9
-rw-r--r--README_ZH.md8
-rw-r--r--cmd/cert_stub.go9
-rw-r--r--cmd/dump.go4
-rw-r--r--cmd/fix.go184
-rw-r--r--cmd/serve.go20
-rw-r--r--cmd/update.go8
-rw-r--r--cmd/web.go7
-rw-r--r--conf/app.ini8
-rw-r--r--conf/locale/TRANSLATORS1
-rwxr-xr-xconf/locale/locale_de-DE.ini25
-rw-r--r--conf/locale/locale_en-US.ini15
-rwxr-xr-xconf/locale/locale_es-ES.ini723
-rwxr-xr-xconf/locale/locale_fr-CA.ini53
-rwxr-xr-xconf/locale/locale_ja-JP.ini25
-rwxr-xr-xconf/locale/locale_lv-LV.ini25
-rwxr-xr-xconf/locale/locale_nl-NL.ini25
-rwxr-xr-xconf/locale/locale_ru-RU.ini27
-rwxr-xr-xconf/locale/locale_zh-CN.ini25
-rwxr-xr-xconf/locale/locale_zh-HK.ini25
-rw-r--r--gogs.go3
-rw-r--r--models/access.go9
-rw-r--r--models/action.go95
-rw-r--r--models/git_diff.go8
-rw-r--r--models/issue.go47
-rw-r--r--models/migrations/migrations.go152
-rw-r--r--models/models.go22
-rw-r--r--models/org.go55
-rw-r--r--models/publickey.go4
-rw-r--r--models/repo.go176
-rw-r--r--models/user.go3
-rw-r--r--models/webhook.go14
-rw-r--r--modules/asn1-ber/ber.go8
-rw-r--r--modules/base/markdown.go9
-rw-r--r--modules/cron/manager.go2
-rw-r--r--modules/middleware/auth.go5
-rw-r--r--modules/middleware/context.go2
-rw-r--r--modules/middleware/repo.go2
-rw-r--r--modules/setting/setting.go44
-rw-r--r--public/ng/css/gogs.css21
-rw-r--r--public/ng/js/gogs.js34
-rw-r--r--public/ng/less/gogs/markdown.less167
-rw-r--r--public/ng/less/gogs/repository.less17
-rw-r--r--routers/admin/admin.go9
-rw-r--r--routers/install.go5
-rw-r--r--routers/org/teams.go7
-rw-r--r--routers/repo/commit.go4
-rw-r--r--routers/repo/http.go54
-rw-r--r--routers/repo/issue.go8
-rw-r--r--routers/repo/view.go12
-rw-r--r--templates/.VERSION2
-rw-r--r--templates/admin/config.tmpl8
-rw-r--r--templates/admin/dashboard.tmpl5
-rw-r--r--templates/home.tmpl2
-rw-r--r--templates/ng/base/footer.tmpl2
-rw-r--r--templates/ng/base/header.tmpl2
-rw-r--r--templates/repo/diff.tmpl4
-rw-r--r--templates/repo/header.tmpl10
-rw-r--r--templates/user/dashboard/feeds.tmpl4
62 files changed, 1524 insertions, 779 deletions
diff --git a/.gitignore b/.gitignore
index b21581331e..ba878d92d4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,7 @@
.DS_Store
*.db
*.log
+log/
custom/
data/
.vendor/
@@ -34,4 +35,4 @@ docker/fig.yml
docker/docker/Dockerfile
docker/docker/init_gogs.sh
gogs.sublime-project
-gogs.sublime-workspace \ No newline at end of file
+gogs.sublime-workspace
diff --git a/.gopmfile b/.gopmfile
index b405e813d0..d09e632bd7 100644
--- a/.gopmfile
+++ b/.gopmfile
@@ -3,6 +3,7 @@ path = github.com/gogits/gogs
[deps]
github.com/beego/memcache = commit:2aea774416
+github.com/bradfitz/gomemcache =
github.com/Unknwon/cae = commit:2e70a1351b
github.com/Unknwon/com = commit:d9bcf409c8
github.com/Unknwon/i18n = commit:1e88666229
@@ -27,6 +28,8 @@ github.com/microcosm-cc/bluemonday =
github.com/nfnt/resize = commit:8f44931448
github.com/russross/blackfriday = commit:05b8cefd6a
github.com/shurcooL/go = commit:48293cbc7a
+golang.org/x/net =
+golang.org/x/text =
gopkg.in/ini.v1 = commit:28ad8c408b
gopkg.in/redis.v2 = commit:e617904962
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index ea713ca455..d3619018a4 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -2,7 +2,7 @@
> 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
@@ -15,36 +15,30 @@ Depends on the situation, you will:
### 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**:
-- **Gogs Version**:
-- **Git Version**:
-- **System Type**:
-- **Error Log**:
-- **Other information**:
-```
+- Bug Description
+- Gogs Version
+- Git Version
+- System Type
+- Error Log
+- 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.
#### Bug Report Example
-- **Bug Description**: Crash when create repository with license|
-- **Gogs Version**: `v0.4.9.0901`
-- **Git Version**: `1.9.0`
-- **System Type**: `Ubuntu 12.04`
-- **Error Log**:
+Gogs crashed when create repository with license, using v0.5.13.0207, SQLite3, Git 1.9.0, Ubuntu 12.04.
+
+Error log:
```
2014/09/01 07:21:49 [E] nil pointer
```
-- **Other information**: Use SQLite3 as database
-
### 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
@@ -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.
-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
@@ -77,4 +71,4 @@ Project maintainers have the right and responsibility to remove, edit, or reject
Instances of abusive, harassing, or otherwise unacceptable behavior can be
reported by emailing contact@gitlab.com
-This Code of Conduct is adapted from the [Contributor Covenant](http:contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/) \ No newline at end of file
+This Code of Conduct is adapted from the [Contributor Covenant](http:contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
diff --git a/README.md b/README.md
index 3d87e3a1ff..a601bb773b 100644
--- a/README.md
+++ b/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)
-##### Current version: 0.5.12 Beta
+##### Current version: 0.5.13 Beta
### 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.
- 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!
#### 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.
- 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).
- 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
- Supports MySQL, PostgreSQL and SQLite3
- 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
@@ -81,7 +82,7 @@ There are 5 ways to install Gogs:
## Contributors
-- The [core team](http://gogs.io/team) of this project.
+- The [core team](http://gogs.io/team) of this project.
- See [contributors page](https://github.com/gogits/gogs/graphs/contributors) for full list of contributors.
- See [TRANSLATORS](conf/locale/TRANSLATORS) for full list of translators.
diff --git a/README_ZH.md b/README_ZH.md
index be3a2b1bc4..b6d74e7b14 100644
--- a/README_ZH.md
+++ b/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 服务。
![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/) 查看。
- 您可以到 [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) 页面获取帮助。
- 希望帮助多国语言界面的翻译吗?请立即访问 [Crowdin](https://crowdin.com/project/gogs)!
@@ -39,7 +39,7 @@ Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自
- Drone CI 持续部署集成
- 支持 MySQL、PostgreSQL 以及 SQLite3 数据库
- 社交帐号登录(GitHub、Google、QQ、微博)
-- 多语言支持([9 种语言]([more](https://crowdin.com/project/gogs)))
+- 多语言支持([10 种语言]([more](https://crowdin.com/project/gogs)))
## 系统要求
diff --git a/cmd/cert_stub.go b/cmd/cert_stub.go
index 69c9821e02..1b68ca83f1 100644
--- a/cmd/cert_stub.go
+++ b/cmd/cert_stub.go
@@ -9,7 +9,6 @@ package cmd
import (
"fmt"
"os"
- "time"
"github.com/codegangsta/cli"
)
@@ -20,14 +19,6 @@ var CmdCert = cli.Command{
Description: `Generate a self-signed X.509 certificate for a TLS server.
Outputs to 'cert.pem' and 'key.pem' and will overwrite existing files.`,
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) {
diff --git a/cmd/dump.go b/cmd/dump.go
index 3e1ccdb8a3..36bb4f0305 100644
--- a/cmd/dump.go
+++ b/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`,
Action: runDump,
Flags: []cli.Flag{
+ cli.StringFlag{"config, c", "custom/conf/app.ini", "Custom configuration file path", ""},
cli.BoolFlag{"verbose, v", "show process details", ""},
},
}
func runDump(ctx *cli.Context) {
+ if ctx.IsSet("config") {
+ setting.CustomConf = ctx.String("config")
+ }
setting.NewConfigContext()
models.LoadModelsConfig()
models.SetEngine()
diff --git a/cmd/fix.go b/cmd/fix.go
deleted file mode 100644
index eff85d6282..0000000000
--- a/cmd/fix.go
+++ /dev/null
@@ -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!")
-}
diff --git a/cmd/serve.go b/cmd/serve.go
index 90e1045c8e..54b3714806 100644
--- a/cmd/serve.go
+++ b/cmd/serve.go
@@ -26,15 +26,23 @@ var CmdServ = cli.Command{
Usage: "This command should only be called by SSH shell",
Description: `Serv provide access auth for repositories`,
Action: runServ,
- Flags: []cli.Flag{},
+ Flags: []cli.Flag{
+ cli.StringFlag{"config, c", "custom/conf/app.ini", "Custom configuration file path", ""},
+ },
}
func setup(logPath string) {
setting.NewConfigContext()
log.NewGitLogger(filepath.Join(setting.LogRootPath, logPath))
+
+ if setting.DisableSSH {
+ println("Gogs: SSH has been disabled")
+ os.Exit(1)
+ }
+
models.LoadModelsConfig()
- if models.UseSQLite3 {
+ if setting.UseSQLite3 {
workDir, _ := setting.WorkDir()
os.Chdir(workDir)
}
@@ -76,9 +84,15 @@ func In(b string, sl map[string]models.AccessMode) bool {
}
func runServ(k *cli.Context) {
+ if k.IsSet("config") {
+ setting.CustomConf = k.String("config")
+ }
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 {
println("Gogs: auth file format error")
log.GitLogger.Fatal(2, "Invalid auth file format: %s", os.Args[2])
diff --git a/cmd/update.go b/cmd/update.go
index cc55693e2b..c9eaeccf7b 100644
--- a/cmd/update.go
+++ b/cmd/update.go
@@ -11,6 +11,7 @@ import (
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/log"
+ "github.com/gogits/gogs/modules/setting"
)
var CmdUpdate = cli.Command{
@@ -18,10 +19,15 @@ var CmdUpdate = cli.Command{
Usage: "This command should only be called by SSH shell",
Description: `Update get pushed info and insert into database`,
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) {
+ if c.IsSet("config") {
+ setting.CustomConf = c.String("config")
+ }
cmd := os.Getenv("SSH_ORIGINAL_COMMAND")
if cmd == "" {
return
diff --git a/cmd/web.go b/cmd/web.go
index 55b6bf0874..3284acb9df 100644
--- a/cmd/web.go
+++ b/cmd/web.go
@@ -55,6 +55,7 @@ and it takes care of all the other things for you`,
Action: runWeb,
Flags: []cli.Flag{
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) {
- routers.GlobalInit()
checkVersion()
+ if ctx.IsSet("config") {
+ setting.CustomConf = ctx.String("config")
+ }
+ routers.GlobalInit()
+
m := newMacaron()
reqSignIn := middleware.Toggle(&middleware.ToggleOptions{SignInRequire: true})
diff --git a/conf/app.ini b/conf/app.ini
index b7a0f1a7c5..2019557bd4 100644
--- a/conf/app.ini
+++ b/conf/app.ini
@@ -18,6 +18,8 @@ DOMAIN = localhost
ROOT_URL = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s/
HTTP_ADDR =
HTTP_PORT = 3000
+; Disable SSH feature when not available
+DISABLE_SSH = false
SSH_PORT = 22
; Disable CDN even in "prod" mode
OFFLINE_MODE = false
@@ -87,6 +89,8 @@ ENABLE_REVERSE_PROXY_AUTO_REGISTERATION = false
TASK_INTERVAL = 1
; Deliver timeout in seconds
DELIVER_TIMEOUT = 5
+; Allow insecure certification
+SKIP_TLS_VERIFY = false
[mailer]
ENABLED = false
@@ -278,5 +282,5 @@ INTERVAL = 24
ARGS =
[i18n]
-LANGS = en-US,zh-CN,zh-HK,de-DE,fr-CA,nl-NL,lv-LV,ru-RU,ja-JP
-NAMES = English,简体中文,繁體中文,Deutsch,Français,Nederlands,Latviešu,Русский,日本语
+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,Русский,日本语,Español
diff --git a/conf/locale/TRANSLATORS b/conf/locale/TRANSLATORS
index 6c72f3342a..4cd8bf6a4e 100644
--- a/conf/locale/TRANSLATORS
+++ b/conf/locale/TRANSLATORS
@@ -3,6 +3,7 @@
Akihiro YAGASAKI <yaggytter@momiage.com>
Christoph Kisfeld <christoph.kisfeld@gmail.com>
+Huimin Wang <wanghm2009@hotmail.co.jp>
Thomas Fanninger <gogs.thomas@fanninger.at>
Łukasz Jan Niemier <lukasz@niemier.pl>
Lafriks <lafriks@gmail.com>
diff --git a/conf/locale/locale_de-DE.ini b/conf/locale/locale_de-DE.ini
index dbf31a3297..1dc7523b0f 100755
--- a/conf/locale/locale_de-DE.ini
+++ b/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.
domain=Domain
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_helper=Dies hat Auswirkung auf die HTTP/HTTPS clone URLs und für die E-Mails.
email_title=E-Mail-Service Einstellungen (optional)
@@ -512,6 +514,11 @@ dashboard.delete_repo_archives=Alle Repository-Archive löschen
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_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.current_goroutine=Aktuelle Goroutines
dashboard.current_memory_usage=Aktuelle Speichernutzung
@@ -631,6 +638,7 @@ config.db_path_helper=(nur für "sqlite3")
config.service_config=Service-Einstellungen
config.register_email_confirm=E-Mail-Bestätigung bei Registrierung
config.disable_register=Registrierung deaktivieren
+config.show_registration_button=Show Register Button
config.require_sign_in_view=Ansehen erfordert Registrierung
config.mail_notify=E-Mail-Benachrichtigung
config.enable_cache_avatar=Avatar-Cache aktivieren
@@ -686,8 +694,8 @@ notices.delete_success=System-Mitteilung erfolgreich gelöscht.
[action]
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
-create_issue=hat Issue <a href="%s/%s/issues/%s">%s#%s</a> eröffnet
-comment_issue=hat Issue <a href="%s/%s/issues/%s">%s#%s</a> kommentiert
+create_issue=`hat Issue <a href="%s/issues/%s">%[1]s#%[2]s</a> eröffnet`
+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>
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
@@ -713,16 +721,3 @@ years=%[2]s %[1]d Jahren
raw_seconds=Sekunden
raw_minutes=Minuten
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/conf/locale/locale_en-US.ini b/conf/locale/locale_en-US.ini
index 660fb253bb..6b59be7391 100644
--- a/conf/locale/locale_en-US.ini
+++ b/conf/locale/locale_en-US.ini
@@ -67,7 +67,7 @@ email_title = E-mail Service Settings (Optional)
smtp_host = SMTP Host
mailer_user = Sender E-mail
mailer_password = Sender Password
-notify_title = Notification Settings(Optional)
+notify_title = Notification Settings (Optional)
register_confirm = Enable Register Confirmation
mail_notify = Enable Mail Notification
admin_title = Admin Account Settings
@@ -280,7 +280,7 @@ license_helper = Select a license file
init_readme = Initialize this repository with a README.md
create_repo = Create Repository
default_branch = Default Branch
-mirror_interval = Mirror Interval(hour)
+mirror_interval = Mirror Interval (hour)
goget_meta = Go-Get Meta
goget_meta_helper = This repository will be <span class="label label-blue label-radius">Go-Getable</span>
@@ -514,8 +514,11 @@ dashboard.delete_repo_archives = Delete all repositories archives
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_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_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.current_goroutine = Current Goroutines
dashboard.current_memory_usage = Current Memory Usage
@@ -635,6 +638,7 @@ config.db_path_helper = (for "sqlite3" only)
config.service_config = Service Configuration
config.register_email_confirm = Require E-mail Confirmation
config.disable_register = Disable Registration
+config.show_registration_button = Show Register Button
config.require_sign_in_view = Require Sign In View
config.mail_notify = Mail Notification
config.enable_cache_avatar = Enable Cache Avatar
@@ -643,6 +647,7 @@ 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.skip_tls_verify = Skip TLS Verify
config.mailer_config = Mailer Configuration
config.mailer_enabled = Enabled
config.mailer_name = Name
@@ -690,8 +695,8 @@ 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/%s/issues/%s">%s#%s</a>
-comment_issue = commented on 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/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
diff --git a/conf/locale/locale_es-ES.ini b/conf/locale/locale_es-ES.ini
new file mode 100755
index 0000000000..d7fab5f961
--- /dev/null
+++ b/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
+
diff --git a/conf/locale/locale_fr-CA.ini b/conf/locale/locale_fr-CA.ini
index 833d8e1dc0..94a2e96867 100755
--- a/conf/locale/locale_fr-CA.ini
+++ b/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.
domain=Domaine
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_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
mailer_user=E-mail 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
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.
-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
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
@@ -192,7 +194,7 @@ delete=Supprimer le Compte
uid=ID d'Utilisateur
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
website=Site Web
location=Localisation
@@ -217,15 +219,15 @@ new_password=Nouveau Mot de Passe
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.
-emails=E-mail Addresses
-manage_emails=Manage e-mail addresses
-email_desc=Your primary e-mail address will be used for notifications and other operations.
-primary=Primary
-primary_email=Set as primary
-delete_email=Delete
-add_new_email=Add new e-mail address
-add_email=Add e-mail
-add_email_success=Your new E-mail address was successfully added.
+emails=Adresses E-mail
+manage_emails=Gérer les adresses e-mail
+email_desc=Votre adresse e-mail principale sera utilisée pour les notifications et d'autres opérations.
+primary=Principale
+primary_email=Définir comme principale
+delete_email=Supprimer
+add_new_email=Ajouter une nouvelle adresse courriel
+add_email=Ajouter un courriel
+add_email_success=Votre courriel a été ajouté avec succès.
manage_ssh_keys=Gérer les clés SSH
add_key=Ajouter une Clé
@@ -414,7 +416,7 @@ release.tag_name_already_exist=Une publication avec ce nom de tag a déjà exist
[org]
org_name_holder=Nom d'organisation
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
repo_updated=Mis à jour
people=Contacts
@@ -512,6 +514,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.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.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.current_goroutine=Goroutines actuelles
dashboard.current_memory_usage=Utilisation Mémoire actuelle
@@ -629,8 +636,9 @@ config.db_ssl_mode_helper=("postgres" uniquement)
config.db_path=Emplacement
config.db_path_helper=("sqlite3" uniquement)
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.show_registration_button=Show Register Button
config.require_sign_in_view=Connexion Obligatoire pour Visualiser
config.mail_notify=Mailer les Notifications
config.enable_cache_avatar=Activer le Cache d'Avatar
@@ -686,8 +694,8 @@ notices.delete_success=Note système supprimée avec succès.
[action]
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>
-create_issue=a ouvert un problème <a href="%s/%s/issues/%s">%s#%s</a>
-comment_issue=a commenté le 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/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>
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
@@ -713,16 +721,3 @@ years=%d ans %s
raw_seconds=secondes
raw_minutes=minutes
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/conf/locale/locale_ja-JP.ini b/conf/locale/locale_ja-JP.ini
index 1d1d61493d..29ea94e4da 100755
--- a/conf/locale/locale_ja-JP.ini
+++ b/conf/locale/locale_ja-JP.ini
@@ -59,6 +59,8 @@ run_user=実行ユーザ
run_user_helper=ユーザーはリポジトリ ルートパスへのアクセス、及びGogs を実行する権限を所有する必要があります。
domain=ドメイン
domain_helper=これはSSHクローンURLに影響する。
+http_port=HTTP ポート
+http_port_helper=アプリケーションが待ち受けするポート番号。
app_url=アプリケーションの URL
app_url_helper=この設定は、HTTP / HTTPSのクローンURLおよび、一部のメールボックスへのリンクに影響を与えます。
email_title=E-mailサービス設定(Optional)
@@ -512,6 +514,11 @@ dashboard.delete_repo_archives=リポジトリのすべてのアーカイブを
dashboard.delete_repo_archives_success=リポジトリのすべてのアーカイブが正常に削除されました。
dashboard.git_gc_repos=リポジトリでのガベージコレクションを実行します。
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.current_goroutine=現在のGoroutine
dashboard.current_memory_usage=現在のメモリ使用量
@@ -631,6 +638,7 @@ config.db_path_helper=(「sqlite3」のみ)
config.service_config=サービスの構成
config.register_email_confirm=電子メールの確認を必要
config.disable_register=登録を無効にする
+config.show_registration_button=登録ボタンを表示します。
config.require_sign_in_view=サインインを要求
config.mail_notify=メール通知
config.enable_cache_avatar=アバターのキャッシュを有効にします。
@@ -686,8 +694,8 @@ notices.delete_success=システム通知が正常に削除されました。
[action]
create_repo=リポジトリ <a href="%s/%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> を開きました
-comment_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/issues/%s">%[1]s#%[2]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> をプッシュしました
compare_2_commits=これら 2 のコミットの比較を閲覧する
@@ -713,16 +721,3 @@ years=%d 年 %s
raw_seconds=秒
raw_minutes=分
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/conf/locale/locale_lv-LV.ini b/conf/locale/locale_lv-LV.ini
index 19373118f3..6ab814806f 100755
--- a/conf/locale/locale_lv-LV.ini
+++ b/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.
domain=Domēns
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_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)
@@ -512,6 +514,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.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.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.current_goroutine=Izmantotās Gorutīnas
dashboard.current_memory_usage=Pašreiz izmantotā atmiņa
@@ -631,6 +638,7 @@ config.db_path_helper=(tikai Sqlite3 datu bāzei)
config.service_config=Pakalpojuma konfigurācija
config.register_email_confirm=Pieprasīt e-pasta apstiprināšanu
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.mail_notify=Pasta paziņojumi
config.enable_cache_avatar=Glabāt profila attēlus kešatmiņā
@@ -686,8 +694,8 @@ notices.delete_success=Sistēmas paziņojums tika veiksmīgi izdzēsts.
[action]
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>
-create_issue=reģistrēja problēmu <a href="%s/%s/issues/%s">%s#%s</a>
-comment_issue=pievienoja komentāru problēmai <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/issues/%s">%[1]s#%[2]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>
compare_2_commits=Veikt salīdzināšanu starp šīm 2 revīzijām
@@ -713,16 +721,3 @@ years=%d gadi %s
raw_seconds=sekundes
raw_minutes=minūtes
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/conf/locale/locale_nl-NL.ini b/conf/locale/locale_nl-NL.ini
index f0bc7c70a2..adc98c9d5a 100755
--- a/conf/locale/locale_nl-NL.ini
+++ b/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
domain=Domein
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_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)
@@ -512,6 +514,11 @@ dashboard.delete_repo_archives=Verwijderen van alle repositories archieven
dashboard.delete_repo_archives_success=Alle repositories archieven hebben verwijderd.
dashboard.git_gc_repos=Garbage collectie uitvoeren
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.current_goroutine=Huidige Goroutines
dashboard.current_memory_usage=Huidige geheugen gebruik
@@ -631,6 +638,7 @@ config.db_path_helper=(alleen voor "sqlite3")
config.service_config=Serviceconfiguratie
config.register_email_confirm=E-mailbevestiging registreren
config.disable_register=Registratie uitgeschakeld
+config.show_registration_button=Registeren knop weergeven
config.require_sign_in_view=Inloggen vereist om te kunnen inzien
config.mail_notify=E-mailnotificaties
config.enable_cache_avatar=Avatar Cache inschakelen
@@ -686,8 +694,8 @@ notices.delete_success=Systeem bericht is met succes verwijderd.
[action]
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
-create_issue=opende issue in <a href="%s/%s/issues/%s">%s#%s</a>
-comment_issue=reactie op issue <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/issues/%s">%[1]s#%[2]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>
compare_2_commits=Weergave vergelijking voor deze 2 commits
@@ -713,16 +721,3 @@ years=%d jaren %s
raw_seconds=seconden
raw_minutes=minuten
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/conf/locale/locale_ru-RU.ini b/conf/locale/locale_ru-RU.ini
index b0da5c550f..aa2c0ee558 100755
--- a/conf/locale/locale_ru-RU.ini
+++ b/conf/locale/locale_ru-RU.ini
@@ -59,6 +59,8 @@ run_user=Пользователь
run_user_helper=У пользователя должен быть доступ к пути к корню репозитория и к запуску Gogs.
domain=Домен
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_helper=This affects HTTP/HTTPS clone URL and somewhere in e-mail.
email_title=Настройки службы электронной почты (опционально)
@@ -278,7 +280,7 @@ license_helper=Выберите файл лицензии
init_readme=Создать репозиторий с файлом README.md
create_repo=Создание репозитория
default_branch=Ветка по умолчанию
-mirror_interval=Mirror Interval(hour)
+mirror_interval=Mirror Interval (hour)
goget_meta=Go-Get Meta
goget_meta_helper=This repository will be <span class="label label-blue label-radius">Go-Getable</span>
@@ -512,6 +514,11 @@ dashboard.delete_repo_archives=Удаление всех архивов репо
dashboard.delete_repo_archives_success=Все архивы репозиториев были успешно удалены.
dashboard.git_gc_repos=Выполнить сборку мусора на репозиториях
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.current_goroutine=Current Goroutines
dashboard.current_memory_usage=Текущее использование памяти
@@ -631,6 +638,7 @@ config.db_path_helper=(for "sqlite3" only)
config.service_config=Service Configuration
config.register_email_confirm=Require E-mail Confirmation
config.disable_register=Отключить регистрацию
+config.show_registration_button=Show Register Button
config.require_sign_in_view=Для просмотра необходима авторизация
config.mail_notify=Почтовые уведомления
config.enable_cache_avatar=Кешировать аватар
@@ -686,8 +694,8 @@ notices.delete_success=System notice has been deleted successfully.
[action]
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>
-create_issue=opened issue <a href="%s/%s/issues/%s">%s#%s</a>
-comment_issue=commented on 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/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
@@ -713,16 +721,3 @@ years=%d years %s
raw_seconds=seconds
raw_minutes=minutes
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/conf/locale/locale_zh-CN.ini b/conf/locale/locale_zh-CN.ini
index 49c013a9f1..efeca15adb 100755
--- a/conf/locale/locale_zh-CN.ini
+++ b/conf/locale/locale_zh-CN.ini
@@ -59,6 +59,8 @@ run_user=运行系统用户
run_user_helper=该用户必须具有对仓库根目录和运行 Gogs 的操作权限。
domain=域名
domain_helper=该设置影响 SSH 克隆地址。
+http_port=HTTP 端口号
+http_port_helper=应用监听的端口号
app_url=应用 URL
app_url_helper=该设置影响 HTTP/HTTPS 克隆地址和一些邮箱中的链接。
email_title=邮件服务设置(可选)
@@ -512,6 +514,11 @@ dashboard.delete_repo_archives=删除所有仓库存档
dashboard.delete_repo_archives_success=所有仓库存档清除成功!
dashboard.git_gc_repos=对仓库进行垃圾回收
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.current_goroutine=当前 Goroutines 数量
dashboard.current_memory_usage=当前内存使用量
@@ -631,6 +638,7 @@ config.db_path_helper=(仅限 "sqlite3" 使用)
config.service_config=服务配置
config.register_email_confirm=注册邮件确认
config.disable_register=关闭注册功能
+config.show_registration_button=显示注册按钮
config.require_sign_in_view=强制登录浏览
config.mail_notify=邮件通知提醒
config.enable_cache_avatar=开启缓存头像
@@ -686,8 +694,8 @@ notices.delete_success=系统提示删除成功!
[action]
create_repo=创建了仓库 <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>
-comment_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/issues/%s">%[1]s#%[2]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>
compare_2_commits=查看 2 次提交的内容对比
@@ -713,16 +721,3 @@ years=%d 年%s
raw_seconds=秒
raw_minutes=分钟
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/conf/locale/locale_zh-HK.ini b/conf/locale/locale_zh-HK.ini
index accf079572..0c9ba19091 100755
--- a/conf/locale/locale_zh-HK.ini
+++ b/conf/locale/locale_zh-HK.ini
@@ -59,6 +59,8 @@ run_user=執行系統用戶
run_user_helper=該用戶必須具有對倉庫根目錄和執行 Gogs 的操作權限。
domain=域名
domain_helper=該設置影響 SSH 複製地址。
+http_port=HTTP 端口號
+http_port_helper=應用監聽的端口號
app_url=應用 URL
app_url_helper=該設置影響 HTTP/HTTPS 複製地址和一些郵箱中的連結。
email_title=電子郵件服務設定(可選)
@@ -512,6 +514,11 @@ dashboard.delete_repo_archives=刪除所有倉庫存檔
dashboard.delete_repo_archives_success=所有倉庫存檔清除成功!
dashboard.git_gc_repos=對倉庫進行垃圾回收
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.current_goroutine=當前 Goroutines 數量
dashboard.current_memory_usage=當前內存使用量
@@ -631,6 +638,7 @@ config.db_path_helper=(僅限 "sqlite3" 使用)
config.service_config=服務配置
config.register_email_confirm=註冊電子郵件確認
config.disable_register=關閉註冊功能
+config.show_registration_button=顯示註冊按鈕
config.require_sign_in_view=強制登錄瀏覽
config.mail_notify=郵件通知提醒
config.enable_cache_avatar=開啟緩存頭像
@@ -686,8 +694,8 @@ notices.delete_success=系統提示刪除成功!
[action]
create_repo=創建了倉庫 <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>
-comment_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/issues/%s">%[1]s#%[2]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>
compare_2_commits=查看 2 次提交的內容對比
@@ -713,16 +721,3 @@ years=%d 年%s
raw_seconds=秒
raw_minutes=分鐘
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/gogs.go b/gogs.go
index 5e69bd68e5..eac5936218 100644
--- a/gogs.go
+++ b/gogs.go
@@ -17,7 +17,7 @@ import (
"github.com/gogits/gogs/modules/setting"
)
-const APP_VER = "0.5.12.0204 Beta"
+const APP_VER = "0.5.13.0211 Beta"
func init() {
runtime.GOMAXPROCS(runtime.NumCPU())
@@ -33,7 +33,6 @@ func main() {
cmd.CmdWeb,
cmd.CmdServ,
cmd.CmdUpdate,
- cmd.CmdFix,
cmd.CmdDump,
cmd.CmdCert,
}
diff --git a/models/access.go b/models/access.go
index 916711f786..174aca987f 100644
--- a/models/access.go
+++ b/models/access.go
@@ -4,10 +4,6 @@
package models
-//import (
-// "github.com/go-xorm/xorm"
-//)
-
type AccessMode int
const (
@@ -81,9 +77,10 @@ func (u *User) GetAccessibleRepositories() (map[*Repository]AccessMode, error) {
if err != nil {
return nil, err
}
- err = repo.GetOwner()
- if err != nil {
+ if err = repo.GetOwner(); err != nil {
return nil, err
+ } else if repo.OwnerId == u.Id {
+ continue
}
repos[repo] = access.Mode
}
diff --git a/models/action.go b/models/action.go
index 318a5f6ad4..5cba2f515a 100644
--- a/models/action.go
+++ b/models/action.go
@@ -41,14 +41,21 @@ var (
var (
// 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"}
- IssueCloseKeywordsPat *regexp.Regexp
- IssueReferenceKeywordsPat *regexp.Regexp
+ IssueCloseKeywords = []string{"close", "closes", "closed", "fix", "fixes", "fixed", "resolve", "resolves", "resolved"}
+ IssueReopenKeywords = []string{"reopen", "reopens", "reopened"}
+
+ IssueCloseKeywordsPat, IssueReopenKeywordsPat *regexp.Regexp
+ IssueReferenceKeywordsPat *regexp.Regexp
)
+func assembleKeywordsPattern(words []string) string {
+ return fmt.Sprintf(`(?i)(?:%s) \S+`, strings.Join(words, "|"))
+}
+
func init() {
- IssueCloseKeywordsPat = regexp.MustCompile(fmt.Sprintf(`(?i)(?:%s) \S+`, strings.Join(IssueCloseKeywords, "|")))
- IssueReferenceKeywordsPat = regexp.MustCompile(fmt.Sprintf(`(?i)(?:) \S+`))
+ IssueCloseKeywordsPat = regexp.MustCompile(assembleKeywordsPattern(IssueCloseKeywords))
+ IssueReopenKeywordsPat = regexp.MustCompile(assembleKeywordsPattern(IssueReopenKeywords))
+ IssueReferenceKeywordsPat = regexp.MustCompile(`(?i)(?:)(^| )\S+`)
}
// Action represents user operation type and other information to repository.,
@@ -91,7 +98,7 @@ func (a Action) GetRepoName() 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 {
@@ -112,13 +119,11 @@ func (a Action) GetIssueInfos() []string {
func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, commits []*base.PushCommit) error {
for _, c := range commits {
- references := IssueReferenceKeywordsPat.FindAllString(c.Message, -1)
-
- for _, ref := range references {
+ for _, ref := range IssueReferenceKeywordsPat.FindAllString(c.Message, -1) {
ref := ref[strings.IndexByte(ref, byte(' '))+1:]
ref = strings.TrimRightFunc(ref, func(c rune) bool {
- return !unicode.IsDigit(c)
- })
+ return !unicode.IsDigit(c)
+ })
if len(ref) == 0 {
continue
@@ -128,33 +133,29 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
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
+ // FIXME: We don't support User#ID syntax yet
// return ErrNotImplemented
continue
}
issue, err := GetIssueByRef(ref)
-
if err != nil {
return err
}
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)
-
- if _, err = CreateComment(userId, issue.RepoId, issue.Id, 0, 0, COMMIT, message, nil); err != nil {
+ if _, err = CreateComment(userId, issue.RepoId, issue.Id, 0, 0, COMMENT_TYPE_COMMIT, message, nil); err != nil {
return err
}
}
- closes := IssueCloseKeywordsPat.FindAllString(c.Message, -1)
-
- for _, ref := range closes {
+ for _, ref := range IssueCloseKeywordsPat.FindAllString(c.Message, -1) {
ref := ref[strings.IndexByte(ref, byte(' '))+1:]
ref = strings.TrimRightFunc(ref, func(c rune) bool {
- return !unicode.IsDigit(c)
- })
+ return !unicode.IsDigit(c)
+ })
if len(ref) == 0 {
continue
@@ -171,7 +172,6 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
}
issue, err := GetIssueByRef(ref)
-
if err != nil {
return err
}
@@ -180,7 +180,6 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
if issue.IsClosed {
continue
}
-
issue.IsClosed = true
if err = UpdateIssue(issue); err != nil {
@@ -194,14 +193,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 _, err = CreateComment(userId, repoId, issue.Id, 0, 0, CLOSE, "", nil); err != nil {
+ if _, err = CreateComment(userId, repoId, issue.Id, 0, 0, COMMENT_TYPE_CLOSE, "", nil); err != nil {
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
}
diff --git a/models/git_diff.go b/models/git_diff.go
index 7e91626f1d..9d34ed6271 100644
--- a/models/git_diff.go
+++ b/models/git_diff.go
@@ -60,6 +60,8 @@ type DiffFile struct {
Index int
Addition, Deletion int
Type int
+ IsCreated bool
+ IsDeleted bool
IsBin bool
Sections []*DiffSection
}
@@ -181,10 +183,16 @@ func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff
switch {
case strings.HasPrefix(scanner.Text(), "new file"):
curFile.Type = DIFF_FILE_ADD
+ curFile.IsDeleted = false
+ curFile.IsCreated = true
case strings.HasPrefix(scanner.Text(), "deleted"):
curFile.Type = DIFF_FILE_DEL
+ curFile.IsCreated = false
+ curFile.IsDeleted = true
case strings.HasPrefix(scanner.Text(), "index"):
curFile.Type = DIFF_FILE_CHANGE
+ curFile.IsCreated = false
+ curFile.IsDeleted = false
}
if curFile.Type > 0 {
break
diff --git a/models/issue.go b/models/issue.go
index 8d0525d7c5..3cd71d8aa4 100644
--- a/models/issue.go
+++ b/models/issue.go
@@ -282,30 +282,33 @@ type IssueUser struct {
}
// NewIssueUserPairs adds new issue-user pairs for new issue of repository.
-func NewIssueUserPairs(repo *Repository, iid, oid, pid, aid int64) (err error) {
- iu := &IssueUser{IssueId: iid, RepoId: repo.Id}
-
- us, err := repo.GetCollaborators()
+func NewIssueUserPairs(repo *Repository, issueID, orgID, posterID, assigneeID int64) (err error) {
+ users, err := repo.GetCollaborators()
if err != nil {
return err
}
+ iu := &IssueUser{
+ IssueId: issueID,
+ RepoId: repo.Id,
+ }
+
isNeedAddPoster := true
- for _, u := range us {
+ for _, u := range users {
iu.Uid = u.Id
- iu.IsPoster = iu.Uid == pid
+ iu.IsPoster = iu.Uid == posterID
if isNeedAddPoster && iu.IsPoster {
isNeedAddPoster = false
}
- iu.IsAssigned = iu.Uid == aid
+ iu.IsAssigned = iu.Uid == assigneeID
if _, err = x.Insert(iu); err != nil {
return err
}
}
if isNeedAddPoster {
- iu.Uid = pid
+ iu.Uid = posterID
iu.IsPoster = true
- iu.IsAssigned = iu.Uid == aid
+ iu.IsAssigned = iu.Uid == assigneeID
if _, err = x.Insert(iu); err != nil {
return err
}
@@ -859,22 +862,16 @@ type CommentType int
const (
// Plain comment, can be associated with a commit (CommitId > 0) and a line (Line > 0)
- COMMENT CommentType = iota
-
- // Reopen action
- REOPEN
-
- // Close action
- CLOSE
-
- // Reference from another issue
- ISSUE
+ COMMENT_TYPE_COMMENT CommentType = iota
+ COMMENT_TYPE_REOPEN
+ COMMENT_TYPE_CLOSE
+ // References.
+ COMMENT_TYPE_ISSUE
// Reference from some commit (not part of a pull request)
- COMMIT
-
+ COMMENT_TYPE_COMMIT
// Reference from some pull request
- PULL
+ COMMENT_TYPE_PULL
)
// Comment represents a comment in commit and issue page.
@@ -908,7 +905,7 @@ func CreateComment(userId, repoId, issueId, commitId, line int64, cmtType Commen
// Check comment type.
switch cmtType {
- case COMMENT:
+ case COMMENT_TYPE_COMMENT:
rawSql := "UPDATE `issue` SET num_comments = num_comments + 1 WHERE id = ?"
if _, err := sess.Exec(rawSql, issueId); err != nil {
sess.Rollback()
@@ -929,13 +926,13 @@ func CreateComment(userId, repoId, issueId, commitId, line int64, cmtType Commen
return nil, err
}
}
- case REOPEN:
+ case COMMENT_TYPE_REOPEN:
rawSql := "UPDATE `repository` SET num_closed_issues = num_closed_issues - 1 WHERE id = ?"
if _, err := sess.Exec(rawSql, repoId); err != nil {
sess.Rollback()
return nil, err
}
- case CLOSE:
+ case COMMENT_TYPE_CLOSE:
rawSql := "UPDATE `repository` SET num_closed_issues = num_closed_issues + 1 WHERE id = ?"
if _, err := sess.Exec(rawSql, repoId); err != nil {
sess.Rollback()
diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go
index 37986b68bd..1510bafdb6 100644
--- a/models/migrations/migrations.go
+++ b/models/migrations/migrations.go
@@ -1,15 +1,44 @@
+// Copyright 2015 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 migrations
import (
- "errors"
- "strconv"
+ "fmt"
"strings"
"time"
+ "github.com/Unknwon/com"
"github.com/go-xorm/xorm"
+
+ "github.com/gogits/gogs/modules/log"
+ "github.com/gogits/gogs/modules/setting"
)
-type migration func(*xorm.Engine) error
+const _MIN_DB_VER = 0
+
+type Migration interface {
+ Description() string
+ Migrate(*xorm.Engine) error
+}
+
+type migration struct {
+ description string
+ migrate func(*xorm.Engine) error
+}
+
+func NewMigration(desc string, fn func(*xorm.Engine) error) Migration {
+ return &migration{desc, fn}
+}
+
+func (m *migration) Description() string {
+ return m.description
+}
+
+func (m *migration) Migrate(x *xorm.Engine) error {
+ return m.migrate(x)
+}
// The version table. Should have only one row with id==1
type Version struct {
@@ -18,23 +47,26 @@ type Version struct {
}
// This is a sequence of migrations. Add new migrations to the bottom of the list.
-// If you want to "retire" a migration, replace it with "expiredMigration"
-var migrations = []migration{
- accessToCollaboration,
- accessRefactor,
+// If you want to "retire" a migration, remove it from the top of the list and
+// update _MIN_VER_DB accordingly
+var migrations = []Migration{
+ NewMigration("generate collaboration from access", accessToCollaboration), // V0 -> V1
+ NewMigration("refactor access table to use id's", accessRefactor), // V1 -> V2
}
// Migrate database to current version
func Migrate(x *xorm.Engine) error {
if err := x.Sync(new(Version)); err != nil {
- return err
+ return fmt.Errorf("sync: %v", err)
}
currentVersion := &Version{Id: 1}
has, err := x.Get(currentVersion)
if err != nil {
- return err
+ return fmt.Errorf("get: %v", err)
} else if !has {
+ // If the user table does not exist it is a fresh installation and we
+ // can skip all migrations
needsMigration, err := x.IsTableExist("user")
if err != nil {
return err
@@ -44,22 +76,24 @@ func Migrate(x *xorm.Engine) error {
if err != nil {
return err
}
+ // If the user table is empty it is a fresh installation and we can
+ // skip all migrations
needsMigration = !isEmpty
}
if !needsMigration {
- currentVersion.Version = int64(len(migrations))
+ currentVersion.Version = int64(_MIN_DB_VER + len(migrations))
}
if _, err = x.InsertOne(currentVersion); err != nil {
- return err
+ return fmt.Errorf("insert: %v", err)
}
}
v := currentVersion.Version
-
- for i, migration := range migrations[v:] {
- if err = migration(x); err != nil {
- return err
+ for i, m := range migrations[v-_MIN_DB_VER:] {
+ log.Info("Migration: %s", m.Description())
+ if err = m.Migrate(x); err != nil {
+ return fmt.Errorf("do migrate: %v", err)
}
currentVersion.Version = v + int64(i) + 1
if _, err = x.Id(1).Update(currentVersion); err != nil {
@@ -69,52 +103,59 @@ func Migrate(x *xorm.Engine) error {
return nil
}
-func expiredMigration(x *xorm.Engine) error {
- return errors.New("You are migrating from a too old gogs version")
-}
-
-func mustParseInt64(in []byte) int64 {
- i, err := strconv.ParseInt(string(in), 10, 64)
- if err != nil {
- i = 0
- }
- return i
-}
-
func accessToCollaboration(x *xorm.Engine) error {
type Collaboration struct {
- ID int64 `xorm:"pk autoincr"`
- RepoID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
- UserID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
- Created time.Time `xorm:"CREATED"`
+ ID int64 `xorm:"pk autoincr"`
+ RepoID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
+ UserID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
+ Created time.Time
}
x.Sync(new(Collaboration))
- sql := `SELECT u.id AS uid, a.repo_name AS repo, a.mode AS mode, a.created as created FROM access a JOIN user u ON a.user_name=u.lower_name`
- results, err := x.Query(sql)
+ results, err := x.Query("SELECT u.id AS `uid`, a.repo_name AS `repo`, a.mode AS `mode`, a.created as `created` FROM `access` a JOIN `user` u ON a.user_name=u.lower_name")
if err != nil {
return err
}
- for _, result := range results {
- userID := mustParseInt64(result["uid"])
- repoRefName := string(result["repo"])
- mode := mustParseInt64(result["mode"])
- created := result["created"]
+ sess := x.NewSession()
+ defer func() {
+ if sess.IsCommitedOrRollbacked {
+ sess.Rollback()
+ }
+ sess.Close()
+ }()
+ if err = sess.Begin(); err != nil {
+ return err
+ }
- //Collaborators must have write access
+ offset := strings.Split(time.Now().String(), " ")[2]
+ for _, result := range results {
+ mode := com.StrTo(result["mode"]).MustInt64()
+ // Collaborators must have write access.
if mode < 2 {
continue
}
+ userID := com.StrTo(result["uid"]).MustInt64()
+ repoRefName := string(result["repo"])
+
+ var created time.Time
+ switch {
+ case setting.UseSQLite3:
+ created, _ = time.Parse(time.RFC3339, string(result["created"]))
+ case setting.UseMySQL:
+ created, _ = time.Parse("2006-01-02 15:04:05-0700", string(result["created"])+offset)
+ case setting.UsePostgreSQL:
+ created, _ = time.Parse("2006-01-02T15:04:05Z-0700", string(result["created"])+offset)
+ }
+
// find owner of repository
parts := strings.SplitN(repoRefName, "/", 2)
ownerName := parts[0]
repoName := parts[1]
- sql = `SELECT u.id as uid, ou.uid as memberid FROM user u LEFT JOIN org_user ou ON ou.org_id=u.id WHERE u.lower_name=?`
- results, err := x.Query(sql, ownerName)
+ results, err := sess.Query("SELECT u.id as `uid`, ou.uid as `memberid` FROM `user` u LEFT JOIN org_user ou ON ou.org_id=u.id WHERE u.lower_name=?", ownerName)
if err != nil {
return err
}
@@ -122,7 +163,7 @@ func accessToCollaboration(x *xorm.Engine) error {
continue
}
- ownerID := mustParseInt64(results[0]["uid"])
+ ownerID := com.StrTo(results[0]["uid"]).MustInt64()
if ownerID == userID {
continue
}
@@ -130,7 +171,7 @@ func accessToCollaboration(x *xorm.Engine) error {
// test if user is member of owning organization
isMember := false
for _, member := range results {
- memberID := mustParseInt64(member["memberid"])
+ memberID := com.StrTo(member["memberid"]).MustInt64()
// We can skip all cases that a user is member of the owning organization
if memberID == userID {
isMember = true
@@ -140,24 +181,31 @@ func accessToCollaboration(x *xorm.Engine) error {
continue
}
- sql = `SELECT id FROM repository WHERE owner_id=? AND lower_name=?`
- results, err = x.Query(sql, ownerID, repoName)
+ results, err = sess.Query("SELECT id FROM `repository` WHERE owner_id=? AND lower_name=?", ownerID, repoName)
if err != nil {
return err
- }
- if len(results) < 1 {
+ } else if len(results) < 1 {
continue
}
- repoID := results[0]["id"]
-
- sql = `INSERT INTO collaboration (user_id, repo_id, created) VALUES (?,?,?)`
- _, err = x.Exec(sql, userID, repoID, created)
+ collaboration := &Collaboration{
+ UserID: userID,
+ RepoID: com.StrTo(results[0]["id"]).MustInt64(),
+ }
+ has, err := sess.Get(collaboration)
if err != nil {
return err
+ } else if has {
+ continue
+ }
+
+ collaboration.Created = created
+ if _, err = sess.InsertOne(collaboration); err != nil {
+ return err
}
}
- return nil
+
+ return sess.Commit()
}
func accessRefactor(x *xorm.Engine) error {
diff --git a/models/models.go b/models/models.go
index 1a67041b4a..141e3ac497 100644
--- a/models/models.go
+++ b/models/models.go
@@ -24,7 +24,10 @@ import (
type Engine interface {
Delete(interface{}) (int64, error)
Exec(string, ...interface{}) (sql.Result, error)
+ Get(interface{}) (bool, error)
Insert(...interface{}) (int64, error)
+ Id(interface{}) *xorm.Session
+ Where(string, ...interface{}) *xorm.Session
}
var (
@@ -37,24 +40,29 @@ var (
}
EnableSQLite3 bool
- UseSQLite3 bool
)
func init() {
tables = append(tables,
- new(User), new(PublicKey), new(Follow), new(Oauth2), new(AccessToken),
- new(Repository), new(Watch), new(Star), new(Action), new(Access),
+ new(User), new(PublicKey), new(Oauth2), new(AccessToken),
+ new(Repository), new(Collaboration), new(Access),
+ new(Watch), new(Star), new(Follow), new(Action),
new(Issue), new(Comment), new(Attachment), new(IssueUser), new(Label), new(Milestone),
new(Mirror), new(Release), new(LoginSource), new(Webhook),
new(UpdateTask), new(HookTask), new(Team), new(OrgUser), new(TeamUser),
- new(Notice), new(EmailAddress), new(Collaboration))
+ new(Notice), new(EmailAddress))
}
func LoadModelsConfig() {
sec := setting.Cfg.Section("database")
DbCfg.Type = sec.Key("DB_TYPE").String()
- if DbCfg.Type == "sqlite3" {
- UseSQLite3 = true
+ switch DbCfg.Type {
+ case "sqlite3":
+ setting.UseSQLite3 = true
+ case "mysql":
+ setting.UseMySQL = true
+ case "postgres":
+ setting.UsePostgreSQL = true
}
DbCfg.Host = sec.Key("HOST").String()
DbCfg.Name = sec.Key("NAME").String()
@@ -138,7 +146,7 @@ func NewEngine() (err error) {
}
if err = migrations.Migrate(x); err != nil {
- return err
+ return fmt.Errorf("migrate: %v", err)
}
if err = x.StoreEngine("InnoDB").Sync2(tables...); err != nil {
diff --git a/models/org.go b/models/org.go
index f6d472a6d9..d667fb26dc 100644
--- a/models/org.go
+++ b/models/org.go
@@ -10,7 +10,6 @@ import (
"strings"
"github.com/Unknwon/com"
- "github.com/go-xorm/xorm"
"github.com/gogits/gogs/modules/base"
)
@@ -389,7 +388,7 @@ func RemoveOrgUser(orgId, uid int64) error {
return err
}
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
}
}
@@ -617,10 +616,9 @@ func GetTeam(orgId int64, name string) (*Team, error) {
return t, nil
}
-// GetTeamById returns team by given ID.
-func GetTeamById(teamId int64) (*Team, error) {
+func getTeamById(e Engine, teamId int64) (*Team, error) {
t := new(Team)
- has, err := x.Id(teamId).Get(t)
+ has, err := e.Id(teamId).Get(t)
if err != nil {
return nil, err
} else if !has {
@@ -629,6 +627,11 @@ func GetTeamById(teamId int64) (*Team, error) {
return t, nil
}
+// GetTeamById returns team by given ID.
+func GetTeamById(teamId int64) (*Team, error) {
+ return getTeamById(x, teamId)
+}
+
// UpdateTeam updates information of team.
func UpdateTeam(t *Team, authChanged bool) (err error) {
if !IsLegalName(t.Name) {
@@ -729,10 +732,14 @@ type TeamUser struct {
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.
func IsTeamMember(orgId, teamId, uid int64) bool {
- has, _ := x.Where("uid=?", uid).And("org_id=?", orgId).And("team_id=?", teamId).Get(new(TeamUser))
- return has
+ return isTeamMember(x, orgId, teamId, uid)
}
// GetTeamMembers returns all members in given team of organization.
@@ -742,17 +749,16 @@ func GetTeamMembers(orgId, teamId int64) ([]*User, error) {
return us, err
}
-// GetUserTeams returns all teams that user belongs to in given organization.
-func GetUserTeams(orgId, uid int64) ([]*Team, error) {
+func getUserTeams(e Engine, orgId, uid int64) ([]*Team, error) {
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
}
ts := make([]*Team, len(tus))
for i, tu := range tus {
t := new(Team)
- has, err := x.Id(tu.TeamId).Get(t)
+ has, err := e.Id(tu.TeamId).Get(t)
if err != nil {
return nil, err
} else if !has {
@@ -763,6 +769,11 @@ func GetUserTeams(orgId, uid int64) ([]*Team, error) {
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.
func AddTeamMember(orgId, teamId, uid int64) error {
if IsTeamMember(orgId, teamId, uid) {
@@ -831,13 +842,13 @@ func AddTeamMember(orgId, teamId, uid int64) error {
return sess.Commit()
}
-func removeTeamMemberWithSess(orgId, teamId, uid int64, sess *xorm.Session) error {
- if !IsTeamMember(orgId, teamId, uid) {
+func removeTeamMember(e Engine, orgId, teamId, uid int64) error {
+ if !isTeamMember(e, orgId, teamId, uid) {
return nil
}
// Get team and its repositories.
- t, err := GetTeamById(teamId)
+ t, err := getTeamById(e, teamId)
if err != nil {
return err
}
@@ -865,35 +876,30 @@ func removeTeamMemberWithSess(orgId, teamId, uid int64, sess *xorm.Session) erro
TeamId: teamId,
}
- if _, err := sess.Delete(tu); err != nil {
- sess.Rollback()
+ if _, err := e.Delete(tu); err != nil {
return err
- } else if _, err = sess.Id(t.Id).AllCols().Update(t); err != nil {
- sess.Rollback()
+ } else if _, err = e.Id(t.Id).AllCols().Update(t); err != nil {
return err
}
// Delete access to team repositories.
for _, repo := range t.Repos {
if err = repo.RecalcAccessSess(); err != nil {
- sess.Rollback()
return err
}
}
// This must exist.
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 {
- sess.Rollback()
return err
}
ou.NumTeams--
if t.IsOwnerTeam() {
ou.IsOwner = false
}
- if _, err = sess.Id(ou.Id).AllCols().Update(ou); err != nil {
- sess.Rollback()
+ if _, err = e.Id(ou.Id).AllCols().Update(ou); err != nil {
return err
}
return nil
@@ -906,7 +912,8 @@ func RemoveTeamMember(orgId, teamId, uid int64) error {
if err := sess.Begin(); err != nil {
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 sess.Commit()
diff --git a/models/publickey.go b/models/publickey.go
index 67ab4242f2..383b85b634 100644
--- a/models/publickey.go
+++ b/models/publickey.go
@@ -29,7 +29,7 @@ import (
const (
// "### 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 (
@@ -98,7 +98,7 @@ func (k *PublicKey) OmitEmail() string {
// GetAuthorizedString generates and returns formatted public key string for authorized_keys file.
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 (
diff --git a/models/repo.go b/models/repo.go
index 5943dd31ad..5a669d9dd8 100644
--- a/models/repo.go
+++ b/models/repo.go
@@ -30,7 +30,7 @@ import (
)
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 (
@@ -239,8 +239,8 @@ func (repo *Repository) CloneLink() (cl CloneLink, err error) {
if err = repo.GetOwner(); err != nil {
return cl, err
}
- 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)
+ 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)
} else {
cl.SSH = fmt.Sprintf("%s@%s:%s/%s.git", setting.RunUser, setting.Domain, repo.Owner.LowerName, repo.LowerName)
}
@@ -349,13 +349,16 @@ func MigrateRepository(u *User, name, desc string, private, mirror bool, url str
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,
fmt.Sprintf("MigrateRepository: %s", repoPath),
"git", "clone", "--mirror", "--bare", url, repoPath)
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)
}
@@ -394,15 +397,9 @@ func initRepoCommit(tmpPath string, sig *git.Signature) (err error) {
return nil
}
-func createHookUpdate(hookPath, content string) error {
- pu, err := os.OpenFile(hookPath, os.O_CREATE|os.O_WRONLY, 0777)
- if err != nil {
- return err
- }
- defer pu.Close()
-
- _, err = pu.WriteString(content)
- return err
+func createUpdateHook(repoPath string) error {
+ return ioutil.WriteFile(path.Join(repoPath, "hooks/update"),
+ []byte(fmt.Sprintf(_TPL_UPDATE_HOOK, setting.ScriptType, "\""+appPath+"\"", setting.CustomConf)), 0777)
}
// InitRepository initializes README and .gitignore if needed.
@@ -414,9 +411,7 @@ func initRepository(f string, u *User, repo *Repository, initReadme bool, repoLa
return err
}
- // hook/post-update
- if err := createHookUpdate(filepath.Join(repoPath, "hooks", "update"),
- fmt.Sprintf(TPL_UPDATE_HOOK, setting.ScriptType, "\""+appPath+"\"")); err != nil {
+ if err := createUpdateHook(repoPath); err != nil {
return err
}
@@ -938,58 +933,6 @@ func GetRepositoryCount(user *User) (int64, error) {
return x.Count(&Repository{OwnerId: user.Id})
}
-// GetCollaborators returns the collaborators for a repository
-func (r *Repository) GetCollaborators() ([]*User, error) {
- collaborations := make([]*Collaboration, 0)
- if err := x.Find(&collaborations, &Collaboration{RepoID: r.Id}); err != nil {
- return nil, err
- }
-
- users := make([]*User, len(collaborations))
- for i, c := range collaborations {
- user, err := GetUserById(c.UserID)
- if err != nil {
- return nil, err
- }
- users[i] = user
- }
- return users, nil
-}
-
-// Add collaborator and accompanying access
-func (r *Repository) AddCollaborator(u *User) error {
- collaboration := &Collaboration{RepoID: r.Id, UserID: u.Id}
-
- has, err := x.Get(collaboration)
- if err != nil {
- return err
- }
- if has {
- return nil
- }
-
- if _, err = x.InsertOne(collaboration); err != nil {
- return err
- }
-
- if err = r.GetOwner(); err != nil {
- return err
- }
-
- return r.RecalcAccessSess()
-}
-
-// Delete collaborator and accompanying access
-func (r *Repository) DeleteCollaborator(u *User) error {
- collaboration := &Collaboration{RepoID: r.Id, UserID: u.Id}
-
- if has, err := x.Delete(collaboration); err != nil || has == 0 {
- return err
- }
-
- return r.RecalcAccessSess()
-}
-
type SearchOption struct {
Keyword string
Uid int64
@@ -1030,6 +973,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 (
// Prevent duplicate tasks.
isMirrorUpdating = false
@@ -1125,6 +1080,73 @@ func GitGcRepos() error {
})
}
+// _________ .__ .__ ___. __ .__
+// \_ ___ \ ____ | | | | _____ \_ |__ ________________ _/ |_|__| ____ ____
+// / \ \/ / _ \| | | | \__ \ | __ \ / _ \_ __ \__ \\ __\ |/ _ \ / \
+// \ \___( <_> ) |_| |__/ __ \| \_\ ( <_> ) | \// __ \| | | ( <_> ) | \
+// \______ /\____/|____/____(____ /___ /\____/|__| (____ /__| |__|\____/|___| /
+// \/ \/ \/ \/ \/
+
+// A Collaboration is a relation between an individual and a repository
+type Collaboration struct {
+ ID int64 `xorm:"pk autoincr"`
+ RepoID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
+ UserID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
+ Created time.Time `xorm:"CREATED"`
+}
+
+// Add collaborator and accompanying access
+func (r *Repository) AddCollaborator(u *User) error {
+ collaboration := &Collaboration{RepoID: r.Id, UserID: u.Id}
+
+ has, err := x.Get(collaboration)
+ if err != nil {
+ return err
+ }
+ if has {
+ return nil
+ }
+
+ if _, err = x.InsertOne(collaboration); err != nil {
+ return err
+ }
+
+ if err = r.GetOwner(); err != nil {
+ return err
+ }
+
+ return r.RecalcAccessSess()
+}
+
+// GetCollaborators returns the collaborators for a repository
+func (r *Repository) GetCollaborators() ([]*User, error) {
+ collaborations := make([]*Collaboration, 0)
+ if err := x.Find(&collaborations, &Collaboration{RepoID: r.Id}); err != nil {
+ return nil, err
+ }
+
+ users := make([]*User, len(collaborations))
+ for i, c := range collaborations {
+ user, err := GetUserById(c.UserID)
+ if err != nil {
+ return nil, err
+ }
+ users[i] = user
+ }
+ return users, nil
+}
+
+// Delete collaborator and accompanying access
+func (r *Repository) DeleteCollaborator(u *User) error {
+ collaboration := &Collaboration{RepoID: r.Id, UserID: u.Id}
+
+ if has, err := x.Delete(collaboration); err != nil || has == 0 {
+ return err
+ }
+
+ return r.RecalcAccessSess()
+}
+
// __ __ __ .__
// / \ / \_____ _/ |_ ____ | |__
// \ \/\/ /\__ \\ __\/ ___\| | \
@@ -1145,7 +1167,7 @@ func IsWatching(uid, repoId int64) bool {
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 IsWatching(uid, repoId) {
return nil
@@ -1168,7 +1190,7 @@ func watchRepoWithEngine(e Engine, uid, repoId int64, watch bool) (err error) {
// Watch or unwatch repository.
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.
@@ -1326,14 +1348,14 @@ func ForkRepository(u *User, oldRepo *Repository, name, desc string) (*Repositor
log.Error(4, "GetMembers: %v", err)
} else {
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)
}
}
}
}
} 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)
}
}
@@ -1375,11 +1397,3 @@ func ForkRepository(u *User, oldRepo *Repository, name, desc string) (*Repositor
return repo, nil
}
-
-// A Collaboration is a relation between an individual and a repository
-type Collaboration struct {
- ID int64 `xorm:"pk autoincr"`
- RepoID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
- UserID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
- Created time.Time `xorm:"CREATED"`
-}
diff --git a/models/user.go b/models/user.go
index b33e529aa6..7e3dc260e5 100644
--- a/models/user.go
+++ b/models/user.go
@@ -512,8 +512,7 @@ func UserPath(userName string) string {
func GetUserByKeyId(keyId int64) (*User, error) {
user := new(User)
- rawSql := "SELECT a.* FROM `user` AS a, public_key AS b WHERE a.id = b.owner_id AND b.id=?"
- has, err := x.Sql(rawSql, keyId).Get(user)
+ has, err := x.Sql("SELECT a.* FROM `user` AS a, public_key AS b WHERE a.id = b.owner_id AND b.id=?", keyId).Get(user)
if err != nil {
return nil, err
} else if !has {
diff --git a/models/webhook.go b/models/webhook.go
index 8e112ac572..96af0b6967 100644
--- a/models/webhook.go
+++ b/models/webhook.go
@@ -5,6 +5,7 @@
package models
import (
+ "crypto/tls"
"encoding/json"
"errors"
"io/ioutil"
@@ -307,13 +308,14 @@ func DeliverHooks() {
defer func() { isShooting = false }()
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),
func(idx int, bean interface{}) error {
t := bean.(*HookTask)
req := httplib.Post(t.Url).SetTimeout(timeout, timeout).
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 {
case JSON:
@@ -329,7 +331,7 @@ func DeliverHooks() {
case GOGS:
{
if _, err := req.Response(); err != nil {
- log.Error(4, "Delivery: %v", err)
+ log.Error(5, "Delivery: %v", err)
} else {
t.IsSucceed = true
}
@@ -337,15 +339,15 @@ func DeliverHooks() {
case SLACK:
{
if res, err := req.Response(); err != nil {
- log.Error(4, "Delivery: %v", err)
+ log.Error(5, "Delivery: %v", err)
} else {
defer res.Body.Close()
contents, err := ioutil.ReadAll(res.Body)
if err != nil {
- log.Error(4, "%s", err)
+ log.Error(5, "%s", err)
} else {
if string(contents) != "ok" {
- log.Error(4, "slack failed with: %s", string(contents))
+ log.Error(5, "slack failed with: %s", string(contents))
} else {
t.IsSucceed = true
}
diff --git a/modules/asn1-ber/ber.go b/modules/asn1-ber/ber.go
index 3e99a273c6..52b9a59180 100644
--- a/modules/asn1-ber/ber.go
+++ b/modules/asn1-ber/ber.go
@@ -256,11 +256,11 @@ func ReadPacket(reader io.Reader) (*Packet, error) {
}
func DecodeString(data []byte) (ret string) {
- for _, c := range data {
- ret += fmt.Sprintf("%c", c)
- }
+ // for _, c := range data {
+ // ret += fmt.Sprintf("%c", c)
+ // }
- return
+ return string(data)
}
func DecodeInteger(data []byte) (ret uint64) {
diff --git a/modules/base/markdown.go b/modules/base/markdown.go
index d3f3e5feaf..4a7adc8a48 100644
--- a/modules/base/markdown.go
+++ b/modules/base/markdown.go
@@ -106,7 +106,7 @@ func (options *CustomRender) Image(out *bytes.Buffer, link []byte, title []byte,
}
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-]*)?`)
issueFullPattern = regexp.MustCompile(`(\s|^)https?.*issues/[0-9]+(#+[0-9a-zA-Z-]*)?`)
issueIndexPattern = regexp.MustCompile(`( |^)#[0-9]+`)
@@ -128,8 +128,9 @@ func RenderSpecialLink(rawBytes []byte, urlPrefix string) []byte {
if !inCodeBlock && !bytes.HasPrefix(line, tab) {
ms := MentionPattern.FindAll(line, -1)
for _, m := range ms {
+ m = bytes.TrimSpace(m)
line = bytes.Replace(line, m,
- []byte(fmt.Sprintf(`<a href="%s/user/%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 {
ms := issueIndexPattern.FindAll(rawBytes, -1)
for _, m := range ms {
- rawBytes = bytes.Replace(rawBytes, m, []byte(fmt.Sprintf(
- `<a href="%s/issues/%s">%s</a>`, urlPrefix, m[1:], m)), -1)
+ rawBytes = bytes.Replace(rawBytes, m, []byte(fmt.Sprintf(`<a href="%s/issues/%s">%s</a>`,
+ urlPrefix, strings.TrimPrefix(string(m[1:]), "#"), m)), -1)
}
return rawBytes
}
diff --git a/modules/cron/manager.go b/modules/cron/manager.go
index 135fec4faa..2990ab0604 100644
--- a/modules/cron/manager.go
+++ b/modules/cron/manager.go
@@ -15,7 +15,7 @@ var c = New()
func NewCronContext() {
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 {
c.AddFunc("Repository health check", fmt.Sprintf("@every %dh", setting.Git.Fsck.Interval), models.GitFsck)
}
diff --git a/modules/middleware/auth.go b/modules/middleware/auth.go
index b0bcd87f54..3c06c69f8c 100644
--- a/modules/middleware/auth.go
+++ b/modules/middleware/auth.go
@@ -6,7 +6,6 @@ package middleware
import (
"net/url"
- "strings"
"github.com/Unknwon/macaron"
"github.com/macaron-contrib/csrf"
@@ -50,10 +49,6 @@ func Toggle(options *ToggleOptions) macaron.Handler {
if options.SignInRequire {
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.Redirect(setting.AppSubUrl + "/user/login")
return
diff --git a/modules/middleware/context.go b/modules/middleware/context.go
index fc7814401f..28be3a3025 100644
--- a/modules/middleware/context.go
+++ b/modules/middleware/context.go
@@ -192,6 +192,8 @@ func Contexter() macaron.Handler {
ctx.Data["CsrfToken"] = x.GetToken()
ctx.Data["CsrfTokenHtml"] = template.HTML(`<input type="hidden" name="_csrf" value="` + x.GetToken() + `">`)
+ ctx.Data["ShowRegistrationButton"] = setting.Service.ShowRegistrationButton
+
c.Map(ctx)
}
}
diff --git a/modules/middleware/repo.go b/modules/middleware/repo.go
index bc1d1f9692..8465af83ef 100644
--- a/modules/middleware/repo.go
+++ b/modules/middleware/repo.go
@@ -64,6 +64,7 @@ func ApiRepoAssignment() macaron.Handler {
ctx.JSON(500, &base.ApiJsonErr{"AccessLevel: " + err.Error(), base.DOC_URL})
return
}
+
ctx.Repo.IsOwner = mode >= models.ACCESS_MODE_WRITE
ctx.Repo.IsAdmin = mode >= models.ACCESS_MODE_READ
ctx.Repo.IsTrueOwner = mode >= models.ACCESS_MODE_OWNER
@@ -305,6 +306,7 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
ctx.Data["IsRepositoryOwner"] = ctx.Repo.IsOwner
ctx.Data["IsRepositoryTrueOwner"] = ctx.Repo.IsTrueOwner
+ ctx.Data["DisableSSH"] = setting.DisableSSH
ctx.Repo.CloneLink, err = repo.CloneLink()
if err != nil {
ctx.Handle(500, "CloneLink", err)
diff --git a/modules/setting/setting.go b/modules/setting/setting.go
index e7c44cdd4f..795bcc5ba2 100644
--- a/modules/setting/setting.go
+++ b/modules/setting/setting.go
@@ -50,7 +50,8 @@ var (
Protocol Scheme
Domain string
HttpAddr, HttpPort string
- SshPort int
+ DisableSSH bool
+ SSHPort int
OfflineMode bool
DisableRouterLog bool
CertFile, KeyFile string
@@ -66,9 +67,17 @@ var (
CookieRememberName string
ReverseProxyAuthUser string
+ // Database settings.
+ UseSQLite3 bool
+ UseMySQL bool
+ UsePostgreSQL bool
+
// Webhook settings.
- WebhookTaskInterval int
- WebhookDeliverTimeout int
+ Webhook struct {
+ TaskInterval int
+ DeliverTimeout int
+ SkipTLSVerify bool
+ }
// Repository settings.
RepoRootPath string
@@ -124,6 +133,7 @@ var (
Cfg *ini.File
ConfRootPath string
CustomPath string // Custom directory path.
+ CustomConf string
ProdMode bool
RunUser string
IsWindows bool
@@ -172,13 +182,16 @@ func NewConfigContext() {
CustomPath = path.Join(workDir, "custom")
}
- cfgPath := path.Join(CustomPath, "conf/app.ini")
- if com.IsFile(cfgPath) {
- if err = Cfg.Append(cfgPath); err != nil {
- log.Fatal(4, "Fail to load custom 'conf/app.ini': %v", err)
+ if len(CustomConf) == 0 {
+ CustomConf = path.Join(CustomPath, "conf/app.ini")
+ }
+
+ if com.IsFile(CustomConf) {
+ if err = Cfg.Append(CustomConf); err != nil {
+ log.Fatal(4, "Fail to load custom conf '%s': %v", CustomConf, err)
}
} 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
@@ -209,7 +222,8 @@ func NewConfigContext() {
Domain = sec.Key("DOMAIN").MustString("localhost")
HttpAddr = sec.Key("HTTP_ADDR").MustString("0.0.0.0")
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()
DisableRouterLog = sec.Key("DISABLE_ROUTER_LOG").MustBool()
StaticRootPath = sec.Key("STATIC_ROOT_PATH").MustString(workDir)
@@ -231,7 +245,7 @@ func NewConfigContext() {
ReverseProxyAuthUser = sec.Key("REVERSE_PROXY_AUTHENTICATION_USER").MustString("X-WEBAUTH-USER")
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")
AttachmentMaxSize = sec.Key("MAX_SIZE").MustInt64(32)
AttachmentMaxFiles = sec.Key("MAX_FILES").MustInt(10)
@@ -288,7 +302,7 @@ func NewConfigContext() {
sec = Cfg.Section("picture")
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)
switch sec.Key("GRAVATAR_SOURCE").MustString("gravatar") {
case "duoshuo":
@@ -311,6 +325,7 @@ func NewConfigContext() {
var Service struct {
RegisterEmailConfirm bool
DisableRegistration bool
+ ShowRegistrationButton bool
RequireSignInView bool
EnableCacheAvatar bool
EnableNotifyMail bool
@@ -324,6 +339,7 @@ func newService() {
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.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.EnableCacheAvatar = Cfg.Section("service").Key("ENABLE_CACHE_AVATAR").MustBool()
Service.EnableReverseProxyAuth = Cfg.Section("service").Key("ENABLE_REVERSE_PROXY_AUTHENTICATION").MustBool()
@@ -500,8 +516,10 @@ func newNotifyMailService() {
}
func newWebhookService() {
- WebhookTaskInterval = Cfg.Section("webhook").Key("TASK_INTERVAL").MustInt(1)
- WebhookDeliverTimeout = Cfg.Section("webhook").Key("DELIVER_TIMEOUT").MustInt(5)
+ sec := Cfg.Section("webhook")
+ 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() {
diff --git a/public/ng/css/gogs.css b/public/ng/css/gogs.css
index dc451a7051..9f6cf12f97 100644
--- a/public/ng/css/gogs.css
+++ b/public/ng/css/gogs.css
@@ -364,6 +364,9 @@ img.avatar-100 {
.markdown table tr:nth-child(2n) {
background-color: #F8F8F8;
}
+.markdown p {
+ margin: 20px 0;
+}
.markdown a {
color: #428BCA;
}
@@ -1063,6 +1066,9 @@ The register and sign-in page style
#repo-header-download-drop .btn > i {
margin-right: 6px;
}
+#repo-header-download-drop input {
+ cursor: default;
+}
#repo-header-download-drop button,
#repo-header-download-drop input {
font-size: 11px;
@@ -1215,6 +1221,9 @@ The register and sign-in page style
#repo-files-table {
margin-bottom: 20px;
}
+#repo-files-table .sha .label {
+ font-family: Monaco, Menlo, Consolas, "Courier New", monospace;
+}
#repo-files-table th,
#repo-files-table td {
text-align: left;
@@ -1620,11 +1629,23 @@ The register and sign-in page style
background-color: #E0E0E0 !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 pre {
background-color: #ffe2dd !important;
border-color: #e9aeae !important;
}
+.diff-file-box .code-diff tbody tr.del-code td.selected-line,
+.diff-file-box .code-diff tbody tr.del-code td.selected-line pre {
+ background-color: #ffffdd !important;
+}
.diff-file-box .code-diff tbody tr.add-code td,
.diff-file-box .code-diff tbody tr.add-code pre {
background-color: #d1ffd6 !important;
diff --git a/public/ng/js/gogs.js b/public/ng/js/gogs.js
index e9b44d6575..a6b9753e17 100644
--- a/public/ng/js/gogs.js
+++ b/public/ng/js/gogs.js
@@ -206,10 +206,18 @@ var Gogs = {};
Gogs.renderDiffView = function () {
function selectRange($list, $select, $from) {
$list.removeClass('active');
+ $list.parents('tr').removeClass('end-selected-line');
$list.parents('tr').find('td').removeClass('selected-line');
if ($from) {
- var a = parseInt($select.attr('rel').substr(1));
- var b = parseInt($from.attr('rel').substr(1));
+ var expr = new RegExp(/diff-(\d+)L(\d+)/);
+ var selectMatches = $select.attr('rel').match(expr)
+ var fromMatches = $from.attr('rel').match(expr)
+ var a = parseInt(selectMatches[2]);
+ var b = parseInt(fromMatches[2]);
+ var linesIntToStr = {};
+ linesIntToStr[a] = selectMatches[2];
+ linesIntToStr[b] = fromMatches[2];
+
var c;
if (a != b) {
if (a > b) {
@@ -217,13 +225,11 @@ var Gogs = {};
a = b;
b = c;
}
- var classes = [];
- for (i = a; i <= b; i++) {
- classes.push('[rel=L' + i + ']');
- }
- $list.filter(classes.join(',')).addClass('active');
- $list.filter(classes.join(',')).parents('tr').find('td').addClass('selected-line');
- $.changeHash('#L' + a + '-' + 'L' + b);
+ $('[rel=diff-'+fromMatches[1]+'L' + linesIntToStr[b] + ']').parents('tr').next().addClass('end-selected-line');
+ var $selectedLines = $('[rel=diff-'+fromMatches[1]+'L' + linesIntToStr[a] + ']').parents('tr').nextUntil('.end-selected-line').andSelf();
+ $selectedLines.find('td.lines-num > span').addClass('active')
+ $selectedLines.find('td').addClass('selected-line');
+ $.changeHash('#diff-'+fromMatches[1]+'L' + linesIntToStr[a] + '-L' + linesIntToStr[b]);
return
}
}
@@ -256,18 +262,18 @@ var Gogs = {};
});
$(window).on('hashchange', function (e) {
- var m = window.location.hash.match(/^#(L\d+)\-(L\d+)$/);
+ var m = window.location.hash.match(/^#diff-(\d+)(L\d+)\-(L\d+)$/);
var $list = $('.code-diff td.lines-num > span');
var $first;
if (m) {
- $first = $list.filter('[rel=' + m[1] + ']');
- selectRange($list, $first, $list.filter('[rel=' + m[2] + ']'));
+ $first = $list.filter('[rel=diff-' + m[1] + m[2] + ']');
+ selectRange($list, $first, $list.filter('[rel=diff-' + m[1] + m[3] + ']'));
$("html, body").scrollTop($first.offset().top - 200);
return;
}
- m = window.location.hash.match(/^#(L\d+)$/);
+ m = window.location.hash.match(/^#diff-(\d+)(L\d+)$/);
if (m) {
- $first = $list.filter('[rel=' + m[1] + ']');
+ $first = $list.filter('[rel=diff-' + m[1] + m[2] + ']');
selectRange($list, $first);
$("html, body").scrollTop($first.offset().top - 200);
}
diff --git a/public/ng/less/gogs/markdown.less b/public/ng/less/gogs/markdown.less
index e3abb480a2..cd2eef99bc 100644
--- a/public/ng/less/gogs/markdown.less
+++ b/public/ng/less/gogs/markdown.less
@@ -1,88 +1,91 @@
.markdown {
- background-color: white;
- font-size: 16px;
- line-height: 24px;
- .markdown-body {
- padding-left: 24px;
- padding-right: 16px;
- }
- h5,
- h6 {
- font-size: 1em;
- }
- ul {
- padding: 10px 0 0 15px;
- li {
- list-style: inside;
- }
- }
- ol li {
- list-style: decimal inside;
- }
+ background-color: white;
+ font-size: 16px;
+ line-height: 24px;
+ .markdown-body {
+ padding-left: 24px;
+ padding-right: 16px;
+ }
+ h5,
+ h6 {
+ font-size: 1em;
+ }
+ ul {
+ padding: 10px 0 0 15px;
li {
- line-height: 1.6;
- margin-top: 6px;
- &:first-child {
- margin-top: 0;
- }
- }
+ list-style: inside;
+ }
+ }
+ 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 {
- 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 {
- padding: 0;
- background-color: inherit;
- }
- }
- img {
- padding: 10px 0;
- max-width: 100%;
- }
- blockquote {
- border-left: 4px solid #ddd;
- margin-bottom: 16px;
- p {
- font-size: 14px;
- padding: 5px 15px;
- color: #777;
- }
- }
- table {
- display: block;
- width: 100%;
- overflow: auto;
- word-break: normal;
- margin: 15px 0;
- border-collapse: collapse;
- border-spacing: 0;
- display: block;
- th {
- font-weight: 700;
- }
- 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;
- }
- }
- }
+ padding: 0;
+ background-color: inherit;
+ }
+ }
+ img {
+ padding: 10px 0;
+ max-width: 100%;
+ }
+ blockquote {
+ border-left: 4px solid #ddd;
+ margin-bottom: 16px;
+ p {
+ font-size: 14px;
+ padding: 5px 15px;
+ color: #777;
+ }
+ }
+ table {
+ display: block;
+ width: 100%;
+ overflow: auto;
+ word-break: normal;
+ margin: 15px 0;
+ border-collapse: collapse;
+ border-spacing: 0;
+ display: block;
+ th {
+ font-weight: 700;
+ }
+ 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;
+ }
+ }
+ }
+ p {
+ margin: 20px 0;
+ }
}
.markdown a {
color: #428BCA;
diff --git a/public/ng/less/gogs/repository.less b/public/ng/less/gogs/repository.less
index e48f5c8713..d683d03341 100644
--- a/public/ng/less/gogs/repository.less
+++ b/public/ng/less/gogs/repository.less
@@ -81,6 +81,9 @@
.btn>i {
margin-right: 6px;
}
+ input {
+ cursor: default;
+ }
button, input {
font-size: 11px;
}
@@ -247,6 +250,9 @@
}
#repo-files-table {
margin-bottom: 20px;
+ .sha .label {
+ font-family: Monaco,Menlo,Consolas,"Courier New",monospace;
+ }
th, td {
text-align: left;
line-height: 32px;
@@ -653,12 +659,23 @@
background-color: #E0E0E0 !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 {
td, pre {
background-color: #ffe2dd !important;
border-color: #e9aeae !important;
}
+ td.selected-line, td.selected-line pre {
+ background-color: #ffffdd !important;
+ }
}
&.add-code {
td, pre {
diff --git a/routers/admin/admin.go b/routers/admin/admin.go
index ea50d5c4cb..316f1d4257 100644
--- a/routers/admin/admin.go
+++ b/routers/admin/admin.go
@@ -119,6 +119,7 @@ const (
CLEAN_REPO_ARCHIVES
GIT_GC_REPOS
SYNC_SSH_AUTHORIZED_KEY
+ SYNC_REPOSITORY_UPDATE_HOOK
)
func Dashboard(ctx *middleware.Context) {
@@ -148,6 +149,9 @@ func Dashboard(ctx *middleware.Context) {
case SYNC_SSH_AUTHORIZED_KEY:
success = ctx.Tr("admin.dashboard.resync_all_sshkeys_success")
err = models.RewriteAllPublicKeys()
+ case SYNC_REPOSITORY_UPDATE_HOOK:
+ success = ctx.Tr("admin.dashboard.resync_all_update_hooks_success")
+ err = models.RewriteRepositoryUpdateHook()
}
if err != nil {
@@ -184,11 +188,8 @@ func Config(ctx *middleware.Context) {
ctx.Data["ReverseProxyAuthUser"] = setting.ReverseProxyAuthUser
ctx.Data["Service"] = setting.Service
-
ctx.Data["DbCfg"] = models.DbCfg
-
- ctx.Data["WebhookTaskInterval"] = setting.WebhookTaskInterval
- ctx.Data["WebhookDeliverTimeout"] = setting.WebhookDeliverTimeout
+ ctx.Data["Webhook"] = setting.Webhook
ctx.Data["MailerEnabled"] = false
if setting.MailService != nil {
diff --git a/routers/install.go b/routers/install.go
index 9c3f134d45..a3583a1a98 100644
--- a/routers/install.go
+++ b/routers/install.go
@@ -9,6 +9,7 @@ import (
"os"
"os/exec"
"path"
+ "path/filepath"
"strings"
"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("SECRET_KEY").SetValue(base.GetRandomString(15))
- os.MkdirAll("custom/conf", os.ModePerm)
- if err := cfg.SaveTo(path.Join(setting.CustomPath, "conf/app.ini")); err != nil {
+ os.MkdirAll(filepath.Dir(setting.CustomConf), os.ModePerm)
+ if err := cfg.SaveTo(setting.CustomConf); err != nil {
ctx.RenderWithErr(ctx.Tr("install.save_config_failed", err), INSTALL, &form)
return
}
diff --git a/routers/org/teams.go b/routers/org/teams.go
index a315abe03e..2fbb1480d1 100644
--- a/routers/org/teams.go
+++ b/routers/org/teams.go
@@ -138,11 +138,8 @@ func TeamsRepoAction(ctx *middleware.Context) {
}
if err != nil {
- log.Error(3, "Action(%s): %v", ctx.Params(":action"), err)
- ctx.JSON(200, map[string]interface{}{
- "ok": false,
- "err": err.Error(),
- })
+ log.Error(3, "Action(%s): '%s' %v", ctx.Params(":action"), ctx.Org.Team.Name, err)
+ ctx.Handle(500, "TeamsRepoAction", err)
return
}
ctx.Redirect(ctx.Org.OrgLink + "/teams/" + ctx.Org.Team.LowerName + "/repositories")
diff --git a/routers/repo/commit.go b/routers/repo/commit.go
index e92ec8c88c..5d354c4b56 100644
--- a/routers/repo/commit.go
+++ b/routers/repo/commit.go
@@ -253,6 +253,9 @@ func Diff(ctx *middleware.Context) {
ctx.Data["Parents"] = parents
ctx.Data["DiffNotAvailable"] = diff.NumFiles() == 0
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.HTML(200, DIFF)
}
@@ -316,6 +319,7 @@ func CompareDiff(ctx *middleware.Context) {
ctx.Data["Diff"] = diff
ctx.Data["DiffNotAvailable"] = diff.NumFiles() == 0
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.HTML(200, DIFF)
}
diff --git a/routers/repo/http.go b/routers/repo/http.go
index 4173c7a91f..a209c2b254 100644
--- a/routers/repo/http.go
+++ b/routers/repo/http.go
@@ -73,11 +73,14 @@ func Http(ctx *middleware.Context) {
return
}
- // only public pull don't need auth
+ // Only public pull don't need auth.
isPublicPull := !repo.IsPrivate && isPull
- var askAuth = !isPublicPull || setting.Service.RequireSignInView
- var authUser *models.User
- var authUsername, passwd string
+ var (
+ askAuth = !isPublicPull || setting.Service.RequireSignInView
+ authUser *models.User
+ authUsername string
+ authPasswd string
+ )
// check access
if askAuth {
@@ -90,12 +93,13 @@ func Http(ctx *middleware.Context) {
auths := strings.Fields(baHead)
// currently check basic 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" {
ctx.Handle(401, "no basic auth and digit auth", nil)
return
}
- authUsername, passwd, err = base.BasicAuthDecode(auths[1])
+ authUsername, authPasswd, err = base.BasicAuthDecode(auths[1])
if err != nil {
ctx.Handle(401, "no basic auth and digit auth", nil)
return
@@ -103,15 +107,33 @@ func Http(ctx *middleware.Context) {
authUser, err = models.GetUserByName(authUsername)
if err != nil {
- ctx.Handle(401, "no basic auth and digit auth", nil)
- return
- }
+ if err != models.ErrUserNotExist {
+ ctx.Handle(500, "GetUserByName", err)
+ return
+ }
- newUser := &models.User{Passwd: passwd, Salt: authUser.Salt}
- newUser.EncodePasswd()
- if authUser.Passwd != newUser.Passwd {
- ctx.Handle(401, "no basic auth and digit auth", nil)
- return
+ // Assume username now is a token.
+ token, err := models.GetAccessTokenBySha(authUsername)
+ if err != nil {
+ if err == models.ErrAccessTokenNotExist {
+ 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 {
@@ -139,9 +161,7 @@ func Http(ctx *middleware.Context) {
}
}
- var f func(rpc string, input []byte)
-
- f = func(rpc string, input []byte) {
+ var f = func(rpc string, input []byte) {
if rpc == "receive-pack" {
var lastLine int64 = 0
diff --git a/routers/repo/issue.go b/routers/repo/issue.go
index 921348dbd1..bf39d9aba6 100644
--- a/routers/repo/issue.go
+++ b/routers/repo/issue.go
@@ -424,7 +424,7 @@ func ViewIssue(ctx *middleware.Context) {
}
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))
}
}
@@ -774,9 +774,9 @@ func Comment(ctx *middleware.Context) {
}
}
- cmtType := models.CLOSE
+ cmtType := models.COMMENT_TYPE_CLOSE
if !issue.IsClosed {
- cmtType = models.REOPEN
+ cmtType = models.COMMENT_TYPE_REOPEN
}
if _, err = models.CreateComment(ctx.User.Id, ctx.Repo.Repository.Id, issue.Id, 0, 0, cmtType, "", nil); err != nil {
@@ -795,7 +795,7 @@ func Comment(ctx *middleware.Context) {
if len(content) > 0 || len(ctx.Req.MultipartForm.File["attachments"]) > 0 {
switch ctx.Params(":action") {
case "new":
- if comment, err = models.CreateComment(ctx.User.Id, ctx.Repo.Repository.Id, issue.Id, 0, 0, models.COMMENT, content, nil); err != nil {
+ if comment, err = models.CreateComment(ctx.User.Id, ctx.Repo.Repository.Id, issue.Id, 0, 0, models.COMMENT_TYPE_COMMENT, content, nil); err != nil {
send(500, nil, err)
return
}
diff --git a/routers/repo/view.go b/routers/repo/view.go
index cb689df6a0..cfe0fa010c 100644
--- a/routers/repo/view.go
+++ b/routers/repo/view.go
@@ -127,7 +127,6 @@ func Home(ctx *middleware.Context) {
entries.Sort()
files := make([][]interface{}, 0, len(entries))
-
for _, te := range entries {
if te.Type != git.COMMIT {
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())})
}
}
-
- // 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
var readmeFile *git.Blob
@@ -208,7 +197,6 @@ func Home(ctx *middleware.Context) {
}
lastCommit := ctx.Repo.Commit
- lastCommit.CommitMessage = string(base.RenderIssueIndexPattern([]byte(lastCommit.CommitMessage), ctx.Repo.RepoLink))
if len(treePath) > 0 {
c, err := ctx.Repo.Commit.GetCommitOfRelPath(treePath)
if err != nil {
diff --git a/templates/.VERSION b/templates/.VERSION
index 40246b9eca..2aad3653cb 100644
--- a/templates/.VERSION
+++ b/templates/.VERSION
@@ -1 +1 @@
-0.5.12.0204 Beta \ No newline at end of file
+0.5.13.0211 Beta \ No newline at end of file
diff --git a/templates/admin/config.tmpl b/templates/admin/config.tmpl
index 1f8a85ecb2..6c328353bc 100644
--- a/templates/admin/config.tmpl
+++ b/templates/admin/config.tmpl
@@ -78,6 +78,8 @@
<dd><i class="fa fa{{if .Service.RegisterEmailConfirm}}-check{{end}}-square-o"></i></dd>
<dt>{{.i18n.Tr "admin.config.disable_register"}}</dt>
<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>
<dd><i class="fa fa{{if .Service.RequireSignInView}}-check{{end}}-square-o"></i></dd>
<dt>{{.i18n.Tr "admin.config.mail_notify"}}</dt>
@@ -100,9 +102,11 @@
<div class="panel-body">
<dl class="dl-horizontal admin-dl-horizontal">
<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>
- <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>
</div>
</div>
diff --git a/templates/admin/dashboard.tmpl b/templates/admin/dashboard.tmpl
index b570517536..5db717bfe1 100644
--- a/templates/admin/dashboard.tmpl
+++ b/templates/admin/dashboard.tmpl
@@ -52,7 +52,10 @@
<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>
</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>
</table>
</div>
diff --git a/templates/home.tmpl b/templates/home.tmpl
index 8603f26f41..29865dbf9a 100644
--- a/templates/home.tmpl
+++ b/templates/home.tmpl
@@ -14,7 +14,9 @@
<input class="ipt ipt-large" name="password" type="password" placeholder="{{.i18n.Tr "home.password_holder"}}"/>
<input name="from" type="hidden" value="home">
<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>
+ {{end}}
</form>
<div id="promo-social" class="social-buttons">
{{template "ng/base/social" .}}
diff --git a/templates/ng/base/footer.tmpl b/templates/ng/base/footer.tmpl
index 734533a108..89836fca23 100644
--- a/templates/ng/base/footer.tmpl
+++ b/templates/ng/base/footer.tmpl
@@ -1,7 +1,7 @@
</div>
<footer id="footer">
<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 Gogs · {{.i18n.Tr "version"}}: {{AppVer}} · {{.i18n.Tr "page"}}: <strong>{{LoadTimes .PageStartTime}}</strong> ·
{{.i18n.Tr "template"}}: <strong>{{call .TmplLoadTimes}}</strong></p>
<div class="right" id="footer-links">
diff --git a/templates/ng/base/header.tmpl b/templates/ng/base/header.tmpl
index aec4e2ef66..da9218368d 100644
--- a/templates/ng/base/header.tmpl
+++ b/templates/ng/base/header.tmpl
@@ -49,10 +49,12 @@
<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>
</li>
+ {{if .ShowRegistrationButton}}
<li class="right">
<a href="{{AppSubUrl}}/user/sign_up" title="Account Settings"><i class="octicon octicon-person-add"></i> {{.i18n.Tr "register"}}</a>
</li>
{{end}}
+ {{end}}
{{end}}
</ul>
</header> \ No newline at end of file
diff --git a/templates/repo/diff.tmpl b/templates/repo/diff.tmpl
index 3d4a8b1fa7..443e002d59 100644
--- a/templates/repo/diff.tmpl
+++ b/templates/repo/diff.tmpl
@@ -89,7 +89,11 @@
{{$.i18n.Tr "repo.diff.bin"}}
{{end}}
</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>
+ {{end}}
<span class="file">{{$file.Name}}</span>
</div>
{{$isImage := (call $.IsImageFile $file.Name)}}
diff --git a/templates/repo/header.tmpl b/templates/repo/header.tmpl
index 20e67db810..a0b927be60 100644
--- a/templates/repo/header.tmpl
+++ b/templates/repo/header.tmpl
@@ -18,9 +18,11 @@
</a>
<div id="repo-header-download-drop" class="drop-down">
<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>
- <button class="btn btn-gray left" id="repo-clone-https" data-link="{{$.CloneLink.HTTPS}}">HTTPS</button>
- <input id="repo-clone-url" class="ipt ipt-disabled left" value="{{$.CloneLink.SSH}}" readonly />
+ {{if not $.DisableSSH}}
+ <button class="btn btn-blue left btn-left-radius" id="repo-clone-ssh" data-link="{{$.CloneLink.SSH}}">SSH</button>
+ {{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>
<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/>
@@ -58,4 +60,4 @@
</ul>
</div>
</div>
-{{end}} \ No newline at end of file
+{{end}}
diff --git a/templates/user/dashboard/feeds.tmpl b/templates/user/dashboard/feeds.tmpl
index 834e5f0a56..8acf228963 100644
--- a/templates/user/dashboard/feeds.tmpl
+++ b/templates/user/dashboard/feeds.tmpl
@@ -12,14 +12,14 @@
{{$.i18n.Tr "action.commit_repo" AppSubUrl .GetRepoLink .GetBranch .GetBranch AppSubUrl .GetRepoLink .GetRepoLink | Str2html}}
{{else if eq .GetOpType 6}}
{{ $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}}
{{$.i18n.Tr "action.transfer_repo" .GetContent AppSubUrl .GetRepoLink .GetRepoLink | Str2html}}
{{else if eq .GetOpType 9}}
{{$.i18n.Tr "action.push_tag" AppSubUrl .GetRepoLink .GetBranch .GetBranch AppSubUrl .GetRepoLink .GetRepoLink | Str2html}}
{{else if eq .GetOpType 10}}
{{ $index := index .GetIssueInfos 0}}
- {{$.i18n.Tr "action.comment_issue" AppSubUrl .GetRepoLink $index .GetRepoLink $index | Str2html}}
+ {{$.i18n.Tr "action.comment_issue" .GetRepoLink $index | Str2html}}
{{end}}
</p>
{{if eq .GetOpType 5}}