Browse Source

Merge https://github.com/gogits/gogs

Dmitry Yu Okunev 5 years ago
parent
commit
0d233f6241
100 changed files with 12451 additions and 5287 deletions
  1. 3 3
      .bra.toml
  2. 11 12
      .dockerignore
  3. 2 0
      .gitattributes
  4. 1 5
      CONTRIBUTING.md
  5. 24 0
      .github/ISSUE_TEMPLATE.md
  6. 9 0
      .github/PULL_REQUEST_TEMPLATE.md
  7. 2 21
      .gitignore
  8. 37 30
      .gopmfile
  9. 4 2
      .travis.yml
  10. 8 8
      Dockerfile
  11. 12 9
      Dockerfile.rpi
  12. 20 2
      Makefile
  13. 22 14
      README.md
  14. 9 3
      README_ZH.md
  15. 5 3
      cmd/cert.go
  16. 7 6
      cmd/cert_stub.go
  17. 15 8
      cmd/dump.go
  18. 29 18
      cmd/serve.go
  19. 12 9
      cmd/update.go
  20. 107 69
      cmd/web.go
  21. 1 5
      conf/README.md
  22. 79 34
      conf/app.ini
  23. 0 39
      conf/license/Creative Commons Zero v1.0 Universal
  24. 1 2
      conf/license/ISC license
  25. 32 1
      conf/locale/TRANSLATORS
  26. 75 24
      conf/locale/locale_bg-BG.ini
  27. 1112 0
      conf/locale/locale_cs-CZ.ini
  28. 428 377
      conf/locale/locale_de-DE.ini
  29. 93 39
      conf/locale/locale_en-US.ini
  30. 184 133
      conf/locale/locale_es-ES.ini
  31. 1112 0
      conf/locale/locale_fi-FI.ini
  32. 242 191
      conf/locale/locale_fr-FR.ini
  33. 289 238
      conf/locale/locale_it-IT.ini
  34. 140 89
      conf/locale/locale_ja-JP.ini
  35. 111 60
      conf/locale/locale_lv-LV.ini
  36. 242 191
      conf/locale/locale_nl-NL.ini
  37. 80 29
      conf/locale/locale_pl-PL.ini
  38. 120 69
      conf/locale/locale_pt-BR.ini
  39. 167 116
      conf/locale/locale_ru-RU.ini
  40. 1112 0
      conf/locale/locale_tr-TR.ini
  41. 76 25
      conf/locale/locale_zh-CN.ini
  42. 131 80
      conf/locale/locale_zh-HK.ini
  43. 1112 0
      conf/locale/locale_zh-TW.ini
  44. 45 8
      docker/README.md
  45. 16 7
      docker/build.sh
  46. 16 0
      docker/nsswitch.conf
  47. 0 0
      docker/s6/crond/down
  48. 9 0
      docker/s6/crond/run
  49. 0 4
      docker/s6/openssh/setup
  50. 0 1
      docker/sshd_config
  51. 9 0
      docker/start.sh
  52. 148 0
      glide.lock
  53. 57 0
      glide.yaml
  54. 2 3
      gogs.go
  55. 53 33
      models/access.go
  56. 99 56
      models/action.go
  57. 48 1
      models/admin.go
  58. 0 59
      models/cron/cron.go
  59. 69 3
      models/error.go
  60. 135 26
      models/git_diff.go
  61. 70 0
      models/git_diff_test.go
  62. 330 635
      models/issue.go
  63. 373 0
      models/issue_comment.go
  64. 234 0
      models/issue_label.go
  65. 81 0
      models/issue_mail.go
  66. 87 33
      models/login.go
  67. 183 0
      models/mail.go
  68. 262 9
      models/migrations/migrations.go
  69. 52 0
      models/migrations/v13.go
  70. 14 38
      models/models.go
  71. 172 646
      models/org.go
  72. 618 0
      models/org_team.go
  73. 74 19
      models/pull.go
  74. 17 5
      models/release.go
  75. 415 294
      models/repo.go
  76. 57 0
      models/repo_branch.go
  77. 160 0
      models/repo_collaboration.go
  78. 62 0
      models/repo_test.go
  79. 249 216
      models/ssh_key.go
  80. 45 0
      models/ssh_key_test.go
  81. 38 20
      models/token.go
  82. 50 40
      models/update.go
  83. 289 329
      models/user.go
  84. 198 0
      models/user_mail.go
  85. 73 31
      models/webhook.go
  86. 1 1
      models/webhook_slack.go
  87. 65 18
      models/wiki.go
  88. 1 0
      modules/auth/admin.go
  89. 5 5
      modules/auth/auth.go
  90. 2 0
      modules/auth/auth_form.go
  91. 83 45
      modules/auth/ldap/ldap.go
  92. 3 3
      modules/auth/org.go
  93. 5 3
      modules/auth/repo_form.go
  94. 1 0
      modules/auth/user_form.go
  95. 11 307
      modules/avatar/avatar.go
  96. 13 51
      modules/avatar/avatar_test.go
  97. 0 21
      modules/base/base.go
  98. 0 339
      modules/base/markdown.go
  99. 74 14
      modules/base/tool.go
  100. 0 0
      modules/bindata/bindata.go

+ 3 - 3
.bra.toml

@@ -1,6 +1,6 @@
 [run]
 init_cmds = [
-	#["grep", "-rn", "FIXME", "."],
+	["make", "build-dev", "TAGS=sqlite"],
 	["./gogs", "web"]
 ]
 watch_all = true
@@ -11,9 +11,9 @@ watch_dirs = [
 	"$WORKDIR/routers"
 ]
 watch_exts = [".go"]
+ignore_files = [".+_test.go"]
 build_delay = 1500
 cmds = [
-	["go", "install", "-race"], # sqlite redis memcache cert pam tidb
-	["go", "build", "-race"],
+	["make", "build-dev", "TAGS=sqlite"], # cert pam tidb
 	["./gogs", "web"]
 ]

+ 11 - 12
.dockerignore

@@ -1,20 +1,19 @@
 .git
