Merge branch 'develop' of github.com:gogits/gogs into release/0.6.1

tokarchuk/v1.17
Unknwon 10 years ago
commit 62e436e6b7
  1. 1
      .bra.toml
  2. 12
      .editorconfig
  3. 22
      .gobuild.yml
  4. 38
      .gopmfile
  5. 17
      Dockerfile
  6. 12
      README.md
  7. 8
      README_ZH.md
  8. 2
      cmd/serve.go
  9. 20
      cmd/web.go
  10. 7
      conf/README
  11. 6
      conf/app.ini
  12. BIN
      conf/content/git-bare.zip
  13. 3
      conf/locale/TRANSLATORS
  14. 21
      conf/locale/locale_de-DE.ini
  15. 93
      conf/locale/locale_en-US.ini
  16. 21
      conf/locale/locale_es-ES.ini
  17. 21
      conf/locale/locale_fr-CA.ini
  18. 21
      conf/locale/locale_ja-JP.ini
  19. 21
      conf/locale/locale_lv-LV.ini
  20. 21
      conf/locale/locale_nl-NL.ini
  21. 727
      conf/locale/locale_pt-BR.ini
  22. 27
      conf/locale/locale_ru-RU.ini
  23. 21
      conf/locale/locale_zh-CN.ini
  24. 27
      conf/locale/locale_zh-HK.ini
  25. 12
      docker-compose.yml
  26. 2
      gogs.go
  27. 6
      models/access.go
  28. 86
      models/action.go
  29. 84
      models/error.go
  30. 6
      models/login.go
  31. 5
      models/migrations/migrations.go
  32. 9
      models/models.go
  33. 35
      models/org.go
  34. 9
      models/publickey.go
  35. 168
      models/repo.go
  36. 89
      models/user.go
  37. 2
      models/webhook.go
  38. 18
      modules/auth/admin.go
  39. 14
      modules/auth/repo_form.go
  40. 2
      modules/base/tool.go
  41. 1041
      modules/bindata/bindata.go
  42. 4
      modules/git/commit.go
  43. 4
      modules/git/submodule.go
  44. 2
      modules/mailer/mail.go
  45. 2
      modules/middleware/auth.go
  46. 4
      modules/middleware/repo.go
  47. 24
      modules/setting/setting.go
  48. 32
      public/ng/css/gogs.css
  49. 37
      public/ng/css/ui.css
  50. 3
      public/ng/less/gogs/dashboard.less
  51. 28
      public/ng/less/gogs/issue.less
  52. 31
      public/ng/less/ui/form.less
  53. 7
      public/ng/less/ui/menu.less
  54. 4
      public/ng/less/ui/reset.less
  55. 4
      public/ng/less/ui/var.less
  56. 13
      routers/admin/users.go
  57. 6
      routers/api/v1/repo.go
  58. 4
      routers/org/members.go
  59. 7
      routers/org/setting.go
  60. 4
      routers/org/teams.go
  61. 47
      routers/repo/http.go
  62. 8
      routers/repo/issue.go
  63. 12
      routers/repo/repo.go
  64. 3
      routers/repo/setting.go
  65. 6
      routers/repo/view.go
  66. 15
      routers/user/home.go
  67. 17
      routers/user/setting.go
  68. 12
      scripts/init/centos/gogs
  69. 2
      templates/.VERSION
  70. 2
      templates/admin/auth/edit.tmpl
  71. 2
      templates/admin/user/edit.tmpl
  72. 6
      templates/ng/base/alert.tmpl
  73. 2
      templates/repo/bare.tmpl
  74. 4
      templates/repo/migrate.tmpl
  75. 4
      templates/repo/view_list.tmpl
  76. 14
      templates/user/dashboard/feeds.tmpl
  77. 95
      templates/user/issues.tmpl
  78. 1
      wercker.yml