-.git/
-.git/*
-conf
-conf/
-conf/*
+.git/**
 packager
-packager/
-packager/*
+packager/**
 scripts
-scripts/
-scripts/*
+scripts/**
+.github/
+.github/**
+config.codekit
+.dockerignore
 *.yml
 *.md
 .bra.toml
 .editorconfig
 .gitignore
-.gopmfile
-config.codekit
-LICENSE
+Dockerfile*
+vendor
+vendor/**
+gogs

+ 2 - 0
.gitattributes

@@ -0,0 +1,2 @@
+public/assets/* linguist-vendored
+public/plugins/* linguist-vendored

+ 1 - 5
CONTRIBUTING.md

@@ -46,11 +46,7 @@ Please read detailed information on [Wiki](https://github.com/gogits/gogs/wiki/C
 
 ### Ask For Help
 
-Before opening an issue, please make sure your problem isn't already addressed on the [Troubleshooting](http://gogs.io/docs/intro/troubleshooting.md) and [FAQs](http://gogs.io/docs/intro/faqs.html) pages.
-
-## Things To Notice
-
-Please take a moment to check that an issue on [GitHub](https://github.com/gogits/gogs/issues) or card on [Trello](https://trello.com/b/uxAoeLUl/gogs-go-git-service) doesn't already exist documenting your bug report or improvement proposal. If it does, it never hurts to add a quick "+1" or "I have this problem too". This will help prioritize the most common problems and requests.
+Before opening an issue, please make sure your problem isn't already addressed on the [Troubleshooting](http://gogs.io/docs/intro/troubleshooting.html) and [FAQs](http://gogs.io/docs/intro/faqs.html) pages.
 
 ## Code of conduct
 

+ 24 - 0
.github/ISSUE_TEMPLATE.md

@@ -0,0 +1,24 @@
+The issue will be closed without any reasons if it does not satisfy any of following requirements:
+
+1. Please do NOT post questions or config/deploy problems on GitHub, please use our forum: https://discuss.gogs.io
+2. Please take a moment to search that an issue doesn't already exist.
+3. Please give all relevant information below for bug reports; incomplete details considered invalid report.
+
+**You MUST delete above content including this line before posting; too lazy to take this action considered invalid report.**
+
+- Gogs version (or commit ref): 
+- Git version: 
+- Operating system: 
+- Database (use `[x]`):
+  - [ ] PostgreSQL
+  - [ ] MySQL
+  - [ ] SQLite
+- Can you reproduce the bug at https://try.gogs.io:
+  - [ ] Yes (provide example URL)
+  - [ ] No
+  - [ ] Not relevant
+- Log gist:
+
+## Description
+
+...

+ 9 - 0
.github/PULL_REQUEST_TEMPLATE.md

@@ -0,0 +1,9 @@
+The pull request will be closed without any reasons if it does not satisfy any of following requirements:
+
+1. Please make sure you are targeting the `develop` branch.
+2. Please read contributing guidelines:
+https://github.com/gogits/gogs/wiki/Contributing-Code
+3. Please describe what your pull request does and which issue you're targeting
+4. ... if it is not related to any particular issues, explain why we should not reject your pull request.
+
+**You MUST delete above content including this line before posting; too lazy to take this action considered invalid pull request.**

+ 2 - 21
.gitignore

@@ -8,32 +8,13 @@ data/
 .idea/
 *.iml
 public/img/avatar/
-files/
-*.o
-*.a
-*.so
-_obj
-_test
-*.[568vq]
-[568vq].out
-*.cgo1.go
-*.cgo2.c
-_cgo_defun.c
-_cgo_gotypes.go
-_cgo_export.*
-_testmain.go
 *.exe
 *.exe~
 /gogs
 profile/
-__pycache__
 *.pem
 output*
-.brackets.json
-docker/fig.yml
-docker/docker/Dockerfile
-docker/docker/init_gogs.sh
 gogs.sublime-project
 gogs.sublime-workspace
-.tags*
-release
+/release
+vendor

+ 37 - 30
.gopmfile

@@ -2,49 +2,56 @@
 path = github.com/gogits/gogs
 
 [deps]
-github.com/bradfitz/gomemcache = commit:72a68649ba
-github.com/codegangsta/cli = commit:b5232bb
-github.com/go-macaron/binding = commit:2502aaf
+github.com/bradfitz/gomemcache = commit:fb1f79c
+github.com/codegangsta/cli = commit:1efa31f
+github.com/go-macaron/binding = commit:9440f33
 github.com/go-macaron/cache = commit:5617353
 github.com/go-macaron/captcha = commit:8aa5919
-github.com/go-macaron/csrf = commit:715bca0
-github.com/go-macaron/gzip = commit:4938e9b
-github.com/go-macaron/i18n = commit:d2d3329
+github.com/go-macaron/csrf = commit:6a9a7df
+github.com/go-macaron/gzip = commit:cad1c65
+github.com/go-macaron/i18n = commit:ef57533
 github.com/go-macaron/inject = commit:c5ab7bf
 github.com/go-macaron/session = commit:66031fc
-github.com/go-macaron/toolbox = commit:ab30a81
-github.com/go-sql-driver/mysql = commit:d512f20
-github.com/go-xorm/core = commit:acb6f00
-github.com/go-xorm/xorm = commit:a8fba4d
-github.com/gogits/chardet = commit:2404f77725
-github.com/gogits/git-shell = commit:1ffc4bc
-github.com/gogits/go-gogs-client = commit:4b541fa
-github.com/issue9/identicon = commit:f8c0d2c
+github.com/go-macaron/toolbox = commit:82b5115
+github.com/go-sql-driver/mysql = commit:3654d25
+github.com/go-xorm/core = commit:bc1b7f8
+github.com/go-xorm/xorm = commit:b8b1711
+github.com/gogits/chardet = commit:2404f77
+github.com/gogits/cron = commit:96040e4
+github.com/gogits/git-module = commit:53bcb73
+github.com/gogits/go-gogs-client = commit:ee68cd9
+github.com/issue9/identicon = commit:d36b545
+github.com/jaytaylor/html2text = commit:52d9b78
 github.com/kardianos/minwinsvc = commit:cad6b2b
-github.com/klauspost/compress = commit:42eb574
-github.com/klauspost/cpuid = commit:eebb3ea
-github.com/klauspost/crc32 = commit:0aff1ea
-github.com/lib/pq = commit:11fc39a
-github.com/mattn/go-sqlite3 = commit:5651a9d
+github.com/klauspost/compress = commit:14eb9c4
+github.com/klauspost/cpuid = commit:09cded8
+github.com/klauspost/crc32 = commit:19b0b33
+github.com/lib/pq = commit:ee1442b
+github.com/mattn/go-sqlite3 = commit:38ee283
 github.com/mcuadros/go-version = commit:d52711f
 github.com/microcosm-cc/bluemonday = commit:4ac6f27
 github.com/msteinert/pam = commit:02ccfbf
-github.com/nfnt/resize = commit:dc93e1b98c
-github.com/russross/blackfriday = commit:d18b67a
+github.com/nfnt/resize = commit:4d93a29
+github.com/russross/blackfriday = commit:4e6f303
+github.com/satori/go.uuid = commit:879c588
+github.com/sergi/go-diff = commit:ec7fdbb
 github.com/shurcooL/sanitized_anchor_name = commit:10ef21a
 github.com/Unknwon/cae = commit:7f5e046
 github.com/Unknwon/com = commit:28b053d
-github.com/Unknwon/i18n = commit:3b48b66
+github.com/Unknwon/i18n = commit:39d6f27
 github.com/Unknwon/paginater = commit:7748a72
-golang.org/x/net = commit:d75b190
-golang.org/x/text = commit:458f474
-golang.org/x/crypto = commit:7b85b09
+golang.org/x/crypto = commit:77f4136
+golang.org/x/net = commit:3f122ce
+golang.org/x/sys = commit:7f918dd
+golang.org/x/text = commit:e477511
+gopkg.in/alexcesaro/quotedprintable.v3 = commit:2caba25
 gopkg.in/asn1-ber.v1 = commit:4e86f43
-gopkg.in/gomail.v2 = commit:fbb71dd
-gopkg.in/ini.v1 = commit:a4e5487
-gopkg.in/ldap.v2 = commit:e9a325d
-gopkg.in/macaron.v1 = commit:1c6dd87
-gopkg.in/redis.v2 = commit:e617904962
+gopkg.in/bufio.v1 = commit:567b2bf
+gopkg.in/gomail.v2 = commit:81ebce5
+gopkg.in/ini.v1 = commit:72ba3e6
+gopkg.in/ldap.v2 = commit:0e7db8e
+gopkg.in/macaron.v1 = commit:2133042
+gopkg.in/redis.v2 = commit:e617904
 
 [res]
 include = public|scripts|templates

+ 4 - 2
.travis.yml

@@ -1,9 +1,9 @@
 language: go
 
 go:
-  - 1.3
   - 1.4
   - 1.5
+  - 1.6
 
 before_install:
   - sudo apt-get update -qq
@@ -13,7 +13,9 @@ before_install:
 install:
   - go get -t -v ./...
 
-script: go build -v -tags "pam"
+script: 
+  - go build -v -tags "pam"
+  - go test -v -cover -race ./...
 
 notifications:
   email:

+ 8 - 8
Dockerfile

@@ -1,13 +1,10 @@
-FROM alpine:3.2
-MAINTAINER roemer.jp@gmail.com
+FROM alpine:3.3
+MAINTAINER jp@roemer.im
 
 # Install system utils & Gogs runtime dependencies
-ADD https://github.com/tianon/gosu/releases/download/1.6/gosu-amd64 /usr/sbin/gosu
-RUN echo "@edge http://dl-4.alpinelinux.org/alpine/edge/main" | tee -a /etc/apk/repositories \
- && echo "@community http://dl-4.alpinelinux.org/alpine/edge/community" | tee -a /etc/apk/repositories \
- && apk -U --no-progress upgrade \
- && apk -U --no-progress add ca-certificates bash git linux-pam s6@edge curl openssh socat \
- && chmod +x /usr/sbin/gosu
+ADD https://github.com/tianon/gosu/releases/download/1.9/gosu-amd64 /usr/sbin/gosu
+RUN chmod +x /usr/sbin/gosu \
+ && apk --no-cache --no-progress add ca-certificates bash git linux-pam s6 curl openssh socat tzdata
 
 ENV GOGS_CUSTOM /data/gogs
 
@@ -15,6 +12,9 @@ COPY . /app/gogs/
 WORKDIR /app/gogs/
 RUN ./docker/build.sh
 
+# Configure LibC Name Service
+COPY docker/nsswitch.conf /etc/nsswitch.conf
+
 # Configure Docker Container
 VOLUME ["/data"]
 EXPOSE 22 3000

+ 12 - 9
Dockerfile.rpi

@@ -1,13 +1,13 @@
-FROM sander85/rpi-alpine:latest
-MAINTAINER roemer.jp@gmail.com, raxetul@gmail.com
+FROM hypriot/rpi-alpine-scratch:v3.2
+MAINTAINER jp@roemer.im, raxetul@gmail.com
 
 # Install system utils & Gogs runtime dependencies
-ADD https://github.com/tianon/gosu/releases/download/1.6/gosu-armhf /usr/sbin/gosu
-RUN echo "@edge http://dl-4.alpinelinux.org/alpine/edge/main" | tee -a /etc/apk/repositories \
- && echo "@community http://dl-4.alpinelinux.org/alpine/edge/community" | tee -a /etc/apk/repositories \
- && apk -U --no-progress upgrade \
- && apk -U --no-progress add ca-certificates bash git linux-pam s6@edge curl openssh socat \
- && chmod +x /usr/sbin/gosu
+ADD https://github.com/tianon/gosu/releases/download/1.9/gosu-armhf /usr/sbin/gosu
+RUN chmod +x /usr/sbin/gosu \
+ && echo "http://dl-4.alpinelinux.org/alpine/v3.3/main/"      | tee /etc/apk/repositories    \
+ && echo "http://dl-4.alpinelinux.org/alpine/v3.3/community/" | tee -a /etc/apk/repositories \
+ && apk -U --no-progress upgrade && rm -f /var/cache/apk/APKINDEX.* \
+ && apk --no-cache --no-progress add ca-certificates bash git linux-pam s6 curl openssh socat tzdata
 
 ENV GOGS_CUSTOM /data/gogs
 
@@ -15,8 +15,11 @@ COPY . /app/gogs/
 WORKDIR /app/gogs/
 RUN ./docker/build.sh
 
+# Configure LibC Name Service
+COPY docker/nsswitch.conf /etc/nsswitch.conf
+
 # Configure Docker Container
 VOLUME ["/data"]
 EXPOSE 22 3000
 ENTRYPOINT ["docker/start.sh"]
-CMD ["/usr/bin/s6-svscan", "/app/gogs/docker/s6/"]
+CMD ["/bin/s6-svscan", "/app/gogs/docker/s6/"]

+ 20 - 2
Makefile

@@ -6,6 +6,7 @@ LESS_FILES := $(wildcard public/less/gogs.less public/less/_*.less)
 GENERATED  := modules/bindata/bindata.go public/css/gogs.css
 
 TAGS = ""
+BUILD_FLAGS = "-v"
 
 RELEASE_ROOT = "release"
 RELEASE_GOGS = "release/gogs"
@@ -16,12 +17,20 @@ NOW = $(shell date -u '+%Y%m%d%I%M%S')
 .IGNORE: public/css/gogs.css
 
 build: $(GENERATED)
-	go install -ldflags '$(LDFLAGS)' -tags '$(TAGS)'
+	go install $(BUILD_FLAGS) -ldflags '$(LDFLAGS)' -tags '$(TAGS)'
 	cp '$(GOPATH)/bin/gogs' .
 
 govet:
 	go tool vet -composites=false -methods=false -structtags=false .
 
+build-dev: $(GENERATED) govet
+	go install $(BUILD_FLAGS) -tags '$(TAGS)'
+	cp '$(GOPATH)/bin/gogs' .
+
+build-dev-race: $(GENERATED) govet
+	go install $(BUILD_FLAGS) -race -tags '$(TAGS)'
+	cp '$(GOPATH)/bin/gogs' .
+
 pack:
 	rm -rf $(RELEASE_GOGS)
 	mkdir -p $(RELEASE_GOGS)
@@ -34,7 +43,7 @@ release: build pack
 bindata: modules/bindata/bindata.go
 
 modules/bindata/bindata.go: $(DATA_FILES)
-	go-bindata -o=$@ -ignore="\\.DS_Store|README.md" -pkg=bindata conf/...
+	go-bindata -o=$@ -ignore="\\.DS_Store|README.md|TRANSLATORS" -pkg=bindata conf/...
 
 less: public/css/gogs.css
 
@@ -46,3 +55,12 @@ clean:
 
 clean-mac: clean
 	find . -name ".DS_Store" -print0 | xargs -0 rm
+
+test:
+	go test -cover -race ./...
+
+fixme:
+	grep -rnw "FIXME" routers models modules
+
+todo:
+	grep -rnw "TODO" routers models modules

File diff suppressed because it is too large
+ 22 - 14
README.md


+ 9 - 3
README_ZH.md

@@ -12,7 +12,7 @@ Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自
 - 有关基本用法和变更日志,请通过 [使用手册](http://gogs.io/docs/intro/) 查看。
 - 您可以到 [Trello Board](https://trello.com/b/uxAoeLUl/gogs-go-git-service) 跟随开发团队的脚步。
 - 想要先睹为快?直接去 [在线体验](https://try.gogs.io/gogs/gogs) 。
-- 使用过程中遇到问题?尝试从 [故障排查](http://gogs.io/docs/intro/troubleshooting.html) 页面获取帮助。
+- 使用过程中遇到问题?尝试从 [故障排查](http://gogs.io/docs/intro/troubleshooting.html) 页面或 [用户论坛](https://discuss.gogs.io/) 获取帮助。
 - 希望帮助多国语言界面的翻译吗?请立即访问 [详情页面](http://gogs.io/docs/features/i18n.html)!
 
 ## 功能特性
@@ -30,7 +30,7 @@ Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自
 - 支持邮件服务
 - 支持后台管理面板
 - 支持 MySQL、PostgreSQL、SQLite3 和 [TiDB](https://github.com/pingcap/tidb)(实验性支持) 数据库
-- 支持多语言本地化([14 种语言]([more](https://crowdin.com/project/gogs)))
+- 支持多语言本地化([18 种语言]([more](https://crowdin.com/project/gogs)))
 
 ## 系统要求
 
@@ -67,12 +67,18 @@ Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自
 - [Portal](https://portaldemo.xyz/cloud/)
 - [Sandstorm](https://github.com/cem/gogs-sandstorm)
 - [sloppy.io](https://github.com/sloppyio/quickstarters/tree/master/gogs)
+- [YunoHost](https://github.com/mbugeia/gogs_ynh)
+- [DPlatform](https://github.com/j8r/DPlatform)
 
 ## 软件及服务支持
 
 - [Drone](https://github.com/drone/drone)(CI)
 - [Fabric8](http://fabric8.io/)(DevOps)
 - [Taiga](https://taiga.io/)(项目管理)
+- [Puppet](https://forge.puppetlabs.com/Siteminds/gogs)(IT)
+- [Kanboard](http://kanboard.net/plugin/gogs-webhook)(项目管理)
+- [BearyChat](https://bearychat.com/)(团队交流)
+- [HiWork](http://www.hiwork.cc/)(团队交流)
 
 ### 产品支持
 
@@ -82,11 +88,11 @@ Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自
 ## 特别鸣谢
 
 - 基于 [Macaron](https://github.com/go-macaron/macaron) 的路由与中间件机制。
-- 基于 [WeTalk](https://github.com/beego/wetalk) 修改的模块设计。
 - 基于 [GoBlog](https://github.com/fuxiaohei/goblog) 修改的系统监视状态。
 - 感谢 [lavachen](http://www.lavachen.cn/) 和 [Rocker](http://weibo.com/rocker1989) 设计的 Logo。
 - 感谢 [Crowdin](https://crowdin.com/project/gogs) 提供免费的开源项目本地化支持。
 - 感谢 [DigitalOcean](https://www.digitalocean.com) 提供主站和体验站点的服务器赞助。
+- 感谢 [KeyCDN](https://www.keycdn.com/) 和 [七牛云存储](http://www.qiniu.com/) 提供 CDN 服务赞助。
 
 ## 贡献成员
 

+ 5 - 3
cmd/cert.go

@@ -59,7 +59,7 @@ func pemBlockForKey(priv interface{}) *pem.Block {
 	case *ecdsa.PrivateKey:
 		b, err := x509.MarshalECPrivateKey(k)
 		if err != nil {
-			log.Fatal("unable to marshal ECDSA private key: %v", err)
+			log.Fatalf("Unable to marshal ECDSA private key: %v\n", err)
 		}
 		return &pem.Block{Type: "EC PRIVATE KEY", Bytes: b}
 	default:
@@ -67,7 +67,7 @@ func pemBlockForKey(priv interface{}) *pem.Block {
 	}
 }
 
-func runCert(ctx *cli.Context) {
+func runCert(ctx *cli.Context) error {
 	if len(ctx.String("host")) == 0 {
 		log.Fatal("Missing required --host parameter")
 	}
@@ -153,9 +153,11 @@ func runCert(ctx *cli.Context) {
 
 	keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
 	if err != nil {
-		log.Fatal("failed to open key.pem for writing: %v", err)
+		log.Fatalf("Failed to open key.pem for writing: %v\n", err)
 	}
 	pem.Encode(keyOut, pemBlockForKey(priv))
 	keyOut.Close()
 	log.Println("Written key.pem")
+
+	return nil
 }

+ 7 - 6
cmd/cert_stub.go

@@ -14,14 +14,15 @@ import (
 )
 
 var CmdCert = cli.Command{
-	Name:  "cert",
-	Usage: "Generate self-signed certificate",
-	Description: `Generate a self-signed X.509 certificate for a TLS server. 
-Outputs to 'cert.pem' and 'key.pem' and will overwrite existing files.`,
-	Action: runCert,
+	Name:        "cert",
+	Usage:       "Generate self-signed certificate",
+	Description: `Please use build tags "cert" to rebuild Gogs in order to have this ability`,
+	Action:      runCert,
 }
 
-func runCert(ctx *cli.Context) {
+func runCert(ctx *cli.Context) error {
 	fmt.Println("Command cert not available, please use build tags 'cert' to rebuild.")
 	os.Exit(1)
+
+	return nil
 }

+ 15 - 8
cmd/dump.go

@@ -28,11 +28,12 @@ It can be used for backup and capture Gogs server image to send to maintainer`,
 	Action: runDump,
 	Flags: []cli.Flag{
 		stringFlag("config, c", "custom/conf/app.ini", "Custom configuration file path"),
-		boolFlag("verbose, v", "show process details"),
+		boolFlag("verbose, v", "Show process details"),
+		stringFlag("tempdir, t", os.TempDir(), "Temporary dir path"),
 	},
 }
 
-func runDump(ctx *cli.Context) {
+func runDump(ctx *cli.Context) error {
 	if ctx.IsSet("config") {
 		setting.CustomConf = ctx.String("config")
 	}
@@ -40,7 +41,11 @@ func runDump(ctx *cli.Context) {
 	models.LoadConfigs()
 	models.SetEngine()
 
-	TmpWorkDir, err := ioutil.TempDir(os.TempDir(), "gogs-dump-")
+	tmpDir := ctx.String("tempdir")
+	if _, err := os.Stat(tmpDir); os.IsNotExist(err) {
+		log.Fatalf("Path does not exist: %s", tmpDir)
+	}
+	TmpWorkDir, err := ioutil.TempDir(tmpDir, "gogs-dump-")
 	if err != nil {
 		log.Fatalf("Fail to create tmp work directory: %v", err)
 	}
@@ -68,21 +73,21 @@ func runDump(ctx *cli.Context) {
 		log.Fatalf("Fail to create %s: %v", fileName, err)
 	}
 
-	if err := z.AddFile("gogs-repo.zip", reposDump); err !=nil {
+	if err := z.AddFile("gogs-repo.zip", reposDump); err != nil {
 		log.Fatalf("Fail to include gogs-repo.zip: %v", err)
 	}
-	if err := z.AddFile("gogs-db.sql", dbDump); err !=nil {
+	if err := z.AddFile("gogs-db.sql", dbDump); err != nil {
 		log.Fatalf("Fail to include gogs-db.sql: %v", err)
 	}
 	customDir, err := os.Stat(setting.CustomPath)
 	if err == nil && customDir.IsDir() {
-		if err := z.AddDir("custom", setting.CustomPath); err !=nil {
+		if err := z.AddDir("custom", setting.CustomPath); err != nil {
 			log.Fatalf("Fail to include custom: %v", err)
-	    }
+		}
 	} else {
 		log.Printf("Custom dir %s doesn't exist, skipped", setting.CustomPath)
 	}
-	if err := z.AddDir("log", setting.LogRootPath); err !=nil {
+	if err := z.AddDir("log", setting.LogRootPath); err != nil {
 		log.Fatalf("Fail to include log: %v", err)
 	}
 	// FIXME: SSH key file.
@@ -94,4 +99,6 @@ func runDump(ctx *cli.Context) {
 	log.Printf("Removing tmp work dir: %s", TmpWorkDir)
 	os.RemoveAll(TmpWorkDir)
 	log.Printf("Finish dumping in file %s", fileName)
+
+	return nil
 }

+ 29 - 18
cmd/serve.go

@@ -15,12 +15,13 @@ import (
 
 	"github.com/Unknwon/com"
 	"github.com/codegangsta/cli"
+	gouuid "github.com/satori/go.uuid"
 
 	"github.com/gogits/gogs/models"
+	"github.com/gogits/gogs/modules/base"
 	"github.com/gogits/gogs/modules/httplib"
 	"github.com/gogits/gogs/modules/log"
 	"github.com/gogits/gogs/modules/setting"
-	"github.com/gogits/gogs/modules/uuid"
 )
 
 const (
@@ -41,11 +42,6 @@ func setup(logPath string) {
 	setting.NewContext()
 	log.NewGitLogger(filepath.Join(setting.LogRootPath, logPath))
 
-	if setting.DisableSSH {
-		println("Gogs: SSH has been disabled")
-		os.Exit(1)
-	}
-
 	models.LoadConfigs()
 
 	if setting.UseSQLite3 || setting.UseTiDB {
@@ -87,7 +83,7 @@ func fail(userMessage, logMessage string, args ...interface{}) {
 	os.Exit(1)
 }
 
-func handleUpdateTask(uuid string, user *models.User, username, reponame string, isWiki bool) {
+func handleUpdateTask(uuid string, user, repoUser *models.User, reponame string, isWiki bool) {
 	task, err := models.GetUpdateTaskByUUID(uuid)
 	if err != nil {
 		if models.IsErrUpdateTaskNotExist(err) {
@@ -103,14 +99,21 @@ func handleUpdateTask(uuid string, user *models.User, username, reponame string,
 		return
 	}
 
-	if err = models.Update(task.RefName, task.OldCommitID, task.NewCommitID,
-		user.Name, username, reponame, user.Id); err != nil {
+	if err = models.PushUpdate(models.PushUpdateOptions{
+		RefName:      task.RefName,
+		OldCommitID:  task.OldCommitID,
+		NewCommitID:  task.NewCommitID,
+		PusherID:     user.ID,
+		PusherName:   user.Name,
+		RepoUserName: repoUser.Name,
+		RepoName:     reponame,
+	}); err != nil {
 		log.GitLogger.Error(2, "Update: %v", err)
 	}
 
 	// Ask for running deliver hook and test pull request tasks.
-	reqURL := setting.LocalUrl + username + "/" + reponame + "/tasks/trigger?branch=" +
-		strings.TrimPrefix(task.RefName, "refs/heads/")
+	reqURL := setting.LocalURL + repoUser.Name + "/" + reponame + "/tasks/trigger?branch=" +
+		strings.TrimPrefix(task.RefName, "refs/heads/") + "&secret=" + base.EncodeMD5(repoUser.Salt)
 	log.GitLogger.Trace("Trigger task: %s", reqURL)
 
 	resp, err := httplib.Head(reqURL).SetTLSClientConfig(&tls.Config{
@@ -126,12 +129,18 @@ func handleUpdateTask(uuid string, user *models.User, username, reponame string,
 	}
 }
 
-func runServ(c *cli.Context) {
+func runServ(c *cli.Context) error {
 	if c.IsSet("config") {
 		setting.CustomConf = c.String("config")
 	}
+
 	setup("serv.log")
 
+	if setting.SSH.Disabled {
+		println("Gogs: SSH has been disabled")
+		return nil
+	}
+
 	if len(c.Args()) < 1 {
 		fail("Not enough arguments", "Not enough arguments")
 	}
@@ -140,7 +149,7 @@ func runServ(c *cli.Context) {
 	if len(cmd) == 0 {
 		println("Hi there, You've successfully authenticated, but Gogs does not provide shell access.")
 		println("If this is unexpected, please log in with password and setup Gogs under another user.")
-		return
+		return nil
 	}
 
 	verb, args := parseCmd(cmd)
@@ -163,10 +172,10 @@ func runServ(c *cli.Context) {
 		if models.IsErrUserNotExist(err) {
 			fail("Repository owner does not exist", "Unregistered owner: %s", username)
 		}
-		fail("Internal error", "Failed to get repository owner(%s): %v", username, err)
+		fail("Internal error", "Failed to get repository owner (%s): %v", username, err)
 	}
 
-	repo, err := models.GetRepositoryByName(repoUser.Id, reponame)
+	repo, err := models.GetRepositoryByName(repoUser.ID, reponame)
 	if err != nil {
 		if models.IsErrRepoNotExist(err) {
 			fail(_ACCESS_DENIED_MESSAGE, "Repository does not exist: %s/%s", repoUser.Name, reponame)
@@ -208,7 +217,7 @@ func runServ(c *cli.Context) {
 			}
 			// Check if this deploy key belongs to current repository.
 			if !models.HasDeployKey(key.ID, repo.ID) {
-				fail("Key access denied", "Key access denied: %d-%d", key.ID, repo.ID)
+				fail("Key access denied", "Deploy key access denied: [key_id: %d, repo_id: %d]", key.ID, repo.ID)
 			}
 
 			// Update deploy key activity.
@@ -242,7 +251,7 @@ func runServ(c *cli.Context) {
 		}
 	}
 
-	uuid := uuid.NewV4().String()
+	uuid := gouuid.NewV4().String()
 	os.Setenv("uuid", uuid)
 
 	// Special handle for Windows.
@@ -266,7 +275,7 @@ func runServ(c *cli.Context) {
 	}
 
 	if requestedMode == models.ACCESS_MODE_WRITE {
-		handleUpdateTask(uuid, user, username, reponame, isWiki)
+		handleUpdateTask(uuid, user, repoUser, reponame, isWiki)
 	}
 
 	// Update user key activity.
@@ -281,4 +290,6 @@ func runServ(c *cli.Context) {
 			fail("Internal error", "UpdatePublicKey: %v", err)
 		}
 	}
+
+	return nil
 }

+ 12 - 9
cmd/update.go

@@ -16,7 +16,7 @@ import (
 
 var CmdUpdate = cli.Command{
 	Name:        "update",
-	Usage:       "This command should only be called by SSH shell",
+	Usage:       "This command should only be called by Git hook",
 	Description: `Update get pushed info and insert into database`,
 	Action:      runUpdate,
 	Flags: []cli.Flag{
@@ -24,22 +24,23 @@ var CmdUpdate = cli.Command{
 	},
 }
 
-func runUpdate(c *cli.Context) {
+func runUpdate(c *cli.Context) error {
 	if c.IsSet("config") {
 		setting.CustomConf = c.String("config")
 	}
-	cmd := os.Getenv("SSH_ORIGINAL_COMMAND")
-	if cmd == "" {
-		return
-	}
 
 	setup("update.log")
 
+	if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
+		log.GitLogger.Trace("SSH_ORIGINAL_COMMAND is empty")
+		return nil
+	}
+
 	args := c.Args()
 	if len(args) != 3 {
-		log.GitLogger.Fatal(2, "received less 3 parameters")
-	} else if args[0] == "" {
-		log.GitLogger.Fatal(2, "refName is empty, shouldn't use")
+		log.GitLogger.Fatal(2, "Arguments received are not equal to three")
+	} else if len(args[0]) == 0 {
+		log.GitLogger.Fatal(2, "First argument 'refName' is empty, shouldn't use")
 	}
 
 	task := models.UpdateTask{
@@ -52,4 +53,6 @@ func runUpdate(c *cli.Context) {
 	if err := models.AddUpdateTask(&task); err != nil {
 		log.GitLogger.Fatal(2, "AddUpdateTask: %v", err)
 	}
+
+	return nil
 }

+ 107 - 69
cmd/web.go

@@ -7,7 +7,6 @@ package cmd
 import (
 	"crypto/tls"
 	"fmt"
-	gotmpl "html/template"
 	"io/ioutil"
 	"net/http"
 	"net/http/fcgi"
@@ -29,14 +28,14 @@ import (
 	"gopkg.in/ini.v1"
 	"gopkg.in/macaron.v1"
 
-	"github.com/gogits/git-shell"
+	"github.com/gogits/git-module"
+	"github.com/gogits/go-gogs-client"
 
 	"github.com/gogits/gogs/models"
 	"github.com/gogits/gogs/modules/auth"
-	"github.com/gogits/gogs/modules/avatar"
 	"github.com/gogits/gogs/modules/bindata"
+	"github.com/gogits/gogs/modules/context"
 	"github.com/gogits/gogs/modules/log"
-	"github.com/gogits/gogs/modules/middleware"
 	"github.com/gogits/gogs/modules/setting"
 	"github.com/gogits/gogs/modules/template"
 	"github.com/gogits/gogs/routers"
@@ -79,20 +78,24 @@ func checkVersion() {
 
 	// Check dependency version.
 	checkers := []VerChecker{
-		{"github.com/go-xorm/xorm", func() string { return xorm.Version }, "0.4.4.1029"},
-		{"github.com/go-macaron/binding", binding.Version, "0.1.0"},
+		{"github.com/go-xorm/xorm", func() string { return xorm.Version }, "0.5.5"},
+		{"github.com/go-macaron/binding", binding.Version, "0.3.2"},
 		{"github.com/go-macaron/cache", cache.Version, "0.1.2"},
-		{"github.com/go-macaron/csrf", csrf.Version, "0.0.3"},
-		{"github.com/go-macaron/i18n", i18n.Version, "0.2.0"},
+		{"github.com/go-macaron/csrf", csrf.Version, "0.1.0"},
+		{"github.com/go-macaron/i18n", i18n.Version, "0.3.0"},
 		{"github.com/go-macaron/session", session.Version, "0.1.6"},
 		{"github.com/go-macaron/toolbox", toolbox.Version, "0.1.0"},
 		{"gopkg.in/ini.v1", ini.Version, "1.8.4"},
-		{"gopkg.in/macaron.v1", macaron.Version, "0.8.0"},
-		{"github.com/gogits/git-shell", git.Version, "0.1.0"},
+		{"gopkg.in/macaron.v1", macaron.Version, "1.1.4"},
+		{"github.com/gogits/git-module", git.Version, "0.3.3"},
+		{"github.com/gogits/go-gogs-client", gogs.Version, "0.7.4"},
 	}
 	for _, c := range checkers {
 		if !version.Compare(c.Version(), c.Expected, ">=") {
-			log.Fatal(4, "Package '%s' version is too old (%s -> %s), did you forget to update?", c.ImportPath, c.Version(), c.Expected)
+			log.Fatal(4, `Dependency outdated!
+Package '%s' current version (%s) is below requirement (%s), 
+please use following command to update this package and recompile Gogs:
+go get -u %[1]s`, c.ImportPath, c.Version(), c.Expected)
 		}
 	}
 }
@@ -123,11 +126,16 @@ func newMacaron() *macaron.Macaron {
 			SkipLogging: setting.DisableRouterLog,
 		},
 	))
+
+	funcMap := template.NewFuncMap()
 	m.Use(macaron.Renderer(macaron.RenderOptions{
-		Directory:  path.Join(setting.StaticRootPath, "templates"),
-		Funcs:      []gotmpl.FuncMap{template.Funcs},
-		IndentJSON: macaron.Env != macaron.PROD,
+		Directory:         path.Join(setting.StaticRootPath, "templates"),
+		AppendDirectories: []string{path.Join(setting.CustomPath, "templates")},
+		Funcs:             funcMap,
+		IndentJSON:        macaron.Env != macaron.PROD,
 	}))
+	models.InitMailRender(path.Join(setting.StaticRootPath, "templates/mail"),
+		path.Join(setting.CustomPath, "templates/mail"), funcMap)
 
 	localeNames, err := bindata.AssetDir("conf/locale")
 	if err != nil {
@@ -157,6 +165,7 @@ func newMacaron() *macaron.Macaron {
 	m.Use(session.Sessioner(setting.SessionConfig))
 	m.Use(csrf.Csrfer(csrf.Options{
 		Secret:     setting.SecretKey,
+		Cookie:     setting.CSRFCookieName,
 		SetCookie:  true,
 		Header:     "X-Csrf-Token",
 		CookiePath: setting.AppSubUrl,
@@ -169,11 +178,11 @@ func newMacaron() *macaron.Macaron {
 			},
 		},
 	}))
-	m.Use(middleware.Contexter())
+	m.Use(context.Contexter())
 	return m
 }
 
-func runWeb(ctx *cli.Context) {
+func runWeb(ctx *cli.Context) error {
 	if ctx.IsSet("config") {
 		setting.CustomConf = ctx.String("config")
 	}
@@ -182,26 +191,28 @@ func runWeb(ctx *cli.Context) {
 
 	m := newMacaron()
 
-	reqSignIn := middleware.Toggle(&middleware.ToggleOptions{SignInRequire: true})
-	ignSignIn := middleware.Toggle(&middleware.ToggleOptions{SignInRequire: setting.Service.RequireSignInView})
-	ignSignInAndCsrf := middleware.Toggle(&middleware.ToggleOptions{DisableCsrf: true})
-	reqSignOut := middleware.Toggle(&middleware.ToggleOptions{SignOutRequire: true})
+	reqSignIn := context.Toggle(&context.ToggleOptions{SignInRequired: true})
+	ignSignIn := context.Toggle(&context.ToggleOptions{SignInRequired: setting.Service.RequireSignInView})
+	ignSignInAndCsrf := context.Toggle(&context.ToggleOptions{DisableCSRF: true})
+	reqSignOut := context.Toggle(&context.ToggleOptions{SignOutRequired: true})
 
 	bindIgnErr := binding.BindIgnErr
 
+	// FIXME: not all routes need go through same middlewares.
+	// Especially some AJAX requests, we can reduce middleware number to improve performance.
 	// Routers.
 	m.Get("/", ignSignIn, routers.Home)
-	m.Get("/explore", ignSignIn, routers.Explore)
+	m.Group("/explore", func() {
+		m.Get("", func(ctx *context.Context) {
+			ctx.Redirect(setting.AppSubUrl + "/explore/repos")
+		})
+		m.Get("/repos", routers.ExploreRepos)
+		m.Get("/users", routers.ExploreUsers)
+	}, ignSignIn)
 	m.Combo("/install", routers.InstallInit).Get(routers.Install).
 		Post(bindIgnErr(auth.InstallForm{}), routers.InstallPost)
 	m.Get("/^:type(issues|pulls)$", reqSignIn, user.Issues)
 
-	// ***** START: API *****
-	m.Group("/api", func() {
-		apiv1.RegisterRoutes(m)
-	}, ignSignIn)
-	// ***** END: API *****
-
 	// ***** START: User *****
 	m.Group("/user", func() {
 		m.Get("/login", user.SignIn)
@@ -216,6 +227,7 @@ func runWeb(ctx *cli.Context) {
 		m.Get("", user.Settings)
 		m.Post("", bindIgnErr(auth.UpdateProfileForm{}), user.SettingsPost)
 		m.Post("/avatar", binding.MultipartForm(auth.UploadAvatarForm{}), user.SettingsAvatar)
+		m.Post("/avatar/delete", user.SettingsDeleteAvatar)
 		m.Combo("/email").Get(user.SettingsEmails).
 			Post(bindIgnErr(auth.AddEmailForm{}), user.SettingsEmailPost)
 		m.Post("/email/delete", user.DeleteEmail)
@@ -228,7 +240,7 @@ func runWeb(ctx *cli.Context) {
 			Post(bindIgnErr(auth.NewAccessTokenForm{}), user.SettingsApplicationsPost)
 		m.Post("/applications/delete", user.SettingsDeleteApplication)
 		m.Route("/delete", "GET,POST", user.SettingsDelete)
-	}, reqSignIn, func(ctx *middleware.Context) {
+	}, reqSignIn, func(ctx *context.Context) {
 		ctx.Data["PageIsUserSettings"] = true
 	})
 
@@ -243,17 +255,13 @@ func runWeb(ctx *cli.Context) {
 	})
 	// ***** END: User *****
 
-	// Gravatar service.
-	avt := avatar.CacheServer("public/img/avatar/", "public/img/avatar_default.jpg")
-	os.MkdirAll("public/img/avatar/", os.ModePerm)
-	m.Get("/avatar/:hash", avt.ServeHTTP)
-
-	adminReq := middleware.Toggle(&middleware.ToggleOptions{SignInRequire: true, AdminRequire: true})
+	adminReq := context.Toggle(&context.ToggleOptions{SignInRequired: true, AdminRequired: true})
 
 	// ***** START: Admin *****
 	m.Group("/admin", func() {
 		m.Get("", adminReq, admin.Dashboard)
 		m.Get("/config", admin.Config)
+		m.Post("/config/test_mail", admin.SendTestMail)
 		m.Get("/monitor", admin.Monitor)
 
 		m.Group("/users", func() {
@@ -289,8 +297,14 @@ func runWeb(ctx *cli.Context) {
 	// ***** END: Admin *****
 
 	m.Group("", func() {
-		m.Get("/:username", user.Profile)
-		m.Get("/attachments/:uuid", func(ctx *middleware.Context) {
+		m.Group("/:username", func() {
+			m.Get("", user.Profile)
+			m.Get("/followers", user.Followers)
+			m.Get("/following", user.Following)
+			m.Get("/stars", user.Stars)
+		})
+
+		m.Get("/attachments/:uuid", func(ctx *context.Context) {
 			attach, err := models.GetAttachmentByUUID(ctx.Params(":uuid"))
 			if err != nil {
 				if models.IsErrAttachmentNotExist(err) {
@@ -319,12 +333,16 @@ func runWeb(ctx *cli.Context) {
 		m.Post("/issues/attachments", repo.UploadIssueAttachment)
 	}, ignSignIn)
 
+	m.Group("/:username", func() {
+		m.Get("/action/:action", user.Action)
+	}, reqSignIn)
+
 	if macaron.Env == macaron.DEV {
 		m.Get("/template/*", dev.TemplatePreview)
 	}
 
-	reqRepoAdmin := middleware.RequireRepoAdmin()
-	reqRepoPusher := middleware.RequireRepoPusher()
+	reqRepoAdmin := context.RequireRepoAdmin()
+	reqRepoWriter := context.RequireRepoWriter()
 
 	// ***** START: Organization *****
 	m.Group("/org", func() {
@@ -338,11 +356,14 @@ func runWeb(ctx *cli.Context) {
 			m.Get("/members/action/:action", org.MembersAction)
 
 			m.Get("/teams", org.Teams)
+		}, context.OrgAssignment(true))
+
+		m.Group("/:org", func() {
 			m.Get("/teams/:team", org.TeamMembers)
 			m.Get("/teams/:team/repositories", org.TeamRepositories)
 			m.Route("/teams/:team/action/:action", "GET,POST", org.TeamsAction)
 			m.Route("/teams/:team/action/repo/:action", "GET,POST", org.TeamsRepoAction)
-		}, middleware.OrgAssignment(true))
+		}, context.OrgAssignment(true, false, true))
 
 		m.Group("/:org", func() {
 			m.Get("/teams/new", org.NewTeam)
@@ -355,6 +376,7 @@ func runWeb(ctx *cli.Context) {
 				m.Combo("").Get(org.Settings).
 					Post(bindIgnErr(auth.UpdateOrgSettingForm{}), org.SettingsPost)
 				m.Post("/avatar", binding.MultipartForm(auth.UploadAvatarForm{}), org.SettingsAvatar)
+				m.Post("/avatar/delete", org.SettingsDeleteAvatar)
 
 				m.Group("/hooks", func() {
 					m.Get("", org.Webhooks)
@@ -371,7 +393,7 @@ func runWeb(ctx *cli.Context) {
 			})
 
 			m.Route("/invitations/new", "GET,POST", org.Invitation)
-		}, middleware.OrgAssignment(true, true))
+		}, context.OrgAssignment(true, true))
 	}, reqSignIn)
 	// ***** END: Organization *****
 
@@ -389,7 +411,11 @@ func runWeb(ctx *cli.Context) {
 		m.Group("/settings", func() {
 			m.Combo("").Get(repo.Settings).
 				Post(bindIgnErr(auth.RepoSettingForm{}), repo.SettingsPost)
-			m.Route("/collaboration", "GET,POST", repo.Collaboration)
+			m.Group("/collaboration", func() {
+				m.Combo("").Get(repo.Collaboration).Post(repo.CollaborationPost)
+				m.Post("/access_mode", repo.ChangeCollaborationAccessMode)
+				m.Post("/delete", repo.DeleteCollaboration)
+			})
 
 			m.Group("/hooks", func() {
 				m.Get("", repo.Webhooks)
@@ -406,7 +432,7 @@ func runWeb(ctx *cli.Context) {
 					m.Get("", repo.GitHooks)
 					m.Combo("/:name").Get(repo.GitHooksEdit).
 						Post(repo.GitHooksEditPost)
-				}, middleware.GitHookService())
+				}, context.GitHookService())
 			})
 
 			m.Group("/keys", func() {
@@ -415,16 +441,15 @@ func runWeb(ctx *cli.Context) {
 				m.Post("/delete", repo.DeleteDeployKey)
 			})
 
-		}, func(ctx *middleware.Context) {
+		}, func(ctx *context.Context) {
 			ctx.Data["PageIsSettings"] = true
 		})
-	}, reqSignIn, middleware.RepoAssignment(), reqRepoAdmin, middleware.RepoRef())
+	}, reqSignIn, context.RepoAssignment(), reqRepoAdmin, context.RepoRef())
 
+	m.Get("/:username/:reponame/action/:action", reqSignIn, context.RepoAssignment(), repo.Action)
 	m.Group("/:username/:reponame", func() {
-		m.Get("/action/:action", repo.Action)
-
 		m.Group("/issues", func() {
-			m.Combo("/new", repo.MustEnableIssues).Get(middleware.RepoRef(), repo.NewIssue).
+			m.Combo("/new", repo.MustEnableIssues).Get(context.RepoRef(), repo.NewIssue).
 				Post(bindIgnErr(auth.CreateIssueForm{}), repo.NewIssuePost)
 
 			m.Combo("/:index/comments").Post(bindIgnErr(auth.CreateCommentForm{}), repo.NewComment)
@@ -432,19 +457,22 @@ func runWeb(ctx *cli.Context) {
 				m.Post("/label", repo.UpdateIssueLabel)
 				m.Post("/milestone", repo.UpdateIssueMilestone)
 				m.Post("/assignee", repo.UpdateIssueAssignee)
-			}, reqRepoAdmin)
+			}, reqRepoWriter)
 
 			m.Group("/:index", func() {
 				m.Post("/title", repo.UpdateIssueTitle)
 				m.Post("/content", repo.UpdateIssueContent)
 			})
 		})
-		m.Post("/comments/:id", repo.UpdateCommentContent)
+		m.Group("/comments/:id", func() {
+			m.Post("", repo.UpdateCommentContent)
+			m.Post("/delete", repo.DeleteComment)
+		})
 		m.Group("/labels", func() {
 			m.Post("/new", bindIgnErr(auth.CreateLabelForm{}), repo.NewLabel)
 			m.Post("/edit", bindIgnErr(auth.CreateLabelForm{}), repo.UpdateLabel)
 			m.Post("/delete", repo.DeleteLabel)
-		}, reqRepoAdmin, middleware.RepoRef())
+		}, reqRepoWriter, context.RepoRef())
 		m.Group("/milestones", func() {
 			m.Combo("/new").Get(repo.NewMilestone).
 				Post(bindIgnErr(auth.CreateMilestoneForm{}), repo.NewMilestonePost)
@@ -452,7 +480,7 @@ func runWeb(ctx *cli.Context) {
 			m.Post("/:id/edit", bindIgnErr(auth.CreateMilestoneForm{}), repo.EditMilestonePost)
 			m.Get("/:id/:action", repo.ChangeMilestonStatus)
 			m.Post("/delete", repo.DeleteMilestone)
-		}, reqRepoAdmin, middleware.RepoRef())
+		}, reqRepoWriter, context.RepoRef())
 
 		m.Group("/releases", func() {
 			m.Get("/new", repo.NewRelease)
@@ -460,11 +488,11 @@ func runWeb(ctx *cli.Context) {
 			m.Get("/edit/:tagname", repo.EditRelease)
 			m.Post("/edit/:tagname", bindIgnErr(auth.EditReleaseForm{}), repo.EditReleasePost)
 			m.Post("/delete", repo.DeleteRelease)
-		}, reqRepoAdmin, middleware.RepoRef())
+		}, reqRepoWriter, context.RepoRef())
 
-		m.Combo("/compare/*", repo.MustEnablePulls).Get(repo.CompareAndPullRequest).
+		m.Combo("/compare/*", repo.MustAllowPulls).Get(repo.CompareAndPullRequest).
 			Post(bindIgnErr(auth.CreateIssueForm{}), repo.CompareAndPullRequestPost)
-	}, reqSignIn, middleware.RepoAssignment())
+	}, reqSignIn, context.RepoAssignment(), repo.MustBeNotBare)
 
 	m.Group("/:username/:reponame", func() {
 		m.Group("", func() {
@@ -473,7 +501,7 @@ func runWeb(ctx *cli.Context) {
 			m.Get("/^:type(issues|pulls)$/:index", repo.ViewIssue)
 			m.Get("/labels/", repo.RetrieveLabels, repo.Labels)
 			m.Get("/milestones", repo.Milestones)
-		}, middleware.RepoRef())
+		}, context.RepoRef())
 
 		// m.Get("/branches", repo.Branches)
 
@@ -486,35 +514,39 @@ func runWeb(ctx *cli.Context) {
 					Post(bindIgnErr(auth.NewWikiForm{}), repo.NewWikiPost)
 				m.Combo("/:page/_edit").Get(repo.EditWiki).
 					Post(bindIgnErr(auth.NewWikiForm{}), repo.EditWikiPost)
-			}, reqSignIn, reqRepoPusher)
-		}, repo.MustEnableWiki, middleware.RepoRef())
+				m.Post("/:page/delete", repo.DeleteWikiPagePost)
+			}, reqSignIn, reqRepoWriter)
+		}, repo.MustEnableWiki, context.RepoRef())
 
 		m.Get("/archive/*", repo.Download)
 
 		m.Group("/pulls/:index", func() {
-			m.Get("/commits", repo.ViewPullCommits)
-			m.Get("/files", repo.ViewPullFiles)
-			m.Post("/merge", reqRepoAdmin, repo.MergePullRequest)
-		}, repo.MustEnablePulls)
+			m.Get("/commits", context.RepoRef(), repo.ViewPullCommits)
+			m.Get("/files", context.RepoRef(), repo.ViewPullFiles)
+			m.Post("/merge", reqRepoWriter, repo.MergePullRequest)
+		}, repo.MustAllowPulls)
 
 		m.Group("", func() {
 			m.Get("/src/*", repo.Home)
 			m.Get("/raw/*", repo.SingleDownload)
 			m.Get("/commits/*", repo.RefCommits)
-			m.Get("/commit/*", repo.Diff)
-			m.Get("/stars", repo.Stars)
-			m.Get("/watchers", repo.Watchers)
+			m.Get("/commit/:sha([a-z0-9]{40})$", repo.Diff)
 			m.Get("/forks", repo.Forks)
-		}, middleware.RepoRef())
+		}, context.RepoRef())
+		m.Get("/commit/:sha([a-z0-9]{40})\\.:ext(patch|diff)", repo.RawDiff)
 
-		m.Get("/compare/:before([a-z0-9]{40})...:after([a-z0-9]{40})", repo.CompareDiff)
-	}, ignSignIn, middleware.RepoAssignment())
+		m.Get("/compare/:before([a-z0-9]{40})\\.\\.\\.:after([a-z0-9]{40})", repo.CompareDiff)
+	}, ignSignIn, context.RepoAssignment(), repo.MustBeNotBare)
+	m.Group("/:username/:reponame", func() {
+		m.Get("/stars", repo.Stars)
+		m.Get("/watchers", repo.Watchers)
+	}, ignSignIn, context.RepoAssignment(), context.RepoRef())
 
 	m.Group("/:username", func() {
 		m.Group("/:reponame", func() {
 			m.Get("", repo.Home)
 			m.Get("\\.git$", repo.Home)
-		}, ignSignIn, middleware.RepoAssignment(true), middleware.RepoRef())
+		}, ignSignIn, context.RepoAssignment(true), context.RepoRef())
 
 		m.Group("/:reponame", func() {
 			m.Any("/*", ignSignInAndCsrf, repo.HTTP)
@@ -523,8 +555,12 @@ func runWeb(ctx *cli.Context) {
 	})
 	// ***** END: Repository *****
 
+	m.Group("/api", func() {
+		apiv1.RegisterRoutes(m)
+	}, ignSignIn)
+
 	// robots.txt
-	m.Get("/robots.txt", func(ctx *middleware.Context) {
+	m.Get("/robots.txt", func(ctx *context.Context) {
 		if setting.HasRobotsTxt {
 			ctx.ServeFileContent(path.Join(setting.CustomPath, "robots.txt"))
 		} else {
@@ -559,4 +595,6 @@ func runWeb(ctx *cli.Context) {
 	if err != nil {
 		log.Fatal(4, "Fail to start server: %v", err)
 	}
+
+	return nil
 }

+ 1 - 5
conf/README.md

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

+ 79 - 34
conf/app.ini

@@ -12,7 +12,7 @@ RUN_MODE = dev
 ROOT =
 SCRIPT_TYPE = bash
 ; Default ANSI charset
-ANSI_CHARSET = 
+ANSI_CHARSET =
 ; Force every new repository to be private
 FORCE_PRIVATE = false
 ; Global maximum creation limit of repository per user, -1 means no limit
@@ -27,6 +27,12 @@ EXPLORE_PAGING_NUM = 20
 ISSUE_PAGING_NUM = 10
 ; Number of maximum commits showed in one activity feed
 FEED_MAX_COMMIT_NUM = 5
+; Value of `theme-color` meta tag, used by Android >= 5.0
+; An invalid color like "none" or "disable" will have the default style
+; More info: https://developers.google.com/web/updates/2014/11/Support-for-theme-color-in-Chrome-39-for-Android
+THEME_COLOR_META_TAG = `#ff5343`
+; Max size of files to be displayed (defaults is 8MiB)
+MAX_DISPLAY_FILE_SIZE = 8388608
 
 [ui.admin]
 ; Number of users that are showed in one page
@@ -38,30 +44,50 @@ NOTICE_PAGING_NUM = 25
 ; Number of organization that are showed in one page
 ORG_PAGING_NUM = 50
 
+[ui.user]
+; Number of repos that are showed in one page
+REPO_PAGING_NUM = 15
+
 [markdown]
 ; Enable hard line break extension
 ENABLE_HARD_LINE_BREAK = false
+; List of custom URL-Schemes that are allowed as links when rendering Markdown
+; for example git,magnet
+CUSTOM_URL_SCHEMES =
 
 [server]
 PROTOCOL = http
 DOMAIN = localhost
 ROOT_URL = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s/
-HTTP_ADDR =
+HTTP_ADDR = 0.0.0.0
 HTTP_PORT = 3000
 ; Local (DMZ) URL for Gogs workers (such as SSH update) accessing web service.
 ; In most cases you do not need to change the default value.
 ; Alter it only if your SSH server node is not the same as HTTP node.
-LOCAL_ROOT_URL = http://localhost:%(HTTP_PORT)s/
+LOCAL_ROOT_URL = %(PROTOCOL)s://%(HTTP_ADDR)s:%(HTTP_PORT)s/
 ; Disable SSH feature when not available
 DISABLE_SSH = false
 ; Whether use builtin SSH server or not.
 START_SSH_SERVER = false
+; Domain name to be exposed in clone URL
+SSH_DOMAIN = %(DOMAIN)s
+; Port number to be exposed in clone URL
 SSH_PORT = 22
+; Port number builtin SSH server listens on
+SSH_LISTEN_PORT = %(SSH_PORT)s
+; Root path of SSH directory, default is '~/.ssh', but you have to use '/home/git/.ssh'.
+SSH_ROOT_PATH =
+; Directory to create temporary files when test publick key using ssh-keygen,
+; default is system temporary directory.
+SSH_KEY_TEST_PATH =
+; Path to ssh-keygen, default is 'ssh-keygen' and let shell find out which one to call.
+SSH_KEYGEN_PATH = ssh-keygen
+; Indicate whether to check minimum key size with corresponding type
+MINIMUM_KEY_SIZE_CHECK = false
 ; Disable CDN even in "prod" mode
 OFFLINE_MODE = false
 DISABLE_ROUTER_LOG = false
 ; Generate steps:
-; $ cd path/to/gogs/custom/https
 ; $ ./gogs cert -ca=true -duration=8760h0m0s -host=myhost.example.com
 ;
 ; Or from a .pfx file exported from the Windows certificate store (do
@@ -73,11 +99,20 @@ KEY_FILE = custom/https/key.pem
 ; Upper level of template and static file path
 ; default is the path where Gogs is executed
 STATIC_ROOT_PATH =
+; Default path for App data
+APP_DATA_PATH = data
 ; Application level GZIP support
 ENABLE_GZIP = false
 ; Landing page for non-logged users, can be "home" or "explore"
 LANDING_PAGE = home
 
+; Define allowed algorithms and their minimum key length (use -1 to disable a type)
+[ssh.minimum_key_sizes]
+ED25519 = 256
+ECDSA   = 256
+RSA     = 2048
+DSA     = 1024
+
 [database]
 ; Either "mysql", "postgres" or "sqlite3", it's your choice
 DB_TYPE = mysql
@@ -87,7 +122,7 @@ USER = root
 PASSWD =
 ; For "postgres" only, either "disable", "require" or "verify-full"
 SSL_MODE = disable
-; For "sqlite3" and "tidb"
+; For "sqlite3" and "tidb", use absolute path when you start as service
 PATH = data/gogs.db
 
 [admin]
@@ -112,28 +147,14 @@ REGISTER_EMAIL_CONFIRM = false
 DISABLE_REGISTRATION = false
 ; User must sign in to view anything.
 REQUIRE_SIGNIN_VIEW = false
-; Cache avatar as picture
-ENABLE_CACHE_AVATAR = false
 ; Mail notification
 ENABLE_NOTIFY_MAIL = false
 ; More detail: https://github.com/gogits/gogs/issues/165
 ENABLE_REVERSE_PROXY_AUTHENTICATION = false
 ENABLE_REVERSE_PROXY_AUTO_REGISTRATION = false
-; Do not check minimum key size with corresponding type
-DISABLE_MINIMUM_KEY_SIZE_CHECK = false
 ; Enable captcha validation for registration
 ENABLE_CAPTCHA = true
 
-; used to filter keys which are too short
-[service.minimum_key_sizes]
-ED25519 = 256
-ECDSA   = 256
-NTRU    = 1087
-MCE     = 1702
-McE     = 1702
-RSA     = 1024
-DSA     = 1024
-
 [webhook]
 ; Hook task queue length
 QUEUE_LENGTH = 1000
@@ -152,24 +173,26 @@ SEND_BUFFER_LEN = 100
 SUBJECT = %(APP_NAME)s
 ; Mail server
 ; Gmail: smtp.gmail.com:587
-; QQ: smtp.qq.com:25
+; QQ: smtp.qq.com:465
 ; Note, if the port ends with "465", SMTPS will be used. Using STARTTLS on port 587 is recommended per RFC 6409. If the server supports STARTTLS it will always be used.
-HOST = 
+HOST =
 ; Disable HELO operation when hostname are different.
-DISABLE_HELO = 
+DISABLE_HELO =
 ; Custom hostname for HELO operation, default is from system.
-HELO_HOSTNAME = 
+HELO_HOSTNAME =
 ; Do not verify the certificate of the server. Only use this for self-signed certificates
-SKIP_VERIFY = 
+SKIP_VERIFY =
 ; Use client certificate
 USE_CERTIFICATE = false
 CERT_FILE = custom/mailer/cert.pem
 KEY_FILE = custom/mailer/key.pem
-; Mail from address, RFC 5322. This can be just an email address, or the `"Name" <email@example.com>` format 
+; Mail from address, RFC 5322. This can be just an email address, or the `"Name" <email@example.com>` format
 FROM =
 ; Mailer user name and password
 USER =
 PASSWD =
+; Use text/html as alternative format of content
+ENABLE_HTML_ALTERNATIVE = false
 
 [cache]
 ; Either "memory", "redis", or "memcache", default is "memory"
@@ -182,7 +205,7 @@ INTERVAL = 60
 HOST =
 
 [session]
-; Either "memory", "file", "redis" or "mysql", default is "memory"
+; Either "memory", "file", or "redis", default is "memory"
 PROVIDER = memory
 ; Provider config options
 ; memory: not have any config yet
@@ -202,8 +225,6 @@ GC_INTERVAL_TIME = 86400
 SESSION_LIFE_TIME = 86400
 
 [picture]
-; The place to picture data, either "server" or "qiniu", default is "server"
-SERVICE = server
 AVATAR_UPLOAD_PATH = data/avatars
 ; Chinese users can choose "duoshuo"
 ; or a custom avatar source, like: http://cn.gravatar.com/avatar/
@@ -297,7 +318,7 @@ RUN_AT_START = false
 
 ; Update mirrors
 [cron.update_mirrors]
-SCHEDULE = @every 1h
+SCHEDULE = @every 10m
 
 ; Repository health check
 [cron.repo_health_check]
@@ -305,7 +326,7 @@ SCHEDULE = @every 24h
 TIMEOUT = 60s
 ; Arguments for command 'git fsck', e.g. "--unreachable --tags"
 ; see more on http://git-scm.com/docs/git-fsck/1.7.5
-ARGS = 
+ARGS =
 
 ; Check repository statistics
 [cron.check_repo_stats]
@@ -313,20 +334,37 @@ RUN_AT_START = true
 SCHEDULE = @every 24h
 
 [git]
-MAX_GIT_DIFF_LINES = 10000
+; Max number of lines allowed of a single file in diff view.
+MAX_GIT_DIFF_LINES = 1000
+; Max number of characters of a line allowed in diff view.
+MAX_GIT_DIFF_LINE_CHARACTERS = 500
+; Max number of files shown in diff view.
+MAX_GIT_DIFF_FILES = 100
 ; Arguments for command 'git gc', e.g. "--aggressive --auto"
 ; see more on http://git-scm.com/docs/git-gc/1.7.5
-GC_ARGS = 
+GC_ARGS =
+
+; Operation timeout in seconds
+[git.timeout]
+MIGRATE = 600
+MIRROR = 300
+CLONE = 300
+PULL = 300
+
+[api]
+; Max number of items will response in a page
+MAX_RESPONSE_ITEMS = 50
 
 [i18n]
-LANGS = en-US,zh-CN,zh-HK,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,ja-JP,es-ES,pt-BR,pl-PL,bg-BG,it-IT
-NAMES = English,简体中文,繁體中文,Deutsch,Français,Nederlands,Latviešu,Русский,日本語,Español,Português do Brasil,Polski,български,Italiano
+LANGS = en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,ja-JP,es-ES,pt-BR,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ
+NAMES = English,简体中文,繁體中文(香港),繁體中文(台湾),Deutsch,Français,Nederlands,Latviešu,Русский,日本語,Español,Português do Brasil,Polski,български,Italiano,Suomalainen,Türkçe,čeština
 
 ; Used for datetimepicker
 [i18n.datelang]
 en-US = en
 zh-CN = zh
 zh-HK = zh-TW
+zh-TW = zh-TW
 de-DE = de
 fr-FR = fr
 nl-NL = nl
@@ -338,6 +376,13 @@ pt-BR = pt-BR
 pl-PL = pl
 bg-BG = bg
 it-IT = it
+fi-FI = fi
+tr-TR = tr
+cs-CZ = cs-CZ
+
+; Extension mapping to highlight class
+; e.g. .toml=ini
+[highlight.mapping]
 
 [other]
 SHOW_FOOTER_BRANDING = false

File diff suppressed because it is too large
+ 0 - 39
conf/license/Creative Commons Zero v1.0 Universal


+ 1 - 2
conf/license/ISC license

@@ -1,6 +1,5 @@
 ISC License:
-Copyright (c) 2004-2010 by Internet Systems Consortium, Inc. ("ISC") 
-Copyright (c) 1995-2003 by Internet Software Consortium
+Copyright (c) Year(s), Company or Person's Name
 
 Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
 

+ 32 - 1
conf/locale/TRANSLATORS

@@ -1,30 +1,61 @@
 # This file lists all PUBLIC individuals having contributed content to the translation.
 # Entries are in alphabetical order.
 
+Adam Strzelecki <ono AT java DOT pl>
+Adrian Verde <me AT adrianverde DOT com>
 Akihiro YAGASAKI <yaggytter AT momiage DOT com>
+Aleksejs Grocevs <aleksejs AT grocevs DOT pro>
+Aleksey Tarakin <hukendo AT yandex DOT ru>
 Alexander Steinhöfer <kontakt AT lx-s DOT de>
 Alexandre Magno <alexandre DOT mbm AT gmail DOT com>
 Andrey Nering <andrey AT nering DOT com DOT br>
+Andrey Solomatin <toadron AT yandex DOT ru>
+Antoine GIRARD <sapk AT sapk DOT fr>
 Arthur Aslanyan <arthur DOT e DOT aslanyan AT gmail DOT com>
+Aurelien Darragon <aurelien DOT darragon AT gmail DOT com>
 Barış Arda Yılmaz <ardayilmazgamer AT gmail DOT com>
+Camille Baronnet <gogs AT camillebaronnet DOT fr>
 Christoph Kisfeld <christoph DOT kisfeld AT gmail DOT com>
+Cysioland
 Daniel Speichert <daniel AT speichert DOT pl>
+David Yzaguirre <dvdyzag AT gmail DOT com>
 Dmitriy Nogay <me AT catwhocode DOT ga>
+Enrico Testori hypertesto AT gmail DOT com
+Ezequiel Gonzalez Rial <gonrial AT gmail DOT com>
+Gabriel Dugny <gabriel DOT dugny AT gmail DOT com>
 Gregor Santner <gdev AT live DOT de>
+Halil Kaya <halil AT halilkaya DOT net>
 Hamid Feizabadi <hamidfzm AT gmail DOT com>
 Huimin Wang <wanghm2009 AT hotmail DOT co DOT jp>
-ilko
+ilko <kontact-mr.k AT outlook DOT com">
+Ilya Makarov
+Jamie Mansfield <dev AT jamierocks DOT uk>
+Jean THOMAS <contact AT tibounise DOT com>
+Juraj Bubniak <contact AT jbub DOT eu>
 Lafriks <lafriks AT gmail DOT com>
 Lauri Ojansivu <x AT xet7 DOT org>
 Luc Stepniewski <luc AT stepniewski DOT fr>
+Luca Bozzo <luca AT bozzo DOT it>
+Luca Kröger <l DOT kroeger01 AT gmail DOT com>
 Marc Schiller <marc AT schiller DOT im>
+Marvin Menzerath <github AT marvin-menzerath DOT de>
+Michael Härtl <haertl DOT mike AT gmail DOT com>
 Miguel de la Cruz <miguel AT mcrx DOT me>
+Mikhail Burdin <xdshot9000 AT gmail DOT com>
 Morten Sørensen <klim8d AT gmail DOT com>
+Muhammad Fawwaz Orabi <mfawwaz93 AT gmail DOT com>
 Nakao Takamasa <at.mattenn AT gmail DOT com>
 Natan Albuquerque <natanalbuquerque5 AT gmail DOT com>
 Odilon Junior <odilon DOT junior93 AT gmail DOT com>
+Richard Bukovansky <richard DOT bukovansky @ gmail DOT com>
+Robert Nuske <robert DOT nuske AT web DOT de>
+Robin Hübner <profan AT prfn DOT se>
+SeongJae Park <sj38 DOT park AT gmail DOT com>
 Thomas Fanninger <gogs DOT thomas AT fanninger DOT at>
 Tilmann Bach <tilmann AT outlook DOT com>
+Toni Villena Jiménez <tonivj5 AT gmail DOT com>
+Vladimir Jigulin mogaika AT yandex DOT ru
 Vladimir Vissoultchev <wqweto AT gmail DOT com>
 YJSoft <yjsoft AT yjsoft DOT pe DOT kr>
 Łukasz Jan Niemier <lukasz AT niemier DOT pl>
+Pablo Saavedra <psaavedra AT igalia DOT com>

+ 75 - 24
conf/locale/locale_bg-BG.ini

@@ -39,19 +39,12 @@ settings=Настройки
 your_profile=Вашият профил
 your_settings=Вашите настройки
 
-news_feed=Поток новини
+activities=Активности
 pull_requests=Заявки за сливане
 issues=Задачи
 
 cancel=Отказ
 
-[search]
-search=Търсене...
-repository=Хранилище
-user=Потребител
-issue=Задача
-code=Код
-
 [install]
 install=Инсталация
 title=Стъпки за инсталиране при първоначално стартиране
@@ -66,7 +59,7 @@ db_name=Име на база данни
 db_helper=Моля, използвайте INNODB engine с utf8_general_ci кодиране на знаци за MySQL.
 ssl_mode=Режим SSL
 path=Път
-sqlite_helper=Файл на SQLite3 или TiDB база данни.
+sqlite_helper=Файл на SQLite3 или TiDB база данни.<br>Моля използвайте абсолютен път до файл когато стартирате Gogs като услуга.
 err_empty_db_path=Пътят до SQLite3 или TiDB база данни не може да е празен.
 err_invalid_tidb_name=TiDB не позволява "." и "-" в името на базата данни.
 no_admin_and_disable_registration=Невъзможно изключване на регистрациите без предварително да е създаден поне един административен профил.
@@ -87,6 +80,8 @@ http_port=HTTP порт
 http_port_helper=Порт, на който приложението ще слуша.
 app_url=URL адрес на приложението
 app_url_helper=Този настройка променя HTTP/HTTPS адреса за клониране, а понякога и адреса на ел. поща.
+log_root_path=Път към журналите
+log_root_path_helper=Директория в която се записват журналите.
 
 optional_title=Опционални настройки
 email_title=Настройки на пощенска услуга
@@ -123,6 +118,7 @@ run_user_not_match=Потребителският контекст на прил
 save_config_failed=Неуспешно запазване на конфигурация: %v
 invalid_admin_setting=Настройките на профил на администратора са невалидни: %v
 install_success=Добре дошли! Радваме се, че избрахте Gogs, и Ви пожелаваме приятна работа и сърдечни поздрави!
+invalid_log_root_path=Основният път към журналите е невалиден: %v
 
 [home]
 uname_holder=Име или ел. поща
@@ -138,6 +134,8 @@ issues.in_your_repos=Във Вашите хранилища
 
 [explore]
 repos=Хранилища
+users=Потребители
+search=Търсене
 
 [auth]
 create_new_account=Създай нов профил
@@ -151,6 +149,8 @@ forget_password=Забравена парола?
 sign_up_now=Нуждаете се от профил? Регистрирайте се сега.
 confirmation_mail_sent_prompt=Ново писмо за потвърждение е изпратено до <b>%s</b>. Моля проверете пощенската си кутия в рамките на следващите %d часа, за да завършите процеса на регистрация.
 active_your_account=Активиране на профил
+prohibit_login=Login Prohibited
+prohibit_login_desc=Your account is prohibited to login, please contact site admin.
 resent_limit_prompt=За съжаление Вие съвсем наскоро изпратихте писмо за активация. Моля изчакайте 3 минути, след което опитайте отново.
 has_unconfirmed_mail=Здравейте %s, имате непотвърден адрес на ел. поща (<b>%s</b>). Ако не сте получили писмо за потвърждение или имате нужда да се изпрати ново писмо, моля щракнете бутона по-долу.
 resend_mail=Щракнете тук, за да се изпрати ново писмо за потвърждение
@@ -160,6 +160,7 @@ reset_password=Нулиране на паролата
 invalid_code=За съжаление Вашия код за потвърждение е изтекъл или е невалиден.
 reset_password_helper=Щракнете тук, за да нулирате паролата си
 password_too_short=Размерът на паролата не може да бъде по-малък от 6 знака.
+non_local_account=Non-local accounts cannot change passwords through Gogs.
 
 [mail]
 activate_account=Моля активирайте Вашия профил
@@ -204,7 +205,6 @@ repo_name_been_taken=Името на хранилището вече се пол
 org_name_been_taken=Името на организацията вече се ползва.
 team_name_been_taken=Името на екипа вече се ползва.
 email_been_used=Този адрес на ел. поща вече се ползва.
-illegal_team_name=Името на екипа съдържа недопустими знаци.
 username_password_incorrect=Потребителското име или паролата не са верни.
 enterred_invalid_repo_name=Моля уверете се, че въведеното име на хранилище е вярно.
 enterred_invalid_owner_name=Моля уверете се, че въведеното име на притежател е вярно.
@@ -220,19 +220,18 @@ still_own_repo=Вашият профил притежава поне едно х
 still_has_org=Вашият профил все още участва в поне една организация. Първо трябва да напуснете или изтриете Вашите участия в организациите.
 org_still_own_repo=Тази организация все още притежава хранилище. Първо трябва да го изтриете или да го прехвърлите на друга организация.
 
-still_own_user=Това удостоверяване се използва от поне един потребител. Моля премахнете потребителите към него и опитайте отново.
-
 target_branch_not_exist=Целевият клон не съществува.
 
 [user]
-change_avatar=Сменете Вашия аватар на gravatar.com
-change_custom_avatar=Сменете Вашия аватар в настройките
+change_avatar=Change your avatar
 join_on=Регистриран
 repositories=Хранилища
 activity=Публична дейност
 followers=Последователи
 starred=Харесано
 following=Следване
+follow=Следване
+unfollow=Не следвай
 
 form.name_reserved=Потребителското име '%s' е запазено.
 form.name_pattern_not_allowed=Потребителското име '%s' не е допустимо.
@@ -261,11 +260,10 @@ continue=Продължи
 cancel=Отказ
 
 enable_custom_avatar=Разреши потребителски аватар
-enable_custom_avatar_helper=Без зареждане от Gravatar
 choose_new_avatar=Избор на нов аватар
 update_avatar=Запази настройките на аватара
+delete_current_avatar=Изтрий аватар
 uploaded_avatar_not_a_image=Каченият файл не е изображение.
-no_custom_avatar_available=Невъзможно използване на външен аватар, защото не е активирано.
 update_avatar_success=Настройките на аватара са запазени успешно.
 
 change_password=Промяна на собствената парола
@@ -355,6 +353,8 @@ readme_helper=Изберете шаблон на readme
 auto_init=Инициализиране на това хранилище с избраните файлове и шаблон
 create_repo=Създай хранилище
 default_branch=Клон по подразбиране
+mirror_prune=Prune
+mirror_prune_desc=Remove any remote-tracking references that no longer exist on the remote
 mirror_interval=Интервал на отразяване (часове)
 mirror_address=Адрес на огледало
 mirror_address_desc=Моля включете потребител и парола в адреса ако са нужни.
@@ -412,6 +412,7 @@ file_raw=Директен файл
 file_history=История
 file_view_raw=Виж директен файл
 file_permalink=Постоянна връзка
+file_too_large=This file is too large to be shown
 
 commits.commits=Ревизии
 commits.search=Търсене в ревизии
@@ -476,7 +477,7 @@ issues.closed_at=`затвори <a id="%[1]s" href="#%[1]s">%[2]s</a>`
 issues.reopened_at=`повторно отвори <a id="%[1]s" href="#%[1]s">%[2]s</a>`
 issues.commit_ref_at=`посочи тази задача от ревизия <a id="%[1]s" href="#%[1]s">%[2]s</a>`
 issues.poster=Участник
-issues.admin=Администратор
+issues.collaborator=Сътрудник
 issues.owner=Притежател
 issues.sign_up_for_free=Регистрирай се безплатно
 issues.sign_in_require_desc=за да се включите в този разговор. Вече имате профил? <a href="%s">Влезте, за да коментирате</a>
@@ -493,6 +494,7 @@ issues.label_modify=Промяна на етикет
 issues.label_deletion=Изтрий етикет
 issues.label_deletion_desc=При изтриване на този етикет ще се премахне информацията за него във всички свързани задачи. Желаете ли да продължите?
 issues.label_deletion_success=Етикетът е изтрит успешно!
+issues.num_participants=%d участника
 
 pulls.new=Нова заявка за сливане
 pulls.compare_changes=Сравни промените
@@ -556,6 +558,8 @@ wiki.save_page=Запис на страница
 wiki.last_commit_info=%s редактира тази страница %s
 wiki.edit_page_button=Редакция
 wiki.new_page_button=Нова страница
+wiki.delete_page_button=Изтрий страница
+wiki.delete_page_notice_1=Това ще изтрие страница <code>"%s"</code>. Моля, бъдете сигурни.
 wiki.page_already_exists=Страница със същото име вече съществува.
 wiki.pages=Страници
 wiki.last_updated=Последна модификация на %s
@@ -563,6 +567,10 @@ wiki.last_updated=Последна модификация на %s
 settings=Настройки
 settings.options=Опции
 settings.collaboration=Сътрудничество
+settings.collaboration.admin=Admin
+settings.collaboration.write=Write
+settings.collaboration.read=Read
+settings.collaboration.undefined=Undefined
 settings.hooks=Уеб-куки
 settings.githooks=Git куки
 settings.basic_settings=Основни настройки
@@ -577,22 +585,32 @@ settings.external_wiki_url_desc=Посетителите ще бъдат пре
 settings.issues_desc=Включва вградена система за проследяване на задачи
 settings.use_external_issue_tracker=Използвай външна система за проследяване на задачи
 settings.tracker_url_format=Формат на URL адрес на външна система за проследяване на задачи
+settings.tracker_issue_style=External Issue Tracker Naming Style:
+settings.tracker_issue_style.numeric=Numeric <span class="ui light grey text">(1234)</span>
+settings.tracker_issue_style.alphanumeric=Alphanumeric <span class="ui light grey text">(ABC-123, DEFG-234, ...)</span>
 settings.tracker_url_format_desc=Можете да използвате текстови маркери <code>{user} {repo} {index}</code> за потребителско име, име на хранилище и индекс на задача съответно.
 settings.pulls_desc=Включва заявки за сливане за да може да се приемат външни доработки
 settings.danger_zone=Опасна зона
+settings.new_owner_has_same_repo=Новият притежател вече има хранилище със същото име. Изберете друго име.
+settings.convert=Промени към редовно хранилище
+settings.convert_desc=Можете да промените това огледало към редовно хранилище. Конверсията не може да се отмени.
+settings.convert_notices_1=- Тази операция ще конвертира огледалото към редовно хранилище и не може да бъде отменена в последствие.
+settings.convert_confirm=Потвърдете конверсията
+settings.convert_succeed=Конверсията към редовно хранилище е извършена успешно.
 settings.transfer=Прехвърли притежание
 settings.transfer_desc=Прехвърля това хранилище на друг потребител или към организация, в която имате права на администратор.
-settings.new_owner_has_same_repo=Новият притежател вече има хранилище със същото име. Изберете друго име.
-settings.delete=Изтрий това хранилище
-settings.delete_desc=След като изтриете хранилището, няма връщане назад. Моля, бъдете сигурни.
 settings.transfer_notices_1=- Вие ще загубите достъп, ако новият притежател е индивидуален потребител.
 settings.transfer_notices_2=- Вие ще запазите достъпа си, ако новият притежател е организация и ако вие сте един от притежателите ѝ.
 settings.transfer_form_title=Моля въведете следната информация за да потвърдите операцията:
+settings.wiki_delete=Изтриване на данни на уики
+settings.wiki_delete_desc=След като изтриете данни за уики, няма връщане назад. Моля, бъдете сигурни.
+settings.wiki_delete_notices_1=- Това ще изтрие и ще деактивира уики за %s
+settings.wiki_deletion_success=Данните за уики на това хранилище са изтрити успешно.
+settings.delete=Изтрий това хранилище
+settings.delete_desc=След като изтриете хранилището, няма връщане назад. Моля, бъдете сигурни.
 settings.delete_notices_1=- Тази операция <strong>НЕ МОЖЕ</strong> да бъде отменена в последствие.
 settings.delete_notices_2=- Тази операция ще изтрие всичко от това хранилище, включително Git данни, задачи, коментари и достъпа на сътрудници.
-settings.delete_notices_fork_1=- Ако това хранилище е публично, всички негови разклонения ще останат независими след изтриването му.
-settings.delete_notices_fork_2=- Ако това хранилище е частно, всички негови разклонения ще бъдат премахнати по време на изтриването.
-settings.delete_notices_fork_3=- Ако желаете да запазите всички разклонения след изтриването му, първо направете хранилището публично.
+settings.delete_notices_fork_1=- All forks will become independent after deletion.
 settings.deletion_success=Хранилището е изтрито успешно!
 settings.update_settings_success=Настройките на хранилището са запазени успешно.
 settings.transfer_owner=Нов притежател
@@ -601,8 +619,12 @@ settings.transfer_succeed=Притежанието на хранилището 
 settings.confirm_delete=Потвърди изтриването
 settings.add_collaborator=Добави нов сътрудник
 settings.add_collaborator_success=Добавен е нов сътрудник.
+settings.delete_collaborator=Премахни
+settings.collaborator_deletion=Премахване на сътрудник
+settings.collaborator_deletion_desc=Този потребител няма да има достъп на сътрудник до хранилището след изтриването. Желаете ли да продължите?
 settings.remove_collaborator_success=Сътрудникът е премахнат.
 settings.search_user_placeholder=Име на потребител...
+settings.org_not_allowed_to_be_collaborator=Невъзможно добавяне на организация като сътрудник.
 settings.user_is_org_member=Потребителят вече участва в организацията и не може да бъде добавен като сътрудник.
 settings.add_webhook=Добави уеб-кука
 settings.hooks_desc=Уеб-куките много приличат на обикновен HTTP POST тригер. Когато нещо се случи в Gogs, ние ще изпратим уведомление до сървъра, който посочите. Научете повече в <a target="_blank" href="%s">Ръководство за уеб-куки</a>.
@@ -667,9 +689,13 @@ diff.parent=родител
 diff.commit=ревизия
 diff.data_not_available=Няма данни за разлики.
 diff.show_diff_stats=Покажи статистика за разликите
+diff.show_split_view=Разделен изглед
+diff.show_unified_view=Обединен изглед
 diff.stats_desc=променени са <strong>%d файла</strong>, в които са <strong>добавени %d</strong> реда и са <strong>изтрити %d</strong> реда
 diff.bin=BIN
 diff.view_file=Целия файл
+diff.file_suppressed=File diff suppressed because it is too large
+diff.too_many_files=Some files were not shown because too many files changed in this diff
 
 release.releases=Версии
 release.new_release=Нова версия
@@ -815,6 +841,8 @@ dashboard.resync_all_sshkeys=Презапис на ".ssh/authorized_keys" фай
 dashboard.resync_all_sshkeys_success=Всички публични ключове са презаписани успешно.
 dashboard.resync_all_update_hooks=Презапис на всички куки, закачени на актуализация на хранилищата (необходимо, когато се ползва собствен път за конфигурацията)
 dashboard.resync_all_update_hooks_success=Всички куки, закачени на актуализация на хранилищата, са презаписани успешно.
+dashboard.reinit_missing_repos=Реинициализира всички записи за хранилища
+dashboard.reinit_missing_repos_success=Всички записи за хранилища със загубени Git файлове са реинициализирани успешно.
 
 dashboard.server_uptime=Операционно време
 dashboard.current_goroutine=Текущи Goroutines
@@ -865,6 +893,7 @@ users.edit_account=Редактирай профил
 users.max_repo_creation=Макс. брой хранилища
 users.max_repo_creation_desc=(Задайте -1 за да се използва глобалния лимит)
 users.is_activated=Този профил е активиран
+users.prohibit_login=This account is prohibited to login
 users.is_admin=Този профил има административни права
 users.allow_git_hook=Този профил има разрешение да създава Git куки
 users.allow_import_local=Този профил има права за импорт на локални хранилища
@@ -895,6 +924,7 @@ auths.enabled=Активно
 auths.updated=Последна модификация
 auths.auth_type=Тип на удостоверяване
 auths.auth_name=Име на удостоверяване
+auths.security_protocol=Security Protocol
 auths.domain=Домейн
 auths.host=Сървър
 auths.port=Порт
@@ -908,6 +938,7 @@ auths.attribute_username_placeholder=Оставете празно за да и
 auths.attribute_name=Атрибут за име
 auths.attribute_surname=Атрибут за фамилия
 auths.attribute_mail=Атрибут за ел. поща
+auths.attributes_in_bind=Извличане на атрибути от контекста на име (DN) за свръзка
 auths.filter=Филтър за потребител
 auths.admin_filter=Филтър за администратор
 auths.ms_ad_sa=Ms Ad SA
@@ -929,6 +960,7 @@ auths.update=Запази настройки за удостоверяване
 auths.delete=Изтриване на това удостоверяване
 auths.delete_auth_title=Изтрий удостоверяването
 auths.delete_auth_desc=Това удостоверяване ще бъде изтрито. Желаете ли да продължите?
+auths.still_in_used=Това удостоверяване все още се използва от някои потребители. Моля изтрийте ги или ги конвертирайте до друг тип на влизане първо.
 auths.deletion_success=Удостоверяването е изтрито успешно!
 
 config.server_config=Сървърни настройки
@@ -945,6 +977,19 @@ config.static_file_root_path=Път към статични файлове
 config.log_file_root_path=Път към журнал
 config.script_type=Тип на скрипта
 config.reverse_auth_user=Потребителско име при обратно удостоверяване
+
+config.ssh_config=SSH конфигурация
+config.ssh_enabled=Активен
+config.ssh_start_builtin_server=Стартирай вграден сървър
+config.ssh_domain=Домейн
+config.ssh_port=Порт
+config.ssh_listen_port=Порт за слушане
+config.ssh_root_path=Основен път
+config.ssh_key_test_path=Път до ключове
+config.ssh_keygen_path=Път до генератор ('ssh-keygen')
+config.ssh_minimum_key_size_check=Проверка за минимален размер на ключове
+config.ssh_minimum_key_sizes=Минимален размер на ключове
+
 config.db_config=Настройки на базата данни
 config.db_type=Тип
 config.db_host=Сървър
@@ -959,7 +1004,6 @@ config.register_email_confirm=Изисквай потвърждение на а
 config.disable_register=Изключи нови регистрации
 config.show_registration_button=Покажи бутон за регистрация
 config.require_sign_in_view=Изисквай вписване за преглед
-config.enable_cache_avatar=Включи кеширане на аватари
 config.mail_notify=Уведомяване по ел. поща
 config.disable_key_size_check=Изключи проверка минимален размер на ключ
 config.enable_captcha=Включи Captcha
@@ -975,6 +1019,9 @@ config.mailer_disable_helo=Изключи HELO
 config.mailer_name=Име
 config.mailer_host=Сървър
 config.mailer_user=Потребител
+config.send_test_mail=Изпрати тестово писмо
+config.test_mail_failed=Невъзможно изпращане на тестово писмо до '%s': %v
+config.test_mail_sent=Тестово писмо беше изпратено до '%s'.
 config.oauth_config=OAuth конфигурация
 config.oauth_enabled=Активна
 config.cache_config=Конфигурация на кеша
@@ -1026,7 +1073,11 @@ create_repo=създаде хранилище <a href="%s"> %s</a>
 rename_repo=преименува хранилище от <code>%[1]s</code> на <a href="%[2]s">%[3]s</a>
 commit_repo=предаде към <a href="%[1]s/src/%[2]s">%[3]s</a> в <a href="%[1]s">%[4]s</a>
 create_issue=`отвори задача <a href="%s/issues/%s">%s#%[2]s"</a>`
+close_issue=`затвори <a href="%s/issues/%s">%s#%[2]s</a>`
+reopen_issue=`повторно отвори <a href="%s/issues/%s">%s#%[2]s</a>`
 create_pull_request=`създаде заявка за сливане <a href="%s/pulls/%s">%s#%[2]s</a>`
+close_pull_request=`затвори заявка за сливане <a href="%s/pulls/%s">%s#%[2]s</a>`
+reopen_pull_request=`повторно отвори заявка за сливане <a href="%s/pulls/%s">%s#%[2]s</a>`
 comment_issue=`коментира задача <a href="%s/issues/%s">%s#%[2]s"</a>`
 merge_pull_request=`обедини заявка за сливане <a href="%s/pulls/%s">%s#%[2]s</a>`
 transfer_repo=прехвърли хранилище <code>%s</code> към <a href="%s">%s</a>

File diff suppressed because it is too large
+ 1112 - 0
conf/locale/locale_cs-CZ.ini


File diff suppressed because it is too large
+ 428 - 377
conf/locale/locale_de-DE.ini


+ 93 - 39
conf/locale/locale_en-US.ini

@@ -39,19 +39,12 @@ settings = Settings
 your_profile = Your Profile
 your_settings = Your Settings
 
-news_feed = News Feed
+activities = Activities
 pull_requests = Pull Requests
 issues = Issues
 
 cancel = Cancel
 
-[search]
-search = Search...
-repository = Repository
-user = User
-issue = Issue
-code = Code
-
 [install]
 install = Installation
 title = Install Steps For First-time Run
@@ -66,7 +59,7 @@ db_name = Database Name
 db_helper = Please use INNODB engine with utf8_general_ci charset for MySQL.
 ssl_mode = SSL Mode
 path = Path
-sqlite_helper = The file path of SQLite3 or TiDB database.
+sqlite_helper = The file path of SQLite3 or TiDB database. <br>Please use absolute path when you start as service.
 err_empty_db_path = SQLite3 or TiDB database path cannot be empty.
 err_invalid_tidb_name = TiDB database name does not allow characters "." and "-".
 no_admin_and_disable_registration = You cannot disable registration without creating an admin account.
@@ -87,6 +80,8 @@ http_port = HTTP Port
 http_port_helper = Port number which application will listen on.
 app_url = Application URL
 app_url_helper = This affects HTTP/HTTPS clone URL and somewhere in email.
+log_root_path = Log Path
+log_root_path_helper = Directory to write log files to.
 
 optional_title = Optional Settings
 email_title = Email Service Settings
@@ -123,12 +118,14 @@ run_user_not_match = Run user isn't the current user: %s -> %s
 save_config_failed = Fail to save configuration: %v
 invalid_admin_setting = Admin account setting is invalid: %v
 install_success = Welcome! We're glad that you chose Gogs, have fun and take care.
+invalid_log_root_path = Log root path is invalid: %v
 
 [home]
 uname_holder = Username or email
 password_holder = Password
 switch_dashboard_context = Switch Dashboard Context
 my_repos = My Repositories
+show_more_repos = Show more repositories...
 collaborative_repos = Collaborative Repositories
 my_orgs = My Organizations
 my_mirrors = My Mirrors
@@ -138,6 +135,8 @@ issues.in_your_repos = In your repositories
 
 [explore]
 repos = Repositories
+users = Users
+search = Search
 
 [auth]
 create_new_account = Create New Account
@@ -151,6 +150,8 @@ forget_password = Forgot password?
 sign_up_now = Need an account? Sign up now.
 confirmation_mail_sent_prompt = A new confirmation email has been sent to <b>%s</b>, please check your inbox within the next %d hours to complete the registration process.
 active_your_account = Activate Your Account
+prohibit_login = Login Prohibited
+prohibit_login_desc = Your account is prohibited to login, please contact site admin.
 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 email address (<b>%s</b>). If you haven't received a confirmation email or need to resend a new one, please click on the button below.
 resend_mail = Click here to resend your activation email
@@ -160,6 +161,7 @@ reset_password = Reset Your Password
 invalid_code = Sorry, your confirmation code has expired or not valid.
 reset_password_helper = Click here to reset your password
 password_too_short = Password length cannot be less then 6.
+non_local_account = Non-local accounts cannot change passwords through Gogs.
 
 [mail]
 activate_account = Please activate your account
@@ -204,7 +206,6 @@ repo_name_been_taken = Repository name has already been taken.
 org_name_been_taken = Organization name has already been taken.
 team_name_been_taken = Team name has already been taken.
 email_been_used = Email address has already been used.
-illegal_team_name = Team name contains illegal characters.
 username_password_incorrect = Username or password is not 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.
@@ -218,21 +219,20 @@ auth_failed = Authentication failed: %v
 
 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 is still in use by at least one user, please remove them from the authentication and try again.
+org_still_own_repo = This organization still has ownership of repositories, you must delete or transfer them first.
 
 target_branch_not_exist = Target branch does not exist.
 
 [user]
-change_avatar = Change your avatar at gravatar.com
-change_custom_avatar = Change your avatar in settings
+change_avatar = Change your avatar
 join_on = Joined on
 repositories = Repositories
 activity = Public Activity
 followers = Followers
-starred = Starred
+starred = Starred repositories
 following = Following
+follow = Follow
+unfollow = Unfollow
 
 form.name_reserved = Username '%s' is reserved.
 form.name_pattern_not_allowed = Username pattern '%s' is not allowed.
@@ -261,11 +261,10 @@ continue = Continue
 cancel = Cancel
 
 enable_custom_avatar = Enable Custom Avatar
-enable_custom_avatar_helper = Disable fetch from Gravatar
 choose_new_avatar = Choose new avatar
 update_avatar = Update Avatar Setting
+delete_current_avatar = Delete Current Avatar
 uploaded_avatar_not_a_image = Uploaded file is not a image.
-no_custom_avatar_available = No custom avatar available, cannot enable it.
 update_avatar_success = Your avatar setting has been updated successfully.
 
 change_password = Change Password
@@ -295,8 +294,8 @@ add_key = Add Key
 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
-ssh_key_been_used = Public key content has been used. 
-ssh_key_name_used = Public key with same name has already existed. 
+ssh_key_been_used = Public key content has been used.
+ssh_key_name_used = Public key with same name has already existed.
 key_name = Key Name
 key_content = Content
 add_key_success = New SSH key '%s' has been added successfully!
@@ -355,6 +354,8 @@ readme_helper = Select a readme template
 auto_init = Initialize this repository with selected files and template
 create_repo = Create Repository
 default_branch = Default Branch
+mirror_prune = Prune
+mirror_prune_desc = Remove any remote-tracking references that no longer exist on the remote
 mirror_interval = Mirror Interval (hour)
 mirror_address = Mirror Address
 mirror_address_desc = Please include necessary user credentials in the address.
@@ -376,7 +377,7 @@ migrate.permission_denied = You are not allowed to import local repositories.
 migrate.invalid_local_path = Invalid local path, it does not exist or not a directory.
 migrate.failed = Migration failed: %v
 
-mirror_from = mirror from
+mirror_from = mirror of
 forked_from = forked from
 fork_from_self = You cannot fork a repository you already own!
 copy_link = Copy
@@ -412,6 +413,7 @@ file_raw = Raw
 file_history = History
 file_view_raw = View Raw
 file_permalink = Permalink
+file_too_large = This file is too large to be shown
 
 commits.commits = Commits
 commits.search = Search commits
@@ -465,7 +467,8 @@ issues.next = Next
 issues.open_title = Open
 issues.closed_title = Closed
 issues.num_comments = %d comments
-issues.commented_at = `commented <a id="%[1]s" href="#%[1]s">%[2]s</a>`
+issues.commented_at = `commented <a href="#%s">%s</a>`
+issues.delete_comment_confirm = Are you sure you want to delete this comment?
 issues.no_content = There is no content yet.
 issues.close_issue = Close
 issues.close_comment_issue = Comment and close
@@ -476,7 +479,7 @@ issues.closed_at = `closed <a id="%[1]s" href="#%[1]s">%[2]s</a>`
 issues.reopened_at = `reopened <a id="%[1]s" href="#%[1]s">%[2]s</a>`
 issues.commit_ref_at = `referenced this issue from a commit <a id="%[1]s" href="#%[1]s">%[2]s</a>`
 issues.poster = Poster
-issues.admin = Admin
+issues.collaborator = Collaborator
 issues.owner = Owner
 issues.sign_up_for_free = Sign up for free
 issues.sign_in_require_desc = to join this conversation. Already have an account? <a href="%s">Sign in to comment</a>
@@ -493,6 +496,7 @@ issues.label_modify = Label Modification
 issues.label_deletion = Label Deletion
 issues.label_deletion_desc = Deleting this label will remove its information in all related issues. Do you want to continue?
 issues.label_deletion_success = Label has been deleted successfully!
+issues.num_participants = %d Participants
 
 pulls.new = New Pull Request
 pulls.compare_changes = Compare Changes
@@ -524,7 +528,7 @@ milestones.new = New Milestone
 milestones.open_tab = %d Open
 milestones.close_tab = %d Closed
 milestones.closed = Closed %s
-milestones.no_due_date = No due date 
+milestones.no_due_date = No due date
 milestones.open = Open
 milestones.close = Close
 milestones.new_subheader = Create milestones to organize your issues.
@@ -556,6 +560,8 @@ wiki.save_page = Save Page
 wiki.last_commit_info = %s edited this page %s
 wiki.edit_page_button = Edit
 wiki.new_page_button = New Page
+wiki.delete_page_button = Delete Page
+wiki.delete_page_notice_1 = This will delete the page <code>"%s"</code>. Please be certain.
 wiki.page_already_exists = Wiki page with same name already exists.
 wiki.pages = Pages
 wiki.last_updated = Last updated %s
@@ -563,6 +569,10 @@ wiki.last_updated = Last updated %s
 settings = Settings
 settings.options = Options
 settings.collaboration = Collaboration
+settings.collaboration.admin = Admin
+settings.collaboration.write = Write
+settings.collaboration.read = Read
+settings.collaboration.undefined = Undefined
 settings.hooks = Webhooks
 settings.githooks = Git Hooks
 settings.basic_settings = Basic Settings
@@ -574,25 +584,35 @@ settings.wiki_desc = Enable wiki to allow people write documents
 settings.use_external_wiki = Use external wiki
 settings.external_wiki_url = External Wiki URL
 settings.external_wiki_url_desc = Visitors will be redirected to URL when they click on the tab.
-settings.issues_desc = Enable builtin lightweight issue tracker 
+settings.issues_desc = Enable builtin lightweight issue tracker
 settings.use_external_issue_tracker = Use external issue tracker
 settings.tracker_url_format = External Issue Tracker URL Format
+settings.tracker_issue_style = External Issue Tracker Naming Style:
+settings.tracker_issue_style.numeric = Numeric
+settings.tracker_issue_style.alphanumeric = Alphanumeric
 settings.tracker_url_format_desc = You can use placeholder <code>{user} {repo} {index}</code> for user name, repository name and issue index.
 settings.pulls_desc = Enable pull requests to accept public contributions
 settings.danger_zone = Danger Zone
+settings.new_owner_has_same_repo = The new owner already has a repository with same name. Please choose another name.
+settings.convert = Convert To Regular Repository
+settings.convert_desc = You can convert this mirror to a regular repository. This cannot be reversed.
+settings.convert_notices_1 = - This operation will convert this repository mirror into a regular repository and cannot be undone.
+settings.convert_confirm = Confirm Conversion
+settings.convert_succeed = Repository has been converted to regular type successfully.
 settings.transfer = Transfer Ownership
 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_1 = - You will lose access if new owner is a individual user.
 settings.transfer_notices_2 = - You will conserve access if new owner is an organization and if you're one of the owners.
-settings.transfer_form_title = Please enter following information to confirm your operation: 
+settings.transfer_form_title = Please enter following information to confirm your operation:
+settings.wiki_delete = Erase Wiki Data
+settings.wiki_delete_desc = Once you erase wiki data there is no going back. Please be certain.
+settings.wiki_delete_notices_1 = - This will delete and disable the wiki for %s
+settings.wiki_deletion_success = Repository wiki data have been erased successfully.
+settings.delete = Delete This Repository
+settings.delete_desc = Once you delete a repository, there is no going back. Please be certain.
 settings.delete_notices_1 = - This operation <strong>CANNOT</strong> be undone.
 settings.delete_notices_2 = - This operation will permanently delete the everything of this repository, including Git data, issues, comments and accesses of collaborators.
-settings.delete_notices_fork_1 = - If this repository is public, all forks will be became independent after deletion.
-settings.delete_notices_fork_2 = - If this repository is private, all forks will be removed at the same time.
-settings.delete_notices_fork_3 = - If you want to keep all forks after deletion, please change visibility of this repository to public first.
+settings.delete_notices_fork_1 = - All forks will become independent after deletion.
 settings.deletion_success = Repository has been deleted successfully!
 settings.update_settings_success = Repository options has been updated successfully.
 settings.transfer_owner = New Owner
@@ -601,8 +621,12 @@ settings.transfer_succeed = Repository ownership has been transferred successful
 settings.confirm_delete = Confirm Deletion
 settings.add_collaborator = Add New Collaborator
 settings.add_collaborator_success = New collaborator has been added.
+settings.delete_collaborator = Delete
+settings.collaborator_deletion = Collaborator Deletion
+settings.collaborator_deletion_desc = This user will no longer have collaboration access to this repository after deletion. Do you want to continue?
 settings.remove_collaborator_success = Collaborator has been removed.
 settings.search_user_placeholder = Search user...
+settings.org_not_allowed_to_be_collaborator = Organization is not allowed to be added as a collaborator.
 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 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>.
@@ -611,7 +635,7 @@ settings.webhook_deletion_desc = Delete this webhook will remove its information
 settings.webhook_deletion_success = Webhook has been deleted successfully!
 settings.webhook.test_delivery = Test Delivery
 settings.webhook.test_delivery_desc = Send a fake push event delivery to test your webhook settings
-settings.webhook.test_delivery_success = Test webhook has been added to delivery queue. It may taks few seconds before it shows up in the delivery history.
+settings.webhook.test_delivery_success = Test webhook has been added to delivery queue. It may take few seconds before it shows up in the delivery history.
 settings.webhook.request = Request
 settings.webhook.response = Response
 settings.webhook.headers = Headers
@@ -651,8 +675,8 @@ settings.slack_domain = Domain
 settings.slack_channel = Channel
 settings.deploy_keys = Deploy Keys
 settings.add_deploy_key = Add Deploy Key
-settings.deploy_key_desc = Deploy key only has read-only access. It is not same as personal account SSH keys.
-settings.no_deploy_keys = You haven't added any deploy key.
+settings.deploy_key_desc = Deploy keys have read-only access. They are not the same as personal account SSH keys.
+settings.no_deploy_keys = You haven't added any deploy keys.
 settings.title = Title
 settings.deploy_key_content = Content
 settings.key_been_used = Deploy key content has been used.
@@ -667,9 +691,13 @@ diff.parent = parent
 diff.commit = commit
 diff.data_not_available = Diff Data Not Available.
 diff.show_diff_stats = Show Diff Stats
+diff.show_split_view = Split View
+diff.show_unified_view = Unified View
 diff.stats_desc = <strong> %d changed files</strong> with <strong>%d additions</strong> and <strong>%d deletions</strong>
 diff.bin = BIN
 diff.view_file = View File
+diff.file_suppressed = File diff suppressed because it is too large
+diff.too_many_files = Some files were not shown because too many files changed in this diff
 
 release.releases = Releases
 release.new_release = New Release
@@ -700,6 +728,7 @@ release.deletion = Release Deletion
 release.deletion_desc = Deleting this release will delete the corresponding Git tag. Do you want to continue?
 release.deletion_success = Release has been deleted successfully!
 release.tag_name_already_exist = Release with this tag name already exists.
+release.tag_name_invalid = Tag name is not valid.
 release.downloads = Downloads
 
 [org]
@@ -815,6 +844,8 @@ dashboard.resync_all_sshkeys = Rewrite '.ssh/authorized_keys' file (caution: non
 dashboard.resync_all_sshkeys_success = All public keys have been rewritten successfully.
 dashboard.resync_all_update_hooks = Rewrite all update hook of repositories (needed when custom config path is changed)
 dashboard.resync_all_update_hooks_success = All repositories' update hook have been rewritten successfully.
+dashboard.reinit_missing_repos = Reinitialize all repository records that lost Git files
+dashboard.reinit_missing_repos_success = All repository records that lost Git files have been reinitialized successfully.
 
 dashboard.server_uptime = Server Uptime
 dashboard.current_goroutine = Current Goroutines
@@ -837,7 +868,7 @@ dashboard.mspan_structures_obtained = MSpan Structures Obtained
 dashboard.mcache_structures_usage = MCache Structures Usage
 dashboard.mcache_structures_obtained = MCache Structures Obtained
 dashboard.profiling_bucket_hash_table_obtained = Profiling Bucket Hash Table Obtained
-dashboard.gc_metadata_obtained = GC Metadada Obtained
+dashboard.gc_metadata_obtained = GC Metadata Obtained
 dashboard.other_system_allocation_obtained = Other System Allocation Obtained
 dashboard.next_gc_recycle = Next GC Recycle
 dashboard.last_gc_time = Since Last GC Time
@@ -865,6 +896,7 @@ users.edit_account = Edit Account
 users.max_repo_creation = Maximum Repository Creation Limit
 users.max_repo_creation_desc = (Set -1 to use global default limit)
 users.is_activated = This account is activated
+users.prohibit_login = This account is prohibited to login
 users.is_admin = This account has administrator permissions
 users.allow_git_hook = This account has permissions to create Git hooks
 users.allow_import_local = This account has permissions to import local repositories
@@ -895,6 +927,7 @@ auths.enabled = Enabled
 auths.updated = Updated
 auths.auth_type = Authentication Type
 auths.auth_name = Authentication Name
+auths.security_protocol = Security Protocol
 auths.domain = Domain
 auths.host = Host
 auths.port = Port
@@ -908,6 +941,7 @@ auths.attribute_username_placeholder = Leave empty to use sign-in form field val
 auths.attribute_name = First name attribute
 auths.attribute_surname = Surname attribute
 auths.attribute_mail = Email attribute
+auths.attributes_in_bind = Fetch attributes in Bind DN context
 auths.filter = User Filter
 auths.admin_filter = Admin Filter
 auths.ms_ad_sa = Ms Ad SA
@@ -922,13 +956,14 @@ auths.pam_service_name = PAM Service Name
 auths.enable_auto_register = Enable Auto Registration
 auths.tips = Tips
 auths.edit = Edit Authentication Setting
-auths.activated = This authentication is activate
+auths.activated = This authentication is activated
 auths.new_success = New authentication '%s' has been added successfully.
 auths.update_success = Authentication setting has been updated successfully.
 auths.update = Update Authentication Setting
 auths.delete = Delete This Authentication
 auths.delete_auth_title = Authentication Deletion
 auths.delete_auth_desc = This authentication is going to be deleted, do you want to continue?
+auths.still_in_used = This authentication is still used by some users, please delete or convert these users to another login type first.
 auths.deletion_success = Authentication has been deleted successfully!
 
 config.server_config = Server Configuration
@@ -945,6 +980,19 @@ config.static_file_root_path = Static File Root Path
 config.log_file_root_path = Log File Root Path
 config.script_type = Script Type
 config.reverse_auth_user = Reverse Authentication User
+
+config.ssh_config = SSH Configuration
+config.ssh_enabled = Enabled
+config.ssh_start_builtin_server = Start Builtin Server
+config.ssh_domain = Domain
+config.ssh_port = Port
+config.ssh_listen_port = Listen Port
+config.ssh_root_path = Root Path
+config.ssh_key_test_path = Key Test Path
+config.ssh_keygen_path = Keygen ('ssh-keygen') Path
+config.ssh_minimum_key_size_check = Minimum Key Size Check
+config.ssh_minimum_key_sizes = Minimum Key Sizes
+
 config.db_config = Database Configuration
 config.db_type = Type
 config.db_host = Host
@@ -959,7 +1007,6 @@ config.register_email_confirm = Require Email Confirmation
 config.disable_register = Disable Registration
 config.show_registration_button = Show Register Button
 config.require_sign_in_view = Require Sign In View
-config.enable_cache_avatar = Enable Cache Avatar
 config.mail_notify = Mail Notification
 config.disable_key_size_check = Disable Minimum Key Size Check
 config.enable_captcha = Enable Captcha
@@ -975,6 +1022,9 @@ config.mailer_disable_helo = Disable HELO
 config.mailer_name = Name
 config.mailer_host = Host
 config.mailer_user = User
+config.send_test_mail = Send Test Email
+config.test_mail_failed = Fail to send test email to '%s': %v
+config.test_mail_sent = Test email has been sent to '%s'.
 config.oauth_config = OAuth Configuration
 config.oauth_enabled = Enabled
 config.cache_config = Cache Configuration
@@ -1026,7 +1076,11 @@ create_repo = created repository <a href="%s">%s</a>
 rename_repo = renamed repository from <code>%[1]s</code> to <a href="%[2]s">%[3]s</a>
 commit_repo = pushed to <a href="%[1]s/src/%[2]s">%[3]s</a> at <a href="%[1]s">%[4]s</a>
 create_issue = `opened issue <a href="%s/issues/%s">%s#%[2]s</a>`
+close_issue = `closed issue <a href="%s/issues/%s">%s#%[2]s</a>`
+reopen_issue = `reopened issue <a href="%s/issues/%s">%s#%[2]s</a>`
 create_pull_request = `created pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
+close_pull_request = `closed pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
+reopen_pull_request = `reopened pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
 comment_issue = `commented on issue <a href="%s/issues/%s">%s#%[2]s</a>`
 merge_pull_request = `merged pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
 transfer_repo = transfered repository <code>%s</code> to <a href="%s">%s</a>
@@ -1057,5 +1111,5 @@ raw_minutes = minutes
 [dropzone]
 default_message = Drop files here or click to upload.
 invalid_input_type = You can't upload files of this type.
-file_too_big = File size({{filesize}} MB) exceeds maximum size({{maxFilesize}} MB).
+file_too_big = File size ({{filesize}} MB) exceeds maximum size ({{maxFilesize}} MB).
 remove_file = Remove file

File diff suppressed because it is too large
+ 184 - 133
conf/locale/locale_es-ES.ini


File diff suppressed because it is too large
+ 1112 - 0
conf/locale/locale_fi-FI.ini


File diff suppressed because it is too large
+ 242 - 191
conf/locale/locale_fr-FR.ini


+ 289 - 238
conf/locale/locale_it-IT.ini

@@ -29,29 +29,22 @@ organization=Organizzazione
 mirror=Mirror
 new_repo=Nuovo Repository
 new_migrate=Nuova Migrazione
-new_mirror=New Mirror
+new_mirror=Nuovo Mirror
 new_fork=Nuovo Fork Repository
 new_org=Nuova organizzazione
 manage_org=Gestisci le organizzazioni
 admin_panel=Pannello di amministrazione
 account_settings=Impostazioni dell'account
 settings=Impostazioni
-your_profile=Profilo
+your_profile=Il tuo profilo
 your_settings=Impostazioni
 
-news_feed=Notizie
-pull_requests=Pull Requests
+activities=Attivitá
+pull_requests=Pull Request
 issues=Problemi
 
 cancel=Annulla
 
-[search]
-search=Ricerca...
-repository=Repository
-user=Utente
-issue=Problema
-code=Codice
-
 [install]
 install=Installazione
 title=Passi d'installazione per il primo avvio
@@ -66,7 +59,7 @@ db_name=Nome del database
 db_helper=Utilizza il motore INNODB con codifica utf8_general_ci per MySQL.
 ssl_mode=Modalità SSL
 path=Percorso
-sqlite_helper=Il percorso file del database SQLite3 o TiDB.
+sqlite_helper=Il path assoluto per il database SQLite3 o TiDB. <br>Per favore usa il path assoluto quando lo avvii come servizio.
 err_empty_db_path=Il percorso file del database SQLite3 o TiDB non può essere vuoto.
 err_invalid_tidb_name=Il nome del database TiDB non ammette caratteri "." e "-".
 no_admin_and_disable_registration=Non puoi disabilitare la registrazione senza aver creato un amministratore.
@@ -80,13 +73,15 @@ repo_path_helper=Tutti i repository Git remoti saranno salvati in questa directo
 run_user=Esegui con l'utente
 run_user_helper=L'utente deve avere accesso al percorso root del repository e avviare Gogs.
 domain=Dominio
-domain_helper=Questo modifica lo SSH clone URLs.
+domain_helper=Questo influisce sugli URL per il clonaggio via SSH.
 ssh_port=Porta SSH
 ssh_port_helper=Numero di porta utilizzato dal server SSH, lasciare vuoto per disabilitare l'integrazione SSH.
 http_port=Porta HTTP
 http_port_helper=Porta di ascolto dell'applicazione.
 app_url=URL Applicazione
 app_url_helper=Questo influisce sugli URL per il clonaggio via HTTP/HTTPS e da qualche parte nella posta elettronica.
+log_root_path=Percorso dei log
+log_root_path_helper=Directory in cui scrivere i file di log.
 
 optional_title=Impostazioni Facoltative
 email_title=Impostazioni E-mail
@@ -123,6 +118,7 @@ run_user_not_match=Run user non è l'utente corrente:  %s -> %s
 save_config_failed=Fallito il salvataggio della configurazione: %v
 invalid_admin_setting=Impostazioni account Admin non valide: %v
 install_success=Benvenuto! Siamo felici che tu abbia scelto Gogs, buon divertimento.
+invalid_log_root_path=Log root path is invalid: %v
 
 [home]
 uname_holder=Nome Utente o E-mail
@@ -138,6 +134,8 @@ issues.in_your_repos=Nei tuoi repository
 
 [explore]
 repos=Repository
+users=Utenti
+search=Cerca
 
 [auth]
 create_new_account=Crea un nuovo Account
@@ -151,6 +149,8 @@ forget_password=Password dimenticata?
 sign_up_now=Bisogno di un account? Iscriviti ora.
 confirmation_mail_sent_prompt=Una nuova email di conferma è stata inviata a <b>%s</b>, verifica la tua casella di posta entro le prossime %d ore per completare la registrazione.
 active_your_account=Attiva il tuo Account
+prohibit_login=Login Prohibited
+prohibit_login_desc=Your account is prohibited to login, please contact site admin.
 resent_limit_prompt=Siamo spiacenti, si stanno inviando e-mail di attivazione troppo spesso. Si prega di attendere 3 minuti.
 has_unconfirmed_mail=Ciao %s, hai un indirizzo di posta elettronica non confermato (<b>%s</b>). Se non hai ricevuto una e-mail di conferma o vuoi riceverla nuovamente, fare clic sul pulsante qui sotto.
 resend_mail=Clicca qui per inviare nuovamente l'e-mail di attivazione
@@ -160,6 +160,7 @@ reset_password=Reimposta la tua Password
 invalid_code=Siamo spiacenti, il codice di conferma è scaduto o non valido.
 reset_password_helper=Clicca qui per reimpostare la password
 password_too_short=La lunghezza della password non può essere meno 6 caratteri.
+non_local_account=Non-local accounts cannot change passwords through Gogs.
 
 [mail]
 activate_account=Per favore attiva il tuo account
@@ -204,7 +205,6 @@ repo_name_been_taken=Il nome del Repository è già utilizzato.
 org_name_been_taken=Il nome dell'Organizzazione è già utlizzato.
 team_name_been_taken=Il nome del Team è già utilizzato.
 email_been_used=L'indirizzo E-mail è già utilizzato.
-illegal_team_name=Il nome del Team contiene caratteri non validi.
 username_password_incorrect=Nome utente o password incorretti.
 enterred_invalid_repo_name=Si prega di assicurarsi che il nome del repository inserito sia corretto.
 enterred_invalid_owner_name=Si prega di assicurarsi che il nome del proprietario inserito sia corretto.
@@ -220,19 +220,18 @@ still_own_repo=Il tuo account possiede ancora almeno un repository, dovete prima
 still_has_org=Il tuo account è ancora associato ad almeno un'organizzazione, disassociarsi prima.
 org_still_own_repo=Questa organizzazione ha ancora la proprietà del repository, dovete cancellarla o trasferirli prima.
 
-still_own_user=Questa autenticazione è ancora in uso da almeno un utente, per favore rimuovili dall'autenticazione e riprova.
-
 target_branch_not_exist=Il ramo (branch) di destinazione non esiste.
 
 [user]
-change_avatar=Cambia il tuo avatar su gravatar.com
-change_custom_avatar=Cambia il tuo avatar nelle impostazioni
+change_avatar=Change your avatar
 join_on=Si è unito il
 repositories=Repository
 activity=Attività pubblica
 followers=Seguaci
 starred=Votate
 following=Seguiti
+follow=Segui
+unfollow=Non seguire più
 
 form.name_reserved=L'username '%s' è riservato.
 form.name_pattern_not_allowed=La struttura del nome utente '%s' non è consentita.
@@ -249,7 +248,7 @@ uid=Uid
 
 public_profile=Profilo pubblico
 profile_desc=Il tuo indirizzo e-mail è pubblico e sarà usato per ogni notifica inerente al tuo account, e per qualsiasi operazione web effettuata attraverso il sito.
-password_username_disabled=Non-local type users are not allowed to change their username.
+password_username_disabled=Gli utenti non locali non possono cambiare il proprio nome utente.
 full_name=Nome Completo
 website=Sito web
 location=Posizione
@@ -261,11 +260,10 @@ continue=Continua
 cancel=Annulla
 
 enable_custom_avatar=Abilita avatar personalizzato
-enable_custom_avatar_helper=Seleziona per disabilitare il fetch da Gravatar
 choose_new_avatar=Scegli un nuovo avatar
 update_avatar=Aggiorna le impostazioni avatar
+delete_current_avatar=Elimina Avatar attuale
 uploaded_avatar_not_a_image=Il file caricato non è un'immagine.
-no_custom_avatar_available=Nessun avatar personalizzato disponibile, impossibile abilitarlo.
 update_avatar_success=Le tue impostazioni avatar sono state aggiornate con successo.
 
 change_password=Cambia Password
@@ -274,7 +272,7 @@ new_password=Nuova Password
 retype_new_password=Re-inserisci la password
 password_incorrect=La Password attuale non è corretta.
 change_password_success=La tua password è stata cambiata con successo. Ora puoi accedere usando la nuova password.
-password_change_disabled=Non-local type users are not allowed to change their password.
+password_change_disabled=Gli utenti non locali non possono cambiare la propria password.
 
 emails=Indirizzi e-mail
 manage_emails=Gestisci indirizzi email
@@ -302,7 +300,7 @@ key_content=Contenuto
 add_key_success=La nuova chiave SSH '%s' è stata aggiunta con successo!
 delete_key=Elimina
 ssh_key_deletion=Eliminazione chiave SSH
-ssh_key_deletion_desc=Delete this SSH key will remove all related accesses for your account. Do you want to continue?
+ssh_key_deletion_desc=Cancellare la chiave SSH rimuoverà tutti i relativi accessi per il tuo account. Vuoi continuare?
 ssh_key_deletion_success=La chiave SSH e' stata cancellata con successo!
 add_on=Aggiunto il
 last_used=Ultimo accesso il
@@ -317,15 +315,15 @@ unbind_success=Account sociale disassociato.
 
 manage_access_token=Gestisci i Token di Accesso Personale
 generate_new_token=Genera Nuovo Token
-tokens_desc=Tokens you have generated that can be used to access the Gogs APIs.
+tokens_desc=I Token che hai generato e che possono essere utilizzati per accedere alle API Gogs.
 new_token_desc=Da questo momento, ogni token avrà pieno accesso al tuo account.
 token_name=Nome Token
 generate_token=Genera Token
 generate_token_succees=Nuovo token di accesso generato con successo! Assicurarsi di copiare il nuovo token di accesso personale ora: non sarà possibile visualizzarlo nuovamente!
 delete_token=Elimina
 access_token_deletion=Eliminazione Token di accesso personale
-access_token_deletion_desc=Delete this personal access token will remove all related accesses of application. Do you want to continue?
-delete_token_success=Personal access token has been removed successfully! Don't forget to update your application as well.
+access_token_deletion_desc=Eliminare questo token di accesso personale rimuoverà tutti i relativi accessi di applicazione. Si desidera continuare?
+delete_token_success=Il token di accesso personale è stato eliminato! Non dimenticare di aggiornare anche l'applicazione.
 
 delete_account=Elimina Account
 delete_prompt=L'operazione eliminerà permanentemente l'account e <strong>NON POTRÀ</strong> essere annullata!
@@ -338,9 +336,9 @@ owner=Proprietario
 repo_name=Nome Repository
 repo_name_helper=I migliori nomi dei repository sono brevi, facili da memorizzare e <strong>univoci</strong>.
 visibility=Visibilità
-visiblity_helper=This repository is <span class="ui red text">Private</span>
-visiblity_helper_forced=Site admin has forced all new repositories to be <span class="ui red text">Private</span>
-visiblity_fork_helper=(Change of this value will affect all forks)
+visiblity_helper=Questo repository è <span class="ui red text"> privato</span>
+visiblity_helper_forced=L'amministratore del sito ha deciso che tutti i nuovi repository devono essere <span class="ui red text">privati</span>
+visiblity_fork_helper=(La modifica di questo valore avrà effetto su tutti i fork)
 clone_helper=Hai bisogno di aiuto per la clonazione? Visita <a target="_blank" href="%s">Aiuto</a>!
 fork_repo=Forka Repository
 fork_from=Forka da
@@ -352,36 +350,38 @@ license=Licenza
 license_helper=Selezionare un file di licenza
 readme=Readme
 readme_helper=Seleziona un template per il readme
-auto_init=Initialize this repository with selected files and template
+auto_init=Inizializzare questo repository con i file e il modello selezionati
 create_repo=Crea Repository
 default_branch=Ramo (Branch) predefinito
+mirror_prune=Prune
+mirror_prune_desc=Remove any remote-tracking references that no longer exist on the remote
 mirror_interval=Intervallo Mirror (in ore)
-mirror_address=Mirror Address
-mirror_address_desc=Please include necessary user credentials in the address.
-watchers=Watchers
-stargazers=Stargazers
-forks=Forks
+mirror_address=Indirizzo del mirror
+mirror_address_desc=Si prega di includere nell'indirizzo le credenziali utente necessarie.
+watchers=Osservatori
+stargazers=Fan
+forks=Fork
 
-form.reach_limit_of_creation=The owner has reached maximum creation limit of %d repositories.
+form.reach_limit_of_creation=Il proprietario ha raggiunto il limite massimo di %d repository creati.
 form.name_reserved=Il nome repository %s è riservato.
 form.name_pattern_not_allowed=La struttura del nome del repository %s non è consentita.
 
 need_auth=Richiesta di autorizzazione
 migrate_type=Tipo di migrazione
-migrate_type_helper=This repository will be a <span class="text blue">mirror</span>
+migrate_type_helper=Questo repository sarà un <span class="text blue">mirror</span>
 migrate_repo=Migra Repository
 migrate.clone_address=Duplica Indirizzo
-migrate.clone_address_desc=This can be a HTTP/HTTPS/GIT URL or local server path.
-migrate.permission_denied=You are not allowed to import local repositories.
+migrate.clone_address_desc=Può essere un URL HTTP/HTTPS/GIT o il percorso del server locale.
+migrate.permission_denied=Non è consentito importare repository locali.
 migrate.invalid_local_path=Percorso locale non valido, non esiste o non è una cartella.
-migrate.failed=Migration failed: %v
+migrate.failed=Migrazione non riuscita: %v
 
-mirror_from=mirror from
+mirror_from=mirror da
 forked_from=forkato da
 fork_from_self=Non puoi forkare il tuo stesso repository!
 copy_link=Copia
 copy_link_success=Copiato!
-copy_link_error=Press ⌘-C or Ctrl-C to copy
+copy_link_error=Premere ⌘-C o Ctrl-C per copiare
 copied=OK copiato
 unwatch=Non seguire più
 watch=Segui
@@ -394,12 +394,12 @@ quick_guide=Guida rapida
 clone_this_repo=Clona questo repository
 create_new_repo_command=Crea nuovo repository da riga di comando
 push_exist_repo=Push un repo esistente dalla riga di comando
-repo_is_empty=This repository is empty, please come back later!
+repo_is_empty=Questo repository è vuoto, si prega di tornare più tardi!
 
-code=Code
+code=Codice
 branch=Ramo (Branch)
 tree=Albero (Tree)
-filter_branch_and_tag=Filter branch or tag
+filter_branch_and_tag=Filtra per branch o tag
 branches=Rami (Branch)
 tags=Tag
 issues=Problemi
@@ -412,6 +412,7 @@ file_raw=Originale
 file_history=Cronologia
 file_view_raw=Vedi originale
 file_permalink=Permalink
+file_too_large=This file is too large to be shown
 
 commits.commits=Commits
 commits.search=Ricerca una versione
@@ -427,62 +428,62 @@ issues.new.labels=Etichette
 issues.new.no_label=Nessuna etichetta
 issues.new.clear_labels=Pulisci le etichette
 issues.new.milestone=Traguardo
-issues.new.no_milestone=No Milestone
-issues.new.clear_milestone=Clear milestone
-issues.new.open_milestone=Open Milestones
-issues.new.closed_milestone=Closed Milestones
+issues.new.no_milestone=Nessuna milestone