@ -14,6 +14,7 @@ watch_dirs = [
watch_exts = [".go", ".ini"]
build_delay = 1500
cmds = [
#["go-bindata", "-o=modules/bindata/bindata.go", "-ignore=\\.DS_Store|README", "-pkg=bindata", "conf/..."],
["go", "install", "-tags", "sqlite cert"],# redis memcache
["go", "build", "-tags", "sqlite cert"],
["./gogs", "web"]

@ -0,0 +1,12 @@
# http://editorconfig.org
root = true
[*]
charset = utf-8
end_of_line = lf
indent_style = tab
[*.yml]
indent_style = space
indent_size = 2

@ -1,22 +0,0 @@
filesets:
includes:
- conf
- etc
- public
- scripts
- templates
- LICENSE
- README.md
- README_ZH.md
excludes:
- \.git
depth: 5
settings:
build: |
if test "$GOOS" = "windows" -a "$GOARCH" = "386"
then
go install -v
else
go get -v -tags "sqlite redis memcache cert" github.com/gogits/gogs
go install -v -tags "sqlite redis memcache cert"
fi

@ -5,33 +5,33 @@ path = github.com/gogits/gogs
github.com/bradfitz/gomemcache = commit:72a68649ba
github.com/Unknwon/cae = commit:2e70a1351b
github.com/Unknwon/com = commit:188d690b1a
github.com/Unknwon/i18n = commit:1e88666229
github.com/Unknwon/macaron = commit:e089393c3f
github.com/codegangsta/cli = commit:6086d7927e
github.com/go-sql-driver/mysql = commit:27633f0519
github.com/go-xorm/core = commit:16cb27928f
github.com/go-xorm/xorm = commit:f2d3be988e
github.com/Unknwon/i18n = commit:7457d88830
github.com/Unknwon/macaron = commit:93de4f3fad
github.com/codegangsta/cli = commit:2bcd11f863
github.com/go-sql-driver/mysql = commit:a197e5d405
github.com/go-xorm/core = commit:be6e7ac47d
github.com/go-xorm/xorm = commit:1f0dd9bef2
github.com/gogits/chardet = commit:2404f77725
github.com/gogits/go-gogs-client = commit:92e76d616a
github.com/lib/pq = commit:835d5eb08d
github.com/macaron-contrib/binding = commit:dc739fabc3
github.com/macaron-contrib/cache = commit:b68f6b448f
github.com/macaron-contrib/captcha = commit:066c50c7eb
github.com/lib/pq = commit:30ed2200d7
github.com/macaron-contrib/binding = commit:548a793679
github.com/macaron-contrib/cache = commit:928d5c35cd
github.com/macaron-contrib/captcha = commit:fbb8b1ebb5
github.com/macaron-contrib/csrf = commit:98ddf5a710
github.com/macaron-contrib/i18n = commit:eeebd44f64
github.com/macaron-contrib/i18n = commit:627d60fe6f
github.com/macaron-contrib/oauth2 = commit:8f394c3629
github.com/macaron-contrib/session = commit:8e8d938b27
github.com/macaron-contrib/session = commit:31e841d95c
github.com/macaron-contrib/toolbox = commit:acbfe36e16
github.com/mattn/go-sqlite3 = commit:25d045f12a
github.com/mattn/go-sqlite3 = commit:5253daf856
github.com/microcosm-cc/bluemonday = commit:fcd0f5074e
github.com/nfnt/resize = commit:8f44931448
github.com/russross/blackfriday = commit:77efab57b2
github.com/shurcooL/go = commit:329f57438c
golang.org/x/net =
golang.org/x/text =
github.com/nfnt/resize = commit:53e9ca890b
github.com/russross/blackfriday = commit:6928e11ecd
github.com/shurcooL/go = commit:bc30a0bd33
golang.org/x/net = commit:0b492c5a96
golang.org/x/text = commit:c6bc7e82e2
gopkg.in/ini.v1 = commit:4febc4104c
gopkg.in/redis.v2 = commit:e617904962
[res]
include = conf|etc|public|scripts|templates
include = etc|public|scripts|templates

@ -0,0 +1,17 @@
FROM google/golang:latest
ENV TAGS="sqlite redis memcache cert" USER="git" HOME="/home/git"
COPY . /gopath/src/github.com/gogits/gogs/
WORKDIR /gopath/src/github.com/gogits/gogs/
RUN go get -v -tags="$TAGS" github.com/gogits/gogs \
&& go build -tags="$TAGS" \
&& useradd -d $HOME -m $USER \
&& chown -R $USER .
USER $USER
ENTRYPOINT [ "./gogs" ]
CMD [ "web" ]

@ -7,14 +7,14 @@ 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.16 Beta
##### Current version: 0.6.0 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.
- The 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 an issue or making a Pull Request.
- If you think there are vulnerabilities in the project, please talk privately to **u@gogs.io**. Thanks!
- The demo site [try.gogs.io](https://try.gogs.io) is running under `develop` branch.
- You **MUST** read [CONTRIBUTING.md](CONTRIBUTING.md) before you start filing an issue or making a Pull Request, and **MUST** discuss with us on [Gitter](https://gitter.im/gogits/gogs) for UI changes and feature Pull Reuqests, otherwise it's high possibilities that we are not going to merge it.
- If you think there are vulnerabilities in the project, please talk privately to **u@gogs.io**. Thanks!
#### Other language version
@ -30,7 +30,7 @@ The goal of this project is to make the easiest, fastest, and most painless way
- See the [Trello Board](https://trello.com/b/uxAoeLUl/gogs-go-git-service) to follow the develop team.
- Want to try it before doing anything else? Do it [online](https://try.gogs.io/unknwon/gogs) or go down to the **Installation -> Install from binary** section!
- Having trouble? Get help with [Troubleshooting](http://gogs.io/docs/intro/troubleshooting.md).
- Want to help with localization? Check out [Crowdin](https://crowdin.com/project/gogs)!
- Want to help with localization? Check out the [guide](http://gogs.io/docs/features/i18n.html)!
## Features
@ -52,7 +52,7 @@ The goal of this project is to make the easiest, fastest, and most painless way
- Drone CI integration
- Supports MySQL, PostgreSQL and SQLite3
- Social account login (GitHub, Google, QQ, Weibo)
- Multi-language support ([10 languages](https://crowdin.com/project/gogs))
- Multi-language support ([11 languages](https://crowdin.com/project/gogs))
## System Requirements

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

@ -128,7 +128,7 @@ func runServ(c *cli.Context) {
repo, err := models.GetRepositoryByName(repoUser.Id, repoName)
if err != nil {
if err == models.ErrRepoNotExist {
if models.IsErrRepoNotExist(err) {
if user.Id == repoUser.Id || repoUser.IsOwnedBy(user.Id) {
fail("Repository does not exist", "Repository does not exist: %s/%s", repoUser.Name, repoName)
} else {

@ -34,6 +34,7 @@ import (
"github.com/gogits/gogs/modules/auth/apiv1"
"github.com/gogits/gogs/modules/avatar"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/bindata"
"github.com/gogits/gogs/modules/git"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/middleware"
@ -78,11 +79,11 @@ func checkVersion() {
// Check dependency version.
checkers := []VerChecker{
{"github.com/Unknwon/macaron", macaron.Version, "0.5.1"},
{"github.com/macaron-contrib/binding", binding.Version, "0.0.5"},
{"github.com/Unknwon/macaron", macaron.Version, "0.5.4"},
{"github.com/macaron-contrib/binding", binding.Version, "0.0.6"},
{"github.com/macaron-contrib/cache", cache.Version, "0.0.7"},
{"github.com/macaron-contrib/csrf", csrf.Version, "0.0.3"},
{"github.com/macaron-contrib/i18n", i18n.Version, "0.0.5"},
{"github.com/macaron-contrib/i18n", i18n.Version, "0.0.7"},
{"github.com/macaron-contrib/session", session.Version, "0.1.6"},
{"gopkg.in/ini.v1", ini.Version, "1.2.0"},
}
@ -123,9 +124,18 @@ func newMacaron() *macaron.Macaron {
Funcs: []template.FuncMap{base.TemplateFuncs},
IndentJSON: macaron.Env != macaron.PROD,
}))
localeNames, err := bindata.AssetDir("conf/locale")
if err != nil {
log.Fatal(4, "Fail to list locale files: %v", err)
}
localFiles := make(map[string][]byte)
for _, name := range localeNames {
localFiles[name] = bindata.MustAsset("conf/locale/" + name)
}
m.Use(i18n.I18n(i18n.Options{
SubURL: setting.AppSubUrl,
Directory: path.Join(setting.ConfRootPath, "locale"),
Files: localFiles,
CustomDirectory: path.Join(setting.CustomPath, "conf/locale"),
Langs: setting.Langs,
Names: setting.Names,
@ -457,7 +467,7 @@ func runWeb(ctx *cli.Context) {
// robots.txt
m.Get("/robots.txt", func(ctx *middleware.Context) {
if setting.HasRobotsTxt {
ctx.ServeFile(path.Join(setting.CustomPath, "robots.txt"))
ctx.ServeFileContent(path.Join(setting.CustomPath, "robots.txt"))
} else {
ctx.Error(404)
}

@ -0,0 +1,7 @@
Execute following command in ROOT directory when anything is changed:
$ go-bindata -o=modules/bindata/bindata.go -ignore="\\.DS_Store|README" -pkg=bindata conf/...
Add -debug flag to make life easier in development(somehow isn't working):
$ go-bindata -debug -o=modules/bindata/bindata.go -ignore="\\.DS_Store|README" -pkg=bindata conf/...

@ -82,7 +82,7 @@ ENABLE_CACHE_AVATAR = false
ENABLE_NOTIFY_MAIL = false
; More detail: https://github.com/gogits/gogs/issues/165
ENABLE_REVERSE_PROXY_AUTHENTICATION = false
ENABLE_REVERSE_PROXY_AUTO_REGISTERATION = false
ENABLE_REVERSE_PROXY_AUTO_REGISTRATION = false
[webhook]
; Cron task interval in minutes
@ -286,5 +286,5 @@ INTERVAL = 24
ARGS =
[i18n]
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
LANGS = en-US,zh-CN,zh-HK,de-DE,fr-CA,nl-NL,lv-LV,ru-RU,ja-JP,es-ES,pt-BR
NAMES = English,简体中文,繁體中文,Deutsch,Français,Nederlands,Latviešu,Русский,日本语,Español,Português

Binary file not shown.

@ -7,4 +7,5 @@ Huimin Wang <wanghm2009@hotmail.co.jp>
Thomas Fanninger <gogs.thomas@fanninger.at>
Łukasz Jan Niemier <lukasz@niemier.pl>
Lafriks <lafriks@gmail.com>
Miguel de la Cruz <miguel@mcrx.me>
Miguel de la Cruz <miguel@mcrx.me>
Natan Albuquerque <natanalbuquerque5@gmail.com>

@ -281,13 +281,13 @@ init_readme=Repository mit README.md initialisieren
create_repo=Repository erstellen
default_branch=Standard-Branch
mirror_interval=Spiegel-Intervall (in Stunden)
goget_meta=Go-Get Meta
goget_meta_helper=Dieses Repository wird man mit <span class="label label-blue label-radius">go get</span> klonen können.
need_auth=Authorisierung benötigt
migrate_type=Migrationstyp
migrate_type_helper=Dieses Repository wird ein <span class="label label-blue label-radius">Spiegel</span>
migrate_repo=Repository migrieren
migrate.clone_address=Adresse kopieren
migrate.invalid_local_path=Lokaler Pfad ist ungültig, er existiert nicht oder ist kein Ordner.
copy_link=Kopieren
click_to_copy=In Zwischenablage kopieren
@ -595,7 +595,10 @@ auths.domain=Domain
auths.host=Host
auths.port=Port
auths.base_dn=Base DN
auths.attributes=Suchattribute
auths.attribute_username=Benutzername Attribut
auths.attribute_name=Vorname Attribut
auths.attribute_surname=Nachname Attribut
auths.attribute_mail=E-Mail Attribut
auths.filter=Suchfilter
auths.ms_ad_sa=Ms Ad SA
auths.smtp_auth=SMTP-Authentifizierungstyp
@ -693,12 +696,12 @@ notices.op=Op.
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/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
create_repo=hat Repository <a href="%s">%s</a> erstellt
commit_repo=hat nach <a href="%s/src/%s">%[2]s</a> in <a href="%[1]s">%[3]s</a> gepusht
create_issue=`hat Issue <a href="%s/issues/%s">%s#%[2]s</a> eröffnet`
comment_issue=`hat Issue <a href="%s/issues/%s">%s#%[2]s</a> kommentiert`
transfer_repo=hat Repository <code>%s</code> transferiert an <a href="%s">%s</a>
push_tag=hat nach <a href="%s/src/%s">%[2]s</a> in <a href="%[1]s">%[3]s</a> gepusht
compare_2_commits=Zeige Vergleich dieser 2 Commits
[tool]

@ -114,13 +114,13 @@ remember_me = Remember Me
forgot_password= Forgot Password
forget_password = Forgot password?
sign_up_now = Need an account? Sign up now.
confirmation_mail_sent_prompt = A new confirmation e-mail has been sent to <b>%s</b>, please check your inbox within the next %d hours to complete your registration.
confirmation_mail_sent_prompt = A new confirmation e-mail has been sent to <b>%s</b>, please check your inbox within the next %d hours to complete the registration process.
sign_in_email = Sign in to your e-mail
active_your_account = Activate Your Account
resent_limit_prompt = Sorry, you are sending an activation e-mail too frequently. Please wait 3 minutes.
resent_limit_prompt = Sorry, you already requested an activation email recently. Please wait 3 minutes then try again.
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.
resend_mail = Click here to resend your activation e-mail
email_not_associate = This e-mail address does not associate to any account.
email_not_associate = This e-mail address is not associated with any account.
send_reset_mail = Click here to (re)send your password reset e-mail
reset_password = Reset Your Password
invalid_code = Sorry, your confirmation code has expired or not valid.
@ -162,23 +162,23 @@ illegal_repo_name = Repository name contains illegal characters.
illegal_org_name = Organization name contains illegal characters.
illegal_team_name = Team name contains illegal characters.
username_password_incorrect = Username or password is not correct.
enterred_invalid_repo_name = Please make sure you entered repository name is correct.
enterred_invalid_owner_name = Please make sure you entered owner name is correct.
enterred_invalid_password = Please make sure you entered password is correct.
enterred_invalid_repo_name = Please make sure that the repository name you entered is correct.
enterred_invalid_owner_name = Please make sure that the owner name you entered is correct.
enterred_invalid_password = Please make sure the that password you entered is correct.
user_not_exist = Given user does not exist.
last_org_owner = The user to remove is the last member in owner team. There must be another owner.
last_org_owner = Removing the last user from a owner team isn't allowed, as there must always be at least one owner in any given organization.
invalid_ssh_key = Sorry, we're not able to verify your SSH key: %s
unable_verify_ssh_key = Gogs cannot verify your SSH key, but we assume that is valid, please make sure yourself.
unable_verify_ssh_key = Gogs cannot verify your SSH key, but we assume that it is valid, please double-check it.
auth_failed = Authentication failed: %v
still_own_repo = Your account still have ownership of repository, you have to delete or transfer them first.
still_has_org = Your account still have membership of organization, you have to left or delete them first.
still_own_repo = Your account still has ownership over at least one repository, you have to delete or transfer them first.
still_has_org = Your account still has membership in at least one organization, you have to leave or delete your memberships first.
org_still_own_repo = This organization still have ownership of repository, you have to delete or transfer them first.
still_own_user = This authentication still has used by some users, you should move them and then delete again.
still_own_user = This authentication still is in use by at least one user, please remove them from the authentication and try again.
target_branch_not_exist = Target branch does not exist
target_branch_not_exist = Target branch does not exist.
[user]
change_avatar = Change your avatar at gravatar.com
@ -208,7 +208,7 @@ location = Location
update_profile = Update Profile
update_profile_success = Your profile has been updated successfully.
change_username = Username Changed
change_username_desc = Username has been changed, do you want to continue? This will affect all links relate to your account.
change_username_desc = You changed your username. This will affect the way how links relate to your account. Do you want to continue?
continue = Continue
cancel = Cancel
@ -224,7 +224,7 @@ change_password = Change Password
old_password = Current Password
new_password = New Password
password_incorrect = Current password is not correct.
change_password_success = Password is changed successfully. You can now sign in via new password.
change_password_success = Your password was successfully changed. You can now sign using this new password.
emails = E-mail Addresses
manage_emails = Manage e-mail addresses
@ -234,12 +234,13 @@ primary_email = Set as primary
delete_email = Delete
add_new_email = Add new e-mail address
add_email = Add e-mail
add_email_confirmation_sent = A new confirmation e-mail has been sent to <b>%s</b>, please check your inbox within the next %d hours to complete the confirmation process.
add_email_success = Your new E-mail address was successfully added.
manage_ssh_keys = Manage SSH Keys
add_key = Add Key
ssh_desc = This is a list of SSH keys associated with your account. Remove any keys that you do not recognize.
ssh_helper = <strong>Need help?</strong> Check out our guide to <a href="%s">generating SSH keys</a> or troubleshoot <a href="%s">common SSH Problems</a>.
ssh_desc = This is a list of SSH keys associated with your account. As these keys allow anyone using them to gain access to your repositories, it is highly important that you make sure you recognize them.
ssh_helper = <strong>Don't know how?</strong> Check out GitHub's guide to <a href="%s">create your own SSH keys</a> or solve <a href="%s">common problems</a> you might encounter using SSH.
add_new_key = Add SSH Key
key_name = Key Name
key_content = Content
@ -257,12 +258,12 @@ unbind_success = Social account has been unbound.
manage_access_token = Manage Personal Access Tokens
generate_new_token = Generate New Token
tokens_desc = Tokens you have generated that can be used to access the Gogs API.
new_token_desc = As for now, every token will have full access to your account.
new_token_desc = Each token will have full access to your account.
token_name = Token Name
generate_token = Generate Token
generate_token_succees = New access token has been generated successfully! Make sure to copy your new personal access token now. You won't be able to see it again!
generate_token_succees = Your access token was successfully generated! Make sure to copy it right now, as you won't be able to see it again later!
delete_token = Delete
delete_token_success = Personal access token has been deleted successfully! Don't forget to update your applications as well.
delete_token_success = This personal access token has been successfully removed successfully! Don't forget to update your applications as well.
delete_account = Delete Your Account
delete_prompt = The operation will delete your account permanently, and <strong>CANNOT</strong> be undone!
@ -273,12 +274,12 @@ delete_account_desc = This account is going to be deleted permanently, do you wa
[repo]
owner = Owner
repo_name = Repository Name
repo_name_helper = Great repository names are short, memorable and <strong>unique</strong>.
repo_name_helper = A good repository name is usually composed of short, memorable and unique keywords.
visibility = Visibility
visiblity_helper = This repository is <span class="label label-red label-radius">Private</span>
fork_repo = Fork Repository
fork_from = Fork From
fork_visiblity_helper = Forked repository cannot change its visiblity
fork_visiblity_helper = You cannot alter the visibility of a forked repository.
repo_desc = Description
repo_lang = Language
repo_lang_helper = Select a .gitignore file
@ -291,7 +292,7 @@ mirror_interval = Mirror Interval (hour)
need_auth = Need Authorization
migrate_type = Migration Type
migrate_type_helper = This repository will be a <span class="label label-blue label-radius">Mirror</span>
migrate_type_helper = This repository will be a <span class="label label-blue label-radius">mirror</span>
migrate_repo = Migrate Repository
migrate.clone_address = Clone Address
migrate.invalid_local_path = Invalid local path, it does not exist or not a directory.
@ -344,13 +345,13 @@ settings.danger_zone = Danger Zone
settings.site = Official Site
settings.update_settings = Update Settings
settings.change_reponame = Repository Name Changed
settings.change_reponame_desc = Repository name has been changed, do you want to continue? This will affect all links relate to this repository.
settings.change_reponame_desc = Repository name was changed. This will affect how links relate to the repository. Do you want to continue?
settings.transfer = Transfer Ownership
settings.transfer_desc = Transfer this repo to another user or to an organization where you have admin rights.
settings.new_owner_has_same_repo = New owner already has a repository with same name.
settings.transfer_desc = Transfer this repository to another user or to an organization in which you have admin rights.
settings.new_owner_has_same_repo = The new owner already has a repository with same name. Please choose another name.
settings.delete = Delete This Repository
settings.delete_desc = Once you delete a repository, there is no going back. Please be certain.
settings.transfer_notices = <p>- You will lose access if new owner is a individual user.</p><p>- You will remain access if new owner is an organization and you're one of the owners.</p>
settings.transfer_notices = <p>- You will lose access if new owner is a individual user.</p><p>- You will conserve access if new owner is an organization and if you're one of the owners.</p>
settings.update_settings_success = Repository options has been updated successfully.
settings.transfer_owner = New Owner
settings.make_transfer = Make Transfer
@ -361,21 +362,21 @@ settings.add_collaborator_success = New collaborator has been added.
settings.remove_collaborator_success = Collaborator has been removed.
settings.user_is_org_member = User is organization member who cannot be added as a collaborator.
settings.add_webhook = Add Webhook
settings.hooks_desc = Webhooks allow external services to be notified when certain events happen on Gogs. When the specified events happen, we'll send a POST request to each of the URLs you provide. Learn more in our <a target="_blank" href="%s">Webhooks Guide</a>.
settings.githooks_desc = Git Hooks are powered by Git itself, you can edit files of supported hooks in the list below to apply custom operations.
settings.githook_edit_desc = If hook is not active, sample content will be presented. Leave content to be blank will disable this hook.
settings.hooks_desc = Webhooks are much like basic HTTP POST event triggers. Whenever something occurs in Gogs, we will handle the notification to the target host you specify. Learn more in this <a target="_blank" href="%s">Webhooks Guide</a>.
settings.githooks_desc = Git Hooks are powered by Git itself, you can edit files of supported hooks in the list below to perform custom operations.
settings.githook_edit_desc = If the hook is inactive, sample content will be presented. Leaving content to an empty value will disable this hook.
settings.githook_name = Hook Name
settings.githook_content = Hook Content
settings.update_githook = Update Hook
settings.remove_hook_success = Webhook has been removed.
settings.add_webhook_desc = We’ll send a <code>POST</code> request to the URL below with details of any subscribed events. You can also specify which data format you'd like to receive (JSON, <code>x-www-form-urlencoded</code>, <em>etc</em>). More information can be found in <a target="_blank" href="%s">Webhooks Guide</a>.
settings.add_webhook_desc = Gogs will send a <code>POST</code> request to the URL you specify, along with regarding the event that occured. You can also specify what kind of data format you'd like to get upon triggering the hook (JSON, x-www-form-urlencoded, XML, etc). More information can be found in our <a target="_blank" href="%s">Webhooks Guide</a>.
settings.payload_url = Payload URL
settings.content_type = Content Type
settings.secret = Secret
settings.event_desc = Which events would you like to trigger this webhook?
settings.event_desc = Upon which events should this webhook be triggered?
settings.event_push_only = Just the <code>push</code> event.
settings.active = Active
settings.active_helper = We will deliver event details when this hook is triggered.
settings.active_helper = Details regarding the event which triggered the hook will be delivered as well.
settings.add_hook_success = New webhook has been added.
settings.update_webhook = Update Webhook
settings.update_hook_success = Webhook has been updated.
@ -414,7 +415,7 @@ release.preview = Preview
release.content_placeholder = Write some content
release.loading = Loading...
release.prerelease_desc = This is a pre-release
release.prerelease_helper = We’ll point out that this release is identified as non-production ready.
release.prerelease_helper = We’ll point out that this release is not production-ready.
release.publish = Publish Release
release.save_draft = Save Draft
release.edit_release = Edit Release
@ -446,11 +447,11 @@ settings.website = Website
settings.location = Location
settings.update_settings = Update Settings
settings.change_orgname = Organization Name Changed
settings.change_orgname_desc = Organization name has been changed, do you want to continue? This will affect all links relate to this organization.
settings.update_setting_success = Organization setting has been updated successfully.
settings.delete = Delete Organization
settings.change_orgname_desc = Organization name has been changed. This will affect how links relate to the organization. Do you want to continue?
settings.update_setting_success = Organization settings were successfully updated.
settings.delete = Delete Organization
settings.delete_account = Delete This Organization
settings.delete_prompt = The operation will delete this organization permanently, and <strong>CANNOT</strong> be undone!
settings.delete_prompt = The organization will be permanently removed, and this <strong>CANNOT</strong> be undone!
settings.confirm_delete_account = Confirm Deletion
settings.delete_org_title = Organization Deletion
settings.delete_org_desc = This organization is going to be deleted permanently, do you want to continue?
@ -484,7 +485,7 @@ teams.update_settings = Update Settings
teams.delete_team = Delete This Team
teams.add_team_member = Add Team Member
teams.delete_team_title = Team Deletion
teams.delete_team_desc = This team is going to be deleted, do you want to continue? Members of this team may lose access to some repositories.
teams.delete_team_desc = As this team will be deleted, members of this team may lose access to some repositories. Do you want to continue?
teams.delete_team_success = Given team has been deleted successfully.
teams.read_permission_desc = This team grants <strong>Read</strong> access: members can view and clone the team's repositories.
teams.write_permission_desc = This team grants <strong>Write</strong> access: members can read from and push to the team's repositories.
@ -574,8 +575,8 @@ 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.
users.still_own_repo = This account still has ownership over at least one repository, you have to delete or transfer them first.
users.still_has_org = This account still has membership in at least one organization, you have to leave or delete the organizations first.
orgs.org_manage_panel = Organization Manage Panel
orgs.name = Name
@ -703,12 +704,12 @@ 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>
create_repo = created repository <a href="%s">%s</a>
commit_repo = pushed to <a href="%s/src/%s">%[2]s</a> at <a href="%[1]s">%[3]s</a>
create_issue = `opened issue <a href="%s/issues/%s">%s#%[2]s</a>`
comment_issue = `commented on issue <a href="%s/issues/%s">%s#%[2]s</a>`
transfer_repo = transfered repository <code>%s</code> to <a href="%s">%s</a>
push_tag = pushed tag <a href="%s/src/%s">%[2]s</a> to <a href="%[1]s">%[3]s</a>
compare_2_commits = View comparison for these 2 commits
[tool]

@ -281,13 +281,13 @@ 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
migrate.clone_address=Clonar Dirección
migrate.invalid_local_path=Rutal local inválida, no existe o no es un directorio.
copy_link=Copiar
click_to_copy=Copiar al portapapeles
@ -595,7 +595,10 @@ auths.domain=Dominio
auths.host=Host
auths.port=Puerto
auths.base_dn=Base DN
auths.attributes=Atributos de búsqueda
auths.attribute_username=Atributo username
auths.attribute_name=Atributo nombre
auths.attribute_surname=Atributo apellido
auths.attribute_mail=Atributo correo electrónico
auths.filter=Filtro de Búsqueda
auths.ms_ad_sa=Ms Ad SA
auths.smtp_auth=Tipo de Autorización SMTP
@ -693,12 +696,12 @@ notices.op=Op.
notices.delete_success=La notificación del sistema se ha eliminado correctamente.
[action]
create_repo=Repositorio creado <a href="%s/%s">%s</a>
commit_repo=hizo push a <a href="%s/%s/src/%s">%s</a> en <a href="%s/%s">%s</a>
create_issue=`incidencia abierta <a href="%s/issues/%s">%[1]s#%[2]s</a>`
comment_issue=`comentó en la incidencia <a href="%s/issues/%s">%[1]s#%[2]s</a>`
transfer_repo=transfirió el repositorio <code>%s</code> a <a href="/%s%s">%s</a>
push_tag=hizo push del tag <a href="%s/%s/src/%s">%s</a> a <a href="%s/%s">%s</a>
create_repo=Repositorio creado <a href="%s">%s</a>
commit_repo=hizo push a <a href="%s/src/%s">%[2]s</a> en <a href="%[1]s">%[3]s</a>
create_issue=`incidencia abierta <a href="%s/issues/%s">%s#%[2]s</a>`
comment_issue=`comentó en la incidencia <a href="%s/issues/%s">%s#%[2]s</a>`
transfer_repo=transfirió el repositorio <code>%s</code> a <a href="%s">%s</a>
push_tag=hizo push del tag <a href="%s/src/%s">%[2]s</a> a <a href="%[1]s">%[3]s</a>
compare_2_commits=Ver la comparación de estos 2 commits
[tool]

@ -281,13 +281,13 @@ init_readme=Initialiser ce Référentiel avec un README.md
create_repo=Créer un Référentiel
default_branch=Branche par défaut
mirror_interval=Intervalle du miroir (heure)
goget_meta=Méta Go-Get
goget_meta_helper=Ce Référentiel sera <span class="label label-blue label-radius">Go-Getable</span>
need_auth=Nécessite une Autorisation
migrate_type=Type de Migration
migrate_type_helper=Ce Référentiel sera un <span class="label label-blue label-radius">Miroir</span>
migrate_repo=Migrer le Référentiel
migrate.clone_address=Adresse du clone
migrate.invalid_local_path=Chemin local non valide, non existant ou n'étant pas un dossier.
copy_link=Copier
click_to_copy=Copier dans le presse-papier
@ -595,7 +595,10 @@ auths.domain=Domaine
auths.host=Hôte
auths.port=Port
auths.base_dn=Base DN (Nom Distingué)
auths.attributes=Rechercher les Attributs
auths.attribute_username=Attribut du nom d'utilisateur
auths.attribute_name=Attribut du prénom
auths.attribute_surname=Attribut du nom de famille
auths.attribute_mail=Attribut de l'e-mail
auths.filter=Filtre de recherche
auths.ms_ad_sa=Ms Ad SA
auths.smtp_auth=Type d'Autorisation SMTP
@ -693,12 +696,12 @@ notices.op=Auteur
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/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>
create_repo=a crée le Référentiel <a href="%s">%s</a>
commit_repo=a soumis à <a href="%s/src/%s">%[2]s</a> chez <a href="%[1]s">%[3]s</a>
create_issue=`a ouvert un problème <a href="%s/issues/%s">%s#%[2]s</a>`
comment_issue=`a commenté le problème <a href="%s/issues/%s">%s#%[2]s</a>`
transfer_repo=a transféré le Référentiel <code>%s</code> à <a href="%s">%s</a>
push_tag=a tagé <a href="%s/src/%s">%[2]s</a> à <a href="%[1]s">%[3]s</a>
compare_2_commits=Comparer ces 2 commissions
[tool]

@ -281,13 +281,13 @@ init_readme=README.md 付きでリポジトリを初期化
create_repo=リポジトリを作成
default_branch=デフォルトのブランチ
mirror_interval=ミラー 間隔(時)
goget_meta=Go-Get メタ
goget_meta_helper=このリポジトリは <span class="label label-blue label-radius"> Go-Getable </span> になります
need_auth=認証が必要
migrate_type=マイグレーションの種類
migrate_type_helper=このリポジトリは <span class="label label-blue label-radius"> ミラー</span> になります
migrate_repo=リポジトリを移行
migrate.clone_address=クローンアドレス
migrate.invalid_local_path=ローカルパスが無効です。存在しないかディレクトリではありません。
copy_link=コピー
click_to_copy=クリップボードにコピー
@ -595,7 +595,10 @@ auths.domain=ドメイン
auths.host=ホスト
auths.port=ポート
auths.base_dn=ベースのドメイン名
auths.attributes=属性検索
auths.attribute_username=ユーザー名属性
auths.attribute_name=名前属性
auths.attribute_surname=名字属性
auths.attribute_mail=Eメール属性
auths.filter=検索フィルター
auths.ms_ad_sa=Ms Ad SA
auths.smtp_auth=SMTP 認証の種類
@ -693,12 +696,12 @@ notices.op=Op。
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/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> をプッシュしました
create_repo=リポジトリ <a href="%s"> %s</a>を作成しました
commit_repo=<a href="%[1]s">%[3]s</a>を<a href="%[1]s/src/%[2]s">%[2]s</a>にプッシュしました
create_issue=`問題 <a href="%s/issues/%s">%s#%[2]s</a> を開きました`
comment_issue=`問題 <a href="%s/issues/%s">%s#%[2]s</a> のコメント`
transfer_repo=リポジトリ <code>%s</code> を <a href="%s">%s</a> へ転送しました
push_tag=<a href="%[1]s">%[3]s</a> に タグ <a href="%[1]s/src/%[2]s">%[2]s</a> をプッシュしました
compare_2_commits=これら 2 のコミットの比較を閲覧する
[tool]

@ -281,13 +281,13 @@ init_readme=Inicializēt šo repozitoriju ar README.md failu
create_repo=Izveidot repozitoriju
default_branch=Noklusējuma atzars
mirror_interval=Spoguļošanas intervāls (stundās)
goget_meta=Go-Get metadati
goget_meta_helper=Šis repozitorijs saturēs <span class="label label-blue label-radius">Go-Get</span> metadatus
need_auth=Nepieciešama autorizācija
migrate_type=Migrācijas veids
migrate_type_helper=Šis repozitorijs būs <span class="label label-blue label-radius">Spoguļots</span>
migrate_repo=Migrēt repozitoriju
migrate.clone_address=Clone Address
migrate.invalid_local_path=Invalid local path, it does not exist or not a directory.
copy_link=Kopēt
click_to_copy=Kopēt uz starpliktuvi
@ -595,7 +595,10 @@ auths.domain=Domēns
auths.host=Resursdators
auths.port=Ports
auths.base_dn=Pamata DN
auths.attributes=Meklēšanas atribūti
auths.attribute_username=Username attribute
auths.attribute_name=First name attribute
auths.attribute_surname=Surname attribute
auths.attribute_mail=E-mail attribute
auths.filter=Meklēšanas filtrs
auths.ms_ad_sa=MS Ad SA
auths.smtp_auth=SMTP autorizācijas veids
@ -693,12 +696,12 @@ notices.op=Op.
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/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>
create_repo=izveidoja repozitoriju <a href="%s">%s</a>
commit_repo=veica izmaiņu nosūtīšanu atzaram <a href="%s/src/%s">%[2]s</a> repozitorijā <a href="%[1]s">%[3]s</a>
create_issue=`reģistrēja problēmu <a href="%s/issues/%s">%s#%[2]s</a>`
comment_issue=`pievienoja komentāru problēmai <a href="%s/issues/%s">%s#%[2]s</a>`
transfer_repo=mainīja repozitorija <code>%s</code> īpašnieku uz <a href="%s">%s</a>
push_tag=pievienoja tagu <a href="%s/src/%s">%[2]s</a> repozitorijam <a href="%[1]s">%[3]s</a>
compare_2_commits=Veikt salīdzināšanu starp šīm 2 revīzijām
[tool]

@ -281,13 +281,13 @@ init_readme=Initialiseer deze repositorie met een README.md
create_repo=Nieuwe Repositorie
default_branch=Standaard branch
mirror_interval=Mirror interval(uur)
goget_meta=Go-Get Meta
goget_meta_helper=Deze repositorie is nu beschikbaar voor <span class="label label-blue label-radius">Go-Get</span>
need_auth=Autorisatie vereist
migrate_type=Migratie type
migrate_type_helper=Deze repositorie zal een <span class="label label-blue label-radius">mirror</span> worden
migrate_repo=Migreer repositorie
migrate.clone_address=Clone Address
migrate.invalid_local_path=Invalid local path, it does not exist or not a directory.
copy_link=Kopieer
click_to_copy=Kopieer link naar plakbord
@ -595,7 +595,10 @@ auths.domain=Domein
auths.host=Host
auths.port=Poort
auths.base_dn=Base DN
auths.attributes=Zoek attributen
auths.attribute_username=Username attribute
auths.attribute_name=First name attribute
auths.attribute_surname=Surname attribute
auths.attribute_mail=E-mail attribute
auths.filter=Zoek filter
auths.ms_ad_sa=MS Ad SA
auths.smtp_auth=SMTP authenticatietype
@ -693,12 +696,12 @@ notices.op=Op.
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/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>
create_repo=repositorie aangemaakt in <a href="%s">%s</a>
commit_repo=push update naar <a href="%s/src/%s">%[2]s</a> in <a href="%[1]s">%[3]s</a>
create_issue=`opende issue in <a href="%s/issues/%s">%s#%[2]s</a>`
comment_issue=`reactie op issue <a href="%s/issues/%s">%s#%[2]s</a>`
transfer_repo=repositorie verplaatst naar <code>%s</code> naar <a href="%s">%s</a>
push_tag=geduwd label <a href="%s/src/%s"> %[2]s</a> naar <a href="%[1]s"> %[3]s</a>
compare_2_commits=Weergave vergelijking voor deze 2 commits
[tool]

@ -0,0 +1,727 @@
app_desc=Um serviço de Git auto-hospedado e amigável escrito em Go
home=Página Inicial
dashboard=Painel de controle
explore=Explorar
help=Ajuda
sign_in=Entrar
social_sign_in=Entrada Social: 2ª etapa <small>associar uma conta</small>
sign_out=Sair
sign_up=Cadastrar
register=Registrar
website=Site
version=Versão
page=Página
template=Modelo
language=Idioma
username=Usuário
email=E-mail
password=Senha
re_type=Redigite
captcha=Captcha
repository=Repositório
organization=Organização
mirror=Espelho
new_repo=Novo Repositório
new_migrate=Nova Migração
new_fork=Novo Fork de Repositório
new_org=Nova Organização
manage_org=Gerenciar Organizações
admin_panel=Painel do Administrador
account_settings=Configurações da Conta
settings=Configurações
news_feed=Feed de Notícias
pull_requests=Solicitações de Pull
issues=Problemas
cancel=Cancelar
[install]
install=Instalação
title=Etapas de instalação para Primeira Execução
requite_db_desc=Gogs requer MySQL, PostgreSQL ou SQLite3.
db_type=Tipo do Banco de Dados
host=Host
user=Usuário
password=Senha
db_name=Nome do Banco de Dados
db_helper=Por favor, use o mecanismo INNODB com o conjunto de caracteres utf8_general_ci para MySQL.
ssl_mode=Modo SSL
path=Caminho
sqlite_helper=O caminho do arquivo do banco de dados do SQLite3.
general_title=Configurações Gerais do Gogs
repo_path=Caminho da Raiz do Repositório
repo_path_helper=Todos os repositórios remotos do Git serão salvos neste diretório.
run_user=Executar Usuário
run_user_helper=O usuário deve ter acesso ao caminho raiz do repositório e executar o Gogs
domain=Domínio
domain_helper=Isto afeta URLs para clonagem via SSH.
http_port=Porta HTTP
http_port_helper=Número da porta em que a aplicação irá executar.
app_url=URL do Aplicativo
app_url_helper=Isto afeta a URL de clonagem via HTTP/HTTPs e também o email.
email_title=Configurações do Serviço de E-mail(Opcionais)
smtp_host=Host SMTP
mailer_user=E-mail do Remetente
mailer_password=Senha do Remetente
notify_title=Configurações de Notificação (Opcional)
register_confirm=Habilitar Confirmação de Registro
mail_notify=Habilitar Notificação de Correio
admin_title=Configurações da Conta de Administrador
admin_name=Nome de Usuário
admin_password=Senha
confirm_password=Confirmar Senha
admin_email=E-mail
install_gogs=Instalar Gogs
test_git_failed=Falha ao testar o comando 'git': %v
sqlite3_not_available=Sua versão não suporta SQLite3, por favor faça o download da versão binária oficial em %s, NÃO da versão gobuild.
invalid_db_setting=Configuração do banco de dados não está correta: %v
invalid_repo_path=A raiz do repositório é inválida: %v
run_user_not_match=O usuário da execução não é o usuário atual: %s -> %s
save_config_failed=Falha ao salvar a configuração: %v
invalid_admin_setting=Configuração da conta de administrador está inválida: %v
install_success=Bem-vindo! Estamos contentes que você escolheu o Gogs, divirta-se e tenha cuidado.
[home]
uname_holder=Nome de Usuário ou E-mail
password_holder=Senha
switch_dashboard_context=Trocar Contexto do Painel de Controle
my_repos=Meus Repositórios
collaborative_repos=Repositórios Colaborativos
my_orgs=Minhas Organizações
my_mirrors=Meus Espelhos
[explore]
repos=Repositórios
[auth]
create_new_account=Criar Nova Conta
register_hepler_msg=Já tem uma conta? Entre agora!
social_register_hepler_msg=Já tem uma conta? Junte-se agora!
disable_register_prompt=Desculpe, novos registros estão desabilitados. Por favor entre em contato com o administrador do site.
disable_register_mail=Desculpe, a confirmação de registro por email foi desabilitada.
remember_me=Lembrar de Mim
forgot_password=Esqueci a Senha
forget_password=Esqueceu a senha?
sign_up_now=Precisa de uma conta? Cadastre-se agora.
confirmation_mail_sent_prompt=Um novo e-mail de confirmação foi enviado para <b>%s</b>, por favor, verifique sua caixa de entrada nas próximas %d horas para completar seu registro.
sign_in_email=Entre com seu e-mail
active_your_account=Ativar Sua Conta
resent_limit_prompt=Desculpe, você está enviando um e-mail de ativação com muita frequência. Por favor, aguarde 3 minutos.
has_unconfirmed_mail=Oi %s, você possui um endereço de e-mail não confirmado (<b>%s</b>). Se você não recebeu um e-mail de confirmação ou precisa reenviar um novo, clique no botão abaixo.
resend_mail=Clique aqui para reenviar seu e-mail de ativação
email_not_associate=Este endereço de e-mail não é associado à nenhuma conta.
send_reset_mail=Clique aqui para (re)enviar seu e-mail de redefinição da senha
reset_password=Redefinir Sua Senha
invalid_code=Desculpe, seu código de confirmação expirou ou não é válido.
reset_password_helper=Clique aqui para redefinir sua senha
password_too_short=O comprimento da senha não pode ser menor que 6.
[form]
UserName=Nome de usuário
RepoName=Nome do repositório
Email=Endereço de e-mail
Password=Senha
Retype=Redigite a senha
SSHTitle=Nome da chave SSH
HttpsUrl=URL HTTPS
PayloadUrl=URL de carga
TeamName=Nome da equipe
AuthName=Nome de autorização
AdminEmail=E-mail do Administrador
require_error=` não pode estar vazio.`
alpha_dash_error=` devem ser caracteres alfanuméricos ou hífen (-) ou sublinhado (_).`
alpha_dash_dot_error=` devem ser caracteres alfanuméricos ou hífen (-) ou sublinhado (_).`
min_size_error=` deve conter pelo menos %s caracteres.`
max_size_error=` deve conter no máximo %s caracteres.`
email_error=` não é um endereço de e-mail válido.`
url_error=`não é uma URL válida.`
unknown_error=Erro desconhecido:
captcha_incorrect=O captcha não correspondeu.
password_not_match=Senha e confirmar senha não são as mesmas.
username_been_taken=Nome de usuário já foi tomado.
repo_name_been_taken=Nome do repositório já foi tomado.
org_name_been_taken=Nome da organização já foi tomado.
team_name_been_taken=Nome da equipe já foi tomado.
email_been_used=Endereço de e-mail já foi usado.
ssh_key_been_used=Nome da chave pública foi usado.
illegal_username=Seu nome de usuário contém caracteres ilegais.
illegal_repo_name=Nome do repositório contém caracteres ilegais.
illegal_org_name=Nome da organização contém caracteres ilegais.
illegal_team_name=O nome da equipe contém caracteres ilegais.
username_password_incorrect=Usuário ou senha incorretos.
enterred_invalid_repo_name=Por favor certifique-se que informou o nome do repositório corretamente.
enterred_invalid_owner_name=Por favor, verifique se o nome do proprietário está correto.
enterred_invalid_password=Por favor, verifique se a senha que você digitou está correta.
user_not_exist=O usuário dado não existe.
last_org_owner=O usuário a ser removido é o último membro na equipe de proprietários. Deve haver um outro proprietário.
invalid_ssh_key=Desculpe, não conseguimos verificar a sua chave SSH: %s
unable_verify_ssh_key=Gogs não pode verificar sua chave SSH, mas assumimos que é válida, por favor, verifique a chave pessoalmente.
auth_failed=A autenticação falhou: %v
still_own_repo=Sua conta ainda tem propriedade do repositório, você tem que excluir ou transferí-la primeiro.
still_has_org=Sua conta ainda faz parte da organização, você deve sair ou excluí-la primeiro.
org_still_own_repo=Esta organização ainda tem a propriedade do repositório, você deve excluir ou transferí-la primeiro.
still_own_user=Esta autenticação ainda é usada por alguns usuários, você deve movê-los e depois apagar novamente.
target_branch_not_exist=O ramo de destino não existe.
[user]
change_avatar=Altere o seu avatar em gravatar.com
change_custom_avatar=Altere seu avatar nas configurações
join_on=Inscreveu-se em
repositories=Repositórios
activity=Atividade Pública
followers=Seguidores
starred=Marcado
following=Seguindo
[settings]
profile=Perfil
password=Senha
ssh_keys=Chaves SSH
social=Contas Sociais
applications=Aplicativos
orgs=Organizações
delete=Deletar Conta
uid=Uid
public_profile=Perfil Público
profile_desc=Seu endereço de E-mail é publico e será usado para qualquer notificação relacionada à conta, e qualquer operação na web feita através do site.
full_name=Nome Completo
website=Site
location=Localização
update_profile=Atualizar o Perfil
update_profile_success=O seu perfil foi atualizado com sucesso.
change_username=Nome de Usuário Alterado
change_username_desc=O nome de usuário foi alterado, você quer continuar? Isto afetará todos os links relacionados à sua conta.
continue=Continuar
cancel=Cancelar
enable_custom_avatar=Habilitar Avatar Customizado
enable_custom_avatar_helper=Habilite para desativar a busca no Gravatar
choose_new_avatar=Escolha um novo avatar
update_avatar=Atualizar configuração de Avatar
uploaded_avatar_not_a_image=O arquivo enviado não é uma imagem.
no_custom_avatar_available=Nenhum avatar personalizado disponível, não pode habilitá-lo.
update_avatar_success=Sua configuração de avatar foi atualizada com sucesso.
change_password=Alterar a Senha
old_password=Senha Atual
new_password=Nova Senha
password_incorrect=A senha atual não está correta.
change_password_success=A senha está alterada com sucesso. Você pode agora entrar com a senha nova.
emails=Endereços de E-mail
manage_emails=Gerenciar endereços de e-mail
email_desc=Seu endereço de email principal será usado para notificações e outras operações.
primary=Principal
primary_email=Definir como principal
delete_email=Deletar
add_new_email=Adicionar novo endereço de e-mail
add_email=Adicionar e-mail
add_email_success=Seu novo endereço de E-mail foi adicionado com sucesso.
manage_ssh_keys=Gerenciar Chaves SSH
add_key=Adicionar Chave
ssh_desc=Esta é uma lista de chaves SSH associadas com a sua conta. Remova quaisquer chaves que você não reconheça.
ssh_helper=<strong>Precisa de ajuda?</strong> Confira nosso guia para <a href="%s">gerar chaves SSH</a> ou solucionar <a href="%s">problemas comuns com SSH</a>.
add_new_key=Adicionar Chave SSH
key_name=Nome da Chave
key_content=Conteúdo
add_key_success=Nova Chave SSH foi adicionada!
delete_key=Deletar
add_on=Adicionado em
last_used=Última vez usado em
no_activity=Nenhuma atividade recente
manage_social=Gerenciar Contas Sociais Associadas
social_desc=Esta é uma lista de contas sociais. Remova qualquer ligação que você não reconheça.
unbind=Desvincular
unbind_success=A conta social foi desvinculada.
manage_access_token=Gerenciar Tokens de Acesso pessoais
generate_new_token=Gerar novo Token
tokens_desc=Tokens gerados por você que podem ser usados para acessar a API Gogs.
new_token_desc=Por enquanto, todo token terá acesso completo à sua conta.
token_name=Nome do Token
generate_token=Gerar Token
generate_token_succees=Novo token de acesso gerado com sucesso! Certifique-se de copiar seu novo token de acesso pessoal agora. Você não poderá vê-lo novamente!
delete_token=Excluir
delete_token_success=Token de acesso pessoal deletado com sucesso! Não esqueça-se de atualizar seus aplicativos também.
delete_account=Deletar Sua Conta
delete_prompt=A operação deletará sua conta permanentemente, e <strong>NÃO PODERÁ</strong> ser desfeita!
confirm_delete_account=Confirmar Deleção
delete_account_title=Deleção da Conta
delete_account_desc=Esta conta será deletada permanentemente, você quer continuar?
[repo]
owner=Dono
repo_name=Nome do Repositório
repo_name_helper=Nomes de repositórios bons são pequenos, memorizáveis e <strong>únicos</strong>.
visibility=Visibilidade
visiblity_helper=Este repositório é <span class="label label-red label-radius">Privado</span>
fork_repo=Fork o Repositório
fork_from=Fork de
fork_visiblity_helper=Não é possível alterar a visibilidade de um repositório bifurcado
repo_desc=Descrição
repo_lang=Idioma
repo_lang_helper=Selecione um arquivo .gitignore
license=Licença
license_helper=Selecione um arquivo de licença
init_readme=Inicialize este repositório com um LEIAME.md
create_repo=Criar Repositório
default_branch=Ramo padrão
mirror_interval=Intervalo de Espelho (hora)
need_auth=Precisa de Autorização
migrate_type=Tipo de Migração
migrate_type_helper=Este repositório será um <span class="label label-blue label-radius">Espelho</span>
migrate_repo=Migrar Repositório
migrate.clone_address=Endereço de Clone
migrate.invalid_local_path=Caminho local inválido, não existe ou não é um diretório.
copy_link=Copiar
click_to_copy=Copiar para a área de transferência
copied=Copiado com sucesso
clone_helper=Precisa de ajuda com a clonagem? Visite a <a target="_blank" href="%s">Ajuda</a>!
unwatch=Deixar de Observar
watch=Observar
unstar=Remover favorito
star=Favorito
fork=Fork
no_desc=Nenhuma Descrição
quick_guide=Guia Rápido
clone_this_repo=Clonar este repositório
create_new_repo_command=Criar um novo repositório na linha de comando
push_exist_repo=Push um repositório existente na linha de comando
branch=Ramo
tree=Árvore
branch_and_tags=Ramos & Tags
branches=Ramos
tags=Tags
issues=Problemas
commits=Commits
releases=Lançamentos
file_raw=Cru
file_history=Histórico
file_view_raw=Ver cru
commits.commits=Commits
commits.search=Pesquisar commits
commits.find=Buscar
commits.author=Autor
commits.message=Mensagem
commits.date=Data
commits.older=Mais Antigo
commits.newer=Mais Novo
settings=Configurações
settings.options=Opções
settings.collaboration=Colaboração
settings.hooks=Hooks da web
settings.githooks=Hooks do Git
settings.deploy_keys=Chaves de Deploy
settings.basic_settings=Configurações Básicas
settings.danger_zone=Zona de Perigo
settings.site=Site Oficial
settings.update_settings=Configurações de Atualização
settings.change_reponame=Nome do Repositório Alterado
settings.change_reponame_desc=O nome do repositório foi alterado, você quer continuar? Isto afetará todos os links relacionados à este repositório.
settings.transfer=Transferir Propriedade
settings.transfer_desc=Transferir este repositório para outro usuário ou para uma organização onde você tem direitos de administrador.
settings.new_owner_has_same_repo=O novo dono já tem um repositório com o mesmo nome.
settings.delete=Deletar Este Repositório
settings.delete_desc=Uma vez que você deleta um repositório, não tem volta. Por favor, tenha certeza.
settings.transfer_notices=<p>- Você perderá acesso se o novo dono é um usuário individual.</p><p>- Você permanecerá com o acesso se o novo dono é uma organização e você é um dos donos.</p>
settings.update_settings_success=As opções do repositório foram atualizadas com sucesso.
settings.transfer_owner=Novo Dono
settings.make_transfer=Fazer Transferência
settings.transfer_succeed=A posse do repositório foi transferido com sucesso.
settings.confirm_delete=Confirmar Deleção
settings.add_collaborator=Adicionar um Novo Colaborador
settings.add_collaborator_success=O novo colaborador foi adicionado.
settings.remove_collaborator_success=O colaborador foi removido.
settings.user_is_org_member=O usuário é um membro da organização que não pode ser adicionado como um colaborador.
settings.add_webhook=Adicionar Webhook
settings.hooks_desc=Hooks da web ou Webhooks permitem serviços externos serem notificados quando certos eventos acontecem no Gogs. Quando acontecem os eventos especificados, enviaremos uma solicitação POST para cada uma das URLs que você fornecer. Saiba mais no nosso <a target="_blank" href="%s"> Guia de Webhooks</a>.
settings.githooks_desc=Hooks do Git são ofertados pelo próprio Git, você pode editar arquivos de hooks suportados na lista abaixo para aplicar operações personalizadas.
settings.githook_edit_desc=Se o hook não estiver ativo, o conteúdo de exemplo será apresentado. Deixar o conteúdo em branco irá desativar esse hook.
settings.githook_name=Nome do Hook
settings.githook_content=Conteúdo do Hook
settings.update_githook=Atualizar Hook
settings.remove_hook_success=O hook da web foi removido.
settings.add_webhook_desc=Enviaremos uma solicitação <code>POST</code> para o URL abaixo com detalhes de quaisquer eventos inscritos. Você pode também especificar qual formato de dados você gostaria de receber (JSON, <code>x-www-form-urlencoded</code>, <em>etc</em>). Mais informação pode ser encontrada em <a target="_blank" href="%s">Webhooks Guide</a>.
settings.payload_url=URL de carga
settings.content_type=Tipo de Conteúdo
settings.secret=Secreto
settings.event_desc=Quais eventos você gostaria de acionar a esse hook da web?
settings.event_push_only=Apenas o evento <code>push</code>.
settings.active=Ativar
settings.active_helper=Enviaremos detalhes do evento quando este hook for acionado.
settings.add_hook_success=Novos hooks de web foram adicionados.
settings.update_webhook=Atualizar Hook da Web
settings.update_hook_success=Hook da web atualizado.
settings.delete_webhook=Excluir Hook da Web
settings.recent_deliveries=Entregas Recentes
settings.hook_type=Tipo de Hook
settings.add_slack_hook_desc=Adicionar <a href="%s">Slack</a> de integração para o seu repositório.
settings.slack_token=Token
settings.slack_domain=Domínio
settings.slack_channel=Canal
diff.browse_source=Ver Fontes
diff.parent=pai
diff.commit=commit
diff.data_not_available=Dados Diff não disponíveis.
diff.show_diff_stats=Mostrar estatísticas do Diff
diff.stats_desc=<strong> %d arquivos alterados</strong> com <strong>%d adições</strong> e <strong>%d exclusões</strong>
diff.bin=BIN
diff.view_file=Ver Arquivo
release.releases=Lançamentos
release.new_release=Novo Lançamento
release.draft=Rascunho
release.prerelease=Pré-Lançamento
release.stable=Estável
release.edit=editar
release.ahead=<strong>%d</strong> commits para %s depois desta versão
release.source_code=Código-fonte
release.tag_name=Nome da tag
release.target=Destino
release.tag_helper=Escolha uma tag existente, ou crie uma nova tag em publicar.
release.release_title=Título da Versão
release.content_with_md=Conteúdo com <a href="%s">Markdown</a>
release.write=Escrever
release.preview=Visualizar
release.content_placeholder=Escreva algum conteúdo
release.loading=Carregando...
release.prerelease_desc=Esta é uma versão prévia
release.prerelease_helper=Vou salientar que esta versão é identificada como não pronta para produção.
release.publish=Publicar Versão
release.save_draft=Salvar Rascunho
release.edit_release=Editar Versão
release.tag_name_already_exist=Já existiu versão com esse nome de tag.
[org]
org_name_holder=Nome da Organização
org_name_helper=Nomes de grandes organizações são curtos e memoráveis.
org_email_helper=O E-mail da organização receberá todas as notificações e as confirmações.
create_org=Criar Organização
repo_updated=Atualizado
people=Pessoas
invite_someone=Convidar Alguém
teams=Equipes
lower_members=membros
lower_repositories=repositórios
create_new_team=Criar Nova Equipe
org_desc=Descrição
team_name=Nome da Equipe
team_desc=Descrição
team_name_helper=Você usará este nome para mencionar esta equipe em conversas.
team_desc_helper=Do que trata essa equipe?
team_permission_desc=Que nível de permissão esta equipe deve ter?
settings=Configurações
settings.options=Opções
settings.full_name=Nome Completo
settings.website=Site
settings.location=Localização
settings.update_settings=Atualizar Configurações
settings.change_orgname=Nome da Organização Alterado
settings.change_orgname_desc=O nome da organização foi alterado, você quer continuar? Isto afetará todos os links que se relacionam a esta organização.
settings.update_setting_success=Configuração da organização atualizada com sucesso.
settings.delete=Deletar Organização
settings.delete_account=Deletar Esta Organização
settings.delete_prompt=A operação deletará esta organização permanentemente, e <strong>NÃO PODERÁ</strong> ser desfeita!
settings.confirm_delete_account=Confirmar Deleção
settings.delete_org_title=Deleção da Organização
settings.delete_org_desc=Esta organização será deletada permanentemente, você quer continuar?
settings.hooks_desc=Adicionar Hooks da Web que serão acionados para <strong>todos os repositórios</strong> dessa organização.
members.public=Público
members.public_helper=tornar privado
members.private=Privado
members.private_helper=torar público
members.owner=Dono
members.member=Membro
members.conceal=Ocultar
members.remove=Remover
members.leave=Sair
members.invite_desc=Comece digitando um nome de usuário para convidá-lo como novo membro para %s:
members.invite_now=Convidar Agora
teams.join=Juntar-se
teams.leave=Deixar
teams.read_access=Acesso de Leitura
teams.read_access_helper=Esta equipe poderá ver e clonar os repositórios dela.
teams.write_access=Acesso de Escrita
teams.write_access_helper=Esta equipa será capaz de ler os seus repositórios, bem como fazer push para eles.
teams.admin_access=Acesso do Administrador
teams.admin_access_helper=Esta equipe será capaz de fazer push/pull em seus repositórios, bem como adicionar-lhes outros colaboradores.
teams.no_desc=Esta equipe não tem descrição
teams.settings=Configurações
teams.owners_permission_desc=Donos tem acesso total a <strong>todos repositórios</strong> e também <strong>direitos de administrador</strong> para a organização.
teams.members=Membros da Equipe
teams.update_settings=Atualizar Configurações
teams.delete_team=Deletar Esta Equipe
teams.add_team_member=Adicionar Membro da Equipe
teams.delete_team_title=Deleção da Equipe
teams.delete_team_desc=Este equipe será deletada, você quer continuar? Membros desta equipe poderão perder acesso a alguns repositórios.
teams.delete_team_success=A equipe dada foi deletada com sucesso.
teams.read_permission_desc=Essa equipe concede acesso para <strong>Leitura</strong>: membros podem ver e clonar os repositórios da equipe.
teams.write_permission_desc=Esta equipe concede acesso para <strong>escrita</strong>: Membros podem ler e fazer push para os repositórios da equipe.
teams.admin_permission_desc=Esta equipe concede acesso de <strong>Administrador</strong>: Membros podem ler, fazer push e adicionar outros colaboradores para os repositórios da equipe.
teams.repositories=Repositórios da Equipe
teams.add_team_repository=Adicionar Repositório da Equipe
teams.remove_repo=Remover
teams.add_nonexistent_repo=O repositório que você está tentando adicionar não existe, por favor, crie-o primeiro.
[admin]
dashboard=Painel de controle
users=Usuários
organizations=Organizações
repositories=Repositórios
authentication=Autenticações
config=Configuração
notices=Sistema de notificações
monitor=Monitoramento
prev=Anterior
next=Próximo
dashboard.statistic=Estatística
dashboard.operations=Operações
dashboard.system_status=Status do Monitor de Sistema
dashboard.statistic_info=O banco de dados do Gogs contém <b>%d</b> usuários, <b>%d</b> organizações, <b>%d</b> chaves públicas, <b>%d</b> repositórios, <b>%d</b> observadores, <b>%d</b> estrelas, <b>%d</b> ações, <b>%d</b> acessos, <b>%d</b> questões, <b>%d</b> comentários, <b>%d</b> contas sociais, <b>%d</b> seguidores, <b>%d</b> espelhos, <b>%d</b> versões, <b>%d</b> origens de login, <b>%d</b> Hooks da Web, <b>%d</b> milestones, <b>%d</b> labels, <b>%d</b> tarefas hook, <b>%d</b> equipes, <b>%d</b> tarefas de atualização, <b>%d</b> anexos.
dashboard.operation_name=Nome da Operação
dashboard.operation_switch=Trocar
dashboard.operation_run=Executar
dashboard.clean_unbind_oauth=Limpar OAuthes não acoplados
dashboard.clean_unbind_oauth_success=Todos OAuthes desvinculados foram excluídos com sucesso.
dashboard.delete_inactivate_accounts=Excluir todas as contas inativas
dashboard.delete_inactivate_accounts_success=Todas as contas inativas foram excluídas com sucesso.
dashboard.delete_repo_archives=Excluir todos os arquivos dos repositórios
dashboard.delete_repo_archives_success=Todos os arquivos dos repositórios foram excluídos com sucesso.
dashboard.git_gc_repos=Fazer coleta de lixo nos repositórios
dashboard.git_gc_repos_success=Em todos repositórios, a coleta de lixo foi realizada com sucesso.
dashboard.resync_all_sshkeys=Reescrever o arquivo '.ssh/autorized_key' (atenção: chaves que não sejam do Gogs serão perdidas)
dashboard.resync_all_sshkeys_success=Todas as chaves públicas foram reescritas com sucesso.
dashboard.resync_all_update_hooks=Reescrever todos os hooks de atualização dos repositórios (necessário quando o caminho de configuração customizado é alterado)
dashboard.resync_all_update_hooks_success=Os hooks de atualização de todos os repositórios foram reescritos com sucesso.
dashboard.server_uptime=Servidor Ligado
dashboard.current_goroutine=Goroutines Atuais
dashboard.current_memory_usage=Uso de Memória Atual
dashboard.total_memory_allocated=Total de Memória Alocada
dashboard.memory_obtained=Memória Obtida
dashboard.pointer_lookup_times=Nº de Consultas a Ponteiros
dashboard.memory_allocate_times=Nº de Alocações de Memória
dashboard.memory_free_times=Nº de Liberações de Memória
dashboard.current_heap_usage=Uso Atual da Heap
dashboard.heap_memory_obtained=Memória de Heap Obtida
dashboard.heap_memory_idle=Memória da Heap Ociosa
dashboard.heap_memory_in_use=Memória da Heap em Uso
dashboard.heap_memory_released=Memória da Heap Liberada
dashboard.heap_objects=Objetos na Heap
dashboard.bootstrap_stack_usage=Uso de Pilha Bootstrap
dashboard.stack_memory_obtained=Memória de Pilha Obtida
dashboard.mspan_structures_usage=Uso de Estruturas de MSpan
dashboard.mspan_structures_obtained=Estruturas de MSpan Obtidas
dashboard.mcache_structures_usage=Uso de Estruturas de MCache
dashboard.mcache_structures_obtained=Estruturas de MCache Obtidas
dashboard.profiling_bucket_hash_table_obtained=Perfil Obtido da Bucket Hash Table
dashboard.gc_metadata_obtained=Metadados do GC Obtidos
dashboard.other_system_allocation_obtained=Outra Alocação de Sistema Obtida
dashboard.next_gc_recycle=Próxima Reciclagem do GC
dashboard.last_gc_time=Desde da Última Vez do GC
dashboard.total_gc_time=Pausa Total do GC
dashboard.total_gc_pause=Pausa Total do GC
dashboard.last_gc_pause=Última Pausa do GC
dashboard.gc_times=Nº Execuções do GC
users.user_manage_panel=Painel de Gerenciamento do Usuário
users.new_account=Criar Nova Conta
users.name=Nome
users.activated=Ativado
users.admin=Administrador
users.repos=Repos
users.created=Criado
users.edit=Editar
users.auth_source=Fonte de Autorização
users.local=Local
users.auth_login_name=Nome de Autorização de Login
users.update_profile_success=O perfil da conta foi atualizado com sucesso.
users.edit_account=Editar Conta
users.is_activated=Esta conta está ativada
users.is_admin=Esta conta tem permissões de administrador
users.allow_git_hook=Esta conta tem permissões para criar ganchos Git
users.update_profile=Atualizar Perfil da Conta
users.delete_account=Deletar Esta Conta
users.still_own_repo=Sua conta ainda é proprietária do repositório, você tem que excluir ou transferi-lo primeiro.
users.still_has_org=Sua conta ainda faz parte da organização, você deve sair ou excluí-la primeiro.
orgs.org_manage_panel=Painel de Gerenciamento da Organização
orgs.name=Nome
orgs.teams=Equipes
orgs.members=Membros
repos.repo_manage_panel=Painel de Gerenciamento do Repositório
repos.owner=Dono
repos.name=Nome
repos.private=Privado
repos.watches=Observadores
repos.stars=Estrelas
repos.issues=Problemas
auths.auth_manage_panel=Painel de Gerenciamento da Autorização
auths.new=Adicionar Nova Fonte de Autorização
auths.name=Nome
auths.type=Tipo
auths.enabled=Habilitado
auths.updated=Atualizado
auths.auth_type=Tipo da Autorização
auths.auth_name=Nome da Autorização
auths.domain=Domínio
auths.host=Host
auths.port=Porta
auths.base_dn=Base DN
auths.attribute_username=Atributo nome de usuário
auths.attribute_name=Atributo primeiro nome
auths.attribute_surname=Atributo sobrenome
auths.attribute_mail=Atributo e-mail
auths.filter=Filtro de Pesquisa
auths.ms_ad_sa=Ms Ad SA
auths.smtp_auth=Tipo de Autorização de SMTP
auths.smtphost=Host SMTP
auths.smtpport=Porta SMTP
auths.enable_tls=Habilitar Criptografia TLS
auths.enable_auto_register=Habilitar Registro Automático
auths.tips=Dicas
auths.edit=Editar Configuração da Autorização
auths.activated=Esta autenticação foi ativada
auths.update_success=A configuração da autorização foi atualizada com sucesso.
auths.update=Atualizar Configuração da Autorização
auths.delete=Excluir Esta Autorização
auths.delete_auth_title=Exclusão da Autorização
auths.delete_auth_desc=Esta autorização será excluída, deseja continuar?
config.server_config=Configuração do Servidor
config.app_name=Nome do Aplicativo
config.app_ver=Versão do Aplicativo
config.app_url=URL do Aplicativo
config.domain=Domínio
config.offline_mode=Modo Offline
config.disable_router_log=Desabilitar o Log do Roteador
config.run_user=Usuário de Execução
config.run_mode=Modo de Execução
config.repo_root_path=Caminho Raiz do Repositório
config.static_file_root_path=Caminho Raiz para Arquivo Estático
config.log_file_root_path=Caminho Raiz para Arquivo de Log
config.script_type=Tipo de Script
config.reverse_auth_user=Usuário de Autenticação Reversa
config.db_config=Configuração do Banco de Dados
config.db_type=Tipo
config.db_host=Host
config.db_name=Nome
config.db_user=Usuário
config.db_ssl_mode=Modo SSL
config.db_ssl_mode_helper=(apenas para "postgres")
config.db_path=Caminho
config.db_path_helper=(apenas para "sqlite3")
config.service_config=Configuração do Serviço
config.register_email_confirm=Requerer Confirmação de E-mail
config.disable_register=Desabilitar Registro
config.show_registration_button=Mostrar Botão de Registo
config.require_sign_in_view=Requerer Entrar no Gogs para Ver
config.mail_notify=Notificação de Correio
config.enable_cache_avatar=Habilitar Cache de Avatar
config.active_code_lives=Ativar Code Lives
config.reset_password_code_lives=Redefinir Senha de Code Lives
config.webhook_config=Configuração de Hook da Web
config.task_interval=Intervalo da Tarefa
config.deliver_timeout=Intervalo de Entrega
config.skip_tls_verify=Pular Verificar TLS
config.mailer_config=Configuração de Correio
config.mailer_enabled=Habilitado
config.mailer_name=Nome
config.mailer_host=Host
config.mailer_user=Usuário
config.oauth_config=Configuração do OAuth
config.oauth_enabled=Habilitado
config.cache_config=Configuração de Cache
config.cache_adapter=Adaptador de Cache
config.cache_interval=Intervalo de Cache
config.cache_conn=Conexão de Cache
config.session_config=Configuração da Sessão
config.session_provider=Provedor da Sessão
config.provider_config=Configuração do Provedor
config.cookie_name=Nome do Cookie
config.enable_set_cookie=Habilitar Uso de Cookie
config.gc_interval_time=Tempo de Intervalo do GC
config.session_life_time=Tempo de Vida da Sessão
config.https_only=Apenas HTTPS
config.cookie_life_time=Tempo de Vida do Cookie
config.picture_config=Configuração da Imagem
config.picture_service=Serviço de Imagens
config.disable_gravatar=Desativar Gravatar
config.log_config=Configuração de Log
config.log_mode=Modo do Log
monitor.cron=Tarefas Cron
monitor.name=Nome
monitor.schedule=Cronograma
monitor.next=Próxima Vez
monitor.previous=Última Vez
monitor.execute_times=Nº de Execuções
monitor.process=Processos em Execução
monitor.desc=Descrição
monitor.start=Hora de Início
monitor.execute_time=Tempo de Execução
notices.system_notice_list=Sistema de Notificações
notices.type=Tipo
notices.type_1=Repositório
notices.desc=Descrição
notices.op=Op.
notices.delete_success=Aviso do sistema foi deletado com sucesso.
[action]
create_repo=repositório criado <a href="%s"> %s</a>
commit_repo=pushed para <a href="%s/src/%s">%[2]s</a> em <a href="%[1]s">%[3]s</a>
create_issue='questão aberta <a href="%s/issues/%s">%s#%[2]s</a>'
comment_issue='comentou sobre a questão <a href="%s/issues/%s">%s#%[2]s</a>'
transfer_repo=repositório transferido de <code>%s</code> para <a href="%s">%s</a>
push_tag=Foi feito push na tag <a href="%s/src/%s">%[2]s</a> para <a href="%[1]s">%[3]s</a>
compare_2_commits=Ver comparação desses 2 commits
[tool]
ago=atrás
from_now=a partir de agora
now=agora
1s=1 segundo %s
1m=1 minuto %s
1h=1 hora %s
1d=1 dia %s
1w=1 semana %s
1mon=1 mês %s
1y=1 ano %s
seconds=%d segundos %s
minutes=%d minutos %s
hours=%d horas %s
days=%d dias %s
weeks=%d semanas %s
months=%d meses %s
years=%d anos %s
raw_seconds=segundos
raw_minutes=minutos

@ -281,13 +281,13 @@ init_readme=Создать репозиторий с файлом README.md
create_repo=Создание репозитория
default_branch=Ветка по умолчанию
mirror_interval=Интервал зеркалирования (час)
goget_meta=Meta-тег для go get
goget_meta_helper=Репозиторий будет доступен для <span class="label label-blue label-radius">go get</span>
need_auth=Требуется авторизация
migrate_type=Тип миграции
migrate_type_helper=Этот репозиторий будет <span class="label label-blue label-radius">зеркалом</span>
migrate_repo=Перенос репозитория
migrate.clone_address=Скопировать адрес
migrate.invalid_local_path=Недопустимый локальный путь. Возможно он не существует или является не папкой.
copy_link=Копировать
click_to_copy=Скопировать в буфер обмена
@ -343,18 +343,18 @@ settings.transfer_desc=Передать репозиторий другому п
settings.new_owner_has_same_repo=У нового владельца уже есть хранилище с таким названием.
settings.delete=Удалить этот репозиторий
settings.delete_desc=Как только вы удалите репозиторий — пути назад не будет. Удостоверьтесь, что вам это точно нужно.
settings.transfer_notices=<p>- You will lose access if new owner is a individual user.</p><p>- You will remain access if new owner is an organization and you're one of the owners.</p>
settings.transfer_notices=<p>- Вы потеряете доступ, если новый владелец является индивидуальным пользователем.</p><p>- У Вас останется доступ, если новый владелец является организацией, и вы один из её владельцев.</p>
settings.update_settings_success=Настройка репозитория обновлена успешно.
settings.transfer_owner=Новый владелец
settings.make_transfer=Выполнить передачу
settings.transfer_succeed=Repository ownership has been transferred successfully.
settings.transfer_succeed=Владение репозиторием было успешно передано.
settings.confirm_delete=Подтвердить удаление
settings.add_collaborator=Добавить нового соавтора
settings.add_collaborator_success=Был добавлен новый соавтор.
settings.remove_collaborator_success=Соавтор был удален.
settings.user_is_org_member=Пользователь является членом организации, члены которой не могут быть добавлены в качестве соавтора.
settings.add_webhook=Добавить Webhook
settings.hooks_desc=Webhooks allow external services to be notified when certain events happen on Gogs. When the specified events happen, we'll send a POST request to each of the URLs you provide. Learn more in our <a target="_blank" href="%s">Webhooks Guide</a>.
settings.hooks_desc=Webhooks позволяют внешним службам получать уведомления при возникновении определенных событий на Gogs. При возникновении указанных событий мы отправим запрос POST на каждый заданный вами URL. Узнать больше можно в нашем <a target="_blank" href="%s">Руководстве по Webhooks</a>.
settings.githooks_desc=Git Hooks are powered by Git itself, you can edit files of supported hooks in the list below to apply custom operations.
settings.githook_edit_desc=If hook is not active, sample content will be presented. Leave content to be blank will disable this hook.
settings.githook_name=Название Hook'a
@ -595,7 +595,10 @@ auths.domain=Домен
auths.host=Хост
auths.port=Порт
auths.base_dn=Base DN
auths.attributes=Search Attributes
auths.attribute_username=Username attribute
auths.attribute_name=First name attribute
auths.attribute_surname=Surname attribute
auths.attribute_mail=E-mail attribute
auths.filter=Фильтр поиска
auths.ms_ad_sa=Ms Ad SA
auths.smtp_auth=Тип авторизации SMTP
@ -693,12 +696,12 @@ notices.op=Op.
notices.delete_success=Системное уведомление успешно удалено.
[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/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>
create_repo=создан репозиторий <a href="%s"> %s</a>
commit_repo=pushed to <a href="%s/src/%s">%[2]s</a> at <a href="%[1]s">%[3]s</a>
create_issue=`opened issue <a href="%s/issues/%s">%s#%[2]s</a>`
comment_issue=`commented on issue <a href="%s/issues/%s">%s#%[2]s</a>`
transfer_repo=transfered repository <code>%s</code> to <a href="%s">%s</a>
push_tag=pushed tag <a href="%s/src/%s">%[2]s</a> to <a href="%[1]s">%[3]s</a>
compare_2_commits=Просмотреть сравнение двух коммитов
[tool]

@ -281,13 +281,13 @@ init_readme=使用 README.md 文件初始化仓库
create_repo=创建仓库
default_branch=默认分支
mirror_interval=镜像同步周期(小时)
goget_meta=Go-Get 支持
goget_meta_helper=本仓库将可以通过 <span class="label label-blue label-radius">Go Get</span> 获取
need_auth=需要授权验证
migrate_type=迁移类型
migrate_type_helper=本仓库将是 <span class="label label-blue label-radius">镜像</span>
migrate_repo=迁移仓库
migrate.clone_address=克隆地址
migrate.invalid_local_path=无效的本地路径,不存在或不是一个目录!
copy_link=复制链接
click_to_copy=复制到剪切板
@ -595,7 +595,10 @@ auths.domain=域名
auths.host=主机地址
auths.port=主机端口
auths.base_dn=Base DN
auths.attributes=Search Attributes
auths.attribute_username=用户名属性
auths.attribute_name=名字属性
auths.attribute_surname=姓氏属性
auths.attribute_mail=邮箱属性
auths.filter=Search Filter
auths.ms_ad_sa=Ms Ad SA
auths.smtp_auth=SMTP 授权类型
@ -693,12 +696,12 @@ notices.op=操作
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/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>
create_repo=创建了仓库 <a href="%s">%s</a>
commit_repo=推送了 <a href="%s/src/%s">%[2]s</a> 分支的代码到 <a href="%[1]s">%[3]s</a>
create_issue=`创建了工单 <a href="%s/issues/%s">%s#%[2]s</a>`
comment_issue=`评论了工单 <a href="%s/issues/%s">%s#%[2]s</a>`
transfer_repo=将仓库 <code>%s</code> 转移至 <a href="%s">%s</a>
push_tag=推送了标签 <a href="%s/src/%s">%[2]s</a> 到 <a href="%[1]s">%[3]s</a>
compare_2_commits=查看 2 次提交的内容对比
[tool]

@ -281,13 +281,13 @@ init_readme=使用 README.md 文件初始化倉庫
create_repo=創建倉庫
default_branch=默認分支
mirror_interval=鏡像同步周期(小時)
goget_meta=Go-Get 支持
goget_meta_helper=本倉庫將可以通過 <span class="label label-blue label-radius">Go Get</span> 獲取
need_auth=需要授權驗證
migrate_type=遷移類型
migrate_type_helper=本倉庫將是 <span class="label label-blue label-radius">鏡像</span>
migrate_repo=遷移倉庫
migrate.clone_address=複製地址
migrate.invalid_local_path=無效的本地路徑,該路徑不存在或不是一個目錄!
copy_link=複製連結
click_to_copy=複製到剪切簿
@ -516,8 +516,8 @@ 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.resync_all_update_hooks=重新生成所有倉庫的 Update 鈎子(用於被修改的自定義配置文件)
dashboard.resync_all_update_hooks_success=已成功重新生成所有倉庫的 Update 鈎子!
dashboard.server_uptime=服務執行時間
dashboard.current_goroutine=當前 Goroutines 數量
@ -595,7 +595,10 @@ auths.domain=域名
auths.host=主機地址
auths.port=主機端口
auths.base_dn=Base DN
auths.attributes=搜尋屬性
auths.attribute_username=用戶名屬性
auths.attribute_name=名子屬性
auths.attribute_surname=姓氏屬性
auths.attribute_mail=電子郵箱屬性
auths.filter=搜尋過濾
auths.ms_ad_sa=Ms Ad SA
auths.smtp_auth=SMTP 授權類型
@ -647,7 +650,7 @@ config.reset_password_code_lives=重置密碼連結有效期
config.webhook_config=Web 鉤子配置
config.task_interval=任務周期
config.deliver_timeout=推送超時
config.skip_tls_verify=Skip TLS Verify
config.skip_tls_verify=忽略 TLS 驗證
config.mailer_config=郵件配置
config.mailer_enabled=啟用服務
config.mailer_name=發送者名稱
@ -693,12 +696,12 @@ notices.op=操作
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/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>
create_repo=創建了倉庫 <a href="%s">%s</a>
commit_repo=推送了 <a href="%s/src/%s">%[2]s</a> 分支的代碼到 <a href="%[1]s">%[3]s</a>
create_issue=`創建了問題 <a href="%s/issues/%s">%s#%[2]s</a>`
comment_issue=`評論了問題 <a href="%s/issues/%s">%s#%[2]s</a>`
transfer_repo=將倉庫 <code>%s</code> 轉移至 <a href="%s">%s</a>
push_tag=推送了標籤 <a href="%s/src/%s">%[2]s</a> 到 <a href="%[1]s">%[3]s</a>
compare_2_commits=查看 2 次提交的內容對比
[tool]

@ -0,0 +1,12 @@
web:
build: .
links:
- mysql
ports:
- "3000:3000"
mysql:
image: mysql
environment:
- MYSQL_ROOT_PASSWORD=gogs
- MYSQL_DATABASE=gogs

@ -17,7 +17,7 @@ import (
"github.com/gogits/gogs/modules/setting"
)
const APP_VER = "0.5.16.0301 Beta"
const APP_VER = "0.6.0.0319 Beta"
func init() {
runtime.GOMAXPROCS(runtime.NumCPU())

@ -6,6 +6,8 @@ package models
import (
"fmt"
"github.com/gogits/gogs/modules/log"
)
type AccessMode int
@ -77,6 +79,10 @@ func (u *User) GetAccessibleRepositories() (map[*Repository]AccessMode, error) {
for _, access := range accesses {
repo, err := GetRepositoryById(access.RepoID)
if err != nil {
if IsErrRepoNotExist(err) {
log.Error(4, "%v", err)
continue
}
return nil, err
}
if err = repo.GetOwner(); err != nil {

@ -61,14 +61,14 @@ func init() {
// Action represents user operation type and other information to repository.,
// it implemented interface base.Actioner so that can be used in template render.
type Action struct {
Id int64
UserId int64 // Receiver user id.
ID int64 `xorm:"pk autoincr"`
UserID int64 // Receiver user id.
OpType ActionType
ActUserId int64 // Action user id.
ActUserID int64 // Action user id.
ActUserName string // Action user name.
ActEmail string
ActAvatar string `xorm:"-"`
RepoId int64
RepoID int64
RepoUserName string
RepoName string
RefName string
@ -97,8 +97,15 @@ func (a Action) GetRepoName() string {
return a.RepoName
}
func (a Action) GetRepoPath() string {
return path.Join(a.RepoUserName, a.RepoName)
}
func (a Action) GetRepoLink() string {
return path.Join(setting.AppSubUrl, a.RepoUserName, a.RepoName)
if len(setting.AppSubUrl) > 0 {
return path.Join(setting.AppSubUrl, a.GetRepoPath())
}
return "/" + a.GetRepoPath()
}
func (a Action) GetBranch() string {
@ -302,7 +309,7 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string,
return errors.New("action.CommitRepoAction(GetRepositoryByName): " + err.Error())
}
repo.IsBare = false
if err = UpdateRepository(repo); err != nil {
if err = UpdateRepository(repo, false); err != nil {
return errors.New("action.CommitRepoAction(UpdateRepository): " + err.Error())
}
@ -312,10 +319,18 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string,
log.Debug("action.CommitRepoAction(updateIssuesCommit): ", err)
}
if err = NotifyWatchers(&Action{ActUserId: userId, ActUserName: userName, ActEmail: actEmail,
OpType: opType, Content: string(bs), RepoId: repoId, RepoUserName: repoUserName,
RepoName: repoName, RefName: refName,
IsPrivate: repo.IsPrivate}); err != nil {
if err = NotifyWatchers(&Action{
ActUserID: userId,
ActUserName: userName,
ActEmail: actEmail,
OpType: opType,
Content: string(bs),
RepoID: repoId,
RepoUserName: repoUserName,
RepoName: repoName,
RefName: refName,
IsPrivate: repo.IsPrivate,
}); err != nil {
return errors.New("action.CommitRepoAction(NotifyWatchers): " + err.Error())
}
@ -402,32 +417,28 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string,
continue
}
var payload BasePayload
switch w.HookTaskType {
case SLACK:
{
s, err := GetSlackPayload(p, w.Meta)
if err != nil {
return errors.New("action.GetSlackPayload: " + err.Error())
}
CreateHookTask(&HookTask{
Type: w.HookTaskType,
Url: w.Url,
BasePayload: s,
ContentType: w.ContentType,
IsSsl: w.IsSsl,
})
s, err := GetSlackPayload(p, w.Meta)
if err != nil {
return errors.New("action.GetSlackPayload: " + err.Error())
}
payload = s
default:
{
p.Secret = w.Secret
CreateHookTask(&HookTask{
Type: w.HookTaskType,
Url: w.Url,
BasePayload: p,
ContentType: w.ContentType,
IsSsl: w.IsSsl,
})
}
payload = p
p.Secret = w.Secret
}
if err = CreateHookTask(&HookTask{
Type: w.HookTaskType,
Url: w.Url,
BasePayload: payload,
ContentType: w.ContentType,
EventType: HOOK_EVENT_PUSH,
IsSsl: w.IsSsl,
}); err != nil {
return fmt.Errorf("CreateHookTask: %v", err)
}
}
@ -436,14 +447,15 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string,
func newRepoAction(e Engine, u *User, repo *Repository) (err error) {
if err = notifyWatchers(e, &Action{
ActUserId: u.Id,
ActUserID: u.Id,
ActUserName: u.Name,
ActEmail: u.Email,
OpType: CREATE_REPO,
RepoId: repo.Id,
RepoID: repo.Id,
RepoUserName: repo.Owner.Name,
RepoName: repo.Name,
IsPrivate: repo.IsPrivate}); err != nil {
IsPrivate: repo.IsPrivate,
}); err != nil {
return fmt.Errorf("notify watchers '%d/%s'", u.Id, repo.Id)
}
@ -458,11 +470,11 @@ func NewRepoAction(u *User, repo *Repository) (err error) {
func transferRepoAction(e Engine, actUser, oldOwner, newOwner *User, repo *Repository) (err error) {
action := &Action{
ActUserId: actUser.Id,
ActUserID: actUser.Id,
ActUserName: actUser.Name,
ActEmail: actUser.Email,
OpType: TRANSFER_REPO,
RepoId: repo.Id,
RepoID: repo.Id,
RepoUserName: newOwner.Name,
RepoName: repo.Name,
IsPrivate: repo.IsPrivate,

@ -0,0 +1,84 @@
// 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 models
import (
"fmt"
)
// ____ ___
// | | \______ ___________
// | | / ___// __ \_ __ \
// | | /\___ \\ ___/| | \/
// |______//____ >\___ >__|
// \/ \/
type ErrUserOwnRepos struct {
UID int64
}
func IsErrUserOwnRepos(err error) bool {
_, ok := err.(ErrUserOwnRepos)
return ok
}
func (err ErrUserOwnRepos) Error() string {
return fmt.Sprintf("user still has ownership of repositories: [uid: %d]", err.UID)
}
type ErrUserHasOrgs struct {
UID int64
}
func IsErrUserHasOrgs(err error) bool {
_, ok := err.(ErrUserHasOrgs)
return ok
}
func (err ErrUserHasOrgs) Error() string {
return fmt.Sprintf("user still has membership of organizations: [uid: %d]", err.UID)
}
// ________ .__ __ .__
// \_____ \_______ _________ ____ |__|____________ _/ |_|__| ____ ____
// / | \_ __ \/ ___\__ \ / \| \___ /\__ \\ __\ |/ _ \ / \
// / | \ | \/ /_/ > __ \| | \ |/ / / __ \| | | ( <_> ) | \
// \_______ /__| \___ (____ /___| /__/_____ \(____ /__| |__|\____/|___| /
// \/ /_____/ \/ \/ \/ \/ \/
type ErrLastOrgOwner struct {
UID int64
}
func IsErrLastOrgOwner(err error) bool {
_, ok := err.(ErrLastOrgOwner)
return ok
}
func (err ErrLastOrgOwner) Error() string {
return fmt.Sprintf("user is the last member of owner team: [uid: %d]", err.UID)
}
// __________ .__ __
// \______ \ ____ ______ ____ _____|__|/ |_ ___________ ___.__.
// | _// __ \\____ \ / _ \/ ___/ \ __\/ _ \_ __ < | |
// | | \ ___/| |_> > <_> )___ \| || | ( <_> ) | \/\___ |
// |____|_ /\___ > __/ \____/____ >__||__| \____/|__| / ____|
// \/ \/|__| \/ \/
type ErrRepoNotExist struct {
ID int64
UID int64
Name string
}
func IsErrRepoNotExist(err error) bool {
_, ok := err.(ErrRepoNotExist)
return ok
}
func (err ErrRepoNotExist) Error() string {
return fmt.Sprintf("repository does not exist [id: %d, uid: %d, name: %s]", err.ID, err.UID, err.Name)
}

@ -215,11 +215,9 @@ func UserSignIn(uname, passwd string) (*User, error) {
switch u.LoginType {
case LDAP:
return LoginUserLdapSource(u, u.LoginName, passwd,
source.Id, source.Cfg.(*LDAPConfig), false)
return LoginUserLdapSource(u, u.LoginName, passwd, source.Id, source.Cfg.(*LDAPConfig), false)
case SMTP:
return LoginUserSMTPSource(u, u.LoginName, passwd,
source.Id, source.Cfg.(*SMTPConfig), false)
return LoginUserSMTPSource(u, u.LoginName, passwd, source.Id, source.Cfg.(*SMTPConfig), false)
}
return nil, ErrUnsupportedLoginType
}

@ -341,12 +341,15 @@ func teamToTeamRepo(x *xorm.Engine) error {
orgID := com.StrTo(team["org_id"]).MustInt64()
teamID := com.StrTo(team["id"]).MustInt64()
// #1032: legacy code can have duplicated IDs for same repository.
mark := make(map[int64]bool)
for _, idStr := range strings.Split(string(team["repo_ids"]), "|") {
repoID := com.StrTo(strings.TrimPrefix(idStr, "$")).MustInt64()
if repoID == 0 {
if repoID == 0 || mark[repoID] {
continue
}
mark[repoID] = true
teamRepos = append(teamRepos, &TeamRepo{
OrgID: orgID,
TeamID: teamID,

@ -89,8 +89,13 @@ func getEngine() (*xorm.Engine, error) {
cnnstr := ""
switch DbCfg.Type {
case "mysql":
cnnstr = fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8",
DbCfg.User, DbCfg.Passwd, DbCfg.Host, DbCfg.Name)
if DbCfg.Host[0] == '/' { // looks like a unix socket
cnnstr = fmt.Sprintf("%s:%s@unix(%s)/%s?charset=utf8",
DbCfg.User, DbCfg.Passwd, DbCfg.Host, DbCfg.Name)
} else {
cnnstr = fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8",
DbCfg.User, DbCfg.Passwd, DbCfg.Host, DbCfg.Name)
}
case "postgres":
var host, port = "127.0.0.1", "5432"
fields := strings.Split(DbCfg.Host, ":")

@ -18,7 +18,6 @@ var (
ErrTeamAlreadyExist = errors.New("Team already exist")
ErrTeamNotExist = errors.New("Team does not exist")
ErrTeamNameIllegal = errors.New("Team name contains illegal characters")
ErrLastOrgOwner = errors.New("The user to remove is the last member in owner team")
)
// IsOwnedBy returns true if given user is in the owner team.
@ -339,18 +338,20 @@ func RemoveOrgUser(orgId, uid int64) error {
has, err := x.Where("uid=?", uid).And("org_id=?", orgId).Get(ou)
if err != nil {
return err
return fmt.Errorf("get org-user: %v", err)
} else if !has {
return nil
}
u, err := GetUserById(uid)
if err != nil {
return err
return fmt.Errorf("GetUserById: %v", err)
}
org, err := GetUserById(orgId)
if err != nil {
return err
return fmt.Errorf("get organization: %v", err)
} else if err = org.GetRepositories(); err != nil {
return fmt.Errorf("GetRepositories: %v", err)
}
// Check if the user to delete is the last member in owner team.
@ -360,49 +361,39 @@ func RemoveOrgUser(orgId, uid int64) error {
return err
}
if t.NumMembers == 1 {
return ErrLastOrgOwner
return ErrLastOrgOwner{UID: uid}
}
}
sess := x.NewSession()
defer sess.Close()
defer sessionRelease(sess)
if err := sess.Begin(); err != nil {
return err
}
if _, err := sess.Id(ou.ID).Delete(ou); err != nil {
sess.Rollback()
return err
} else if _, err = sess.Exec("UPDATE `user` SET num_members=num_members-1 WHERE id = ?", orgId); err != nil {
sess.Rollback()
} else if _, err = sess.Exec("UPDATE `user` SET num_members=num_members-1 WHERE id=?", orgId); err != nil {
return err
}
// Delete all repository accesses.
if err = org.GetRepositories(); err != nil {
sess.Rollback()
return err
}
access := &Access{
UserID: u.Id,
}
access := &Access{UserID: u.Id}
for _, repo := range org.Repos {
access.RepoID = repo.Id
if _, err = sess.Delete(access); err != nil {
sess.Rollback()
return err
} else if err = WatchRepo(u.Id, repo.Id, false); err != nil {
sess.Rollback()
} else if err = watchRepo(sess, u.Id, repo.Id, false); err != nil {
return err
}
}
// Delete member in his/her teams.
ts, err := GetUserTeams(org.Id, u.Id)
teams, err := getUserTeams(sess, org.Id, u.Id)
if err != nil {
return err
}
for _, t := range ts {
for _, t := range teams {
if err = removeTeamMember(sess, org.Id, t.ID, u.Id); err != nil {
return err
}
@ -902,7 +893,7 @@ func removeTeamMember(e Engine, orgId, teamId, uid int64) error {
// Check if the user to delete is the last member in owner team.
if t.IsOwnerTeam() && t.NumMembers == 1 {
return ErrLastOrgOwner
return ErrLastOrgOwner{UID: uid}
}
t.NumMembers--

@ -254,15 +254,16 @@ func saveAuthorizedKeyFile(keys ...*PublicKey) error {
}
defer f.Close()
finfo, err := f.Stat()
fi, err := f.Stat()
if err != nil {
return err
}
// FIXME: following command does not support in Windows.
if !setting.IsWindows {
if finfo.Mode().Perm() > 0600 {
log.Error(4, "authorized_keys file has unusual permission flags: %s - setting to -rw-------", finfo.Mode().Perm().String())
// .ssh directory should have mode 700, and authorized_keys file should have mode 600.
if fi.Mode().Perm() > 0600 {
log.Error(4, "authorized_keys file has unusual permission flags: %s - setting to -rw-------", fi.Mode().Perm().String())
if err = f.Chmod(0600); err != nil {
return err
}
@ -433,7 +434,7 @@ func RewriteAllPublicKeys() error {
defer sshOpLocker.Unlock()
tmpPath := filepath.Join(SSHPath, "authorized_keys.tmp")
f, err := os.Create(tmpPath)
f, err := os.OpenFile(tmpPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
return err
}

@ -23,6 +23,7 @@ import (
"github.com/Unknwon/com"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/bindata"
"github.com/gogits/gogs/modules/git"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/process"
@ -35,7 +36,6 @@ const (
var (
ErrRepoAlreadyExist = errors.New("Repository already exist")
ErrRepoNotExist = errors.New("Repository does not exist")
ErrRepoFileNotExist = errors.New("Repository file does not exist")
ErrRepoNameIllegal = errors.New("Repository name contains illegal characters")
ErrRepoFileNotLoaded = errors.New("Repository file not loaded")
@ -56,7 +56,7 @@ func LoadRepoConfig() {
types := []string{"gitignore", "license"}
typeFiles := make([][]string, 2)
for i, t := range types {
files, err := com.StatDir(path.Join("conf", t))
files, err := bindata.AssetDir("conf/" + t)
if err != nil {
log.Fatal(4, "Fail to get %s files: %v", t, err)
}
@ -348,7 +348,7 @@ func MigrateRepository(u *User, name, desc string, private, mirror bool, url str
return repo, err
}
repo.IsMirror = true
return repo, UpdateRepository(repo)
return repo, UpdateRepository(repo, false)
} else {
os.RemoveAll(repoPath)
}
@ -363,18 +363,7 @@ func MigrateRepository(u *User, name, desc string, private, mirror bool, url str
return repo, fmt.Errorf("create update hook: %v", err)
}
return repo, UpdateRepository(repo)
}
// extractGitBareZip extracts git-bare.zip to repository path.
func extractGitBareZip(repoPath string) error {
z, err := zip.Open(path.Join(setting.ConfRootPath, "content/git-bare.zip"))
if err != nil {
return err
}
defer z.Close()
return z.ExtractTo(repoPath)
return repo, UpdateRepository(repo, false)
}
// initRepoCommit temporarily changes with work directory.
@ -407,12 +396,14 @@ func createUpdateHook(repoPath string) error {
}
// InitRepository initializes README and .gitignore if needed.
func initRepository(e Engine, f string, u *User, repo *Repository, initReadme bool, repoLang, license string) error {
repoPath := RepoPath(u.Name, repo.Name)
// Create bare new repository.
if err := extractGitBareZip(repoPath); err != nil {
return err
func initRepository(e Engine, repoPath string, u *User, repo *Repository, initReadme bool, repoLang, license string) error {
// Init bare new repository.
os.MkdirAll(repoPath, os.ModePerm)
_, stderr, err := process.ExecDir(-1, repoPath,
fmt.Sprintf("initRepository(git init --bare): %s", repoPath),
"git", "init", "--bare")
if err != nil {
return errors.New("git init --bare: " + stderr)
}
if err := createUpdateHook(repoPath); err != nil {
@ -435,11 +426,11 @@ func initRepository(e Engine, f string, u *User, repo *Repository, initReadme bo
tmpDir := filepath.Join(os.TempDir(), com.ToStr(time.Now().Nanosecond()))
os.MkdirAll(tmpDir, os.ModePerm)
_, stderr, err := process.Exec(
_, stderr, err = process.Exec(
fmt.Sprintf("initRepository(git clone): %s", repoPath),
"git", "clone", repoPath, tmpDir)
if err != nil {
return errors.New("initRepository(git clone): " + stderr)
return errors.New("git clone: " + stderr)
}
// README
@ -452,43 +443,36 @@ func initRepository(e Engine, f string, u *User, repo *Repository, initReadme bo
}
}
// FIXME: following two can be merged.
// .gitignore
filePath := "conf/gitignore/" + repoLang
if com.IsFile(filePath) {
targetPath := path.Join(tmpDir, fileName["gitign"])
if com.IsFile(filePath) {
if err = com.Copy(filePath, targetPath); err != nil {
return err
}
} else {
// Check custom files.
filePath = path.Join(setting.CustomPath, "conf/gitignore", repoLang)
if com.IsFile(filePath) {
if err := com.Copy(filePath, targetPath); err != nil {
return err
}
}
// Copy custom file when available.
customPath := path.Join(setting.CustomPath, "conf/gitignore", repoLang)
targetPath := path.Join(tmpDir, fileName["gitign"])
if com.IsFile(customPath) {
if err := com.Copy(customPath, targetPath); err != nil {
return fmt.Errorf("copy gitignore: %v", err)
}
} else if com.IsSliceContainsStr(Gitignores, repoLang) {
if err = ioutil.WriteFile(targetPath,
bindata.MustAsset(path.Join("conf/gitignore", repoLang)), os.ModePerm); err != nil {
return fmt.Errorf("generate gitignore: %v", err)
}
} else {
delete(fileName, "gitign")
}
// LICENSE
filePath = "conf/license/" + license
if com.IsFile(filePath) {
targetPath := path.Join(tmpDir, fileName["license"])
if com.IsFile(filePath) {
if err = com.Copy(filePath, targetPath); err != nil {
return err
}
} else {
// Check custom files.
filePath = path.Join(setting.CustomPath, "conf/license", license)
if com.IsFile(filePath) {
if err := com.Copy(filePath, targetPath); err != nil {
return err
}
}
customPath = path.Join(setting.CustomPath, "conf/license", license)
targetPath = path.Join(tmpDir, fileName["license"])
if com.IsFile(customPath) {
if err = com.Copy(customPath, targetPath); err != nil {
return fmt.Errorf("copy license: %v", err)
}
} else if com.IsSliceContainsStr(Licenses, license) {
if err = ioutil.WriteFile(targetPath,
bindata.MustAsset(path.Join("conf/license", license)), os.ModePerm); err != nil {
return fmt.Errorf("generate license: %v", err)
}
} else {
delete(fileName, "license")
@ -502,7 +486,7 @@ func initRepository(e Engine, f string, u *User, repo *Repository, initReadme bo
}
repo.IsBare = true
repo.DefaultBranch = "master"
return updateRepository(e, repo)
return updateRepository(e, repo, false)
}
// Apply changes and commit.
@ -734,7 +718,7 @@ func ChangeRepositoryName(userName, oldRepoName, newRepoName string) (err error)
return os.Rename(RepoPath(userName, oldRepoName), RepoPath(userName, newRepoName))
}
func updateRepository(e Engine, repo *Repository) error {
func updateRepository(e Engine, repo *Repository, visibilityChanged bool) (err error) {
repo.LowerName = strings.ToLower(repo.Name)
if len(repo.Description) > 255 {
@ -743,12 +727,40 @@ func updateRepository(e Engine, repo *Repository) error {
if len(repo.Website) > 255 {
repo.Website = repo.Website[:255]
}
_, err := e.Id(repo.Id).AllCols().Update(repo)
return err
if _, err = e.Id(repo.Id).AllCols().Update(repo); err != nil {
return fmt.Errorf("update: %v", err)
}
if visibilityChanged {
if err = repo.getOwner(e); err != nil {
return fmt.Errorf("getOwner: %v", err)
}
if !repo.Owner.IsOrganization() {
return nil
}
// Organization repository need to recalculate access table when visivility is changed.
if err = repo.recalculateTeamAccesses(e, 0); err != nil {
return fmt.Errorf("recalculateTeamAccesses: %v", err)
}
}
return nil
}
func UpdateRepository(repo *Repository) error {
return updateRepository(x, repo)
func UpdateRepository(repo *Repository, visibilityChanged bool) (err error) {
sess := x.NewSession()
defer sessionRelease(sess)
if err = sess.Begin(); err != nil {
return err
}
if err = updateRepository(x, repo, visibilityChanged); err != nil {
return fmt.Errorf("updateRepository: %v", err)
}
return sess.Commit()
}
// DeleteRepository deletes a repository for a user or organization.
@ -758,7 +770,7 @@ func DeleteRepository(uid, repoID int64, userName string) error {
if err != nil {
return err
} else if !has {
return ErrRepoNotExist
return ErrRepoNotExist{repoID, uid, ""}
}
// In case is a organization.
@ -792,9 +804,9 @@ func DeleteRepository(uid, repoID int64, userName string) error {
return err
} else if _, err = sess.Delete(&Access{RepoID: repo.Id}); err != nil {
return err
} else if _, err = sess.Delete(&Action{RepoId: repo.Id}); err != nil {
} else if _, err = sess.Delete(&Action{RepoID: repo.Id}); err != nil {
return err
} else if _, err = sess.Delete(&Watch{RepoId: repoID}); err != nil {
} else if _, err = sess.Delete(&Watch{RepoID: repoID}); err != nil {
return err
} else if _, err = sess.Delete(&Mirror{RepoId: repoID}); err != nil {
return err
@ -875,18 +887,18 @@ func GetRepositoryByName(uid int64, repoName string) (*Repository, error) {
if err != nil {
return nil, err
} else if !has {
return nil, ErrRepoNotExist
return nil, ErrRepoNotExist{0, uid, repoName}
}
return repo, err
}
func getRepositoryById(e Engine, id int64) (*Repository, error) {
repo := &Repository{}
repo := new(Repository)
has, err := e.Id(id).Get(repo)
if err != nil {
return nil, err
} else if !has {
return nil, ErrRepoNotExist
return nil, ErrRepoNotExist{id, 0, ""}
}
return repo, nil
}
@ -1163,9 +1175,9 @@ func (repo *Repository) DeleteCollaborator(u *User) (err error) {
// Watch is connection request for receiving repository notification.
type Watch struct {
Id int64
UserId int64 `xorm:"UNIQUE(watch)"`
RepoId int64 `xorm:"UNIQUE(watch)"`
ID int64 `xorm:"pk autoincr"`
UserID int64 `xorm:"UNIQUE(watch)"`
RepoID int64 `xorm:"UNIQUE(watch)"`
}
// IsWatching checks if user has watched given repository.
@ -1179,7 +1191,7 @@ func watchRepo(e Engine, uid, repoId int64, watch bool) (err error) {
if IsWatching(uid, repoId) {
return nil
}
if _, err = e.Insert(&Watch{RepoId: repoId, UserId: uid}); err != nil {
if _, err = e.Insert(&Watch{RepoID: repoId, UserID: uid}); err != nil {
return err
}
_, err = e.Exec("UPDATE `repository` SET num_watches = num_watches + 1 WHERE id = ?", repoId)
@ -1190,7 +1202,7 @@ func watchRepo(e Engine, uid, repoId int64, watch bool) (err error) {
if _, err = e.Delete(&Watch{0, uid, repoId}); err != nil {
return err
}
_, err = e.Exec("UPDATE `repository` SET num_watches = num_watches - 1 WHERE id = ?", repoId)
_, err = e.Exec("UPDATE `repository` SET num_watches=num_watches-1 WHERE id=?", repoId)
}
return err
}
@ -1202,7 +1214,7 @@ func WatchRepo(uid, repoId int64, watch bool) (err error) {
func getWatchers(e Engine, rid int64) ([]*Watch, error) {
watches := make([]*Watch, 0, 10)
err := e.Find(&watches, &Watch{RepoId: rid})
err := e.Find(&watches, &Watch{RepoID: rid})
return watches, err
}
@ -1213,24 +1225,24 @@ func GetWatchers(rid int64) ([]*Watch, error) {
func notifyWatchers(e Engine, act *Action) error {
// Add feeds for user self and all watchers.
watches, err := getWatchers(e, act.RepoId)
watches, err := getWatchers(e, act.RepoID)
if err != nil {
return fmt.Errorf("get watchers: %v", err)
}
// Add feed for actioner.
act.UserId = act.ActUserId
act.UserID = act.ActUserID
if _, err = e.InsertOne(act); err != nil {
return fmt.Errorf("insert new actioner: %v", err)
}
for i := range watches {
if act.ActUserId == watches[i].UserId {
if act.ActUserID == watches[i].UserID {
continue
}
act.Id = 0
act.UserId = watches[i].UserId
act.ID = 0
act.UserID = watches[i].UserID
if _, err = e.InsertOne(act); err != nil {
return fmt.Errorf("insert new action: %v", err)
}
@ -1377,5 +1389,9 @@ func ForkRepository(u *User, oldRepo *Repository, name, desc string) (_ *Reposit
return nil, fmt.Errorf("git update-server-info: %v", err)
}
if err = createUpdateHook(repoPath); err != nil {
return nil, fmt.Errorf("createUpdateHook: %v", err)
}
return repo, sess.Commit()
}

@ -36,8 +36,6 @@ const (
)
var (
ErrUserOwnRepos = errors.New("User still have ownership of repositories")
ErrUserHasOrgs = errors.New("User still have membership of organization")
ErrUserAlreadyExist = errors.New("User already exist")
ErrUserNotExist = errors.New("User does not exist")
ErrUserNotKeyOwner = errors.New("User does not the owner of public key")
@ -124,7 +122,7 @@ func (u *User) AvatarLink() string {
switch {
case u.UseCustomAvatar:
return setting.AppSubUrl + "/avatars/" + com.ToStr(u.Id)
case setting.DisableGravatar:
case setting.DisableGravatar, setting.OfflineMode:
return setting.AppSubUrl + "/img/avatar_default.jpg"
case setting.Service.EnableCacheAvatar:
return setting.AppSubUrl + "/avatar/" + u.Avatar
@ -432,55 +430,75 @@ func UpdateUser(u *User) error {
return err
}
// DeleteBeans deletes all given beans, beans should contain delete conditions.
func DeleteBeans(e Engine, beans ...interface{}) (err error) {
for i := range beans {
if _, err = e.Delete(beans[i]); err != nil {
return err
}
}
return nil
}
// FIXME: need some kind of mechanism to record failure. HINT: system notice
// DeleteUser completely and permanently deletes everything of user.
func DeleteUser(u *User) error {
// Check ownership of repository.
count, err := GetRepositoryCount(u)
if err != nil {
return errors.New("GetRepositoryCount: " + err.Error())
return fmt.Errorf("GetRepositoryCount: %v", err)
} else if count > 0 {
return ErrUserOwnRepos
return ErrUserOwnRepos{UID: u.Id}
}
// Check membership of organization.
count, err = u.GetOrganizationCount()
if err != nil {
return errors.New("GetOrganizationCount: " + err.Error())
return fmt.Errorf("GetOrganizationCount: %v", err)
} else if count > 0 {
return ErrUserHasOrgs
return ErrUserHasOrgs{UID: u.Id}
}
// FIXME: check issues, other repos' commits
// FIXME: roll backable in some point.
// Delete all followers.
if _, err = x.Delete(&Follow{FollowId: u.Id}); err != nil {
return err
// Get watches before session.
watches := make([]*Watch, 0, 10)
if err = x.Where("user_id=?", u.Id).Find(&watches); err != nil {
return fmt.Errorf("get all watches: %v", err)
}
// Delete oauth2.
if _, err = x.Delete(&Oauth2{Uid: u.Id}); err != nil {
return err
repoIDs := make([]int64, 0, len(watches))
for i := range watches {
repoIDs = append(repoIDs, watches[i].RepoID)
}
// Delete all feeds.
if _, err = x.Delete(&Action{UserId: u.Id}); err != nil {
return err
}
// Delete all watches.
if _, err = x.Delete(&Watch{UserId: u.Id}); err != nil {
// FIXME: check issues, other repos' commits
sess := x.NewSession()
defer sessionRelease(sess)
if err = sess.Begin(); err != nil {
return err
}
// Delete all accesses.
if _, err = x.Delete(&Access{UserID: u.Id}); err != nil {
if err = DeleteBeans(sess,
&Follow{FollowID: u.Id},
&Oauth2{Uid: u.Id},
&Action{UserID: u.Id},
&Access{UserID: u.Id},
&Collaboration{UserID: u.Id},
&EmailAddress{Uid: u.Id},
&Watch{UserID: u.Id},
); err != nil {
return err
}
// Delete all alternative email addresses
if _, err = x.Delete(&EmailAddress{Uid: u.Id}); err != nil {
return err
// Decrease all watch numbers.
for i := range repoIDs {
if _, err = sess.Exec("UPDATE `repository` SET num_watches=num_watches-1 WHERE id=?", repoIDs[i]); err != nil {
return err
}
}
// Delete all SSH keys.
keys := make([]*PublicKey, 0, 10)
if err = x.Find(&keys, &PublicKey{OwnerId: u.Id}); err != nil {
if err = sess.Find(&keys, &PublicKey{OwnerId: u.Id}); err != nil {
return err
}
for _, key := range keys {
@ -489,13 +507,16 @@ func DeleteUser(u *User) error {
}
}
if _, err = sess.Delete(u); err != nil {
return err
}
// Delete user directory.
if err = os.RemoveAll(UserPath(u.Name)); err != nil {
return err
}
_, err = x.Delete(u)
return err
return sess.Commit()
}
// DeleteInactivateUsers deletes all inactivate users and email addresses.
@ -777,8 +798,8 @@ func SearchUserByName(opt SearchOption) (us []*User, err error) {
// Follow is connection request for receiving user notification.
type Follow struct {
Id int64
UserId int64 `xorm:"unique(follow)"`
FollowId int64 `xorm:"unique(follow)"`
UserID int64 `xorm:"unique(follow)"`
FollowID int64 `xorm:"unique(follow)"`
}
// FollowUser marks someone be another's follower.
@ -787,7 +808,7 @@ func FollowUser(userId int64, followId int64) (err error) {
defer sess.Close()
sess.Begin()
if _, err = sess.Insert(&Follow{UserId: userId, FollowId: followId}); err != nil {
if _, err = sess.Insert(&Follow{UserID: userId, FollowID: followId}); err != nil {
sess.Rollback()
return err
}
@ -812,7 +833,7 @@ func UnFollowUser(userId int64, unFollowId int64) (err error) {
defer session.Close()
session.Begin()
if _, err = session.Delete(&Follow{UserId: userId, FollowId: unFollowId}); err != nil {
if _, err = session.Delete(&Follow{UserID: userId, FollowID: unFollowId}); err != nil {
session.Rollback()
return err
}

@ -205,7 +205,7 @@ func IsValidHookTaskType(name string) bool {
type HookEventType string
const (
PUSH HookEventType = "push"
HOOK_EVENT_PUSH HookEventType = "push"
)
// FIXME: just use go-gogs-client structs maybe?

@ -11,15 +11,15 @@ import (
)
type AdminEditUserForm struct {
Email string `form:"email" binding:"Required;Email;MaxSize(50)"`
Passwd string `form:"password"`
Website string `form:"website" binding:"MaxSize(50)"`
Location string `form:"location" binding:"MaxSize(50)"`
Avatar string `form:"avatar" binding:"Required;Email;MaxSize(50)"`
Active bool `form:"active"`
Admin bool `form:"admin"`
AllowGitHook bool `form:"allow_git_hook"`
LoginType int `form:"login_type"`
Email string `binding:"Required;Email;MaxSize(50)"`
Password string `binding:"OmitEmpty;MinSize(6);MaxSize(255)"`
Website string `binding:"MaxSize(50)"`
Location string `binding:"MaxSize(50)"`
Avatar string `binding:"Required;Email;MaxSize(50)"`
Active bool
Admin bool
AllowGitHook bool
LoginType int
}
func (f *AdminEditUserForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {

@ -32,13 +32,13 @@ func (f *CreateRepoForm) Validate(ctx *macaron.Context, errs binding.Errors) bin
type MigrateRepoForm struct {
CloneAddr string `binding:"Required"`
AuthUserName string `form:"auth_username"`
AuthPasswd string `form:"auth_password"`
Uid int64 `form:"uid" binding:"Required"`
RepoName string `form:"repo_name" binding:"Required;AlphaDashDot;MaxSize(100)"`
Mirror bool `form:"mirror"`
Private bool `form:"private"`
Description string `form:"desc" binding:"MaxSize(255)"`
AuthUsername string
AuthPassword string
Uid int64 `binding:"Required"`
RepoName string `binding:"Required;AlphaDashDot;MaxSize(100)"`
Mirror bool
Private bool
Description string `binding:"MaxSize(255)"`
}
func (f *MigrateRepoForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {

@ -171,7 +171,7 @@ func CreateTimeLimitCode(data string, minutes int, startInf interface{}) string
// AvatarLink returns avatar link by given e-mail.
func AvatarLink(email string) string {
if setting.DisableGravatar {
if setting.DisableGravatar || setting.OfflineMode {
return setting.AppSubUrl + "/img/avatar_default.jpg"
}

File diff suppressed because one or more lines are too long

@ -88,11 +88,11 @@ func (c *Commit) GetCommitOfRelPath(relPath string) (*Commit, error) {
}
func (c *Commit) GetSubModule(entryname string) (*SubModule, error) {
moduels, err := c.GetSubModules()
modules, err := c.GetSubModules()
if err != nil {
return nil, err
}
return moduels[entryname], nil
return modules[entryname], nil
}
func (c *Commit) GetSubModules() (map[string]*SubModule, error) {

@ -31,6 +31,10 @@ func NewSubModuleFile(c *Commit, refUrl, refId string) *SubModuleFile {
// RefUrl guesses and returns reference URL.
func (sf *SubModuleFile) RefUrl() string {
if sf.refUrl == "" {
return ""
}
url := strings.TrimSuffix(sf.refUrl, ".git")
// git://xxx/user/repo

@ -163,7 +163,7 @@ func SendIssueNotifyMail(u, owner *models.User, repo *models.Repository, issue *
tos := make([]string, 0, len(ws))
for i := range ws {
uid := ws[i].UserId
uid := ws[i].UserID
if u.Id == uid {
continue
}

@ -30,7 +30,7 @@ func Toggle(options *ToggleOptions) macaron.Handler {
// Checking non-logged users landing page.
if !ctx.IsSigned && ctx.Req.RequestURI == "/" && setting.LandingPageUrl != setting.LANDING_PAGE_HOME {
ctx.Redirect(string(setting.LandingPageUrl))
ctx.Redirect(setting.AppSubUrl + string(setting.LandingPageUrl))
return
}

@ -47,7 +47,7 @@ func ApiRepoAssignment() macaron.Handler {
// Get repository.
repo, err := models.GetRepositoryByName(u.Id, repoName)
if err != nil {
if err == models.ErrRepoNotExist {
if models.IsErrRepoNotExist(err) {
ctx.Error(404)
} else {
ctx.JSON(500, &base.ApiJsonErr{"GetRepositoryByName: " + err.Error(), base.DOC_URL})
@ -223,7 +223,7 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
// Get repository.
repo, err := models.GetRepositoryByName(u.Id, repoName)
if err != nil {
if err == models.ErrRepoNotExist {
if models.IsErrRepoNotExist(err) {
ctx.Handle(404, "GetRepositoryByName", err)
} else {
ctx.Handle(500, "GetRepositoryByName", err)

@ -20,6 +20,7 @@ import (
"github.com/macaron-contrib/session"
"gopkg.in/ini.v1"
"github.com/gogits/gogs/modules/bindata"
"github.com/gogits/gogs/modules/log"
// "github.com/gogits/gogs/modules/ssh"
)
@ -131,7 +132,6 @@ var (
// Global setting objects.
Cfg *ini.File
ConfRootPath string
CustomPath string // Custom directory path.
CustomConf string
ProdMode bool
@ -163,6 +163,12 @@ func WorkDir() (string, error) {
return path.Dir(strings.Replace(execPath, "\\", "/", -1)), err
}
func forcePathSeparator(path string) {
if strings.Contains(path, "\\") {
log.Fatal(4, "Do not use '\\' or '\\\\' in paths, instead, please use '/' in all places")
}
}
// NewConfigContext initializes configuration context.
// NOTE: do not print any log except error.
func NewConfigContext() {
@ -170,9 +176,8 @@ func NewConfigContext() {
if err != nil {
log.Fatal(4, "Fail to get work directory: %v", err)
}
ConfRootPath = path.Join(workDir, "conf")
Cfg, err = ini.Load(path.Join(workDir, "conf/app.ini"))
Cfg, err = ini.Load(bindata.MustAsset("conf/app.ini"))
if err != nil {
log.Fatal(4, "Fail to parse 'conf/app.ini': %v", err)
}
@ -196,6 +201,7 @@ func NewConfigContext() {
Cfg.NameMapper = ini.AllCapsUnderscore
LogRootPath = Cfg.Section("log").Key("ROOT_PATH").MustString(path.Join(workDir, "log"))
forcePathSeparator(LogRootPath)
sec := Cfg.Section("server")
AppName = Cfg.Section("").Key("APP_NAME").MustString("Gogs: Go Git Service")
@ -287,18 +293,22 @@ func NewConfigContext() {
if err != nil {
log.Fatal(4, "Fail to get home directory: %v", err)
}
homeDir = strings.Replace(homeDir, "\\", "/", -1)
sec = Cfg.Section("repository")
RepoRootPath = sec.Key("ROOT").MustString(filepath.Join(homeDir, "gogs-repositories"))
RepoRootPath = sec.Key("ROOT").MustString(path.Join(homeDir, "gogs-repositories"))
forcePathSeparator(RepoRootPath)
if !filepath.IsAbs(RepoRootPath) {
RepoRootPath = filepath.Join(workDir, RepoRootPath)
RepoRootPath = path.Join(workDir, RepoRootPath)
} else {
RepoRootPath = filepath.Clean(RepoRootPath)
RepoRootPath = path.Clean(RepoRootPath)
}
ScriptType = sec.Key("SCRIPT_TYPE").MustString("bash")
sec = Cfg.Section("picture")
PictureService = sec.Key("SERVICE").In("server", []string{"server"})
AvatarUploadPath = sec.Key("AVATAR_UPLOAD_PATH").MustString("data/avatars")
forcePathSeparator(AvatarUploadPath)
if !filepath.IsAbs(AvatarUploadPath) {
AvatarUploadPath = path.Join(workDir, AvatarUploadPath)
}
@ -341,7 +351,7 @@ func newService() {
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()
Service.EnableReverseProxyAutoRegister = Cfg.Section("service").Key("ENABLE_REVERSE_PROXY_AUTO_REGISTERATION").MustBool()
Service.EnableReverseProxyAutoRegister = Cfg.Section("service").Key("ENABLE_REVERSE_PROXY_AUTO_REGISTRATION").MustBool()
}
var logLevels = map[string]string{

@ -732,7 +732,8 @@ ol.linenums {
#dashboard-header > .menu-line > li.right > a {
font-size: 1.2em;
color: #444444;
padding: .4em .8em;
margin: -12px 0px;
padding: 22px 0.8em;
}
#dashboard-header > .menu-line > li.right > a:hover {
background-color: transparent;
@ -2413,6 +2414,35 @@ textarea#issue-add-content {
#milestone-list .action-bar a {
margin-left: 12px;
}
.issues.list-group {
margin: 10px 0 20px 0;
}
.issues.list-group > .list-group-item {
background-color: #FFF;
border: 1px solid #e5e5e5;
display: block;
padding: 10px 15px;
margin-bottom: -1px;
}
.issues.list-group > .list-group-item:hover {
background-color: rgba(19, 95, 215, 0.03);
}
.issues.list-group > .list-group-item > .title {
margin-bottom: 16px;
font-weight: bold;
font-size: 1.2em;
}
.issues.list-group > .list-group-item > .title > a {
color: #444;
}
.issues.list-group > .list-group-item > .info span {
margin-right: 12px;
color: #888;
line-height: 20px;
}
.issues.list-group > .list-group-item > .info span > a {
color: #444;
}
.org-header-alert .alert {
margin-top: 10px;
}

@ -188,7 +188,8 @@ input:focus,
background-color: #f2fffc;
outline: none;
}
button {
button,
.btn {
overflow: visible;
padding: .6em 1.2em;
}
@ -431,6 +432,19 @@ dt {
background-color: #fafafa;
color: #444444;
}
.btn-white {
background-color: #ffffff;
color: #444444;
border: 1px solid #c6c6c6;
}
.btn-white:hover {
background-color: #e8e8e8;
color: #444444;
}
.btn-white.active {
background-color: #e8e8e8;
color: #444444;
}
.btn-active {
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1) inset, 0 0 4px rgba(0, 0, 0, 0.15) inset;
}
@ -475,6 +489,22 @@ dt {
background-image: none !important;
color: #ffffff;
}
.btn-group {
display: inline-block;
}
.btn-group > .btn {
position: relative;
float: left;
margin-right: -1px;
}
.btn-group > .btn:first-child {
border-bottom-left-radius: .25em;
border-top-left-radius: .25em;
}
.btn-group > .btn:last-child {
border-bottom-right-radius: .25em;
border-top-right-radius: .25em;
}
.ipt:focus {
border-color: #428bca;
}
@ -550,6 +580,10 @@ ul.menu > li > a:hover {
background-color: #eaeaea;
color: #444444;
}
ul.menu > li > a.active {
background-color: #4183c4;
color: #FFF;
}
ul.menu > li.current > a,
ul.menu > li.hover > a {
color: #444444;
@ -597,6 +631,7 @@ ul.menu-vertical > li.head,
ul.menu-down > li.head {
display: block;
padding: .4em 1.2em;
margin-bottom: 4px;
}
ul.menu-vertical > li.down,
ul.menu-down > li.down {

@ -27,7 +27,8 @@
> a {
font-size: 1.2em;
color: @dashboardHeaderLinkColor;
padding: .4em .8em;
margin: -12px 0px;
padding: 22px 0.8em;
&:hover {
background-color: transparent;
color: @dashboardHeaderLinkHoverColor;

@ -511,4 +511,30 @@ textarea#issue-add-content {
margin-left: 12px;
}
}
}
}
.issues.list-group {
margin: 10px 0 20px 0;
> .list-group-item {
background-color: #FFF;
border: 1px solid #e5e5e5;
display: block;
padding: 10px 15px;
margin-bottom: -1px;
&:hover {
background-color: rgba(19, 95, 215, 0.03);
}
> .title {
margin-bottom: 16px;
font-weight: bold;
font-size: 1.2em;
> a { color: #444; }
}
> .info span {
margin-right: 12px;
color: #888;
line-height: 20px;
> a { color: #444; }
}
}
}

@ -70,6 +70,19 @@
}
}
.btn-white {
background-color: @btnWhiteColor;
color: @baseFontColor;
border: 1px solid @btnWhiteBorderColor;
&:hover {
background-color: @btnWhiteHoverColor;
color: @baseFontColor;
}
&.active {
background-color: @btnWhiteHoverColor;
color: @baseFontColor;
}
}
// status buttons
.btn-active {
@ -118,6 +131,22 @@
}
}
.btn-group {
display: inline-block;
> .btn {
position: relative;
float: left;
margin-right: -1px;
&:first-child{
border-bottom-left-radius: .25em;
border-top-left-radius: .25em;
}
&:last-child{
border-bottom-right-radius: .25em;
border-top-right-radius: .25em;
}
}
}
// input form elements
.ipt {
&:focus {
@ -198,4 +227,4 @@ label {
color: @labelRedColor;
}
}
}
}

@ -11,6 +11,10 @@ ul.menu {
background-color: @lineMenuHoverBgColor;
color: @lineMenuHoverFontColor;
}
&.active {
background-color: #4183c4;
color: #FFF;
}
}
&.current > a,
&.hover > a {
@ -67,6 +71,7 @@ ul.menu-down {
> li.head {
display: block;
padding: .4em 1.2em;
margin-bottom: 4px;
}
> li.down {
position: relative;
@ -163,4 +168,4 @@ ul.menu-radius {
content: "\25B4";
margin-left: .4em;
}
}
}

@ -238,7 +238,7 @@ input,
}
}
button {
button,.btn {
overflow: visible;
padding: .6em 1.2em;
}
@ -365,4 +365,4 @@ pre {
dt {
font-weight: bold;
}
}

@ -45,6 +45,10 @@
@btnGrayHoverColor: #FAFAFA;
@btnGrayBorderColor: #D0D0D0;
@btnWhiteColor: #FFF;
@btnWhiteHoverColor: #e8e8e8;
@btnWhiteBorderColor: #c6c6c6;
@lineMenuHoverBgColor: #EAEAEA;
@lineMenuHoverFontColor: #444;

@ -168,6 +168,7 @@ func EditUserPost(ctx *middleware.Context, form auth.AdminEditUserForm) {
ctx.Handle(500, "GetUserById", err)
return
}
ctx.Data["User"] = u
if ctx.HasError() {
ctx.HTML(200, USER_EDIT)
@ -175,8 +176,8 @@ func EditUserPost(ctx *middleware.Context, form auth.AdminEditUserForm) {
}
// FIXME: need password length check
if len(form.Passwd) > 0 {
u.Passwd = form.Passwd
if len(form.Password) > 0 {
u.Passwd = form.Password
u.Salt = models.GetUserSalt()
u.EncodePasswd()
}
@ -193,8 +194,6 @@ func EditUserPost(ctx *middleware.Context, form auth.AdminEditUserForm) {
u.IsAdmin = form.Admin
u.AllowGitHook = form.AllowGitHook
ctx.Data["User"] = u
if err := models.UpdateUser(u); err != nil {
if err == models.ErrEmailAlreadyUsed {
ctx.Data["Err_Email"] = true
@ -223,11 +222,11 @@ func DeleteUser(ctx *middleware.Context) {
}
if err = models.DeleteUser(u); err != nil {
switch err {
case models.ErrUserOwnRepos:
switch {
case models.IsErrUserOwnRepos(err):
ctx.Flash.Error(ctx.Tr("admin.users.still_own_repo"))
ctx.Redirect(setting.AppSubUrl + "/admin/users/" + ctx.Params(":userid"))
case models.ErrUserHasOrgs:
case models.IsErrUserHasOrgs(err):
ctx.Flash.Error(ctx.Tr("admin.users.still_has_org"))
ctx.Redirect(setting.AppSubUrl + "/admin/users/" + ctx.Params(":userid"))
default:

@ -196,7 +196,7 @@ func MigrateRepo(ctx *middleware.Context, form auth.MigrateRepoForm) {
}
}
// Remote address can be HTTPS URL or local path.
// Remote address can be HTTP/HTTPS URL or local path.
remoteAddr := form.CloneAddr
if strings.HasPrefix(form.CloneAddr, "http") {
u, err := url.Parse(form.CloneAddr)
@ -204,8 +204,8 @@ func MigrateRepo(ctx *middleware.Context, form auth.MigrateRepoForm) {
ctx.HandleAPI(422, err)
return
}
if len(form.AuthUserName) > 0 || len(form.AuthPasswd) > 0 {
u.User = url.UserPassword(form.AuthUserName, form.AuthPasswd)
if len(form.AuthUsername) > 0 || len(form.AuthPassword) > 0 {
u.User = url.UserPassword(form.AuthUsername, form.AuthPassword)
}
remoteAddr = u.String()
} else if !com.IsDir(remoteAddr) {

@ -61,14 +61,14 @@ func MembersAction(ctx *middleware.Context) {
return
}
err = org.RemoveMember(uid)
if err == models.ErrLastOrgOwner {
if models.IsErrLastOrgOwner(err) {
ctx.Flash.Error(ctx.Tr("form.last_org_owner"))
ctx.Redirect(ctx.Org.OrgLink + "/members")
return
}
case "leave":
err = org.RemoveMember(ctx.User.Id)
if err == models.ErrLastOrgOwner {
if models.IsErrLastOrgOwner(err) {
ctx.Flash.Error(ctx.Tr("form.last_org_owner"))
ctx.Redirect(ctx.Org.OrgLink + "/members")
return

@ -87,13 +87,12 @@ func SettingsDelete(ctx *middleware.Context) {
org := ctx.Org.Organization
if ctx.Req.Method == "POST" {
// TODO: validate password.
// FIXME: validate password.
if err := models.DeleteOrganization(org); err != nil {
switch err {
case models.ErrUserOwnRepos:
if models.IsErrUserOwnRepos(err) {
ctx.Flash.Error(ctx.Tr("form.org_still_own_repo"))
ctx.Redirect(setting.AppSubUrl + "/org/" + org.LowerName + "/settings/delete")
default:
} else {
ctx.Handle(500, "DeleteOrganization", err)
}
} else {

@ -91,7 +91,7 @@ func TeamsAction(ctx *middleware.Context) {
}
if err != nil {
if err == models.ErrLastOrgOwner {
if models.IsErrLastOrgOwner(err) {
ctx.Flash.Error(ctx.Tr("form.last_org_owner"))
} else {
log.Error(3, "Action(%s): %v", ctx.Params(":action"), err)
@ -124,7 +124,7 @@ func TeamsRepoAction(ctx *middleware.Context) {
var repo *models.Repository
repo, err = models.GetRepositoryByName(ctx.Org.Organization.Id, repoName)
if err != nil {
if err == models.ErrRepoNotExist {
if models.IsErrRepoNotExist(err) {
ctx.Flash.Error(ctx.Tr("org.teams.add_nonexistent_repo"))
ctx.Redirect(ctx.Org.OrgLink + "/teams/" + ctx.Org.Team.LowerName + "/repositories")
return

@ -65,7 +65,7 @@ func Http(ctx *middleware.Context) {
repo, err := models.GetRepositoryByName(repoUser.Id, reponame)
if err != nil {
if err == models.ErrRepoNotExist {
if models.IsErrRepoNotExist(err) {
ctx.Handle(404, "GetRepositoryByName", nil)
} else {
ctx.Handle(500, "GetRepositoryByName", err)
@ -105,7 +105,7 @@ func Http(ctx *middleware.Context) {
return
}
authUser, err := models.UserSignIn(authUsername, authPasswd)
authUser, err = models.UserSignIn(authUsername, authPasswd)
if err != nil {
if err != models.ErrUserNotExist {
ctx.Handle(500, "UserSignIn error: %v", err)
@ -160,7 +160,7 @@ func Http(ctx *middleware.Context) {
}
}
var f = func(rpc string, input []byte) {
callback := func(rpc string, input []byte) {
if rpc == "receive-pack" {
var lastLine int64 = 0
@ -189,6 +189,7 @@ func Http(ctx *middleware.Context) {
newCommitId := fields[1]
refName := fields[2]
// FIXME: handle error.
models.Update(refName, oldCommitId, newCommitId, authUsername, username, reponame, authUser.Id)
}
lastLine = lastLine + size
@ -199,25 +200,23 @@ func Http(ctx *middleware.Context) {
}
}
config := Config{setting.RepoRootPath, "git", true, true, f}
HTTPBackend(&Config{
RepoRootPath: setting.RepoRootPath,
GitBinPath: "git",
UploadPack: true,
ReceivePack: true,
OnSucceed: callback,
})(ctx.Resp, ctx.Req.Request)
handler := HttpBackend(&config)
handler(ctx.Resp, ctx.Req.Request)
runtime.GC()
}
type route struct {
cr *regexp.Regexp
method string
handler func(handler)
}
type Config struct {
ReposRoot string
GitBinPath string
UploadPack bool
ReceivePack bool
OnSucceed func(rpc string, input []byte)
RepoRootPath string
GitBinPath string
UploadPack bool
ReceivePack bool
OnSucceed func(rpc string, input []byte)
}
type handler struct {
@ -228,6 +227,12 @@ type handler struct {
File string
}
type route struct {
cr *regexp.Regexp
method string
handler func(handler)
}
var routes = []route{
{regexp.MustCompile("(.*?)/git-upload-pack$"), "POST", serviceUploadPack},
{regexp.MustCompile("(.*?)/git-receive-pack$"), "POST", serviceReceivePack},
@ -243,7 +248,7 @@ var routes = []route{
}
// Request handling function
func HttpBackend(config *Config) http.HandlerFunc {
func HTTPBackend(config *Config) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
for _, route := range routes {
r.URL.Path = strings.ToLower(r.URL.Path) // blue: In case some repo name has upper case name
@ -285,8 +290,7 @@ func serviceReceivePack(hr handler) {
func serviceRpc(rpc string, hr handler) {
w, r, dir := hr.w, hr.r, hr.Dir
access := hasAccess(r, hr.Config, dir, rpc, true)
if access == false {
if !hasAccess(r, hr.Config, dir, rpc, true) {
renderNoAccess(w)
return
}
@ -337,7 +341,6 @@ func serviceRpc(rpc string, hr handler) {
if hr.Config.OnSucceed != nil {
hr.Config.OnSucceed(rpc, input)
}
w.WriteHeader(http.StatusOK)
}
func getInfoRefs(hr handler) {
@ -408,7 +411,7 @@ func sendFile(contentType string, hr handler) {
}
func getGitDir(config *Config, fPath string) (string, error) {
root := config.ReposRoot
root := config.RepoRootPath
if root == "" {
cwd, err := os.Getwd()

@ -270,12 +270,12 @@ func CreateIssuePost(ctx *middleware.Context, form auth.CreateIssueForm) {
}
act := &models.Action{
ActUserId: ctx.User.Id,
ActUserID: ctx.User.Id,
ActUserName: ctx.User.Name,
ActEmail: ctx.User.Email,
OpType: models.CREATE_ISSUE,
Content: fmt.Sprintf("%d|%s", issue.Index, issue.Name),
RepoId: ctx.Repo.Repository.Id,
RepoID: ctx.Repo.Repository.Id,
RepoUserName: ctx.Repo.Owner.Name,
RepoName: ctx.Repo.Repository.Name,
RefName: ctx.Repo.BranchName,
@ -845,12 +845,12 @@ func Comment(ctx *middleware.Context) {
// Notify watchers.
act := &models.Action{
ActUserId: ctx.User.Id,
ActUserID: ctx.User.Id,
ActUserName: ctx.User.LowerName,
ActEmail: ctx.User.Email,
OpType: models.COMMENT_ISSUE,
Content: fmt.Sprintf("%d|%s", issue.Index, strings.Split(content, "\n")[0]),
RepoId: ctx.Repo.Repository.Id,
RepoID: ctx.Repo.Repository.Id,
RepoUserName: ctx.Repo.Owner.LowerName,
RepoName: ctx.Repo.Repository.LowerName,
}

@ -181,7 +181,7 @@ func MigratePost(ctx *middleware.Context, form auth.MigrateRepoForm) {
}
}
// Remote address can be HTTPS URL or local path.
// Remote address can be HTTP/HTTPS URL or local path.
remoteAddr := form.CloneAddr
if strings.HasPrefix(form.CloneAddr, "http") {
u, err := url.Parse(form.CloneAddr)
@ -190,8 +190,8 @@ func MigratePost(ctx *middleware.Context, form auth.MigrateRepoForm) {
ctx.RenderWithErr(ctx.Tr("form.url_error"), MIGRATE, &form)
return
}
if len(form.AuthUserName) > 0 || len(form.AuthPasswd) > 0 {
u.User = url.UserPassword(form.AuthUserName, form.AuthPasswd)
if len(form.AuthUsername) > 0 || len(form.AuthPassword) > 0 {
u.User = url.UserPassword(form.AuthUsername, form.AuthPassword)
}
remoteAddr = u.String()
} else if !com.IsDir(remoteAddr) {
@ -251,7 +251,7 @@ func Fork(ctx *middleware.Context) {
ctx.Data["Title"] = ctx.Tr("new_fork")
if _, err := getForkRepository(ctx); err != nil {
if err == models.ErrRepoNotExist {
if models.IsErrRepoNotExist(err) {
ctx.Redirect(setting.AppSubUrl + "/")
} else {
ctx.Handle(500, "getForkRepository", err)
@ -275,7 +275,7 @@ func ForkPost(ctx *middleware.Context, form auth.CreateRepoForm) {
forkRepo, err := getForkRepository(ctx)
if err != nil {
if err == models.ErrRepoNotExist {
if models.IsErrRepoNotExist(err) {
ctx.Redirect(setting.AppSubUrl + "/")
} else {
ctx.Handle(500, "getForkRepository", err)
@ -356,7 +356,7 @@ func Action(ctx *middleware.Context) {
ctx.Repo.Repository.Description = ctx.Query("desc")
ctx.Repo.Repository.Website = ctx.Query("site")
err = models.UpdateRepository(ctx.Repo.Repository)
err = models.UpdateRepository(ctx.Repo.Repository, false)
}
if err != nil {

@ -78,8 +78,9 @@ func SettingsPost(ctx *middleware.Context, form auth.RepoSettingForm) {
}
ctx.Repo.Repository.Description = form.Description
ctx.Repo.Repository.Website = form.Website
visibilityChanged := ctx.Repo.Repository.IsPrivate != form.Private
ctx.Repo.Repository.IsPrivate = form.Private
if err := models.UpdateRepository(ctx.Repo.Repository); err != nil {
if err := models.UpdateRepository(ctx.Repo.Repository, visibilityChanged); err != nil {
ctx.Handle(404, "UpdateRepository", err)
return
}

@ -141,13 +141,17 @@ func Home(ctx *middleware.Context) {
ctx.Handle(500, "GetSubModule", err)
return
}
smUrl := ""
if sm != nil {
smUrl = sm.Url
}
c, err := ctx.Repo.Commit.GetCommitOfRelPath(filepath.Join(treePath, te.Name()))
if err != nil {
ctx.Handle(500, "GetCommitOfRelPath", err)
return
}
files = append(files, []interface{}{te, git.NewSubModuleFile(c, sm.Url, te.Id.String())})
files = append(files, []interface{}{te, git.NewSubModuleFile(c, smUrl, te.Id.String())})
}
}
ctx.Data["Files"] = files

@ -104,7 +104,7 @@ func Dashboard(ctx *middleware.Context) {
for _, act := range actions {
if act.IsPrivate {
// This prevents having to retrieve the repository for each action
repo := &models.Repository{Id: act.RepoId, IsPrivate: true}
repo := &models.Repository{Id: act.RepoID, IsPrivate: true}
if act.RepoUserName != ctx.User.LowerName {
if has, _ := models.HasAccess(ctx.User, repo, models.ACCESS_MODE_READ); !has {
continue
@ -216,7 +216,7 @@ func Profile(ctx *middleware.Context) {
continue
}
// This prevents having to retrieve the repository for each action
repo := &models.Repository{Id: act.RepoId, IsPrivate: true}
repo := &models.Repository{Id: act.RepoID, IsPrivate: true}
if act.RepoUserName != ctx.User.LowerName {
if has, _ := models.HasAccess(ctx.User, repo, models.ACCESS_MODE_READ); !has {
continue
@ -261,8 +261,10 @@ func Email2User(ctx *middleware.Context) {
ctx.Redirect(setting.AppSubUrl + "/user/" + u.Name)
}
func Issues(ctx *middleware.Context) {
ctx.Data["Title"] = "Your Issues"
func Issues(ctx *middleware.Context) {
ctx.Data["Title"] = ctx.Tr("issues")
ctx.Data["PageIsDashboard"] = true
ctx.Data["PageIsIssues"] = true
viewType := ctx.Query("type")
types := []string{"assigned", "created_by"}
@ -354,7 +356,7 @@ func Issues(ctx *middleware.Context) {
issues[i].Repo, err = models.GetRepositoryById(issues[i].RepoId)
if err != nil {
if err == models.ErrRepoNotExist {
if models.IsErrRepoNotExist(err) {
log.Warn("user.Issues(GetRepositoryById #%d): repository not exist", issues[i].RepoId)
continue
} else {
@ -386,5 +388,8 @@ func Issues(ctx *middleware.Context) {
} else {
ctx.Data["ShowCount"] = issueStats.OpenCount
}
ctx.Data["ContextUser"] = ctx.User
ctx.HTML(200, ISSUES)
}

@ -218,7 +218,7 @@ func SettingsEmailPost(ctx *middleware.Context, form auth.AddEmailForm) {
if err := ctx.Cache.Put("MailResendLimit_"+ctx.User.LowerName, ctx.User.LowerName, 180); err != nil {
log.Error(4, "Set cache(MailResendLimit) fail: %v", err)
}
ctx.Flash.Success(ctx.Tr("settings.add_email_success_confirmation_email_sent"))
ctx.Flash.Info(ctx.Tr("settings.add_email_confirmation_sent", cleanEmail, setting.Service.ActiveCodeLives/60))
} else {
ctx.Flash.Success(ctx.Tr("settings.add_email_success"))
}
@ -451,20 +451,13 @@ func SettingsDelete(ctx *middleware.Context) {
ctx.Data["PageIsSettingsDelete"] = true
if ctx.Req.Method == "POST" {
// tmpUser := models.User{
// Passwd: ctx.Query("password"),
// Salt: ctx.User.Salt,
// }
// tmpUser.EncodePasswd()
// if tmpUser.Passwd != ctx.User.Passwd {
// ctx.Flash.Error("Password is not correct. Make sure you are owner of this account.")
// } else {
// FIXME: validate password.
if err := models.DeleteUser(ctx.User); err != nil {
switch err {
case models.ErrUserOwnRepos:
switch {
case models.IsErrUserOwnRepos(err):
ctx.Flash.Error(ctx.Tr("form.still_own_repo"))
ctx.Redirect(setting.AppSubUrl + "/user/settings/delete")
case models.ErrUserHasOrgs:
case models.IsErrUserHasOrgs(err):
ctx.Flash.Error(ctx.Tr("form.still_has_org"))
ctx.Redirect(setting.AppSubUrl + "/user/settings/delete")
default:

@ -28,7 +28,6 @@ GOGS_HOME=/home/git/gogs
GOGS_PATH=${GOGS_HOME}/$NAME
GOGS_USER=git
SERVICENAME="Gogs Go Git Service"
PID=/var/run/$NAME.pid
LOCKFILE=/var/lock/subsys/gogs
LOGFILE=${GOGS_HOME}/log/gogs.log
RETVAL=0
@ -39,7 +38,7 @@ RETVAL=0
# Don't do anything if nothing is installed
[ -x ${GOGS_PATH} ] || exit 0
DAEMON_OPTS=""
DAEMON_OPTS="--check $NAME"
# Set additional options, if any
[ ! -z "$GOGS_USER" ] && DAEMON_OPTS="$DAEMON_OPTS --user=${GOGS_USER}"
@ -47,8 +46,7 @@ DAEMON_OPTS=""
start() {
cd ${GOGS_HOME}
echo -n "Starting ${SERVICENAME}: "
daemon $DAEMON_OPTS --pidfile=${PID} "${GOGS_PATH} web 2>&1 > ${LOGFILE} &"
echo $! > ${PID}
daemon $DAEMON_OPTS "${GOGS_PATH} web > ${LOGFILE} 2>&1 &"
RETVAL=$?
echo
[ $RETVAL = 0 ] && touch ${LOCKFILE}
@ -59,10 +57,10 @@ start() {
stop() {
cd ${GOGS_HOME}
echo -n "Shutting down ${SERVICENAME}: "
killproc -p ${PID} ${NAME}
killproc ${NAME}
RETVAL=$?
echo
[ $RETVAL = 0 ] && rm -f ${LOCKFILE} ${PID}
[ $RETVAL = 0 ] && rm -f ${LOCKFILE}
}
case "$1" in
@ -74,7 +72,7 @@ case "$1" in
stop
;;
status)
status -p ${PID} ${NAME}
status ${NAME}
;;
restart)
stop

@ -1 +1 @@
0.5.16.0301 Beta
0.6.0.0319 Beta

@ -12,7 +12,7 @@
<div class="panel-header">
<strong>{{.i18n.Tr "admin.auths.edit"}}</strong>
</div>
<form class="form form-align panel-body" id="auth-setting-form" action="{{AppSubUrl}}/admin/auths/{{.Source.Id}}" data-delete-url="/admin/auths/{{.Source.Id}}/delete" method="post">
<form class="form form-align panel-body" id="auth-setting-form" action="{{AppSubUrl}}/admin/auths/{{.Source.Id}}" data-delete-url="{{AppSubUrl}}/admin/auths/{{.Source.Id}}/delete" method="post">
{{.CsrfTokenHtml}}
<input type="hidden" value="{{.Source.Id}}" name="id"/>
{{$type := .Source.Type}}

@ -12,7 +12,7 @@
<div class="panel-header">
<strong>{{.i18n.Tr "admin.users.edit_account"}}</strong>
</div>
<form class="form form-align panel-body" id="user-profile-form" action="{{AppSubUrl}}/admin/users/{{.User.Id}}" method="post" data-delete-url="/admin/users/{{.User.Id}}/delete">
<form class="form form-align panel-body" id="user-profile-form" action="{{AppSubUrl}}/admin/users/{{.User.Id}}" method="post" data-delete-url="{{AppSubUrl}}/admin/users/{{.User.Id}}/delete">
{{.CsrfTokenHtml}}
<div class="field">
<label class="req">{{.i18n.Tr "admin.users.auth_source"}}</label>

@ -1,3 +1,3 @@
{{if .Flash.ErrorMsg}}<span class="alert alert-red alert-radius block text-bold"><i class="octicon octicon-alert"></i>{{.Flash.ErrorMsg}}</span>{{end}}
{{if .Flash.SuccessMsg}}<div class="alert alert-green alert-radius block"><i class="octicon octicon-check"></i>{{.Flash.SuccessMsg}}</div>{{end}}
{{if .Flash.InfoMsg}}<div class="alert alert-blue alert-radius block"><i class="octicon octicon-info"></i>{{.Flash.InfoMsg}}</div>{{end}}
{{if .Flash.ErrorMsg}}<span class="alert alert-red alert-radius block text-bold"><i class="octicon octicon-alert"></i>{{.Flash.ErrorMsg|Str2html}}</span>{{end}}
{{if .Flash.SuccessMsg}}<div class="alert alert-green alert-radius block"><i class="octicon octicon-check"></i>{{.Flash.SuccessMsg|Str2html}}</div>{{end}}
{{if .Flash.InfoMsg}}<div class="alert alert-blue alert-radius block"><i class="octicon octicon-info"></i>{{.Flash.InfoMsg|Str2html}}</div>{{end}}

@ -25,7 +25,7 @@
<button class="btn btn-gray left" id="repo-clone-https" data-link="{{.CloneLink.HTTPS}}">HTTPS</button>
<input id="repo-clone-url" type="text" class="ipt ipt-disabled left" value="{{.CloneLink.SSH}}" onclick="this.select()" readonly />
<button class="btn btn-black left btn-right-radius" id="repo-clone-copy" data-copy-val="val" data-copy-from="#repo-clone-url">{{.i18n.Tr "repo.copy_link"}}</button>
<p class="text-center" id="repo-clone-help">{{.i18n.Tr "repo.clone_helper" | Str2html}}</p>
<p class="text-center" id="repo-clone-help">{{.i18n.Tr "repo.clone_helper" "http://git-scm.com/book/en/Git-Basics-Getting-a-Git-Repository" | Str2html}}</p>
<hr/>
</div>
<div id="repo-bare-cmd" class="text-center">

@ -68,8 +68,8 @@
<span>{{.i18n.Tr "repo.migrate_type_helper" | Str2html}}</span>
</div>
<div class="field clear">
<label class="left" for="desc">{{.i18n.Tr "repo.repo_desc"}}</label>
<textarea class="ipt ipt-large ipt-radius {{if .Err_Description}}ipt-error{{end}}" id="desc" name="desc">{{.desc}}</textarea>
<label class="left" for="description">{{.i18n.Tr "repo.repo_desc"}}</label>
<textarea class="ipt ipt-large ipt-radius {{if .Err_Description}}ipt-error{{end}}" id="description" name="description">{{.description}}</textarea>
</div>
<div class="field">
<label for="repo-create-submit"></label>

@ -39,7 +39,11 @@
<span class="octicon octicon-file-submodule"></span>
</td>
<td class="name">
{{if $commit.RefUrl}}
<a href="{{$commit.RefUrl}}" class="text-truncate">{{$entry.Name}}</a> @ <a href="{{$commit.RefUrl}}/commit/{{$commit.RefId}}">{{ShortSha $commit.RefId}}</a>
{{else}}
{{$entry.Name}} @ {{ShortSha $commit.RefId}}
{{end}}
</td>
{{else}}
<td class="icon">

@ -7,19 +7,19 @@
<p class="text-bold">
<a href="{{AppSubUrl}}/{{.GetActUserName}}">{{.GetActUserName}}</a>
{{if eq .GetOpType 1}}
{{$.i18n.Tr "action.create_repo" AppSubUrl .GetRepoLink .GetRepoLink | Str2html}}
{{$.i18n.Tr "action.create_repo" .GetRepoLink .GetRepoPath | Str2html}}
{{else if eq .GetOpType 5}}
{{$.i18n.Tr "action.commit_repo" AppSubUrl .GetRepoLink .GetBranch .GetBranch AppSubUrl .GetRepoLink .GetRepoLink | Str2html}}
{{$.i18n.Tr "action.commit_repo" .GetRepoLink .GetBranch .GetRepoPath | Str2html}}
{{else if eq .GetOpType 6}}
{{ $index := index .GetIssueInfos 0}}
{{$.i18n.Tr "action.create_issue" .GetRepoLink $index | Str2html}}
{{$.i18n.Tr "action.create_issue" .GetRepoLink $index .GetRepoPath | Str2html}}
{{else if eq .GetOpType 8}}
{{$.i18n.Tr "action.transfer_repo" .GetContent AppSubUrl .GetRepoLink .GetRepoLink | Str2html}}
{{$.i18n.Tr "action.transfer_repo" .GetContent .GetRepoLink .GetRepoPath | Str2html}}
{{else if eq .GetOpType 9}}
{{$.i18n.Tr "action.push_tag" AppSubUrl .GetRepoLink .GetBranch .GetBranch AppSubUrl .GetRepoLink .GetRepoLink | Str2html}}
{{$.i18n.Tr "action.push_tag" .GetRepoLink .GetBranch .GetRepoPath | Str2html}}
{{else if eq .GetOpType 10}}
{{ $index := index .GetIssueInfos 0}}
{{$.i18n.Tr "action.comment_issue" .GetRepoLink $index | Str2html}}
{{$.i18n.Tr "action.comment_issue" .GetRepoLink $index .GetRepoPath | Str2html}}
{{end}}
</p>
{{if eq .GetOpType 5}}
@ -28,7 +28,7 @@
{{ $push := ActionContent2Commits .}}
{{ $repoLink := .GetRepoLink}}
{{range $push.Commits}}
<li><img class="avatar-16" src="{{AvatarLink .AuthorEmail}}?s=16"> <a href="{{AppSubUrl}}/{{$repoLink}}/commit/{{.Sha1}}">{{ShortSha .Sha1}}</a> <span class="text-truncate grid-4-5">{{.Message}}</span></li>
<li><img class="avatar-16" src="{{AvatarLink .AuthorEmail}}?s=16"> <a href="{{$repoLink}}/commit/{{.Sha1}}">{{ShortSha .Sha1}}</a> <span class="text-truncate grid-4-5">{{.Message}}</span></li>
{{end}}
{{if $push.CompareUrl}}<li><a href="{{$push.CompareUrl}}">{{$.i18n.Tr "action.compare_2_commits"}} »</a></li>{{end}}
</ul>

@ -1,53 +1,44 @@
{{template "base/head" .}}
{{template "base/navbar" .}}
<div id="body-nav">
<div class="container">
<ul class="nav nav-pills pull-right">
<li><a href="{{AppSubUrl}}/">News Feed</a></li>
<li class="active"><a href="{{AppSubUrl}}/issues">Issues</a></li>
<!-- <li><a href="{{AppSubUrl}}/pulls">Pull Requests</a></li>
<li><a href="{{AppSubUrl}}/stars">Stars</a></li> -->
</ul>
<h3>Your Issues</h3>
</div>
{{template "ng/base/head" .}}
{{template "ng/base/header" .}}
{{template "user/dashboard/nav" .}}
<div id="dashboard-wrapper">
<div id="dashboard" class="container" data-page="user">
{{if .HasInfo}}<div class="alert alert-info">{{.InfoMsg}}</div>{{end}}
<div id="issue">
<div class="left grid-1-5 filter-list">
<ul class="list-unstyled menu menu-vertical">
<li><a href="{{AppSubUrl}}/issues?state={{.State}}&repoid={{.RepoId}}" class="radius{{if eq .ViewType "all"}} active{{end}}" >In your repositories <strong class="pull-right">{{.IssueStats.AllCount}}</strong></a></li>
<li><a href="{{AppSubUrl}}/issues?type=assigned&repoid={{.RepoId}}&state={{.State}}" class="radius{{if eq .ViewType "assigned"}} active{{end}}">Assigned to you <strong class="pull-right">{{.IssueStats.AssignCount}}</strong></a></li>
<li><a href="{{AppSubUrl}}/issues?type=created_by&repoid={{.RepoId}}&state={{.State}}" class="radius{{if eq .ViewType "created_by"}} active{{end}}">Created by you <strong class="pull-right">{{.IssueStats.CreateCount}}</strong></a></li>
<li><hr/></li>
{{range .Repos}}
<li><a href="{{AppSubUrl}}/issues?type={{$.ViewType}}{{if eq $.RepoId .Id}}{{else}}&repoid={{.Id}}{{end}}&state={{$.State}}" class="radius{{if eq $.RepoId .Id}} active{{end}}">{{$.SignedUser.Name}}/{{.Name}} <strong class="pull-right">{{if $.IsShowClosed}}{{.NumClosedIssues}}{{else}}{{.NumOpenIssues}}{{end}}</strong></a></li>
{{end}}
</ul>
</div>
<div class="right grid-3-4">
<div class="filter-option">
<div class="btn-group">
<a class="btn btn-white btn-small issue-open{{if not .IsShowClosed}} active{{end}}" href="{{AppSubUrl}}/issues?type={{.ViewType}}&repoid={{.RepoId}}">Open</a>
<a class="btn btn-white btn-small issue-close{{if .IsShowClosed}} active{{end}}" href="{{AppSubUrl}}/issues?type={{.ViewType}}&repoid={{.RepoId}}&state=closed">Closed</a>
</div>
</div>
<div class="issues list-group">
{{range .Issues}}{{if .}}
<div class="list-group-item issue-item" id="issue-{{.Id}}" onclick="window.location.href='{{AppSubUrl}}/{{.Repo.Owner.Name}}/{{.Repo.Name}}/issues/{{.Index}}'">
<span class="number pull-right">#{{.Index}}</span>
<h5 class="title"><a href="{{AppSubUrl}}/{{.Repo.Owner.Name}}/{{.Repo.Name}}/issues/{{.Index}}">{{.Name}}</a></h5>
<p class="info">
<span class="author"><img class="avatar" src="{{.Poster.AvatarLink}}" alt="" width="20"/>
<a href="{{AppSubUrl}}/{{.Poster.Name}}">{{.Poster.Name}}</a></span>
<span class="time">{{TimeSince .Created $.Lang}}</span>
<span class="comment"><i class="fa fa-comments"></i> {{.NumComments}}</span>
</p>
</div>
{{end}}{{end}}
</div>
</div>
</div>
</div>
</div>
<div id="body" class="container" data-page="user">
{{if .HasInfo}}<div class="alert alert-info">{{.InfoMsg}}</div>{{end}}
<div id="issue">
<div class="col-md-3 filter-list">
<ul class="list-unstyled">
<li><a href="{{AppSubUrl}}/issues?state={{.State}}&repoid={{.RepoId}}"{{if eq .ViewType "all"}} class="active"{{end}}>In your repositories <strong class="pull-right">{{.IssueStats.AllCount}}</strong></a></li>
<li><a href="{{AppSubUrl}}/issues?type=assigned&repoid={{.RepoId}}&state={{.State}}"{{if eq .ViewType "assigned"}} class="active"{{end}}>Assigned to you <strong class="pull-right">{{.IssueStats.AssignCount}}</strong></a></li>
<li><a href="{{AppSubUrl}}/issues?type=created_by&repoid={{.RepoId}}&state={{.State}}"{{if eq .ViewType "created_by"}} class="active"{{end}}>Created by you <strong class="pull-right">{{.IssueStats.CreateCount}}</strong></a></li>
<li><hr/></li>
{{range .Repos}}
<li><a href="{{AppSubUrl}}/issues?type={{$.ViewType}}{{if eq $.RepoId .Id}}{{else}}&repoid={{.Id}}{{end}}&state={{$.State}}" class="sm{{if eq $.RepoId .Id}} active{{end}}">{{$.SignedUser.Name}}/{{.Name}} <strong class="pull-right">{{if $.IsShowClosed}}{{.NumClosedIssues}}{{else}}{{.NumOpenIssues}}{{end}}</strong></a></li>
{{end}}
</ul>
</div>
<div class="col-md-9">
<div class="filter-option">
<div class="btn-group">
<a class="btn btn-default issue-open{{if not .IsShowClosed}} active{{end}}" href="{{AppSubUrl}}/issues?type={{.ViewType}}&repoid={{.RepoId}}">Open</a>
<a class="btn btn-default issue-close{{if .IsShowClosed}} active{{end}}" href="{{AppSubUrl}}/issues?type={{.ViewType}}&repoid={{.RepoId}}&state=closed">Closed</a>
</div>
</div>
<div class="issues list-group">
{{range .Issues}}{{if .}}
<div class="list-group-item issue-item" id="issue-{{.Id}}">
<span class="number pull-right">#{{.Index}}</span>
<h5 class="title"><a href="{{AppSubUrl}}/{{.Repo.Owner.Name}}/{{.Repo.Name}}/issues/{{.Index}}">{{.Name}}</a></h5>
<p class="info">
<span class="author"><img class="avatar" src="{{.Poster.AvatarLink}}" alt="" width="20"/>
<a href="{{AppSubUrl}}/{{.Poster.Name}}">{{.Poster.Name}}</a></span>
<span class="time">{{TimeSince .Created $.Lang}}</span>
<span class="comment"><i class="fa fa-comments"></i> {{.NumComments}}</span>
</p>
</div>
{{end}}{{end}}
</div>
</div>
</div>
</div>
{{template "base/footer" .}}
{{template "ng/base/footer" .}}

@ -1 +0,0 @@
box: wercker/default
Loading…
Cancel
Save