فهرست منبع

Merge pull request #89 from achilleas-k/upstream-update-p2

Upstream update p2 (git: migrate to github.com/gogs/git-module@v1.0.0)
Michael Sonntag 4 سال پیش
والد
کامیت
85a02127d3
100فایلهای تغییر یافته به همراه6466 افزوده شده و 3865 حذف شده
  1. 0 21
      .bra.toml
  2. 1 2
      .editorconfig
  3. 17 0
      .github/workflows/lsif.yml
  4. 2 2
      .packager/hooks/postinst
  5. 1 1
      .pkgr.yml
  6. 1 0
      CHANGELOG.md
  7. 1 1
      README_ZH.md
  8. 30 25
      conf/app.ini
  9. 154 94
      conf/locale/locale_bg-BG.ini
  10. 154 94
      conf/locale/locale_cs-CZ.ini
  11. 154 94
      conf/locale/locale_de-DE.ini
  12. 154 94
      conf/locale/locale_en-GB.ini
  13. 43 28
      conf/locale/locale_en-US.ini
  14. 154 94
      conf/locale/locale_es-ES.ini
  15. 154 94
      conf/locale/locale_fa-IR.ini
  16. 166 106
      conf/locale/locale_fi-FI.ini
  17. 154 94
      conf/locale/locale_fr-FR.ini
  18. 157 97
      conf/locale/locale_gl-ES.ini
  19. 154 94
      conf/locale/locale_hu-HU.ini
  20. 157 97
      conf/locale/locale_id-ID.ini
  21. 154 94
      conf/locale/locale_it-IT.ini
  22. 154 94
      conf/locale/locale_ja-JP.ini
  23. 188 128
      conf/locale/locale_ko-KR.ini
  24. 154 94
      conf/locale/locale_lv-LV.ini
  25. 157 97
      conf/locale/locale_nl-NL.ini
  26. 154 94
      conf/locale/locale_pl-PL.ini
  27. 154 94
      conf/locale/locale_pt-BR.ini
  28. 154 94
      conf/locale/locale_pt-PT.ini
  29. 154 94
      conf/locale/locale_ru-RU.ini
  30. 154 94
      conf/locale/locale_sk-SK.ini
  31. 154 94
      conf/locale/locale_sr-SP.ini
  32. 159 99
      conf/locale/locale_sv-SE.ini
  33. 154 94
      conf/locale/locale_tr-TR.ini
  34. 154 94
      conf/locale/locale_uk-UA.ini
  35. 154 94
      conf/locale/locale_vi-VN.ini
  36. 154 94
      conf/locale/locale_zh-CN.ini
  37. 159 99
      conf/locale/locale_zh-HK.ini
  38. 154 94
      conf/locale/locale_zh-TW.ini
  39. 27 21
      go.mod
  40. 113 2
      go.sum
  41. 31 31
      internal/assets/conf/conf_gen.go
  42. 11 11
      internal/assets/public/public_gen.go
  43. 11 11
      internal/assets/templates/templates_gen.go
  44. 2 0
      internal/cmd/cmd.go
  45. 12 11
      internal/cmd/hook.go
  46. 10 4
      internal/cmd/serv.go
  47. 25 7
      internal/conf/log.go
  48. 3 3
      internal/conf/log_test.go
  49. 8 7
      internal/conf/static.go
  50. 1 1
      internal/context/auth.go
  51. 1 1
      internal/context/context.go
  52. 15 15
      internal/context/context_gin.go
  53. 44 50
      internal/context/repo.go
  54. 5 5
      internal/dav/middle.go
  55. 15 15
      internal/db/action.go
  56. 0 194
      internal/db/git_diff.go
  57. 0 41
      internal/db/git_diff_test.go
  58. 3 3
      internal/db/issue.go
  59. 7 7
      internal/db/login_source.go
  60. 6 6
      internal/db/migrations/v16.go
  61. 54 105
      internal/db/mirror.go
  62. 18 89
      internal/db/mirror_test.go
  63. 3 3
      internal/db/models_gin.go
  64. 2 2
      internal/db/org_team.go
  65. 59 44
      internal/db/pull.go
  66. 7 7
      internal/db/release.go
  67. 70 65
      internal/db/repo.go
  68. 16 16
      internal/db/repo_branch.go
  69. 61 67
      internal/db/repo_editor.go
  70. 1 1
      internal/db/token.go
  71. 2 2
      internal/db/two_factor.go
  72. 23 28
      internal/db/update.go
  73. 19 26
      internal/db/user.go
  74. 3 3
      internal/db/user_mail.go
  75. 3 3
      internal/db/webhook.go
  76. 4 4
      internal/db/webhook_dingtalk.go
  77. 4 4
      internal/db/webhook_discord.go
  78. 4 4
      internal/db/webhook_slack.go
  79. 15 21
      internal/db/wiki.go
  80. 7 11
      internal/email/message.go
  81. 4 4
      internal/form/repo.go
  82. 196 0
      internal/gitutil/diff.go
  83. 49 0
      internal/gitutil/diff_test.go
  84. 19 0
      internal/gitutil/error.go
  85. 23 0
      internal/gitutil/error_test.go
  86. 23 0
      internal/gitutil/mock.go
  87. 90 0
      internal/gitutil/module.go
  88. 69 0
      internal/gitutil/pull_request.go
  89. 108 0
      internal/gitutil/pull_request_test.go
  90. 48 0
      internal/gitutil/submodule.go
  91. 58 0
      internal/gitutil/submodule_test.go
  92. 95 0
      internal/gitutil/tag.go
  93. 109 0
      internal/gitutil/tag_test.go
  94. 1 1
      internal/httplib/httplib.go
  95. 1 6
      internal/route/admin/admin.go
  96. 1 0
      internal/route/api/v1/api.go
  97. 2 2
      internal/route/api/v1/convert/convert.go
  98. 20 19
      internal/route/api/v1/repo/commits.go
  99. 188 0
      internal/route/api/v1/repo/contents.go
  100. 10 11
      internal/route/api/v1/repo/file.go

+ 0 - 21
.bra.toml

@@ -1,21 +0,0 @@
-[run]
-init_cmds = [
-	["make", "build-dev"],
-	["./gogs", "web"]
-]
-watch_all = true
-watch_dirs = [
-	"$WORKDIR/cmd",
-	"$WORKDIR/models",
-	"$WORKDIR/pkg",
-	"$WORKDIR/routes"
-]
-watch_exts = [".go"]
-ignore_files = [".+_test.go"]
-build_delay = 1500
-interrupt_timout = 1
-graceful_kill = true
-cmds = [
-	["make", "build-dev"], # TAGS=sqlite cert pam tidb
-	["./gogs", "web"]
-]

+ 1 - 2
.editorconfig

@@ -21,5 +21,4 @@ indent_style = space
 indent_size = 2
 
 [*.js]
-indent_style = tab
-indent_size = 4
+indent_size = 2

+ 17 - 0
.github/workflows/lsif.yml

@@ -0,0 +1,17 @@
+name: LSIF
+on: [push]
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v1
+      - name: Generate LSIF data
+        uses: sourcegraph/lsif-go-action@master
+        with:
+          verbose: 'true'
+      - name: Upload LSIF data
+        uses: sourcegraph/lsif-upload-action@master
+        continue-on-error: true
+        with:
+          endpoint: https://sourcegraph.com
+          github_token: ${{ secrets.GITHUB_TOKEN }}

+ 2 - 2
.packager/hooks/postinst

@@ -8,8 +8,8 @@ APP_USER=$(${CLI} config:get APP_USER)
 APP_GROUP=$(${CLI} config:get APP_GROUP)
 APP_CONFIG="/etc/${APP_NAME}/conf/app.ini"
 
-mkdir -p $(dirname ${APP_CONFIG})
-chown "${APP_USER}"."${APP_GROUP}" $(dirname ${APP_CONFIG})
+mkdir -p "$(dirname ${APP_CONFIG})"
+chown "${APP_USER}"."${APP_GROUP}" "$(dirname ${APP_CONFIG})"
 [ -f ${APP_CONFIG} ] || ${CLI} run cp conf/app.ini ${APP_CONFIG}
 ${CLI} config:set USER="${APP_USER}"
 sed -i "s|RUN_USER = git|RUN_USER = ${APP_USER}|" ${APP_CONFIG}

+ 1 - 1
.pkgr.yml

@@ -33,4 +33,4 @@ before:
 after:
   - mv bin/gogs gogs
 after_install: ./.packager/hooks/postinst
-buildpack: https://github.com/heroku/heroku-buildpack-go.git#v126
+buildpack: https://github.com/heroku/heroku-buildpack-go.git

+ 1 - 0
CHANGELOG.md

@@ -53,6 +53,7 @@ All notable changes to Gogs are documented in this file.
 - Configuration option `[repository] PULL_REQUEST_QUEUE_LENGTH`
 - Configuration option `[session] ENABLE_SET_COOKIE`
 - Configuration option `[release.attachment] PATH`
+- Configuration option `[webhook] QUEUE_LENGTH`
 
 ---
 

+ 1 - 1
README_ZH.md

@@ -30,7 +30,7 @@ Gogs(`/gɑgz/`)项目旨在打造一个以最简便的方式搭建简单、
 - 通过 SMTP、LDAP、反向代理、GitHub.com 和 GitHub 企业版进行用户认证
 - 开启两步验证(2FA)登录
 - 自定义 HTML 模板、静态文件和许多其它组件
-- 多样的数据库后端,包括 PostgreSQL、MySQL、SQLite3、MSSQL 和 [TiDB](https://github.com/pingcap/tidb)
+- 多样的数据库后端,包括 PostgreSQL、MySQL、SQLite3 和 [TiDB](https://github.com/pingcap/tidb)
 - 超过[30 种语言](https://crowdin.com/project/gogs)的本地化
 
 ## 硬件要求

+ 30 - 25
conf/app.ini

@@ -2,7 +2,7 @@
 # !!! PLEASE MAKE CHANGES ON CORRESPONDING CUSTOM CONFIG FILE !!!
 # !!! IF YOU ARE PACKAGING PROVIDER, PLEASE MAKE OWN COPY OF IT !!!
 
-; The brand name of the application.
+; The brand name of the application, can be your company or team name.
 BRAND_NAME = Gogs
 ; The system user who should be running the applications. It has no effect on Windows,
 ; otherwise, it should match the value of $USER environment variable.
@@ -52,7 +52,8 @@ APP_DATA_PATH = data
 ; Whether to enable to load assets (i.e. "conf", "templates", "public") from disk instead of embedded bindata.
 LOAD_ASSETS_FROM_DISK = false
 
-; The landing page URL for anonymous users, can be a link to a external site.
+; The landing page URL for anonymous users, the value should not include
+; subpath that is handled by the reverse proxy.
 LANDING_URL = /
 
 ; Whether to disable SSH access to the application entirely.
@@ -314,16 +315,17 @@ DISABLE_GRAVATAR = false
 ENABLE_FEDERATED_AVATAR = false
 
 [markdown]
-; Enable hard line break extension
+; Whether to 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
+; The list of custom URL schemes that are allowed as links when rendering Markdown.
+; For example, "git" (for "git://") and "magnet" (for "magnet://").
 CUSTOM_URL_SCHEMES =
-; List of file extensions that should be rendered/edited as Markdown
-; Separate extensions with a comma. To render files w/o extension as markdown, just put a comma
+; The list of file extensions that should be rendered/edited as Markdown.
+; Separate extensions with a comma. To render files with no extension as markdown, just put a comma.
 FILE_EXTENSIONS = .md,.markdown,.mdown,.mkd
 
 [smartypants]
+; Whether to enable the Smartypants extension.
 ENABLED = false
 FRACTIONS = true
 DASHES = true
@@ -331,25 +333,24 @@ LATEX_DASHES = true
 ANGLED_QUOTES = true
 
 [admin]
-; Disable regular (non-admin) users to create organizations
+; Whether to disable regular (non-admin) users to create organizations.
 DISABLE_REGULAR_ORG_CREATION = false
 
 [webhook]
-; Types are enabled for users to use, can be "gogs", "slack", "discord", "dingtalk"
+; The list of enabled types for users to use, can be "gogs", "slack", "discord", "dingtalk".
 TYPES = gogs, slack, discord, dingtalk
-; Hook task queue length, increase if webhook shooting starts hanging
-QUEUE_LENGTH = 1000
-; Deliver timeout in seconds
+; Deliver timeout in seconds.
 DELIVER_TIMEOUT = 15
-; Allow insecure certification
+; Whether to allow insecure certification.
 SKIP_TLS_VERIFY = false
-; Number of history information in each page
+; The number of history information in each page.
 PAGING_NUM = 10
 
-; General settings of loggers
+; General settings of loggers.
 [log]
+; The root path for all log files, default is "log/" subdirectory.
 ROOT_PATH =
-; Can be "console" and "file", default is "console"
+; Can be "console", "file", "slack" and "discord".
 ; Use comma to separate multiple modes, e.g. "console, file"
 MODE = console
 ; Buffer length of channel, keep it as it is if you don't know what it is.
@@ -366,15 +367,15 @@ LEVEL = Trace
 [log.file]
 ; Comment out to inherit
 ; LEVEL =
-; This enables automated log rotate (switch of following options)
+; Whether to enable automated log rotate (switch of following options).
 LOG_ROTATE = true
-; Segment log daily
+; Whether to segment log files daily.
 DAILY_ROTATE = true
-; Max size shift of single file, default is 28 means 1 << 28, 256MB
+; The maximum size shift of single file, default is 28 means 1 << 28 = 256MB.
 MAX_SIZE_SHIFT = 28
-; Max line number of single file
+; The maximum number of lines of single file.
 MAX_LINES = 1000000
-; Expired days of log file (delete after max days)
+; The expired days of log file (delete after max days).
 MAX_DAYS = 7
 
 ; For "slack" mode only
@@ -389,7 +390,7 @@ URL =
 ; LEVEL =
 ; Webhook URL
 URL =
-; Username displayed in webhook
+; The username to be displayed in notification.
 USERNAME = %(BRAND_NAME)s
 
 [log.xorm]
@@ -435,12 +436,12 @@ OLDER_THAN = 24h
 [git]
 ; Disables highlight of added and removed changes
 DISABLE_DIFF_HIGHLIGHT = false
+; Max number of files shown in diff view
+MAX_GIT_DIFF_FILES = 100
 ; 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
+MAX_GIT_DIFF_LINE_CHARACTERS = 2000
 ; Arguments for command 'git gc', e.g. "--aggressive --auto"
 ; see more on http://git-scm.com/docs/git-gc/1.7.5
 GC_ARGS =
@@ -496,9 +497,13 @@ NEWS_FEED_PAGING_NUM = 20
 COMMITS_PAGING_NUM = 30
 
 [prometheus]
+; Whether to enable Prometheus metrics.
 ENABLED = true
+; Whether to enable HTTP Basic Authentication to protect metrics data.
 ENABLE_BASIC_AUTH = false
+; The username for HTTP Basic Authentication.
 BASIC_AUTH_USERNAME =
+; The password for HTTP Basic Authentication.
 BASIC_AUTH_PASSWORD =
 
 ; Extension mapping to highlight class

+ 154 - 94
conf/locale/locale_bg-BG.ini

@@ -9,7 +9,6 @@ sign_out=Изход
 sign_up=Регистрирайте се
 register=Регистрация
 website=Уебсайт
-version=Версия
 page=Страница
 template=Шаблон
 language=Език
@@ -122,6 +121,7 @@ run_user_not_match=Потребителският контекст на прил
 smtp_host_missing_port=Липсва порт в зададения SMTP адрес.
 invalid_smtp_from=Невалидно поле От: %v
 save_config_failed=Неуспешно запазване на конфигурация: %v
+init_failed=Failed to initialize application: %v
 invalid_admin_setting=Настройките на профил на администратора са невалидни: %v
 install_success=Добре дошли! Радваме се, че избрахте Gogs, и Ви пожелаваме приятна работа и сърдечни поздрави!
 invalid_log_root_path=Основният път към журналите е невалиден: %v
@@ -1001,6 +1001,12 @@ first_page=Първа
 last_page=Последна
 total=Общо: %d
 
+dashboard.build_info=Build Information
+dashboard.app_ver=Application version
+dashboard.git_version=Git version
+dashboard.go_version=Go version
+dashboard.build_time=Build time
+dashboard.build_commit=Build commit
 dashboard.statistic=Статистика
 dashboard.operations=Операции
 dashboard.system_status=Наблюдение на системния статус
@@ -1156,117 +1162,170 @@ auths.github_api_endpoint=API Endpoint
 
 config.not_set=(not set)
 config.server_config=Сървърни настройки
-config.app_name=Име на приложението
-config.app_ver=Версия на приложението
-config.app_url=URL адрес на приложението
-config.domain=Домейн
-config.offline_mode=Офлайн режим
-config.disable_router_log=Изключи журнал на маршрутизатора
+config.brand_name=Brand name
 config.run_user=Потребителски контекст
 config.run_mode=Режим на изпълнение
-config.git_version=Git версия
-config.static_file_root_path=Път към статични файлове
-config.log_file_root_path=Път към журнал
-config.reverse_auth_user=Потребителско име при обратно удостоверяване
+config.server.external_url=External URL
+config.server.domain=Domain
+config.server.protocol=Protocol
+config.server.http_addr=HTTP address
+config.server.http_port=HTTP port
+config.server.cert_file=Certificate file
+config.server.key_file=Key file
+config.server.tls_min_version=Minimum TLS version
+config.server.unix_socket_permission=Unix socket permission
+config.server.local_root_url=Local root URL
+config.server.offline_mode=Offline mode
+config.server.disable_router_log=Disable router log
+config.server.enable_gzip=Enable Gzip
+config.server.app_data_path=Application data path
+config.server.load_assets_from_disk=Load assets from disk
+config.server.landing_url=Landing URL
 
 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_rewrite_authorized_keys_at_start=Rewrite authorized_keys At Start
-config.ssh_key_test_path=Път до ключове
-config.ssh_keygen_path=Път до генератор ('ssh-keygen')
-config.ssh_minimum_key_size_check=Проверка за минимален размер на ключове
-config.ssh_minimum_key_sizes=Минимален размер на ключове
+config.ssh.enabled=Enabled
+config.ssh.domain=Exposed domain
+config.ssh.port=Exposed port
+config.ssh.root_path=Root path
+config.ssh.keygen_path=Keygen path
+config.ssh.key_test_path=Key test path
+config.ssh.minimum_key_size_check=Minimum key size check
+config.ssh.minimum_key_sizes=Minimum key sizes
+config.ssh.rewrite_authorized_keys_at_start=Rewrite "authorized_keys" at start
+config.ssh.start_builtin_server=Start builtin server
+config.ssh.listen_host=Listen host
+config.ssh.listen_port=Listen port
+config.ssh.server_ciphers=Server ciphers
 
 config.repo_config=Конфигурация на хранилище
-config.repo_root_path=Основен път към хранилища
-config.script_type=Тип на скрипта
-config.repo_force_private=Force Private
-config.max_creation_limit=Max Creation Limit
-config.preferred_licenses=Предпочитани лицензи
-config.disable_http_git=Забраняване на HTTP Git
-config.enable_local_path_migration=Enable Local Path Migration
-config.commits_fetch_concurrency=Commits Fetch Concurrency
-
-config.http_config=Конфигуриране на HTTP
-config.http_access_control_allow_origin=Access Control Allow Origin
+config.repo.root_path=Root path
+config.repo.script_type=Script type
+config.repo.ansi_chatset=ANSI charset
+config.repo.force_private=Force private
+config.repo.max_creation_limit=Max creation limit
+config.repo.preferred_licenses=Preferred licenses
+config.repo.disable_http_git=Disable HTTP Git
+config.repo.enable_local_path_migration=Enable local path migration
+config.repo.enable_raw_file_render_mode=Enable raw file render mode
+config.repo.commits_fetch_concurrency=Commits fetch concurrency
+config.repo.editor.line_wrap_extensions=Editor line wrap extensions
+config.repo.editor.previewable_file_modes=Editor previewable file modes
+config.repo.upload.enabled=Upload enabled
+config.repo.upload.temp_path=Upload temporary path
+config.repo.upload.allowed_types=Upload allowed types
+config.repo.upload.file_max_size=Upload file size limit
+config.repo.upload.max_files=Upload files limit
 
 config.db_config=Настройки на базата данни
-config.db_type=Тип
-config.db_host=Сървър
-config.db_name=Име
-config.db_user=Потребител
-config.db_ssl_mode=SSL режим
-config.db_ssl_mode_helper=(само за postgres)
-config.db_path=Път
-config.db_path_helper=(за "sqlite3" и "tidb")
-
-config.service_config=Настройка на услугата
-config.register_email_confirm=Изисквай потвърждение на адреси на ел. поща
-config.disable_register=Изключи нови регистрации
-config.show_registration_button=Покажи бутон за регистрация
-config.require_sign_in_view=Изисквай вписване за преглед
-config.mail_notify=Уведомяване по ел. поща
-config.disable_key_size_check=Изключи проверка минимален размер на ключ
-config.enable_captcha=Включи Captcha
-config.active_code_lives=Кодове за активиране
-config.reset_password_code_lives=Кодове за изчистване на парола
+config.db.type=Type
+config.db.host=Host
+config.db.name=Name
+config.db.user=User
+config.db.ssl_mode=SSL mode
+config.db.ssl_mode_helper=(for "postgres" only)
+config.db.path=Path
+config.db.path_helper=(for "sqlite3"only)
+
+config.security_config=Security configuration
+config.security.login_remember_days=Login remember days
+config.security.cookie_remember_name=Remember cookie
+config.security.cookie_username=Username cookie
+config.security.cookie_secure=Enable secure cookie
+config.security.reverse_proxy_auth_user=Reverse proxy authentication header
+config.security.enable_login_status_cookie=Enable login status cookie
+config.security.login_status_cookie_name=Login status cookie
+
+config.email_config=Email configuration
+config.email.enabled=Enabled
+config.email.subject_prefix=Subject prefix
+config.email.host=Host
+config.email.from=From
+config.email.user=User
+config.email.disable_helo=Disable HELO
+config.email.helo_hostname=HELO hostname
+config.email.skip_verify=Skip certificate verify
+config.email.use_certificate=Use custom certificate
+config.email.cert_file=Certificate file
+config.email.key_file=Key file
+config.email.use_plain_text=Use plain text
+config.email.add_plain_text_alt=Add plain text alternative
+config.email.send_test_mail=Send test email
+config.email.test_mail_failed=Failed to send test email to '%s': %v
+config.email.test_mail_sent=Test email has been sent to '%s'.
+
+config.auth_config=Authentication configuration
+config.auth.activate_code_lives=Activate code lives
+config.auth.reset_password_code_lives=Reset password code lives
+config.auth.require_email_confirm=Require email confirmation
+config.auth.require_sign_in_view=Require sign in view
+config.auth.disable_registration=Disable registration
+config.auth.enable_registration_captcha=Enable registration captcha
+config.auth.enable_reverse_proxy_authentication=Enable reverse proxy authentication
+config.auth.enable_reverse_proxy_auto_registration=Enable reverse proxy auto registration
+config.auth.reverse_proxy_authentication_header=Reverse proxy authentication header
+
+config.user_config=User configuration
+config.user.enable_email_notify=Enable email notification
 
-config.webhook_config=Конфигурация на уеб-куки
-config.queue_length=Дължина на опашка
-config.deliver_timeout=Време за отказ при изпращане
-config.skip_tls_verify=Пропусни проверка на TLS
-
-config.mailer_config=Конфигурация на мейлър
-config.mailer_enabled=Активен
-config.mailer_disable_helo=Изключи HELO
-config.mailer_subject_prefix=Subject Prefix
-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.session_config=Конфигурация на сесии
+config.session.provider=Provider
+config.session.provider_config=Provider config
+config.session.cookie_name=Cookie
+config.session.https_only=HTTPS only
+config.session.gc_interval=GC interval
+config.session.max_life_time=Max life time
+config.session.csrf_cookie_name=CSRF cookie
 
 config.cache_config=Конфигурация на кеша
-config.cache_adapter=Кеш адаптер
-config.cache_interval=Кеш интервал
-config.cache_conn=Кеш на връзката
+config.cache.adapter=Adapter
+config.cache.interval=GC interval
+config.cache.host=Host
 
-config.session_config=Конфигурация на сесии
-config.session_provider=Доставчик на сесии
-config.provider_config=Конфигурация на доставчик
-config.cookie_name=Име на бисквитката
-config.enable_set_cookie=Включи използване на бисквитки
-config.gc_interval_time=GC през интервал
-config.session_life_time=Период на валидност на сесиите
-config.https_only=HTTPS само
-config.cookie_life_time=Период на валидност на бисквитките
+config.http_config=Конфигуриране на HTTP
+config.http.access_control_allow_origin=Access control allow origin
+
+config.attachment_config=Attachment configuration
+config.attachment.enabled=Enabled
+config.attachment.path=Path
+config.attachment.allowed_types=Allowed types
+config.attachment.max_size=Size limit
+config.attachment.max_files=Files limit
+
+config.release_config=Release configuration
+config.release.attachment.enabled=Attachment enabled
+config.release.attachment.allowed_types=Attachment allowed types
+config.release.attachment.max_size=Attachment size limit
+config.release.attachment.max_files=Attachment files limit
 
 config.picture_config=Конфигурация на изображения
-config.picture_service=Услуги за снимки
-config.disable_gravatar=Изключи Gravatar
-config.enable_federated_avatar=Включи външни аватари
+config.picture.avatar_upload_path=User avatar upload path
+config.picture.repo_avatar_upload_path=Repository avatar upload path
+config.picture.gravatar_source=Gravatar source
+config.picture.disable_gravatar=Disable Gravatar
+config.picture.enable_federated_avatar=Enable federated avatars
+
+config.mirror_config=Mirror configuration
+config.mirror.default_interval=Default interval
+
+config.webhook_config=Конфигурация на уеб-куки
+config.webhook.types=Types
+config.webhook.deliver_timeout=Deliver timeout
+config.webhook.skip_tls_verify=Skip TLS verify
 
 config.git_config=Конфигурация на git
-config.git_disable_diff_highlight=Забрани оцветяване на синтаксис при преглед на разлики
-config.git_max_diff_lines=Максимален брой различни редове (за файл)
-config.git_max_diff_line_characters=Максимален брой различни символи (на ред)
-config.git_max_diff_files=Максимален брой променени файлове (при показване)
-config.git_gc_args=Аргументи на GC
-config.git_migrate_timeout=Време за отказ при миграция
-config.git_mirror_timeout=Време за отказ при синхр. на огледало
-config.git_clone_timeout=Време за отказ при клониране
-config.git_pull_timeout=Време за отказ при сливане
-config.git_gc_timeout=Време за отказ при GC
+config.git.disable_diff_highlight=Disable diff syntax highlight
+config.git.max_diff_lines=Diff lines limit (for a single file)
+config.git.max_diff_line_characters=Diff characters limit (for a single line)
+config.git.max_diff_files=Diff files limit (for a single diff)
+config.git.gc_args=GC arguments
+config.git.migrate_timeout=Migration timeout
+config.git.mirror_timeout=Mirror fetch timeout
+config.git.clone_timeout=Clone timeout
+config.git.pull_timeout=Pull timeout
+config.git.gc_timeout=GC timeout
 
 config.log_config=Конфигурация на журнал
+config.log_file_root_path=Път към журнал
 config.log_mode=Режим
 config.log_options=Настройки
 
@@ -1338,6 +1397,7 @@ months=%[2]s %[1]d месеца
 years=%[2]s %[1]d години
 raw_seconds=секунди
 raw_minutes=минути
+raw_hours=hours
 
 [dropzone]
 default_message=Тук пуснете файлове с влачене или просто щракнете за избор на файл за качване.

+ 154 - 94
conf/locale/locale_cs-CZ.ini

@@ -9,7 +9,6 @@ sign_out=Odhlásit se
 sign_up=Registrovat se
 register=Registrovat se
 website=Webové stránky
-version=Verze
 page=Strana
 template=Šablona
 language=Jazyk
@@ -122,6 +121,7 @@ run_user_not_match=Uživatel pro spuštění není aktuální uživatel: %s -> %
 smtp_host_missing_port=V adrese SMTP serveru chybí číslo portu.
 invalid_smtp_from=Hodnota položky SMTP Od: není zadána správně: %v
 save_config_failed=Uložení konfigurace se nezdařilo: %v
+init_failed=Failed to initialize application: %v
 invalid_admin_setting=Nastavení účtu správce není správné: %v
 install_success=Vítejte! Jsme rádi, že jste si vybrali GIN. Bavte se a opatrujte se.
 invalid_log_root_path=Kořenový adresář souborů systémových záznamů není správný: %v
@@ -1001,6 +1001,12 @@ first_page=První
 last_page=Poslední
 total=Celkem: %d
 
+dashboard.build_info=Build Information
+dashboard.app_ver=Application version
+dashboard.git_version=Git version
+dashboard.go_version=Go version
+dashboard.build_time=Build time
+dashboard.build_commit=Build commit
 dashboard.statistic=Statistika
 dashboard.operations=Operace
 dashboard.system_status=Stav sledování systému
@@ -1156,117 +1162,170 @@ auths.github_api_endpoint=Koncový bod API
 
 config.not_set=(není nastaveno)
 config.server_config=Nastavení serveru
-config.app_name=Název aplikace
-config.app_ver=Verze aplikace
-config.app_url=URL aplikace
-config.domain=Doména
-config.offline_mode=Režim off-line
-config.disable_router_log=Vypnout systémové záznamy směrovače
+config.brand_name=Brand name
 config.run_user=Účet pro spouštění
 config.run_mode=Režim spouštění
-config.git_version=Verze Gitu
-config.static_file_root_path=Kořenový adresář statického souboru
-config.log_file_root_path=Kořenový adresář souboru systémových záznamů
-config.reverse_auth_user=Uživatel obráceného ověření
+config.server.external_url=External URL
+config.server.domain=Domain
+config.server.protocol=Protocol
+config.server.http_addr=HTTP address
+config.server.http_port=HTTP port
+config.server.cert_file=Certificate file
+config.server.key_file=Key file
+config.server.tls_min_version=Minimum TLS version
+config.server.unix_socket_permission=Unix socket permission
+config.server.local_root_url=Local root URL
+config.server.offline_mode=Offline mode
+config.server.disable_router_log=Disable router log
+config.server.enable_gzip=Enable Gzip
+config.server.app_data_path=Application data path
+config.server.load_assets_from_disk=Load assets from disk
+config.server.landing_url=Landing URL
 
 config.ssh_config=Nastavení SSH
-config.ssh_enabled=Povolený
-config.ssh_start_builtin_server=Spustit vestavěný server
-config.ssh_domain=Doména
-config.ssh_port=Port
-config.ssh_listen_port=Port pro naslouchání
-config.ssh_root_path=Kořenová cesta
-config.ssh_rewrite_authorized_keys_at_start=Přepsat authorized_keys při startu
-config.ssh_key_test_path=Cesta testu klíčů
-config.ssh_keygen_path=Cesta ke generátoru klíčů ('ssh-keygen')
-config.ssh_minimum_key_size_check=Kontrola minimální velikosti klíčů
-config.ssh_minimum_key_sizes=Minimální velikost klíčů
+config.ssh.enabled=Enabled
+config.ssh.domain=Exposed domain
+config.ssh.port=Exposed port
+config.ssh.root_path=Root path
+config.ssh.keygen_path=Keygen path
+config.ssh.key_test_path=Key test path
+config.ssh.minimum_key_size_check=Minimum key size check
+config.ssh.minimum_key_sizes=Minimum key sizes
+config.ssh.rewrite_authorized_keys_at_start=Rewrite "authorized_keys" at start
+config.ssh.start_builtin_server=Start builtin server
+config.ssh.listen_host=Listen host
+config.ssh.listen_port=Listen port
+config.ssh.server_ciphers=Server ciphers
 
 config.repo_config=Nastavení repositáře
-config.repo_root_path=Kořenový adresář repositářů
-config.script_type=Typ skriptu
-config.repo_force_private=Vynutit soukromé
-config.max_creation_limit=Maximální lhůta pro vytvoření
-config.preferred_licenses=Upřednostňované licence
-config.disable_http_git=Vypnout HTTP Git
-config.enable_local_path_migration=Povolit migraci z místní cesty
-config.commits_fetch_concurrency=Souběžnost vyzvednutí revizí
-
-config.http_config=Nastavení HTTP
-config.http_access_control_allow_origin=Access Control Allow Origin
+config.repo.root_path=Root path
+config.repo.script_type=Script type
+config.repo.ansi_chatset=ANSI charset
+config.repo.force_private=Force private
+config.repo.max_creation_limit=Max creation limit
+config.repo.preferred_licenses=Preferred licenses
+config.repo.disable_http_git=Disable HTTP Git
+config.repo.enable_local_path_migration=Enable local path migration
+config.repo.enable_raw_file_render_mode=Enable raw file render mode
+config.repo.commits_fetch_concurrency=Commits fetch concurrency
+config.repo.editor.line_wrap_extensions=Editor line wrap extensions
+config.repo.editor.previewable_file_modes=Editor previewable file modes
+config.repo.upload.enabled=Upload enabled
+config.repo.upload.temp_path=Upload temporary path
+config.repo.upload.allowed_types=Upload allowed types
+config.repo.upload.file_max_size=Upload file size limit
+config.repo.upload.max_files=Upload files limit
 
 config.db_config=Nastavení databáze
-config.db_type=Typ
-config.db_host=Server
-config.db_name=Název
-config.db_user=Uživatel
-config.db_ssl_mode=SSL režim
-config.db_ssl_mode_helper=(pouze pro 'postgres')
-config.db_path=Cesta
-config.db_path_helper=(pro "sqlite3" a "tidb")
-
-config.service_config=Nastavení služby
-config.register_email_confirm=Vyžadovat potvrzení e-mailu
-config.disable_register=Vypnout registraci
-config.show_registration_button=Ukázat tlačítko registrace
-config.require_sign_in_view=Vyžadovat zobrazení přihlášení
-config.mail_notify=Upozornění e-mailem
-config.disable_key_size_check=Vypnout kontrolu minimální velikosti klíčů
-config.enable_captcha=Povolit službu CAPTCHA
-config.active_code_lives=Doba života aktivního kódu
-config.reset_password_code_lives=Lhůta kódu pro obnovu hesla
+config.db.type=Type
+config.db.host=Host
+config.db.name=Name
+config.db.user=User
+config.db.ssl_mode=SSL mode
+config.db.ssl_mode_helper=(for "postgres" only)
+config.db.path=Path
+config.db.path_helper=(for "sqlite3"only)
+
+config.security_config=Security configuration
+config.security.login_remember_days=Login remember days
+config.security.cookie_remember_name=Remember cookie
+config.security.cookie_username=Username cookie
+config.security.cookie_secure=Enable secure cookie
+config.security.reverse_proxy_auth_user=Reverse proxy authentication header
+config.security.enable_login_status_cookie=Enable login status cookie
+config.security.login_status_cookie_name=Login status cookie
+
+config.email_config=Email configuration
+config.email.enabled=Enabled
+config.email.subject_prefix=Subject prefix
+config.email.host=Host
+config.email.from=From
+config.email.user=User
+config.email.disable_helo=Disable HELO
+config.email.helo_hostname=HELO hostname
+config.email.skip_verify=Skip certificate verify
+config.email.use_certificate=Use custom certificate
+config.email.cert_file=Certificate file
+config.email.key_file=Key file
+config.email.use_plain_text=Use plain text
+config.email.add_plain_text_alt=Add plain text alternative
+config.email.send_test_mail=Send test email
+config.email.test_mail_failed=Failed to send test email to '%s': %v
+config.email.test_mail_sent=Test email has been sent to '%s'.
+
+config.auth_config=Authentication configuration
+config.auth.activate_code_lives=Activate code lives
+config.auth.reset_password_code_lives=Reset password code lives
+config.auth.require_email_confirm=Require email confirmation
+config.auth.require_sign_in_view=Require sign in view
+config.auth.disable_registration=Disable registration
+config.auth.enable_registration_captcha=Enable registration captcha
+config.auth.enable_reverse_proxy_authentication=Enable reverse proxy authentication
+config.auth.enable_reverse_proxy_auto_registration=Enable reverse proxy auto registration
+config.auth.reverse_proxy_authentication_header=Reverse proxy authentication header
+
+config.user_config=User configuration
+config.user.enable_email_notify=Enable email notification
 
-config.webhook_config=Nastavení webových háčků
-config.queue_length=Délka fronty
-config.deliver_timeout=Časový limit doručení
-config.skip_tls_verify=Přeskočit ověření TLS
-
-config.mailer_config=Nastavení odesílání e-mailů
-config.mailer_enabled=Povolený
-config.mailer_disable_helo=Vypnout HELO
-config.mailer_subject_prefix=Předpona předmětu
-config.mailer_host=Server
-config.mailer_user=Uživatel
-config.send_test_mail=Odeslat zkušební E-mail
-config.test_mail_failed=Odeslání testovacího e-mailu na '%s' selhalo: %v
-config.test_mail_sent=Zkušební e-mail byl odeslán na '%s'.
-
-config.oauth_config=Nastavení ověření OAuth
-config.oauth_enabled=Povolený
+config.session_config=Nastavení relace
+config.session.provider=Provider
+config.session.provider_config=Provider config
+config.session.cookie_name=Cookie
+config.session.https_only=HTTPS only
+config.session.gc_interval=GC interval
+config.session.max_life_time=Max life time
+config.session.csrf_cookie_name=CSRF cookie
 
 config.cache_config=Nastavení mezipaměti
-config.cache_adapter=Adaptér mezipaměti
-config.cache_interval=Interval mezipaměti
-config.cache_conn=Připojení mezipaměti
+config.cache.adapter=Adapter
+config.cache.interval=GC interval
+config.cache.host=Host
 
-config.session_config=Nastavení relace
-config.session_provider=Poskytovatel relace
-config.provider_config=Nastavení poskytovatele
-config.cookie_name=Název souboru cookie
-config.enable_set_cookie=Povolit nastavení cookie
-config.gc_interval_time=Čas intervalu GC
-config.session_life_time=Doba trvání relace
-config.https_only=Pouze protokol HTTPS
-config.cookie_life_time=Doba života souboru cookie
+config.http_config=Nastavení HTTP
+config.http.access_control_allow_origin=Access control allow origin
+
+config.attachment_config=Attachment configuration
+config.attachment.enabled=Enabled
+config.attachment.path=Path
+config.attachment.allowed_types=Allowed types
+config.attachment.max_size=Size limit
+config.attachment.max_files=Files limit
+
+config.release_config=Release configuration
+config.release.attachment.enabled=Attachment enabled
+config.release.attachment.allowed_types=Attachment allowed types
+config.release.attachment.max_size=Attachment size limit
+config.release.attachment.max_files=Attachment files limit
 
 config.picture_config=Nastavení ikony uživatele
-config.picture_service=Služba ikon uživatelů
-config.disable_gravatar=Vypnout službu Gravatar
-config.enable_federated_avatar=Povolit jednotné ikony uživatelů
+config.picture.avatar_upload_path=User avatar upload path
+config.picture.repo_avatar_upload_path=Repository avatar upload path
+config.picture.gravatar_source=Gravatar source
+config.picture.disable_gravatar=Disable Gravatar
+config.picture.enable_federated_avatar=Enable federated avatars
+
+config.mirror_config=Mirror configuration
+config.mirror.default_interval=Default interval
+
+config.webhook_config=Nastavení webových háčků
+config.webhook.types=Types
+config.webhook.deliver_timeout=Deliver timeout
+config.webhook.skip_tls_verify=Skip TLS verify
 
 config.git_config=Konfigurace Gitu
-config.git_disable_diff_highlight=Vypnout zvýraznění syntaxe v rozdílovém zobrazení
-config.git_max_diff_lines=Maximální počet rozdílných řádků jednoho souboru
-config.git_max_diff_line_characters=Maximální počet zobrazených rozdílných znaků jedné řádky
-config.git_max_diff_files=Maximální počet zobrazených rozdílných souborů
-config.git_gc_args=Parametry GC
-config.git_migrate_timeout=Časová lhůta přenesení
-config.git_mirror_timeout=Časový limit aktualizace zrcadla
-config.git_clone_timeout=Časový limit operace naklonování
-config.git_pull_timeout=Časový limit operace stažení
-config.git_gc_timeout=Časový limit operace GC
+config.git.disable_diff_highlight=Disable diff syntax highlight
+config.git.max_diff_lines=Diff lines limit (for a single file)
+config.git.max_diff_line_characters=Diff characters limit (for a single line)
+config.git.max_diff_files=Diff files limit (for a single diff)
+config.git.gc_args=GC arguments
+config.git.migrate_timeout=Migration timeout
+config.git.mirror_timeout=Mirror fetch timeout
+config.git.clone_timeout=Clone timeout
+config.git.pull_timeout=Pull timeout
+config.git.gc_timeout=GC timeout
 
 config.log_config=Nastavení systémových záznamů
+config.log_file_root_path=Kořenový adresář souboru systémových záznamů
 config.log_mode=Režim
 config.log_options=Možnosti
 
@@ -1338,6 +1397,7 @@ months=%[2]s %[1]d měsíci
 years=%[2]s %[1]d roky
 raw_seconds=sekundy
 raw_minutes=minuty
+raw_hours=hours
 
 [dropzone]
 default_message=Přetáhněte soubory sem nebo stiskněte Nahrát.

+ 154 - 94
conf/locale/locale_de-DE.ini

@@ -9,7 +9,6 @@ sign_out=Abmelden
 sign_up=Registrieren
 register=Registrieren
 website=Webseite
-version=Version
 page=Seite
 template=Vorlage
 language=Sprache
@@ -122,6 +121,7 @@ run_user_not_match=Der ausführende Benutzer ist nicht der aktuelle Benutzer: %s
 smtp_host_missing_port=In der Adresse des SMTP Host fehlt die Portnummer.
 invalid_smtp_from=SMTP Absender Feld ist nicht gültig: %v
 save_config_failed=Fehler beim Speichern der Konfiguration: %v
+init_failed=Failed to initialize application: %v
 invalid_admin_setting=Admin-Konto Einstellungen sind ungültig: %v
 install_success=Herzlich Willkommen! Wir sind froh, dass Sie sich für GIN entschieden haben. Wir wünschen viel Vergnügen damit.
 invalid_log_root_path=Pfad zum Log-Verzeichnis ist ungültig: %v
@@ -1005,6 +1005,12 @@ first_page=Erste
 last_page=Letzte
 total=Gesamt: %d
 
+dashboard.build_info=Build Information
+dashboard.app_ver=Application version
+dashboard.git_version=Git version
+dashboard.go_version=Go version
+dashboard.build_time=Build time
+dashboard.build_commit=Build commit
 dashboard.statistic=Statistik
 dashboard.operations=Operationen
 dashboard.system_status=Systemmonitor-Status
@@ -1160,117 +1166,170 @@ auths.github_api_endpoint=API Endpunkt
 
 config.not_set=(nicht festgelegt)
 config.server_config=Serverkonfiguration
-config.app_name=Name der Anwendung
-config.app_ver=Anwendungsversion
-config.app_url=Anwendungs-URL
-config.domain=Domain
-config.offline_mode=Offline-Modus
-config.disable_router_log=Router-Log deaktivieren
+config.brand_name=Brand name
 config.run_user=Ausführender Benutzer
 config.run_mode=Laufzeit-Modus
-config.git_version=Git Version
-config.static_file_root_path=Verzeichnis für statische Dateien
-config.log_file_root_path=Log-Verzeichnis
-config.reverse_auth_user=Nutzer bei Reverse-Authentifizierung
+config.server.external_url=External URL
+config.server.domain=Domain
+config.server.protocol=Protocol
+config.server.http_addr=HTTP address
+config.server.http_port=HTTP port
+config.server.cert_file=Certificate file
+config.server.key_file=Key file
+config.server.tls_min_version=Minimum TLS version
+config.server.unix_socket_permission=Unix socket permission
+config.server.local_root_url=Local root URL
+config.server.offline_mode=Offline mode
+config.server.disable_router_log=Disable router log
+config.server.enable_gzip=Enable Gzip
+config.server.app_data_path=Application data path
+config.server.load_assets_from_disk=Load assets from disk
+config.server.landing_url=Landing URL
 
 config.ssh_config=SSH Konfiguration
-config.ssh_enabled=Aktiviert
-config.ssh_start_builtin_server=Eingebauten Server starten
-config.ssh_domain=Domain
-config.ssh_port=Port
-config.ssh_listen_port=Listen Port
-config.ssh_root_path=Verzeichnis
-config.ssh_rewrite_authorized_keys_at_start=Beim Start authorized_keys umschreiben
-config.ssh_key_test_path=Schlüssel-Test-Pfad
-config.ssh_keygen_path=Keygen ('ssh-keygen') Pfad
-config.ssh_minimum_key_size_check=Prüfung der Mindestschlüssellänge
-config.ssh_minimum_key_sizes=Minimale Schlüssellängen
+config.ssh.enabled=Enabled
+config.ssh.domain=Exposed domain
+config.ssh.port=Exposed port
+config.ssh.root_path=Root path
+config.ssh.keygen_path=Keygen path
+config.ssh.key_test_path=Key test path
+config.ssh.minimum_key_size_check=Minimum key size check
+config.ssh.minimum_key_sizes=Minimum key sizes
+config.ssh.rewrite_authorized_keys_at_start=Rewrite "authorized_keys" at start
+config.ssh.start_builtin_server=Start builtin server
+config.ssh.listen_host=Listen host
+config.ssh.listen_port=Listen port
+config.ssh.server_ciphers=Server ciphers
 
 config.repo_config=Repository-Konfiguration
-config.repo_root_path=Repository-Verzeichnis
-config.script_type=Skript-Typ
-config.repo_force_private=Erzwinge privat
-config.max_creation_limit=Maximal erstellbare Anzahl
-config.preferred_licenses=Bevorzugte Lizenzen
-config.disable_http_git=Deaktiviere HTTP-Git
-config.enable_local_path_migration=Erlaube Migration von lokalem Pfad
-config.commits_fetch_concurrency=Anzahl gleichzeitiger Commit-/Fetch-Prozesse
-
-config.http_config=HTTP-Konfiguration
-config.http_access_control_allow_origin=Access Control Allow Origin
+config.repo.root_path=Root path
+config.repo.script_type=Script type
+config.repo.ansi_chatset=ANSI charset
+config.repo.force_private=Force private
+config.repo.max_creation_limit=Max creation limit
+config.repo.preferred_licenses=Preferred licenses
+config.repo.disable_http_git=Disable HTTP Git
+config.repo.enable_local_path_migration=Enable local path migration
+config.repo.enable_raw_file_render_mode=Enable raw file render mode
+config.repo.commits_fetch_concurrency=Commits fetch concurrency
+config.repo.editor.line_wrap_extensions=Editor line wrap extensions
+config.repo.editor.previewable_file_modes=Editor previewable file modes
+config.repo.upload.enabled=Upload enabled
+config.repo.upload.temp_path=Upload temporary path
+config.repo.upload.allowed_types=Upload allowed types
+config.repo.upload.file_max_size=Upload file size limit
+config.repo.upload.max_files=Upload files limit
 
 config.db_config=Datenbankkonfiguration
-config.db_type=Typ
-config.db_host=Host
-config.db_name=Name
-config.db_user=Benutzer
-config.db_ssl_mode=SSL-Modus
-config.db_ssl_mode_helper=(nur für "postgres")
-config.db_path=Verzeichnis
-config.db_path_helper=(für "sqlite3" und "tidb")
-
-config.service_config=Service-Konfiguration
-config.register_email_confirm=E-Mail-Bestätigung bei Registrierung
-config.disable_register=Registrierung deaktivieren
-config.show_registration_button=Schaltfläche Registrieren anzeigen
-config.require_sign_in_view=Ansehen erfordert Anmeldung
-config.mail_notify=E-Mail-Benachrichtigung
-config.disable_key_size_check=Prüfung der Mindestschlüssellänge deaktiveren
-config.enable_captcha=Captcha aktivieren
-config.active_code_lives=Aktivierungscode Lebensdauer
-config.reset_password_code_lives=Passwortcode Lebensdauer
+config.db.type=Type
+config.db.host=Host
+config.db.name=Name
+config.db.user=User
+config.db.ssl_mode=SSL mode
+config.db.ssl_mode_helper=(for "postgres" only)
+config.db.path=Path
+config.db.path_helper=(for "sqlite3"only)
+
+config.security_config=Security configuration
+config.security.login_remember_days=Login remember days
+config.security.cookie_remember_name=Remember cookie
+config.security.cookie_username=Username cookie
+config.security.cookie_secure=Enable secure cookie
+config.security.reverse_proxy_auth_user=Reverse proxy authentication header
+config.security.enable_login_status_cookie=Enable login status cookie
+config.security.login_status_cookie_name=Login status cookie
+
+config.email_config=Email configuration
+config.email.enabled=Enabled
+config.email.subject_prefix=Subject prefix
+config.email.host=Host
+config.email.from=From
+config.email.user=User
+config.email.disable_helo=Disable HELO
+config.email.helo_hostname=HELO hostname
+config.email.skip_verify=Skip certificate verify
+config.email.use_certificate=Use custom certificate
+config.email.cert_file=Certificate file
+config.email.key_file=Key file
+config.email.use_plain_text=Use plain text
+config.email.add_plain_text_alt=Add plain text alternative
+config.email.send_test_mail=Send test email
+config.email.test_mail_failed=Failed to send test email to '%s': %v
+config.email.test_mail_sent=Test email has been sent to '%s'.
+
+config.auth_config=Authentication configuration
+config.auth.activate_code_lives=Activate code lives
+config.auth.reset_password_code_lives=Reset password code lives
+config.auth.require_email_confirm=Require email confirmation
+config.auth.require_sign_in_view=Require sign in view
+config.auth.disable_registration=Disable registration
+config.auth.enable_registration_captcha=Enable registration captcha
+config.auth.enable_reverse_proxy_authentication=Enable reverse proxy authentication
+config.auth.enable_reverse_proxy_auto_registration=Enable reverse proxy auto registration
+config.auth.reverse_proxy_authentication_header=Reverse proxy authentication header
+
+config.user_config=User configuration
+config.user.enable_email_notify=Enable email notification
 
-config.webhook_config=Webhook-Konfiguration
-config.queue_length=Warteschlangenlänge
-config.deliver_timeout=Zeitlimit für Zustellung
-config.skip_tls_verify=TLS verifikation überspringen
-
-config.mailer_config=Mailer-Konfiguration
-config.mailer_enabled=Aktiviert
-config.mailer_disable_helo=HELO Deaktivieren
-config.mailer_subject_prefix=Betreff-Präfix
-config.mailer_host=Host
-config.mailer_user=Benutzer
-config.send_test_mail=Test-E-Mail senden
-config.test_mail_failed=Das Senden der Test-E-Mail an '%s': %v ist fehlgeschlagen
-config.test_mail_sent=Test-E-Mail wurde an '%s' gesendet.
-
-config.oauth_config=OAuth-Konfiguration
-config.oauth_enabled=Aktiviert
+config.session_config=Session-Konfiguration
+config.session.provider=Provider
+config.session.provider_config=Provider config
+config.session.cookie_name=Cookie
+config.session.https_only=HTTPS only
+config.session.gc_interval=GC interval
+config.session.max_life_time=Max life time
+config.session.csrf_cookie_name=CSRF cookie
 
 config.cache_config=Cache-Konfiguration
-config.cache_adapter=Cache-Adapter
-config.cache_interval=Cache-Intervall
-config.cache_conn=Cache-Anbindung
+config.cache.adapter=Adapter
+config.cache.interval=GC interval
+config.cache.host=Host
 
-config.session_config=Session-Konfiguration
-config.session_provider=Session-Provider
-config.provider_config=Provider-Einstellungen
-config.cookie_name=Cookie-Name
-config.enable_set_cookie=Cookies verwenden
-config.gc_interval_time=GC-Intervall
-config.session_life_time=Session-Lebensdauer
-config.https_only=Nur HTTPS
-config.cookie_life_time=Cookie-Lebensdauer
+config.http_config=HTTP-Konfiguration
+config.http.access_control_allow_origin=Access control allow origin
+
+config.attachment_config=Attachment configuration
+config.attachment.enabled=Enabled
+config.attachment.path=Path
+config.attachment.allowed_types=Allowed types
+config.attachment.max_size=Size limit
+config.attachment.max_files=Files limit
+
+config.release_config=Release configuration
+config.release.attachment.enabled=Attachment enabled
+config.release.attachment.allowed_types=Attachment allowed types
+config.release.attachment.max_size=Attachment size limit
+config.release.attachment.max_files=Attachment files limit
 
 config.picture_config=Konfiguration der Profilbilder
-config.picture_service=Bildservice
-config.disable_gravatar=Gravatar deaktivieren
-config.enable_federated_avatar=Föderierte Profilbilder einschalten
+config.picture.avatar_upload_path=User avatar upload path
+config.picture.repo_avatar_upload_path=Repository avatar upload path
+config.picture.gravatar_source=Gravatar source
+config.picture.disable_gravatar=Disable Gravatar
+config.picture.enable_federated_avatar=Enable federated avatars
+
+config.mirror_config=Mirror configuration
+config.mirror.default_interval=Default interval
+
+config.webhook_config=Webhook-Konfiguration
+config.webhook.types=Types
+config.webhook.deliver_timeout=Deliver timeout
+config.webhook.skip_tls_verify=Skip TLS verify
 
 config.git_config=Git Konfiguration
-config.git_disable_diff_highlight=Diff Syntaxhervorhebung ausschalten
-config.git_max_diff_lines=Max Diff Zeilen (in einer Datei)
-config.git_max_diff_line_characters=Max Diff Zeichen (in einer Zeile)
-config.git_max_diff_files=Max Diff Dateien (Anzeige)
-config.git_gc_args=GC-Argumente
-config.git_migrate_timeout=Zeitlimit für Migration
-config.git_mirror_timeout=Zeitlimit für Mirror-Aktualisierung
-config.git_clone_timeout=Zeitlimit für Clone
-config.git_pull_timeout=Zeitlimit für Pull
-config.git_gc_timeout=Zeitlimit für GC
+config.git.disable_diff_highlight=Disable diff syntax highlight
+config.git.max_diff_lines=Diff lines limit (for a single file)
+config.git.max_diff_line_characters=Diff characters limit (for a single line)
+config.git.max_diff_files=Diff files limit (for a single diff)
+config.git.gc_args=GC arguments
+config.git.migrate_timeout=Migration timeout
+config.git.mirror_timeout=Mirror fetch timeout
+config.git.clone_timeout=Clone timeout
+config.git.pull_timeout=Pull timeout
+config.git.gc_timeout=GC timeout
 
 config.log_config=Konfiguration des Loggings
+config.log_file_root_path=Log-Verzeichnis
 config.log_mode=Modus
 config.log_options=Optionen
 
@@ -1342,6 +1401,7 @@ months=%[2]s %[1]d Monaten
 years=%[2]s %[1]d Jahren
 raw_seconds=Sekunden
 raw_minutes=Minuten
+raw_hours=hours
 
 [dropzone]
 default_message=Zum Hochladen hier klicken oder Datei hier ablegen.

+ 154 - 94
conf/locale/locale_en-GB.ini

@@ -11,7 +11,6 @@ sign_out=Sign Out
 sign_up=Sign Up
 register=Register
 website=Website
-version=Version
 page=Page
 template=Template
 language=Language
@@ -124,6 +123,7 @@ run_user_not_match=Run user isn't the current user: %s -> %s
 smtp_host_missing_port=SMTP Host is missing port in address.
 invalid_smtp_from=SMTP From field is not valid: %v
 save_config_failed=Fail to save configuration: %v
+init_failed=Failed to initialize application: %v
 invalid_admin_setting=Admin account setting is invalid: %v
 install_success=Welcome! We're glad that you chose GIN, have fun and take care.
 invalid_log_root_path=Log root path is invalid: %v
@@ -1012,6 +1012,12 @@ first_page=First
 last_page=Last
 total=Total: %d
 
+dashboard.build_info=Build Information
+dashboard.app_ver=Application version
+dashboard.git_version=Git version
+dashboard.go_version=Go version
+dashboard.build_time=Build time
+dashboard.build_commit=Build commit
 dashboard.statistic=Statistics
 dashboard.operations=Operations
 dashboard.system_status=System Monitor Status
@@ -1167,117 +1173,170 @@ auths.github_api_endpoint=API Endpoint
 
 config.not_set=(not set)
 config.server_config=Server Configuration
-config.app_name=Application Name
-config.app_ver=Application Version
-config.app_url=Application URL
-config.domain=Domain
-config.offline_mode=Offline Mode
-config.disable_router_log=Disable Router Log
+config.brand_name=Brand name
 config.run_user=Run User
 config.run_mode=Run Mode
-config.git_version=Git Version
-config.static_file_root_path=Static File Root Path
-config.log_file_root_path=Log File Root Path
-config.reverse_auth_user=Reverse Authentication User
+config.server.external_url=External URL
+config.server.domain=Domain
+config.server.protocol=Protocol
+config.server.http_addr=HTTP address
+config.server.http_port=HTTP port
+config.server.cert_file=Certificate file
+config.server.key_file=Key file
+config.server.tls_min_version=Minimum TLS version
+config.server.unix_socket_permission=Unix socket permission
+config.server.local_root_url=Local root URL
+config.server.offline_mode=Offline mode
+config.server.disable_router_log=Disable router log
+config.server.enable_gzip=Enable Gzip
+config.server.app_data_path=Application data path
+config.server.load_assets_from_disk=Load assets from disk
+config.server.landing_url=Landing URL
 
 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_rewrite_authorized_keys_at_start=Rewrite authorized_keys At Start
-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.ssh.enabled=Enabled
+config.ssh.domain=Exposed domain
+config.ssh.port=Exposed port
+config.ssh.root_path=Root path
+config.ssh.keygen_path=Keygen path
+config.ssh.key_test_path=Key test path
+config.ssh.minimum_key_size_check=Minimum key size check
+config.ssh.minimum_key_sizes=Minimum key sizes
+config.ssh.rewrite_authorized_keys_at_start=Rewrite "authorized_keys" at start
+config.ssh.start_builtin_server=Start builtin server
+config.ssh.listen_host=Listen host
+config.ssh.listen_port=Listen port
+config.ssh.server_ciphers=Server ciphers
 
 config.repo_config=Repository Configuration
-config.repo_root_path=Repository Root Path
-config.script_type=Script Type
-config.repo_force_private=Force Private
-config.max_creation_limit=Max Creation Limit
-config.preferred_licenses=Preferred Licences
-config.disable_http_git=Disable HTTP Git
-config.enable_local_path_migration=Enable Local Path Migration
-config.commits_fetch_concurrency=Commits Fetch Concurrency
-
-config.http_config=HTTP Configuration
-config.http_access_control_allow_origin=Access Control Allow Origin
+config.repo.root_path=Root path
+config.repo.script_type=Script type
+config.repo.ansi_chatset=ANSI charset
+config.repo.force_private=Force private
+config.repo.max_creation_limit=Max creation limit
+config.repo.preferred_licenses=Preferred licenses
+config.repo.disable_http_git=Disable HTTP Git
+config.repo.enable_local_path_migration=Enable local path migration
+config.repo.enable_raw_file_render_mode=Enable raw file render mode
+config.repo.commits_fetch_concurrency=Commits fetch concurrency
+config.repo.editor.line_wrap_extensions=Editor line wrap extensions
+config.repo.editor.previewable_file_modes=Editor previewable file modes
+config.repo.upload.enabled=Upload enabled
+config.repo.upload.temp_path=Upload temporary path
+config.repo.upload.allowed_types=Upload allowed types
+config.repo.upload.file_max_size=Upload file size limit
+config.repo.upload.max_files=Upload files limit
 
 config.db_config=Database Configuration
-config.db_type=Type
-config.db_host=Host
-config.db_name=Name
-config.db_user=User
-config.db_ssl_mode=SSL Mode
-config.db_ssl_mode_helper=(for "postgres" only)
-config.db_path=Path
-config.db_path_helper=(for "sqlite3" and "tidb")
-
-config.service_config=Service Configuration
-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.mail_notify=Mail Notification
-config.disable_key_size_check=Disable Minimum Key Size Check
-config.enable_captcha=Enable Captcha
-config.active_code_lives=Active Code Lives
-config.reset_password_code_lives=Reset Password Code Lives
+config.db.type=Type
+config.db.host=Host
+config.db.name=Name
+config.db.user=User
+config.db.ssl_mode=SSL mode
+config.db.ssl_mode_helper=(for "postgres" only)
+config.db.path=Path
+config.db.path_helper=(for "sqlite3"only)
+
+config.security_config=Security configuration
+config.security.login_remember_days=Login remember days
+config.security.cookie_remember_name=Remember cookie
+config.security.cookie_username=Username cookie
+config.security.cookie_secure=Enable secure cookie
+config.security.reverse_proxy_auth_user=Reverse proxy authentication header
+config.security.enable_login_status_cookie=Enable login status cookie
+config.security.login_status_cookie_name=Login status cookie
+
+config.email_config=Email configuration
+config.email.enabled=Enabled
+config.email.subject_prefix=Subject prefix
+config.email.host=Host
+config.email.from=From
+config.email.user=User
+config.email.disable_helo=Disable HELO
+config.email.helo_hostname=HELO hostname
+config.email.skip_verify=Skip certificate verify
+config.email.use_certificate=Use custom certificate
+config.email.cert_file=Certificate file
+config.email.key_file=Key file
+config.email.use_plain_text=Use plain text
+config.email.add_plain_text_alt=Add plain text alternative
+config.email.send_test_mail=Send test email
+config.email.test_mail_failed=Failed to send test email to '%s': %v
+config.email.test_mail_sent=Test email has been sent to '%s'.
+
+config.auth_config=Authentication configuration
+config.auth.activate_code_lives=Activate code lives
+config.auth.reset_password_code_lives=Reset password code lives
+config.auth.require_email_confirm=Require email confirmation
+config.auth.require_sign_in_view=Require sign in view
+config.auth.disable_registration=Disable registration
+config.auth.enable_registration_captcha=Enable registration captcha
+config.auth.enable_reverse_proxy_authentication=Enable reverse proxy authentication
+config.auth.enable_reverse_proxy_auto_registration=Enable reverse proxy auto registration
+config.auth.reverse_proxy_authentication_header=Reverse proxy authentication header
+
+config.user_config=User configuration
+config.user.enable_email_notify=Enable email notification
 
-config.webhook_config=Webhook Configuration
-config.queue_length=Queue Length
-config.deliver_timeout=Deliver Timeout
-config.skip_tls_verify=Skip TLS Verify
-
-config.mailer_config=Mailer Configuration
-config.mailer_enabled=Enabled
-config.mailer_disable_helo=Disable HELO
-config.mailer_subject_prefix=Subject Prefix
-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.session_config=Session Configuration
+config.session.provider=Provider
+config.session.provider_config=Provider config
+config.session.cookie_name=Cookie
+config.session.https_only=HTTPS only
+config.session.gc_interval=GC interval
+config.session.max_life_time=Max life time
+config.session.csrf_cookie_name=CSRF cookie
 
 config.cache_config=Cache Configuration
-config.cache_adapter=Cache Adapter
-config.cache_interval=Cache Interval
-config.cache_conn=Cache Connection
+config.cache.adapter=Adapter
+config.cache.interval=GC interval
+config.cache.host=Host
 
-config.session_config=Session Configuration
-config.session_provider=Session Provider
-config.provider_config=Provider Config
-config.cookie_name=Cookie Name
-config.enable_set_cookie=Enable Set Cookie
-config.gc_interval_time=GC Interval Time
-config.session_life_time=Session Life Time
-config.https_only=HTTPS Only
-config.cookie_life_time=Cookie Life Time
+config.http_config=HTTP Configuration
+config.http.access_control_allow_origin=Access control allow origin
+
+config.attachment_config=Attachment configuration
+config.attachment.enabled=Enabled
+config.attachment.path=Path
+config.attachment.allowed_types=Allowed types
+config.attachment.max_size=Size limit
+config.attachment.max_files=Files limit
+
+config.release_config=Release configuration
+config.release.attachment.enabled=Attachment enabled
+config.release.attachment.allowed_types=Attachment allowed types
+config.release.attachment.max_size=Attachment size limit
+config.release.attachment.max_files=Attachment files limit
 
 config.picture_config=Picture Configuration
-config.picture_service=Picture Service
-config.disable_gravatar=Disable Gravatar
-config.enable_federated_avatar=Enable Federated Avatars
+config.picture.avatar_upload_path=User avatar upload path
+config.picture.repo_avatar_upload_path=Repository avatar upload path
+config.picture.gravatar_source=Gravatar source
+config.picture.disable_gravatar=Disable Gravatar
+config.picture.enable_federated_avatar=Enable federated avatars
+
+config.mirror_config=Mirror configuration
+config.mirror.default_interval=Default interval
+
+config.webhook_config=Webhook Configuration
+config.webhook.types=Types
+config.webhook.deliver_timeout=Deliver timeout
+config.webhook.skip_tls_verify=Skip TLS verify
 
 config.git_config=Git Configuration
-config.git_disable_diff_highlight=Disable Diff Syntax Highlight
-config.git_max_diff_lines=Max Diff Lines (for a single file)
-config.git_max_diff_line_characters=Max Diff Characters (for a single line)
-config.git_max_diff_files=Max Diff Files (to be shown)
-config.git_gc_args=GC Arguments
-config.git_migrate_timeout=Migration Timeout
-config.git_mirror_timeout=Mirror Update Timeout
-config.git_clone_timeout=Clone Operation Timeout
-config.git_pull_timeout=Pull Operation Timeout
-config.git_gc_timeout=GC Operation Timeout
+config.git.disable_diff_highlight=Disable diff syntax highlight
+config.git.max_diff_lines=Diff lines limit (for a single file)
+config.git.max_diff_line_characters=Diff characters limit (for a single line)
+config.git.max_diff_files=Diff files limit (for a single diff)
+config.git.gc_args=GC arguments
+config.git.migrate_timeout=Migration timeout
+config.git.mirror_timeout=Mirror fetch timeout
+config.git.clone_timeout=Clone timeout
+config.git.pull_timeout=Pull timeout
+config.git.gc_timeout=GC timeout
 
 config.log_config=Log Configuration
+config.log_file_root_path=Log File Root Path
 config.log_mode=Mode
 config.log_options=Options
 
@@ -1350,6 +1409,7 @@ months=%d months %s
 years=%d years %s
 raw_seconds=seconds
 raw_minutes=minutes
+raw_hours=hours
 
 [dropzone]
 default_message=Drop files here or click to upload.

+ 43 - 28
conf/locale/locale_en-US.ini

@@ -1301,34 +1301,48 @@ config.cache.host = Host
 config.http_config = HTTP configuration
 config.http.access_control_allow_origin = Access control allow origin
 
-config.log_file_root_path = Log File Root Path
-
-config.webhook_config = Webhook Configuration
-config.queue_length = Queue Length
-config.deliver_timeout = Deliver Timeout
-config.skip_tls_verify = Skip TLS Verify
-
-config.oauth_config = OAuth Configuration
-config.oauth_enabled = Enabled
-
-config.picture_config = Picture Configuration
-config.picture_service = Picture Service
-config.disable_gravatar = Disable Gravatar
-config.enable_federated_avatar = Enable Federated Avatars
-
-config.git_config = Git Configuration
-config.git_disable_diff_highlight = Disable Diff Syntax Highlight
-config.git_max_diff_lines = Max Diff Lines (for a single file)
-config.git_max_diff_line_characters = Max Diff Characters (for a single line)
-config.git_max_diff_files = Max Diff Files (to be shown)
-config.git_gc_args = GC Arguments
-config.git_migrate_timeout = Migration Timeout
-config.git_mirror_timeout = Mirror Update Timeout
-config.git_clone_timeout = Clone Operation Timeout
-config.git_pull_timeout = Pull Operation Timeout
-config.git_gc_timeout = GC Operation Timeout
-
-config.log_config = Log Configuration
+config.attachment_config = Attachment configuration
+config.attachment.enabled = Enabled
+config.attachment.path = Path
+config.attachment.allowed_types = Allowed types
+config.attachment.max_size = Size limit
+config.attachment.max_files = Files limit
+
+config.release_config = Release configuration
+config.release.attachment.enabled = Attachment enabled
+config.release.attachment.allowed_types = Attachment allowed types
+config.release.attachment.max_size = Attachment size limit
+config.release.attachment.max_files = Attachment files limit
+
+config.picture_config = Picture configuration
+config.picture.avatar_upload_path = User avatar upload path
+config.picture.repo_avatar_upload_path = Repository avatar upload path
+config.picture.gravatar_source = Gravatar source
+config.picture.disable_gravatar = Disable Gravatar
+config.picture.enable_federated_avatar = Enable federated avatars
+
+config.mirror_config = Mirror configuration
+config.mirror.default_interval = Default interval
+
+config.webhook_config = Webhook configuration
+config.webhook.types = Types
+config.webhook.deliver_timeout = Deliver timeout
+config.webhook.skip_tls_verify = Skip TLS verify
+
+config.git_config = Git configuration
+config.git.disable_diff_highlight = Disable diff syntax highlight
+config.git.max_diff_lines = Diff lines limit (for a single file)
+config.git.max_diff_line_characters = Diff characters limit (for a single line)
+config.git.max_diff_files = Diff files limit (for a single diff)
+config.git.gc_args = GC arguments
+config.git.migrate_timeout = Migration timeout
+config.git.mirror_timeout = Mirror fetch timeout
+config.git.clone_timeout = Clone timeout
+config.git.pull_timeout = Pull timeout
+config.git.gc_timeout = GC timeout
+
+config.log_config = Log configuration
+config.log_file_root_path = Log file root path
 config.log_mode = Mode
 config.log_options = Options
 
@@ -1400,6 +1414,7 @@ months = %d months %s
 years = %d years %s
 raw_seconds = seconds
 raw_minutes = minutes
+raw_hours = hours
 
 [dropzone]
 default_message = Drop files here or click to upload.

+ 154 - 94
conf/locale/locale_es-ES.ini

@@ -9,7 +9,6 @@ sign_out=Cerrar sesión
 sign_up=Registro
 register=Registro
 website=Página web
-version=Versión
 page=Página
 template=Plantilla
 language=Idioma
@@ -122,6 +121,7 @@ run_user_not_match=El usuario que está ejecutando la aplicación no es el usuar
 smtp_host_missing_port=No se ha definido el puerto para el host SMTP.
 invalid_smtp_from=El campo SMTP no es válido: %v
 save_config_failed=Error al guardar la configuración: %v
+init_failed=Failed to initialize application: %v
 invalid_admin_setting=La configuración de la cuenta de administración es inválida: %v
 install_success=Bienvenido! Estamos encantados de que hayas escogido GIN, diviértete y cuídate.
 invalid_log_root_path=La ruta para los registros es inválida: %v
@@ -1001,6 +1001,12 @@ first_page=Primera
 last_page=Última
 total=Total: %d
 
+dashboard.build_info=Build Information
+dashboard.app_ver=Application version
+dashboard.git_version=Git version
+dashboard.go_version=Go version
+dashboard.build_time=Build time
+dashboard.build_commit=Build commit
 dashboard.statistic=Estadísticas
 dashboard.operations=Operaciones
 dashboard.system_status=Estado del Monitor del Sistema
@@ -1156,117 +1162,170 @@ auths.github_api_endpoint=API Endpoint
 
 config.not_set=(sin definir)
 config.server_config=Configuración del servidor
-config.app_name=Nombre de la Aplicación
-config.app_ver=Versión de la Aplicación
-config.app_url=URL de la Aplicación
-config.domain=Dominio
-config.offline_mode=Modo Sin Conexión
-config.disable_router_log=Deshabilitar Log del Router
+config.brand_name=Brand name
 config.run_user=Ejecutada como Usuario
 config.run_mode=Modo de ejecución
-config.git_version=Versión de Git
-config.static_file_root_path=Ruta de los Ficheros Estáticos
-config.log_file_root_path=Ruta de los Ficheros de Log
-config.reverse_auth_user=Autenticación Inversa de Usuario
+config.server.external_url=External URL
+config.server.domain=Domain
+config.server.protocol=Protocol
+config.server.http_addr=HTTP address
+config.server.http_port=HTTP port
+config.server.cert_file=Certificate file
+config.server.key_file=Key file
+config.server.tls_min_version=Minimum TLS version
+config.server.unix_socket_permission=Unix socket permission
+config.server.local_root_url=Local root URL
+config.server.offline_mode=Offline mode
+config.server.disable_router_log=Disable router log
+config.server.enable_gzip=Enable Gzip
+config.server.app_data_path=Application data path
+config.server.load_assets_from_disk=Load assets from disk
+config.server.landing_url=Landing URL
 
 config.ssh_config=Configuración SSH
-config.ssh_enabled=Habilitado
-config.ssh_start_builtin_server=Iniciar servidor integrado
-config.ssh_domain=Dominio
-config.ssh_port=Puerto
-config.ssh_listen_port=Puerto de escucha
-config.ssh_root_path=Ruta raíz
-config.ssh_rewrite_authorized_keys_at_start=Reescribir authorized_keys en el arranque
-config.ssh_key_test_path=Ruta de la clave de prueba
-config.ssh_keygen_path=Ruta del generador de claves ('ssh-keygen')
-config.ssh_minimum_key_size_check=Tamaño mínimo de la clave de verificación
-config.ssh_minimum_key_sizes=Tamaños de clave mínimos
+config.ssh.enabled=Enabled
+config.ssh.domain=Exposed domain
+config.ssh.port=Exposed port
+config.ssh.root_path=Root path
+config.ssh.keygen_path=Keygen path
+config.ssh.key_test_path=Key test path
+config.ssh.minimum_key_size_check=Minimum key size check
+config.ssh.minimum_key_sizes=Minimum key sizes
+config.ssh.rewrite_authorized_keys_at_start=Rewrite "authorized_keys" at start
+config.ssh.start_builtin_server=Start builtin server
+config.ssh.listen_host=Listen host
+config.ssh.listen_port=Listen port
+config.ssh.server_ciphers=Server ciphers
 
 config.repo_config=Configuración del repositorio
-config.repo_root_path=Ruta del Repositorio
-config.script_type=Tipo de Script
-config.repo_force_private=Forzar Privado
-config.max_creation_limit=Limite máximo de creación
-config.preferred_licenses=Licencias Preferidas
-config.disable_http_git=Desactivar HTTP Git
-config.enable_local_path_migration=Activar la migración de la ruta de acceso Local
-config.commits_fetch_concurrency=Concurrencia de la búsqueda de commits
-
-config.http_config=Configuración HTTP
-config.http_access_control_allow_origin=Access Control Allow Origin
+config.repo.root_path=Root path
+config.repo.script_type=Script type
+config.repo.ansi_chatset=ANSI charset
+config.repo.force_private=Force private
+config.repo.max_creation_limit=Max creation limit
+config.repo.preferred_licenses=Preferred licenses
+config.repo.disable_http_git=Disable HTTP Git
+config.repo.enable_local_path_migration=Enable local path migration
+config.repo.enable_raw_file_render_mode=Enable raw file render mode
+config.repo.commits_fetch_concurrency=Commits fetch concurrency
+config.repo.editor.line_wrap_extensions=Editor line wrap extensions
+config.repo.editor.previewable_file_modes=Editor previewable file modes
+config.repo.upload.enabled=Upload enabled
+config.repo.upload.temp_path=Upload temporary path
+config.repo.upload.allowed_types=Upload allowed types
+config.repo.upload.file_max_size=Upload file size limit
+config.repo.upload.max_files=Upload files limit
 
 config.db_config=Configuración de la Base de Datos
-config.db_type=Tipo
-config.db_host=Host
-config.db_name=Nombre
-config.db_user=Usuario
-config.db_ssl_mode=Modo SSL
-config.db_ssl_mode_helper=(sólo para "postgres")
-config.db_path=Ruta
-config.db_path_helper=(para "sqlite3" y "tidb")
-
-config.service_config=Configuración del servicio
-config.register_email_confirm=Solicitar Confirmación por Correo Electrónico
-config.disable_register=Deshabilitar el Registro
-config.show_registration_button=Mostrar Botón de Registro
-config.require_sign_in_view=Solicitar la Vista de Inicio de Sesión
-config.mail_notify=Notificación por Correo Electrónico
-config.disable_key_size_check=Deshabilitar la comprobación de Tamaño Mínimo de Clave
-config.enable_captcha=Activar Captcha
-config.active_code_lives=Habilitar Vida del Código
-config.reset_password_code_lives=Restablecer Contraseña de Vida del Código
+config.db.type=Type
+config.db.host=Host
+config.db.name=Name
+config.db.user=User
+config.db.ssl_mode=SSL mode
+config.db.ssl_mode_helper=(for "postgres" only)
+config.db.path=Path
+config.db.path_helper=(for "sqlite3"only)
+
+config.security_config=Security configuration
+config.security.login_remember_days=Login remember days
+config.security.cookie_remember_name=Remember cookie
+config.security.cookie_username=Username cookie
+config.security.cookie_secure=Enable secure cookie
+config.security.reverse_proxy_auth_user=Reverse proxy authentication header
+config.security.enable_login_status_cookie=Enable login status cookie
+config.security.login_status_cookie_name=Login status cookie
+
+config.email_config=Email configuration
+config.email.enabled=Enabled
+config.email.subject_prefix=Subject prefix
+config.email.host=Host
+config.email.from=From
+config.email.user=User
+config.email.disable_helo=Disable HELO
+config.email.helo_hostname=HELO hostname
+config.email.skip_verify=Skip certificate verify
+config.email.use_certificate=Use custom certificate
+config.email.cert_file=Certificate file
+config.email.key_file=Key file
+config.email.use_plain_text=Use plain text
+config.email.add_plain_text_alt=Add plain text alternative
+config.email.send_test_mail=Send test email
+config.email.test_mail_failed=Failed to send test email to '%s': %v
+config.email.test_mail_sent=Test email has been sent to '%s'.
+
+config.auth_config=Authentication configuration
+config.auth.activate_code_lives=Activate code lives
+config.auth.reset_password_code_lives=Reset password code lives
+config.auth.require_email_confirm=Require email confirmation
+config.auth.require_sign_in_view=Require sign in view
+config.auth.disable_registration=Disable registration
+config.auth.enable_registration_captcha=Enable registration captcha
+config.auth.enable_reverse_proxy_authentication=Enable reverse proxy authentication
+config.auth.enable_reverse_proxy_auto_registration=Enable reverse proxy auto registration
+config.auth.reverse_proxy_authentication_header=Reverse proxy authentication header
+
+config.user_config=User configuration
+config.user.enable_email_notify=Enable email notification
 
-config.webhook_config=Configuración de Webhooks
-config.queue_length=Tamaño de Cola de Envío
-config.deliver_timeout=Timeout de Entrega
-config.skip_tls_verify=Omitir la Verificación TLS
-
-config.mailer_config=Configuración del servidor de correo
-config.mailer_enabled=Activado
-config.mailer_disable_helo=Desactivar HELO
-config.mailer_subject_prefix=Prefijo del asunto
-config.mailer_host=Host
-config.mailer_user=Usuario
-config.send_test_mail=Enviar email de prueba
-config.test_mail_failed=Fallo al enviar el email de prueba a '%s': %v
-config.test_mail_sent=El email de prueba ha sido enviado a '%s'.
-
-config.oauth_config=Configuración OAuth
-config.oauth_enabled=Activado
+config.session_config=Configuración de la Sesión
+config.session.provider=Provider
+config.session.provider_config=Provider config
+config.session.cookie_name=Cookie
+config.session.https_only=HTTPS only
+config.session.gc_interval=GC interval
+config.session.max_life_time=Max life time
+config.session.csrf_cookie_name=CSRF cookie
 
 config.cache_config=Configuración de la Caché
-config.cache_adapter=Adaptador de la Caché
-config.cache_interval=Intervalo de la Caché
-config.cache_conn=Conexión de la Caché
+config.cache.adapter=Adapter
+config.cache.interval=GC interval
+config.cache.host=Host
 
-config.session_config=Configuración de la Sesión
-config.session_provider=Proveedor de la Sesión
-config.provider_config=Configuración del Proveedor
-config.cookie_name=Nombre de la Cookie
-config.enable_set_cookie=Activar Establecimiento de Cookie
-config.gc_interval_time=Intervalo de tiempo del GC
-config.session_life_time=Tiempo de Vida de la Sesión
-config.https_only=Sólo HTTPS
-config.cookie_life_time=Tiempo de Vida de la Cookie
+config.http_config=Configuración HTTP
+config.http.access_control_allow_origin=Access control allow origin
+
+config.attachment_config=Attachment configuration
+config.attachment.enabled=Enabled
+config.attachment.path=Path
+config.attachment.allowed_types=Allowed types
+config.attachment.max_size=Size limit
+config.attachment.max_files=Files limit
+
+config.release_config=Release configuration
+config.release.attachment.enabled=Attachment enabled
+config.release.attachment.allowed_types=Attachment allowed types
+config.release.attachment.max_size=Attachment size limit
+config.release.attachment.max_files=Attachment files limit
 
 config.picture_config=Configuración de Imagen
-config.picture_service=Servicio de Imágen
-config.disable_gravatar=Desactivar Gravatar
-config.enable_federated_avatar=Habilitar Avatares Federados
+config.picture.avatar_upload_path=User avatar upload path
+config.picture.repo_avatar_upload_path=Repository avatar upload path
+config.picture.gravatar_source=Gravatar source
+config.picture.disable_gravatar=Disable Gravatar
+config.picture.enable_federated_avatar=Enable federated avatars
+
+config.mirror_config=Mirror configuration
+config.mirror.default_interval=Default interval
+
+config.webhook_config=Configuración de Webhooks
+config.webhook.types=Types
+config.webhook.deliver_timeout=Deliver timeout
+config.webhook.skip_tls_verify=Skip TLS verify
 
 config.git_config=Configuración de Git
-config.git_disable_diff_highlight=Desactivar resaltado de sintaxis del Diff
-config.git_max_diff_lines=Líneas de Diff máximas (por un solo archivo)
-config.git_max_diff_line_characters=Carácteres de Diff máximos (para una sola línea)
-config.git_max_diff_files=Máximo de archivos de Diff (que se mostrarán)
-config.git_gc_args=Argumentos de GC
-config.git_migrate_timeout=Tiempo de espera de migración
-config.git_mirror_timeout=Tiempo de espera de actualización de réplicas
-config.git_clone_timeout=Tiempo de espera de operación de clones
-config.git_pull_timeout=Tiempo de espera de operación de pull
-config.git_gc_timeout=Tiempo de espera de operación de GC
+config.git.disable_diff_highlight=Disable diff syntax highlight
+config.git.max_diff_lines=Diff lines limit (for a single file)
+config.git.max_diff_line_characters=Diff characters limit (for a single line)
+config.git.max_diff_files=Diff files limit (for a single diff)
+config.git.gc_args=GC arguments
+config.git.migrate_timeout=Migration timeout
+config.git.mirror_timeout=Mirror fetch timeout
+config.git.clone_timeout=Clone timeout
+config.git.pull_timeout=Pull timeout
+config.git.gc_timeout=GC timeout
 
 config.log_config=Configuración del Log
+config.log_file_root_path=Ruta de los Ficheros de Log
 config.log_mode=Modo
 config.log_options=Opciones
 
@@ -1338,6 +1397,7 @@ months=%[2]s %[1]d meses
 years=%[2]s %[1]d años
 raw_seconds=segundos
 raw_minutes=minutos
+raw_hours=hours
 
 [dropzone]
 default_message=Suéltelos aquí o pulse para cargar archivos.

+ 154 - 94
conf/locale/locale_fa-IR.ini

@@ -9,7 +9,6 @@ sign_out=خروج
 sign_up=ثبت‌نام کنید
 register=ثبت نام
 website=وب‌سایت
-version=نسخه
 page=صفحه
 template=قالب
 language=زبان
@@ -122,6 +121,7 @@ run_user_not_match=کاربری را اجرا کنید که کاربر فعلی
 smtp_host_missing_port=شماره پورت در آدرس میزبان SMTP وارد نشده است.
 invalid_smtp_from=مقدار وارد شده در فرم SMTP معتبر نیست: %v
 save_config_failed=تنظیمات ذخیره نشد: %v
+init_failed=Failed to initialize application: %v
 invalid_admin_setting=تنظیمات حساب مدیر نامعتبر است: %v
 install_success=خوش آمدی! ما خوشحالیم که شما Gogs را انتخاب کردید. لذت ببرید و مراقب خودتون باشید.
 invalid_log_root_path=آدرس روت فایل لاگ صحیح نیست: %v
@@ -1003,6 +1003,12 @@ first_page=اولین
 last_page=آخرين
 total=مجموع: %d
 
+dashboard.build_info=Build Information
+dashboard.app_ver=Application version
+dashboard.git_version=Git version
+dashboard.go_version=Go version
+dashboard.build_time=Build time
+dashboard.build_commit=Build commit
 dashboard.statistic=آمار
 dashboard.operations=عملیات
 dashboard.system_status=سیستم مانیتور وضعیت
@@ -1158,117 +1164,170 @@ auths.github_api_endpoint=API Endpoint
 
 config.not_set=(تنظیم نشده)
 config.server_config=پیکربندی سرور
-config.app_name=نام برنامه
-config.app_ver=نسخه برنامه
-config.app_url=آدرس اینترنتی (URL) نرم‌افزار
-config.domain=دامنه
-config.offline_mode=حالت آفلاین
-config.disable_router_log=غیرفعال کردن لاگ مسیریاب
+config.brand_name=Brand name
 config.run_user=کاربر در حال اجرا
 config.run_mode=حالت اجرا
-config.git_version=نسخه‌ی Git
-config.static_file_root_path=مسیر ریشه فایل استاتیک
-config.log_file_root_path=مسیر ریشه ی فایل لاگ
-config.reverse_auth_user=شیوه ی احرازهویت معکوس
+config.server.external_url=External URL
+config.server.domain=Domain
+config.server.protocol=Protocol
+config.server.http_addr=HTTP address
+config.server.http_port=HTTP port
+config.server.cert_file=Certificate file
+config.server.key_file=Key file
+config.server.tls_min_version=Minimum TLS version
+config.server.unix_socket_permission=Unix socket permission
+config.server.local_root_url=Local root URL
+config.server.offline_mode=Offline mode
+config.server.disable_router_log=Disable router log
+config.server.enable_gzip=Enable Gzip
+config.server.app_data_path=Application data path
+config.server.load_assets_from_disk=Load assets from disk
+config.server.landing_url=Landing URL
 
 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_rewrite_authorized_keys_at_start=Rewrite authorized_keys At Start
-config.ssh_key_test_path=مسیر کلید تست
-config.ssh_keygen_path=مسیر فایل ssh-keygen
-config.ssh_minimum_key_size_check=بررسی حداقل طول کلید
-config.ssh_minimum_key_sizes=حداقل اندازه‌ی کلید ها
+config.ssh.enabled=Enabled
+config.ssh.domain=Exposed domain
+config.ssh.port=Exposed port
+config.ssh.root_path=Root path
+config.ssh.keygen_path=Keygen path
+config.ssh.key_test_path=Key test path
+config.ssh.minimum_key_size_check=Minimum key size check
+config.ssh.minimum_key_sizes=Minimum key sizes
+config.ssh.rewrite_authorized_keys_at_start=Rewrite "authorized_keys" at start
+config.ssh.start_builtin_server=Start builtin server
+config.ssh.listen_host=Listen host
+config.ssh.listen_port=Listen port
+config.ssh.server_ciphers=Server ciphers
 
 config.repo_config=پیکربندی مخزن
-config.repo_root_path=مسیر پوشه اصلی (روت) برای مخزن کد
-config.script_type=نوع اسکریپت
-config.repo_force_private=خصوصی سازی اجباری
-config.max_creation_limit=محدودیت حداکثر ایجاد
-config.preferred_licenses=مجوزهای پیشنهادی
-config.disable_http_git=غیرفعال کردنHTTP در Git
-config.enable_local_path_migration=فعال سازی مسیر انتقال محلی
-config.commits_fetch_concurrency=همروندی در واکشی کامیت
-
-config.http_config=تنظیمات HTTP
-config.http_access_control_allow_origin=Access Control Allow Origin
+config.repo.root_path=Root path
+config.repo.script_type=Script type
+config.repo.ansi_chatset=ANSI charset
+config.repo.force_private=Force private
+config.repo.max_creation_limit=Max creation limit
+config.repo.preferred_licenses=Preferred licenses
+config.repo.disable_http_git=Disable HTTP Git
+config.repo.enable_local_path_migration=Enable local path migration
+config.repo.enable_raw_file_render_mode=Enable raw file render mode
+config.repo.commits_fetch_concurrency=Commits fetch concurrency
+config.repo.editor.line_wrap_extensions=Editor line wrap extensions
+config.repo.editor.previewable_file_modes=Editor previewable file modes
+config.repo.upload.enabled=Upload enabled
+config.repo.upload.temp_path=Upload temporary path
+config.repo.upload.allowed_types=Upload allowed types
+config.repo.upload.file_max_size=Upload file size limit
+config.repo.upload.max_files=Upload files limit
 
 config.db_config=تنظیمات پایگاه داده
-config.db_type=نوع
-config.db_host=میزبان
-config.db_name=نام
-config.db_user=کاربر
-config.db_ssl_mode=حالت SSL
-config.db_ssl_mode_helper=(تنها برای "postgres")
-config.db_path=مسیر
-config.db_path_helper=(فقط برای "sqlite3" و "tidb")
-
-config.service_config=پیکربندی سرویس
-config.register_email_confirm=درخواست تایید ایمیل
-config.disable_register=غیر فعال‌کردن ثبت نام
-config.show_registration_button=نشان دادن دکمه ثبت نام
-config.require_sign_in_view=اجبار کردن نمای ورود
-config.mail_notify=فعال‌سازی نوتیفکیشن ایمیل
-config.disable_key_size_check=غیر فعال کردن چک حداقل اندازه کلید
-config.enable_captcha=فعال‌کردن تصویر امنیتی
-config.active_code_lives=مدت زمان اعتبار کد
-config.reset_password_code_lives=مدت زمان اعتبار کد بازنشانی پسورد
+config.db.type=Type
+config.db.host=Host
+config.db.name=Name
+config.db.user=User
+config.db.ssl_mode=SSL mode
+config.db.ssl_mode_helper=(for "postgres" only)
+config.db.path=Path
+config.db.path_helper=(for "sqlite3"only)
+
+config.security_config=Security configuration
+config.security.login_remember_days=Login remember days
+config.security.cookie_remember_name=Remember cookie
+config.security.cookie_username=Username cookie
+config.security.cookie_secure=Enable secure cookie
+config.security.reverse_proxy_auth_user=Reverse proxy authentication header
+config.security.enable_login_status_cookie=Enable login status cookie
+config.security.login_status_cookie_name=Login status cookie
+
+config.email_config=Email configuration
+config.email.enabled=Enabled
+config.email.subject_prefix=Subject prefix
+config.email.host=Host
+config.email.from=From
+config.email.user=User
+config.email.disable_helo=Disable HELO
+config.email.helo_hostname=HELO hostname
+config.email.skip_verify=Skip certificate verify
+config.email.use_certificate=Use custom certificate
+config.email.cert_file=Certificate file
+config.email.key_file=Key file
+config.email.use_plain_text=Use plain text
+config.email.add_plain_text_alt=Add plain text alternative
+config.email.send_test_mail=Send test email
+config.email.test_mail_failed=Failed to send test email to '%s': %v
+config.email.test_mail_sent=Test email has been sent to '%s'.
+
+config.auth_config=Authentication configuration
+config.auth.activate_code_lives=Activate code lives
+config.auth.reset_password_code_lives=Reset password code lives
+config.auth.require_email_confirm=Require email confirmation
+config.auth.require_sign_in_view=Require sign in view
+config.auth.disable_registration=Disable registration
+config.auth.enable_registration_captcha=Enable registration captcha
+config.auth.enable_reverse_proxy_authentication=Enable reverse proxy authentication
+config.auth.enable_reverse_proxy_auto_registration=Enable reverse proxy auto registration
+config.auth.reverse_proxy_authentication_header=Reverse proxy authentication header
+
+config.user_config=User configuration
+config.user.enable_email_notify=Enable email notification
 
-config.webhook_config=تنظیمات Webhook
-config.queue_length=طول صف
-config.deliver_timeout=مهلت تحویل
-config.skip_tls_verify=صرف نظر از اعتبار سنجی TLS
-
-config.mailer_config=پیکربندی سیستم ایمیلی
-config.mailer_enabled=فعال شده
-config.mailer_disable_helo=غیر فعال کردن HELO
-config.mailer_subject_prefix=پيشوند موضوع
-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.session_config=پیکربندی Session ها
+config.session.provider=Provider
+config.session.provider_config=Provider config
+config.session.cookie_name=Cookie
+config.session.https_only=HTTPS only
+config.session.gc_interval=GC interval
+config.session.max_life_time=Max life time
+config.session.csrf_cookie_name=CSRF cookie
 
 config.cache_config=پیکربندی cache
-config.cache_adapter=آداپتور cache
-config.cache_interval=وقفه cache
-config.cache_conn=اتصال cache
+config.cache.adapter=Adapter
+config.cache.interval=GC interval
+config.cache.host=Host
 
-config.session_config=پیکربندی Session ها
-config.session_provider=منبع فراهم ساز Session
-config.provider_config=پیکربندی سرویس دهنده
-config.cookie_name=نام کوکی
-config.enable_set_cookie=فعال سازی تنظیم کردن کوکی
-config.gc_interval_time=فاصله زمانی GC
-config.session_life_time=طول عمر نشست
-config.https_only=فقط HTTPS
-config.cookie_life_time=طول عمر کوکی
+config.http_config=تنظیمات HTTP
+config.http.access_control_allow_origin=Access control allow origin
+
+config.attachment_config=Attachment configuration
+config.attachment.enabled=Enabled
+config.attachment.path=Path
+config.attachment.allowed_types=Allowed types
+config.attachment.max_size=Size limit
+config.attachment.max_files=Files limit
+
+config.release_config=Release configuration
+config.release.attachment.enabled=Attachment enabled
+config.release.attachment.allowed_types=Attachment allowed types
+config.release.attachment.max_size=Attachment size limit
+config.release.attachment.max_files=Attachment files limit
 
 config.picture_config=تنظیمات تصویر
-config.picture_service=سرویس تصویر
-config.disable_gravatar=غیر فعال کردن Gravatar
-config.enable_federated_avatar=فعال سازی آواتار مشترک
+config.picture.avatar_upload_path=User avatar upload path
+config.picture.repo_avatar_upload_path=Repository avatar upload path
+config.picture.gravatar_source=Gravatar source
+config.picture.disable_gravatar=Disable Gravatar
+config.picture.enable_federated_avatar=Enable federated avatars
+
+config.mirror_config=Mirror configuration
+config.mirror.default_interval=Default interval
+
+config.webhook_config=تنظیمات Webhook
+config.webhook.types=Types
+config.webhook.deliver_timeout=Deliver timeout
+config.webhook.skip_tls_verify=Skip TLS verify
 
 config.git_config=پیکربندی Git
-config.git_disable_diff_highlight=غیرفعال کردن برجسته سازی در Diff
-config.git_max_diff_lines=حداکثر خط برای Diff (برای یک فایل)
-config.git_max_diff_line_characters=حداکثر کاراکتر در Diff (برای یک خط)
-config.git_max_diff_files=حداکثر فایل های Diff (برای نمایش)
-config.git_gc_args=آرگومان های GC
-config.git_migrate_timeout=آستانه ی زمان در Migration
-config.git_mirror_timeout=زمان آستانه در به روز رسانی Mirror
-config.git_clone_timeout=زمان آستانه ی عملیات Clone
-config.git_pull_timeout=زمان آستانه ی عملیات Pull
-config.git_gc_timeout=زمان آستانه ی عملیات GC
+config.git.disable_diff_highlight=Disable diff syntax highlight
+config.git.max_diff_lines=Diff lines limit (for a single file)
+config.git.max_diff_line_characters=Diff characters limit (for a single line)
+config.git.max_diff_files=Diff files limit (for a single diff)
+config.git.gc_args=GC arguments
+config.git.migrate_timeout=Migration timeout
+config.git.mirror_timeout=Mirror fetch timeout
+config.git.clone_timeout=Clone timeout
+config.git.pull_timeout=Pull timeout
+config.git.gc_timeout=GC timeout
 
 config.log_config=پیکربندی لاگ
+config.log_file_root_path=مسیر ریشه ی فایل لاگ
 config.log_mode=حالت
 config.log_options=گزینه‌‌‌‌‌‌ها
 
@@ -1340,6 +1399,7 @@ months=%d ماه %s
 years=%d سال %s
 raw_seconds=ثانیه
 raw_minutes=دقیقه ها
+raw_hours=hours
 
 [dropzone]
 default_message=فایل را در این محل رها کنید یا دکمه ی آپلود یا بارگزاری را فشار دهید.

+ 166 - 106
conf/locale/locale_fi-FI.ini

@@ -9,7 +9,6 @@ sign_out=Kirjaudu ulos
 sign_up=Rekisteröidy
 register=Rekisteröidy
 website=Nettisivut
-version=Versio
 page=Sivu
 template=Malli
 language=Kieli
@@ -122,6 +121,7 @@ run_user_not_match=Suoritus käyttäjä ei ole nykyinen käyttäjä: %s -> %s
 smtp_host_missing_port=SMTP-isännältä puuttuu portin osoite.
 invalid_smtp_from=SMTP From kenttä ei ole kelvollinen: %v
 save_config_failed=Asetuksien tallennus epäonnistui: %v
+init_failed=Failed to initialize application: %v
 invalid_admin_setting=Ylläpito tili asetus virheellinen: %v
 install_success=Tervetuloa! Olemme iloisia että valitsit GIN, pidä hauskaa ja pidä huolta itsestäsi.
 invalid_log_root_path=Loki juurihakemisto ei kelpaa: %v
@@ -151,8 +151,8 @@ register_hepler_msg=On jo tili? Kirjaudu sisään nyt!
 social_register_hepler_msg=On jo tili? Liitä nyt!
 disable_register_prompt=Sori, rekisteröinti on poistettu käytöstä. Ole hyvä ja ota yhteyttä sivuston ylläpitoon.
 disable_register_mail=Sori, rekisteröinti sähköpostivarmistukset on poistettu käytöstä.
-auth_source=Authentication Source
-local=Local
+auth_source=Todennuslähde
+local=Paikallinen
 remember_me=Muista minut
 forgot_password=Unohtuiko salasana
 forget_password=Unohtuiko salasana?
@@ -231,7 +231,7 @@ org_name_been_taken=Organisaation nimi on jo käytössä.
 team_name_been_taken=Tiimin nimi on jo käytössä.
 email_been_used=Sähköpostiosoite on jo käytössä.
 username_password_incorrect=Käyttäjätunnus tai salasana ei ole oikein.
-auth_source_mismatch=The authentication source selected is not associated with the user.
+auth_source_mismatch=Valittua todennuslähdettä ei liitetä käyttäjään.
 enterred_invalid_repo_name=Ole hyvä ja varmista että kirjoittamasi repon nimi on oikein.
 enterred_invalid_owner_name=Ole hyvä ja varmista että kirjoittamasi omistajan nimi on oikein.
 enterred_invalid_password=Ole hyvä ja varmista että kirjoittamasi salasana on oikein.
@@ -351,7 +351,7 @@ two_factor_or_enter_secret=Tai kirjoita salaisuus:
 two_factor_then_enter_passcode=Sitten kirjoita salasana:
 two_factor_verify=Vahvista
 two_factor_invalid_passcode=Kirjoittamasi salasana ei kelpaa, yritä uudelleen!
-two_factor_reused_passcode=The passcode you entered has already been used, please try another one!
+two_factor_reused_passcode=Antamasi salasana on jo käytetty, kokeile toista!
 two_factor_enable_error=Ota käyttöön kaksivaiheinen todennus epäonnistui: %v
 two_factor_enable_success=Kaksivaiheinen todennus on otettu käyttöön tilissäsi menestyksekkäästi!
 two_factor_recovery_codes_title=Kaksivaiheinen todennus palautuskoodit
@@ -374,7 +374,7 @@ delete_token=Poista
 access_token_deletion=Henkilökohtaisen pääsymerkin poisto
 access_token_deletion_desc=Tämän henkilökohtaisen pääsymerkin poistaminen poistaa kaikki siihen liittyvät pääsyt sovellukseen. Haluatko jatkaa?
 delete_token_success=Henkilökohtainen pääsymerkki on poistettu onnistuneesti! Älä unohda päivittää sovellustasi myös.
-token_name_exists=Token with same name already exists.
+token_name_exists=Saman nimen tunnus on jo olemassa.
 
 orgs.none=Et ole yhdenkään organisaation jäsen.
 orgs.leave_title=Poistu organisaatiosta
@@ -422,8 +422,8 @@ mirror_last_synced=Synkronoitu viimeksi
 watchers=Tarkkailijat
 stargazers=Tähtiharrastajat
 forks=Haarat
-repo_description_helper=Description of repository. Maximum 512 characters length.
-repo_description_length=Available characters
+repo_description_helper=Repon kuvaus. Enintään 512 merkkiä.
+repo_description_length=Käytettävissä olevat merkit
 
 form.reach_limit_of_creation=Omistaja on saavuttanut maksimi luontirajan %d repoa.
 form.name_reserved=Repon nimi '%s' on varattu.
@@ -521,7 +521,7 @@ editor.file_changed_while_editing=Tiedoston sisältöä on muutettu aloittamises
 editor.file_already_exists=Tiedosto '%s' on jo olemassa tässä repossa.
 editor.no_changes_to_show=Ei muutoksia näytettäväksi.
 editor.fail_to_update_file=Tiedoston '%s' päivitys/luonti epäonnistui virheeseen: %v
-editor.fail_to_delete_file=Failed to delete file '%s' with error: %v
+editor.fail_to_delete_file=Tiedoston '%s' poistaminen epäonnistui virheellä: %v
 editor.add_subdir=Lisää alikansio...
 editor.unable_to_upload_files=Tiedostojen lataus epäonnistui kansioon '%s' virheellä: %v
 editor.upload_files_to_dir=Lataa tiedostoja kansioon '%s'
@@ -624,7 +624,7 @@ pulls.compare_compare=vertaa
 pulls.filter_branch=Suodata branch
 pulls.no_results=Tuloksia ei löytynyt.
 pulls.nothing_to_compare=Ei ole mitään verrattavaa koska base ja head branchit ovat tasoissa.
-pulls.nothing_merge_base=There is nothing to compare because two branches have completely different history.
+pulls.nothing_merge_base=Ei ole mitään verrattavaa, koska kahdella haaralla on täysin erilainen historia.
 pulls.has_pull_request=`On olemassa jo pull pyyntö näiden kohteiden välillä: <a href="%[1]s/pulls/%[3]d">%[2]s#%[3]d</a>`
 pulls.create=Luo Pull-pyyntö
 pulls.title_desc=haluaa yhdistää %[1]d committia lähteestä <code>%[2]s</code> kohteeseen <code>%[3]s</code>
@@ -640,9 +640,9 @@ pulls.is_checking=Konfliktin tarkistus on yhä meneillään, ole hyvä ja päivi
 pulls.can_auto_merge_desc=Tämä pull-pyyntö voidaan yhdistää automaattisesti.
 pulls.cannot_auto_merge_desc=Tätä pull-pyyntöä ei voi yhdistää automaattisesti koska on konflikteja.
 pulls.cannot_auto_merge_helper=Ole hyvä ja yhdistä manuaalisesti konfliktien ratkaisemiseksi.
-pulls.create_merge_commit=Create a merge commit
-pulls.rebase_before_merging=Rebase before merging
-pulls.commit_description=Commit Description
+pulls.create_merge_commit=Luo yhdistämistoiminto
+pulls.rebase_before_merging=Rebase ennen yhdistämistä
+pulls.commit_description=Toimituksen kuvaus
 pulls.merge_pull_request=Yhdistä Pull-pyyntö
 pulls.open_unmerged_pull_exists=`Et voi suorittaa uudelleenavaus toimintoa koska on jo olemassa pull-pyyntö (#%d) samasta reposta samoilla yhdistämistiedoilla ja odottaa yhdistämistä.`
 pulls.delete_branch=Poista haara
@@ -1001,6 +1001,12 @@ first_page=Ensimmäinen
 last_page=Viimeisin
 total=Yhteensä: %d
 
+dashboard.build_info=Build Information
+dashboard.app_ver=Application version
+dashboard.git_version=Git version
+dashboard.go_version=Go version
+dashboard.build_time=Build time
+dashboard.build_commit=Build commit
 dashboard.statistic=Statistiikka
 dashboard.operations=Toiminnot
 dashboard.system_status=Järjestelmänvalvonnan tila
@@ -1156,117 +1162,170 @@ auths.github_api_endpoint=API päätepiste
 
 config.not_set=(ei ole asetettu)
 config.server_config=Palvelin asetukset
-config.app_name=Sovellus nimi
-config.app_ver=Sovellus versio
-config.app_url=Sovellus URL
-config.domain=Verkkotunnus
-config.offline_mode=Offline-tila
-config.disable_router_log=Poista käytöstä reitittimen loki
+config.brand_name=Brand name
 config.run_user=Suorita käyttäjänä
 config.run_mode=Suoritustila
-config.git_version=Git versio
-config.static_file_root_path=Staattisen tiedoston juuren polku
-config.log_file_root_path=Lokitiedoston juuren polku
-config.reverse_auth_user=Käänteinen todennus käyttäjä
+config.server.external_url=External URL
+config.server.domain=Domain
+config.server.protocol=Protocol
+config.server.http_addr=HTTP address
+config.server.http_port=HTTP port
+config.server.cert_file=Certificate file
+config.server.key_file=Key file
+config.server.tls_min_version=Minimum TLS version
+config.server.unix_socket_permission=Unix socket permission
+config.server.local_root_url=Local root URL
+config.server.offline_mode=Offline mode
+config.server.disable_router_log=Disable router log
+config.server.enable_gzip=Enable Gzip
+config.server.app_data_path=Application data path
+config.server.load_assets_from_disk=Load assets from disk
+config.server.landing_url=Landing URL
 
 config.ssh_config=SSH asetukset
-config.ssh_enabled=Käytössä
-config.ssh_start_builtin_server=Käynnistä sisäänrakennettu palvelin
-config.ssh_domain=Verkkotunnus
-config.ssh_port=Portti
-config.ssh_listen_port=Kuuntele porttia
-config.ssh_root_path=Juuren polku
-config.ssh_rewrite_authorized_keys_at_start=Rewrite authorized_keys At Start
-config.ssh_key_test_path=Polku jossa avaimet testataan
-config.ssh_keygen_path=Keygen ('ssh-keygen') polku
-config.ssh_minimum_key_size_check=Avaimen vähimmäiskoko tarkistus
-config.ssh_minimum_key_sizes=Avaimen vähimmäiskoot
+config.ssh.enabled=Enabled
+config.ssh.domain=Exposed domain
+config.ssh.port=Exposed port
+config.ssh.root_path=Root path
+config.ssh.keygen_path=Keygen path
+config.ssh.key_test_path=Key test path
+config.ssh.minimum_key_size_check=Minimum key size check
+config.ssh.minimum_key_sizes=Minimum key sizes
+config.ssh.rewrite_authorized_keys_at_start=Rewrite "authorized_keys" at start
+config.ssh.start_builtin_server=Start builtin server
+config.ssh.listen_host=Listen host
+config.ssh.listen_port=Listen port
+config.ssh.server_ciphers=Server ciphers
 
 config.repo_config=Repositoryn asetukset
-config.repo_root_path=Repon juuren polku
-config.script_type=Komentosarjan tyyppi
-config.repo_force_private=Pakota yksityiseksi
-config.max_creation_limit=Enimmäis-luontiraja
-config.preferred_licenses=Ensisijaiset lisenssit
-config.disable_http_git=Poista käytöstä HTTP Git
-config.enable_local_path_migration=Ota käyttöön paikallisen polun migraatio
-config.commits_fetch_concurrency=Committien noudon samanaikaisuus
-
-config.http_config=HTTP-asetukset
-config.http_access_control_allow_origin=Access Control Allow Origin
+config.repo.root_path=Root path
+config.repo.script_type=Script type
+config.repo.ansi_chatset=ANSI charset
+config.repo.force_private=Force private
+config.repo.max_creation_limit=Max creation limit
+config.repo.preferred_licenses=Preferred licenses
+config.repo.disable_http_git=Disable HTTP Git
+config.repo.enable_local_path_migration=Enable local path migration
+config.repo.enable_raw_file_render_mode=Enable raw file render mode
+config.repo.commits_fetch_concurrency=Commits fetch concurrency
+config.repo.editor.line_wrap_extensions=Editor line wrap extensions
+config.repo.editor.previewable_file_modes=Editor previewable file modes
+config.repo.upload.enabled=Upload enabled
+config.repo.upload.temp_path=Upload temporary path
+config.repo.upload.allowed_types=Upload allowed types
+config.repo.upload.file_max_size=Upload file size limit
+config.repo.upload.max_files=Upload files limit
 
 config.db_config=Tietokannan asetukset
-config.db_type=Tyyppi
-config.db_host=Isäntä
-config.db_name=Nimi
-config.db_user=Käyttäjä
-config.db_ssl_mode=SSL tila
-config.db_ssl_mode_helper=(vain "postgres")
-config.db_path=Polku
-config.db_path_helper=("sqlite3" ja "tidb")
-
-config.service_config=Palvelu asetukset
-config.register_email_confirm=Vaadi sähköpostivahvistus
-config.disable_register=Poista käytöstä rekisteröinti
-config.show_registration_button=Näytä rekisteröidy painike
-config.require_sign_in_view=Vaadi sisäänkirjautuminen nähdäksesi
-config.mail_notify=Sähköposti ilmoitukset
-config.disable_key_size_check=Poista käytöstä avaimen vähimmäiskoko tarkistus
-config.enable_captcha=Ota käyttöön Captcha
-config.active_code_lives=Aktiivinen koodi elämät ennen vanhenemista
-config.reset_password_code_lives=Nollaa salasana koodi elämät
+config.db.type=Type
+config.db.host=Host
+config.db.name=Name
+config.db.user=User
+config.db.ssl_mode=SSL mode
+config.db.ssl_mode_helper=(for "postgres" only)
+config.db.path=Path
+config.db.path_helper=(for "sqlite3"only)
+
+config.security_config=Security configuration
+config.security.login_remember_days=Login remember days
+config.security.cookie_remember_name=Remember cookie
+config.security.cookie_username=Username cookie
+config.security.cookie_secure=Enable secure cookie
+config.security.reverse_proxy_auth_user=Reverse proxy authentication header
+config.security.enable_login_status_cookie=Enable login status cookie
+config.security.login_status_cookie_name=Login status cookie
+
+config.email_config=Email configuration
+config.email.enabled=Enabled
+config.email.subject_prefix=Subject prefix
+config.email.host=Host
+config.email.from=From
+config.email.user=User
+config.email.disable_helo=Disable HELO
+config.email.helo_hostname=HELO hostname
+config.email.skip_verify=Skip certificate verify
+config.email.use_certificate=Use custom certificate
+config.email.cert_file=Certificate file
+config.email.key_file=Key file
+config.email.use_plain_text=Use plain text
+config.email.add_plain_text_alt=Add plain text alternative
+config.email.send_test_mail=Send test email
+config.email.test_mail_failed=Failed to send test email to '%s': %v
+config.email.test_mail_sent=Test email has been sent to '%s'.
+
+config.auth_config=Authentication configuration
+config.auth.activate_code_lives=Activate code lives
+config.auth.reset_password_code_lives=Reset password code lives
+config.auth.require_email_confirm=Require email confirmation
+config.auth.require_sign_in_view=Require sign in view
+config.auth.disable_registration=Disable registration
+config.auth.enable_registration_captcha=Enable registration captcha
+config.auth.enable_reverse_proxy_authentication=Enable reverse proxy authentication
+config.auth.enable_reverse_proxy_auto_registration=Enable reverse proxy auto registration
+config.auth.reverse_proxy_authentication_header=Reverse proxy authentication header
+
+config.user_config=User configuration
+config.user.enable_email_notify=Enable email notification
 
-config.webhook_config=Webkoukku asetukset
-config.queue_length=Jonon pituus
-config.deliver_timeout=Toimitus aikakatkaisu
-config.skip_tls_verify=Ohita TLS tarkistaminen
-
-config.mailer_config=Sähköpostipalvelin asetukset
-config.mailer_enabled=Käytössä
-config.mailer_disable_helo=Poista käytöstä HELO
-config.mailer_subject_prefix=Subject Prefix
-config.mailer_host=Isäntä
-config.mailer_user=Käyttäjä
-config.send_test_mail=Lähetä testi sähköposti
-config.test_mail_failed=Testi sähköpostin lähettäminen vastaanottajalle '%s': %v epäonnistui
-config.test_mail_sent=Testi sähköposti on lähetetty vastaanottajalle '%s'.
-
-config.oauth_config=OAuth asetukset
-config.oauth_enabled=Käytössä
+config.session_config=Istunnon asetukset
+config.session.provider=Provider
+config.session.provider_config=Provider config
+config.session.cookie_name=Cookie
+config.session.https_only=HTTPS only
+config.session.gc_interval=GC interval
+config.session.max_life_time=Max life time
+config.session.csrf_cookie_name=CSRF cookie
 
 config.cache_config=Välimuistin asetukset
-config.cache_adapter=Välimuistin sovitin
-config.cache_interval=Välimuistin aikaväli
-config.cache_conn=Välimuistin yhteys merkkijono
+config.cache.adapter=Adapter
+config.cache.interval=GC interval
+config.cache.host=Host
 
-config.session_config=Istunnon asetukset
-config.session_provider=Istunnon toimittaja
-config.provider_config=Toimittajan asetukset
-config.cookie_name=Evästenimi
-config.enable_set_cookie=Ota käyttöön aseta eväste
-config.gc_interval_time=GC aikaväli aika
-config.session_life_time=Istunnon elinikä
-config.https_only=Vain HTTPS
-config.cookie_life_time=Evästeen elinikä
+config.http_config=HTTP-asetukset
+config.http.access_control_allow_origin=Access control allow origin
+
+config.attachment_config=Attachment configuration
+config.attachment.enabled=Enabled
+config.attachment.path=Path
+config.attachment.allowed_types=Allowed types
+config.attachment.max_size=Size limit
+config.attachment.max_files=Files limit
+
+config.release_config=Release configuration
+config.release.attachment.enabled=Attachment enabled
+config.release.attachment.allowed_types=Attachment allowed types
+config.release.attachment.max_size=Attachment size limit
+config.release.attachment.max_files=Attachment files limit
 
 config.picture_config=Kuva asetukset
-config.picture_service=Kuva palvelu
-config.disable_gravatar=Poista käytöstä Gravatar
-config.enable_federated_avatar=Käytä ulkopuolisia profiilikuvia
+config.picture.avatar_upload_path=User avatar upload path
+config.picture.repo_avatar_upload_path=Repository avatar upload path
+config.picture.gravatar_source=Gravatar source
+config.picture.disable_gravatar=Disable Gravatar
+config.picture.enable_federated_avatar=Enable federated avatars
+
+config.mirror_config=Mirror configuration
+config.mirror.default_interval=Default interval
+
+config.webhook_config=Webkoukku asetukset
+config.webhook.types=Types
+config.webhook.deliver_timeout=Deliver timeout
+config.webhook.skip_tls_verify=Skip TLS verify
 
 config.git_config=Git asetukset
-config.git_disable_diff_highlight=Poista koodinväritys käytöstä diff-näkymässä
-config.git_max_diff_lines=Diff-rivien enimmäismäärä (yhdelle tiedostolle)
-config.git_max_diff_line_characters=Enimmäismäärä merkkejä (yhdellä diff-rivillä)
-config.git_max_diff_files=Enimmäismäärä tiedostoja (diff-näkymässä)
-config.git_gc_args=Roskienkeruun parametrit
-config.git_migrate_timeout=Migraatio aikakatkaistiin
-config.git_mirror_timeout=Peilauspäivitys aikakatkaistiin
-config.git_clone_timeout=Kloonaus aikakatkaistiin
-config.git_pull_timeout=Pull-operaatio aikakatkaistiin
-config.git_gc_timeout=Roskienkeruu aikakatkaistiin
+config.git.disable_diff_highlight=Disable diff syntax highlight
+config.git.max_diff_lines=Diff lines limit (for a single file)
+config.git.max_diff_line_characters=Diff characters limit (for a single line)
+config.git.max_diff_files=Diff files limit (for a single diff)
+config.git.gc_args=GC arguments
+config.git.migrate_timeout=Migration timeout
+config.git.mirror_timeout=Mirror fetch timeout
+config.git.clone_timeout=Clone timeout
+config.git.pull_timeout=Pull timeout
+config.git.gc_timeout=GC timeout
 
 config.log_config=Loki asetukset
+config.log_file_root_path=Lokitiedoston juuren polku
 config.log_mode=Tila
 config.log_options=Valinnaiset
 
@@ -1338,6 +1397,7 @@ months=%d kuukautta %s
 years=%d vuotta %s
 raw_seconds=sekuntia
 raw_minutes=minuuttia
+raw_hours=hours
 
 [dropzone]
 default_message=Pudota tiedostot tähän tai klikkaa lataamista varten.

+ 154 - 94
conf/locale/locale_fr-FR.ini

@@ -9,7 +9,6 @@ sign_out=Déconnexion
 sign_up=Inscription
 register=S'inscrire
 website=Site web
-version=Version
 page=Page
 template=Modèle
 language=Langue
@@ -122,6 +121,7 @@ run_user_not_match=L'utilisateur d'exécution saisi n'est pas l'utilisateur d'ex
 smtp_host_missing_port=Le numéro de port est manquant dans l'adresse de l'Hôte SMTP.
 invalid_smtp_from=Le champ SMTP Provenant de n'est pas valide: %v
 save_config_failed=La sauvegarde de la configuration a échoué : %v
+init_failed=Failed to initialize application: %v
 invalid_admin_setting=Paramètres du compte administrateur invalides : %v
 install_success=Bienvenue ! Nous sommes heureux que vous ayez choisi GIN, amusez-vous et prenez soin de vous.
 invalid_log_root_path=L'emplacement racine des fichiers logs est invalide : %v
@@ -1001,6 +1001,12 @@ first_page=Première
 last_page=Dernière
 total=Total : %d
 
+dashboard.build_info=Build Information
+dashboard.app_ver=Application version
+dashboard.git_version=Git version
+dashboard.go_version=Go version
+dashboard.build_time=Build time
+dashboard.build_commit=Build commit
 dashboard.statistic=Statistiques
 dashboard.operations=Opérations
 dashboard.system_status=État du système
@@ -1156,117 +1162,170 @@ auths.github_api_endpoint=API Endpoint
 
 config.not_set=(non défini)
 config.server_config=Configuration du Serveur
-config.app_name=Nom de l'application
-config.app_ver=Version de l'application
-config.app_url=URL de l'application
-config.domain=Domaine
-config.offline_mode=Mode hors-ligne
-config.disable_router_log=Désactiver la Journalisation du Routeur
+config.brand_name=Brand name
 config.run_user=Utilisateur système
 config.run_mode=Mode d'Éxécution
-config.git_version=Version de Git
-config.static_file_root_path=Chemin statique des fichiers racines
-config.log_file_root_path=Emplacement Racine du Fichier Journal
-config.reverse_auth_user=Annuler l'Authentification de l'Utilisateur
+config.server.external_url=External URL
+config.server.domain=Domain
+config.server.protocol=Protocol
+config.server.http_addr=HTTP address
+config.server.http_port=HTTP port
+config.server.cert_file=Certificate file
+config.server.key_file=Key file
+config.server.tls_min_version=Minimum TLS version
+config.server.unix_socket_permission=Unix socket permission
+config.server.local_root_url=Local root URL
+config.server.offline_mode=Offline mode
+config.server.disable_router_log=Disable router log
+config.server.enable_gzip=Enable Gzip
+config.server.app_data_path=Application data path
+config.server.load_assets_from_disk=Load assets from disk
+config.server.landing_url=Landing URL
 
 config.ssh_config=Configuration SSH
-config.ssh_enabled=Activé
-config.ssh_start_builtin_server=Démarrer le serveur intégré
-config.ssh_domain=Domaine
-config.ssh_port=Port
-config.ssh_listen_port=Port d'écoute
-config.ssh_root_path=Emplacement racine
-config.ssh_rewrite_authorized_keys_at_start=Réécrire authorized_keys au démarrage
-config.ssh_key_test_path=Chemin de test des clés
-config.ssh_keygen_path=Chemin vers le générateur de clefs ("ssh-keygen")
-config.ssh_minimum_key_size_check=Vérification de la longueur de clé minimale
-config.ssh_minimum_key_sizes=Tailles de clé minimales
+config.ssh.enabled=Enabled
+config.ssh.domain=Exposed domain
+config.ssh.port=Exposed port
+config.ssh.root_path=Root path
+config.ssh.keygen_path=Keygen path
+config.ssh.key_test_path=Key test path
+config.ssh.minimum_key_size_check=Minimum key size check
+config.ssh.minimum_key_sizes=Minimum key sizes
+config.ssh.rewrite_authorized_keys_at_start=Rewrite "authorized_keys" at start
+config.ssh.start_builtin_server=Start builtin server
+config.ssh.listen_host=Listen host
+config.ssh.listen_port=Listen port
+config.ssh.server_ciphers=Server ciphers
 
 config.repo_config=Configuration du dépôt
-config.repo_root_path=Emplacement des Dépôts
-config.script_type=Type de Script
-config.repo_force_private=Privé forcé
-config.max_creation_limit=Limite de création maximale
-config.preferred_licenses=Licences préférées
-config.disable_http_git=Désactiver Git HTTP
-config.enable_local_path_migration=Activer la migration de chemin locale
-config.commits_fetch_concurrency=Concurrence des récupérations de commits
-
-config.http_config=Configuration HTTP
-config.http_access_control_allow_origin=Autoriser le partage d’accès avec l’origine
+config.repo.root_path=Root path
+config.repo.script_type=Script type
+config.repo.ansi_chatset=ANSI charset
+config.repo.force_private=Force private
+config.repo.max_creation_limit=Max creation limit
+config.repo.preferred_licenses=Preferred licenses
+config.repo.disable_http_git=Disable HTTP Git
+config.repo.enable_local_path_migration=Enable local path migration
+config.repo.enable_raw_file_render_mode=Enable raw file render mode
+config.repo.commits_fetch_concurrency=Commits fetch concurrency
+config.repo.editor.line_wrap_extensions=Editor line wrap extensions
+config.repo.editor.previewable_file_modes=Editor previewable file modes
+config.repo.upload.enabled=Upload enabled
+config.repo.upload.temp_path=Upload temporary path
+config.repo.upload.allowed_types=Upload allowed types
+config.repo.upload.file_max_size=Upload file size limit
+config.repo.upload.max_files=Upload files limit
 
 config.db_config=Configuration de la Base de Données
-config.db_type=Type
-config.db_host=Hôte
-config.db_name=Nom
-config.db_user=Utilisateur
-config.db_ssl_mode=Mode SSL
-config.db_ssl_mode_helper=("postgres" uniquement)
-config.db_path=Emplacement
-config.db_path_helper=(pour « sqlite3 » et « TIDB »)
-
-config.service_config=Configuration du Service
-config.register_email_confirm=Nécessite une confirmation par e-mail
-config.disable_register=Désactiver les inscriptions
-config.show_registration_button=Afficher le bouton d'enregistrement
-config.require_sign_in_view=Connexion obligatoire pour visualiser
-config.mail_notify=Notifier par mail
-config.disable_key_size_check=Désactiver la vérification de la taille de clé minimale
-config.enable_captcha=Activez le Captcha
-config.active_code_lives=Limites de Code Actif
-config.reset_password_code_lives=Réinitialiser le Mot De Passe des Limites de Code
+config.db.type=Type
+config.db.host=Host
+config.db.name=Name
+config.db.user=User
+config.db.ssl_mode=SSL mode
+config.db.ssl_mode_helper=(for "postgres" only)
+config.db.path=Path
+config.db.path_helper=(for "sqlite3"only)
+
+config.security_config=Security configuration
+config.security.login_remember_days=Login remember days
+config.security.cookie_remember_name=Remember cookie
+config.security.cookie_username=Username cookie
+config.security.cookie_secure=Enable secure cookie
+config.security.reverse_proxy_auth_user=Reverse proxy authentication header
+config.security.enable_login_status_cookie=Enable login status cookie
+config.security.login_status_cookie_name=Login status cookie
+
+config.email_config=Email configuration
+config.email.enabled=Enabled
+config.email.subject_prefix=Subject prefix
+config.email.host=Host
+config.email.from=From
+config.email.user=User
+config.email.disable_helo=Disable HELO
+config.email.helo_hostname=HELO hostname
+config.email.skip_verify=Skip certificate verify
+config.email.use_certificate=Use custom certificate
+config.email.cert_file=Certificate file
+config.email.key_file=Key file
+config.email.use_plain_text=Use plain text
+config.email.add_plain_text_alt=Add plain text alternative
+config.email.send_test_mail=Send test email
+config.email.test_mail_failed=Failed to send test email to '%s': %v
+config.email.test_mail_sent=Test email has been sent to '%s'.
+
+config.auth_config=Authentication configuration
+config.auth.activate_code_lives=Activate code lives
+config.auth.reset_password_code_lives=Reset password code lives
+config.auth.require_email_confirm=Require email confirmation
+config.auth.require_sign_in_view=Require sign in view
+config.auth.disable_registration=Disable registration
+config.auth.enable_registration_captcha=Enable registration captcha
+config.auth.enable_reverse_proxy_authentication=Enable reverse proxy authentication
+config.auth.enable_reverse_proxy_auto_registration=Enable reverse proxy auto registration
+config.auth.reverse_proxy_authentication_header=Reverse proxy authentication header
+
+config.user_config=User configuration
+config.user.enable_email_notify=Enable email notification
 
-config.webhook_config=Configuration Webhook
-config.queue_length=Longueur de la file d'attente
-config.deliver_timeout=Expiration d'Envoi
-config.skip_tls_verify=Ne pas vérifier TLS
-
-config.mailer_config=Configuration du service de mail
-config.mailer_enabled=Activé
-config.mailer_disable_helo=Désactiver HELO
-config.mailer_subject_prefix=Préfixe du sujet
-config.mailer_host=Hôte
-config.mailer_user=Utilisateur
-config.send_test_mail=Envoyer courriel de Test
-config.test_mail_failed=Impossible d'envoyer un e-mail de test à '%s': %v
-config.test_mail_sent=Un e-mail de test à été envoyé à '%s'.
-
-config.oauth_config=Configuration OAuth
-config.oauth_enabled=Activé
+config.session_config=Configuration de session
+config.session.provider=Provider
+config.session.provider_config=Provider config
+config.session.cookie_name=Cookie
+config.session.https_only=HTTPS only
+config.session.gc_interval=GC interval
+config.session.max_life_time=Max life time
+config.session.csrf_cookie_name=CSRF cookie
 
 config.cache_config=Configuration du Cache
-config.cache_adapter=Adaptateur du Cache
-config.cache_interval=Intervales du Cache
-config.cache_conn=Liaison du Cache
+config.cache.adapter=Adapter
+config.cache.interval=GC interval
+config.cache.host=Host
 
-config.session_config=Configuration de session
-config.session_provider=Fournisseur de session
-config.provider_config=Configuration du fournisseur
-config.cookie_name=Nom du cookie
-config.enable_set_cookie=Activer les cookies
-config.gc_interval_time=Intervals GC
-config.session_life_time=Durée des sessions
-config.https_only=HTTPS uniquement
-config.cookie_life_time=Expiration du cookie
+config.http_config=Configuration HTTP
+config.http.access_control_allow_origin=Access control allow origin
+
+config.attachment_config=Attachment configuration
+config.attachment.enabled=Enabled
+config.attachment.path=Path
+config.attachment.allowed_types=Allowed types
+config.attachment.max_size=Size limit
+config.attachment.max_files=Files limit
+
+config.release_config=Release configuration
+config.release.attachment.enabled=Attachment enabled
+config.release.attachment.allowed_types=Attachment allowed types
+config.release.attachment.max_size=Attachment size limit
+config.release.attachment.max_files=Attachment files limit
 
 config.picture_config=Configuration d'Image
-config.picture_service=Service d'Imagerie
-config.disable_gravatar=Désactiver Gravatar
-config.enable_federated_avatar=Activer les avatars unifiés
+config.picture.avatar_upload_path=User avatar upload path
+config.picture.repo_avatar_upload_path=Repository avatar upload path
+config.picture.gravatar_source=Gravatar source
+config.picture.disable_gravatar=Disable Gravatar
+config.picture.enable_federated_avatar=Enable federated avatars
+
+config.mirror_config=Mirror configuration
+config.mirror.default_interval=Default interval
+
+config.webhook_config=Configuration Webhook
+config.webhook.types=Types
+config.webhook.deliver_timeout=Deliver timeout
+config.webhook.skip_tls_verify=Skip TLS verify
 
 config.git_config=Configuration de Git
-config.git_disable_diff_highlight=Désactiver la surbrillance syntaxique de Diff
-config.git_max_diff_lines=Lignes de Diff Max (pour un seul fichier)
-config.git_max_diff_line_characters=Nombre max de caractères de Diff (pour une seule ligne)
-config.git_max_diff_files=Nombre max de fichiers de Diff (à afficher)
-config.git_gc_args=Arguments de GC
-config.git_migrate_timeout=Délai imparti pour une migration
-config.git_mirror_timeout=Délai imparti pour mettre à jour le miroir
-config.git_clone_timeout=Délai imparti pour l'opération "Clone"
-config.git_pull_timeout=Délai imparti pour l'opération "Pull"
-config.git_gc_timeout=Délai imparti pour l'opération "GC"
+config.git.disable_diff_highlight=Disable diff syntax highlight
+config.git.max_diff_lines=Diff lines limit (for a single file)
+config.git.max_diff_line_characters=Diff characters limit (for a single line)
+config.git.max_diff_files=Diff files limit (for a single diff)
+config.git.gc_args=GC arguments
+config.git.migrate_timeout=Migration timeout
+config.git.mirror_timeout=Mirror fetch timeout
+config.git.clone_timeout=Clone timeout
+config.git.pull_timeout=Pull timeout
+config.git.gc_timeout=GC timeout
 
 config.log_config=Configuration du Journal
+config.log_file_root_path=Emplacement Racine du Fichier Journal
 config.log_mode=Mode
 config.log_options=Options
 
@@ -1338,6 +1397,7 @@ months=%[2]s %[1]d mois
 years=%[2]s %[1]d ans
 raw_seconds=secondes
 raw_minutes=minutes
+raw_hours=hours
 
 [dropzone]
 default_message=Déposez les fichiers ici ou cliquez pour télécharger.

+ 157 - 97
conf/locale/locale_gl-ES.ini

@@ -9,7 +9,6 @@ sign_out=Cerrar sesión
 sign_up=Rexistro
 register=Rexistro
 website=Páxina web
-version=Versión
 page=Páxina
 template=Modelo
 language=Idioma
@@ -123,6 +122,7 @@ smtp_host_missing_port=Falta o porto do Host SMTP
 
 invalid_smtp_from=O campo From do SMTP non é valido: %v
 save_config_failed=Erro ao gardar a configuración: %v
+init_failed=Failed to initialize application: %v
 invalid_admin_setting=A configuración da conta de administración é inválida: %v
 install_success=Benvido/a! Estamos encantados de que escolleses GIN, divírtete e cóidate.
 invalid_log_root_path=A ruta para os rexistros é inválida: %v
@@ -1002,6 +1002,12 @@ first_page=Primeira
 last_page=Última
 total=Total: %d
 
+dashboard.build_info=Build Information
+dashboard.app_ver=Application version
+dashboard.git_version=Git version
+dashboard.go_version=Go version
+dashboard.build_time=Build time
+dashboard.build_commit=Build commit
 dashboard.statistic=Estatísticas
 dashboard.operations=Operacións
 dashboard.system_status=Estado do Monitor do Sistema
@@ -1157,117 +1163,170 @@ auths.github_api_endpoint=API Endpoint
 
 config.not_set=(not set)
 config.server_config=Configuración do servidor
-config.app_name=Nome da aplicación
-config.app_ver=Versión da aplicación
-config.app_url=URL da aplicación
-config.domain=Dominio
-config.offline_mode=Modo sen conexión
-config.disable_router_log=Deshabilitar log do router
+config.brand_name=Brand name
 config.run_user=Executada como usuario
 config.run_mode=Modo de execución
-config.git_version=Versión de Git
-config.static_file_root_path=Ruta dos ficheiros estáticos
-config.log_file_root_path=Ruta dos ficheiros de log
-config.reverse_auth_user=Autenticación inversa de usuario
+config.server.external_url=External URL
+config.server.domain=Domain
+config.server.protocol=Protocol
+config.server.http_addr=HTTP address
+config.server.http_port=HTTP port
+config.server.cert_file=Certificate file
+config.server.key_file=Key file
+config.server.tls_min_version=Minimum TLS version
+config.server.unix_socket_permission=Unix socket permission
+config.server.local_root_url=Local root URL
+config.server.offline_mode=Offline mode
+config.server.disable_router_log=Disable router log
+config.server.enable_gzip=Enable Gzip
+config.server.app_data_path=Application data path
+config.server.load_assets_from_disk=Load assets from disk
+config.server.landing_url=Landing URL
 
 config.ssh_config=Configuración SSH
-config.ssh_enabled=Habilitado
-config.ssh_start_builtin_server=Iniciar servidor integrado
-config.ssh_domain=Dominio
-config.ssh_port=Porto
-config.ssh_listen_port=Porto de escoita
-config.ssh_root_path=Ruta raíz
-config.ssh_rewrite_authorized_keys_at_start=Rewrite authorized_keys At Start
-config.ssh_key_test_path=Ruta da clave de proba
-config.ssh_keygen_path=Ruta do xerador de claves ('ssh-keygen')
-config.ssh_minimum_key_size_check=Tamaño mínimo da clave de verificación
-config.ssh_minimum_key_sizes=Tamaños de clave mínimos
-
-config.repo_config=Repository Configuration
-config.repo_root_path=Ruta do repositorio
-config.script_type=Tipo de Script
-config.repo_force_private=Force Private
-config.max_creation_limit=Max Creation Limit
-config.preferred_licenses=Preferred Licenses
-config.disable_http_git=Disable HTTP Git
-config.enable_local_path_migration=Enable Local Path Migration
-config.commits_fetch_concurrency=Commits Fetch Concurrency
-
-config.http_config=HTTP Configuration
-config.http_access_control_allow_origin=Access Control Allow Origin
+config.ssh.enabled=Enabled
+config.ssh.domain=Exposed domain
+config.ssh.port=Exposed port
+config.ssh.root_path=Root path
+config.ssh.keygen_path=Keygen path
+config.ssh.key_test_path=Key test path
+config.ssh.minimum_key_size_check=Minimum key size check
+config.ssh.minimum_key_sizes=Minimum key sizes
+config.ssh.rewrite_authorized_keys_at_start=Rewrite "authorized_keys" at start
+config.ssh.start_builtin_server=Start builtin server
+config.ssh.listen_host=Listen host
+config.ssh.listen_port=Listen port
+config.ssh.server_ciphers=Server ciphers
+
+config.repo_config=Repository configuration
+config.repo.root_path=Root path
+config.repo.script_type=Script type
+config.repo.ansi_chatset=ANSI charset
+config.repo.force_private=Force private
+config.repo.max_creation_limit=Max creation limit
+config.repo.preferred_licenses=Preferred licenses
+config.repo.disable_http_git=Disable HTTP Git
+config.repo.enable_local_path_migration=Enable local path migration
+config.repo.enable_raw_file_render_mode=Enable raw file render mode
+config.repo.commits_fetch_concurrency=Commits fetch concurrency
+config.repo.editor.line_wrap_extensions=Editor line wrap extensions
+config.repo.editor.previewable_file_modes=Editor previewable file modes
+config.repo.upload.enabled=Upload enabled
+config.repo.upload.temp_path=Upload temporary path
+config.repo.upload.allowed_types=Upload allowed types
+config.repo.upload.file_max_size=Upload file size limit
+config.repo.upload.max_files=Upload files limit
 
 config.db_config=Configuración da base de datos
-config.db_type=Tipo
-config.db_host=Host
-config.db_name=Nome
-config.db_user=Usuario
-config.db_ssl_mode=Modo SSL
-config.db_ssl_mode_helper=(só para "postgres")
-config.db_path=Ruta
-config.db_path_helper=(para "sqlite3" e "tidb")
-
-config.service_config=Configuración do servizo
-config.register_email_confirm=Solicitar confirmación por correo electrónico
-config.disable_register=Deshabilitar o rexistro
-config.show_registration_button=Mostrar botón de rexistro
-config.require_sign_in_view=Solicitar a vista de inicio de sesión
-config.mail_notify=Notificación por correo electrónico
-config.disable_key_size_check=Deshabilitar a comprobación de tamaño mínimo de clave
-config.enable_captcha=Activar captcha
-config.active_code_lives=Habilitar vida do código
-config.reset_password_code_lives=Restablecer contrasinal de vida do código
+config.db.type=Type
+config.db.host=Host
+config.db.name=Name
+config.db.user=User
+config.db.ssl_mode=SSL mode
+config.db.ssl_mode_helper=(for "postgres" only)
+config.db.path=Path
+config.db.path_helper=(for "sqlite3"only)
+
+config.security_config=Security configuration
+config.security.login_remember_days=Login remember days
+config.security.cookie_remember_name=Remember cookie
+config.security.cookie_username=Username cookie
+config.security.cookie_secure=Enable secure cookie
+config.security.reverse_proxy_auth_user=Reverse proxy authentication header
+config.security.enable_login_status_cookie=Enable login status cookie
+config.security.login_status_cookie_name=Login status cookie
+
+config.email_config=Email configuration
+config.email.enabled=Enabled
+config.email.subject_prefix=Subject prefix
+config.email.host=Host
+config.email.from=From
+config.email.user=User
+config.email.disable_helo=Disable HELO
+config.email.helo_hostname=HELO hostname
+config.email.skip_verify=Skip certificate verify
+config.email.use_certificate=Use custom certificate
+config.email.cert_file=Certificate file
+config.email.key_file=Key file
+config.email.use_plain_text=Use plain text
+config.email.add_plain_text_alt=Add plain text alternative
+config.email.send_test_mail=Send test email
+config.email.test_mail_failed=Failed to send test email to '%s': %v
+config.email.test_mail_sent=Test email has been sent to '%s'.
+
+config.auth_config=Authentication configuration
+config.auth.activate_code_lives=Activate code lives
+config.auth.reset_password_code_lives=Reset password code lives
+config.auth.require_email_confirm=Require email confirmation
+config.auth.require_sign_in_view=Require sign in view
+config.auth.disable_registration=Disable registration
+config.auth.enable_registration_captcha=Enable registration captcha
+config.auth.enable_reverse_proxy_authentication=Enable reverse proxy authentication
+config.auth.enable_reverse_proxy_auto_registration=Enable reverse proxy auto registration
+config.auth.reverse_proxy_authentication_header=Reverse proxy authentication header
+
+config.user_config=User configuration
+config.user.enable_email_notify=Enable email notification
 
-config.webhook_config=Configuración de Webhooks
-config.queue_length=Tamaño de cola de envío
-config.deliver_timeout=Timeout de entrega
-config.skip_tls_verify=Omitir a verificación TLS
-
-config.mailer_config=Configuración do servidor de correo
-config.mailer_enabled=Activado
-config.mailer_disable_helo=Desactivar HELO
-config.mailer_subject_prefix=Subject Prefix
-config.mailer_host=Host
-config.mailer_user=Usuario
-config.send_test_mail=Enviar correo electrónico de proba
-config.test_mail_failed=Fallo ao enviar o correo electrónico de proba a '%s': %v
-config.test_mail_sent=O correo electrónico de proba foi enviado a '%s'.
-
-config.oauth_config=Configuración OAuth
-config.oauth_enabled=Activado
+config.session_config=Configuración da sesión
+config.session.provider=Provider
+config.session.provider_config=Provider config
+config.session.cookie_name=Cookie
+config.session.https_only=HTTPS only
+config.session.gc_interval=GC interval
+config.session.max_life_time=Max life time
+config.session.csrf_cookie_name=CSRF cookie
 
 config.cache_config=Configuración da caché
-config.cache_adapter=Adaptador da caché
-config.cache_interval=Intervalo da caché
-config.cache_conn=Conexión da caché
-
-config.session_config=Configuración da sesión
-config.session_provider=Provedor da sesión
-config.provider_config=Configuración do provedor
-config.cookie_name=Nome da cookie
-config.enable_set_cookie=Activar establecemento de cookie
-config.gc_interval_time=Intervalo de tempo do GC
-config.session_life_time=Tempo de vida da sesión
-config.https_only=Só HTTPS
-config.cookie_life_time=Tempo de vida da cookie
+config.cache.adapter=Adapter
+config.cache.interval=GC interval
+config.cache.host=Host
+
+config.http_config=HTTP configuration
+config.http.access_control_allow_origin=Access control allow origin
+
+config.attachment_config=Attachment configuration
+config.attachment.enabled=Enabled
+config.attachment.path=Path
+config.attachment.allowed_types=Allowed types
+config.attachment.max_size=Size limit
+config.attachment.max_files=Files limit
+
+config.release_config=Release configuration
+config.release.attachment.enabled=Attachment enabled
+config.release.attachment.allowed_types=Attachment allowed types
+config.release.attachment.max_size=Attachment size limit
+config.release.attachment.max_files=Attachment files limit
 
 config.picture_config=Configuración de imaxe
-config.picture_service=Servizo de imaxe
-config.disable_gravatar=Desactivar gravatar
-config.enable_federated_avatar=Habilitar avatares federados
+config.picture.avatar_upload_path=User avatar upload path
+config.picture.repo_avatar_upload_path=Repository avatar upload path
+config.picture.gravatar_source=Gravatar source
+config.picture.disable_gravatar=Disable Gravatar
+config.picture.enable_federated_avatar=Enable federated avatars
+
+config.mirror_config=Mirror configuration
+config.mirror.default_interval=Default interval
+
+config.webhook_config=Configuración de Webhooks
+config.webhook.types=Types
+config.webhook.deliver_timeout=Deliver timeout
+config.webhook.skip_tls_verify=Skip TLS verify
 
 config.git_config=Configuración de git
-config.git_disable_diff_highlight=Desactivar resaltado de sintaxe do Diff
-config.git_max_diff_lines=Liñas de Diff máximas (por un só arquivo)
-config.git_max_diff_line_characters=Caracteres de Diff máximos (para unha soa liña)
-config.git_max_diff_files=Máximo de arquivos de Diff (que se mostrarán)
-config.git_gc_args=Argumentos de GC
-config.git_migrate_timeout=Tempo de espera de migración
-config.git_mirror_timeout=Tempo de espera de actualización de réplicas
-config.git_clone_timeout=Tempo de espera de operación de clóns
-config.git_pull_timeout=Tempo de espera de operación de pull
-config.git_gc_timeout=Tempo de espera de operación de GC
+config.git.disable_diff_highlight=Disable diff syntax highlight
+config.git.max_diff_lines=Diff lines limit (for a single file)
+config.git.max_diff_line_characters=Diff characters limit (for a single line)
+config.git.max_diff_files=Diff files limit (for a single diff)
+config.git.gc_args=GC arguments
+config.git.migrate_timeout=Migration timeout
+config.git.mirror_timeout=Mirror fetch timeout
+config.git.clone_timeout=Clone timeout
+config.git.pull_timeout=Pull timeout
+config.git.gc_timeout=GC timeout
 
 config.log_config=Configuración do log
+config.log_file_root_path=Ruta dos ficheiros de log
 config.log_mode=Mode
 config.log_options=Options
 
@@ -1339,6 +1398,7 @@ months=%[2]s %[1]d meses
 years=%s %d anos
 raw_seconds=segundos
 raw_minutes=minutos
+raw_hours=hours
 
 [dropzone]
 default_message=Sólteos aquí ou pulse para cargar arquivos.

+ 154 - 94
conf/locale/locale_hu-HU.ini

@@ -9,7 +9,6 @@ sign_out=Kijelentkezés
 sign_up=Regisztráció
 register=Regisztráció
 website=Weboldal
-version=Verzió
 page=Oldal
 template=Sablon
 language=Nyelv
@@ -122,6 +121,7 @@ run_user_not_match=Futtató felhasználó más, mint az aktuális felhasználó:
 smtp_host_missing_port=Az SMTP kiszolgáló címéből hiányzik a portszám.
 invalid_smtp_from=Érvénytelen SMTP Feladó mező: %v
 save_config_failed=Hiba a beállítások tárolásakor: %v
+init_failed=Failed to initialize application: %v
 invalid_admin_setting=Hibás a rendszergazdai fiók beállítása: %v
 install_success=Üdv! Örülünk, hogy a GIN-ot választottad, érezd jól magad és viseld gondját.
 invalid_log_root_path=Naplózás gyökérmappa érvénytelen: %v
@@ -1001,6 +1001,12 @@ first_page=Első
 last_page=Utolsó
 total=Összesen: %d
 
+dashboard.build_info=Build Information
+dashboard.app_ver=Application version
+dashboard.git_version=Git version
+dashboard.go_version=Go version
+dashboard.build_time=Build time
+dashboard.build_commit=Build commit
 dashboard.statistic=Statisztika
 dashboard.operations=Műveletek
 dashboard.system_status=Rendszerfigyelő Állapota
@@ -1156,117 +1162,170 @@ auths.github_api_endpoint=API végpont
 
 config.not_set=(nincs beállítva)
 config.server_config=Kiszolgáló konfiguráció
-config.app_name=Alkalmazás neve
-config.app_ver=Alkalmazás verziója
-config.app_url=Alkalmazás URL-je
-config.domain=Tartomány
-config.offline_mode=Kapcsolat nélküli mód
-config.disable_router_log=Útválasztás naplózásának letiltása
+config.brand_name=Brand name
 config.run_user=Futtató felhasználó
 config.run_mode=Futtatás módja
-config.git_version=Git verzió
-config.static_file_root_path=Statikus fájl gyökérútvonal
-config.log_file_root_path=Naplófájl gyökérútvonal
-config.reverse_auth_user=Visszafelé hitelesítés felhasználója
+config.server.external_url=External URL
+config.server.domain=Domain
+config.server.protocol=Protocol
+config.server.http_addr=HTTP address
+config.server.http_port=HTTP port
+config.server.cert_file=Certificate file
+config.server.key_file=Key file
+config.server.tls_min_version=Minimum TLS version
+config.server.unix_socket_permission=Unix socket permission
+config.server.local_root_url=Local root URL
+config.server.offline_mode=Offline mode
+config.server.disable_router_log=Disable router log
+config.server.enable_gzip=Enable Gzip
+config.server.app_data_path=Application data path
+config.server.load_assets_from_disk=Load assets from disk
+config.server.landing_url=Landing URL
 
 config.ssh_config=SSH konfiguráció
-config.ssh_enabled=Engedélyezett
-config.ssh_start_builtin_server=Beépített kiszolgáló indítása
-config.ssh_domain=Tartomány
-config.ssh_port=Port
-config.ssh_listen_port=Figyelő port
-config.ssh_root_path=Gyökér elérési útvonal
-config.ssh_rewrite_authorized_keys_at_start=SSH authorized_keys fájl újraírása indításnál
-config.ssh_key_test_path=Kulcs ellenőrzés útvonala
-config.ssh_keygen_path=Kulcsgeneráló ('ssh-keygen') elérési útja
-config.ssh_minimum_key_size_check=Minimális kulcsméret ellenőrzés
-config.ssh_minimum_key_sizes=Kulcsok Minimális Mérete
+config.ssh.enabled=Enabled
+config.ssh.domain=Exposed domain
+config.ssh.port=Exposed port
+config.ssh.root_path=Root path
+config.ssh.keygen_path=Keygen path
+config.ssh.key_test_path=Key test path
+config.ssh.minimum_key_size_check=Minimum key size check
+config.ssh.minimum_key_sizes=Minimum key sizes
+config.ssh.rewrite_authorized_keys_at_start=Rewrite "authorized_keys" at start
+config.ssh.start_builtin_server=Start builtin server
+config.ssh.listen_host=Listen host
+config.ssh.listen_port=Listen port
+config.ssh.server_ciphers=Server ciphers
 
 config.repo_config=Tároló konfiguráció
-config.repo_root_path=Tárolók gyökérkönyvtára
-config.script_type=Szkript típus
-config.repo_force_private=Privát erőltetése
-config.max_creation_limit=Maximum létrehozási korlát
-config.preferred_licenses=Előnyben részesített licencek
-config.disable_http_git=A HTTP protokoll letiltása GIT-hez
-config.enable_local_path_migration=Engedélyezi a migrációt helyi elérési út alapján
-config.commits_fetch_concurrency=Konkurens lekérés
-
-config.http_config=HTTP beállítások
-config.http_access_control_allow_origin=Hozzáférés vezérlés forrás szerint
+config.repo.root_path=Root path
+config.repo.script_type=Script type
+config.repo.ansi_chatset=ANSI charset
+config.repo.force_private=Force private
+config.repo.max_creation_limit=Max creation limit
+config.repo.preferred_licenses=Preferred licenses
+config.repo.disable_http_git=Disable HTTP Git
+config.repo.enable_local_path_migration=Enable local path migration
+config.repo.enable_raw_file_render_mode=Enable raw file render mode
+config.repo.commits_fetch_concurrency=Commits fetch concurrency
+config.repo.editor.line_wrap_extensions=Editor line wrap extensions
+config.repo.editor.previewable_file_modes=Editor previewable file modes
+config.repo.upload.enabled=Upload enabled
+config.repo.upload.temp_path=Upload temporary path
+config.repo.upload.allowed_types=Upload allowed types
+config.repo.upload.file_max_size=Upload file size limit
+config.repo.upload.max_files=Upload files limit
 
 config.db_config=Adatbázis konfiguráció
-config.db_type=Típus
-config.db_host=Állomás
-config.db_name=Név
-config.db_user=Felhasználó
-config.db_ssl_mode=SSL-mód
-config.db_ssl_mode_helper=(csak "postgres" )
-config.db_path=Elérési út
-config.db_path_helper=("sqlite3" és "tidb")
-
-config.service_config=Szolgáltatás beállításai
-config.register_email_confirm=E-mail megerősítés szükséges
-config.disable_register=Regisztráció tiltása
-config.show_registration_button=Regisztráció gomb megjelenítése
-config.require_sign_in_view=Bejelentkező Nézet
-config.mail_notify=E-mail értesítés
-config.disable_key_size_check=Minimális kulcsméret ellenőrzés letiltása
-config.enable_captcha=Ellenőrző kód engedélyezése
-config.active_code_lives=Aktivál kód élet
-config.reset_password_code_lives=Jelkód élettartamának visszaálítása
+config.db.type=Type
+config.db.host=Host
+config.db.name=Name
+config.db.user=User
+config.db.ssl_mode=SSL mode
+config.db.ssl_mode_helper=(for "postgres" only)
+config.db.path=Path
+config.db.path_helper=(for "sqlite3"only)
+
+config.security_config=Security configuration
+config.security.login_remember_days=Login remember days
+config.security.cookie_remember_name=Remember cookie
+config.security.cookie_username=Username cookie
+config.security.cookie_secure=Enable secure cookie
+config.security.reverse_proxy_auth_user=Reverse proxy authentication header
+config.security.enable_login_status_cookie=Enable login status cookie
+config.security.login_status_cookie_name=Login status cookie
+
+config.email_config=Email configuration
+config.email.enabled=Enabled
+config.email.subject_prefix=Subject prefix
+config.email.host=Host
+config.email.from=From
+config.email.user=User
+config.email.disable_helo=Disable HELO
+config.email.helo_hostname=HELO hostname
+config.email.skip_verify=Skip certificate verify
+config.email.use_certificate=Use custom certificate
+config.email.cert_file=Certificate file
+config.email.key_file=Key file
+config.email.use_plain_text=Use plain text
+config.email.add_plain_text_alt=Add plain text alternative
+config.email.send_test_mail=Send test email
+config.email.test_mail_failed=Failed to send test email to '%s': %v
+config.email.test_mail_sent=Test email has been sent to '%s'.
+
+config.auth_config=Authentication configuration
+config.auth.activate_code_lives=Activate code lives
+config.auth.reset_password_code_lives=Reset password code lives
+config.auth.require_email_confirm=Require email confirmation
+config.auth.require_sign_in_view=Require sign in view
+config.auth.disable_registration=Disable registration
+config.auth.enable_registration_captcha=Enable registration captcha
+config.auth.enable_reverse_proxy_authentication=Enable reverse proxy authentication
+config.auth.enable_reverse_proxy_auto_registration=Enable reverse proxy auto registration
+config.auth.reverse_proxy_authentication_header=Reverse proxy authentication header
+
+config.user_config=User configuration
+config.user.enable_email_notify=Enable email notification
 
-config.webhook_config=Webhook beállítás
-config.queue_length=Várólista hossza
-config.deliver_timeout=Kézbesítési időtúllépés
-config.skip_tls_verify=TLS ellenőrzése mellőzése
-
-config.mailer_config=Levelező beállítások
-config.mailer_enabled=Engedélyezett
-config.mailer_disable_helo=HELO letiltása
-config.mailer_subject_prefix=Tárgy előtag
-config.mailer_host=Állomás
-config.mailer_user=Felhasználó
-config.send_test_mail=Teszt E-mail küldése
-config.test_mail_failed=Nem sikerült kiküldeni az e-mailt '%s': %v
-config.test_mail_sent=Teszt e-mail kiküldve '%s'.
-
-config.oauth_config=OAuth-konfiguráció
-config.oauth_enabled=Engedélyezett
+config.session_config=Munkamenet beállítások
+config.session.provider=Provider
+config.session.provider_config=Provider config
+config.session.cookie_name=Cookie
+config.session.https_only=HTTPS only
+config.session.gc_interval=GC interval
+config.session.max_life_time=Max life time
+config.session.csrf_cookie_name=CSRF cookie
 
 config.cache_config=Cache beállítás
-config.cache_adapter=Gyorsítótár-adapter
-config.cache_interval=Gyorsítótár intervallum
-config.cache_conn=Cache kapcsolat
+config.cache.adapter=Adapter
+config.cache.interval=GC interval
+config.cache.host=Host
 
-config.session_config=Munkamenet beállítások
-config.session_provider=Munkamenet szolgáltató
-config.provider_config=Szolgáltató beállítás
-config.cookie_name=Süti neve
-config.enable_set_cookie=Süti használatának engedélyezése
-config.gc_interval_time=GC intervallum idő
-config.session_life_time=Munkamenet élettartama
-config.https_only=Csak HTTPS
-config.cookie_life_time=Cookie-k élettartama
+config.http_config=HTTP beállítások
+config.http.access_control_allow_origin=Access control allow origin
+
+config.attachment_config=Attachment configuration
+config.attachment.enabled=Enabled
+config.attachment.path=Path
+config.attachment.allowed_types=Allowed types
+config.attachment.max_size=Size limit
+config.attachment.max_files=Files limit
+
+config.release_config=Release configuration
+config.release.attachment.enabled=Attachment enabled
+config.release.attachment.allowed_types=Attachment allowed types
+config.release.attachment.max_size=Attachment size limit
+config.release.attachment.max_files=Attachment files limit
 
 config.picture_config=Kép beállítások
-config.picture_service=Kép szolgáltatás
-config.disable_gravatar=Tiltsa le a Gravatart
-config.enable_federated_avatar=Összevont profilkép lekérés engedélyezése
+config.picture.avatar_upload_path=User avatar upload path
+config.picture.repo_avatar_upload_path=Repository avatar upload path
+config.picture.gravatar_source=Gravatar source
+config.picture.disable_gravatar=Disable Gravatar
+config.picture.enable_federated_avatar=Enable federated avatars
+
+config.mirror_config=Mirror configuration
+config.mirror.default_interval=Default interval
+
+config.webhook_config=Webhook beállítás
+config.webhook.types=Types
+config.webhook.deliver_timeout=Deliver timeout
+config.webhook.skip_tls_verify=Skip TLS verify
 
 config.git_config=Git konfiguráció
-config.git_disable_diff_highlight=Különbségi nézetben a szintakszis kiemelés kikapcsolása
-config.git_max_diff_lines=Maximális sorok száma különbségi nézetben (egy fájl esetén)
-config.git_max_diff_line_characters=Maximális karakterek száma különbségi nézetben (egy fájl esetén)
-config.git_max_diff_files=Maximális fájlok száma különbségi nézetben
-config.git_gc_args=Szemétgyűjtő (GC) argumentumok
-config.git_migrate_timeout=Migráció időtúllépés
-config.git_mirror_timeout=Tükör frissítési időtúllépés
-config.git_clone_timeout=Migráció időtúllépés
-config.git_pull_timeout=Frissítő időtúllépés
-config.git_gc_timeout=Szemétgyűjtő (GC) időtúllépés
+config.git.disable_diff_highlight=Disable diff syntax highlight
+config.git.max_diff_lines=Diff lines limit (for a single file)
+config.git.max_diff_line_characters=Diff characters limit (for a single line)
+config.git.max_diff_files=Diff files limit (for a single diff)
+config.git.gc_args=GC arguments
+config.git.migrate_timeout=Migration timeout
+config.git.mirror_timeout=Mirror fetch timeout
+config.git.clone_timeout=Clone timeout
+config.git.pull_timeout=Pull timeout
+config.git.gc_timeout=GC timeout
 
 config.log_config=Naplózás beállítása
+config.log_file_root_path=Naplófájl gyökérútvonal
 config.log_mode=Mód
 config.log_options=Opciók
 
@@ -1338,6 +1397,7 @@ months=%d hónapja %s
 years=%d éve %s
 raw_seconds=másodperc
 raw_minutes=perc
+raw_hours=hours
 
 [dropzone]
 default_message=Húzz ide fájlokat vagy kattints a feltöltéshez.

+ 157 - 97
conf/locale/locale_id-ID.ini

@@ -9,7 +9,6 @@ sign_out=Keluar
 sign_up=Daftar
 register=Daftar
 website=Situs web
-version=Versi
 page=Halaman
 template=Templat
 language=Bahasa
@@ -122,6 +121,7 @@ run_user_not_match=Pengguna yang sedang menjalankan bukanlah pengguna saat ini:
 smtp_host_missing_port=Alamat Host SMTP hilang di alamat.
 invalid_smtp_from=SMTP Dari lapangan tidak sesuai: %v
 save_config_failed=Gagal untuk menyimpan konfigurasi: %v
+init_failed=Failed to initialize application: %v
 invalid_admin_setting=Pengaturan akun admin tidak valid: %v
 install_success=Selamat datang! Kami senang bahwa Anda memilih Gogs, bersenang-senang dan berhati-hatilah.
 invalid_log_root_path=Path akar log tidak valid: %v
@@ -1001,6 +1001,12 @@ first_page=Pertama
 last_page=Terakhir
 total=Total: %d
 
+dashboard.build_info=Build Information
+dashboard.app_ver=Application version
+dashboard.git_version=Git version
+dashboard.go_version=Go version
+dashboard.build_time=Build time
+dashboard.build_commit=Build commit
 dashboard.statistic=Statistik
 dashboard.operations=Operasi
 dashboard.system_status=Status Monitor Sistem
@@ -1156,117 +1162,170 @@ auths.github_api_endpoint=API Endpoint
 
 config.not_set=(tidak diterapkan)
 config.server_config=Konfigurasi Server
-config.app_name=Nama aplikasi
-config.app_ver=Versi aplikasi
-config.app_url=Aplikasi URL
-config.domain=Domain
-config.offline_mode=Mode Luring
-config.disable_router_log=Nonaktifkan Log Perute
+config.brand_name=Brand name
 config.run_user=Menjalankan penggunaa
-config.run_mode=Run Mode
-config.git_version=Versi Git
-config.static_file_root_path=Static File Root Path
-config.log_file_root_path=Log File Root Path
-config.reverse_auth_user=Mengembalikan Pengguna Autentikasi
+config.run_mode=Run mode
+config.server.external_url=External URL
+config.server.domain=Domain
+config.server.protocol=Protocol
+config.server.http_addr=HTTP address
+config.server.http_port=HTTP port
+config.server.cert_file=Certificate file
+config.server.key_file=Key file
+config.server.tls_min_version=Minimum TLS version
+config.server.unix_socket_permission=Unix socket permission
+config.server.local_root_url=Local root URL
+config.server.offline_mode=Offline mode
+config.server.disable_router_log=Disable router log
+config.server.enable_gzip=Enable Gzip
+config.server.app_data_path=Application data path
+config.server.load_assets_from_disk=Load assets from disk
+config.server.landing_url=Landing URL
 
 config.ssh_config=Konfigurasi SSH
-config.ssh_enabled=Diaktifkan
-config.ssh_start_builtin_server=Start Builtin Server
-config.ssh_domain=Domain
-config.ssh_port=Pelabuhan
-config.ssh_listen_port=Listen Port
-config.ssh_root_path=Path akar
-config.ssh_rewrite_authorized_keys_at_start=Tulis ulang authorized_keys Saat Memulai
-config.ssh_key_test_path=Key Test Path
-config.ssh_keygen_path=Jalur ('ssh-keygen') Generator Kunci
-config.ssh_minimum_key_size_check=Periksa Ukuran Kunci Minimum
-config.ssh_minimum_key_sizes=Ukuran Kunci Minimum
+config.ssh.enabled=Enabled
+config.ssh.domain=Exposed domain
+config.ssh.port=Exposed port
+config.ssh.root_path=Root path
+config.ssh.keygen_path=Keygen path
+config.ssh.key_test_path=Key test path
+config.ssh.minimum_key_size_check=Minimum key size check
+config.ssh.minimum_key_sizes=Minimum key sizes
+config.ssh.rewrite_authorized_keys_at_start=Rewrite "authorized_keys" at start
+config.ssh.start_builtin_server=Start builtin server
+config.ssh.listen_host=Listen host
+config.ssh.listen_port=Listen port
+config.ssh.server_ciphers=Server ciphers
 
 config.repo_config=Konfigurasi Repositori
-config.repo_root_path=Jalur Akar Repositori
-config.script_type=Jenis Skrip
-config.repo_force_private=Paksa Pribadi
-config.max_creation_limit=Max Creation Limit
-config.preferred_licenses=Lisensi yang Diutamakan
-config.disable_http_git=Nonaktifkan HTTP Git
-config.enable_local_path_migration=Aktifkan Migrasi Jalur Lokal
-config.commits_fetch_concurrency=Komitmen Ambil Concurrency
-
-config.http_config=Konfigurasi HTTP
-config.http_access_control_allow_origin=Kontrol Akses Memungkinkan Asal
+config.repo.root_path=Root path
+config.repo.script_type=Script type
+config.repo.ansi_chatset=ANSI charset
+config.repo.force_private=Force private
+config.repo.max_creation_limit=Max creation limit
+config.repo.preferred_licenses=Preferred licenses
+config.repo.disable_http_git=Disable HTTP Git
+config.repo.enable_local_path_migration=Enable local path migration
+config.repo.enable_raw_file_render_mode=Enable raw file render mode
+config.repo.commits_fetch_concurrency=Commits fetch concurrency
+config.repo.editor.line_wrap_extensions=Editor line wrap extensions
+config.repo.editor.previewable_file_modes=Editor previewable file modes
+config.repo.upload.enabled=Upload enabled
+config.repo.upload.temp_path=Upload temporary path
+config.repo.upload.allowed_types=Upload allowed types
+config.repo.upload.file_max_size=Upload file size limit
+config.repo.upload.max_files=Upload files limit
 
 config.db_config=Konfigurasi Basis Data
-config.db_type=Mengetik
-config.db_host=Rumah
-config.db_name=Nama
-config.db_user=Pengguna
-config.db_ssl_mode=Mode SSL
-config.db_ssl_mode_helper=(untuk "postgres" saja)
-config.db_path=Jalan
-config.db_path_helper=(untuk "sqlite3" dan "tidb")
-
-config.service_config=Konfigurasi Layanan
-config.register_email_confirm=Perlu konfirmasi email
-config.disable_register=Nonaktifkan Pendaftaran
-config.show_registration_button=Tampilkan Tombol Register
-config.require_sign_in_view=Memerlukan Tampilan Masuk
-config.mail_notify=Pemberitahuan Mail
-config.disable_key_size_check=Nonaktifkan Minimum Key Size Check
-config.enable_captcha=Aktifkan Captcha
-config.active_code_lives=Kode aktif hidup
-config.reset_password_code_lives=Reset Password Code Lives
+config.db.type=Type
+config.db.host=Host
+config.db.name=Name
+config.db.user=User
+config.db.ssl_mode=SSL mode
+config.db.ssl_mode_helper=(for "postgres" only)
+config.db.path=Path
+config.db.path_helper=(for "sqlite3"only)
+
+config.security_config=Security configuration
+config.security.login_remember_days=Login remember days
+config.security.cookie_remember_name=Remember cookie
+config.security.cookie_username=Username cookie
+config.security.cookie_secure=Enable secure cookie
+config.security.reverse_proxy_auth_user=Reverse proxy authentication header
+config.security.enable_login_status_cookie=Enable login status cookie
+config.security.login_status_cookie_name=Login status cookie
+
+config.email_config=Email configuration
+config.email.enabled=Enabled
+config.email.subject_prefix=Subject prefix
+config.email.host=Host
+config.email.from=From
+config.email.user=User
+config.email.disable_helo=Disable HELO
+config.email.helo_hostname=HELO hostname
+config.email.skip_verify=Skip certificate verify
+config.email.use_certificate=Use custom certificate
+config.email.cert_file=Certificate file
+config.email.key_file=Key file
+config.email.use_plain_text=Use plain text
+config.email.add_plain_text_alt=Add plain text alternative
+config.email.send_test_mail=Send test email
+config.email.test_mail_failed=Failed to send test email to '%s': %v
+config.email.test_mail_sent=Test email has been sent to '%s'.
+
+config.auth_config=Authentication configuration
+config.auth.activate_code_lives=Activate code lives
+config.auth.reset_password_code_lives=Reset password code lives
+config.auth.require_email_confirm=Require email confirmation
+config.auth.require_sign_in_view=Require sign in view
+config.auth.disable_registration=Disable registration
+config.auth.enable_registration_captcha=Enable registration captcha
+config.auth.enable_reverse_proxy_authentication=Enable reverse proxy authentication
+config.auth.enable_reverse_proxy_auto_registration=Enable reverse proxy auto registration
+config.auth.reverse_proxy_authentication_header=Reverse proxy authentication header
+
+config.user_config=User configuration
+config.user.enable_email_notify=Enable email notification
 
-config.webhook_config=Webhook Konfigurasi
-config.queue_length=Panjang Antrian
-config.deliver_timeout=Berikan waktu habis
-config.skip_tls_verify=Lewati TLS Verifikasi
-
-config.mailer_config=Mailer Konfigurasi
-config.mailer_enabled=Diaktifkan
-config.mailer_disable_helo=Nonaktifkan HALO
-config.mailer_subject_prefix=Subyek Awalan
-config.mailer_host=Rumah
-config.mailer_user=Pengguna
-config.send_test_mail=Kirim Email Uji
-config.test_mail_failed=Gagal mengirim email uji ke '%s': %v
-config.test_mail_sent=Email percobaan telah dikirim ke ' % s '.
-
-config.oauth_config=OAuth Konfigurasi
-config.oauth_enabled=Diaktifkan
+config.session_config=Konfigurasi Sesi
+config.session.provider=Provider
+config.session.provider_config=Provider config
+config.session.cookie_name=Cookie
+config.session.https_only=HTTPS only
+config.session.gc_interval=GC interval
+config.session.max_life_time=Max life time
+config.session.csrf_cookie_name=CSRF cookie
 
 config.cache_config=Konfigurasi Cache
-config.cache_adapter=Adaptor Cache
-config.cache_interval=Interval Cache
-config.cache_conn=Koneksi Cache
+config.cache.adapter=Adapter
+config.cache.interval=GC interval
+config.cache.host=Host
 
-config.session_config=Konfigurasi Sesi
-config.session_provider=Penyedia Sesi
-config.provider_config=Konfigurasi Penyedia
-config.cookie_name=Nama Kuki
-config.enable_set_cookie=Aktifkan Pengatur Kuki
-config.gc_interval_time=Waktu Interval GC
-config.session_life_time=Sesi jangka Waktu
-config.https_only=Hanya HTTPS
-config.cookie_life_time=Jangka Waktu Kuki
+config.http_config=Konfigurasi HTTP
+config.http.access_control_allow_origin=Access control allow origin
+
+config.attachment_config=Attachment configuration
+config.attachment.enabled=Enabled
+config.attachment.path=Path
+config.attachment.allowed_types=Allowed types
+config.attachment.max_size=Size limit
+config.attachment.max_files=Files limit
+
+config.release_config=Release configuration
+config.release.attachment.enabled=Attachment enabled
+config.release.attachment.allowed_types=Attachment allowed types
+config.release.attachment.max_size=Attachment size limit
+config.release.attachment.max_files=Attachment files limit
 
 config.picture_config=Konfigurasi Gambar
-config.picture_service=Gambar layanan
-config.disable_gravatar=Nonaktifkan Gravatar
-config.enable_federated_avatar=Aktifkan Avatar Gabungan
+config.picture.avatar_upload_path=User avatar upload path
+config.picture.repo_avatar_upload_path=Repository avatar upload path
+config.picture.gravatar_source=Gravatar source
+config.picture.disable_gravatar=Disable Gravatar
+config.picture.enable_federated_avatar=Enable federated avatars
+
+config.mirror_config=Mirror configuration
+config.mirror.default_interval=Default interval
+
+config.webhook_config=Webhook Konfigurasi
+config.webhook.types=Types
+config.webhook.deliver_timeout=Deliver timeout
+config.webhook.skip_tls_verify=Skip TLS verify
 
 config.git_config=Konfigurasi Git
-config.git_disable_diff_highlight=Nonaktifkan Diff Syntax Highlight
-config.git_max_diff_lines=Garis Maksimal Diff (untuk berkas tunggal)
-config.git_max_diff_line_characters=Karakter Maksimal Diff (untuk garis tunggal)
-config.git_max_diff_files=Berkas Maksimal Diff (untuk ditampilkan)
-config.git_gc_args=Argumen GC
-config.git_migrate_timeout=Jenis migrasi
-config.git_mirror_timeout=Mirror Update Timeout
-config.git_clone_timeout=Waktu Kloning Habis
-config.git_pull_timeout=Pull Operation Timeout
-config.git_gc_timeout=GC Operation Timeout
-
-config.log_config=Log Configuration
+config.git.disable_diff_highlight=Disable diff syntax highlight
+config.git.max_diff_lines=Diff lines limit (for a single file)
+config.git.max_diff_line_characters=Diff characters limit (for a single line)
+config.git.max_diff_files=Diff files limit (for a single diff)
+config.git.gc_args=GC arguments
+config.git.migrate_timeout=Migration timeout
+config.git.mirror_timeout=Mirror fetch timeout
+config.git.clone_timeout=Clone timeout
+config.git.pull_timeout=Pull timeout
+config.git.gc_timeout=GC timeout
+
+config.log_config=Log configuration
+config.log_file_root_path=Log file root path
 config.log_mode=Mode
 config.log_options=Pilihan
 
@@ -1338,6 +1397,7 @@ months=%d bulan %s
 years=%d tahun %s
 raw_seconds=detik
 raw_minutes=menit
+raw_hours=hours
 
 [dropzone]
 default_message=Jatuhkan berkas disini atau klik untuk mengunggah.

+ 154 - 94
conf/locale/locale_it-IT.ini

@@ -9,7 +9,6 @@ sign_out=Esci
 sign_up=Registrati
 register=Registrati
 website=Sito Web
-version=Versione
 page=Pagina
 template=Template
 language=Lingua
@@ -122,6 +121,7 @@ run_user_not_match=Run user non è l'utente corrente:  %s -> %s
 smtp_host_missing_port=All'Host SMTP manca la porta nell'indirizzo.
 invalid_smtp_from=Campo SMTP From non valido: %v
 save_config_failed=Fallito il salvataggio della configurazione: %v
+init_failed=Failed to initialize application: %v
 invalid_admin_setting=Impostazioni account Admin non valide: %v
 install_success=Benvenuto! Siamo felici che tu abbia scelto GIN, buon divertimento.
 invalid_log_root_path=Percorso deilog non valido: %v
@@ -1001,6 +1001,12 @@ first_page=Prima
 last_page=Ultima
 total=Totale: %d
 
+dashboard.build_info=Build Information
+dashboard.app_ver=Application version
+dashboard.git_version=Git version
+dashboard.go_version=Go version
+dashboard.build_time=Build time
+dashboard.build_commit=Build commit
 dashboard.statistic=Statistiche
 dashboard.operations=Operazioni
 dashboard.system_status=Stato del Monitor di Sistema
@@ -1156,117 +1162,170 @@ auths.github_api_endpoint=API Endpoint
 
 config.not_set=(non impostata)
 config.server_config=Configurazione Server
-config.app_name=Nome Applicazione
-config.app_ver=Versione Applicazione
-config.app_url=URL Applicazione
-config.domain=Dominio
-config.offline_mode=Modalità Offline
-config.disable_router_log=Disattivare Log del Router
+config.brand_name=Brand name
 config.run_user=Utente Esecutore
 config.run_mode=Modalità Esecuzione
-config.git_version=Versione Git
-config.static_file_root_path=Percorso Root del File Statico
-config.log_file_root_path=Percorso Root del File di Log
-config.reverse_auth_user=Autenticazione Utente Inversa
+config.server.external_url=External URL
+config.server.domain=Domain
+config.server.protocol=Protocol
+config.server.http_addr=HTTP address
+config.server.http_port=HTTP port
+config.server.cert_file=Certificate file
+config.server.key_file=Key file
+config.server.tls_min_version=Minimum TLS version
+config.server.unix_socket_permission=Unix socket permission
+config.server.local_root_url=Local root URL
+config.server.offline_mode=Offline mode
+config.server.disable_router_log=Disable router log
+config.server.enable_gzip=Enable Gzip
+config.server.app_data_path=Application data path
+config.server.load_assets_from_disk=Load assets from disk
+config.server.landing_url=Landing URL
 
 config.ssh_config=Configurazione SSH
-config.ssh_enabled=Attivo
-config.ssh_start_builtin_server=Avvia server builtin
-config.ssh_domain=Dominio
-config.ssh_port=Porta
-config.ssh_listen_port=Porta in ascolto
-config.ssh_root_path=Percorso Root
-config.ssh_rewrite_authorized_keys_at_start=Rewrite authorized_keys At Start
-config.ssh_key_test_path=Percorso chiave di test
-config.ssh_keygen_path=Percorso Keygen ('ssh-keygen')
-config.ssh_minimum_key_size_check=Verifica delle dimensioni minime della chiave
-config.ssh_minimum_key_sizes=Dimensioni minime della chiave
+config.ssh.enabled=Enabled
+config.ssh.domain=Exposed domain
+config.ssh.port=Exposed port
+config.ssh.root_path=Root path
+config.ssh.keygen_path=Keygen path
+config.ssh.key_test_path=Key test path
+config.ssh.minimum_key_size_check=Minimum key size check
+config.ssh.minimum_key_sizes=Minimum key sizes
+config.ssh.rewrite_authorized_keys_at_start=Rewrite "authorized_keys" at start
+config.ssh.start_builtin_server=Start builtin server
+config.ssh.listen_host=Listen host
+config.ssh.listen_port=Listen port
+config.ssh.server_ciphers=Server ciphers
 
 config.repo_config=Configurazione Repository
-config.repo_root_path=Percorso Root del Repository
-config.script_type=Tipo di Script
-config.repo_force_private=Force Private
-config.max_creation_limit=Max Creation Limit
-config.preferred_licenses=Preferred Licenses
-config.disable_http_git=Disabilita Git in HTTP
-config.enable_local_path_migration=Abilita migrazioni con path locale
-config.commits_fetch_concurrency=Commits Fetch Concurrency
-
-config.http_config=Configurazione HTTP
-config.http_access_control_allow_origin=Access Control Allow Origin
+config.repo.root_path=Root path
+config.repo.script_type=Script type
+config.repo.ansi_chatset=ANSI charset
+config.repo.force_private=Force private
+config.repo.max_creation_limit=Max creation limit
+config.repo.preferred_licenses=Preferred licenses
+config.repo.disable_http_git=Disable HTTP Git
+config.repo.enable_local_path_migration=Enable local path migration
+config.repo.enable_raw_file_render_mode=Enable raw file render mode
+config.repo.commits_fetch_concurrency=Commits fetch concurrency
+config.repo.editor.line_wrap_extensions=Editor line wrap extensions
+config.repo.editor.previewable_file_modes=Editor previewable file modes
+config.repo.upload.enabled=Upload enabled
+config.repo.upload.temp_path=Upload temporary path
+config.repo.upload.allowed_types=Upload allowed types
+config.repo.upload.file_max_size=Upload file size limit
+config.repo.upload.max_files=Upload files limit
 
 config.db_config=Configurazione Database
-config.db_type=Tipo
-config.db_host=Host
-config.db_name=Nome
-config.db_user=Utente
-config.db_ssl_mode=Modalità SSL
-config.db_ssl_mode_helper=(solo per "postgres")
-config.db_path=Percorso
-config.db_path_helper=(per "sqlite3" e "tidb")
-
-config.service_config=Configurazione Servizio
-config.register_email_confirm=Richiedono Conferma dell'Email
-config.disable_register=Disabilita Registrazione
-config.show_registration_button=Mostra Pulsante Registrazione
-config.require_sign_in_view=Richiesto Accesso per Vedere
-config.mail_notify=Email di Notifica
-config.disable_key_size_check=Disabilita controllo sulle dimensioni minime della chiave
-config.enable_captcha=Abilita Captcha
-config.active_code_lives=Attiva Vita del Codice
-config.reset_password_code_lives=Reimpostare Password della Vita del Codice
+config.db.type=Type
+config.db.host=Host
+config.db.name=Name
+config.db.user=User
+config.db.ssl_mode=SSL mode
+config.db.ssl_mode_helper=(for "postgres" only)
+config.db.path=Path
+config.db.path_helper=(for "sqlite3"only)
+
+config.security_config=Security configuration
+config.security.login_remember_days=Login remember days
+config.security.cookie_remember_name=Remember cookie
+config.security.cookie_username=Username cookie
+config.security.cookie_secure=Enable secure cookie
+config.security.reverse_proxy_auth_user=Reverse proxy authentication header
+config.security.enable_login_status_cookie=Enable login status cookie
+config.security.login_status_cookie_name=Login status cookie
+
+config.email_config=Email configuration
+config.email.enabled=Enabled
+config.email.subject_prefix=Subject prefix
+config.email.host=Host
+config.email.from=From
+config.email.user=User
+config.email.disable_helo=Disable HELO
+config.email.helo_hostname=HELO hostname
+config.email.skip_verify=Skip certificate verify
+config.email.use_certificate=Use custom certificate
+config.email.cert_file=Certificate file
+config.email.key_file=Key file
+config.email.use_plain_text=Use plain text
+config.email.add_plain_text_alt=Add plain text alternative
+config.email.send_test_mail=Send test email
+config.email.test_mail_failed=Failed to send test email to '%s': %v
+config.email.test_mail_sent=Test email has been sent to '%s'.
+
+config.auth_config=Authentication configuration
+config.auth.activate_code_lives=Activate code lives
+config.auth.reset_password_code_lives=Reset password code lives
+config.auth.require_email_confirm=Require email confirmation
+config.auth.require_sign_in_view=Require sign in view
+config.auth.disable_registration=Disable registration
+config.auth.enable_registration_captcha=Enable registration captcha
+config.auth.enable_reverse_proxy_authentication=Enable reverse proxy authentication
+config.auth.enable_reverse_proxy_auto_registration=Enable reverse proxy auto registration
+config.auth.reverse_proxy_authentication_header=Reverse proxy authentication header
+
+config.user_config=User configuration
+config.user.enable_email_notify=Enable email notification
 
-config.webhook_config=Configurazione Webhook
-config.queue_length=Lunghezza della coda
-config.deliver_timeout=Tempo Limite di Consegna
-config.skip_tls_verify=Salta verifiche TLS
-
-config.mailer_config=Configurazione Mailer
-config.mailer_enabled=Attivo
-config.mailer_disable_helo=Disattiva HELO
-config.mailer_subject_prefix=Subject Prefix
-config.mailer_host=Host
-config.mailer_user=Utente
-config.send_test_mail=Invia email di test
-config.test_mail_failed=Impossibile inviare mail a '%s': %v
-config.test_mail_sent=Una mail di prova è stata inviata a '%s'.
-
-config.oauth_config=Configurazione OAuth
-config.oauth_enabled=Attivo
+config.session_config=Configurazione Sessione
+config.session.provider=Provider
+config.session.provider_config=Provider config
+config.session.cookie_name=Cookie
+config.session.https_only=HTTPS only
+config.session.gc_interval=GC interval
+config.session.max_life_time=Max life time
+config.session.csrf_cookie_name=CSRF cookie
 
 config.cache_config=Configurazione Cache
-config.cache_adapter=Adattatore Cache
-config.cache_interval=Intervallo Cache
-config.cache_conn=Connessione Cache
+config.cache.adapter=Adapter
+config.cache.interval=GC interval
+config.cache.host=Host
 
-config.session_config=Configurazione Sessione
-config.session_provider=Fornitore Sessione
-config.provider_config=Impostazioni Provider
-config.cookie_name=Nome del Cookie
-config.enable_set_cookie=Abilita Uso dei Cookie
-config.gc_interval_time=Intervallo di tempo della GC
-config.session_life_time=Durata Sessione
-config.https_only=Solo HTTPS
-config.cookie_life_time=Durata Cookie
+config.http_config=Configurazione HTTP
+config.http.access_control_allow_origin=Access control allow origin
+
+config.attachment_config=Attachment configuration
+config.attachment.enabled=Enabled
+config.attachment.path=Path
+config.attachment.allowed_types=Allowed types
+config.attachment.max_size=Size limit
+config.attachment.max_files=Files limit
+
+config.release_config=Release configuration
+config.release.attachment.enabled=Attachment enabled
+config.release.attachment.allowed_types=Attachment allowed types
+config.release.attachment.max_size=Attachment size limit
+config.release.attachment.max_files=Attachment files limit
 
 config.picture_config=Configurazione Foto
-config.picture_service=Servizio foto
-config.disable_gravatar=Disabilita Gravatar
-config.enable_federated_avatar=Attiva Federated Avatars
+config.picture.avatar_upload_path=User avatar upload path
+config.picture.repo_avatar_upload_path=Repository avatar upload path
+config.picture.gravatar_source=Gravatar source
+config.picture.disable_gravatar=Disable Gravatar
+config.picture.enable_federated_avatar=Enable federated avatars
+
+config.mirror_config=Mirror configuration
+config.mirror.default_interval=Default interval
+
+config.webhook_config=Configurazione Webhook
+config.webhook.types=Types
+config.webhook.deliver_timeout=Deliver timeout
+config.webhook.skip_tls_verify=Skip TLS verify
 
 config.git_config=Configurazione Git
-config.git_disable_diff_highlight=Disattiva evidenziazione delle differenze
-config.git_max_diff_lines=Numero massimo di righe di diff (per singolo file)
-config.git_max_diff_line_characters=Numero massimo di caratteri di diff (per singola riga)
-config.git_max_diff_files=Numero massimo di file diff mostrati
-config.git_gc_args=Parametri GC
-config.git_migrate_timeout=Timeout per la migrazione
-config.git_mirror_timeout=Timeoute per l'aggiornamento del mirror
-config.git_clone_timeout=Timeout per il clone
-config.git_pull_timeout=Timeout per il pull
-config.git_gc_timeout=Timeout per le operazioni di GC
+config.git.disable_diff_highlight=Disable diff syntax highlight
+config.git.max_diff_lines=Diff lines limit (for a single file)
+config.git.max_diff_line_characters=Diff characters limit (for a single line)
+config.git.max_diff_files=Diff files limit (for a single diff)
+config.git.gc_args=GC arguments
+config.git.migrate_timeout=Migration timeout
+config.git.mirror_timeout=Mirror fetch timeout
+config.git.clone_timeout=Clone timeout
+config.git.pull_timeout=Pull timeout
+config.git.gc_timeout=GC timeout
 
 config.log_config=Configurazione Log
+config.log_file_root_path=Percorso Root del File di Log
 config.log_mode=Modalità
 config.log_options=Opzioni
 
@@ -1338,6 +1397,7 @@ months=%d mesi %s
 years=%d anni %s
 raw_seconds=secondi
 raw_minutes=minuti
+raw_hours=hours
 
 [dropzone]
 default_message=Trascina i file qui o clicca per caricare.

+ 154 - 94
conf/locale/locale_ja-JP.ini

@@ -9,7 +9,6 @@ sign_out=サインアウト
 sign_up=サインアップ
 register=登録
 website=WEBサイト
-version=バージョン
 page=ページ
 template=テンプレート
 language=言語
@@ -122,6 +121,7 @@ run_user_not_match=実行ユーザーは現在のユーザーではありませ
 smtp_host_missing_port=SMTPホストのポートが見つかりません。
 invalid_smtp_from=SMTP From フィールドの値が有効ではありません: %v
 save_config_failed=構成の保存に失敗した: %v
+init_failed=Failed to initialize application: %v
 invalid_admin_setting=管理者アカウントの設定が無効です: %v
 install_success=ようこそ!我々はあなたが GIN を選んでくれて嬉しいです!楽しみましょう!
 invalid_log_root_path=リポジトリのルート パスが無効です: %v
@@ -1001,6 +1001,12 @@ first_page=First
 last_page=Last
 total=合計: %d
 
+dashboard.build_info=Build Information
+dashboard.app_ver=Application version
+dashboard.git_version=Git version
+dashboard.go_version=Go version
+dashboard.build_time=Build time
+dashboard.build_commit=Build commit
 dashboard.statistic=統計
 dashboard.operations=操作
 dashboard.system_status=システム モニターのステータス
@@ -1156,117 +1162,170 @@ auths.github_api_endpoint=APIエンドポイント
 
 config.not_set=(未設定)
 config.server_config=サーバーの構成
-config.app_name=アプリケーション名
-config.app_ver=アプリケーションのバージョン
-config.app_url=アプリケーションの URL
-config.domain=ドメイン
-config.offline_mode=オフラインモード
-config.disable_router_log=ルーターのログを無効にする
+config.brand_name=Brand name
 config.run_user=実行ユーザー
 config.run_mode=実行モード
-config.git_version=Git バージョン
-config.static_file_root_path=静的ファイルのルートパス
-config.log_file_root_path=ログファイルのルートパス
-config.reverse_auth_user=リバース認証ユーザー
+config.server.external_url=External URL
+config.server.domain=Domain
+config.server.protocol=Protocol
+config.server.http_addr=HTTP address
+config.server.http_port=HTTP port
+config.server.cert_file=Certificate file
+config.server.key_file=Key file
+config.server.tls_min_version=Minimum TLS version
+config.server.unix_socket_permission=Unix socket permission
+config.server.local_root_url=Local root URL
+config.server.offline_mode=Offline mode
+config.server.disable_router_log=Disable router log
+config.server.enable_gzip=Enable Gzip
+config.server.app_data_path=Application data path
+config.server.load_assets_from_disk=Load assets from disk
+config.server.landing_url=Landing URL
 
 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_rewrite_authorized_keys_at_start=書き換え authorized_keys 開始
-config.ssh_key_test_path=キーテストパス
-config.ssh_keygen_path=鍵生成コマンド ('ssh-keygen') のパス
-config.ssh_minimum_key_size_check=最小キーサイズチェック
-config.ssh_minimum_key_sizes=最小キーサイズ
+config.ssh.enabled=Enabled
+config.ssh.domain=Exposed domain
+config.ssh.port=Exposed port
+config.ssh.root_path=Root path
+config.ssh.keygen_path=Keygen path
+config.ssh.key_test_path=Key test path
+config.ssh.minimum_key_size_check=Minimum key size check
+config.ssh.minimum_key_sizes=Minimum key sizes
+config.ssh.rewrite_authorized_keys_at_start=Rewrite "authorized_keys" at start
+config.ssh.start_builtin_server=Start builtin server
+config.ssh.listen_host=Listen host
+config.ssh.listen_port=Listen port
+config.ssh.server_ciphers=Server ciphers
 
 config.repo_config=リポジトリの設定
-config.repo_root_path=リポジトリのルートパス
-config.script_type=スクリプトの種類
-config.repo_force_private=非公開リポジトリの強制
-config.max_creation_limit=最大作成数
-config.preferred_licenses=優先ライセンス
-config.disable_http_git=HTTP Git の無効化
-config.enable_local_path_migration=ローカルパス移行の有効化
-config.commits_fetch_concurrency=コミットのフェッチの並行数
-
-config.http_config=HTTP の設定
-config.http_access_control_allow_origin=Access Control Allow Origin
+config.repo.root_path=Root path
+config.repo.script_type=Script type
+config.repo.ansi_chatset=ANSI charset
+config.repo.force_private=Force private
+config.repo.max_creation_limit=Max creation limit
+config.repo.preferred_licenses=Preferred licenses
+config.repo.disable_http_git=Disable HTTP Git
+config.repo.enable_local_path_migration=Enable local path migration
+config.repo.enable_raw_file_render_mode=Enable raw file render mode
+config.repo.commits_fetch_concurrency=Commits fetch concurrency
+config.repo.editor.line_wrap_extensions=Editor line wrap extensions
+config.repo.editor.previewable_file_modes=Editor previewable file modes
+config.repo.upload.enabled=Upload enabled
+config.repo.upload.temp_path=Upload temporary path
+config.repo.upload.allowed_types=Upload allowed types
+config.repo.upload.file_max_size=Upload file size limit
+config.repo.upload.max_files=Upload files limit
 
 config.db_config=データベース設定
-config.db_type=タイプ
-config.db_host=ホスト
-config.db_name=名前
-config.db_user=ユーザー
-config.db_ssl_mode=SSL モード
-config.db_ssl_mode_helper=(「postgres」のみ)
-config.db_path=パス
-config.db_path_helper=("sqlite3" および "tidb" の場合)
-
-config.service_config=サービスの設定
-config.register_email_confirm=電子メールの確認を必要
-config.disable_register=登録を無効にする
-config.show_registration_button=登録ボタンを表示
-config.require_sign_in_view=サインインを要求
-config.mail_notify=メール通知
-config.disable_key_size_check=最小キーサイズチェックを無効にする
-config.enable_captcha=Captchaを有効にする
-config.active_code_lives=コードリンクの有効期限をアクティブ
-config.reset_password_code_lives=パスワードリンクの有効期限をリセット
+config.db.type=Type
+config.db.host=Host
+config.db.name=Name
+config.db.user=User
+config.db.ssl_mode=SSL mode
+config.db.ssl_mode_helper=(for "postgres" only)
+config.db.path=Path
+config.db.path_helper=(for "sqlite3"only)
+
+config.security_config=Security configuration
+config.security.login_remember_days=Login remember days
+config.security.cookie_remember_name=Remember cookie
+config.security.cookie_username=Username cookie
+config.security.cookie_secure=Enable secure cookie
+config.security.reverse_proxy_auth_user=Reverse proxy authentication header
+config.security.enable_login_status_cookie=Enable login status cookie
+config.security.login_status_cookie_name=Login status cookie
+
+config.email_config=Email configuration
+config.email.enabled=Enabled
+config.email.subject_prefix=Subject prefix
+config.email.host=Host
+config.email.from=From
+config.email.user=User
+config.email.disable_helo=Disable HELO
+config.email.helo_hostname=HELO hostname
+config.email.skip_verify=Skip certificate verify
+config.email.use_certificate=Use custom certificate
+config.email.cert_file=Certificate file
+config.email.key_file=Key file
+config.email.use_plain_text=Use plain text
+config.email.add_plain_text_alt=Add plain text alternative
+config.email.send_test_mail=Send test email
+config.email.test_mail_failed=Failed to send test email to '%s': %v
+config.email.test_mail_sent=Test email has been sent to '%s'.
+
+config.auth_config=Authentication configuration
+config.auth.activate_code_lives=Activate code lives
+config.auth.reset_password_code_lives=Reset password code lives
+config.auth.require_email_confirm=Require email confirmation
+config.auth.require_sign_in_view=Require sign in view
+config.auth.disable_registration=Disable registration
+config.auth.enable_registration_captcha=Enable registration captcha
+config.auth.enable_reverse_proxy_authentication=Enable reverse proxy authentication
+config.auth.enable_reverse_proxy_auto_registration=Enable reverse proxy auto registration
+config.auth.reverse_proxy_authentication_header=Reverse proxy authentication header
+
+config.user_config=User configuration
+config.user.enable_email_notify=Enable email notification
 
-config.webhook_config=Webhook設定
-config.queue_length=キューの長さ
-config.deliver_timeout=送信タイムアウト
-config.skip_tls_verify=TLSの確認を省略
-
-config.mailer_config=メーラーの設定
-config.mailer_enabled=有効にした
-config.mailer_disable_helo=HELOコマンド無効
-config.mailer_subject_prefix=件名プレフィックス
-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.session_config=セッションの設定
+config.session.provider=Provider
+config.session.provider_config=Provider config
+config.session.cookie_name=Cookie
+config.session.https_only=HTTPS only
+config.session.gc_interval=GC interval
+config.session.max_life_time=Max life time
+config.session.csrf_cookie_name=CSRF cookie
 
 config.cache_config=キャッシュの設定
-config.cache_adapter=キャッシュ アダプター
-config.cache_interval=キャッシュ間隔
-config.cache_conn=キャッシュ接続
+config.cache.adapter=Adapter
+config.cache.interval=GC interval
+config.cache.host=Host
 
-config.session_config=セッションの設定
-config.session_provider=セッション プロバイダー
-config.provider_config=プロバイダーの構成
-config.cookie_name=クッキーの名前
-config.enable_set_cookie=クッキーの設定を有効にする
-config.gc_interval_time=GC 間隔
-config.session_life_time=セッションのライフタイム
-config.https_only=HTTPS のみ
-config.cookie_life_time=クッキーのライフタイム
+config.http_config=HTTP の設定
+config.http.access_control_allow_origin=Access control allow origin
+
+config.attachment_config=Attachment configuration
+config.attachment.enabled=Enabled
+config.attachment.path=Path
+config.attachment.allowed_types=Allowed types
+config.attachment.max_size=Size limit
+config.attachment.max_files=Files limit
+
+config.release_config=Release configuration
+config.release.attachment.enabled=Attachment enabled
+config.release.attachment.allowed_types=Attachment allowed types
+config.release.attachment.max_size=Attachment size limit
+config.release.attachment.max_files=Attachment files limit
 
 config.picture_config=画像の設定
-config.picture_service=画像サービス
-config.disable_gravatar=Gravatarを無効にする
-config.enable_federated_avatar=連合アバターを有効にする
+config.picture.avatar_upload_path=User avatar upload path
+config.picture.repo_avatar_upload_path=Repository avatar upload path
+config.picture.gravatar_source=Gravatar source
+config.picture.disable_gravatar=Disable Gravatar
+config.picture.enable_federated_avatar=Enable federated avatars
+
+config.mirror_config=Mirror configuration
+config.mirror.default_interval=Default interval
+
+config.webhook_config=Webhook設定
+config.webhook.types=Types
+config.webhook.deliver_timeout=Deliver timeout
+config.webhook.skip_tls_verify=Skip TLS verify
 
 config.git_config=Git 設定
-config.git_disable_diff_highlight=Diff のシンタックスハイライトを無効にする
-config.git_max_diff_lines=Diff の最大行数(1ファイルあたり)
-config.git_max_diff_line_characters=Diff の最大文字数(1行あたり)
-config.git_max_diff_files=Diff の最大ファイル数(表示)
-config.git_gc_args=GC の引数
-config.git_migrate_timeout=移行タイムアウト
-config.git_mirror_timeout=ミラー更新タイムアウト
-config.git_clone_timeout=Clone 操作のタイムアウト
-config.git_pull_timeout=Pull 操作のタイムアウト
-config.git_gc_timeout=GC 操作のタイムアウト
+config.git.disable_diff_highlight=Disable diff syntax highlight
+config.git.max_diff_lines=Diff lines limit (for a single file)
+config.git.max_diff_line_characters=Diff characters limit (for a single line)
+config.git.max_diff_files=Diff files limit (for a single diff)
+config.git.gc_args=GC arguments
+config.git.migrate_timeout=Migration timeout
+config.git.mirror_timeout=Mirror fetch timeout
+config.git.clone_timeout=Clone timeout
+config.git.pull_timeout=Pull timeout
+config.git.gc_timeout=GC timeout
 
 config.log_config=ログの設定
+config.log_file_root_path=ログファイルのルートパス
 config.log_mode=モード
 config.log_options=オプション
 
@@ -1338,6 +1397,7 @@ months=%d ヶ月 %s
 years=%d 年 %s
 raw_seconds=秒
 raw_minutes=分
+raw_hours=hours
 
 [dropzone]
 default_message=ここにファイルをドロップまたはクリックしてアップロードします。

+ 188 - 128
conf/locale/locale_ko-KR.ini

@@ -9,7 +9,6 @@ sign_out=로그아웃
 sign_up=가입하기
 register=가입하기
 website=웹 사이트
-version=버전
 page=페이지
 template=템플릿
 language=언어
@@ -122,6 +121,7 @@ run_user_not_match=실행 유저가 현재 유저가 아닙니다: %s -> %s
 smtp_host_missing_port=SMTP 호스트 포트가 주소에 없습니다.
 invalid_smtp_from=SMTP 보낸 사람 필드가 유효하지 않습니다: %v
 save_config_failed=설정을 저장할 수 없습니다: %v
+init_failed=프로그램을 초기화하는데 실패하였습니다: %v
 invalid_admin_setting=관리자 계정 설정이 잘못되었습니다: %v
 install_success=환영합니다! Gogs를 선택해 주셔서 감사합니다.
 invalid_log_root_path=로그 루트 경로가 올바르지 않습니다: %v
@@ -351,7 +351,7 @@ two_factor_or_enter_secret=또는 이 비밀키를 입력하세요:
 two_factor_then_enter_passcode=그리고 코드를 입력하세요:
 two_factor_verify=확인
 two_factor_invalid_passcode=입력한 코드가 올바르지 않습니다. 다시 시도해 주세요!
-two_factor_reused_passcode=The passcode you entered has already been used, please try another one!
+two_factor_reused_passcode=입력하신 비밀번호가 이미 사용되였습니.다른 비밀번호를 사용해보십시오!.
 two_factor_enable_error=2단계 인증 활성화 실패: %v
 two_factor_enable_success=2단계 인증이 성공적으로 활성화되었습니다!
 two_factor_recovery_codes_title=2단계 인증 복구 코드
@@ -374,7 +374,7 @@ delete_token=삭제
 access_token_deletion=개인 액세스 토큰 삭제
 access_token_deletion_desc=이 토큰을 사용하는 애플리케이션의 접근권한 또한 삭제됩니다. 계속 하시겠습니까?
 delete_token_success=액세스 토큰이 삭제되었습니다. 애플리케이션의 업데이트도 잊지 마세요.
-token_name_exists=Token with same name already exists.
+token_name_exists=같은 이름의 토큰이 이미 존재합니다.
 
 orgs.none=당신은 어떤 조직의 구성원도 아닙니다.
 orgs.leave_title=조직 떠나기
@@ -382,8 +382,8 @@ orgs.leave_desc=조직을 떠난 후에는 모든 리포지토리와 팀에 액
 
 repos.leave=나가기
 repos.leave_title=저장소 나가기
-repos.leave_desc=You will lose access to the repository after you left. Do you want to continue?
-repos.leave_success=You have left repository '%s' successfully!
+repos.leave_desc=이 페지를 떠나면 저장소에 액세스할수 없게 됩니다. 계속하시겠습니까?
+repos.leave_success=당신은 저장소  '%s' 에서 성공적으로 탈퇴하였습니다.!
 
 delete_account=계정 삭제
 delete_prompt=당신의 계정을 삭제합니다.  완료된 후에는 <strong>취소할 수 없습니다</strong>.
@@ -422,8 +422,8 @@ mirror_last_synced=마지막으로 동기화됨
 watchers=주시하고 있는 사람들
 stargazers=별을 준 사람들
 forks=포크
-repo_description_helper=Description of repository. Maximum 512 characters length.
-repo_description_length=Available characters
+repo_description_helper=저장소 설명.최대 512길이의 문자열이 가능합니다.
+repo_description_length=가능한 문자열입니다.
 
 form.reach_limit_of_creation=소유자가 저장소 만들기 최대 제한에 (%d개) 도달했습니다.
 form.name_reserved=저장소 이름 '%s'은 예약 되어 있습니다.
@@ -483,7 +483,7 @@ branches.overview=개요
 branches.active_branches=활성 브랜치
 branches.stale_branches=오래된 브랜치
 branches.all=모든 브랜치
-branches.updated_by=Updated %[1]s by %[2]s
+branches.updated_by=%[2]s이 %[1]s를 업데이트
 branches.change_default_branch=기본 브랜치 변경
 
 editor.new_file=파일 생성
@@ -521,7 +521,7 @@ editor.file_changed_while_editing=편집을 시작한 이후 파일 내용이 
 editor.file_already_exists=이 저장소에 이름이 '%s'인 파일이 이미 존재합니다.
 editor.no_changes_to_show=표시할 변경사항이 없습니다.
 editor.fail_to_update_file=파일 '%s'를 변경/추가 하는데 실패하였습니다. 에러: %v
-editor.fail_to_delete_file=Failed to delete file '%s' with error: %v
+editor.fail_to_delete_file=파일 '%s'를 삭제하는데 실패하였습니다. 오유: %v
 editor.add_subdir=하위 디렉토리 추가...
 editor.unable_to_upload_files=파일 '%s'를 업로드하는데 실패하였습니다. 에러: %v
 editor.upload_files_to_dir=파일 업로드 '%s'
@@ -624,7 +624,7 @@ pulls.compare_compare=비교
 pulls.filter_branch=Filter Branch
 pulls.no_results=결과 없음
 pulls.nothing_to_compare=Base 와 head 브랜치가 동일해서 비교할 게 없습니다.
-pulls.nothing_merge_base=There is nothing to compare because two branches have completely different history.
+pulls.nothing_merge_base=두 브런치의 리력이 완전히 다르므로 비교할수 없습니다.
 pulls.has_pull_request=`이 두 타겟 사이엔 이미 풀 리퀘스트가 있습니다:<a href="%[1]s/pulls/%[3]d">%[2]s#%[3]d</a>`
 pulls.create=풀 리퀘스트 생성
 pulls.title_desc=<code>%[2]s</code> 에서 <code>%[3]s</code> 로 %[1]d commits 를 머지하려 합니다
@@ -641,9 +641,9 @@ pulls.is_checking=아직 컨플릭트 여부 체크 중입니다, 잠시 후 이
 pulls.can_auto_merge_desc=이 풀리퀘스트는 자동적으로 머지될 수 있습니다.
 pulls.cannot_auto_merge_desc=컨플릭이 존재해서 이 풀리퀘스트는 자동을 머지될 수 없습니다.
 pulls.cannot_auto_merge_helper=컨플릭을 해결하려면 수동으로 머지해 주십시오.
-pulls.create_merge_commit=Create a merge commit
+pulls.create_merge_commit=합치기커밋 생성
 pulls.rebase_before_merging=병합 하기 전에 리베이스
-pulls.commit_description=Commit Description
+pulls.commit_description=커밋설명
 pulls.merge_pull_request=풀리퀘스트 머지
 pulls.open_unmerged_pull_exists=`같은 리파지토리에서 같은 머지 정보로 만들어진 풀리퀘스트 (#%d) 가 이미 오픈 상태이고 머지를 기다리고 있기 때문에 다시 열기 작업을 할 수 없습니다.`
 pulls.delete_branch=브랜치 삭제
@@ -699,7 +699,7 @@ settings.collaboration.write=쓰기
 settings.collaboration.read=읽기
 settings.collaboration.undefined=미정의
 settings.branches=브랜치
-settings.branches_bare=You cannot manage branches for bare repository. Please push some content first.
+settings.branches_bare=당신은 빈 저장소에 대한 브런치를 관리할수 없습니다. 먼저 저장소에 내용을 푸쉬하십시오.
 settings.default_branch=기본 브랜치
 settings.default_branch_desc=The default branch is considered the "base" branch for code commits, pull requests and online editing.
 settings.update=업데이트
@@ -719,7 +719,7 @@ settings.protect_whitelist_committers_desc=Add people or teams to whitelist of d
 settings.protect_whitelist_users=이 브랜치에 푸시를 할 수 있는 유저
 settings.protect_whitelist_search_users=유저 검색
 settings.protect_whitelist_teams=Teams for which members of them can push to this branch
-settings.protect_whitelist_search_teams=Search teams
+settings.protect_whitelist_search_teams=팀 검색
 settings.update_protect_branch_success=Protect options for this branch has been updated successfully!
 settings.hooks=Webhooks
 settings.githooks=Git Hooks
@@ -733,7 +733,7 @@ settings.change_reponame_prompt=이 변경은 이 저장소와 연관된 링크
 settings.advanced_settings=고급 설정
 settings.wiki_desc=위키 시스템 활성화
 settings.use_internal_wiki=내장 위키 사용
-settings.allow_public_wiki_desc=Allow public access to wiki when repository is private
+settings.allow_public_wiki_desc=저장소가 비공개되어 있으면 위키에 공개적으로 접속할 수 있도록 허용하기
 settings.use_external_wiki=외부 위키 사용하기
 settings.external_wiki_url=외부 위키 URL
 settings.external_wiki_url_desc=탭을 클릭하면 URL로 리다이렉트됩니다.
@@ -795,7 +795,7 @@ settings.webhook_deletion_success=Webhook을 성공적으로 삭제했습니다!
 settings.webhook.test_delivery=전달 시험
 settings.webhook.test_delivery_desc=가짜 푸시 이벤트 전달하여 웹훅 설정을 테스트합니다.
 settings.webhook.test_delivery_success=Webhook 테스트가 delivery 큐에 추가되었습니다. delivery 기록에서 나오기까지 몇 초의 시간이 걸릴 것입니다.
-settings.webhook.redelivery=Redelivery
+settings.webhook.redelivery=재전송
 settings.webhook.redelivery_success=Hook task '%s' has been readded to delivery queue. It may take few seconds to update delivery status in history.
 settings.webhook.request=요청
 settings.webhook.response=응답
@@ -824,17 +824,17 @@ settings.event_create_desc=브랜치 또는 태그를 생성합니다.
 settings.event_delete=삭제
 settings.event_delete_desc=브랜치나 태그 삭제됨
 settings.event_fork=포크
-settings.event_fork_desc=Repository forked
+settings.event_fork_desc=저장소 포크됨
 settings.event_push=푸시
 settings.event_push_desc=깃 저장소로 푸시
 settings.event_issues=이슈
 settings.event_issues_desc=Issue opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, or demilestoned.
 settings.event_pull_request=끌어오기 요청
 settings.event_pull_request_desc=Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, demilestoned, or synchronized.
-settings.event_issue_comment=Issue Comment
-settings.event_issue_comment_desc=Issue comment created, edited, or deleted.
-settings.event_release=Release
-settings.event_release_desc=Release published in a repository.
+settings.event_issue_comment=이슈 댓글
+settings.event_issue_comment_desc=이슈 댓글이 작성, 편집 또는 삭제되었습니다.
+settings.event_release=릴리즈
+settings.event_release_desc=저장소에 릴리즈가 출시되었습니다.
 settings.active=활성
 settings.active_helper=후크를 트리거하면 이벤트에 대한 세부 정보도 전달됩니다.
 settings.add_hook_success=새로운 웹훅이 생성되었습니다.
@@ -862,8 +862,8 @@ settings.add_key_success=새로운 배포 키 '%s'가 성공적으로 추가 되
 settings.deploy_key_deletion=배포 키 삭제
 settings.deploy_key_deletion_desc=이 배포키를 삭제하면 이 저장소와 관련된 모든 접근 권한이 삭제됩니다. 계속 하시겠습니까?
 settings.deploy_key_deletion_success=배포 키가 성공적으로 삭제되었습니다!
-settings.description_desc=Description of repository. Maximum 512 characters length.
-settings.description_length=Available characters
+settings.description_desc=저장소 설명입니다. 최대 512길이의 문자열이 가능합니다.
+settings.description_length=사용 가능한 문자열
 
 diff.browse_source=소스 검색
 diff.parent=부모
@@ -930,7 +930,7 @@ team_permission_desc=이 팀이 가진 권한이 무엇입니까?
 
 form.name_reserved=조직이름 '%s'는 예약되어있습니다.
 form.name_pattern_not_allowed=조직이름 패턴 '%s'는 허용되지 않았습니다.
-form.team_name_reserved=Team name '%s' is reserved.
+form.team_name_reserved=팀명  '%s'는 예약되어 있습니다.
 
 settings=설정
 settings.options=옵션
@@ -1002,6 +1002,12 @@ first_page=처음
 last_page=마지막
 total=총: %d
 
+dashboard.build_info=빌드정보
+dashboard.app_ver=애플리케이션 버전
+dashboard.git_version=Git 버전
+dashboard.go_version=Go 버전
+dashboard.build_time=태그 만들기
+dashboard.build_commit=빌드 커밋
 dashboard.statistic=통계
 dashboard.operations=작업
 dashboard.system_status=시스템 모니터 상태
@@ -1099,12 +1105,12 @@ repos.stars=Stars
 repos.issues=이슈
 repos.size=크기
 
-auths.auth_sources=Authentication Sources
+auths.auth_sources=인증 소스
 auths.new=새로운 소스를 추가
 auths.name=이름
 auths.type=유형
 auths.enabled=활성화됨
-auths.default=Default
+auths.default=기본값
 auths.updated=업데이트됨
 auths.auth_type=인증 유형
 auths.auth_name=인증 이름
@@ -1124,8 +1130,8 @@ auths.attribute_name=첫번째 이름 속성
 auths.attribute_surname=성씨 속성
 auths.attribute_mail=이메일 속성
 auths.verify_group_membership=그룹 구성원 자격을 확인
-auths.group_search_base_dn=Group Search Base DN
-auths.group_filter=Group Filter
+auths.group_search_base_dn=그룹 설정 Base DN
+auths.group_filter=그룹 필터
 auths.group_attribute_contain_user_list=Group Attribute Containing List of Users
 auths.user_attribute_listed_in_group=User Attribute Listed in Group
 auths.attributes_in_bind=DN 컨텍스트에서 속성을 가져와 연결합니다.
@@ -1153,123 +1159,176 @@ auths.delete_auth_desc=이 인증이 삭제됩니다. 정말로 진행하시겠
 auths.still_in_used=이 인증은 아직 몇몇 사용자들이 사용하고 있습니다, 먼저 사용자들의 로그인 유형을 삭제하거나 변경해주십시오.
 auths.deletion_success=인증이 성공적으로 삭제 되었습니다!
 auths.login_source_exist=로그인 소스 '%s'는 이미 존재합니다.
-auths.github_api_endpoint=API Endpoint
+auths.github_api_endpoint=API 끝점
 
-config.not_set=(not set)
+config.not_set=(설정되지 않음)
 config.server_config=서버 설정
-config.app_name=애플리케이션 이름
-config.app_ver=응용 프로그램 버전
-config.app_url=애플리케이션 URL
-config.domain=도메인
-config.offline_mode=오프라인 모드
-config.disable_router_log=라우터 로그 비활성화
+config.brand_name=브랜드 이름
 config.run_user=데몬 실행 계정
 config.run_mode=실행 모드
-config.git_version=Git 버전
-config.static_file_root_path=정적 파일 최상위 경로
-config.log_file_root_path=로그 파일 최상위 경로
-config.reverse_auth_user=역방향 사용자 인증
+config.server.external_url=외부 URL
+config.server.domain=도메인
+config.server.protocol=프로토콜
+config.server.http_addr=HTTP 주소
+config.server.http_port=HTTP 포트
+config.server.cert_file=인증서 파일
+config.server.key_file=키 파일
+config.server.tls_min_version=최소 TLS 버전
+config.server.unix_socket_permission=Unix 소켓 권한
+config.server.local_root_url=로컬 최상위 URL
+config.server.offline_mode=오프라인 모드
+config.server.disable_router_log=라우터 로그 비활성화
+config.server.enable_gzip=Gzip 활성화
+config.server.app_data_path=애플리케이션 데이터 경로
+config.server.load_assets_from_disk=디스크에서 요소 불러오기
+config.server.landing_url=랜딩 URL
 
 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_rewrite_authorized_keys_at_start=Rewrite authorized_keys At Start
-config.ssh_key_test_path=주 테스트 경로
-config.ssh_keygen_path=키 생성 ('ssh-keygen') 경로
-config.ssh_minimum_key_size_check=최소 키 사이즈 검사
-config.ssh_minimum_key_sizes=최소 키 사이즈
-
-config.repo_config=Repository Configuration
-config.repo_root_path=저장소 최상위 경로
-config.script_type=스크립트 유형
-config.repo_force_private=Force Private
-config.max_creation_limit=Max Creation Limit
-config.preferred_licenses=Preferred Licenses
-config.disable_http_git=Disable HTTP Git
-config.enable_local_path_migration=Enable Local Path Migration
-config.commits_fetch_concurrency=Commits Fetch Concurrency
-
-config.http_config=HTTP 설정
-config.http_access_control_allow_origin=Access Control Allow Origin
+config.ssh.enabled=활성화됨
+config.ssh.domain=노출된 도메인
+config.ssh.port=노출 포트
+config.ssh.root_path=최상위 경로
+config.ssh.keygen_path=키 생성 경로
+config.ssh.key_test_path=키 테스트 경로
+config.ssh.minimum_key_size_check=최소 키 크기 검사
+config.ssh.minimum_key_sizes=최소 키 사이즈
+config.ssh.rewrite_authorized_keys_at_start=Rewrite "authorized_keys" at start
+config.ssh.start_builtin_server=빌트인 서버 시작
+config.ssh.listen_host=수신 대기 호스트
+config.ssh.listen_port=수신 대기 포트
+config.ssh.server_ciphers=서버 암호화
+
+config.repo_config=저장소 설정
+config.repo.root_path=최상위 경로
+config.repo.script_type=스크립트 유형
+config.repo.ansi_chatset=ANSI 문자열
+config.repo.force_private=비공개 강제
+config.repo.max_creation_limit=최대 생성 제한
+config.repo.preferred_licenses=선호 라이선스
+config.repo.disable_http_git=HTTP Git 비활성화
+config.repo.enable_local_path_migration=로컬 경로 마이그레이션 활성화
+config.repo.enable_raw_file_render_mode=raw 파일 렌더링 모드 활성화
+config.repo.commits_fetch_concurrency=Commits fetch concurrency
+config.repo.editor.line_wrap_extensions=편집기 줄 바꿈 확장
+config.repo.editor.previewable_file_modes=Editor previewable file modes
+config.repo.upload.enabled=업로드 활성화됨
+config.repo.upload.temp_path=임시 경로 업로드
+config.repo.upload.allowed_types=허용되는 유형 업로드
+config.repo.upload.file_max_size=업로드 파일 크기 제한
+config.repo.upload.max_files=업로드 파일 제한
 
 config.db_config=데이터베이스 설정
-config.db_type=유형
-config.db_host=호스트
-config.db_name=이름
-config.db_user=사용자
-config.db_ssl_mode=SSL 모드
-config.db_ssl_mode_helper=("postgres" 전용)
-config.db_path=경로
-config.db_path_helper=("sqlite3" 및 "tidb"만)
-
-config.service_config=서비스 설정
-config.register_email_confirm=이메일 확인 필수
-config.disable_register=등록 비활성화
-config.show_registration_button=등록 버튼을 표시
-config.require_sign_in_view=보기 위해선 로그인 필수
-config.mail_notify=메일 알림
-config.disable_key_size_check=최소 키 크기 검사를 비활성화
-config.enable_captcha=Captcha 활성화
-config.active_code_lives=코드 만료 기한
-config.reset_password_code_lives=비밀번호 코드 만료 기한
+config.db.type=유형
+config.db.host=호스트
+config.db.name=이름
+config.db.user=사용자
+config.db.ssl_mode=SSL 모드
+config.db.ssl_mode_helper=("postgres" 전용)
+config.db.path=경로
+config.db.path_helper={"sqlite3" 전용)
+
+config.security_config=보안 설정
+config.security.login_remember_days=로그인 기억 날짜
+config.security.cookie_remember_name=쿠키 기억하기
+config.security.cookie_username=사용자 이름 쿠키
+config.security.cookie_secure=보안 쿠키 활성화
+config.security.reverse_proxy_auth_user=Reverse proxy authentication header
+config.security.enable_login_status_cookie=로그인 상태 쿠키 활성화
+config.security.login_status_cookie_name=로그인 상태 쿠키
+
+config.email_config=이메일 설정
+config.email.enabled=활성화됨
+config.email.subject_prefix=제목 접두어
+config.email.host=호스트
+config.email.from=보내는 사람
+config.email.user=사용자
+config.email.disable_helo=HELO 비활성화
+config.email.helo_hostname=HELO 호스트 이름
+config.email.skip_verify=인증서 검증 건너뛰기
+config.email.use_certificate=커스텀 인증서 사용하기
+config.email.cert_file=인증서 파일
+config.email.key_file=키 파일
+config.email.use_plain_text=평문 텍스트 사용
+config.email.add_plain_text_alt=평문 텍스트 대체 추가
+config.email.send_test_mail=테스트 이메일 보내기
+config.email.test_mail_failed=Failed to send test email to '%s': %v
+config.email.test_mail_sent='%s'로 테스트 이메일을 보냈습니다.
+
+config.auth_config=Authentication configuration
+config.auth.activate_code_lives=Activate code lives
+config.auth.reset_password_code_lives=Reset password code lives
+config.auth.require_email_confirm=Require email confirmation
+config.auth.require_sign_in_view=Require sign in view
+config.auth.disable_registration=Disable registration
+config.auth.enable_registration_captcha=Enable registration captcha
+config.auth.enable_reverse_proxy_authentication=Enable reverse proxy authentication
+config.auth.enable_reverse_proxy_auto_registration=Enable reverse proxy auto registration
+config.auth.reverse_proxy_authentication_header=Reverse proxy authentication header
+
+config.user_config=User configuration
+config.user.enable_email_notify=Enable email notification
 
-config.webhook_config=웹훅 설정
-config.queue_length=큐 길이
-config.deliver_timeout=시간 제한 사용
-config.skip_tls_verify=TLS 확인 건너뛰기
-
-config.mailer_config=메일러 설정
-config.mailer_enabled=활성화됨
-config.mailer_disable_helo=HELO 비활성화
-config.mailer_subject_prefix=Subject Prefix
-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.session_config=세션 설정
+config.session.provider=Provider
+config.session.provider_config=Provider config
+config.session.cookie_name=Cookie
+config.session.https_only=HTTPS only
+config.session.gc_interval=GC interval
+config.session.max_life_time=Max life time
+config.session.csrf_cookie_name=CSRF cookie
 
 config.cache_config=캐시 설정
-config.cache_adapter=캐시 어댑터
-config.cache_interval=캐시 간격
-config.cache_conn=캐시 연결
+config.cache.adapter=Adapter
+config.cache.interval=GC interval
+config.cache.host=Host
 
-config.session_config=세션 설정
-config.session_provider=세션 공급자
-config.provider_config=공급자 설정
-config.cookie_name=쿠키 이름
-config.enable_set_cookie=쿠키 활성화
-config.gc_interval_time=GC 인터벌 시간
-config.session_life_time=세션 수명
-config.https_only=HTTPS만
-config.cookie_life_time=쿠키 수명
+config.http_config=HTTP 설정
+config.http.access_control_allow_origin=Access control allow origin
+
+config.attachment_config=Attachment configuration
+config.attachment.enabled=Enabled
+config.attachment.path=Path
+config.attachment.allowed_types=Allowed types
+config.attachment.max_size=Size limit
+config.attachment.max_files=Files limit
+
+config.release_config=Release configuration
+config.release.attachment.enabled=Attachment enabled
+config.release.attachment.allowed_types=Attachment allowed types
+config.release.attachment.max_size=Attachment size limit
+config.release.attachment.max_files=Attachment files limit
 
 config.picture_config=이미지 설정
-config.picture_service=이미지 서비스
-config.disable_gravatar=Gravatar 사용안함
-config.enable_federated_avatar=연합 아바타 사용
+config.picture.avatar_upload_path=User avatar upload path
+config.picture.repo_avatar_upload_path=Repository avatar upload path
+config.picture.gravatar_source=Gravatar source
+config.picture.disable_gravatar=Disable Gravatar
+config.picture.enable_federated_avatar=Enable federated avatars
+
+config.mirror_config=Mirror configuration
+config.mirror.default_interval=Default interval
+
+config.webhook_config=웹훅 설정
+config.webhook.types=Types
+config.webhook.deliver_timeout=Deliver timeout
+config.webhook.skip_tls_verify=Skip TLS verify
 
 config.git_config=깃 설정
-config.git_disable_diff_highlight=변경 사항 구문 강조 비활성화
-config.git_max_diff_lines=변경사항 최대 표시 줄 수 (단일 파일에 대해)
-config.git_max_diff_line_characters=변경사항 최대 표시 문자 수 (단일 행에 대해)
-config.git_max_diff_files=변경사항 최대 파일 개 수 (표시 되는)
-config.git_gc_args=가비지 콜렉션 인수
-config.git_migrate_timeout=마이그레이션 제한 시간
-config.git_mirror_timeout=미러 업데이트 시간 제한
-config.git_clone_timeout=복제 작업 시간 제한
-config.git_pull_timeout=끌어오기 작업 시간 제한
-config.git_gc_timeout=가비지 콜렉션 작업 시간 제한
+config.git.disable_diff_highlight=Disable diff syntax highlight
+config.git.max_diff_lines=Diff lines limit (for a single file)
+config.git.max_diff_line_characters=Diff characters limit (for a single line)
+config.git.max_diff_files=Diff files limit (for a single diff)
+config.git.gc_args=GC arguments
+config.git.migrate_timeout=Migration timeout
+config.git.mirror_timeout=Mirror fetch timeout
+config.git.clone_timeout=Clone timeout
+config.git.pull_timeout=Pull timeout
+config.git.gc_timeout=GC timeout
 
 config.log_config=로그 설정
-config.log_mode=Mode
-config.log_options=Options
+config.log_file_root_path=로그 파일 최상위 경로
+config.log_mode=모드
+config.log_options=설정
 
 monitor.cron=Cron 작업
 monitor.name=이름
@@ -1313,7 +1372,7 @@ merge_pull_request=`병합된 끌어오기 요청 <a href="%s/pulls/%s"> %s #%[2
 create_branch=created new branch <a href="%[1]s/src/%[2]s">%[3]s</a> at <a href="%[1]s">%[4]s</a>
 delete_branch=deleted branch <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
 push_tag=태그 <a href="%s/src/%s">%[2]s</a>를 <a href="%[1]s">%[3]s</a>로 푸시함
-delete_tag=deleted tag <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
+delete_tag=<a href="%[1]s">%[3]s</a>에서 code>%[2]s</code> 태그 삭제됨
 fork_repo=forked a repository to <a href="%s">%s</a>
 mirror_sync_push=synced commits to <a href="%[1]s/src/%[2]s">%[3]s</a> at <a href="%[1]s">%[4]s</a> from mirror
 mirror_sync_create=synced new reference <a href="%s/src/%s">%[2]s</a> to <a href="%[1]s">%[3]s</a> from mirror
@@ -1339,6 +1398,7 @@ months=%d 달 %s
 years=%d 년 %s
 raw_seconds=초
 raw_minutes=분
+raw_hours=hours
 
 [dropzone]
 default_message=여기에 파일을 끌어 놓거나 클릭하여 업로드하세요.

+ 154 - 94
conf/locale/locale_lv-LV.ini

@@ -9,7 +9,6 @@ sign_out=Izrakstīties
 sign_up=Reģistrēties
 register=Reģistrēties
 website=Mājas lapa
-version=Versija
 page=Lapa
 template=Sagatave
 language=Valoda
@@ -122,6 +121,7 @@ run_user_not_match=Izpildes lietotājs nav pašreizējais lietotājs: %s -> %s
 smtp_host_missing_port=SMTP adresē nav norādīts ports.
 invalid_smtp_from=SMTP sūtītāja lauks ir nekorekts: %v
 save_config_failed=Neizdevās saglabāt konfigurāciju: %v
+init_failed=Failed to initialize application: %v
 invalid_admin_setting=Nekorekts admin konta iestatījums: %v
 install_success=Laipni lūdzam! Mēs priecājamies, ka Jūs izvēlaties GIN, patīkamu lietošanu!
 invalid_log_root_path=Norādītā žurnalizēšanas direktorija ir kļūdaina: %v
@@ -1001,6 +1001,12 @@ first_page=Pirmā
 last_page=Pēdējā
 total=Kopā: %d
 
+dashboard.build_info=Build Information
+dashboard.app_ver=Application version
+dashboard.git_version=Git version
+dashboard.go_version=Go version
+dashboard.build_time=Build time
+dashboard.build_commit=Build commit
 dashboard.statistic=Statistika
 dashboard.operations=Darbības
 dashboard.system_status=Sistēmas uzraudzības statuss
@@ -1156,117 +1162,170 @@ auths.github_api_endpoint=API Endpoint
 
 config.not_set=(nav noteikts)
 config.server_config=Servera konfigurācija
-config.app_name=Lietotnes nosaukums
-config.app_ver=Lietotnes versija
-config.app_url=Lietotnes URL
-config.domain=Domēns
-config.offline_mode=Bezsaistes režīms
-config.disable_router_log=Atspējot maršrutētāja žurnalizēšanu
+config.brand_name=Brand name
 config.run_user=Izpildes lietotājs
 config.run_mode=Izpildes režīms
-config.git_version=Git versija
-config.static_file_root_path=Statisko failu atrašanās vieta
-config.log_file_root_path=Žurnalizēšanas failu glabāšanas vieta
-config.reverse_auth_user=Reversā lietotāja autentifikācija
+config.server.external_url=External URL
+config.server.domain=Domain
+config.server.protocol=Protocol
+config.server.http_addr=HTTP address
+config.server.http_port=HTTP port
+config.server.cert_file=Certificate file
+config.server.key_file=Key file
+config.server.tls_min_version=Minimum TLS version
+config.server.unix_socket_permission=Unix socket permission
+config.server.local_root_url=Local root URL
+config.server.offline_mode=Offline mode
+config.server.disable_router_log=Disable router log
+config.server.enable_gzip=Enable Gzip
+config.server.app_data_path=Application data path
+config.server.load_assets_from_disk=Load assets from disk
+config.server.landing_url=Landing URL
 
 config.ssh_config=SSH konfigurācija
-config.ssh_enabled=Iespējots
-config.ssh_start_builtin_server=Startēt iebūvēto serveri
-config.ssh_domain=Domēns
-config.ssh_port=Ports
-config.ssh_listen_port=Klausīšanās ports
-config.ssh_root_path=Saknes ceļš
-config.ssh_rewrite_authorized_keys_at_start=Rewrite authorized_keys At Start
-config.ssh_key_test_path=Atslēgu pārbaudes ceļš
-config.ssh_keygen_path=Keygen ('ssh-keygen') ceļš
-config.ssh_minimum_key_size_check=Minimālā atslēgas lieluma pārbaude
-config.ssh_minimum_key_sizes=Minimālais atslēgas lielums
+config.ssh.enabled=Enabled
+config.ssh.domain=Exposed domain
+config.ssh.port=Exposed port
+config.ssh.root_path=Root path
+config.ssh.keygen_path=Keygen path
+config.ssh.key_test_path=Key test path
+config.ssh.minimum_key_size_check=Minimum key size check
+config.ssh.minimum_key_sizes=Minimum key sizes
+config.ssh.rewrite_authorized_keys_at_start=Rewrite "authorized_keys" at start
+config.ssh.start_builtin_server=Start builtin server
+config.ssh.listen_host=Listen host
+config.ssh.listen_port=Listen port
+config.ssh.server_ciphers=Server ciphers
 
 config.repo_config=Repozitorija konfigurācija
-config.repo_root_path=Repozitoriju glabāšanas vieta
-config.script_type=Skripta veids
-config.repo_force_private=Piespiedu privāti repozitoriji
-config.max_creation_limit=Max Creation Limit
-config.preferred_licenses=Preferred Licenses
-config.disable_http_git=Atspējot HTTP Git
-config.enable_local_path_migration=Atļaut migrāciju no lokāla ceļa
-config.commits_fetch_concurrency=Commits Fetch Concurrency
-
-config.http_config=HTTP konfigurācija
-config.http_access_control_allow_origin=Access Control Allow Origin
+config.repo.root_path=Root path
+config.repo.script_type=Script type
+config.repo.ansi_chatset=ANSI charset
+config.repo.force_private=Force private
+config.repo.max_creation_limit=Max creation limit
+config.repo.preferred_licenses=Preferred licenses
+config.repo.disable_http_git=Disable HTTP Git
+config.repo.enable_local_path_migration=Enable local path migration
+config.repo.enable_raw_file_render_mode=Enable raw file render mode
+config.repo.commits_fetch_concurrency=Commits fetch concurrency
+config.repo.editor.line_wrap_extensions=Editor line wrap extensions
+config.repo.editor.previewable_file_modes=Editor previewable file modes
+config.repo.upload.enabled=Upload enabled
+config.repo.upload.temp_path=Upload temporary path
+config.repo.upload.allowed_types=Upload allowed types
+config.repo.upload.file_max_size=Upload file size limit
+config.repo.upload.max_files=Upload files limit
 
 config.db_config=Datu bāzes konfigurācija
-config.db_type=Veids
-config.db_host=Resursdators
-config.db_name=Nosaukums
-config.db_user=Lietotājs
-config.db_ssl_mode=SSL režīms
-config.db_ssl_mode_helper=(tikai PostgreSQL datu bāzei)
-config.db_path=Ceļš
-config.db_path_helper=(priekš "sqlite3" and "tidb")
-
-config.service_config=Pakalpojuma konfigurācija
-config.register_email_confirm=Pieprasīt e-pasta apstiprināšanu
-config.disable_register=Atspējot jaunu lietotāju reģistrāciju
-config.show_registration_button=Rādīt reģistrēšanās pogu
-config.require_sign_in_view=Nepieciešama autorizācija
-config.mail_notify=Pasta paziņojumi
-config.disable_key_size_check=Atspējot atslēgas minimālā garuma pārbaudi
-config.enable_captcha=Iespējot drošības kodu
-config.active_code_lives=Aktīvā koda ilgums
-config.reset_password_code_lives=Paroles atiestatīšanas koda ilgums
+config.db.type=Type
+config.db.host=Host
+config.db.name=Name
+config.db.user=User
+config.db.ssl_mode=SSL mode
+config.db.ssl_mode_helper=(for "postgres" only)
+config.db.path=Path
+config.db.path_helper=(for "sqlite3"only)
+
+config.security_config=Security configuration
+config.security.login_remember_days=Login remember days
+config.security.cookie_remember_name=Remember cookie
+config.security.cookie_username=Username cookie
+config.security.cookie_secure=Enable secure cookie
+config.security.reverse_proxy_auth_user=Reverse proxy authentication header
+config.security.enable_login_status_cookie=Enable login status cookie
+config.security.login_status_cookie_name=Login status cookie
+
+config.email_config=Email configuration
+config.email.enabled=Enabled
+config.email.subject_prefix=Subject prefix
+config.email.host=Host
+config.email.from=From
+config.email.user=User
+config.email.disable_helo=Disable HELO
+config.email.helo_hostname=HELO hostname
+config.email.skip_verify=Skip certificate verify
+config.email.use_certificate=Use custom certificate
+config.email.cert_file=Certificate file
+config.email.key_file=Key file
+config.email.use_plain_text=Use plain text
+config.email.add_plain_text_alt=Add plain text alternative
+config.email.send_test_mail=Send test email
+config.email.test_mail_failed=Failed to send test email to '%s': %v
+config.email.test_mail_sent=Test email has been sent to '%s'.
+
+config.auth_config=Authentication configuration
+config.auth.activate_code_lives=Activate code lives
+config.auth.reset_password_code_lives=Reset password code lives
+config.auth.require_email_confirm=Require email confirmation
+config.auth.require_sign_in_view=Require sign in view
+config.auth.disable_registration=Disable registration
+config.auth.enable_registration_captcha=Enable registration captcha
+config.auth.enable_reverse_proxy_authentication=Enable reverse proxy authentication
+config.auth.enable_reverse_proxy_auto_registration=Enable reverse proxy auto registration
+config.auth.reverse_proxy_authentication_header=Reverse proxy authentication header
+
+config.user_config=User configuration
+config.user.enable_email_notify=Enable email notification
 
-config.webhook_config=Tīkla āķu konfigurācija
-config.queue_length=Rindas garums
-config.deliver_timeout=Piegādes noildze
-config.skip_tls_verify=Izlaist TLS pārbaudi
-
-config.mailer_config=Sūtītāja konfigurācija
-config.mailer_enabled=Iespējots
-config.mailer_disable_helo=Atspējot HELO
-config.mailer_subject_prefix=Subject Prefix
-config.mailer_host=Resursdators
-config.mailer_user=Lietotājs
-config.send_test_mail=Nosūtīt pārbaudes e-pastu
-config.test_mail_failed=Neizdevās nosūtīt pārbaudes e-pasta vēstuli uz '%s': %v
-config.test_mail_sent=Pārbaudes e-pasta vēstule tika nosūtīta uz '%s'.
-
-config.oauth_config=OAuth konfigurācija
-config.oauth_enabled=Iespējota
+config.session_config=Sesijas konfigurācja
+config.session.provider=Provider
+config.session.provider_config=Provider config
+config.session.cookie_name=Cookie
+config.session.https_only=HTTPS only
+config.session.gc_interval=GC interval
+config.session.max_life_time=Max life time
+config.session.csrf_cookie_name=CSRF cookie
 
 config.cache_config=Kešatmiņas konfigurācija
-config.cache_adapter=Kešatmiņas adapteris
-config.cache_interval=Kešatmiņas intervāls
-config.cache_conn=Kešatmiņas pieslēguma parametri
+config.cache.adapter=Adapter
+config.cache.interval=GC interval
+config.cache.host=Host
 
-config.session_config=Sesijas konfigurācja
-config.session_provider=Sesijas nodrošinātājs
-config.provider_config=Pakalpojumu sniedzēja konfigurācija
-config.cookie_name=Sīkdatnes nosaukums
-config.enable_set_cookie=Ļaut izmantot sīkdatnes
-config.gc_interval_time=GC laika intervāls
-config.session_life_time=Sesijas ilgums
-config.https_only=Tikai HTTPS
-config.cookie_life_time=Sīkdatņu glabāšanas ilgums
+config.http_config=HTTP konfigurācija
+config.http.access_control_allow_origin=Access control allow origin
+
+config.attachment_config=Attachment configuration
+config.attachment.enabled=Enabled
+config.attachment.path=Path
+config.attachment.allowed_types=Allowed types
+config.attachment.max_size=Size limit
+config.attachment.max_files=Files limit
+
+config.release_config=Release configuration
+config.release.attachment.enabled=Attachment enabled
+config.release.attachment.allowed_types=Attachment allowed types
+config.release.attachment.max_size=Attachment size limit
+config.release.attachment.max_files=Attachment files limit
 
 config.picture_config=Attēlu konfigurācija
-config.picture_service=Lokāli attēli
-config.disable_gravatar=Atspējot Gravatar
-config.enable_federated_avatar=Iespējot apvienotās profila bildes
+config.picture.avatar_upload_path=User avatar upload path
+config.picture.repo_avatar_upload_path=Repository avatar upload path
+config.picture.gravatar_source=Gravatar source
+config.picture.disable_gravatar=Disable Gravatar
+config.picture.enable_federated_avatar=Enable federated avatars
+
+config.mirror_config=Mirror configuration
+config.mirror.default_interval=Default interval
+
+config.webhook_config=Tīkla āķu konfigurācija
+config.webhook.types=Types
+config.webhook.deliver_timeout=Deliver timeout
+config.webhook.skip_tls_verify=Skip TLS verify
 
 config.git_config=Git konfigurācija
-config.git_disable_diff_highlight=Atspējot salīdzināšanas sintakses iekrāsošanu
-config.git_max_diff_lines=Maksimālais salīdzināmo rindu skaits vienam failam
-config.git_max_diff_line_characters=Maksimālais salīdzināmo simbolu skaits vienai rindai
-config.git_max_diff_files=Maksimālais salīdzināmo failu skaits, ko attēlot
-config.git_gc_args=GC argumenti
-config.git_migrate_timeout=Migrācijas noilgums
-config.git_mirror_timeout=Spoguļa atjaunošanas noilgums
-config.git_clone_timeout=Klonēšanas darbības noilgums
-config.git_pull_timeout=Izmaiņu saņemšanas darbības noilgums
-config.git_gc_timeout=GC darbības noilgums
+config.git.disable_diff_highlight=Disable diff syntax highlight
+config.git.max_diff_lines=Diff lines limit (for a single file)
+config.git.max_diff_line_characters=Diff characters limit (for a single line)
+config.git.max_diff_files=Diff files limit (for a single diff)
+config.git.gc_args=GC arguments
+config.git.migrate_timeout=Migration timeout
+config.git.mirror_timeout=Mirror fetch timeout
+config.git.clone_timeout=Clone timeout
+config.git.pull_timeout=Pull timeout
+config.git.gc_timeout=GC timeout
 
 config.log_config=Žurnalizēšanas konfigurācija
+config.log_file_root_path=Žurnalizēšanas failu glabāšanas vieta
 config.log_mode=Režīms
 config.log_options=Opcijas
 
@@ -1338,6 +1397,7 @@ months=%d mēneši %s
 years=%d gadi %s
 raw_seconds=sekundes
 raw_minutes=minūtes
+raw_hours=hours
 
 [dropzone]
 default_message=Ievelciet failus šeit vai noklikšķiniet, lai augšupielādētu.

+ 157 - 97
conf/locale/locale_nl-NL.ini

@@ -9,7 +9,6 @@ sign_out=Uitloggen
 sign_up=Aanmelden
 register=Registreren
 website=Website
-version=Versie
 page=Pagina
 template=Sjabloon
 language=Taal
@@ -122,6 +121,7 @@ run_user_not_match=De uitvoerende gebruiker is niet de huidig gebruiker: %s -> %
 smtp_host_missing_port=SMTP-Host mist een poort in het adres.
 invalid_smtp_from=SMTP-van-veld is niet geldig: %v
 save_config_failed=Kan de configuratie niet opslaan: %v
+init_failed=Failed to initialize application: %v
 invalid_admin_setting=Uw admin-instellingen zijn niet geldig: %v
 install_success=Welkom! Wij zijn veheugd dat u voor GIN heeft gekozen, veel plezier en tot ziens
 invalid_log_root_path=Ongeldig log-pad: %v
@@ -1001,6 +1001,12 @@ first_page=Eerste
 last_page=Laatste
 total=Totaal: %d
 
+dashboard.build_info=Build Information
+dashboard.app_ver=Application version
+dashboard.git_version=Git version
+dashboard.go_version=Go version
+dashboard.build_time=Build time
+dashboard.build_commit=Build commit
 dashboard.statistic=Statistieken
 dashboard.operations=Bewerkingen
 dashboard.system_status=Status Systeemmonitor
@@ -1156,117 +1162,170 @@ auths.github_api_endpoint=API Endpoint
 
 config.not_set=(not set)
 config.server_config=Serverconfiguratie
-config.app_name=Applicatienaam
-config.app_ver=Applicatieversie
-config.app_url=Applicatie-URL
-config.domain=Domein
-config.offline_mode=Offline-modus
-config.disable_router_log=Router-log uitschakelen
+config.brand_name=Brand name
 config.run_user=Uitvoerende gebruiker
 config.run_mode=Uitvoer modus
-config.git_version=Gitversie
-config.static_file_root_path=Statische bestanden basis pad
-config.log_file_root_path=Log bestand basis pad
-config.reverse_auth_user=Omgekeerde verificatie gebruiker
+config.server.external_url=External URL
+config.server.domain=Domain
+config.server.protocol=Protocol
+config.server.http_addr=HTTP address
+config.server.http_port=HTTP port
+config.server.cert_file=Certificate file
+config.server.key_file=Key file
+config.server.tls_min_version=Minimum TLS version
+config.server.unix_socket_permission=Unix socket permission
+config.server.local_root_url=Local root URL
+config.server.offline_mode=Offline mode
+config.server.disable_router_log=Disable router log
+config.server.enable_gzip=Enable Gzip
+config.server.app_data_path=Application data path
+config.server.load_assets_from_disk=Load assets from disk
+config.server.landing_url=Landing URL
 
 config.ssh_config=SSH-configuratie
-config.ssh_enabled=Ingeschakeld
-config.ssh_start_builtin_server=Ingebouwde server starten
-config.ssh_domain=Domein
-config.ssh_port=Poort
-config.ssh_listen_port=Luister op poort
-config.ssh_root_path=Root-pad
-config.ssh_rewrite_authorized_keys_at_start=Rewrite authorized_keys At Start
-config.ssh_key_test_path=Pad voor key-tests
-config.ssh_keygen_path=Pad van keygen ('ssh-keygen')
-config.ssh_minimum_key_size_check=Controleer minimale key-lengte
-config.ssh_minimum_key_sizes=Minimale key-lengtes
-
-config.repo_config=Repository Configuration
-config.repo_root_path=Repositorie basis pad
-config.script_type=Script type
-config.repo_force_private=Force Private
-config.max_creation_limit=Max Creation Limit
-config.preferred_licenses=Preferred Licenses
-config.disable_http_git=Disable HTTP Git
-config.enable_local_path_migration=Enable Local Path Migration
-config.commits_fetch_concurrency=Commits Fetch Concurrency
-
-config.http_config=HTTP Configuration
-config.http_access_control_allow_origin=Access Control Allow Origin
+config.ssh.enabled=Enabled
+config.ssh.domain=Exposed domain
+config.ssh.port=Exposed port
+config.ssh.root_path=Root path
+config.ssh.keygen_path=Keygen path
+config.ssh.key_test_path=Key test path
+config.ssh.minimum_key_size_check=Minimum key size check
+config.ssh.minimum_key_sizes=Minimum key sizes
+config.ssh.rewrite_authorized_keys_at_start=Rewrite "authorized_keys" at start
+config.ssh.start_builtin_server=Start builtin server
+config.ssh.listen_host=Listen host
+config.ssh.listen_port=Listen port
+config.ssh.server_ciphers=Server ciphers
+
+config.repo_config=Repository configuration
+config.repo.root_path=Root path
+config.repo.script_type=Script type
+config.repo.ansi_chatset=ANSI charset
+config.repo.force_private=Force private
+config.repo.max_creation_limit=Max creation limit
+config.repo.preferred_licenses=Preferred licenses
+config.repo.disable_http_git=Disable HTTP Git
+config.repo.enable_local_path_migration=Enable local path migration
+config.repo.enable_raw_file_render_mode=Enable raw file render mode
+config.repo.commits_fetch_concurrency=Commits fetch concurrency
+config.repo.editor.line_wrap_extensions=Editor line wrap extensions
+config.repo.editor.previewable_file_modes=Editor previewable file modes
+config.repo.upload.enabled=Upload enabled
+config.repo.upload.temp_path=Upload temporary path
+config.repo.upload.allowed_types=Upload allowed types
+config.repo.upload.file_max_size=Upload file size limit
+config.repo.upload.max_files=Upload files limit
 
 config.db_config=Databaseconfiguratie
-config.db_type=Type
-config.db_host=Host
-config.db_name=Naam
-config.db_user=Gebruiker
-config.db_ssl_mode=SSL modus
-config.db_ssl_mode_helper=(alleen voor "postgres")
-config.db_path=Pad
-config.db_path_helper=(voor "sqlite3" en "tidb")
-
-config.service_config=Serviceconfiguratie
-config.register_email_confirm=E-mailbevestiging registreren
-config.disable_register=Registratie uitgeschakeld
-config.show_registration_button=Registeren knop weergeven
-config.require_sign_in_view=Inloggen vereist om te kunnen inzien
-config.mail_notify=E-mailnotificaties
-config.disable_key_size_check=Controle op key-lengte uitschakelen
-config.enable_captcha=CAPTCHA inschakelen
-config.active_code_lives=Actieve Code leven
-config.reset_password_code_lives=Reset wachtwoord Code leven
+config.db.type=Type
+config.db.host=Host
+config.db.name=Name
+config.db.user=User
+config.db.ssl_mode=SSL mode
+config.db.ssl_mode_helper=(for "postgres" only)
+config.db.path=Path
+config.db.path_helper=(for "sqlite3"only)
+
+config.security_config=Security configuration
+config.security.login_remember_days=Login remember days
+config.security.cookie_remember_name=Remember cookie
+config.security.cookie_username=Username cookie
+config.security.cookie_secure=Enable secure cookie
+config.security.reverse_proxy_auth_user=Reverse proxy authentication header
+config.security.enable_login_status_cookie=Enable login status cookie
+config.security.login_status_cookie_name=Login status cookie
+
+config.email_config=Email configuration
+config.email.enabled=Enabled
+config.email.subject_prefix=Subject prefix
+config.email.host=Host
+config.email.from=From
+config.email.user=User
+config.email.disable_helo=Disable HELO
+config.email.helo_hostname=HELO hostname
+config.email.skip_verify=Skip certificate verify
+config.email.use_certificate=Use custom certificate
+config.email.cert_file=Certificate file
+config.email.key_file=Key file
+config.email.use_plain_text=Use plain text
+config.email.add_plain_text_alt=Add plain text alternative
+config.email.send_test_mail=Send test email
+config.email.test_mail_failed=Failed to send test email to '%s': %v
+config.email.test_mail_sent=Test email has been sent to '%s'.
+
+config.auth_config=Authentication configuration
+config.auth.activate_code_lives=Activate code lives
+config.auth.reset_password_code_lives=Reset password code lives
+config.auth.require_email_confirm=Require email confirmation
+config.auth.require_sign_in_view=Require sign in view
+config.auth.disable_registration=Disable registration
+config.auth.enable_registration_captcha=Enable registration captcha
+config.auth.enable_reverse_proxy_authentication=Enable reverse proxy authentication
+config.auth.enable_reverse_proxy_auto_registration=Enable reverse proxy auto registration
+config.auth.reverse_proxy_authentication_header=Reverse proxy authentication header
+
+config.user_config=User configuration
+config.user.enable_email_notify=Enable email notification
 
-config.webhook_config=Webhook configuratie
-config.queue_length=Lengte van wachtrij
-config.deliver_timeout=Bezorging verlooptijd
-config.skip_tls_verify=TLS certificaat controle overslaan
-
-config.mailer_config=Mailerconfiguatie
-config.mailer_enabled=Ingeschakeld
-config.mailer_disable_helo=Schakel HELO uit
-config.mailer_subject_prefix=Subject Prefix
-config.mailer_host=Host
-config.mailer_user=Gebruiker
-config.send_test_mail=Testbericht verzenden
-config.test_mail_failed=Verzending van een testmail naar '%s' is mislukt: %v
-config.test_mail_sent=Test-email is verstuurd naar '%s'.
-
-config.oauth_config=OAuth-configuratie
-config.oauth_enabled=Ingeschakeld
+config.session_config=Sessieconfiguratie
+config.session.provider=Provider
+config.session.provider_config=Provider config
+config.session.cookie_name=Cookie
+config.session.https_only=HTTPS only
+config.session.gc_interval=GC interval
+config.session.max_life_time=Max life time
+config.session.csrf_cookie_name=CSRF cookie
 
 config.cache_config=Cache-configuratie
-config.cache_adapter=Cache-adapter
-config.cache_interval=Cache-interval
-config.cache_conn=Cache-connectie
-
-config.session_config=Sessieconfiguratie
-config.session_provider=Sessieprovider
-config.provider_config=Provider config
-config.cookie_name=Cookie naam
-config.enable_set_cookie=Set Cookie inschakelen
-config.gc_interval_time=GC interval time
-config.session_life_time=Sessie duur
-config.https_only=Alleen HTTPS
-config.cookie_life_time=Cookie duur leeftijd
+config.cache.adapter=Adapter
+config.cache.interval=GC interval
+config.cache.host=Host
+
+config.http_config=HTTP configuration
+config.http.access_control_allow_origin=Access control allow origin
+
+config.attachment_config=Attachment configuration
+config.attachment.enabled=Enabled
+config.attachment.path=Path
+config.attachment.allowed_types=Allowed types
+config.attachment.max_size=Size limit
+config.attachment.max_files=Files limit
+
+config.release_config=Release configuration
+config.release.attachment.enabled=Attachment enabled
+config.release.attachment.allowed_types=Attachment allowed types
+config.release.attachment.max_size=Attachment size limit
+config.release.attachment.max_files=Attachment files limit
 
 config.picture_config=Foto configuratie
-config.picture_service=Foto service
-config.disable_gravatar=Gravatar uitschakelen
-config.enable_federated_avatar=Federated Avatars toestaan
+config.picture.avatar_upload_path=User avatar upload path
+config.picture.repo_avatar_upload_path=Repository avatar upload path
+config.picture.gravatar_source=Gravatar source
+config.picture.disable_gravatar=Disable Gravatar
+config.picture.enable_federated_avatar=Enable federated avatars
+
+config.mirror_config=Mirror configuration
+config.mirror.default_interval=Default interval
+
+config.webhook_config=Webhook configuratie
+config.webhook.types=Types
+config.webhook.deliver_timeout=Deliver timeout
+config.webhook.skip_tls_verify=Skip TLS verify
 
 config.git_config=Gitconfiguratie
-config.git_disable_diff_highlight=Disable Diff Syntax Highlight
-config.git_max_diff_lines=Max Diff Lines (for a single file)
-config.git_max_diff_line_characters=Max Diff Characters (for a single line)
-config.git_max_diff_files=Max Diff Files (to be shown)
-config.git_gc_args=GC Arguments
-config.git_migrate_timeout=Migration Timeout
-config.git_mirror_timeout=Mirror Update Timeout
-config.git_clone_timeout=Clone Operation Timeout
-config.git_pull_timeout=Pull Operation Timeout
-config.git_gc_timeout=GC Operation Timeout
+config.git.disable_diff_highlight=Disable diff syntax highlight
+config.git.max_diff_lines=Diff lines limit (for a single file)
+config.git.max_diff_line_characters=Diff characters limit (for a single line)
+config.git.max_diff_files=Diff files limit (for a single diff)
+config.git.gc_args=GC arguments
+config.git.migrate_timeout=Migration timeout
+config.git.mirror_timeout=Mirror fetch timeout
+config.git.clone_timeout=Clone timeout
+config.git.pull_timeout=Pull timeout
+config.git.gc_timeout=GC timeout
 
 config.log_config=Logconfiguratie
+config.log_file_root_path=Log bestand basis pad
 config.log_mode=Mode
 config.log_options=Options
 
@@ -1338,6 +1397,7 @@ months=%d maanden %s
 years=%d jaren %s
 raw_seconds=seconden
 raw_minutes=minuten
+raw_hours=hours
 
 [dropzone]
 default_message=Drop bestanden hier of klik om te uploaden.

+ 154 - 94
conf/locale/locale_pl-PL.ini

@@ -9,7 +9,6 @@ sign_out=Wyloguj
 sign_up=Zarejestruj się
 register=Zarejestruj się
 website=Strona
-version=Wersja
 page=Strona
 template=Szablon
 language=Język
@@ -122,6 +121,7 @@ run_user_not_match=Użytkownik aplikacji nie jest aktualnym użytkownikiem: %s -
 smtp_host_missing_port=W SMTP Host brakuje portu w adresie.
 invalid_smtp_from=Pole SMTP OD nie jest prawidłowe: %v
 save_config_failed=Nie udało się zapisać konfiguracji: %v
+init_failed=Failed to initialize application: %v
 invalid_admin_setting=Nieprawidłowe ustawienia konta admina: %v
 install_success=Cześć! Cieszymy się, że wybierałeś GIN, baw się dobrze.
 invalid_log_root_path=Ścieżka dla logów jest niepoprawna: %v
@@ -1001,6 +1001,12 @@ first_page=Pierwsza
 last_page=Ostatnia
 total=Ogółem: %d
 
+dashboard.build_info=Build Information
+dashboard.app_ver=Application version
+dashboard.git_version=Git version
+dashboard.go_version=Go version
+dashboard.build_time=Build time
+dashboard.build_commit=Build commit
 dashboard.statistic=Statystyki
 dashboard.operations=Operacje
 dashboard.system_status=Stan monitora systemu
@@ -1156,117 +1162,170 @@ auths.github_api_endpoint=Punkt końcowy API
 
 config.not_set=(nie ustawiono)
 config.server_config=Konfiguracja serwera
-config.app_name=Nazwa aplikacji
-config.app_ver=Wersja aplikacji
-config.app_url=Adres URL aplikacji
-config.domain=Domena
-config.offline_mode=Tryb offline
-config.disable_router_log=Wyłącz dziennik routera
+config.brand_name=Brand name
 config.run_user=Użytkownik uruchomieniowy
 config.run_mode=Tryb uruchamienia
-config.git_version=Wersja Git
-config.static_file_root_path=Ścieżka plików statycznych
-config.log_file_root_path=Ścieżka plików dziennika
-config.reverse_auth_user=Użytkownik dostarczony przez odwrotne proxy
+config.server.external_url=External URL
+config.server.domain=Domain
+config.server.protocol=Protocol
+config.server.http_addr=HTTP address
+config.server.http_port=HTTP port
+config.server.cert_file=Certificate file
+config.server.key_file=Key file
+config.server.tls_min_version=Minimum TLS version
+config.server.unix_socket_permission=Unix socket permission
+config.server.local_root_url=Local root URL
+config.server.offline_mode=Offline mode
+config.server.disable_router_log=Disable router log
+config.server.enable_gzip=Enable Gzip
+config.server.app_data_path=Application data path
+config.server.load_assets_from_disk=Load assets from disk
+config.server.landing_url=Landing URL
 
 config.ssh_config=Konfiguracja SSH
-config.ssh_enabled=Aktywne
-config.ssh_start_builtin_server=Uruchom serwer wbudowany
-config.ssh_domain=Domena
-config.ssh_port=Port
-config.ssh_listen_port=Port nasłuchu
-config.ssh_root_path=Ścieżka katalogu głównego
-config.ssh_rewrite_authorized_keys_at_start=Przepisz authorized_keys przy uruchomieniu
-config.ssh_key_test_path=Ścieżka klucza testowego
-config.ssh_keygen_path=Ścieżka generatora ('ssh-keygen')
-config.ssh_minimum_key_size_check=Sprawdzanie minimalnej długości klucza
-config.ssh_minimum_key_sizes=Minimalne rozmiary kluczy
+config.ssh.enabled=Enabled
+config.ssh.domain=Exposed domain
+config.ssh.port=Exposed port
+config.ssh.root_path=Root path
+config.ssh.keygen_path=Keygen path
+config.ssh.key_test_path=Key test path
+config.ssh.minimum_key_size_check=Minimum key size check
+config.ssh.minimum_key_sizes=Minimum key sizes
+config.ssh.rewrite_authorized_keys_at_start=Rewrite "authorized_keys" at start
+config.ssh.start_builtin_server=Start builtin server
+config.ssh.listen_host=Listen host
+config.ssh.listen_port=Listen port
+config.ssh.server_ciphers=Server ciphers
 
 config.repo_config=Konfiguracja repozytorium
-config.repo_root_path=Ścieżka repozytoriów
-config.script_type=Typ skryptu
-config.repo_force_private=Forsuj tryb prywatny
-config.max_creation_limit=Maksymalny limit utworzeń
-config.preferred_licenses=Preferowane licencje
-config.disable_http_git=Wyłącz HTTP Git
-config.enable_local_path_migration=Włącz lokalną ścieżkę migracji
-config.commits_fetch_concurrency=Pobieraj zmiany w trybie równoległym
-
-config.http_config=Konfiguracja HTTP
-config.http_access_control_allow_origin=Kontrola Dostępu Uwzględnia Źródło
+config.repo.root_path=Root path
+config.repo.script_type=Script type
+config.repo.ansi_chatset=ANSI charset
+config.repo.force_private=Force private
+config.repo.max_creation_limit=Max creation limit
+config.repo.preferred_licenses=Preferred licenses
+config.repo.disable_http_git=Disable HTTP Git
+config.repo.enable_local_path_migration=Enable local path migration
+config.repo.enable_raw_file_render_mode=Enable raw file render mode
+config.repo.commits_fetch_concurrency=Commits fetch concurrency
+config.repo.editor.line_wrap_extensions=Editor line wrap extensions
+config.repo.editor.previewable_file_modes=Editor previewable file modes
+config.repo.upload.enabled=Upload enabled
+config.repo.upload.temp_path=Upload temporary path
+config.repo.upload.allowed_types=Upload allowed types
+config.repo.upload.file_max_size=Upload file size limit
+config.repo.upload.max_files=Upload files limit
 
 config.db_config=Konfiguracja bazy danych
-config.db_type=Typ
-config.db_host=Host
-config.db_name=Nazwa
-config.db_user=Użytkownik
-config.db_ssl_mode=Tryb SSL
-config.db_ssl_mode_helper=(tylko dla „postgres”)
-config.db_path=Ścieżka
-config.db_path_helper=(dla „sqlite3” i „tidb”)
-
-config.service_config=Konfiguracja usługi
-config.register_email_confirm=Wymagaj potwierdzenia e-mail
-config.disable_register=Wyłącz rejestrację
-config.show_registration_button=Pokazuj przycisk rejestracji
-config.require_sign_in_view=Wymagaj bycia zalogowanym
-config.mail_notify=Powiadomienia e-mail
-config.disable_key_size_check=Wyłącz sprawdzanie minimalnego rozmiaru klucza
-config.enable_captcha=Włącz Captcha
-config.active_code_lives=Ważność kodów aktywacyjnych
-config.reset_password_code_lives=Czas życia kodu resetowania hasła
+config.db.type=Type
+config.db.host=Host
+config.db.name=Name
+config.db.user=User
+config.db.ssl_mode=SSL mode
+config.db.ssl_mode_helper=(for "postgres" only)
+config.db.path=Path
+config.db.path_helper=(for "sqlite3"only)
+
+config.security_config=Security configuration
+config.security.login_remember_days=Login remember days
+config.security.cookie_remember_name=Remember cookie
+config.security.cookie_username=Username cookie
+config.security.cookie_secure=Enable secure cookie
+config.security.reverse_proxy_auth_user=Reverse proxy authentication header
+config.security.enable_login_status_cookie=Enable login status cookie
+config.security.login_status_cookie_name=Login status cookie
+
+config.email_config=Email configuration
+config.email.enabled=Enabled
+config.email.subject_prefix=Subject prefix
+config.email.host=Host
+config.email.from=From
+config.email.user=User
+config.email.disable_helo=Disable HELO
+config.email.helo_hostname=HELO hostname
+config.email.skip_verify=Skip certificate verify
+config.email.use_certificate=Use custom certificate
+config.email.cert_file=Certificate file
+config.email.key_file=Key file
+config.email.use_plain_text=Use plain text
+config.email.add_plain_text_alt=Add plain text alternative
+config.email.send_test_mail=Send test email
+config.email.test_mail_failed=Failed to send test email to '%s': %v
+config.email.test_mail_sent=Test email has been sent to '%s'.
+
+config.auth_config=Authentication configuration
+config.auth.activate_code_lives=Activate code lives
+config.auth.reset_password_code_lives=Reset password code lives
+config.auth.require_email_confirm=Require email confirmation
+config.auth.require_sign_in_view=Require sign in view
+config.auth.disable_registration=Disable registration
+config.auth.enable_registration_captcha=Enable registration captcha
+config.auth.enable_reverse_proxy_authentication=Enable reverse proxy authentication
+config.auth.enable_reverse_proxy_auto_registration=Enable reverse proxy auto registration
+config.auth.reverse_proxy_authentication_header=Reverse proxy authentication header
+
+config.user_config=User configuration
+config.user.enable_email_notify=Enable email notification
 
-config.webhook_config=Konfiguracja webhooka
-config.queue_length=Długość kolejki
-config.deliver_timeout=Limit czasu zdarzenia
-config.skip_tls_verify=Pomiń weryfikację protokołu TLS
-
-config.mailer_config=Konfiguracja poczty
-config.mailer_enabled=Aktywne
-config.mailer_disable_helo=Wyłącz HELO
-config.mailer_subject_prefix=Prefiks tematu
-config.mailer_host=Host
-config.mailer_user=Użytkownik
-config.send_test_mail=Wyślij email testowy
-config.test_mail_failed=Nieudane wysłanie wiadomości email do '%s': %v
-config.test_mail_sent=Testowa wiadomość email została wysłana do '%s'.
-
-config.oauth_config=Konfiguracja OAuth
-config.oauth_enabled=Aktywne
+config.session_config=Konfiguracja sesji
+config.session.provider=Provider
+config.session.provider_config=Provider config
+config.session.cookie_name=Cookie
+config.session.https_only=HTTPS only
+config.session.gc_interval=GC interval
+config.session.max_life_time=Max life time
+config.session.csrf_cookie_name=CSRF cookie
 
 config.cache_config=Konfiguracja cache
-config.cache_adapter=Adapter cache
-config.cache_interval=Interwał pamięci podręcznej
-config.cache_conn=Połączenie z pamięcią podręczną
+config.cache.adapter=Adapter
+config.cache.interval=GC interval
+config.cache.host=Host
 
-config.session_config=Konfiguracja sesji
-config.session_provider=Dostawca sesji
-config.provider_config=Konfiguracja dostawcy
-config.cookie_name=Nazwa ciasteczka
-config.enable_set_cookie=Włącz ciasteczka
-config.gc_interval_time=Interwał odśmiecania
-config.session_life_time=Czas życia sesji
-config.https_only=Tylko HTTPS
-config.cookie_life_time=Czas życia ciasteczka
+config.http_config=Konfiguracja HTTP
+config.http.access_control_allow_origin=Access control allow origin
+
+config.attachment_config=Attachment configuration
+config.attachment.enabled=Enabled
+config.attachment.path=Path
+config.attachment.allowed_types=Allowed types
+config.attachment.max_size=Size limit
+config.attachment.max_files=Files limit
+
+config.release_config=Release configuration
+config.release.attachment.enabled=Attachment enabled
+config.release.attachment.allowed_types=Attachment allowed types
+config.release.attachment.max_size=Attachment size limit
+config.release.attachment.max_files=Attachment files limit
 
 config.picture_config=Ustawienia obrazów
-config.picture_service=Serwis obrazów
-config.disable_gravatar=Wyłącz Gravatara
-config.enable_federated_avatar=Włącz zewnętrzne avatary
+config.picture.avatar_upload_path=User avatar upload path
+config.picture.repo_avatar_upload_path=Repository avatar upload path
+config.picture.gravatar_source=Gravatar source
+config.picture.disable_gravatar=Disable Gravatar
+config.picture.enable_federated_avatar=Enable federated avatars
+
+config.mirror_config=Mirror configuration
+config.mirror.default_interval=Default interval
+
+config.webhook_config=Konfiguracja webhooka
+config.webhook.types=Types
+config.webhook.deliver_timeout=Deliver timeout
+config.webhook.skip_tls_verify=Skip TLS verify
 
 config.git_config=Konfiguracja Git
-config.git_disable_diff_highlight=Wyłączyć wyróżnianie składni diff
-config.git_max_diff_lines=Maksymalna ilość linii diff (dla pojedynczego pliku)
-config.git_max_diff_line_characters=Maksymalna ilość znaków diff (dla pojedynczego pliku)
-config.git_max_diff_files=Maksymalna ilość plików diff (które zostaną wyświetlone)
-config.git_gc_args=Argumenty GC
-config.git_migrate_timeout=Limit czasu migracji
-config.git_mirror_timeout=Limit czasu aktualizacji kopii lustrzanej
-config.git_clone_timeout=Limit czasu operacji klonowania
-config.git_pull_timeout=Limit czasu dla operacji pull
-config.git_gc_timeout=Limit czasu odśmiecania pamięci
+config.git.disable_diff_highlight=Disable diff syntax highlight
+config.git.max_diff_lines=Diff lines limit (for a single file)
+config.git.max_diff_line_characters=Diff characters limit (for a single line)
+config.git.max_diff_files=Diff files limit (for a single diff)
+config.git.gc_args=GC arguments
+config.git.migrate_timeout=Migration timeout
+config.git.mirror_timeout=Mirror fetch timeout
+config.git.clone_timeout=Clone timeout
+config.git.pull_timeout=Pull timeout
+config.git.gc_timeout=GC timeout
 
 config.log_config=Konfiguracja dziennika
+config.log_file_root_path=Ścieżka plików dziennika
 config.log_mode=Tryb
 config.log_options=Ustawienia
 
@@ -1338,6 +1397,7 @@ months=%d miesięcy %s
 years=%d lat %s
 raw_seconds=sekund
 raw_minutes=minut
+raw_hours=hours
 
 [dropzone]
 default_message=Upuść pliki tutaj lub kliknij, aby przesłać.

+ 154 - 94
conf/locale/locale_pt-BR.ini

@@ -9,7 +9,6 @@ sign_out=Sair
 sign_up=Cadastrar
 register=Registrar
 website=Site
-version=Versão
 page=Página
 template=Modelo
 language=Idioma
@@ -122,6 +121,7 @@ run_user_not_match=O usuário da execução não é o usuário atual: %s -> %s
 smtp_host_missing_port=O endereço do host SMTP não possui porta.
 invalid_smtp_from=O SMTP do campo não é válido: %v
 save_config_failed=Falha ao salvar a configuração: %v
+init_failed=Failed to initialize application: %v
 invalid_admin_setting=Configuração da conta de administrador está inválida: %v
 install_success=Bem-vindo! Estamos contentes que você escolheu o GIN, divirta-se e tenha cuidado.
 invalid_log_root_path=Pasta raíz do log é inválida: %v
@@ -1001,6 +1001,12 @@ first_page=Primeira
 last_page=Última
 total=Total: %d
 
+dashboard.build_info=Build Information
+dashboard.app_ver=Application version
+dashboard.git_version=Git version
+dashboard.go_version=Go version
+dashboard.build_time=Build time
+dashboard.build_commit=Build commit
 dashboard.statistic=Estatística
 dashboard.operations=Operações
 dashboard.system_status=Status do monitor de sistema
@@ -1156,117 +1162,170 @@ auths.github_api_endpoint=API Endpoint
 
 config.not_set=(não definido)
 config.server_config=Configuração do servidor
-config.app_name=Nome do aplicativo
-config.app_ver=Versão do aplicativo
-config.app_url=URL do aplicativo
-config.domain=Domínio
-config.offline_mode=Modo Offline
-config.disable_router_log=Desabilitar o Log do router
+config.brand_name=Brand name
 config.run_user=Usuário de execução
 config.run_mode=Modo de execução
-config.git_version=Versão do Git
-config.static_file_root_path=Caminho raiz para arquivo estático
-config.log_file_root_path=Caminho raiz para arquivo de log
-config.reverse_auth_user=Usuário de autenticação reversa
+config.server.external_url=External URL
+config.server.domain=Domain
+config.server.protocol=Protocol
+config.server.http_addr=HTTP address
+config.server.http_port=HTTP port
+config.server.cert_file=Certificate file
+config.server.key_file=Key file
+config.server.tls_min_version=Minimum TLS version
+config.server.unix_socket_permission=Unix socket permission
+config.server.local_root_url=Local root URL
+config.server.offline_mode=Offline mode
+config.server.disable_router_log=Disable router log
+config.server.enable_gzip=Enable Gzip
+config.server.app_data_path=Application data path
+config.server.load_assets_from_disk=Load assets from disk
+config.server.landing_url=Landing URL
 
 config.ssh_config=Configuração de SSH
-config.ssh_enabled=Habilitado
-config.ssh_start_builtin_server=Iniciar servidor embutido
-config.ssh_domain=Domínio
-config.ssh_port=Porta
-config.ssh_listen_port=Porta de escuta
-config.ssh_root_path=Caminho da raiz
-config.ssh_rewrite_authorized_keys_at_start=Rewrite authorized_keys At Start
-config.ssh_key_test_path=Caminho da chave de teste
-config.ssh_keygen_path=Caminho do keygen ('ssh-keygen')
-config.ssh_minimum_key_size_check=Verificar tamanho mínimo da chave
-config.ssh_minimum_key_sizes=Tamanhos mínimos da chave
+config.ssh.enabled=Enabled
+config.ssh.domain=Exposed domain
+config.ssh.port=Exposed port
+config.ssh.root_path=Root path
+config.ssh.keygen_path=Keygen path
+config.ssh.key_test_path=Key test path
+config.ssh.minimum_key_size_check=Minimum key size check
+config.ssh.minimum_key_sizes=Minimum key sizes
+config.ssh.rewrite_authorized_keys_at_start=Rewrite "authorized_keys" at start
+config.ssh.start_builtin_server=Start builtin server
+config.ssh.listen_host=Listen host
+config.ssh.listen_port=Listen port
+config.ssh.server_ciphers=Server ciphers
 
 config.repo_config=Configuração do Repositório
-config.repo_root_path=Caminho raiz do repositório
-config.script_type=Tipo de script
-config.repo_force_private=Forçar Privado
-config.max_creation_limit=Limite de Criação
-config.preferred_licenses=Licenças Preferidas
-config.disable_http_git=Desabilitar Git por HTTP
-config.enable_local_path_migration=Permitir a migração de caminho local
-config.commits_fetch_concurrency=Commits Fetch Concurrency
-
-config.http_config=Configuração de HTTP
-config.http_access_control_allow_origin=Access Control Allow Origin
+config.repo.root_path=Root path
+config.repo.script_type=Script type
+config.repo.ansi_chatset=ANSI charset
+config.repo.force_private=Force private
+config.repo.max_creation_limit=Max creation limit
+config.repo.preferred_licenses=Preferred licenses
+config.repo.disable_http_git=Disable HTTP Git
+config.repo.enable_local_path_migration=Enable local path migration
+config.repo.enable_raw_file_render_mode=Enable raw file render mode
+config.repo.commits_fetch_concurrency=Commits fetch concurrency
+config.repo.editor.line_wrap_extensions=Editor line wrap extensions
+config.repo.editor.previewable_file_modes=Editor previewable file modes
+config.repo.upload.enabled=Upload enabled
+config.repo.upload.temp_path=Upload temporary path
+config.repo.upload.allowed_types=Upload allowed types
+config.repo.upload.file_max_size=Upload file size limit
+config.repo.upload.max_files=Upload files limit
 
 config.db_config=Configuração do banco de dados
-config.db_type=Tipo
-config.db_host=Host
-config.db_name=Nome
-config.db_user=Usuário
-config.db_ssl_mode=Modo SSL
-config.db_ssl_mode_helper=(apenas para "postgres")
-config.db_path=Caminho
-config.db_path_helper=(para "sqlite3" e "tidb")
-
-config.service_config=Configuração do serviço
-config.register_email_confirm=Requerer confirmação de e-mail
-config.disable_register=Desabilitar registro
-config.show_registration_button=Mostrar botão de registo
-config.require_sign_in_view=Requerer entrar no GIN para visualizar
-config.mail_notify=Notificação de e-mail
-config.disable_key_size_check=Desativar verificação de tamanho mínimo da chave
-config.enable_captcha=Habilitar o captcha
-config.active_code_lives=Ativar Code Lives
-config.reset_password_code_lives=Redefinir senha de Code Lives
+config.db.type=Type
+config.db.host=Host
+config.db.name=Name
+config.db.user=User
+config.db.ssl_mode=SSL mode
+config.db.ssl_mode_helper=(for "postgres" only)
+config.db.path=Path
+config.db.path_helper=(for "sqlite3"only)
+
+config.security_config=Security configuration
+config.security.login_remember_days=Login remember days
+config.security.cookie_remember_name=Remember cookie
+config.security.cookie_username=Username cookie
+config.security.cookie_secure=Enable secure cookie
+config.security.reverse_proxy_auth_user=Reverse proxy authentication header
+config.security.enable_login_status_cookie=Enable login status cookie
+config.security.login_status_cookie_name=Login status cookie
+
+config.email_config=Email configuration
+config.email.enabled=Enabled
+config.email.subject_prefix=Subject prefix
+config.email.host=Host
+config.email.from=From
+config.email.user=User
+config.email.disable_helo=Disable HELO
+config.email.helo_hostname=HELO hostname
+config.email.skip_verify=Skip certificate verify
+config.email.use_certificate=Use custom certificate
+config.email.cert_file=Certificate file
+config.email.key_file=Key file
+config.email.use_plain_text=Use plain text
+config.email.add_plain_text_alt=Add plain text alternative
+config.email.send_test_mail=Send test email
+config.email.test_mail_failed=Failed to send test email to '%s': %v
+config.email.test_mail_sent=Test email has been sent to '%s'.
+
+config.auth_config=Authentication configuration
+config.auth.activate_code_lives=Activate code lives
+config.auth.reset_password_code_lives=Reset password code lives
+config.auth.require_email_confirm=Require email confirmation
+config.auth.require_sign_in_view=Require sign in view
+config.auth.disable_registration=Disable registration
+config.auth.enable_registration_captcha=Enable registration captcha
+config.auth.enable_reverse_proxy_authentication=Enable reverse proxy authentication
+config.auth.enable_reverse_proxy_auto_registration=Enable reverse proxy auto registration
+config.auth.reverse_proxy_authentication_header=Reverse proxy authentication header
+
+config.user_config=User configuration
+config.user.enable_email_notify=Enable email notification
 
-config.webhook_config=Configuração de Hook da Web
-config.queue_length=Tamanho da fila
-config.deliver_timeout=Intervalo de entrega
-config.skip_tls_verify=Pular verificação de TLS
-
-config.mailer_config=Configuração de envio de e-mail
-config.mailer_enabled=Habilitado
-config.mailer_disable_helo=Desabilitar HELO
-config.mailer_subject_prefix=Prefixo do Assunto
-config.mailer_host=Host
-config.mailer_user=Usuário
-config.send_test_mail=Enviar email de teste
-config.test_mail_failed=Falha ao enviar o email de teste para '%s': %v
-config.test_mail_sent=O email de teste foi enviado para '%s'.
-
-config.oauth_config=Configuração do OAuth
-config.oauth_enabled=Habilitado
+config.session_config=Configuração da sessão
+config.session.provider=Provider
+config.session.provider_config=Provider config
+config.session.cookie_name=Cookie
+config.session.https_only=HTTPS only
+config.session.gc_interval=GC interval
+config.session.max_life_time=Max life time
+config.session.csrf_cookie_name=CSRF cookie
 
 config.cache_config=Configuração de cache
-config.cache_adapter=Adaptador de cache
-config.cache_interval=Intervalo de cache
-config.cache_conn=Conexão de cache
+config.cache.adapter=Adapter
+config.cache.interval=GC interval
+config.cache.host=Host
 
-config.session_config=Configuração da sessão
-config.session_provider=Provedor da sessão
-config.provider_config=Configuração do provedor
-config.cookie_name=Nome do cookie
-config.enable_set_cookie=Habilitar uso de cookie
-config.gc_interval_time=Tempo de Intervalo do GC
-config.session_life_time=Tempo de vida da sessão
-config.https_only=Apenas HTTPS
-config.cookie_life_time=Tempo de vida do cookie
+config.http_config=Configuração de HTTP
+config.http.access_control_allow_origin=Access control allow origin
+
+config.attachment_config=Attachment configuration
+config.attachment.enabled=Enabled
+config.attachment.path=Path
+config.attachment.allowed_types=Allowed types
+config.attachment.max_size=Size limit
+config.attachment.max_files=Files limit
+
+config.release_config=Release configuration
+config.release.attachment.enabled=Attachment enabled
+config.release.attachment.allowed_types=Attachment allowed types
+config.release.attachment.max_size=Attachment size limit
+config.release.attachment.max_files=Attachment files limit
 
 config.picture_config=Configuração da imagem
-config.picture_service=Serviço de imagens
-config.disable_gravatar=Desativar Gravatar
-config.enable_federated_avatar=Habilitar avatares federativos
+config.picture.avatar_upload_path=User avatar upload path
+config.picture.repo_avatar_upload_path=Repository avatar upload path
+config.picture.gravatar_source=Gravatar source
+config.picture.disable_gravatar=Disable Gravatar
+config.picture.enable_federated_avatar=Enable federated avatars
+
+config.mirror_config=Mirror configuration
+config.mirror.default_interval=Default interval
+
+config.webhook_config=Configuração de Hook da Web
+config.webhook.types=Types
+config.webhook.deliver_timeout=Deliver timeout
+config.webhook.skip_tls_verify=Skip TLS verify
 
 config.git_config=Configuração do Git
-config.git_disable_diff_highlight=Habilitar realce de mudanças no diff
-config.git_max_diff_lines=Máximo de linhas mostradas no diff (para um único arquivo)
-config.git_max_diff_line_characters=Máximo de caracteres mostrados no diff (para uma única linha)
-config.git_max_diff_files=Máximo de arquivos a serem mostrados no diff
-config.git_gc_args=Argumentos do GC
-config.git_migrate_timeout=Timeout de migração
-config.git_mirror_timeout=Timeout para sincronização de mirror
-config.git_clone_timeout=Timeout para operação de clone
-config.git_pull_timeout=Timeout para operação de pull
-config.git_gc_timeout=Timeout para execução do GC
+config.git.disable_diff_highlight=Disable diff syntax highlight
+config.git.max_diff_lines=Diff lines limit (for a single file)
+config.git.max_diff_line_characters=Diff characters limit (for a single line)
+config.git.max_diff_files=Diff files limit (for a single diff)
+config.git.gc_args=GC arguments
+config.git.migrate_timeout=Migration timeout
+config.git.mirror_timeout=Mirror fetch timeout
+config.git.clone_timeout=Clone timeout
+config.git.pull_timeout=Pull timeout
+config.git.gc_timeout=GC timeout
 
 config.log_config=Configuração de log
+config.log_file_root_path=Caminho raiz para arquivo de log
 config.log_mode=Modo
 config.log_options=Opções
 
@@ -1338,6 +1397,7 @@ months=%d meses %s
 years=%d anos %s
 raw_seconds=segundos
 raw_minutes=minutos
+raw_hours=hours
 
 [dropzone]
 default_message=Arraste e solte arquivos aqui, ou clique para selecioná-los.

+ 154 - 94
conf/locale/locale_pt-PT.ini

@@ -9,7 +9,6 @@ sign_out=Terminar Sessão
 sign_up=Criar conta
 register=Registe-se
 website=Site Web
-version=Versão
 page=Página
 template=Modelo
 language=Língua
@@ -122,6 +121,7 @@ run_user_not_match=O utilizador de execução não é igual ao utilizador actual
 smtp_host_missing_port=Porta em falta no endereço SMTP.
 invalid_smtp_from=Campo SMTP From inválido: %v
 save_config_failed=Falha ao salvar a configuração: %v
+init_failed=Failed to initialize application: %v
 invalid_admin_setting=Configuração do utilizador de administração está inválida: %v
 install_success=Bem-vindo! Estamos contentes por ter escolhido o Gogs, esperemos que goste.
 invalid_log_root_path=Caminho da pasta de logs inválida: %v
@@ -1001,6 +1001,12 @@ first_page=Primeiro
 last_page=Último
 total=Total: %d
 
+dashboard.build_info=Build Information
+dashboard.app_ver=Application version
+dashboard.git_version=Git version
+dashboard.go_version=Go version
+dashboard.build_time=Build time
+dashboard.build_commit=Build commit
 dashboard.statistic=Estatísticas
 dashboard.operations=Operações
 dashboard.system_status=Monitorização de estado do sistema
@@ -1156,117 +1162,170 @@ auths.github_api_endpoint=Endpoint da API
 
 config.not_set=(não definido)
 config.server_config=Configuração do Servidor
-config.app_name=Nome da Aplicação
-config.app_ver=Versão da Aplicação
-config.app_url=URL da Aplicação
-config.domain=Domínio
-config.offline_mode=Modo Offline
-config.disable_router_log=Desativar o Log do Router
+config.brand_name=Brand name
 config.run_user=Utilizador de execução
 config.run_mode=Mode de execução
-config.git_version=Versão Git
-config.static_file_root_path=Caminho Root Estático
-config.log_file_root_path=Caminho Raiz para Ficheiro Log
-config.reverse_auth_user=Utilizador de Autenticação Inversa
+config.server.external_url=External URL
+config.server.domain=Domain
+config.server.protocol=Protocol
+config.server.http_addr=HTTP address
+config.server.http_port=HTTP port
+config.server.cert_file=Certificate file
+config.server.key_file=Key file
+config.server.tls_min_version=Minimum TLS version
+config.server.unix_socket_permission=Unix socket permission
+config.server.local_root_url=Local root URL
+config.server.offline_mode=Offline mode
+config.server.disable_router_log=Disable router log
+config.server.enable_gzip=Enable Gzip
+config.server.app_data_path=Application data path
+config.server.load_assets_from_disk=Load assets from disk
+config.server.landing_url=Landing URL
 
 config.ssh_config=Configuração SSH
-config.ssh_enabled=Ativado
-config.ssh_start_builtin_server=Iniciar Servidor Embutido
-config.ssh_domain=Domínio
-config.ssh_port=Porta
-config.ssh_listen_port=Porta
-config.ssh_root_path=Caminho para raiz
-config.ssh_rewrite_authorized_keys_at_start=Reescrever authorized_keys no inicio
-config.ssh_key_test_path=Caminho da Chave de Teste
-config.ssh_keygen_path=Caminho do Keygen ('ssh-keygen')
-config.ssh_minimum_key_size_check=Verificar Tamanho Mínimo da Chave
-config.ssh_minimum_key_sizes=Tamanho minimo de chave
+config.ssh.enabled=Enabled
+config.ssh.domain=Exposed domain
+config.ssh.port=Exposed port
+config.ssh.root_path=Root path
+config.ssh.keygen_path=Keygen path
+config.ssh.key_test_path=Key test path
+config.ssh.minimum_key_size_check=Minimum key size check
+config.ssh.minimum_key_sizes=Minimum key sizes
+config.ssh.rewrite_authorized_keys_at_start=Rewrite "authorized_keys" at start
+config.ssh.start_builtin_server=Start builtin server
+config.ssh.listen_host=Listen host
+config.ssh.listen_port=Listen port
+config.ssh.server_ciphers=Server ciphers
 
 config.repo_config=Configuração de repositório
-config.repo_root_path=Caminho Raiz do Repositório
-config.script_type=Tipo de Script
-config.repo_force_private=Forçar Privado
-config.max_creation_limit=Limite Maximo de Criação
-config.preferred_licenses=Licensas preferenciais
-config.disable_http_git=Desativar HTTP Git
-config.enable_local_path_migration=Permitir a Migração de Caminho Local
-config.commits_fetch_concurrency=Concorrência de Commits Fetch
-
-config.http_config=Configuração HTTP
-config.http_access_control_allow_origin=Controle de Acesso Allow Origin
+config.repo.root_path=Root path
+config.repo.script_type=Script type
+config.repo.ansi_chatset=ANSI charset
+config.repo.force_private=Force private
+config.repo.max_creation_limit=Max creation limit
+config.repo.preferred_licenses=Preferred licenses
+config.repo.disable_http_git=Disable HTTP Git
+config.repo.enable_local_path_migration=Enable local path migration
+config.repo.enable_raw_file_render_mode=Enable raw file render mode
+config.repo.commits_fetch_concurrency=Commits fetch concurrency
+config.repo.editor.line_wrap_extensions=Editor line wrap extensions
+config.repo.editor.previewable_file_modes=Editor previewable file modes
+config.repo.upload.enabled=Upload enabled
+config.repo.upload.temp_path=Upload temporary path
+config.repo.upload.allowed_types=Upload allowed types
+config.repo.upload.file_max_size=Upload file size limit
+config.repo.upload.max_files=Upload files limit
 
 config.db_config=Configuração da base de dados
-config.db_type=Tipo
-config.db_host=Anfitrião
-config.db_name=Nome
-config.db_user=Utilizador
-config.db_ssl_mode=Modo SSL
-config.db_ssl_mode_helper=(apenas para "postgres")
-config.db_path=Caminho
-config.db_path_helper=(para "sqlite3" e "tidb")
-
-config.service_config=Configuração do Servidor
-config.register_email_confirm=Requer confirmação por email
-config.disable_register=Desactivar registo
-config.show_registration_button=Mostrar botão de registo
-config.require_sign_in_view=Requerer Entrar Para Visualizar
-config.mail_notify=Notificação de e-mail
-config.disable_key_size_check=Desativar Verificação de Tamanho Mínimo da Chave
-config.enable_captcha=Activar o Captcha
-config.active_code_lives=Code Lives Ativos
-config.reset_password_code_lives=Redefinir Senha de Code Lives
+config.db.type=Type
+config.db.host=Host
+config.db.name=Name
+config.db.user=User
+config.db.ssl_mode=SSL mode
+config.db.ssl_mode_helper=(for "postgres" only)
+config.db.path=Path
+config.db.path_helper=(for "sqlite3"only)
+
+config.security_config=Security configuration
+config.security.login_remember_days=Login remember days
+config.security.cookie_remember_name=Remember cookie
+config.security.cookie_username=Username cookie
+config.security.cookie_secure=Enable secure cookie
+config.security.reverse_proxy_auth_user=Reverse proxy authentication header
+config.security.enable_login_status_cookie=Enable login status cookie
+config.security.login_status_cookie_name=Login status cookie
+
+config.email_config=Email configuration
+config.email.enabled=Enabled
+config.email.subject_prefix=Subject prefix
+config.email.host=Host
+config.email.from=From
+config.email.user=User
+config.email.disable_helo=Disable HELO
+config.email.helo_hostname=HELO hostname
+config.email.skip_verify=Skip certificate verify
+config.email.use_certificate=Use custom certificate
+config.email.cert_file=Certificate file
+config.email.key_file=Key file
+config.email.use_plain_text=Use plain text
+config.email.add_plain_text_alt=Add plain text alternative
+config.email.send_test_mail=Send test email
+config.email.test_mail_failed=Failed to send test email to '%s': %v
+config.email.test_mail_sent=Test email has been sent to '%s'.
+
+config.auth_config=Authentication configuration
+config.auth.activate_code_lives=Activate code lives
+config.auth.reset_password_code_lives=Reset password code lives
+config.auth.require_email_confirm=Require email confirmation
+config.auth.require_sign_in_view=Require sign in view
+config.auth.disable_registration=Disable registration
+config.auth.enable_registration_captcha=Enable registration captcha
+config.auth.enable_reverse_proxy_authentication=Enable reverse proxy authentication
+config.auth.enable_reverse_proxy_auto_registration=Enable reverse proxy auto registration
+config.auth.reverse_proxy_authentication_header=Reverse proxy authentication header
+
+config.user_config=User configuration
+config.user.enable_email_notify=Enable email notification
 
-config.webhook_config=Configuração de WebHook
-config.queue_length=Tamanho da Fila
-config.deliver_timeout=Tempo Limite de Entrega
-config.skip_tls_verify=Pular Verificação de TLS
-
-config.mailer_config=Configuração de E-mail
-config.mailer_enabled=Ativado
-config.mailer_disable_helo=Desativar HELO
-config.mailer_subject_prefix=Prefixo de assunto
-config.mailer_host=Anfitrião
-config.mailer_user=Utilizador
-config.send_test_mail=Enviar email de teste
-config.test_mail_failed=Falhou o envio do email de teste para '%s': %v
-config.test_mail_sent=O email de teste foi enviado para '%s'.
-
-config.oauth_config=Configuração OAuth
-config.oauth_enabled=Ativado
+config.session_config=Configuração de sessão
+config.session.provider=Provider
+config.session.provider_config=Provider config
+config.session.cookie_name=Cookie
+config.session.https_only=HTTPS only
+config.session.gc_interval=GC interval
+config.session.max_life_time=Max life time
+config.session.csrf_cookie_name=CSRF cookie
 
 config.cache_config=Configuração de cache
-config.cache_adapter=Adaptador de cache
-config.cache_interval=Último de cache
-config.cache_conn=Conexão de cache
+config.cache.adapter=Adapter
+config.cache.interval=GC interval
+config.cache.host=Host
 
-config.session_config=Configuração de sessão
-config.session_provider=Provedor de sessão
-config.provider_config=Provedor Config
-config.cookie_name=Nome do cookie
-config.enable_set_cookie=Ativar Set Cookie
-config.gc_interval_time=Tempo de Intervalo do GC
-config.session_life_time=Duração de sessão
-config.https_only=Apenas HTTPS
-config.cookie_life_time=Tempo de Vida do Cookie
+config.http_config=Configuração HTTP
+config.http.access_control_allow_origin=Access control allow origin
+
+config.attachment_config=Attachment configuration
+config.attachment.enabled=Enabled
+config.attachment.path=Path
+config.attachment.allowed_types=Allowed types
+config.attachment.max_size=Size limit
+config.attachment.max_files=Files limit
+
+config.release_config=Release configuration
+config.release.attachment.enabled=Attachment enabled
+config.release.attachment.allowed_types=Attachment allowed types
+config.release.attachment.max_size=Attachment size limit
+config.release.attachment.max_files=Attachment files limit
 
 config.picture_config=Configuração de imagem
-config.picture_service=Serviço de imagem
-config.disable_gravatar=Desativar Gravatar
-config.enable_federated_avatar=Ativar Avatares Federados
+config.picture.avatar_upload_path=User avatar upload path
+config.picture.repo_avatar_upload_path=Repository avatar upload path
+config.picture.gravatar_source=Gravatar source
+config.picture.disable_gravatar=Disable Gravatar
+config.picture.enable_federated_avatar=Enable federated avatars
+
+config.mirror_config=Mirror configuration
+config.mirror.default_interval=Default interval
+
+config.webhook_config=Configuração de WebHook
+config.webhook.types=Types
+config.webhook.deliver_timeout=Deliver timeout
+config.webhook.skip_tls_verify=Skip TLS verify
 
 config.git_config=Configuração Git
-config.git_disable_diff_highlight=Desativar Realce de Sintaxe no diff
-config.git_max_diff_lines=Numero Máximo de Linhas no diff (para um único ficheiro)
-config.git_max_diff_line_characters=Numero Máximo de Caracteres no diff (para uma única linha)
-config.git_max_diff_files=Numero Máximo de Ficheiros no diff (a serem mostrados)
-config.git_gc_args=Argumentos GC
-config.git_migrate_timeout=Tempo de migrção
-config.git_mirror_timeout=Tempo Limite para Atualização de Mirror
-config.git_clone_timeout=Tempo Limite para Operação de Clone
-config.git_pull_timeout=Tempo Limite para Operação de Pull
-config.git_gc_timeout=Tempo Limite para Execução do GC
+config.git.disable_diff_highlight=Disable diff syntax highlight
+config.git.max_diff_lines=Diff lines limit (for a single file)
+config.git.max_diff_line_characters=Diff characters limit (for a single line)
+config.git.max_diff_files=Diff files limit (for a single diff)
+config.git.gc_args=GC arguments
+config.git.migrate_timeout=Migration timeout
+config.git.mirror_timeout=Mirror fetch timeout
+config.git.clone_timeout=Clone timeout
+config.git.pull_timeout=Pull timeout
+config.git.gc_timeout=GC timeout
 
 config.log_config=Configuração de Log
+config.log_file_root_path=Caminho Raiz para Ficheiro Log
 config.log_mode=Modo
 config.log_options=Opções
 
@@ -1338,6 +1397,7 @@ months=há %d meses %s
 years=há %d anos %s
 raw_seconds=segundos
 raw_minutes=minutos
+raw_hours=hours
 
 [dropzone]
 default_message=Coloque os ficheiros aqui ou clique em enviar.

+ 154 - 94
conf/locale/locale_ru-RU.ini

@@ -9,7 +9,6 @@ sign_out=Выход
 sign_up=Регистрация
 register=Регистрация
 website=Веб-сайт
-version=Версия
 page=Страница
 template=Шаблон
 language=Язык
@@ -122,6 +121,7 @@ run_user_not_match=Текущий пользователь не является
 smtp_host_missing_port=Не указан порт в адресе хоста SMTP.
 invalid_smtp_from=Поле SMTP From неправильное: %v
 save_config_failed=Не удалось сохранить конфигурацию: %v
+init_failed=Failed to initialize application: %v
 invalid_admin_setting=Указан недопустимый параметр учетной записи администратора: %v
 install_success=Добро пожаловать! Мы рады, что вы выбрали GIN. Веселитесь и берегите себя.
 invalid_log_root_path=Недопустимый путь для логов: %v
@@ -1001,6 +1001,12 @@ first_page=Первый
 last_page=Последний
 total=Всего: %d
 
+dashboard.build_info=Build Information
+dashboard.app_ver=Application version
+dashboard.git_version=Git version
+dashboard.go_version=Go version
+dashboard.build_time=Build time
+dashboard.build_commit=Build commit
 dashboard.statistic=Статистика
 dashboard.operations=Операции
 dashboard.system_status=Статус системного монитора
@@ -1156,117 +1162,170 @@ auths.github_api_endpoint=Конечная точка API
 
 config.not_set=(не задано)
 config.server_config=Конфигурация сервера
-config.app_name=Имя приложения
-config.app_ver=Версия приложения
-config.app_url=URL приложения
-config.domain=Домен
-config.offline_mode=Автономный режим
-config.disable_router_log=Отключение журнала маршрутизатора
+config.brand_name=Brand name
 config.run_user=Запуск пользователем
 config.run_mode=Режим выполнения
-config.git_version=Версия Git
-config.static_file_root_path=Статичный путь до файла
-config.log_file_root_path=Путь до папки с логами
-config.reverse_auth_user=Заголовок с именем пользователя для авторизации на reverse proxy
+config.server.external_url=External URL
+config.server.domain=Domain
+config.server.protocol=Protocol
+config.server.http_addr=HTTP address
+config.server.http_port=HTTP port
+config.server.cert_file=Certificate file
+config.server.key_file=Key file
+config.server.tls_min_version=Minimum TLS version
+config.server.unix_socket_permission=Unix socket permission
+config.server.local_root_url=Local root URL
+config.server.offline_mode=Offline mode
+config.server.disable_router_log=Disable router log
+config.server.enable_gzip=Enable Gzip
+config.server.app_data_path=Application data path
+config.server.load_assets_from_disk=Load assets from disk
+config.server.landing_url=Landing URL
 
 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_rewrite_authorized_keys_at_start=Перезаписать authorized_keys при запуске
-config.ssh_key_test_path=Путь к тестовому ключу
-config.ssh_keygen_path=Путь к генератору ключей ('ssh-keygen')
-config.ssh_minimum_key_size_check=Минимальный размер ключа проверки
-config.ssh_minimum_key_sizes=Минимальные размеры ключа
+config.ssh.enabled=Enabled
+config.ssh.domain=Exposed domain
+config.ssh.port=Exposed port
+config.ssh.root_path=Root path
+config.ssh.keygen_path=Keygen path
+config.ssh.key_test_path=Key test path
+config.ssh.minimum_key_size_check=Minimum key size check
+config.ssh.minimum_key_sizes=Minimum key sizes
+config.ssh.rewrite_authorized_keys_at_start=Rewrite "authorized_keys" at start
+config.ssh.start_builtin_server=Start builtin server
+config.ssh.listen_host=Listen host
+config.ssh.listen_port=Listen port
+config.ssh.server_ciphers=Server ciphers
 
 config.repo_config=Настройка репозитория
-config.repo_root_path=Путь до корня репозитория
-config.script_type=Тип сценария
-config.repo_force_private=Сделать личным принудительно
-config.max_creation_limit=Лимит созданий
-config.preferred_licenses=Предпочитаемые лицензии
-config.disable_http_git=Выключить HTTP Git
-config.enable_local_path_migration=Включить миграцию с локального пути
-config.commits_fetch_concurrency=Параллельность получения коммитов
-
-config.http_config=Конфигурация HTTP
-config.http_access_control_allow_origin=Содержимое заголовка Access Control Allow Origin
+config.repo.root_path=Root path
+config.repo.script_type=Script type
+config.repo.ansi_chatset=ANSI charset
+config.repo.force_private=Force private
+config.repo.max_creation_limit=Max creation limit
+config.repo.preferred_licenses=Preferred licenses
+config.repo.disable_http_git=Disable HTTP Git
+config.repo.enable_local_path_migration=Enable local path migration
+config.repo.enable_raw_file_render_mode=Enable raw file render mode
+config.repo.commits_fetch_concurrency=Commits fetch concurrency
+config.repo.editor.line_wrap_extensions=Editor line wrap extensions
+config.repo.editor.previewable_file_modes=Editor previewable file modes
+config.repo.upload.enabled=Upload enabled
+config.repo.upload.temp_path=Upload temporary path
+config.repo.upload.allowed_types=Upload allowed types
+config.repo.upload.file_max_size=Upload file size limit
+config.repo.upload.max_files=Upload files limit
 
 config.db_config=Конфигурация базы данных
-config.db_type=Тип
-config.db_host=Хост
-config.db_name=Имя
-config.db_user=Пользователь
-config.db_ssl_mode=Режим SSL
-config.db_ssl_mode_helper=(только для «postgres»)
-config.db_path=Путь
-config.db_path_helper=(для "SQLite3" и "TiDB")
-
-config.service_config=Сервисная конфигурация
-config.register_email_confirm=Требуется подтверждение по электронной почте
-config.disable_register=Отключить регистрацию
-config.show_registration_button=Показать кнопку регистрации
-config.require_sign_in_view=Для просмотра необходима авторизация
-config.mail_notify=Почтовые уведомления
-config.disable_key_size_check=Отключить проверку на минимальный размер ключа
-config.enable_captcha=Включить капчу
-config.active_code_lives=Время жизни кода для активации
-config.reset_password_code_lives=Время жизни кода сброса пароля
+config.db.type=Type
+config.db.host=Host
+config.db.name=Name
+config.db.user=User
+config.db.ssl_mode=SSL mode
+config.db.ssl_mode_helper=(for "postgres" only)
+config.db.path=Path
+config.db.path_helper=(for "sqlite3"only)
+
+config.security_config=Security configuration
+config.security.login_remember_days=Login remember days
+config.security.cookie_remember_name=Remember cookie
+config.security.cookie_username=Username cookie
+config.security.cookie_secure=Enable secure cookie
+config.security.reverse_proxy_auth_user=Reverse proxy authentication header
+config.security.enable_login_status_cookie=Enable login status cookie
+config.security.login_status_cookie_name=Login status cookie
+
+config.email_config=Email configuration
+config.email.enabled=Enabled
+config.email.subject_prefix=Subject prefix
+config.email.host=Host
+config.email.from=From
+config.email.user=User
+config.email.disable_helo=Disable HELO
+config.email.helo_hostname=HELO hostname
+config.email.skip_verify=Skip certificate verify
+config.email.use_certificate=Use custom certificate
+config.email.cert_file=Certificate file
+config.email.key_file=Key file
+config.email.use_plain_text=Use plain text
+config.email.add_plain_text_alt=Add plain text alternative
+config.email.send_test_mail=Send test email
+config.email.test_mail_failed=Failed to send test email to '%s': %v
+config.email.test_mail_sent=Test email has been sent to '%s'.
+
+config.auth_config=Authentication configuration
+config.auth.activate_code_lives=Activate code lives
+config.auth.reset_password_code_lives=Reset password code lives
+config.auth.require_email_confirm=Require email confirmation
+config.auth.require_sign_in_view=Require sign in view
+config.auth.disable_registration=Disable registration
+config.auth.enable_registration_captcha=Enable registration captcha
+config.auth.enable_reverse_proxy_authentication=Enable reverse proxy authentication
+config.auth.enable_reverse_proxy_auto_registration=Enable reverse proxy auto registration
+config.auth.reverse_proxy_authentication_header=Reverse proxy authentication header
+
+config.user_config=User configuration
+config.user.enable_email_notify=Enable email notification
 
-config.webhook_config=Конфигурация Webhook
-config.queue_length=Длина очереди
-config.deliver_timeout=Задержка доставки
-config.skip_tls_verify=Пропустить проверку TLS
-
-config.mailer_config=Настройки почты
-config.mailer_enabled=Включено
-config.mailer_disable_helo=Отключить HELO
-config.mailer_subject_prefix=Префикс темы письма
-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.session_config=Конфигурация сессии
+config.session.provider=Provider
+config.session.provider_config=Provider config
+config.session.cookie_name=Cookie
+config.session.https_only=HTTPS only
+config.session.gc_interval=GC interval
+config.session.max_life_time=Max life time
+config.session.csrf_cookie_name=CSRF cookie
 
 config.cache_config=Настройки кеша
-config.cache_adapter=Адаптер кэша
-config.cache_interval=Интервал кэширования
-config.cache_conn=Подключение кэша
+config.cache.adapter=Adapter
+config.cache.interval=GC interval
+config.cache.host=Host
 
-config.session_config=Конфигурация сессии
-config.session_provider=Провайдер сессии
-config.provider_config=Конфигурация провайдера
-config.cookie_name=Имя файла cookie
-config.enable_set_cookie=Включить установку cookies
-config.gc_interval_time=Интервал работы сборщика мусора
-config.session_life_time=Время жизни сессии
-config.https_only=Только HTTPS
-config.cookie_life_time=Время жизни файла cookie
+config.http_config=Конфигурация HTTP
+config.http.access_control_allow_origin=Access control allow origin
+
+config.attachment_config=Attachment configuration
+config.attachment.enabled=Enabled
+config.attachment.path=Path
+config.attachment.allowed_types=Allowed types
+config.attachment.max_size=Size limit
+config.attachment.max_files=Files limit
+
+config.release_config=Release configuration
+config.release.attachment.enabled=Attachment enabled
+config.release.attachment.allowed_types=Attachment allowed types
+config.release.attachment.max_size=Attachment size limit
+config.release.attachment.max_files=Attachment files limit
 
 config.picture_config=Настройка изображения
-config.picture_service=Сервис изображений
-config.disable_gravatar=Отключить Gravatar
-config.enable_federated_avatar=Включить внешние Аватары
+config.picture.avatar_upload_path=User avatar upload path
+config.picture.repo_avatar_upload_path=Repository avatar upload path
+config.picture.gravatar_source=Gravatar source
+config.picture.disable_gravatar=Disable Gravatar
+config.picture.enable_federated_avatar=Enable federated avatars
+
+config.mirror_config=Mirror configuration
+config.mirror.default_interval=Default interval
+
+config.webhook_config=Конфигурация Webhook
+config.webhook.types=Types
+config.webhook.deliver_timeout=Deliver timeout
+config.webhook.skip_tls_verify=Skip TLS verify
 
 config.git_config=Конфигурация GIT
-config.git_disable_diff_highlight=Отключить подсветку синтаксиса Diff
-config.git_max_diff_lines=Максимальное количество строк Diff (на файл)
-config.git_max_diff_line_characters=Максимальное количество символов Diff (в строке)
-config.git_max_diff_files=Максимальное количество Diff-файлов (при показе)
-config.git_gc_args=Аргументы GC
-config.git_migrate_timeout=Тайм-аут миграции
-config.git_mirror_timeout=Время ожидания обновления зеркала
-config.git_clone_timeout=Время ожидания операции клонирования
-config.git_pull_timeout=Время ожидания операции извлечения
-config.git_gc_timeout=Время Ожидания Операции Сборки Мусора
+config.git.disable_diff_highlight=Disable diff syntax highlight
+config.git.max_diff_lines=Diff lines limit (for a single file)
+config.git.max_diff_line_characters=Diff characters limit (for a single line)
+config.git.max_diff_files=Diff files limit (for a single diff)
+config.git.gc_args=GC arguments
+config.git.migrate_timeout=Migration timeout
+config.git.mirror_timeout=Mirror fetch timeout
+config.git.clone_timeout=Clone timeout
+config.git.pull_timeout=Pull timeout
+config.git.gc_timeout=GC timeout
 
 config.log_config=Конфигурация журнала
+config.log_file_root_path=Путь до папки с логами
 config.log_mode=Режим
 config.log_options=Опции
 
@@ -1338,6 +1397,7 @@ months=%d месяцев %s
 years=%d лет %s
 raw_seconds=секунд
 raw_minutes=минут
+raw_hours=hours
 
 [dropzone]
 default_message=Перетащите файл сюда, или кликните для загрузки.

+ 154 - 94
conf/locale/locale_sk-SK.ini

@@ -9,7 +9,6 @@ sign_out=Odhlásiť sa
 sign_up=Zaregistrovať sa
 register=Registrovať
 website=Web stránka
-version=Verzia
 page=Stránka
 template=Šablóna
 language=Jazyk
@@ -122,6 +121,7 @@ run_user_not_match=Používateľ pre spustenie sa nezhoduje s aktuálnym použí
 smtp_host_missing_port=V adrese SMTP servera chýba číslo portu.
 invalid_smtp_from=Hodnota položky SMTP Od: je nesprávne zadaná: %v
 save_config_failed=Chyba pri uložení konfigurácie: %v
+init_failed=Failed to initialize application: %v
 invalid_admin_setting=Nastavenie administrátorského účtu je neplatné: %v
 install_success=Vitajte! Sme radi, že ste si vybrali Gogs, bavte sa a dávajte si pozor.
 invalid_log_root_path=Koreňový adresár pre log súbory je neplatný: %v
@@ -1001,6 +1001,12 @@ first_page=Prvý
 last_page=Posledný
 total=Celkom: %d
 
+dashboard.build_info=Build Information
+dashboard.app_ver=Application version
+dashboard.git_version=Git version
+dashboard.go_version=Go version
+dashboard.build_time=Build time
+dashboard.build_commit=Build commit
 dashboard.statistic=Štatistika
 dashboard.operations=Operácie
 dashboard.system_status=Monitor stavu systému
@@ -1156,117 +1162,170 @@ auths.github_api_endpoint=API Endpoint
 
 config.not_set=(nezadané)
 config.server_config=Konfigurácia servera
-config.app_name=Názov aplikácie
-config.app_ver=Verzia aplikácie
-config.app_url=URL adresa aplikácie
-config.domain=Doména
-config.offline_mode=Offline režim
-config.disable_router_log=Vypnúť systémové záznamy smerovača
+config.brand_name=Brand name
 config.run_user=Používateľ pre spustenie aplikácie
 config.run_mode=Režim spúšťania
-config.git_version=Verzia Gitu
-config.static_file_root_path=Koreňový adresár statického súboru
-config.log_file_root_path=Koreňový adresár súboru systémových záznamov
-config.reverse_auth_user=Užívateľ obráteného overenia
+config.server.external_url=External URL
+config.server.domain=Domain
+config.server.protocol=Protocol
+config.server.http_addr=HTTP address
+config.server.http_port=HTTP port
+config.server.cert_file=Certificate file
+config.server.key_file=Key file
+config.server.tls_min_version=Minimum TLS version
+config.server.unix_socket_permission=Unix socket permission
+config.server.local_root_url=Local root URL
+config.server.offline_mode=Offline mode
+config.server.disable_router_log=Disable router log
+config.server.enable_gzip=Enable Gzip
+config.server.app_data_path=Application data path
+config.server.load_assets_from_disk=Load assets from disk
+config.server.landing_url=Landing URL
 
 config.ssh_config=Nastavenie SSH
-config.ssh_enabled=Povolené
-config.ssh_start_builtin_server=Spustiť vstavaný server
-config.ssh_domain=Doména
-config.ssh_port=Port
-config.ssh_listen_port=Port pre poslúchanie
-config.ssh_root_path=Koreňová cesta
-config.ssh_rewrite_authorized_keys_at_start=Prepísať authorized_keys pri štarte
-config.ssh_key_test_path=Cesta testu kľúčov
-config.ssh_keygen_path=Cesta ku generátoru kľúčov ('ssh-keygen')
-config.ssh_minimum_key_size_check=Kontrola minimálnej veľkosti kľúčov
-config.ssh_minimum_key_sizes=Minimálna veľkosť kľúčov
+config.ssh.enabled=Enabled
+config.ssh.domain=Exposed domain
+config.ssh.port=Exposed port
+config.ssh.root_path=Root path
+config.ssh.keygen_path=Keygen path
+config.ssh.key_test_path=Key test path
+config.ssh.minimum_key_size_check=Minimum key size check
+config.ssh.minimum_key_sizes=Minimum key sizes
+config.ssh.rewrite_authorized_keys_at_start=Rewrite "authorized_keys" at start
+config.ssh.start_builtin_server=Start builtin server
+config.ssh.listen_host=Listen host
+config.ssh.listen_port=Listen port
+config.ssh.server_ciphers=Server ciphers
 
 config.repo_config=Nastavenie repozitára
-config.repo_root_path=Koreňový adresár repozitára
-config.script_type=Typ skriptu
-config.repo_force_private=Vynútiť súkromné
-config.max_creation_limit=Maximálna lehota pre vytvorenie
-config.preferred_licenses=Uprednostňované licencie
-config.disable_http_git=Vypnúť HTTP Git
-config.enable_local_path_migration=Povoliť migráciu z miestnej cesty
-config.commits_fetch_concurrency=Súbežnosť vyzdvihnutia revízii
-
-config.http_config=HTTP konfigurácia
-config.http_access_control_allow_origin=Access Control Allow Origin
+config.repo.root_path=Root path
+config.repo.script_type=Script type
+config.repo.ansi_chatset=ANSI charset
+config.repo.force_private=Force private
+config.repo.max_creation_limit=Max creation limit
+config.repo.preferred_licenses=Preferred licenses
+config.repo.disable_http_git=Disable HTTP Git
+config.repo.enable_local_path_migration=Enable local path migration
+config.repo.enable_raw_file_render_mode=Enable raw file render mode
+config.repo.commits_fetch_concurrency=Commits fetch concurrency
+config.repo.editor.line_wrap_extensions=Editor line wrap extensions
+config.repo.editor.previewable_file_modes=Editor previewable file modes
+config.repo.upload.enabled=Upload enabled
+config.repo.upload.temp_path=Upload temporary path
+config.repo.upload.allowed_types=Upload allowed types
+config.repo.upload.file_max_size=Upload file size limit
+config.repo.upload.max_files=Upload files limit
 
 config.db_config=Konfigurácia databázy
-config.db_type=Typ
-config.db_host=Host
-config.db_name=Názov
-config.db_user=Používateľ
-config.db_ssl_mode=SSL režim
-config.db_ssl_mode_helper=(iba pre "postgres")
-config.db_path=Cesta
-config.db_path_helper=(iba pre "sqlite3" a "tidb")
-
-config.service_config=Konfigurácia služby
-config.register_email_confirm=Vyžadovať potvrdenie e-mailu
-config.disable_register=Zakázať registráciu
-config.show_registration_button=Zobraziť tlačítko registrácie
-config.require_sign_in_view=Vyžadovať zobrazenie prihlásenia
-config.mail_notify=Upozornenie e-mailom
-config.disable_key_size_check=Vypnúť kontrolu minimálnej veľkosti kľúčov
-config.enable_captcha=Povoliť Captcha
-config.active_code_lives=Doba života aktívneho kódu
-config.reset_password_code_lives=Lehota kódu pre obnovu hesla
+config.db.type=Type
+config.db.host=Host
+config.db.name=Name
+config.db.user=User
+config.db.ssl_mode=SSL mode
+config.db.ssl_mode_helper=(for "postgres" only)
+config.db.path=Path
+config.db.path_helper=(for "sqlite3"only)
+
+config.security_config=Security configuration
+config.security.login_remember_days=Login remember days
+config.security.cookie_remember_name=Remember cookie
+config.security.cookie_username=Username cookie
+config.security.cookie_secure=Enable secure cookie
+config.security.reverse_proxy_auth_user=Reverse proxy authentication header
+config.security.enable_login_status_cookie=Enable login status cookie
+config.security.login_status_cookie_name=Login status cookie
+
+config.email_config=Email configuration
+config.email.enabled=Enabled
+config.email.subject_prefix=Subject prefix
+config.email.host=Host
+config.email.from=From
+config.email.user=User
+config.email.disable_helo=Disable HELO
+config.email.helo_hostname=HELO hostname
+config.email.skip_verify=Skip certificate verify
+config.email.use_certificate=Use custom certificate
+config.email.cert_file=Certificate file
+config.email.key_file=Key file
+config.email.use_plain_text=Use plain text
+config.email.add_plain_text_alt=Add plain text alternative
+config.email.send_test_mail=Send test email
+config.email.test_mail_failed=Failed to send test email to '%s': %v
+config.email.test_mail_sent=Test email has been sent to '%s'.
+
+config.auth_config=Authentication configuration
+config.auth.activate_code_lives=Activate code lives
+config.auth.reset_password_code_lives=Reset password code lives
+config.auth.require_email_confirm=Require email confirmation
+config.auth.require_sign_in_view=Require sign in view
+config.auth.disable_registration=Disable registration
+config.auth.enable_registration_captcha=Enable registration captcha
+config.auth.enable_reverse_proxy_authentication=Enable reverse proxy authentication
+config.auth.enable_reverse_proxy_auto_registration=Enable reverse proxy auto registration
+config.auth.reverse_proxy_authentication_header=Reverse proxy authentication header
+
+config.user_config=User configuration
+config.user.enable_email_notify=Enable email notification
 
-config.webhook_config=Nastavenie webových háčikov
-config.queue_length=Dĺžka fronty
-config.deliver_timeout=Časový limit doručenia
-config.skip_tls_verify=Preskočiť overenie TLS
-
-config.mailer_config=Nastavenie mailera
-config.mailer_enabled=Povolený
-config.mailer_disable_helo=Zakázať HELO
-config.mailer_subject_prefix=Predpona predmetu
-config.mailer_host=Host
-config.mailer_user=Používateľ
-config.send_test_mail=Odoslať testovací E-mail
-config.test_mail_failed=Odoslanie testovacieho e-mailu na '%s' zlyhalo: %v
-config.test_mail_sent=Testovací e-mail bol odoslaný na '%s'.
-
-config.oauth_config=OAuth konfigurácia
-config.oauth_enabled=Povolený
+config.session_config=Nastavenie session
+config.session.provider=Provider
+config.session.provider_config=Provider config
+config.session.cookie_name=Cookie
+config.session.https_only=HTTPS only
+config.session.gc_interval=GC interval
+config.session.max_life_time=Max life time
+config.session.csrf_cookie_name=CSRF cookie
 
 config.cache_config=Konfigurácia cache
-config.cache_adapter=Cache adaptér
-config.cache_interval=Cache interval
-config.cache_conn=Cache pripojenie
+config.cache.adapter=Adapter
+config.cache.interval=GC interval
+config.cache.host=Host
 
-config.session_config=Nastavenie session
-config.session_provider=Session provider
-config.provider_config=Nastavenie providera
-config.cookie_name=Názov cookie
-config.enable_set_cookie=Povoliť nastavenie Cookie
-config.gc_interval_time=GC Časový interval
-config.session_life_time=Doba trvania relácie
-config.https_only=Iba HTTPS
-config.cookie_life_time=Doba života súboru cookie
+config.http_config=HTTP konfigurácia
+config.http.access_control_allow_origin=Access control allow origin
+
+config.attachment_config=Attachment configuration
+config.attachment.enabled=Enabled
+config.attachment.path=Path
+config.attachment.allowed_types=Allowed types
+config.attachment.max_size=Size limit
+config.attachment.max_files=Files limit
+
+config.release_config=Release configuration
+config.release.attachment.enabled=Attachment enabled
+config.release.attachment.allowed_types=Attachment allowed types
+config.release.attachment.max_size=Attachment size limit
+config.release.attachment.max_files=Attachment files limit
 
 config.picture_config=Nastavenie ikony užívateľa
-config.picture_service=Služba ikon užívateľov
-config.disable_gravatar=Zakázať Gravatar
-config.enable_federated_avatar=Povoliť jednotné ikony užívateľov
+config.picture.avatar_upload_path=User avatar upload path
+config.picture.repo_avatar_upload_path=Repository avatar upload path
+config.picture.gravatar_source=Gravatar source
+config.picture.disable_gravatar=Disable Gravatar
+config.picture.enable_federated_avatar=Enable federated avatars
+
+config.mirror_config=Mirror configuration
+config.mirror.default_interval=Default interval
+
+config.webhook_config=Nastavenie webových háčikov
+config.webhook.types=Types
+config.webhook.deliver_timeout=Deliver timeout
+config.webhook.skip_tls_verify=Skip TLS verify
 
 config.git_config=Konfigurácia Gitu
-config.git_disable_diff_highlight=Vypnúť zvýraznenie syntaxi v rozdielovom zobrazení
-config.git_max_diff_lines=Maximálny počet rozdielnych riadkov jedného súboru
-config.git_max_diff_line_characters=Maximálny počet zobrazených rozdielnych znakov jedného riadku
-config.git_max_diff_files=Maximálny počet zobrazených rozdielnych súborov
-config.git_gc_args=Parametre GC
-config.git_migrate_timeout=Časová lehota prenesenia
-config.git_mirror_timeout=Časový limit aktualizácie zrkadla
-config.git_clone_timeout=Časový limit operácie naklonovania
-config.git_pull_timeout=Časový limit operácie stiahnutia
-config.git_gc_timeout=Časový limit operácie GC
+config.git.disable_diff_highlight=Disable diff syntax highlight
+config.git.max_diff_lines=Diff lines limit (for a single file)
+config.git.max_diff_line_characters=Diff characters limit (for a single line)
+config.git.max_diff_files=Diff files limit (for a single diff)
+config.git.gc_args=GC arguments
+config.git.migrate_timeout=Migration timeout
+config.git.mirror_timeout=Mirror fetch timeout
+config.git.clone_timeout=Clone timeout
+config.git.pull_timeout=Pull timeout
+config.git.gc_timeout=GC timeout
 
 config.log_config=Nastavenie systémových záznamov
+config.log_file_root_path=Koreňový adresár súboru systémových záznamov
 config.log_mode=Režim
 config.log_options=Možnosti
 
@@ -1338,6 +1397,7 @@ months=%d mesiacov %s
 years=%d rokov %s
 raw_seconds=sekúnd
 raw_minutes=minút
+raw_hours=hours
 
 [dropzone]
 default_message=Pretiahnite súbory sem alebo stlačte Nahrať.

+ 154 - 94
conf/locale/locale_sr-SP.ini

@@ -9,7 +9,6 @@ sign_out=Одјава
 sign_up=Регистрација
 register=Регистрација
 website=Веб-страница
-version=Верзија
 page=Страница
 template=Шаблон
 language=Језик
@@ -122,6 +121,7 @@ run_user_not_match=Тренутни корисник није корисник 
 smtp_host_missing_port=У адресу SMTP сервера недостаје порт.
 invalid_smtp_from=Поље SMTP From није важећи: %v
 save_config_failed=Није могуће сачувати конфигурацију: %v
+init_failed=Failed to initialize application: %v
 invalid_admin_setting=Подешавањна администратора су неправилна: %v
 install_success=Добродошли! Ми смо срећни што сте изабрали GIN.
 invalid_log_root_path=Пут до корена журнала је неправилан: %v
@@ -1001,6 +1001,12 @@ first_page=Први
 last_page=Последњи
 total=Укупно: %d
 
+dashboard.build_info=Build Information
+dashboard.app_ver=Application version
+dashboard.git_version=Git version
+dashboard.go_version=Go version
+dashboard.build_time=Build time
+dashboard.build_commit=Build commit
 dashboard.statistic=Статистика
 dashboard.operations=Операције
 dashboard.system_status=Статус системског монитора
@@ -1156,117 +1162,170 @@ auths.github_api_endpoint=API Endpoint
 
 config.not_set=(није подешено)
 config.server_config=Конфигурација сервера
-config.app_name=Име апликације
-config.app_ver=Верзија апликације
-config.app_url=URL адреса апликације
-config.domain=Домен
-config.offline_mode=Режим ван мреже
-config.disable_router_log=Онемогући журнал рутера
+config.brand_name=Brand name
 config.run_user=Покретни корисник
 config.run_mode=Режим извршавања
-config.git_version=Git Version
-config.static_file_root_path=Пут до статичке датотеке
-config.log_file_root_path=Пут до журнала
-config.reverse_auth_user=Корисничко име при обрнуту аутентикацију
+config.server.external_url=External URL
+config.server.domain=Domain
+config.server.protocol=Protocol
+config.server.http_addr=HTTP address
+config.server.http_port=HTTP port
+config.server.cert_file=Certificate file
+config.server.key_file=Key file
+config.server.tls_min_version=Minimum TLS version
+config.server.unix_socket_permission=Unix socket permission
+config.server.local_root_url=Local root URL
+config.server.offline_mode=Offline mode
+config.server.disable_router_log=Disable router log
+config.server.enable_gzip=Enable Gzip
+config.server.app_data_path=Application data path
+config.server.load_assets_from_disk=Load assets from disk
+config.server.landing_url=Landing URL
 
 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_rewrite_authorized_keys_at_start=Переписати authorized_keys на почeтку
-config.ssh_key_test_path=Пут до кључу
-config.ssh_keygen_path=Пут до генератор кључева ('ssh-keygen')
-config.ssh_minimum_key_size_check=Минимална величина провера кључа
-config.ssh_minimum_key_sizes=Минимална величина кључева
+config.ssh.enabled=Enabled
+config.ssh.domain=Exposed domain
+config.ssh.port=Exposed port
+config.ssh.root_path=Root path
+config.ssh.keygen_path=Keygen path
+config.ssh.key_test_path=Key test path
+config.ssh.minimum_key_size_check=Minimum key size check
+config.ssh.minimum_key_sizes=Minimum key sizes
+config.ssh.rewrite_authorized_keys_at_start=Rewrite "authorized_keys" at start
+config.ssh.start_builtin_server=Start builtin server
+config.ssh.listen_host=Listen host
+config.ssh.listen_port=Listen port
+config.ssh.server_ciphers=Server ciphers
 
 config.repo_config=Конфигурација спремишта
-config.repo_root_path=Пут до корена спремишта
-config.script_type=Врста скрипта
-config.repo_force_private=Force Private
-config.max_creation_limit=Ограничење максималне креације
-config.preferred_licenses=Преференцијалне лиценце
-config.disable_http_git=Онемогући HTTP Git
-config.enable_local_path_migration=Омогући миграцију локалнe путањe
-config.commits_fetch_concurrency=Предузеће Fetch Concurrency
-
-config.http_config=HTTP Конфигурација
-config.http_access_control_allow_origin=Контрола приступа дозвољава порекло
+config.repo.root_path=Root path
+config.repo.script_type=Script type
+config.repo.ansi_chatset=ANSI charset
+config.repo.force_private=Force private
+config.repo.max_creation_limit=Max creation limit
+config.repo.preferred_licenses=Preferred licenses
+config.repo.disable_http_git=Disable HTTP Git
+config.repo.enable_local_path_migration=Enable local path migration
+config.repo.enable_raw_file_render_mode=Enable raw file render mode
+config.repo.commits_fetch_concurrency=Commits fetch concurrency
+config.repo.editor.line_wrap_extensions=Editor line wrap extensions
+config.repo.editor.previewable_file_modes=Editor previewable file modes
+config.repo.upload.enabled=Upload enabled
+config.repo.upload.temp_path=Upload temporary path
+config.repo.upload.allowed_types=Upload allowed types
+config.repo.upload.file_max_size=Upload file size limit
+config.repo.upload.max_files=Upload files limit
 
 config.db_config=Конфигурација базе података
-config.db_type=Тип
-config.db_host=Хост
-config.db_name=Име
-config.db_user=Корисник
-config.db_ssl_mode=Режим SSL
-config.db_ssl_mode_helper=(само за postgres)
-config.db_path=Пут
-config.db_path_helper=(за "sqlite3" и "tidb")
-
-config.service_config=Подешавања сервиса
-config.register_email_confirm=Потражи потврду путем е-поштом
-config.disable_register=Искључи нове регистрације
-config.show_registration_button=Прикажи дугме за регистрацију
-config.require_sign_in_view=Прикажи налог за пријаву
-config.mail_notify=Обавештења преко е-поште
-config.disable_key_size_check=Онемогући проверу на минималној величини кључа
-config.enable_captcha=Омогући Captcha
-config.active_code_lives=Дужина живота активних кодова
-config.reset_password_code_lives=Дужина живота ресетних кодова за лозинку
+config.db.type=Type
+config.db.host=Host
+config.db.name=Name
+config.db.user=User
+config.db.ssl_mode=SSL mode
+config.db.ssl_mode_helper=(for "postgres" only)
+config.db.path=Path
+config.db.path_helper=(for "sqlite3"only)
+
+config.security_config=Security configuration
+config.security.login_remember_days=Login remember days
+config.security.cookie_remember_name=Remember cookie
+config.security.cookie_username=Username cookie
+config.security.cookie_secure=Enable secure cookie
+config.security.reverse_proxy_auth_user=Reverse proxy authentication header
+config.security.enable_login_status_cookie=Enable login status cookie
+config.security.login_status_cookie_name=Login status cookie
+
+config.email_config=Email configuration
+config.email.enabled=Enabled
+config.email.subject_prefix=Subject prefix
+config.email.host=Host
+config.email.from=From
+config.email.user=User
+config.email.disable_helo=Disable HELO
+config.email.helo_hostname=HELO hostname
+config.email.skip_verify=Skip certificate verify
+config.email.use_certificate=Use custom certificate
+config.email.cert_file=Certificate file
+config.email.key_file=Key file
+config.email.use_plain_text=Use plain text
+config.email.add_plain_text_alt=Add plain text alternative
+config.email.send_test_mail=Send test email
+config.email.test_mail_failed=Failed to send test email to '%s': %v
+config.email.test_mail_sent=Test email has been sent to '%s'.
+
+config.auth_config=Authentication configuration
+config.auth.activate_code_lives=Activate code lives
+config.auth.reset_password_code_lives=Reset password code lives
+config.auth.require_email_confirm=Require email confirmation
+config.auth.require_sign_in_view=Require sign in view
+config.auth.disable_registration=Disable registration
+config.auth.enable_registration_captcha=Enable registration captcha
+config.auth.enable_reverse_proxy_authentication=Enable reverse proxy authentication
+config.auth.enable_reverse_proxy_auto_registration=Enable reverse proxy auto registration
+config.auth.reverse_proxy_authentication_header=Reverse proxy authentication header
+
+config.user_config=User configuration
+config.user.enable_email_notify=Enable email notification
 
-config.webhook_config=Подешавања Webhook
-config.queue_length=Дужина реда
-config.deliver_timeout=Време до отказивање слања
-config.skip_tls_verify=Прескочи TLS проверу
-
-config.mailer_config=Подешавања поште
-config.mailer_enabled=Омогућено
-config.mailer_disable_helo=Онемогући HELO
-config.mailer_subject_prefix=Префикс Предмета
-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.session_config=Подешавања сесије
+config.session.provider=Provider
+config.session.provider_config=Provider config
+config.session.cookie_name=Cookie
+config.session.https_only=HTTPS only
+config.session.gc_interval=GC interval
+config.session.max_life_time=Max life time
+config.session.csrf_cookie_name=CSRF cookie
 
 config.cache_config=Подешавања кеша
-config.cache_adapter=Кеш адаптер
-config.cache_interval=Кеш интервал
-config.cache_conn=Кеш на вези
+config.cache.adapter=Adapter
+config.cache.interval=GC interval
+config.cache.host=Host
 
-config.session_config=Подешавања сесије
-config.session_provider=Добављач сесија
-config.provider_config=Конфигурација на добављачу
-config.cookie_name=Име датотеке cookie
-config.enable_set_cookie=Укључи поставку cookie
-config.gc_interval_time=Интервал cакупљања смећа
-config.session_life_time=Дужина живота сесјие
-config.https_only=Само HTTPS
-config.cookie_life_time=Дужина живота датотеке cookie
+config.http_config=HTTP Конфигурација
+config.http.access_control_allow_origin=Access control allow origin
+
+config.attachment_config=Attachment configuration
+config.attachment.enabled=Enabled
+config.attachment.path=Path
+config.attachment.allowed_types=Allowed types
+config.attachment.max_size=Size limit
+config.attachment.max_files=Files limit
+
+config.release_config=Release configuration
+config.release.attachment.enabled=Attachment enabled
+config.release.attachment.allowed_types=Attachment allowed types
+config.release.attachment.max_size=Attachment size limit
+config.release.attachment.max_files=Attachment files limit
 
 config.picture_config=Подешавање слика
-config.picture_service=Услуга за слике
-config.disable_gravatar=Онемогући Gravatar
-config.enable_federated_avatar=Омогући Federated Avatars
+config.picture.avatar_upload_path=User avatar upload path
+config.picture.repo_avatar_upload_path=Repository avatar upload path
+config.picture.gravatar_source=Gravatar source
+config.picture.disable_gravatar=Disable Gravatar
+config.picture.enable_federated_avatar=Enable federated avatars
+
+config.mirror_config=Mirror configuration
+config.mirror.default_interval=Default interval
+
+config.webhook_config=Подешавања Webhook
+config.webhook.types=Types
+config.webhook.deliver_timeout=Deliver timeout
+config.webhook.skip_tls_verify=Skip TLS verify
 
 config.git_config=Git конфигурација
-config.git_disable_diff_highlight=Онемогући бојење синтаксе када гледате разлике
-config.git_max_diff_lines=Максималан број различитих редова (у датотеци)
-config.git_max_diff_line_characters=Максималан број различитих карактера (у реду)
-config.git_max_diff_files=Максималан број измењених датотека (приказаних)
-config.git_gc_args=Аргументи на cакупљање смећа
-config.git_migrate_timeout=Време до отказања миграције
-config.git_mirror_timeout=Време до отазање синхронизацији огледала
-config.git_clone_timeout=Време до отказивања клонирањем
-config.git_pull_timeout=Време до отказивања pull операцији
-config.git_gc_timeout=Време до отказивања cакупљање смећа
+config.git.disable_diff_highlight=Disable diff syntax highlight
+config.git.max_diff_lines=Diff lines limit (for a single file)
+config.git.max_diff_line_characters=Diff characters limit (for a single line)
+config.git.max_diff_files=Diff files limit (for a single diff)
+config.git.gc_args=GC arguments
+config.git.migrate_timeout=Migration timeout
+config.git.mirror_timeout=Mirror fetch timeout
+config.git.clone_timeout=Clone timeout
+config.git.pull_timeout=Pull timeout
+config.git.gc_timeout=GC timeout
 
 config.log_config=Kонфигурација журнала
+config.log_file_root_path=Пут до журнала
 config.log_mode=Режим
 config.log_options=Опције
 
@@ -1338,6 +1397,7 @@ months=%[2]s %[1]d месеци
 years=%[2]s %[1]d година
 raw_seconds=секунди
 raw_minutes=минута
+raw_hours=hours
 
 [dropzone]
 default_message=Превуците датотеку овде или кликните за преузимање.

+ 159 - 99
conf/locale/locale_sv-SE.ini

@@ -9,7 +9,6 @@ sign_out=Logga ut
 sign_up=Registrera dig
 register=Registrera dig
 website=Webbplats
-version=Version
 page=Sida
 template=Mall
 language=Språk
@@ -122,6 +121,7 @@ run_user_not_match=Köranvändaren är inte aktuell användare: %s -> %s
 smtp_host_missing_port=SMTP-värden saknar port i adressen.
 invalid_smtp_from=SMTP från fält är inte giltigt: %v
 save_config_failed=Konfigurationssparningen misslyckades: %v
+init_failed=Failed to initialize application: %v
 invalid_admin_setting=Inställningarna för administratörskontot är felaktiga: %v
 install_success=Välkommen! Vi är glada att du väljer GIN, ha kul och ta hand om dig.
 invalid_log_root_path=Ogiltig rotsökväg för loggfiler: %v
@@ -1001,6 +1001,12 @@ first_page=Första
 last_page=Sista
 total=Totalt: %d
 
+dashboard.build_info=Build Information
+dashboard.app_ver=Application version
+dashboard.git_version=Git version
+dashboard.go_version=Go version
+dashboard.build_time=Build time
+dashboard.build_commit=Build commit
 dashboard.statistic=Statistik
 dashboard.operations=Operationer
 dashboard.system_status=Systemstatus
@@ -1156,117 +1162,170 @@ auths.github_api_endpoint=API Endpoint
 
 config.not_set=(not set)
 config.server_config=Server-konfiguration
-config.app_name=Applikationsnamn
-config.app_ver=Applikationsversion
-config.app_url=Applikations-URL
-config.domain=Domän
-config.offline_mode=Offline-läge
-config.disable_router_log=Disable Router Log
-config.run_user=Run User
-config.run_mode=Run Mode
-config.git_version=Git Version
-config.static_file_root_path=Static File Root Path
-config.log_file_root_path=Log File Root Path
-config.reverse_auth_user=Reverse Authentication User
+config.brand_name=Brand name
+config.run_user=Run user
+config.run_mode=Run mode
+config.server.external_url=External URL
+config.server.domain=Domain
+config.server.protocol=Protocol
+config.server.http_addr=HTTP address
+config.server.http_port=HTTP port
+config.server.cert_file=Certificate file
+config.server.key_file=Key file
+config.server.tls_min_version=Minimum TLS version
+config.server.unix_socket_permission=Unix socket permission
+config.server.local_root_url=Local root URL
+config.server.offline_mode=Offline mode
+config.server.disable_router_log=Disable router log
+config.server.enable_gzip=Enable Gzip
+config.server.app_data_path=Application data path
+config.server.load_assets_from_disk=Load assets from disk
+config.server.landing_url=Landing URL
 
 config.ssh_config=SSH-konfiguration
-config.ssh_enabled=Aktiverad
-config.ssh_start_builtin_server=Start Builtin Server
-config.ssh_domain=Domän
-config.ssh_port=Port
-config.ssh_listen_port=Lyssningsport
-config.ssh_root_path=Rotsökväg
-config.ssh_rewrite_authorized_keys_at_start=Rewrite authorized_keys At Start
-config.ssh_key_test_path=Testsökväg för nyckel
-config.ssh_keygen_path=Sökväg för nyckelgenerator ('ssh-keygen')
-config.ssh_minimum_key_size_check=Kontroll av minsta tillåtna nyckelstorlek
-config.ssh_minimum_key_sizes=Minsta tillåtna nyckelstorlek
-
-config.repo_config=Repository Configuration
-config.repo_root_path=Rotsökväg för utvecklingskatalog
-config.script_type=Script-typ
-config.repo_force_private=Force Private
-config.max_creation_limit=Max Creation Limit
-config.preferred_licenses=Preferred Licenses
-config.disable_http_git=Disable HTTP Git
-config.enable_local_path_migration=Enable Local Path Migration
-config.commits_fetch_concurrency=Commits Fetch Concurrency
-
-config.http_config=HTTP Configuration
-config.http_access_control_allow_origin=Access Control Allow Origin
+config.ssh.enabled=Enabled
+config.ssh.domain=Exposed domain
+config.ssh.port=Exposed port
+config.ssh.root_path=Root path
+config.ssh.keygen_path=Keygen path
+config.ssh.key_test_path=Key test path
+config.ssh.minimum_key_size_check=Minimum key size check
+config.ssh.minimum_key_sizes=Minimum key sizes
+config.ssh.rewrite_authorized_keys_at_start=Rewrite "authorized_keys" at start
+config.ssh.start_builtin_server=Start builtin server
+config.ssh.listen_host=Listen host
+config.ssh.listen_port=Listen port
+config.ssh.server_ciphers=Server ciphers
+
+config.repo_config=Repository configuration
+config.repo.root_path=Root path
+config.repo.script_type=Script type
+config.repo.ansi_chatset=ANSI charset
+config.repo.force_private=Force private
+config.repo.max_creation_limit=Max creation limit
+config.repo.preferred_licenses=Preferred licenses
+config.repo.disable_http_git=Disable HTTP Git
+config.repo.enable_local_path_migration=Enable local path migration
+config.repo.enable_raw_file_render_mode=Enable raw file render mode
+config.repo.commits_fetch_concurrency=Commits fetch concurrency
+config.repo.editor.line_wrap_extensions=Editor line wrap extensions
+config.repo.editor.previewable_file_modes=Editor previewable file modes
+config.repo.upload.enabled=Upload enabled
+config.repo.upload.temp_path=Upload temporary path
+config.repo.upload.allowed_types=Upload allowed types
+config.repo.upload.file_max_size=Upload file size limit
+config.repo.upload.max_files=Upload files limit
 
 config.db_config=Databaskonfiguration
-config.db_type=Typ
-config.db_host=Värd
-config.db_name=Namn
-config.db_user=Användare
-config.db_ssl_mode=SSL-läge
-config.db_ssl_mode_helper=(endast för "postgres")
-config.db_path=Sökväg
-config.db_path_helper=(för "sqlite3" och "tidb")
-
-config.service_config=Tjänstkonfiguration
-config.register_email_confirm=Kräv bekräftelse via e-post
-config.disable_register=Avaktivera registrering
-config.show_registration_button=Visa registreringsknapp
-config.require_sign_in_view=Kräv inloggningsvy
-config.mail_notify=E-postavisering
-config.disable_key_size_check=Avaktivera kontroll av minsta tillåtna nyckelstorlek
-config.enable_captcha=Aktivera Captcha
-config.active_code_lives=Aktivera livstid för koder
-config.reset_password_code_lives=Livstid för koder för återställning av lösenord
+config.db.type=Type
+config.db.host=Host
+config.db.name=Name
+config.db.user=User
+config.db.ssl_mode=SSL mode
+config.db.ssl_mode_helper=(for "postgres" only)
+config.db.path=Path
+config.db.path_helper=(for "sqlite3"only)
+
+config.security_config=Security configuration
+config.security.login_remember_days=Login remember days
+config.security.cookie_remember_name=Remember cookie
+config.security.cookie_username=Username cookie
+config.security.cookie_secure=Enable secure cookie
+config.security.reverse_proxy_auth_user=Reverse proxy authentication header
+config.security.enable_login_status_cookie=Enable login status cookie
+config.security.login_status_cookie_name=Login status cookie
+
+config.email_config=Email configuration
+config.email.enabled=Enabled
+config.email.subject_prefix=Subject prefix
+config.email.host=Host
+config.email.from=From
+config.email.user=User
+config.email.disable_helo=Disable HELO
+config.email.helo_hostname=HELO hostname
+config.email.skip_verify=Skip certificate verify
+config.email.use_certificate=Use custom certificate
+config.email.cert_file=Certificate file
+config.email.key_file=Key file
+config.email.use_plain_text=Use plain text
+config.email.add_plain_text_alt=Add plain text alternative
+config.email.send_test_mail=Send test email
+config.email.test_mail_failed=Failed to send test email to '%s': %v
+config.email.test_mail_sent=Test email has been sent to '%s'.
+
+config.auth_config=Authentication configuration
+config.auth.activate_code_lives=Activate code lives
+config.auth.reset_password_code_lives=Reset password code lives
+config.auth.require_email_confirm=Require email confirmation
+config.auth.require_sign_in_view=Require sign in view
+config.auth.disable_registration=Disable registration
+config.auth.enable_registration_captcha=Enable registration captcha
+config.auth.enable_reverse_proxy_authentication=Enable reverse proxy authentication
+config.auth.enable_reverse_proxy_auto_registration=Enable reverse proxy auto registration
+config.auth.reverse_proxy_authentication_header=Reverse proxy authentication header
+
+config.user_config=User configuration
+config.user.enable_email_notify=Enable email notification
 
-config.webhook_config=Webbkrokskonfiguration
-config.queue_length=Kölängd
-config.deliver_timeout=Tidsfrist för leverans
-config.skip_tls_verify=Skippa verifikation av TLS
-
-config.mailer_config=Konfiguration för e-postutskick
-config.mailer_enabled=Aktiverad
-config.mailer_disable_helo=Avaktivera HELO
-config.mailer_subject_prefix=Subject Prefix
-config.mailer_host=Server
-config.mailer_user=Användare
-config.send_test_mail=Skicka testmeddelande
-config.test_mail_failed=Misslyckades skicka testmeddelande till '%s': %v
-config.test_mail_sent=Testmeddelande har skickats till '%s'.
-
-config.oauth_config=OAuth-konfiguration
-config.oauth_enabled=Aktiverad
+config.session_config=Sessionskonfiguration
+config.session.provider=Provider
+config.session.provider_config=Provider config
+config.session.cookie_name=Cookie
+config.session.https_only=HTTPS only
+config.session.gc_interval=GC interval
+config.session.max_life_time=Max life time
+config.session.csrf_cookie_name=CSRF cookie
 
 config.cache_config=Mellanlagringskonfiguration
-config.cache_adapter=Mellanlagringsadapter
-config.cache_interval=Mellanlagringsintervall
-config.cache_conn=Mellanlagringsanslutning
-
-config.session_config=Sessionskonfiguration
-config.session_provider=Sessionsleverantör
-config.provider_config=Leverantörskonfiguration
-config.cookie_name=Cookie-namn
-config.enable_set_cookie=Aktivera sättning av kaka
-config.gc_interval_time=Tidsintervall för skräpsamling
-config.session_life_time=Livstid för session
-config.https_only=Endast HTTPS
-config.cookie_life_time=Livstid för kaka
+config.cache.adapter=Adapter
+config.cache.interval=GC interval
+config.cache.host=Host
+
+config.http_config=HTTP configuration
+config.http.access_control_allow_origin=Access control allow origin
+
+config.attachment_config=Attachment configuration
+config.attachment.enabled=Enabled
+config.attachment.path=Path
+config.attachment.allowed_types=Allowed types
+config.attachment.max_size=Size limit
+config.attachment.max_files=Files limit
+
+config.release_config=Release configuration
+config.release.attachment.enabled=Attachment enabled
+config.release.attachment.allowed_types=Attachment allowed types
+config.release.attachment.max_size=Attachment size limit
+config.release.attachment.max_files=Attachment files limit
 
 config.picture_config=Bildkonfiguration
-config.picture_service=Bildtjänst
-config.disable_gravatar=Inaktivera gravatar
-config.enable_federated_avatar=Enable Federated Avatars
+config.picture.avatar_upload_path=User avatar upload path
+config.picture.repo_avatar_upload_path=Repository avatar upload path
+config.picture.gravatar_source=Gravatar source
+config.picture.disable_gravatar=Disable Gravatar
+config.picture.enable_federated_avatar=Enable federated avatars
+
+config.mirror_config=Mirror configuration
+config.mirror.default_interval=Default interval
+
+config.webhook_config=Webbkrokskonfiguration
+config.webhook.types=Types
+config.webhook.deliver_timeout=Deliver timeout
+config.webhook.skip_tls_verify=Skip TLS verify
 
 config.git_config=Git-konfiguration
-config.git_disable_diff_highlight=Disable Diff Syntax Highlight
-config.git_max_diff_lines=Max Diff Lines (for a single file)
-config.git_max_diff_line_characters=Max Diff Characters (for a single line)
-config.git_max_diff_files=Max Diff Files (to be shown)
-config.git_gc_args=GC-argument
-config.git_migrate_timeout=Migration Timeout
-config.git_mirror_timeout=Mirror Update Timeout
-config.git_clone_timeout=Clone Operation Timeout
-config.git_pull_timeout=Pull Operation Timeout
-config.git_gc_timeout=GC Operation Timeout
+config.git.disable_diff_highlight=Disable diff syntax highlight
+config.git.max_diff_lines=Diff lines limit (for a single file)
+config.git.max_diff_line_characters=Diff characters limit (for a single line)
+config.git.max_diff_files=Diff files limit (for a single diff)
+config.git.gc_args=GC arguments
+config.git.migrate_timeout=Migration timeout
+config.git.mirror_timeout=Mirror fetch timeout
+config.git.clone_timeout=Clone timeout
+config.git.pull_timeout=Pull timeout
+config.git.gc_timeout=GC timeout
 
 config.log_config=Logg-konfiguration
+config.log_file_root_path=Log file root path
 config.log_mode=Mode
 config.log_options=Options
 
@@ -1338,6 +1397,7 @@ months=%d månader %s
 years=%d år %s
 raw_seconds=sekunder
 raw_minutes=minuter
+raw_hours=hours
 
 [dropzone]
 default_message=Drop files here or click to upload.

+ 154 - 94
conf/locale/locale_tr-TR.ini

@@ -9,7 +9,6 @@ sign_out=Çıkış Yap
 sign_up=Kaydol
 register=Üye Ol
 website=Web sitesi
-version=Sürüm
 page=Sayfa
 template=Şablon
 language=Dil
@@ -122,6 +121,7 @@ run_user_not_match=Çalıştırma kullanıcısı geçerli kullanıcı değil: %s
 smtp_host_missing_port=SMTP ana makine adresindeki bağlantı noktası eksik.
 invalid_smtp_from=SMTP form alanı geçerli değil: %v
 save_config_failed=Yapılandırma kaydedilemedi: %v
+init_failed=Failed to initialize application: %v
 invalid_admin_setting=Yönetici hesap ayarları geçersiz: %v
 install_success=Merhaba! GIN'u tercih ettiğiniz için çok mutluyuz, keyfini çıkarın!
 invalid_log_root_path=Günlük kök dizini geçersiz: %v
@@ -1001,6 +1001,12 @@ first_page=İlk
 last_page=Son
 total=Toplam: %d
 
+dashboard.build_info=Build Information
+dashboard.app_ver=Application version
+dashboard.git_version=Git version
+dashboard.go_version=Go version
+dashboard.build_time=Build time
+dashboard.build_commit=Build commit
 dashboard.statistic=İstatistik
 dashboard.operations=İşlemler
 dashboard.system_status=Sistem İzleme Durumu
@@ -1156,117 +1162,170 @@ auths.github_api_endpoint=API Endpoint
 
 config.not_set=(ayarlı değil)
 config.server_config=Sunucu Yapılandırması
-config.app_name=Uygulama Adı
-config.app_ver=Uygulama Sürümü
-config.app_url=Uygulama Bağlantısı
-config.domain=Alan Adı
-config.offline_mode=Çevrim Dışı Modu
-config.disable_router_log=Yönlendirici Log'larını Devre Dışı Bırak
+config.brand_name=Brand name
 config.run_user=Çalıştırma Kullanıcısı
 config.run_mode=Çalıştırma Modu
-config.git_version=Git Sürümü
-config.static_file_root_path=Sabit Dosya Kök Yolu
-config.log_file_root_path=Log Dosyası Kök Yolu
-config.reverse_auth_user=Tersine Yetkilendirme Kullanıcısı
+config.server.external_url=External URL
+config.server.domain=Domain
+config.server.protocol=Protocol
+config.server.http_addr=HTTP address
+config.server.http_port=HTTP port
+config.server.cert_file=Certificate file
+config.server.key_file=Key file
+config.server.tls_min_version=Minimum TLS version
+config.server.unix_socket_permission=Unix socket permission
+config.server.local_root_url=Local root URL
+config.server.offline_mode=Offline mode
+config.server.disable_router_log=Disable router log
+config.server.enable_gzip=Enable Gzip
+config.server.app_data_path=Application data path
+config.server.load_assets_from_disk=Load assets from disk
+config.server.landing_url=Landing URL
 
 config.ssh_config=SSH Yapılandırması
-config.ssh_enabled=Aktif
-config.ssh_start_builtin_server=Hazır Sunucuyu Başlat
-config.ssh_domain=Alan Adı
-config.ssh_port=Port
-config.ssh_listen_port=Port'u Dinle
-config.ssh_root_path=Kök Yol
-config.ssh_rewrite_authorized_keys_at_start=Başlangıçta yetkili anahtarları yeniden yaz
-config.ssh_key_test_path=Anahtar Test Yolu
-config.ssh_keygen_path=Keygen ('ssh-keygen') Yolu
-config.ssh_minimum_key_size_check=Minimum Anahtar Uzunluğu Kontrolü
-config.ssh_minimum_key_sizes=Minimum Anahtar Uzunlukları
+config.ssh.enabled=Enabled
+config.ssh.domain=Exposed domain
+config.ssh.port=Exposed port
+config.ssh.root_path=Root path
+config.ssh.keygen_path=Keygen path
+config.ssh.key_test_path=Key test path
+config.ssh.minimum_key_size_check=Minimum key size check
+config.ssh.minimum_key_sizes=Minimum key sizes
+config.ssh.rewrite_authorized_keys_at_start=Rewrite "authorized_keys" at start
+config.ssh.start_builtin_server=Start builtin server
+config.ssh.listen_host=Listen host
+config.ssh.listen_port=Listen port
+config.ssh.server_ciphers=Server ciphers
 
 config.repo_config=Depo Yapılandırması
-config.repo_root_path=Depo Kök Yolu
-config.script_type=Betik Türü
-config.repo_force_private=Özel Kuvvet
-config.max_creation_limit=Maksimum Oluşturma Sınırı
-config.preferred_licenses=Tercih Edilen Lisanslar
-config.disable_http_git=HTTP Git'i devre dışı bırak
-config.enable_local_path_migration=Yerel Yol Geçişi Etkinleştir
-config.commits_fetch_concurrency=Eşzamanlılık Alma Taahhüdü
-
-config.http_config=HTTP Yapılandırması
-config.http_access_control_allow_origin=Erişim Kontrolü Kaynağına İzin Ver
+config.repo.root_path=Root path
+config.repo.script_type=Script type
+config.repo.ansi_chatset=ANSI charset
+config.repo.force_private=Force private
+config.repo.max_creation_limit=Max creation limit
+config.repo.preferred_licenses=Preferred licenses
+config.repo.disable_http_git=Disable HTTP Git
+config.repo.enable_local_path_migration=Enable local path migration
+config.repo.enable_raw_file_render_mode=Enable raw file render mode
+config.repo.commits_fetch_concurrency=Commits fetch concurrency
+config.repo.editor.line_wrap_extensions=Editor line wrap extensions
+config.repo.editor.previewable_file_modes=Editor previewable file modes
+config.repo.upload.enabled=Upload enabled
+config.repo.upload.temp_path=Upload temporary path
+config.repo.upload.allowed_types=Upload allowed types
+config.repo.upload.file_max_size=Upload file size limit
+config.repo.upload.max_files=Upload files limit
 
 config.db_config=Veritabanı Yapılandırması
-config.db_type=Türü
-config.db_host=Sunucu
-config.db_name=İsim
-config.db_user=Kullanıcı
-config.db_ssl_mode=SSL Biçimi
-config.db_ssl_mode_helper=(sadece "postgres" için)
-config.db_path=Yol
-config.db_path_helper=("sqlite3" ve "tidb" için)
-
-config.service_config=Servis Yapılandırması
-config.register_email_confirm=E-posta Onayı Gerekli
-config.disable_register=Kaydolma Hizmet Dışı
-config.show_registration_button=Kaydolma Tuşunu Göster
-config.require_sign_in_view=Oturum Açma Görünümünü İste
-config.mail_notify=E-posta Bildirimi
-config.disable_key_size_check=Minimum Anahtar Uzunluğu Kontrolünü Devre Dışı Bırak
-config.enable_captcha=Captcha'yı Aktifleştir
-config.active_code_lives=Kod Yaşamlarını Aktifleştir
-config.reset_password_code_lives=Kod Yaşamları Parolasını Yenile
+config.db.type=Type
+config.db.host=Host
+config.db.name=Name
+config.db.user=User
+config.db.ssl_mode=SSL mode
+config.db.ssl_mode_helper=(for "postgres" only)
+config.db.path=Path
+config.db.path_helper=(for "sqlite3"only)
+
+config.security_config=Security configuration
+config.security.login_remember_days=Login remember days
+config.security.cookie_remember_name=Remember cookie
+config.security.cookie_username=Username cookie
+config.security.cookie_secure=Enable secure cookie
+config.security.reverse_proxy_auth_user=Reverse proxy authentication header
+config.security.enable_login_status_cookie=Enable login status cookie
+config.security.login_status_cookie_name=Login status cookie
+
+config.email_config=Email configuration
+config.email.enabled=Enabled
+config.email.subject_prefix=Subject prefix
+config.email.host=Host
+config.email.from=From
+config.email.user=User
+config.email.disable_helo=Disable HELO
+config.email.helo_hostname=HELO hostname
+config.email.skip_verify=Skip certificate verify
+config.email.use_certificate=Use custom certificate
+config.email.cert_file=Certificate file
+config.email.key_file=Key file
+config.email.use_plain_text=Use plain text
+config.email.add_plain_text_alt=Add plain text alternative
+config.email.send_test_mail=Send test email
+config.email.test_mail_failed=Failed to send test email to '%s': %v
+config.email.test_mail_sent=Test email has been sent to '%s'.
+
+config.auth_config=Authentication configuration
+config.auth.activate_code_lives=Activate code lives
+config.auth.reset_password_code_lives=Reset password code lives
+config.auth.require_email_confirm=Require email confirmation
+config.auth.require_sign_in_view=Require sign in view
+config.auth.disable_registration=Disable registration
+config.auth.enable_registration_captcha=Enable registration captcha
+config.auth.enable_reverse_proxy_authentication=Enable reverse proxy authentication
+config.auth.enable_reverse_proxy_auto_registration=Enable reverse proxy auto registration
+config.auth.reverse_proxy_authentication_header=Reverse proxy authentication header
+
+config.user_config=User configuration
+config.user.enable_email_notify=Enable email notification
 
-config.webhook_config=Web İstekleri Yapılandırması
-config.queue_length=Kuyruk Uzunluğu
-config.deliver_timeout=Dağıtım Zaman Aşımı
-config.skip_tls_verify=TLS Doğrulamasını Atla
-
-config.mailer_config=Mailer Yapılandırması
-config.mailer_enabled=Aktif
-config.mailer_disable_helo=HELO'yu Devre Dışı Bırak
-config.mailer_subject_prefix=Konu Öneki
-config.mailer_host=Sunucu
-config.mailer_user=Kullanıcı
-config.send_test_mail=Test E-Postası Gönder
-config.test_mail_failed='%s' adresine test e-postası gönderimi başarısız: %v
-config.test_mail_sent='%s' adresine test e-postası gönderildi.
-
-config.oauth_config=OAuth Yapılandırması
-config.oauth_enabled=Aktif
+config.session_config=Oturum Yapılandırması
+config.session.provider=Provider
+config.session.provider_config=Provider config
+config.session.cookie_name=Cookie
+config.session.https_only=HTTPS only
+config.session.gc_interval=GC interval
+config.session.max_life_time=Max life time
+config.session.csrf_cookie_name=CSRF cookie
 
 config.cache_config=Önbellek Yapılandırması
-config.cache_adapter=Önbellek Uyarlayıcısı
-config.cache_interval=Önbellek Aralığı
-config.cache_conn=Önbellek Bağlantısı
+config.cache.adapter=Adapter
+config.cache.interval=GC interval
+config.cache.host=Host
 
-config.session_config=Oturum Yapılandırması
-config.session_provider=Oturum Sağlayıcı
-config.provider_config=Sağlayıcı Yapılandırması
-config.cookie_name=Çerez Adı
-config.enable_set_cookie=Çerezleri Aktifleştir
-config.gc_interval_time=GC Aralık Zamanı
-config.session_life_time=Oturum Yaşam Zamanı
-config.https_only=Yalnız HTTPS
-config.cookie_life_time=Çerez Yaşam Zamanı
+config.http_config=HTTP Yapılandırması
+config.http.access_control_allow_origin=Access control allow origin
+
+config.attachment_config=Attachment configuration
+config.attachment.enabled=Enabled
+config.attachment.path=Path
+config.attachment.allowed_types=Allowed types
+config.attachment.max_size=Size limit
+config.attachment.max_files=Files limit
+
+config.release_config=Release configuration
+config.release.attachment.enabled=Attachment enabled
+config.release.attachment.allowed_types=Attachment allowed types
+config.release.attachment.max_size=Attachment size limit
+config.release.attachment.max_files=Attachment files limit
 
 config.picture_config=Resim Yapılandırması
-config.picture_service=Resim Servisi
-config.disable_gravatar=Gravatar Hizmet Dışı
-config.enable_federated_avatar=Birleştirilmiş Avatarları Etkinleştir
+config.picture.avatar_upload_path=User avatar upload path
+config.picture.repo_avatar_upload_path=Repository avatar upload path
+config.picture.gravatar_source=Gravatar source
+config.picture.disable_gravatar=Disable Gravatar
+config.picture.enable_federated_avatar=Enable federated avatars
+
+config.mirror_config=Mirror configuration
+config.mirror.default_interval=Default interval
+
+config.webhook_config=Web İstekleri Yapılandırması
+config.webhook.types=Types
+config.webhook.deliver_timeout=Deliver timeout
+config.webhook.skip_tls_verify=Skip TLS verify
 
 config.git_config=Git Yapılandırması
-config.git_disable_diff_highlight=Diff İşlemi Sözdizimini Devre Dışı Bırak
-config.git_max_diff_lines=Maksimum Ayırma Hatları (tek bir dosya için)
-config.git_max_diff_line_characters=Maksimum Ayırma Karakterleri(tek bir hat için)
-config.git_max_diff_files=Maksimum Ayırma Dosyaları(gösterilmek için)
-config.git_gc_args=GC Tartışmaları
-config.git_migrate_timeout=Geçiş Zaman Aşımı
-config.git_mirror_timeout=Yansımayı Güncelle Zaman Aşımı
-config.git_clone_timeout=Klon Çalışma Zaman Aşımı
-config.git_pull_timeout=Çekme İşlemi Zaman Aşımı
-config.git_gc_timeout=GC İşlem Zaman Aşımı
+config.git.disable_diff_highlight=Disable diff syntax highlight
+config.git.max_diff_lines=Diff lines limit (for a single file)
+config.git.max_diff_line_characters=Diff characters limit (for a single line)
+config.git.max_diff_files=Diff files limit (for a single diff)
+config.git.gc_args=GC arguments
+config.git.migrate_timeout=Migration timeout
+config.git.mirror_timeout=Mirror fetch timeout
+config.git.clone_timeout=Clone timeout
+config.git.pull_timeout=Pull timeout
+config.git.gc_timeout=GC timeout
 
 config.log_config=Log Yapılandırması
+config.log_file_root_path=Log Dosyası Kök Yolu
 config.log_mode=Mod
 config.log_options=Seçenekler
 
@@ -1338,6 +1397,7 @@ months=%d ay %s
 years=%d yıl %s
 raw_seconds=saniyeler
 raw_minutes=dakikalar
+raw_hours=hours
 
 [dropzone]
 default_message=Dosyaları yüklemek için sürükleyin veya tıklayın.

+ 154 - 94
conf/locale/locale_uk-UA.ini

@@ -9,7 +9,6 @@ sign_out=Вийти
 sign_up=Реєстрація
 register=Реєстрація
 website=Веб-сторінка
-version=Версія
 page=Сторінка
 template=Шаблон
 language=Мова
@@ -122,6 +121,7 @@ run_user_not_match=Користувач, що здійснює запуск, н
 smtp_host_missing_port=В адресі SMTP-хосту не вистачає порту.
 invalid_smtp_from=Невалідне SMTP поле Від: %v
 save_config_failed=Не в змозі зберегти конфігурацію: %v
+init_failed=Failed to initialize application: %v
 invalid_admin_setting=Неприпустимі налаштування облікового запису адміністратора: %v
 install_success=Вітаємо! Ми раді, що ви обрали GIN, отримуйте задоволення і будьте обережні.
 invalid_log_root_path=Шлях до лог файлу хибний: %v
@@ -1001,6 +1001,12 @@ first_page=Перша
 last_page=Остання
 total=Всього: %d
 
+dashboard.build_info=Build Information
+dashboard.app_ver=Application version
+dashboard.git_version=Git version
+dashboard.go_version=Go version
+dashboard.build_time=Build time
+dashboard.build_commit=Build commit
 dashboard.statistic=Статистика
 dashboard.operations=Операції
 dashboard.system_status=Статус системного монітору
@@ -1156,117 +1162,170 @@ auths.github_api_endpoint=Адреса API
 
 config.not_set=(не встановлено)
 config.server_config=Конфігурація сервера
-config.app_name=Назва програми
-config.app_ver=Версія програми
-config.app_url=URL адреса програми
-config.domain=Домен
-config.offline_mode=Офлайн режим
-config.disable_router_log=Вимкнути логування роутеру
+config.brand_name=Brand name
 config.run_user=Запущено користувачем
 config.run_mode=Режим виконання
-config.git_version=Версія Git
-config.static_file_root_path=Повний шлях до статичного файлу
-config.log_file_root_path=Повний шлях до Log-файлу
-config.reverse_auth_user=Reverse Authentication User
+config.server.external_url=External URL
+config.server.domain=Domain
+config.server.protocol=Protocol
+config.server.http_addr=HTTP address
+config.server.http_port=HTTP port
+config.server.cert_file=Certificate file
+config.server.key_file=Key file
+config.server.tls_min_version=Minimum TLS version
+config.server.unix_socket_permission=Unix socket permission
+config.server.local_root_url=Local root URL
+config.server.offline_mode=Offline mode
+config.server.disable_router_log=Disable router log
+config.server.enable_gzip=Enable Gzip
+config.server.app_data_path=Application data path
+config.server.load_assets_from_disk=Load assets from disk
+config.server.landing_url=Landing URL
 
 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_rewrite_authorized_keys_at_start=Переписати authorized_keys на початку
-config.ssh_key_test_path=Шлях до тестових ключів
-config.ssh_keygen_path=Шлях до генератора ключів ('ssh-keygen')
-config.ssh_minimum_key_size_check=Мінімальний розмір ключа перевірки
-config.ssh_minimum_key_sizes=Мінімальні розміри ключів
+config.ssh.enabled=Enabled
+config.ssh.domain=Exposed domain
+config.ssh.port=Exposed port
+config.ssh.root_path=Root path
+config.ssh.keygen_path=Keygen path
+config.ssh.key_test_path=Key test path
+config.ssh.minimum_key_size_check=Minimum key size check
+config.ssh.minimum_key_sizes=Minimum key sizes
+config.ssh.rewrite_authorized_keys_at_start=Rewrite "authorized_keys" at start
+config.ssh.start_builtin_server=Start builtin server
+config.ssh.listen_host=Listen host
+config.ssh.listen_port=Listen port
+config.ssh.server_ciphers=Server ciphers
 
 config.repo_config=Налаштування репозиторія
-config.repo_root_path=Повний шлях до репозиторія
-config.script_type=Тип скрипта
-config.repo_force_private=Зробити приватним примусово
-config.max_creation_limit=Ліміт створень
-config.preferred_licenses=Бажана ліцензія
-config.disable_http_git=Вимкнути HTTP Git
-config.enable_local_path_migration=Увімкнути міграцію з локального шляху
-config.commits_fetch_concurrency=Запросити коміти конкурентно
-
-config.http_config=Налаштування HTTP
-config.http_access_control_allow_origin=Контроль доступу дозволяє Origin
+config.repo.root_path=Root path
+config.repo.script_type=Script type
+config.repo.ansi_chatset=ANSI charset
+config.repo.force_private=Force private
+config.repo.max_creation_limit=Max creation limit
+config.repo.preferred_licenses=Preferred licenses
+config.repo.disable_http_git=Disable HTTP Git
+config.repo.enable_local_path_migration=Enable local path migration
+config.repo.enable_raw_file_render_mode=Enable raw file render mode
+config.repo.commits_fetch_concurrency=Commits fetch concurrency
+config.repo.editor.line_wrap_extensions=Editor line wrap extensions
+config.repo.editor.previewable_file_modes=Editor previewable file modes
+config.repo.upload.enabled=Upload enabled
+config.repo.upload.temp_path=Upload temporary path
+config.repo.upload.allowed_types=Upload allowed types
+config.repo.upload.file_max_size=Upload file size limit
+config.repo.upload.max_files=Upload files limit
 
 config.db_config=Налаштування бази даних
-config.db_type=Тип
-config.db_host=Хост
-config.db_name=Назва
-config.db_user=Користувач
-config.db_ssl_mode=Режим SSL
-config.db_ssl_mode_helper=(тільки для "postgres")
-config.db_path=Шлях
-config.db_path_helper=(для "sqlite3" і "tidb")
-
-config.service_config=Конфігурація сервіса
-config.register_email_confirm=Вимагати підтвердження по електронній пошті
-config.disable_register=Вимкнути реєстрацію
-config.show_registration_button=Показувати кнопку "Реєстрація"
-config.require_sign_in_view=Необхідно авторизуватися для перегляду
-config.mail_notify=Сповіщення поштою
-config.disable_key_size_check=Вимкнути перевірку мінімального розміру ключа
-config.enable_captcha=Увімкнути капчу
-config.active_code_lives=Час актуальності кода підтвердження
-config.reset_password_code_lives=Термін придатності кода скидання пароля
+config.db.type=Type
+config.db.host=Host
+config.db.name=Name
+config.db.user=User
+config.db.ssl_mode=SSL mode
+config.db.ssl_mode_helper=(for "postgres" only)
+config.db.path=Path
+config.db.path_helper=(for "sqlite3"only)
+
+config.security_config=Security configuration
+config.security.login_remember_days=Login remember days
+config.security.cookie_remember_name=Remember cookie
+config.security.cookie_username=Username cookie
+config.security.cookie_secure=Enable secure cookie
+config.security.reverse_proxy_auth_user=Reverse proxy authentication header
+config.security.enable_login_status_cookie=Enable login status cookie
+config.security.login_status_cookie_name=Login status cookie
+
+config.email_config=Email configuration
+config.email.enabled=Enabled
+config.email.subject_prefix=Subject prefix
+config.email.host=Host
+config.email.from=From
+config.email.user=User
+config.email.disable_helo=Disable HELO
+config.email.helo_hostname=HELO hostname
+config.email.skip_verify=Skip certificate verify
+config.email.use_certificate=Use custom certificate
+config.email.cert_file=Certificate file
+config.email.key_file=Key file
+config.email.use_plain_text=Use plain text
+config.email.add_plain_text_alt=Add plain text alternative
+config.email.send_test_mail=Send test email
+config.email.test_mail_failed=Failed to send test email to '%s': %v
+config.email.test_mail_sent=Test email has been sent to '%s'.
+
+config.auth_config=Authentication configuration
+config.auth.activate_code_lives=Activate code lives
+config.auth.reset_password_code_lives=Reset password code lives
+config.auth.require_email_confirm=Require email confirmation
+config.auth.require_sign_in_view=Require sign in view
+config.auth.disable_registration=Disable registration
+config.auth.enable_registration_captcha=Enable registration captcha
+config.auth.enable_reverse_proxy_authentication=Enable reverse proxy authentication
+config.auth.enable_reverse_proxy_auto_registration=Enable reverse proxy auto registration
+config.auth.reverse_proxy_authentication_header=Reverse proxy authentication header
+
+config.user_config=User configuration
+config.user.enable_email_notify=Enable email notification
 
-config.webhook_config=Налаштування web-хуків
-config.queue_length=Довжина черги
-config.deliver_timeout=Затримка доставлення
-config.skip_tls_verify=Пропустити перевірку TLS
-
-config.mailer_config=Налаштування пошти
-config.mailer_enabled=Увімкнено
-config.mailer_disable_helo=Вимкнути HELO
-config.mailer_subject_prefix=Префікс теми
-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.session_config=Налаштування сесії
+config.session.provider=Provider
+config.session.provider_config=Provider config
+config.session.cookie_name=Cookie
+config.session.https_only=HTTPS only
+config.session.gc_interval=GC interval
+config.session.max_life_time=Max life time
+config.session.csrf_cookie_name=CSRF cookie
 
 config.cache_config=Конфігурація кешу
-config.cache_adapter=Адаптер кешу
-config.cache_interval=Інтервал кешування
-config.cache_conn=Підключення до кешу
+config.cache.adapter=Adapter
+config.cache.interval=GC interval
+config.cache.host=Host
 
-config.session_config=Налаштування сесії
-config.session_provider=Провайдер сесії
-config.provider_config=Provider Config
-config.cookie_name=Ім'я cookie-файлу
-config.enable_set_cookie=Увімкнути встановлення cookie
-config.gc_interval_time=Інтервал запуску GC
-config.session_life_time=Час життя сесії
-config.https_only=Виключно HTTPS
-config.cookie_life_time=Час життя cookie-файлу
+config.http_config=Налаштування HTTP
+config.http.access_control_allow_origin=Access control allow origin
+
+config.attachment_config=Attachment configuration
+config.attachment.enabled=Enabled
+config.attachment.path=Path
+config.attachment.allowed_types=Allowed types
+config.attachment.max_size=Size limit
+config.attachment.max_files=Files limit
+
+config.release_config=Release configuration
+config.release.attachment.enabled=Attachment enabled
+config.release.attachment.allowed_types=Attachment allowed types
+config.release.attachment.max_size=Attachment size limit
+config.release.attachment.max_files=Attachment files limit
 
 config.picture_config=Налаштування зображень
-config.picture_service=Сервіс зображень
-config.disable_gravatar=Вимкнути Gravatar
-config.enable_federated_avatar=Увімкнути зовнішні аватари
+config.picture.avatar_upload_path=User avatar upload path
+config.picture.repo_avatar_upload_path=Repository avatar upload path
+config.picture.gravatar_source=Gravatar source
+config.picture.disable_gravatar=Disable Gravatar
+config.picture.enable_federated_avatar=Enable federated avatars
+
+config.mirror_config=Mirror configuration
+config.mirror.default_interval=Default interval
+
+config.webhook_config=Налаштування web-хуків
+config.webhook.types=Types
+config.webhook.deliver_timeout=Deliver timeout
+config.webhook.skip_tls_verify=Skip TLS verify
 
 config.git_config=Налаштування git
-config.git_disable_diff_highlight=Вимкнути підсвітку синтаксису diff
-config.git_max_diff_lines=Максимум рядків на diff (на один файл)
-config.git_max_diff_line_characters=Максимум символів на diff (на один файл)
-config.git_max_diff_files=Максимум diff-файлів (для показу)
-config.git_gc_args=Аргументи GC
-config.git_migrate_timeout=Тайм-аут міграції
-config.git_mirror_timeout=Тайм-аут оновлення дзеркала
-config.git_clone_timeout=Тайм-аут операції клонування
-config.git_pull_timeout=Тайм-аут операції витягання
-config.git_gc_timeout=Тайм-аут операції GC
+config.git.disable_diff_highlight=Disable diff syntax highlight
+config.git.max_diff_lines=Diff lines limit (for a single file)
+config.git.max_diff_line_characters=Diff characters limit (for a single line)
+config.git.max_diff_files=Diff files limit (for a single diff)
+config.git.gc_args=GC arguments
+config.git.migrate_timeout=Migration timeout
+config.git.mirror_timeout=Mirror fetch timeout
+config.git.clone_timeout=Clone timeout
+config.git.pull_timeout=Pull timeout
+config.git.gc_timeout=GC timeout
 
 config.log_config=Конфігурація журналу
+config.log_file_root_path=Повний шлях до Log-файлу
 config.log_mode=Режим
 config.log_options=Опції
 
@@ -1338,6 +1397,7 @@ months=%d місяців %s
 years=%d роки %s
 raw_seconds=секунди
 raw_minutes=хвилини
+raw_hours=hours
 
 [dropzone]
 default_message=Перетягніть файли сюди або натисніть "завантажити".

+ 154 - 94
conf/locale/locale_vi-VN.ini

@@ -9,7 +9,6 @@ sign_out=Đăng xuất
 sign_up=Đăng ký
 register=Đăng ký
 website=Website
-version=Phiên bản
 page=Trang
 template=Mẫu
 language=Ngôn ngữ
@@ -122,6 +121,7 @@ run_user_not_match=Người dùng đang chạy không phải là người dùng
 smtp_host_missing_port=SMTP host thiếu thông tin cổng ở địa chỉ.
 invalid_smtp_from=Trường SMTP không hợp lệ: %v
 save_config_failed=Lưu cấu hình thất bại: %v
+init_failed=Failed to initialize application: %v
 invalid_admin_setting=Thiết lập tài khoản admin không hợp lệ: %v
 install_success=Chào mừng! Chúng tôi vui mừng vì bạn chọn Gogs, chúc bạn vui.
 invalid_log_root_path=Đường dẫn gốc cho Log không hợp lệ: %v
@@ -1001,6 +1001,12 @@ first_page=Đầu tiên
 last_page=Cuối
 total=Tổng: %d
 
+dashboard.build_info=Build Information
+dashboard.app_ver=Application version
+dashboard.git_version=Git version
+dashboard.go_version=Go version
+dashboard.build_time=Build time
+dashboard.build_commit=Build commit
 dashboard.statistic=Thống kê
 dashboard.operations=Hoạt động
 dashboard.system_status=Tình trạng quản lý hệ thống
@@ -1156,117 +1162,170 @@ auths.github_api_endpoint=API Endpoint
 
 config.not_set=(chưa đặt)
 config.server_config=Cấu hình server
-config.app_name=Tên chương trình
-config.app_ver=Phiên bản phần mềm
-config.app_url=URL chương trình
-config.domain=Tên miền
-config.offline_mode=Chế độ ngoại tuyến
-config.disable_router_log=Vô hiệu hóa log định tuyến
+config.brand_name=Brand name
 config.run_user=Người dùng đang chạy
 config.run_mode=Chế độ đang chạy
-config.git_version=Phiên bản git
-config.static_file_root_path=Đường dẫn gốc file trạng thái
-config.log_file_root_path=Đường dẫn gốc file Log
-config.reverse_auth_user=Reverse Authentication User
+config.server.external_url=External URL
+config.server.domain=Domain
+config.server.protocol=Protocol
+config.server.http_addr=HTTP address
+config.server.http_port=HTTP port
+config.server.cert_file=Certificate file
+config.server.key_file=Key file
+config.server.tls_min_version=Minimum TLS version
+config.server.unix_socket_permission=Unix socket permission
+config.server.local_root_url=Local root URL
+config.server.offline_mode=Offline mode
+config.server.disable_router_log=Disable router log
+config.server.enable_gzip=Enable Gzip
+config.server.app_data_path=Application data path
+config.server.load_assets_from_disk=Load assets from disk
+config.server.landing_url=Landing URL
 
 config.ssh_config=Cấu hình SSH
-config.ssh_enabled=Đã kích hoạt
-config.ssh_start_builtin_server=Bắt đầu máy chủ Builtin
-config.ssh_domain=Tên miền
-config.ssh_port=Cổng
-config.ssh_listen_port=Cổng lắng nghe
-config.ssh_root_path=Đường dẫn Root
-config.ssh_rewrite_authorized_keys_at_start=Rewrite authorized_keys lúc bắt đầu
-config.ssh_key_test_path=Đường dẫn khóa kiểm tra
-config.ssh_keygen_path=Keygen ('ssh-keygen') Path
-config.ssh_minimum_key_size_check=Kiểm tra kích cỡ khóa nhỏ nhất
-config.ssh_minimum_key_sizes=Làm nhỏ kích cỡ khóa
+config.ssh.enabled=Enabled
+config.ssh.domain=Exposed domain
+config.ssh.port=Exposed port
+config.ssh.root_path=Root path
+config.ssh.keygen_path=Keygen path
+config.ssh.key_test_path=Key test path
+config.ssh.minimum_key_size_check=Minimum key size check
+config.ssh.minimum_key_sizes=Minimum key sizes
+config.ssh.rewrite_authorized_keys_at_start=Rewrite "authorized_keys" at start
+config.ssh.start_builtin_server=Start builtin server
+config.ssh.listen_host=Listen host
+config.ssh.listen_port=Listen port
+config.ssh.server_ciphers=Server ciphers
 
 config.repo_config=Cấu hình kho
-config.repo_root_path=Đường dẫn gốc cho kho
-config.script_type=Kiểu script
-config.repo_force_private=Bắc buộc riêng tư
-config.max_creation_limit=Giới hạn số lượng tạo
-config.preferred_licenses=Giấy phép ưu tiên
-config.disable_http_git=Vô hiệu hóa HTTP Git
-config.enable_local_path_migration=Kích hoạt di cư đường dẫn địa phương
-config.commits_fetch_concurrency=Commits Fetch Concurrency
-
-config.http_config=Cấu hình HTTP
-config.http_access_control_allow_origin=Kiểm soát truy cập cho phép origin
+config.repo.root_path=Root path
+config.repo.script_type=Script type
+config.repo.ansi_chatset=ANSI charset
+config.repo.force_private=Force private
+config.repo.max_creation_limit=Max creation limit
+config.repo.preferred_licenses=Preferred licenses
+config.repo.disable_http_git=Disable HTTP Git
+config.repo.enable_local_path_migration=Enable local path migration
+config.repo.enable_raw_file_render_mode=Enable raw file render mode
+config.repo.commits_fetch_concurrency=Commits fetch concurrency
+config.repo.editor.line_wrap_extensions=Editor line wrap extensions
+config.repo.editor.previewable_file_modes=Editor previewable file modes
+config.repo.upload.enabled=Upload enabled
+config.repo.upload.temp_path=Upload temporary path
+config.repo.upload.allowed_types=Upload allowed types
+config.repo.upload.file_max_size=Upload file size limit
+config.repo.upload.max_files=Upload files limit
 
 config.db_config=Cấu hình Cơ sỡ dữ liệu
-config.db_type=Loại database
-config.db_host=Host
-config.db_name=Tên
-config.db_user=Người dùng
-config.db_ssl_mode=Chế độ SSL
-config.db_ssl_mode_helper=(for "postgres" only)
-config.db_path=Đường dẫn
-config.db_path_helper=(cho "sqlite3" và "tidb")
-
-config.service_config=Cấu hình dịch vụ
-config.register_email_confirm=Yêu cầu xác nhận email
-config.disable_register=Vô hiệu hóa tự đăng ký
-config.show_registration_button=Hiển thị nút đăng ký
-config.require_sign_in_view=Yêu cầu đăng nhập để xem
-config.mail_notify=Thông báo mail
-config.disable_key_size_check=Vô hiệu hóa kiểm tra kích cỡ khóa nhỏ nhất
-config.enable_captcha=Bật Captcha
-config.active_code_lives=Active Code Lives
-config.reset_password_code_lives=Reset Password Code Lives
+config.db.type=Type
+config.db.host=Host
+config.db.name=Name
+config.db.user=User
+config.db.ssl_mode=SSL mode
+config.db.ssl_mode_helper=(for "postgres" only)
+config.db.path=Path
+config.db.path_helper=(for "sqlite3"only)
+
+config.security_config=Security configuration
+config.security.login_remember_days=Login remember days
+config.security.cookie_remember_name=Remember cookie
+config.security.cookie_username=Username cookie
+config.security.cookie_secure=Enable secure cookie
+config.security.reverse_proxy_auth_user=Reverse proxy authentication header
+config.security.enable_login_status_cookie=Enable login status cookie
+config.security.login_status_cookie_name=Login status cookie
+
+config.email_config=Email configuration
+config.email.enabled=Enabled
+config.email.subject_prefix=Subject prefix
+config.email.host=Host
+config.email.from=From
+config.email.user=User
+config.email.disable_helo=Disable HELO
+config.email.helo_hostname=HELO hostname
+config.email.skip_verify=Skip certificate verify
+config.email.use_certificate=Use custom certificate
+config.email.cert_file=Certificate file
+config.email.key_file=Key file
+config.email.use_plain_text=Use plain text
+config.email.add_plain_text_alt=Add plain text alternative
+config.email.send_test_mail=Send test email
+config.email.test_mail_failed=Failed to send test email to '%s': %v
+config.email.test_mail_sent=Test email has been sent to '%s'.
+
+config.auth_config=Authentication configuration
+config.auth.activate_code_lives=Activate code lives
+config.auth.reset_password_code_lives=Reset password code lives
+config.auth.require_email_confirm=Require email confirmation
+config.auth.require_sign_in_view=Require sign in view
+config.auth.disable_registration=Disable registration
+config.auth.enable_registration_captcha=Enable registration captcha
+config.auth.enable_reverse_proxy_authentication=Enable reverse proxy authentication
+config.auth.enable_reverse_proxy_auto_registration=Enable reverse proxy auto registration
+config.auth.reverse_proxy_authentication_header=Reverse proxy authentication header
+
+config.user_config=User configuration
+config.user.enable_email_notify=Enable email notification
 
-config.webhook_config=Cấu hình Webhook
-config.queue_length=Chiều dài hàng đợi
-config.deliver_timeout=Thời gian chờ phân phối
-config.skip_tls_verify=Bỏ qua xác thực TLS
-
-config.mailer_config=Cấu hình Mail
-config.mailer_enabled=Đã kích hoạt
-config.mailer_disable_helo=Vô hiệu hoá HELO
-config.mailer_subject_prefix=Subject Prefix
-config.mailer_host=Host
-config.mailer_user=Người dùng
-config.send_test_mail=Gửi Mail Thử nghiệm
-config.test_mail_failed=Thất bại gửi email test đến '%s':%v
-config.test_mail_sent=Email test đã được gửi đến '%s'.
-
-config.oauth_config=Cấu hình OAuth
-config.oauth_enabled=Đã kích hoạt
+config.session_config=Cấu hình session
+config.session.provider=Provider
+config.session.provider_config=Provider config
+config.session.cookie_name=Cookie
+config.session.https_only=HTTPS only
+config.session.gc_interval=GC interval
+config.session.max_life_time=Max life time
+config.session.csrf_cookie_name=CSRF cookie
 
 config.cache_config=Cấu hình cache
-config.cache_adapter=Bộ chuyển cache
-config.cache_interval=Thời gian chờ cache
-config.cache_conn=Kết nối cache
+config.cache.adapter=Adapter
+config.cache.interval=GC interval
+config.cache.host=Host
 
-config.session_config=Cấu hình session
-config.session_provider=Nhà cung cấp provider
-config.provider_config=Cấu hình nhà cung cấp
-config.cookie_name=Tên Cookie
-config.enable_set_cookie=Bật thiết lập Cookie
-config.gc_interval_time=GC Interval Time
-config.session_life_time=Thời gian phiên làm việc
-config.https_only=Chỉ HTTPS
-config.cookie_life_time=Thời gian hoạt động của Cookie
+config.http_config=Cấu hình HTTP
+config.http.access_control_allow_origin=Access control allow origin
+
+config.attachment_config=Attachment configuration
+config.attachment.enabled=Enabled
+config.attachment.path=Path
+config.attachment.allowed_types=Allowed types
+config.attachment.max_size=Size limit
+config.attachment.max_files=Files limit
+
+config.release_config=Release configuration
+config.release.attachment.enabled=Attachment enabled
+config.release.attachment.allowed_types=Attachment allowed types
+config.release.attachment.max_size=Attachment size limit
+config.release.attachment.max_files=Attachment files limit
 
 config.picture_config=Cấu hình ảnh
-config.picture_service=Dịch vụ ảnh
-config.disable_gravatar=Vô hiệu hóa Gravatar
-config.enable_federated_avatar=Kích hoạt Federated Avatar
+config.picture.avatar_upload_path=User avatar upload path
+config.picture.repo_avatar_upload_path=Repository avatar upload path
+config.picture.gravatar_source=Gravatar source
+config.picture.disable_gravatar=Disable Gravatar
+config.picture.enable_federated_avatar=Enable federated avatars
+
+config.mirror_config=Mirror configuration
+config.mirror.default_interval=Default interval
+
+config.webhook_config=Cấu hình Webhook
+config.webhook.types=Types
+config.webhook.deliver_timeout=Deliver timeout
+config.webhook.skip_tls_verify=Skip TLS verify
 
 config.git_config=Cấu hình Git
-config.git_disable_diff_highlight=Disable Diff Syntax Highlight
-config.git_max_diff_lines=Số dòng khác tối đa (cho một file duy nhất)
-config.git_max_diff_line_characters=Số ký tự khác tối đa (cho một dòng)
-config.git_max_diff_files=Số file khác tối đa (sẽ được hiển thị)
-config.git_gc_args=Các tham số GC
-config.git_migrate_timeout=Thời gian chờ di chuyển
-config.git_mirror_timeout=Thời gian chờ cập nhật Mirror
-config.git_clone_timeout=Thời gian chờ hoạt động Clone
-config.git_pull_timeout=Thời gian chờ hoạt động Pull
-config.git_gc_timeout=Thời gian chờ hoạt động GC
+config.git.disable_diff_highlight=Disable diff syntax highlight
+config.git.max_diff_lines=Diff lines limit (for a single file)
+config.git.max_diff_line_characters=Diff characters limit (for a single line)
+config.git.max_diff_files=Diff files limit (for a single diff)
+config.git.gc_args=GC arguments
+config.git.migrate_timeout=Migration timeout
+config.git.mirror_timeout=Mirror fetch timeout
+config.git.clone_timeout=Clone timeout
+config.git.pull_timeout=Pull timeout
+config.git.gc_timeout=GC timeout
 
 config.log_config=Cấu hình Log
+config.log_file_root_path=Đường dẫn gốc file Log
 config.log_mode=Chế độ
 config.log_options=Tuỳ chọn
 
@@ -1338,6 +1397,7 @@ months=%d tháng trước %s
 years=%d năm trước %s
 raw_seconds=giây
 raw_minutes=phút
+raw_hours=hours
 
 [dropzone]
 default_message=Thả các tập tin ở đây hoặc bấm vào để tải lên.

+ 154 - 94
conf/locale/locale_zh-CN.ini

@@ -9,7 +9,6 @@ sign_out=退出
 sign_up=注册
 register=注册
 website=官方网站
-version=当前版本
 page=页面
 template=模板
 language=语言选项
@@ -122,6 +121,7 @@ run_user_not_match=运行系统用户非当前用户:%s -> %s
 smtp_host_missing_port=SMTP 地址缺少端口号。
 invalid_smtp_from=SMTP From 字段不合法:%v
 save_config_failed=应用配置保存失败:%v
+init_failed=Failed to initialize application: %v
 invalid_admin_setting=管理员帐户设置不正确:%v
 install_success=您好!我们很高兴您选择使用 Gogs,祝您使用愉快,代码从此无 BUG!
 invalid_log_root_path=无效的日志路径:%v
@@ -1001,6 +1001,12 @@ first_page=首页
 last_page=末页
 total=总计:%d
 
+dashboard.build_info=Build Information
+dashboard.app_ver=Application version
+dashboard.git_version=Git version
+dashboard.go_version=Go version
+dashboard.build_time=Build time
+dashboard.build_commit=Build commit
 dashboard.statistic=应用统计数据
 dashboard.operations=管理员操作
 dashboard.system_status=系统监视状态
@@ -1156,117 +1162,170 @@ auths.github_api_endpoint=API Endpoint
 
 config.not_set=(未设置)
 config.server_config=服务器配置
-config.app_name=应用名称
-config.app_ver=应用版本
-config.app_url=应用 URL
-config.domain=应用域名
-config.offline_mode=离线模式
-config.disable_router_log=关闭路由日志
+config.brand_name=Brand name
 config.run_user=运行用户
 config.run_mode=运行模式
-config.git_version=Git 版本
-config.static_file_root_path=静态文件根目录
-config.log_file_root_path=日志文件根目录
-config.reverse_auth_user=反向代理认证
+config.server.external_url=External URL
+config.server.domain=Domain
+config.server.protocol=Protocol
+config.server.http_addr=HTTP address
+config.server.http_port=HTTP port
+config.server.cert_file=Certificate file
+config.server.key_file=Key file
+config.server.tls_min_version=Minimum TLS version
+config.server.unix_socket_permission=Unix socket permission
+config.server.local_root_url=Local root URL
+config.server.offline_mode=Offline mode
+config.server.disable_router_log=Disable router log
+config.server.enable_gzip=Enable Gzip
+config.server.app_data_path=Application data path
+config.server.load_assets_from_disk=Load assets from disk
+config.server.landing_url=Landing URL
 
 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_rewrite_authorized_keys_at_start=在启动时重写 authorized_keys 文件
-config.ssh_key_test_path=密钥测试路径
-config.ssh_keygen_path=密钥生成器('ssh-keygen')路径
-config.ssh_minimum_key_size_check=密钥最小长度检查
-config.ssh_minimum_key_sizes=密钥最小长度限制
+config.ssh.enabled=Enabled
+config.ssh.domain=Exposed domain
+config.ssh.port=Exposed port
+config.ssh.root_path=Root path
+config.ssh.keygen_path=Keygen path
+config.ssh.key_test_path=Key test path
+config.ssh.minimum_key_size_check=Minimum key size check
+config.ssh.minimum_key_sizes=Minimum key sizes
+config.ssh.rewrite_authorized_keys_at_start=Rewrite "authorized_keys" at start
+config.ssh.start_builtin_server=Start builtin server
+config.ssh.listen_host=Listen host
+config.ssh.listen_port=Listen port
+config.ssh.server_ciphers=Server ciphers
 
 config.repo_config=仓库配置
-config.repo_root_path=仓库根目录
-config.script_type=脚本类型
-config.repo_force_private=强制设为私有
-config.max_creation_limit=可创建数量限制
-config.preferred_licenses=推荐许可证
-config.disable_http_git=禁用 HTTP Git 操作
-config.enable_local_path_migration=启用本地路径迁移
-config.commits_fetch_concurrency=代码提交拉取并发量
-
-config.http_config=HTTP 配置
-config.http_access_control_allow_origin=Access Control Allow Origin
+config.repo.root_path=Root path
+config.repo.script_type=Script type
+config.repo.ansi_chatset=ANSI charset
+config.repo.force_private=Force private
+config.repo.max_creation_limit=Max creation limit
+config.repo.preferred_licenses=Preferred licenses
+config.repo.disable_http_git=Disable HTTP Git
+config.repo.enable_local_path_migration=Enable local path migration
+config.repo.enable_raw_file_render_mode=Enable raw file render mode
+config.repo.commits_fetch_concurrency=Commits fetch concurrency
+config.repo.editor.line_wrap_extensions=Editor line wrap extensions
+config.repo.editor.previewable_file_modes=Editor previewable file modes
+config.repo.upload.enabled=Upload enabled
+config.repo.upload.temp_path=Upload temporary path
+config.repo.upload.allowed_types=Upload allowed types
+config.repo.upload.file_max_size=Upload file size limit
+config.repo.upload.max_files=Upload files limit
 
 config.db_config=数据库配置
-config.db_type=数据库类型
-config.db_host=主机地址
-config.db_name=数据库名称
-config.db_user=连接用户
-config.db_ssl_mode=SSL 模式
-config.db_ssl_mode_helper=(仅限 "postgres" 使用)
-config.db_path=数据库路径
-config.db_path_helper=(用于 "sqlite3" 和 "tidb")
-
-config.service_config=服务配置
-config.register_email_confirm=注册邮件确认
-config.disable_register=关闭注册功能
-config.show_registration_button=显示注册按钮
-config.require_sign_in_view=强制登录浏览
-config.mail_notify=邮件通知提醒
-config.disable_key_size_check=禁用密钥最小长度检查
-config.enable_captcha=启用验证码服务
-config.active_code_lives=激活用户链接有效期
-config.reset_password_code_lives=重置密码链接有效期
+config.db.type=Type
+config.db.host=Host
+config.db.name=Name
+config.db.user=User
+config.db.ssl_mode=SSL mode
+config.db.ssl_mode_helper=(for "postgres" only)
+config.db.path=Path
+config.db.path_helper=(for "sqlite3"only)
+
+config.security_config=Security configuration
+config.security.login_remember_days=Login remember days
+config.security.cookie_remember_name=Remember cookie
+config.security.cookie_username=Username cookie
+config.security.cookie_secure=Enable secure cookie
+config.security.reverse_proxy_auth_user=Reverse proxy authentication header
+config.security.enable_login_status_cookie=Enable login status cookie
+config.security.login_status_cookie_name=Login status cookie
+
+config.email_config=Email configuration
+config.email.enabled=Enabled
+config.email.subject_prefix=Subject prefix
+config.email.host=Host
+config.email.from=From
+config.email.user=User
+config.email.disable_helo=Disable HELO
+config.email.helo_hostname=HELO hostname
+config.email.skip_verify=Skip certificate verify
+config.email.use_certificate=Use custom certificate
+config.email.cert_file=Certificate file
+config.email.key_file=Key file
+config.email.use_plain_text=Use plain text
+config.email.add_plain_text_alt=Add plain text alternative
+config.email.send_test_mail=Send test email
+config.email.test_mail_failed=Failed to send test email to '%s': %v
+config.email.test_mail_sent=Test email has been sent to '%s'.
+
+config.auth_config=Authentication configuration
+config.auth.activate_code_lives=Activate code lives
+config.auth.reset_password_code_lives=Reset password code lives
+config.auth.require_email_confirm=Require email confirmation
+config.auth.require_sign_in_view=Require sign in view
+config.auth.disable_registration=Disable registration
+config.auth.enable_registration_captcha=Enable registration captcha
+config.auth.enable_reverse_proxy_authentication=Enable reverse proxy authentication
+config.auth.enable_reverse_proxy_auto_registration=Enable reverse proxy auto registration
+config.auth.reverse_proxy_authentication_header=Reverse proxy authentication header
+
+config.user_config=User configuration
+config.user.enable_email_notify=Enable email notification
 
-config.webhook_config=Web 钩子配置
-config.queue_length=队列长度
-config.deliver_timeout=推送超时
-config.skip_tls_verify=忽略 TLS 验证
-
-config.mailer_config=邮件配置
-config.mailer_enabled=启用服务
-config.mailer_disable_helo=禁用 HELO 操作
-config.mailer_subject_prefix=主题前缀
-config.mailer_host=邮件主机地址
-config.mailer_user=发送者帐号
-config.send_test_mail=发送测试邮件
-config.test_mail_failed=发送测试邮件至 '%s' 时失败:%v
-config.test_mail_sent=测试邮件已经发送至 '%s'。
-
-config.oauth_config=社交帐号配置
-config.oauth_enabled=启用服务
+config.session_config=Session 配置
+config.session.provider=Provider
+config.session.provider_config=Provider config
+config.session.cookie_name=Cookie
+config.session.https_only=HTTPS only
+config.session.gc_interval=GC interval
+config.session.max_life_time=Max life time
+config.session.csrf_cookie_name=CSRF cookie
 
 config.cache_config=Cache 配置
-config.cache_adapter=Cache 适配器
-config.cache_interval=Cache 周期
-config.cache_conn=Cache 连接字符串
+config.cache.adapter=Adapter
+config.cache.interval=GC interval
+config.cache.host=Host
 
-config.session_config=Session 配置
-config.session_provider=Session 提供者
-config.provider_config=提供者配置
-config.cookie_name=Cookie 名称
-config.enable_set_cookie=启用设置 Cookie
-config.gc_interval_time=GC 周期
-config.session_life_time=Session 生命周期
-config.https_only=仅限 HTTPS
-config.cookie_life_time=Cookie 生命周期
+config.http_config=HTTP 配置
+config.http.access_control_allow_origin=Access control allow origin
+
+config.attachment_config=Attachment configuration
+config.attachment.enabled=Enabled
+config.attachment.path=Path
+config.attachment.allowed_types=Allowed types
+config.attachment.max_size=Size limit
+config.attachment.max_files=Files limit
+
+config.release_config=Release configuration
+config.release.attachment.enabled=Attachment enabled
+config.release.attachment.allowed_types=Attachment allowed types
+config.release.attachment.max_size=Attachment size limit
+config.release.attachment.max_files=Attachment files limit
 
 config.picture_config=图片配置
-config.picture_service=图片服务
-config.disable_gravatar=禁用 Gravatar 头像
-config.enable_federated_avatar=启用 Federated Avatars
+config.picture.avatar_upload_path=User avatar upload path
+config.picture.repo_avatar_upload_path=Repository avatar upload path
+config.picture.gravatar_source=Gravatar source
+config.picture.disable_gravatar=Disable Gravatar
+config.picture.enable_federated_avatar=Enable federated avatars
+
+config.mirror_config=Mirror configuration
+config.mirror.default_interval=Default interval
+
+config.webhook_config=Web 钩子配置
+config.webhook.types=Types
+config.webhook.deliver_timeout=Deliver timeout
+config.webhook.skip_tls_verify=Skip TLS verify
 
 config.git_config=Git 配置
-config.git_disable_diff_highlight=禁用差异对比语法高亮
-config.git_max_diff_lines=差异对比显示的最大行数(单个文件)
-config.git_max_diff_line_characters=差异对比显示的最大字符数(单行)
-config.git_max_diff_files=差异对比显示的最大文件数
-config.git_gc_args=GC 参数
-config.git_migrate_timeout=迁移操作超时
-config.git_mirror_timeout=镜像更新操作超时
-config.git_clone_timeout=克隆操作超时
-config.git_pull_timeout=拉取操作超时
-config.git_gc_timeout=GC 操作超时
+config.git.disable_diff_highlight=Disable diff syntax highlight
+config.git.max_diff_lines=Diff lines limit (for a single file)
+config.git.max_diff_line_characters=Diff characters limit (for a single line)
+config.git.max_diff_files=Diff files limit (for a single diff)
+config.git.gc_args=GC arguments
+config.git.migrate_timeout=Migration timeout
+config.git.mirror_timeout=Mirror fetch timeout
+config.git.clone_timeout=Clone timeout
+config.git.pull_timeout=Pull timeout
+config.git.gc_timeout=GC timeout
 
 config.log_config=日志配置
+config.log_file_root_path=日志文件根目录
 config.log_mode=模式
 config.log_options=选项
 
@@ -1338,6 +1397,7 @@ months=%d 月%s
 years=%d 年%s
 raw_seconds=秒
 raw_minutes=分钟
+raw_hours=hours
 
 [dropzone]
 default_message=拖曳文件到此处或单击上传

+ 159 - 99
conf/locale/locale_zh-HK.ini

@@ -9,7 +9,6 @@ sign_out=登出
 sign_up=註冊
 register=註冊
 website=網站
-version=版本
 page=頁面
 template=樣板
 language=語言
@@ -122,6 +121,7 @@ run_user_not_match=執行系統用戶非當前用戶:%s -> %s
 smtp_host_missing_port=SMTP Host port missing from address.
 invalid_smtp_from=SMTP From field is invalid: %v
 save_config_failed=應用配置保存失敗:%v
+init_failed=Failed to initialize application: %v
 invalid_admin_setting=管理員帳戶設置不正確:%v
 install_success=您好!我們很高興您選擇使用 Gogs,祝您使用愉快,代碼從此無 BUG!
 invalid_log_root_path=日誌根目錄無效: %v
@@ -1001,6 +1001,12 @@ first_page=首頁
 last_page=末頁
 total=總計:%d
 
+dashboard.build_info=Build Information
+dashboard.app_ver=Application version
+dashboard.git_version=Git version
+dashboard.go_version=Go version
+dashboard.build_time=Build time
+dashboard.build_commit=Build commit
 dashboard.statistic=應用統計數據
 dashboard.operations=管理員操作
 dashboard.system_status=系統監視狀態
@@ -1156,117 +1162,170 @@ auths.github_api_endpoint=API Endpoint
 
 config.not_set=(not set)
 config.server_config=服務器配置
-config.app_name=應用名稱
-config.app_ver=應用版本
-config.app_url=應用 URL
-config.domain=應用域名
-config.offline_mode=離線模式
-config.disable_router_log=關閉路由日志
+config.brand_name=Brand name
 config.run_user=執行用戶
 config.run_mode=執行模式
-config.git_version=Git Version
-config.static_file_root_path=靜態文件根目錄
-config.log_file_root_path=日志文件根目錄
-config.reverse_auth_user=反向代理認證
+config.server.external_url=External URL
+config.server.domain=Domain
+config.server.protocol=Protocol
+config.server.http_addr=HTTP address
+config.server.http_port=HTTP port
+config.server.cert_file=Certificate file
+config.server.key_file=Key file
+config.server.tls_min_version=Minimum TLS version
+config.server.unix_socket_permission=Unix socket permission
+config.server.local_root_url=Local root URL
+config.server.offline_mode=Offline mode
+config.server.disable_router_log=Disable router log
+config.server.enable_gzip=Enable Gzip
+config.server.app_data_path=Application data path
+config.server.load_assets_from_disk=Load assets from disk
+config.server.landing_url=Landing URL
 
 config.ssh_config=SSH 配置
-config.ssh_enabled=已啟用
-config.ssh_start_builtin_server=啟動內建伺服器
-config.ssh_domain=Domain
-config.ssh_port=埠
-config.ssh_listen_port=監聽埠
-config.ssh_root_path=根路徑
-config.ssh_rewrite_authorized_keys_at_start=Rewrite authorized_keys At Start
-config.ssh_key_test_path=金鑰測試路徑
-config.ssh_keygen_path=金鑰產生 (' ssh-keygen ') 路徑
-config.ssh_minimum_key_size_check=金鑰最小大小檢查
-config.ssh_minimum_key_sizes=金鑰最小大小
-
-config.repo_config=Repository Configuration
-config.repo_root_path=倉庫根目錄
-config.script_type=腳本類型
-config.repo_force_private=Force Private
-config.max_creation_limit=Max Creation Limit
-config.preferred_licenses=Preferred Licenses
-config.disable_http_git=Disable HTTP Git
-config.enable_local_path_migration=Enable Local Path Migration
-config.commits_fetch_concurrency=Commits Fetch Concurrency
-
-config.http_config=HTTP Configuration
-config.http_access_control_allow_origin=Access Control Allow Origin
+config.ssh.enabled=Enabled
+config.ssh.domain=Exposed domain
+config.ssh.port=Exposed port
+config.ssh.root_path=Root path
+config.ssh.keygen_path=Keygen path
+config.ssh.key_test_path=Key test path
+config.ssh.minimum_key_size_check=Minimum key size check
+config.ssh.minimum_key_sizes=Minimum key sizes
+config.ssh.rewrite_authorized_keys_at_start=Rewrite "authorized_keys" at start
+config.ssh.start_builtin_server=Start builtin server
+config.ssh.listen_host=Listen host
+config.ssh.listen_port=Listen port
+config.ssh.server_ciphers=Server ciphers
+
+config.repo_config=Repository configuration
+config.repo.root_path=Root path
+config.repo.script_type=Script type
+config.repo.ansi_chatset=ANSI charset
+config.repo.force_private=Force private
+config.repo.max_creation_limit=Max creation limit
+config.repo.preferred_licenses=Preferred licenses
+config.repo.disable_http_git=Disable HTTP Git
+config.repo.enable_local_path_migration=Enable local path migration
+config.repo.enable_raw_file_render_mode=Enable raw file render mode
+config.repo.commits_fetch_concurrency=Commits fetch concurrency
+config.repo.editor.line_wrap_extensions=Editor line wrap extensions
+config.repo.editor.previewable_file_modes=Editor previewable file modes
+config.repo.upload.enabled=Upload enabled
+config.repo.upload.temp_path=Upload temporary path
+config.repo.upload.allowed_types=Upload allowed types
+config.repo.upload.file_max_size=Upload file size limit
+config.repo.upload.max_files=Upload files limit
 
 config.db_config=數據庫配置
-config.db_type=數據庫類型
-config.db_host=主機地址
-config.db_name=數據庫名稱
-config.db_user=數據庫用戶
-config.db_ssl_mode=SSL 模式
-config.db_ssl_mode_helper=(僅限 "postgres" 使用)
-config.db_path=數據庫路徑
-config.db_path_helper=(用於 "sqlite3" 和 "tidb")
-
-config.service_config=服務配置
-config.register_email_confirm=註冊電子郵件確認
-config.disable_register=關閉註冊功能
-config.show_registration_button=顯示註冊按鈕
-config.require_sign_in_view=強制登錄瀏覽
-config.mail_notify=郵件通知提醒
-config.disable_key_size_check=禁用密鑰最小長度檢查
-config.enable_captcha=啟用驗證碼服務
-config.active_code_lives=激活用戶連結有效期
-config.reset_password_code_lives=重置密碼連結有效期
+config.db.type=Type
+config.db.host=Host
+config.db.name=Name
+config.db.user=User
+config.db.ssl_mode=SSL mode
+config.db.ssl_mode_helper=(for "postgres" only)
+config.db.path=Path
+config.db.path_helper=(for "sqlite3"only)
+
+config.security_config=Security configuration
+config.security.login_remember_days=Login remember days
+config.security.cookie_remember_name=Remember cookie
+config.security.cookie_username=Username cookie
+config.security.cookie_secure=Enable secure cookie
+config.security.reverse_proxy_auth_user=Reverse proxy authentication header
+config.security.enable_login_status_cookie=Enable login status cookie
+config.security.login_status_cookie_name=Login status cookie
+
+config.email_config=Email configuration
+config.email.enabled=Enabled
+config.email.subject_prefix=Subject prefix
+config.email.host=Host
+config.email.from=From
+config.email.user=User
+config.email.disable_helo=Disable HELO
+config.email.helo_hostname=HELO hostname
+config.email.skip_verify=Skip certificate verify
+config.email.use_certificate=Use custom certificate
+config.email.cert_file=Certificate file
+config.email.key_file=Key file
+config.email.use_plain_text=Use plain text
+config.email.add_plain_text_alt=Add plain text alternative
+config.email.send_test_mail=Send test email
+config.email.test_mail_failed=Failed to send test email to '%s': %v
+config.email.test_mail_sent=Test email has been sent to '%s'.
+
+config.auth_config=Authentication configuration
+config.auth.activate_code_lives=Activate code lives
+config.auth.reset_password_code_lives=Reset password code lives
+config.auth.require_email_confirm=Require email confirmation
+config.auth.require_sign_in_view=Require sign in view
+config.auth.disable_registration=Disable registration
+config.auth.enable_registration_captcha=Enable registration captcha
+config.auth.enable_reverse_proxy_authentication=Enable reverse proxy authentication
+config.auth.enable_reverse_proxy_auto_registration=Enable reverse proxy auto registration
+config.auth.reverse_proxy_authentication_header=Reverse proxy authentication header
+
+config.user_config=User configuration
+config.user.enable_email_notify=Enable email notification
 
-config.webhook_config=Web 鉤子配置
-config.queue_length=隊列長度
-config.deliver_timeout=推送超時
-config.skip_tls_verify=忽略 TLS 驗證
-
-config.mailer_config=郵件配置
-config.mailer_enabled=啟用服務
-config.mailer_disable_helo=禁用 HELO 操作
-config.mailer_subject_prefix=Subject Prefix
-config.mailer_host=郵件主機地址
-config.mailer_user=發送者帳號
-config.send_test_mail=發送測試郵件
-config.test_mail_failed=無法向 '%s' 發送測試郵件: %v
-config.test_mail_sent=測試電子郵件已發送到 '%s'。
-
-config.oauth_config=社交帳號配置
-config.oauth_enabled=啟用服務
+config.session_config=Session 配置
+config.session.provider=Provider
+config.session.provider_config=Provider config
+config.session.cookie_name=Cookie
+config.session.https_only=HTTPS only
+config.session.gc_interval=GC interval
+config.session.max_life_time=Max life time
+config.session.csrf_cookie_name=CSRF cookie
 
 config.cache_config=Cache 配置
-config.cache_adapter=Cache 適配器
-config.cache_interval=Cache 周期
-config.cache_conn=Cache 連接字符串
-
-config.session_config=Session 配置
-config.session_provider=Session 提供者
-config.provider_config=提供者配置
-config.cookie_name=Cookie 名稱
-config.enable_set_cookie=啟用設置 Cookie
-config.gc_interval_time=垃圾收集周期
-config.session_life_time=Session 生命周期
-config.https_only=僅限 HTTPS
-config.cookie_life_time=Cookie 生命周期
+config.cache.adapter=Adapter
+config.cache.interval=GC interval
+config.cache.host=Host
+
+config.http_config=HTTP configuration
+config.http.access_control_allow_origin=Access control allow origin
+
+config.attachment_config=Attachment configuration
+config.attachment.enabled=Enabled
+config.attachment.path=Path
+config.attachment.allowed_types=Allowed types
+config.attachment.max_size=Size limit
+config.attachment.max_files=Files limit
+
+config.release_config=Release configuration
+config.release.attachment.enabled=Attachment enabled
+config.release.attachment.allowed_types=Attachment allowed types
+config.release.attachment.max_size=Attachment size limit
+config.release.attachment.max_files=Attachment files limit
 
 config.picture_config=圖片配置
-config.picture_service=圖片服務
-config.disable_gravatar=禁用 Gravatar 頭像
-config.enable_federated_avatar=Enable Federated Avatars
-
-config.git_config=Git Configuration
-config.git_disable_diff_highlight=Disable Diff Syntax Highlight
-config.git_max_diff_lines=Max Diff Lines (for a single file)
-config.git_max_diff_line_characters=Max Diff Characters (for a single line)
-config.git_max_diff_files=Max Diff Files (to be shown)
-config.git_gc_args=GC Arguments
-config.git_migrate_timeout=Migration Timeout
-config.git_mirror_timeout=Mirror Update Timeout
-config.git_clone_timeout=Clone Operation Timeout
-config.git_pull_timeout=Pull Operation Timeout
-config.git_gc_timeout=GC Operation Timeout
+config.picture.avatar_upload_path=User avatar upload path
+config.picture.repo_avatar_upload_path=Repository avatar upload path
+config.picture.gravatar_source=Gravatar source
+config.picture.disable_gravatar=Disable Gravatar
+config.picture.enable_federated_avatar=Enable federated avatars
+
+config.mirror_config=Mirror configuration
+config.mirror.default_interval=Default interval
+
+config.webhook_config=Web 鉤子配置
+config.webhook.types=Types
+config.webhook.deliver_timeout=Deliver timeout
+config.webhook.skip_tls_verify=Skip TLS verify
+
+config.git_config=Git configuration
+config.git.disable_diff_highlight=Disable diff syntax highlight
+config.git.max_diff_lines=Diff lines limit (for a single file)
+config.git.max_diff_line_characters=Diff characters limit (for a single line)
+config.git.max_diff_files=Diff files limit (for a single diff)
+config.git.gc_args=GC arguments
+config.git.migrate_timeout=Migration timeout
+config.git.mirror_timeout=Mirror fetch timeout
+config.git.clone_timeout=Clone timeout
+config.git.pull_timeout=Pull timeout
+config.git.gc_timeout=GC timeout
 
 config.log_config=日誌配置
+config.log_file_root_path=日志文件根目錄
 config.log_mode=Mode
 config.log_options=Options
 
@@ -1338,6 +1397,7 @@ months=%d 月%s
 years=%d 年%s
 raw_seconds=秒
 raw_minutes=分鐘
+raw_hours=hours
 
 [dropzone]
 default_message=拖曳文件到此處或單擊上傳

+ 154 - 94
conf/locale/locale_zh-TW.ini

@@ -9,7 +9,6 @@ sign_out=登出
 sign_up=註冊
 register=註冊
 website=網站
-version=版本
 page=頁面
 template=樣板
 language=語言
@@ -122,6 +121,7 @@ run_user_not_match=執行系統用戶非當前用戶:%s -> %s
 smtp_host_missing_port=SMTP 主機缺少位址中的埠。
 invalid_smtp_from=SMTP 寄件者欄位無效﹔%v
 save_config_failed=設定儲存失敗:%v
+init_failed=Failed to initialize application: %v
 invalid_admin_setting=管理員帳戶設置不正確:%v
 install_success=您好!我們很高興您選擇使用 GIN,祝您使用愉快,代碼從此無 BUG!
 invalid_log_root_path=日誌根目錄無效: %v
@@ -1001,6 +1001,12 @@ first_page=首頁
 last_page=末頁
 total=總計:%d
 
+dashboard.build_info=Build Information
+dashboard.app_ver=Application version
+dashboard.git_version=Git version
+dashboard.go_version=Go version
+dashboard.build_time=Build time
+dashboard.build_commit=Build commit
 dashboard.statistic=應用統計數據
 dashboard.operations=管理員操作
 dashboard.system_status=系統監視狀態
@@ -1156,117 +1162,170 @@ auths.github_api_endpoint=API 端點
 
 config.not_set=(未設定)
 config.server_config=服務器配置
-config.app_name=應用名稱
-config.app_ver=應用版本
-config.app_url=應用 URL
-config.domain=應用域名
-config.offline_mode=離線模式
-config.disable_router_log=關閉路由日志
+config.brand_name=Brand name
 config.run_user=執行用戶
 config.run_mode=執行模式
-config.git_version=Git 版本
-config.static_file_root_path=靜態文件根目錄
-config.log_file_root_path=日志文件根目錄
-config.reverse_auth_user=反向代理認證
+config.server.external_url=External URL
+config.server.domain=Domain
+config.server.protocol=Protocol
+config.server.http_addr=HTTP address
+config.server.http_port=HTTP port
+config.server.cert_file=Certificate file
+config.server.key_file=Key file
+config.server.tls_min_version=Minimum TLS version
+config.server.unix_socket_permission=Unix socket permission
+config.server.local_root_url=Local root URL
+config.server.offline_mode=Offline mode
+config.server.disable_router_log=Disable router log
+config.server.enable_gzip=Enable Gzip
+config.server.app_data_path=Application data path
+config.server.load_assets_from_disk=Load assets from disk
+config.server.landing_url=Landing URL
 
 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_rewrite_authorized_keys_at_start=在啟動時重寫 authorized_keys 檔案
-config.ssh_key_test_path=金鑰測試路徑
-config.ssh_keygen_path=金鑰產生 (' ssh-keygen ') 路徑
-config.ssh_minimum_key_size_check=金鑰最小大小檢查
-config.ssh_minimum_key_sizes=金鑰最小大小
+config.ssh.enabled=Enabled
+config.ssh.domain=Exposed domain
+config.ssh.port=Exposed port
+config.ssh.root_path=Root path
+config.ssh.keygen_path=Keygen path
+config.ssh.key_test_path=Key test path
+config.ssh.minimum_key_size_check=Minimum key size check
+config.ssh.minimum_key_sizes=Minimum key sizes
+config.ssh.rewrite_authorized_keys_at_start=Rewrite "authorized_keys" at start
+config.ssh.start_builtin_server=Start builtin server
+config.ssh.listen_host=Listen host
+config.ssh.listen_port=Listen port
+config.ssh.server_ciphers=Server ciphers
 
 config.repo_config=Repository 設定
-config.repo_root_path=倉庫根目錄
-config.script_type=腳本類型
-config.repo_force_private=強制設為私有
-config.max_creation_limit=最大建立限制
-config.preferred_licenses=推薦授權
-config.disable_http_git=停用 HTTP Git
-config.enable_local_path_migration=啟用本地路徑遷移
-config.commits_fetch_concurrency=同時Fetch Commit數量
-
-config.http_config=HTTP設定
-config.http_access_control_allow_origin=Access Control Allow Origin
+config.repo.root_path=Root path
+config.repo.script_type=Script type
+config.repo.ansi_chatset=ANSI charset
+config.repo.force_private=Force private
+config.repo.max_creation_limit=Max creation limit
+config.repo.preferred_licenses=Preferred licenses
+config.repo.disable_http_git=Disable HTTP Git
+config.repo.enable_local_path_migration=Enable local path migration
+config.repo.enable_raw_file_render_mode=Enable raw file render mode
+config.repo.commits_fetch_concurrency=Commits fetch concurrency
+config.repo.editor.line_wrap_extensions=Editor line wrap extensions
+config.repo.editor.previewable_file_modes=Editor previewable file modes
+config.repo.upload.enabled=Upload enabled
+config.repo.upload.temp_path=Upload temporary path
+config.repo.upload.allowed_types=Upload allowed types
+config.repo.upload.file_max_size=Upload file size limit
+config.repo.upload.max_files=Upload files limit
 
 config.db_config=資料庫設定
-config.db_type=數據庫類型
-config.db_host=主機地址
-config.db_name=數據庫名稱
-config.db_user=數據庫用戶
-config.db_ssl_mode=SSL 模式
-config.db_ssl_mode_helper=(僅限 "postgres" 使用)
-config.db_path=數據庫路徑
-config.db_path_helper=(用於 "sqlite3" 和 "tidb")
-
-config.service_config=服務配置
-config.register_email_confirm=註冊電子郵件確認
-config.disable_register=關閉註冊功能
-config.show_registration_button=顯示註冊按鈕
-config.require_sign_in_view=強制登錄瀏覽
-config.mail_notify=郵件通知提醒
-config.disable_key_size_check=禁用密鑰最小長度檢查
-config.enable_captcha=啟用驗證碼服務
-config.active_code_lives=激活用戶連結有效期
-config.reset_password_code_lives=重置密碼連結有效期
+config.db.type=Type
+config.db.host=Host
+config.db.name=Name
+config.db.user=User
+config.db.ssl_mode=SSL mode
+config.db.ssl_mode_helper=(for "postgres" only)
+config.db.path=Path
+config.db.path_helper=(for "sqlite3"only)
+
+config.security_config=Security configuration
+config.security.login_remember_days=Login remember days
+config.security.cookie_remember_name=Remember cookie
+config.security.cookie_username=Username cookie
+config.security.cookie_secure=Enable secure cookie
+config.security.reverse_proxy_auth_user=Reverse proxy authentication header
+config.security.enable_login_status_cookie=Enable login status cookie
+config.security.login_status_cookie_name=Login status cookie
+
+config.email_config=Email configuration
+config.email.enabled=Enabled
+config.email.subject_prefix=Subject prefix
+config.email.host=Host
+config.email.from=From
+config.email.user=User
+config.email.disable_helo=Disable HELO
+config.email.helo_hostname=HELO hostname
+config.email.skip_verify=Skip certificate verify
+config.email.use_certificate=Use custom certificate
+config.email.cert_file=Certificate file
+config.email.key_file=Key file
+config.email.use_plain_text=Use plain text
+config.email.add_plain_text_alt=Add plain text alternative
+config.email.send_test_mail=Send test email
+config.email.test_mail_failed=Failed to send test email to '%s': %v
+config.email.test_mail_sent=Test email has been sent to '%s'.
+
+config.auth_config=Authentication configuration
+config.auth.activate_code_lives=Activate code lives
+config.auth.reset_password_code_lives=Reset password code lives
+config.auth.require_email_confirm=Require email confirmation
+config.auth.require_sign_in_view=Require sign in view
+config.auth.disable_registration=Disable registration
+config.auth.enable_registration_captcha=Enable registration captcha
+config.auth.enable_reverse_proxy_authentication=Enable reverse proxy authentication
+config.auth.enable_reverse_proxy_auto_registration=Enable reverse proxy auto registration
+config.auth.reverse_proxy_authentication_header=Reverse proxy authentication header
+
+config.user_config=User configuration
+config.user.enable_email_notify=Enable email notification
 
-config.webhook_config=Web 鉤子配置
-config.queue_length=隊列長度
-config.deliver_timeout=推送超時
-config.skip_tls_verify=忽略 TLS 驗證
-
-config.mailer_config=郵件配置
-config.mailer_enabled=啟用服務
-config.mailer_disable_helo=禁用 HELO 操作
-config.mailer_subject_prefix=主旨前置詞
-config.mailer_host=郵件主機地址
-config.mailer_user=發送者帳號
-config.send_test_mail=發送測試郵件
-config.test_mail_failed=無法向 '%s' 發送測試郵件: %v
-config.test_mail_sent=測試電子郵件已發送到 '%s'。
-
-config.oauth_config=社交帳號配置
-config.oauth_enabled=啟用服務
+config.session_config=Session 配置
+config.session.provider=Provider
+config.session.provider_config=Provider config
+config.session.cookie_name=Cookie
+config.session.https_only=HTTPS only
+config.session.gc_interval=GC interval
+config.session.max_life_time=Max life time
+config.session.csrf_cookie_name=CSRF cookie
 
 config.cache_config=Cache 配置
-config.cache_adapter=Cache 適配器
-config.cache_interval=Cache 周期
-config.cache_conn=Cache 連接字符串
+config.cache.adapter=Adapter
+config.cache.interval=GC interval
+config.cache.host=Host
 
-config.session_config=Session 配置
-config.session_provider=Session 提供者
-config.provider_config=提供者配置
-config.cookie_name=Cookie 名稱
-config.enable_set_cookie=啟用設置 Cookie
-config.gc_interval_time=垃圾收集周期
-config.session_life_time=Session 生命周期
-config.https_only=僅限 HTTPS
-config.cookie_life_time=Cookie 生命周期
+config.http_config=HTTP設定
+config.http.access_control_allow_origin=Access control allow origin
+
+config.attachment_config=Attachment configuration
+config.attachment.enabled=Enabled
+config.attachment.path=Path
+config.attachment.allowed_types=Allowed types
+config.attachment.max_size=Size limit
+config.attachment.max_files=Files limit
+
+config.release_config=Release configuration
+config.release.attachment.enabled=Attachment enabled
+config.release.attachment.allowed_types=Attachment allowed types
+config.release.attachment.max_size=Attachment size limit
+config.release.attachment.max_files=Attachment files limit
 
 config.picture_config=圖片配置
-config.picture_service=圖片服務
-config.disable_gravatar=禁用 Gravatar 頭像
-config.enable_federated_avatar=開啟聯合頭像
+config.picture.avatar_upload_path=User avatar upload path
+config.picture.repo_avatar_upload_path=Repository avatar upload path
+config.picture.gravatar_source=Gravatar source
+config.picture.disable_gravatar=Disable Gravatar
+config.picture.enable_federated_avatar=Enable federated avatars
+
+config.mirror_config=Mirror configuration
+config.mirror.default_interval=Default interval
+
+config.webhook_config=Web 鉤子配置
+config.webhook.types=Types
+config.webhook.deliver_timeout=Deliver timeout
+config.webhook.skip_tls_verify=Skip TLS verify
 
 config.git_config=Git 配置
-config.git_disable_diff_highlight=禁用比較語法高亮
-config.git_max_diff_lines=Max Diff 線 (對於單個檔)
-config.git_max_diff_line_characters=最大比較的字元 (單行)
-config.git_max_diff_files=Max Diff 檔 (顯示)
-config.git_gc_args=GC 參數
-config.git_migrate_timeout=移動超時
-config.git_mirror_timeout=鏡像更新超時
-config.git_clone_timeout=複製操作超時
-config.git_pull_timeout=操作超時
-config.git_gc_timeout=GC 操作超時
+config.git.disable_diff_highlight=Disable diff syntax highlight
+config.git.max_diff_lines=Diff lines limit (for a single file)
+config.git.max_diff_line_characters=Diff characters limit (for a single line)
+config.git.max_diff_files=Diff files limit (for a single diff)
+config.git.gc_args=GC arguments
+config.git.migrate_timeout=Migration timeout
+config.git.mirror_timeout=Mirror fetch timeout
+config.git.clone_timeout=Clone timeout
+config.git.pull_timeout=Pull timeout
+config.git.gc_timeout=GC timeout
 
 config.log_config=日誌配置
+config.log_file_root_path=日志文件根目錄
 config.log_mode=模式
 config.log_options=選項
 
@@ -1338,6 +1397,7 @@ months=%d 月%s
 years=%d 年%s
 raw_seconds=秒
 raw_minutes=分鐘
+raw_hours=hours
 
 [dropzone]
 default_message=拖曳文件到此處或單擊上傳

+ 27 - 21
go.mod

@@ -6,70 +6,76 @@ require (
 	github.com/G-Node/git-module v0.8.4-gnode
 	github.com/G-Node/libgin v0.3.2
 	github.com/bgentry/speakeasy v0.1.0 // indirect
-	github.com/denisenkom/go-mssqldb v0.0.0-20191001013358-cfbb681360f0
+	github.com/blang/semver v3.5.1+incompatible // indirect
+	github.com/denisenkom/go-mssqldb v0.0.0-20200206145737-bbfc9a55622e
 	github.com/dustinkirkland/golang-petname v0.0.0-20191129215211-8e5a1ed0cff0
-	github.com/editorconfig/editorconfig-core-go/v2 v2.2.1
+	github.com/editorconfig/editorconfig-core-go/v2 v2.3.2
 	github.com/fatih/color v1.9.0 // indirect
-	github.com/go-macaron/binding v1.0.1
+	github.com/go-macaron/binding v1.1.0
 	github.com/go-macaron/cache v0.0.0-20190810181446-10f7c57e2196
-	github.com/go-macaron/captcha v0.0.0-20190813234938-24f40749f36d
+	github.com/go-macaron/captcha v0.2.0
 	github.com/go-macaron/csrf v0.0.0-20190812063352-946f6d303a4c
 	github.com/go-macaron/gzip v0.0.0-20160222043647-cad1c6580a07
 	github.com/go-macaron/i18n v0.5.0
 	github.com/go-macaron/session v0.0.0-20190805070824-1a3cdc6f5659
 	github.com/go-macaron/toolbox v0.0.0-20190813233741-94defb8383c6
-	github.com/go-sql-driver/mysql v1.4.1
+	github.com/go-sql-driver/mysql v1.5.0
 	github.com/gogs/chardet v0.0.0-20150115103509-2404f7772561
 	github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14
+	github.com/gogs/git-module v1.1.2
 	github.com/gogs/go-gogs-client v0.0.0-20200128182646-c69cb7680fd4
 	github.com/gogs/go-libravatar v0.0.0-20191106065024-33a75213d0a0
 	github.com/gogs/minwinsvc v0.0.0-20170301035411-95be6356811a
+	github.com/google/go-cmp v0.4.0
 	github.com/google/go-github v17.0.0+incompatible
 	github.com/google/go-querystring v1.0.0 // indirect
 	github.com/issue9/identicon v1.0.1
 	github.com/jaytaylor/html2text v0.0.0-20190408195923-01ec452cbe43
-	github.com/json-iterator/go v1.1.7
+	github.com/json-iterator/go v1.1.10
 	github.com/klauspost/compress v1.8.6 // indirect
 	github.com/klauspost/cpuid v1.2.1 // indirect
-	github.com/lib/pq v1.2.0
+	github.com/lib/pq v1.3.0
 	github.com/mattn/go-isatty v0.0.12 // indirect
 	github.com/mattn/go-runewidth v0.0.4 // indirect
-	github.com/mattn/go-sqlite3 v1.11.0
+	github.com/mattn/go-sqlite3 v2.0.3+incompatible
 	github.com/mcuadros/go-version v0.0.0-20190830083331-035f6764e8d2
-	github.com/microcosm-cc/bluemonday v1.0.2
+	github.com/microcosm-cc/bluemonday v1.0.4
 	github.com/msteinert/pam v0.0.0-20190215180659-f29b9f28d6f9
 	github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
-	github.com/niklasfasching/go-org v0.1.6
+	github.com/niklasfasching/go-org v0.1.9
 	github.com/olekukonko/tablewriter v0.0.1 // indirect
-	github.com/pkg/errors v0.8.1
+	github.com/pkg/errors v0.9.1
 	github.com/pquerna/otp v1.2.0
-	github.com/prometheus/client_golang v1.2.1
+	github.com/prometheus/client_golang v1.6.0
 	github.com/russross/blackfriday v1.5.2
 	github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca // indirect
 	github.com/satori/go.uuid v1.2.0
-	github.com/sergi/go-diff v1.0.0
+	github.com/sergi/go-diff v1.1.0
 	github.com/smartystreets/goconvey v1.6.4
 	github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect
-	github.com/stretchr/testify v1.4.0
+	github.com/stretchr/testify v1.6.1
 	github.com/unknwon/cae v1.0.0
 	github.com/unknwon/com v1.0.1
 	github.com/unknwon/i18n v0.0.0-20190805065654-5c6446a380b6
 	github.com/unknwon/paginater v0.0.0-20170405233947-45e5d631308e
-	github.com/urfave/cli v1.22.1
+	github.com/urfave/cli v1.22.4
+	gogs.io/gogs v0.12.1
 	golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975
 	golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582
-	golang.org/x/sys v0.0.0-20200219091948-cb0a6d8edb6c // indirect
-	golang.org/x/text v0.3.2
+	golang.org/x/text v0.3.3
 	gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
 	gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d // indirect
 	gopkg.in/clog.v1 v1.2.0
 	gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
-	gopkg.in/ini.v1 v1.52.0
+	gopkg.in/ini.v1 v1.56.0
 	gopkg.in/ldap.v2 v2.5.1
-	gopkg.in/macaron.v1 v1.3.4
-	gopkg.in/yaml.v2 v2.2.2
-	unknwon.dev/clog/v2 v2.1.1
+	gopkg.in/macaron.v1 v1.3.9
+	gopkg.in/yaml.v2 v2.2.7
+	unknwon.dev/clog/v2 v2.1.2
 	xorm.io/builder v0.3.6
 	xorm.io/core v0.7.2
 	xorm.io/xorm v0.8.0
 )
+
+// +heroku goVersion go1.13
+// +heroku install ./

+ 113 - 2
go.sum

@@ -10,6 +10,8 @@ github.com/G-Node/libgin v0.0.0-20191216094436-47f8aadc0067/go.mod h1:2yLXQnNbwj
 github.com/G-Node/libgin v0.3.0/go.mod h1:VjulCBq7k/kgf4Eabk2f4w9SDNowWhLnK+yZvy5Nppk=
 github.com/G-Node/libgin v0.3.2 h1:pbOIm+paF4VqfrTvSu4sPXmo2j5XSOnfxf137uzAHIs=
 github.com/G-Node/libgin v0.3.2/go.mod h1:/2l42QsLZTneVp2LjPoPOWhVjvfbO26atvcbvWA+axI=
+github.com/Masterminds/semver/v3 v3.1.0 h1:Y2lUDsFKVRSYGojLJ1yLxSXdMmMYTYls0rCvoqmMUQk=
+github.com/Masterminds/semver/v3 v3.1.0/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
 github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
 github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
 github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
@@ -17,6 +19,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
 github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
 github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
 github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
+github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
+github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
 github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
 github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
@@ -31,6 +35,10 @@ github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668 h1:U/lr3Dgy4WK
 github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
 github.com/cespare/xxhash/v2 v2.1.0 h1:yTUvW7Vhb89inJ+8irsUqiWjh8iT6sQPZiQzI6ReGkA=
 github.com/cespare/xxhash/v2 v2.1.0/go.mod h1:dgIUBU3pDso/gPgZ1osOZ0iQf77oPR28Tjxl5dIMyVM=
+github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
+github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/chris-ramon/douceur v0.2.0 h1:IDMEdxlEUUBYBKE4z/mJnFyVXox+MjuEVDJNN27glkU=
+github.com/chris-ramon/douceur v0.2.0/go.mod h1:wDW5xjJdeoMm1mRt4sD4c/LbF/mWdEpRXQKjTR8nIBE=
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
 github.com/couchbase/gomemcached v0.0.0-20190515232915-c4b4ca0eb21d/go.mod h1:srVSlQLB8iXBVXHgnqemxUXqN6FCvClgCMPCsjBDR7c=
 github.com/couchbase/goutils v0.0.0-20190315194238-f9d42b11473b/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs=
@@ -41,9 +49,13 @@ github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGii
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM=
 github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM=
 github.com/denisenkom/go-mssqldb v0.0.0-20191001013358-cfbb681360f0 h1:epsH3lb7KVbXHYk7LYGN5EiE0MxcevHU85CKITJ0wUY=
 github.com/denisenkom/go-mssqldb v0.0.0-20191001013358-cfbb681360f0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
+github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
+github.com/denisenkom/go-mssqldb v0.0.0-20200206145737-bbfc9a55622e h1:LzwWXEScfcTu7vUZNlDDWDARoSGEtvlDKK2BYHowNeE=
+github.com/denisenkom/go-mssqldb v0.0.0-20200206145737-bbfc9a55622e/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
 github.com/docker/docker v1.13.1/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
 github.com/dustinkirkland/golang-petname v0.0.0-20191129215211-8e5a1ed0cff0 h1:90Ly+6UfUypEF6vvvW5rQIv9opIL8CbmW9FT20LDQoY=
 github.com/dustinkirkland/golang-petname v0.0.0-20191129215211-8e5a1ed0cff0/go.mod h1:V+Qd57rJe8gd4eiGzZyg4h54VLHmYVVw54iMnlAMrF8=
@@ -52,7 +64,12 @@ github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1
 github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
 github.com/editorconfig/editorconfig-core-go/v2 v2.2.1 h1:jY5PCRQf4V0oqpim/Ympl6MwHcb9+nBHEnHOPXqNZ/A=
 github.com/editorconfig/editorconfig-core-go/v2 v2.2.1/go.mod h1:6XDmqAZsQu8ikS+onLRJfLZvTP3RWTVT8ROX6qcdkio=
+github.com/editorconfig/editorconfig-core-go/v2 v2.3.0 h1:QD1YB/rbntMEQIKM42kQOaqGdS13UvGsl9c8m/nFNWY=
+github.com/editorconfig/editorconfig-core-go/v2 v2.3.0/go.mod h1:RNdPfKd9PliYEUZ3r+GxbDsSHNnEluC1wdkQJc3jD4k=
+github.com/editorconfig/editorconfig-core-go/v2 v2.3.2 h1:j9GLz0kWF9+1T3IX0MOhhvzLtqhFOvIKLhZFxtY95Qc=
+github.com/editorconfig/editorconfig-core-go/v2 v2.3.2/go.mod h1:+u4rFiKVvlbukHyJM76GYXqQcnHScxvQCuKpMLRtJVw=
 github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
+github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
 github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
 github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
@@ -64,10 +81,14 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9
 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
 github.com/go-macaron/binding v1.0.1 h1:4LASxd4EKsESZ6ZMyzNVX+TM4Yuex4bTHYyz/PQjsRA=
 github.com/go-macaron/binding v1.0.1/go.mod h1:AG8Z6qkQM8s47aUDJOco/SNwJ8Czif2hMm7rc0abDog=
+github.com/go-macaron/binding v1.1.0 h1:A5jpr5UdHr81Hfmb6QUAMTHyvniudOMcgtEg13TJ1ig=
+github.com/go-macaron/binding v1.1.0/go.mod h1:dJU/AtPKG0gUiFra1K5TTGduFGMNxMvfJzV/zmXwyGM=
 github.com/go-macaron/cache v0.0.0-20190810181446-10f7c57e2196 h1:fqWZxyMLF6RVGmjvsZ9FijiU9UlAjuE6nu9RfNBZ+iE=
 github.com/go-macaron/cache v0.0.0-20190810181446-10f7c57e2196/go.mod h1:O6fSdaYZbGh4clVMGMGO5k2KbMO0Cz8YdBnPrD0I8dM=
 github.com/go-macaron/captcha v0.0.0-20190813234938-24f40749f36d h1:aSJXLVjEjbLeHo8aCTDcD3/gMWizaRjMBb3VCsEWEHs=
 github.com/go-macaron/captcha v0.0.0-20190813234938-24f40749f36d/go.mod h1:lmhlZnu9cTRGNQEkSh1qZi2IK3HJH4Z1MXkg6ARQKZA=
+github.com/go-macaron/captcha v0.2.0 h1:d38eYDDF8tdqoM0hJbk+Jb7WQGWlwYNnQwRqLRmSk1Y=
+github.com/go-macaron/captcha v0.2.0/go.mod h1:lmhlZnu9cTRGNQEkSh1qZi2IK3HJH4Z1MXkg6ARQKZA=
 github.com/go-macaron/csrf v0.0.0-20190812063352-946f6d303a4c h1:kFFz1OpaH3+efG7RA33z+D0piwpA/a3x/Zn2d8z9rfw=
 github.com/go-macaron/csrf v0.0.0-20190812063352-946f6d303a4c/go.mod h1:FX53Xq0NNlUj0E5in5J8Dq5nrbdK3ZyDIy6y5VWOiUo=
 github.com/go-macaron/gzip v0.0.0-20160222043647-cad1c6580a07 h1:YSIA98PevNf1NtCa/J6cz7gjzpz99WVAOa9Eg0klKps=
@@ -82,6 +103,8 @@ github.com/go-macaron/toolbox v0.0.0-20190813233741-94defb8383c6 h1:x/v1iUWlqXTK
 github.com/go-macaron/toolbox v0.0.0-20190813233741-94defb8383c6/go.mod h1:YFNJ/JT4yLnpuIXTFef30SZkxGHUczjGZGFaZpPcdn0=
 github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
 github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
+github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
+github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
 github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:9wScpmSP5A3Bk8V3XHWUcJmYTh+ZnlHVyc+A4oZYS3Y=
 github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:56xuuqnHyryaerycW3BfssRdxQstACi0Epw/yC5E2xM=
@@ -91,6 +114,14 @@ github.com/gogs/chardet v0.0.0-20150115103509-2404f7772561 h1:aBzukfDxQlCTVS0NBU
 github.com/gogs/chardet v0.0.0-20150115103509-2404f7772561/go.mod h1:Pcatq5tYkCW2Q6yrR2VRHlbHpZ/R4/7qyL1TCF7vl14=
 github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14 h1:yXtpJr/LV6PFu4nTLgfjQdcMdzjbqqXMEnHfq0Or6p8=
 github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14/go.mod h1:jPoNZLWDAqA5N3G5amEoiNbhVrmM+ZQEcnQvNQ2KaZk=
+github.com/gogs/git-module v0.8.3 h1:9f8oxSs9OACWrGBYMVnnQNzyTcVN+zzcBM7CXnbmezw=
+github.com/gogs/git-module v0.8.3/go.mod h1:aj4tcm7DxaszJWpZLZIRL6gfPXyguAHiE1PDfAAPrCw=
+github.com/gogs/git-module v1.0.0-beta.4 h1:5CyCvTfrb2n5LRpHcNIaFnywHDkM/NxSZVP6t4tpTXI=
+github.com/gogs/git-module v1.0.0-beta.4/go.mod h1:oN37FFStFjdnTJXsSbhIHKJXh2YeDsEcXPATVz/oeuQ=
+github.com/gogs/git-module v1.0.0 h1:iOlCZ5kPc3RjnWRxdziL5hjCaosYyZw/Lf2odzR/kjw=
+github.com/gogs/git-module v1.0.0/go.mod h1:oN37FFStFjdnTJXsSbhIHKJXh2YeDsEcXPATVz/oeuQ=
+github.com/gogs/git-module v1.1.2 h1:30jO+rKEmCDk/O6Mnl7MVrw6rI1qLDByXpkRB+bpYwM=
+github.com/gogs/git-module v1.1.2/go.mod h1:oN37FFStFjdnTJXsSbhIHKJXh2YeDsEcXPATVz/oeuQ=
 github.com/gogs/go-gogs-client v0.0.0-20200128182646-c69cb7680fd4 h1:C7NryI/RQhsIWwC2bHN601P1wJKeuQ6U/UCOYTn3Cic=
 github.com/gogs/go-gogs-client v0.0.0-20200128182646-c69cb7680fd4/go.mod h1:fR6z1Ie6rtF7kl/vBYMfgD5/G5B1blui7z426/sj2DU=
 github.com/gogs/go-libravatar v0.0.0-20191106065024-33a75213d0a0 h1:K02vod+sn3M1OOkdqi2tPxN2+xESK4qyITVQ3JkGEv4=
@@ -106,12 +137,20 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
 github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
 github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
+github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
+github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
+github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
+github.com/golang/protobuf v1.4.0 h1:oOuy+ugB+P/kBdUnG5QaMXSIyJ1q38wWSojYCb3z5VQ=
+github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
 github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
 github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
 github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
 github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
 github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
@@ -125,6 +164,8 @@ github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORR
 github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4=
 github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
 github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
+github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY=
+github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c=
 github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
 github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
@@ -134,9 +175,16 @@ github.com/issue9/identicon v1.0.1 h1:pCDfjMDM6xWK0Chxo8Lif+ST/nOEtmXgMITgV1YA9O
 github.com/issue9/identicon v1.0.1/go.mod h1:UKNVkUFI68RPz/RlLhsAr1aX6bBSaYEWRHVfdjrMUmk=
 github.com/jaytaylor/html2text v0.0.0-20190408195923-01ec452cbe43 h1:jTkyeF7NZ5oIr0ESmcrpiDgAfoidCBF4F5kJhjtaRwE=
 github.com/jaytaylor/html2text v0.0.0-20190408195923-01ec452cbe43/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk=
+github.com/jinzhu/gorm v1.9.11/go.mod h1:bu/pK8szGZ2puuErfU0RwyeNdsf3e6nCX/noXaVxkfw=
+github.com/jinzhu/gorm v1.9.12/go.mod h1:vhTjlKSJUTWNtcbQtrMBFCxy7eXTzeCAzfL5fBZT/Qs=
+github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
+github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
 github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
 github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo=
 github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
+github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
 github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
 github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
@@ -155,8 +203,11 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
 github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
 github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU=
+github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
 github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de/go.mod h1:3q8WtuPQsoRbatJuy3nvq/hRSvuBJrHHr+ybPPiNvHQ=
 github.com/lunny/nodb v0.0.0-20160621015157-fc1ef06ad4af/go.mod h1:Cqz6pqow14VObJ7peltM+2n3PWOz7yTrfUuGbVFkzN0=
 github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
@@ -172,12 +223,17 @@ github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzp
 github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
 github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q=
 github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
+github.com/mattn/go-sqlite3 v2.0.1+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
+github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
 github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
+github.com/mcuadros/go-version v0.0.0-20190308113854-92cdf37c5b75/go.mod h1:76rfSfYPWj01Z85hUf/ituArm797mNKcvINh1OlsZKo=
 github.com/mcuadros/go-version v0.0.0-20190830083331-035f6764e8d2 h1:YocNLcTBdEdvY3iDK6jfWXvEaM5OCKkjxPKoJRdB3Gg=
 github.com/mcuadros/go-version v0.0.0-20190830083331-035f6764e8d2/go.mod h1:76rfSfYPWj01Z85hUf/ituArm797mNKcvINh1OlsZKo=
 github.com/microcosm-cc/bluemonday v1.0.2 h1:5lPfLTTAvAbtS0VqT+94yOtFnGfUWYyx0+iToC3Os3s=
 github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc=
+github.com/microcosm-cc/bluemonday v1.0.4 h1:p0L+CTpo/PLFdkoPcJemLXG+fpMD7pYOoDEq1axMbGg=
+github.com/microcosm-cc/bluemonday v1.0.4/go.mod h1:8iwZnFn2CDDNZ0r6UXhF4xawGvzaqzCRa1n3/lO3W2w=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -191,6 +247,8 @@ github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6
 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
 github.com/niklasfasching/go-org v0.1.6 h1:F521WcqRNl8OJumlgAnekZgERaTA2HpfOYYfVEKOeI8=
 github.com/niklasfasching/go-org v0.1.6/go.mod h1:AsLD6X7djzRIz4/RFZu8vwRL0VGjUvGZCCH1Nz0VdrU=
+github.com/niklasfasching/go-org v0.1.9 h1:Toz8WMIt+qJb52uYEk1YD/muLuOOmRt1CfkV+bKVMkI=
+github.com/niklasfasching/go-org v0.1.9/go.mod h1:AsLD6X7djzRIz4/RFZu8vwRL0VGjUvGZCCH1Nz0VdrU=
 github.com/olekukonko/tablewriter v0.0.1 h1:b3iUnf1v+ppJiOfNX4yxxqfWKMQPZR5yoh8urCTFX88=
 github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
@@ -204,6 +262,8 @@ github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/pquerna/otp v1.2.0 h1:/A3+Jn+cagqayeR3iHs/L62m5ue7710D35zl1zJ1kok=
@@ -213,20 +273,28 @@ github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod
 github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
 github.com/prometheus/client_golang v1.2.1 h1:JnMpQc6ppsNgw9QPAGF6Dod479itz7lvlsMzzNayLOI=
 github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U=
+github.com/prometheus/client_golang v1.6.0 h1:YVPodQOcK15POxhgARIvnDRVpLcuK8mglnMrWfyrw6A=
+github.com/prometheus/client_golang v1.6.0/go.mod h1:ZLOG9ck3JLRdB5MgO8f+lLTe83AXG6ro35rLTxvnIl4=
 github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
 github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
 github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM=
 github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
+github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
 github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
 github.com/prometheus/common v0.7.0 h1:L+1lyG48J1zAQXA3RBX/nG/B3gjlHq0zTt2tlbJLyCY=
 github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
+github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U=
+github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
 github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
 github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
 github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
 github.com/prometheus/procfs v0.0.5 h1:3+auTFlqw+ZaQYJARz6ArODtkaIwtvBTx3N2NehQlL8=
 github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
+github.com/prometheus/procfs v0.0.11 h1:DhHlBtkHWPYi8O2y31JkK0TF+DGM+51OopZjH/Ia5qI=
+github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
 github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
 github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
 github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
@@ -238,6 +306,8 @@ github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
 github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
 github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
 github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
+github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
+github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
 github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
 github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
 github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw=
@@ -264,7 +334,9 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
+github.com/t-tiger/gorm-bulk-insert v1.3.0/go.mod h1:ruDlk8xDl+8sX4bA7PQuYly9YEb3pbp1eP2LCyeRrFY=
 github.com/unknwon/cae v1.0.0 h1:i39lOFaBXZxhGjQOy/RNbi8uzettCs6OQxpR0xXohGU=
 github.com/unknwon/cae v1.0.0/go.mod h1:QaSeRctcea9fK6piJpAMCCPKxzJ01+xFcr2k1m3WRPU=
 github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM=
@@ -276,20 +348,28 @@ github.com/unknwon/paginater v0.0.0-20170405233947-45e5d631308e h1:Qf3QQl/zmEbWD
 github.com/unknwon/paginater v0.0.0-20170405233947-45e5d631308e/go.mod h1:TBwoao3Q4Eb/cp+dHbXDfRTrZSsj/k7kLr2j1oWRWC0=
 github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY=
 github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
+github.com/urfave/cli v1.22.4 h1:u7tSpNPPswAFymm8IehJhy4uJMlUuU/GmqSkvJ1InXA=
+github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
 github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=
 github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
 go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
+gogs.io/gogs v0.12.1 h1:TmCr+FgRjzOvr8s/tX8X9uOTAZ3eNEvfon8F9oN3R/4=
+gogs.io/gogs v0.12.1/go.mod h1:FwcFYxh13Lw+BdOuVs+caeNNnfNFc1amnyLkwIV4kjk=
 golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 h1:/Tl7pH94bvbAAHBdZJT947M/+gp0+CqQXDtMRC0fseo=
 golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
 golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
 golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
+golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -313,6 +393,7 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -328,13 +409,18 @@ golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20191010194322-b09406accb47 h1:/XfQ9z7ib8eEJX2hdgFTZJ/ntt0swNk5oYBziWeTCvY=
 golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200219091948-cb0a6d8edb6c h1:jceGD5YNJGgGMkJz79agzOln1K9TaZUjv5ird16qniQ=
 golang.org/x/sys v0.0.0-20200219091948-cb0a6d8edb6c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f h1:gWF768j/LaZugp8dyS4UwsslYCYz9XgFxvlgsn0n9H8=
+golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -345,6 +431,10 @@ golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3
 golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
 golang.org/x/tools v0.0.0-20190802220118-1d1727260058/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
 golang.org/x/tools v0.0.0-20190805222050-c5a2fd39b72a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
 google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@@ -356,6 +446,12 @@ google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRn
 google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
 google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
+google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
+google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
+google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
+google.golang.org/protobuf v1.21.0 h1:qdOKuR/EIArgaWNjetjgTzgVTAZ+S/WXVrq9HW9zimw=
+google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
 gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
 gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
@@ -366,6 +462,7 @@ gopkg.in/bufio.v1 v1.0.0-20140618132640-567b2bfa514e/go.mod h1:xsQCaysVCudhrYTfz
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/clog.v1 v1.2.0 h1:BHfwHRNQy497iBNsRBassPixSAxRbn2z5KVkdBFbwxc=
 gopkg.in/clog.v1 v1.2.0/go.mod h1:L6fgdpdhFgKX4eGuDvt+N6X2GwZE160NRrIHzvaF8ZM=
 gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
@@ -373,23 +470,37 @@ gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AW
 gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
 gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
 gopkg.in/ini.v1 v1.46.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
 gopkg.in/ini.v1 v1.52.0 h1:j+Lt/M1oPPejkniCg1TkWE2J3Eh1oZTsHSXzMTzUXn4=
 gopkg.in/ini.v1 v1.52.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/ini.v1 v1.53.0 h1:c7ruDvTQi0MUTFuNpDRXLSjs7xT4TerM1icIg4uKWRg=
+gopkg.in/ini.v1 v1.53.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/ini.v1 v1.55.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/ini.v1 v1.56.0 h1:DPMeDvGTM54DXbPkVIZsp19fp/I2K7zwA/itHYHKo8Y=
+gopkg.in/ini.v1 v1.56.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
 gopkg.in/ldap.v2 v2.5.1 h1:wiu0okdNfjlBzg6UWvd1Hn8Y+Ux17/u/4nlk4CQr6tU=
 gopkg.in/ldap.v2 v2.5.1/go.mod h1:oI0cpe/D7HRtBQl8aTg+ZmzFUAvu4lsv3eLXMLGFxWk=
 gopkg.in/macaron.v1 v1.3.4 h1:HvIscOwxhFhx3swWM/979wh2QMYyuXrNmrF9l+j3HZs=
 gopkg.in/macaron.v1 v1.3.4/go.mod h1:/RoHTdC8ALpyJ3+QR36mKjwnT1F1dyYtsGM9Ate6ZFI=
+gopkg.in/macaron.v1 v1.3.5/go.mod h1:uMZCFccv9yr5TipIalVOyAyZQuOH3OkmXvgcWwhJuP4=
+gopkg.in/macaron.v1 v1.3.9 h1:Dw+DDRYdXgQyEsPlfAfKz+UA5qVUrH3KPD7JhmZ9MFc=
+gopkg.in/macaron.v1 v1.3.9/go.mod h1:uMZCFccv9yr5TipIalVOyAyZQuOH3OkmXvgcWwhJuP4=
 gopkg.in/redis.v2 v2.3.2 h1:GPVIIB/JnL1wvfULefy3qXmPu1nfNu2d0yA09FHgwfs=
 gopkg.in/redis.v2 v2.3.2/go.mod h1:4wl9PJ/CqzeHk3LVq1hNLHH8krm3+AXEgut4jVc++LU=
 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
 gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo=
+gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-unknwon.dev/clog/v2 v2.1.1 h1:jBmBoMfsedJ/Sirm4/TdDy00mxh1vlbr9dM+AnYsNik=
-unknwon.dev/clog/v2 v2.1.1/go.mod h1:zvUlyibDHI4mykYdWyWje2G9nF/nBzfDOqRo2my4mWc=
+unknwon.dev/clog/v2 v2.1.2 h1:+jwPPp10UtOPunFtviUmXF01Abf6q7p5GEy4jluLl8o=
+unknwon.dev/clog/v2 v2.1.2/go.mod h1:zvUlyibDHI4mykYdWyWje2G9nF/nBzfDOqRo2my4mWc=
 xorm.io/builder v0.3.6 h1:ha28mQ2M+TFx96Hxo+iq6tQgnkC9IZkM6D8w9sKHHF8=
 xorm.io/builder v0.3.6/go.mod h1:LEFAPISnRzG+zxaxj2vPicRwz67BdhFreKg8yv8/TgU=
 xorm.io/core v0.7.2 h1:mEO22A2Z7a3fPaZMk6gKL/jMD80iiyNwRrX5HOv3XLw=

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 31 - 31
internal/assets/conf/conf_gen.go


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 11 - 11
internal/assets/public/public_gen.go


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 11 - 11
internal/assets/templates/templates_gen.go


+ 2 - 0
internal/cmd/cmd.go

@@ -25,6 +25,7 @@ func boolFlag(name, usage string) cli.BoolFlag {
 	}
 }
 
+//nolint:deadcode
 func intFlag(name string, value int, usage string) cli.IntFlag {
 	return cli.IntFlag{
 		Name:  name,
@@ -33,6 +34,7 @@ func intFlag(name string, value int, usage string) cli.IntFlag {
 	}
 }
 
+//nolint:deadcode
 func durationFlag(name string, value time.Duration, usage string) cli.DurationFlag {
 	return cli.DurationFlag{
 		Name:  name,

+ 12 - 11
internal/cmd/hook.go

@@ -9,6 +9,7 @@ import (
 	"bytes"
 	"crypto/tls"
 	"fmt"
+	"net/url"
 	"os"
 	"os/exec"
 	"path/filepath"
@@ -18,14 +19,13 @@ import (
 	"github.com/urfave/cli"
 	log "unknwon.dev/clog/v2"
 
-	"github.com/G-Node/git-module"
+	"github.com/gogs/git-module"
 
 	"github.com/G-Node/gogs/internal/conf"
 	"github.com/G-Node/gogs/internal/db"
 	"github.com/G-Node/gogs/internal/db/errors"
 	"github.com/G-Node/gogs/internal/email"
 	"github.com/G-Node/gogs/internal/httplib"
-	"github.com/G-Node/gogs/internal/template"
 )
 
 var (
@@ -87,7 +87,7 @@ func runHookPreReceive(c *cli.Context) error {
 		}
 		oldCommitID := string(fields[0])
 		newCommitID := string(fields[1])
-		branchName := strings.TrimPrefix(string(fields[2]), git.BRANCH_PREFIX)
+		branchName := git.RefShortName(string(fields[2]))
 
 		// Branch protection
 		repoID := com.StrTo(os.Getenv(db.ENV_REPO_ID)).MustInt64()
@@ -121,7 +121,7 @@ func runHookPreReceive(c *cli.Context) error {
 		}
 
 		// check and deletion
-		if newCommitID == git.EMPTY_SHA {
+		if newCommitID == git.EmptyID {
 			fail(fmt.Sprintf("Branch '%s' is protected from deletion", branchName), "")
 		}
 
@@ -221,7 +221,7 @@ func runHookPostReceive(c *cli.Context) error {
 		options := db.PushUpdateOptions{
 			OldCommitID:  string(fields[0]),
 			NewCommitID:  string(fields[1]),
-			RefFullName:  string(fields[2]),
+			FullRefspec:  string(fields[2]),
 			PusherID:     com.StrTo(os.Getenv(db.ENV_AUTH_USER_ID)).MustInt64(),
 			PusherName:   os.Getenv(db.ENV_AUTH_USER_NAME),
 			RepoUserName: os.Getenv(db.ENV_REPO_OWNER_NAME),
@@ -232,19 +232,20 @@ func runHookPostReceive(c *cli.Context) error {
 		}
 
 		// Ask for running deliver hook and test pull request tasks
-		reqURL := conf.Server.LocalRootURL + options.RepoUserName + "/" + options.RepoName + "/tasks/trigger?branch=" +
-			template.EscapePound(strings.TrimPrefix(options.RefFullName, git.BRANCH_PREFIX)) +
-			"&secret=" + os.Getenv(db.ENV_REPO_OWNER_SALT_MD5) +
-			"&pusher=" + os.Getenv(db.ENV_AUTH_USER_ID)
+		q := make(url.Values)
+		q.Add("branch", git.RefShortName(options.FullRefspec))
+		q.Add("secret", os.Getenv(db.ENV_REPO_OWNER_SALT_MD5))
+		q.Add("pusher", os.Getenv(db.ENV_AUTH_USER_ID))
+		reqURL := fmt.Sprintf("%s%s/%s/tasks/trigger?%s", conf.Server.LocalRootURL, options.RepoUserName, options.RepoName, q.Encode())
 		log.Trace("Trigger task: %s", reqURL)
 
 		resp, err := httplib.Head(reqURL).SetTLSClientConfig(&tls.Config{
 			InsecureSkipVerify: true,
 		}).Response()
 		if err == nil {
-			resp.Body.Close()
+			_ = resp.Body.Close()
 			if resp.StatusCode/100 != 2 {
-				log.Error("Failed to trigger task: not 2xx response code")
+				log.Error("Failed to trigger task: unsuccessful response code %d", resp.StatusCode)
 			}
 		} else {
 			log.Error("Failed to trigger task: %v", err)

+ 10 - 4
internal/cmd/serv.go

@@ -35,20 +35,25 @@ var Serv = cli.Command{
 	},
 }
 
-func fail(userMessage, logMessage string, args ...interface{}) {
+// fail prints user message to the Git client (i.e. os.Stderr) and
+// logs error message on the server side. When not in "prod" mode,
+// error message is also printed to the client for easier debugging.
+func fail(userMessage, errMessage string, args ...interface{}) {
 	fmt.Fprintln(os.Stderr, "GIN:", userMessage)
 
-	if len(logMessage) > 0 {
+	if len(errMessage) > 0 {
 		if !conf.IsProdMode() {
-			fmt.Fprintf(os.Stderr, logMessage+"\n", args...)
+			fmt.Fprintf(os.Stderr, errMessage+"\n", args...)
 		}
-		log.Fatal(logMessage, args...)
+		log.Error(errMessage, args...)
 	}
 
 	os.Exit(1)
 }
 
 func setup(c *cli.Context, logPath string, connectDB bool) {
+	conf.HookMode = true
+
 	var customConf string
 	if c.IsSet("config") {
 		customConf = c.String("config")
@@ -60,6 +65,7 @@ func setup(c *cli.Context, logPath string, connectDB bool) {
 	if err != nil {
 		fail("Internal error", "Failed to init configuration: %v", err)
 	}
+	conf.InitLogging(true)
 
 	level := log.LevelTrace
 	if conf.IsProdMode() {

+ 25 - 7
internal/conf/log.go

@@ -28,12 +28,19 @@ type logConf struct {
 // Log settings
 var Log *logConf
 
-// initLogConf returns parsed logging configuration from given INI file.
+// initLogConf returns parsed logging configuration from given INI file. When the
+// argument "hookMode" is true, it only initializes the root path for log files.
 // NOTE: Because we always create a console logger as the primary logger at init time,
 // we need to remove it in case the user doesn't configure to use it after the logging
 // service is initalized.
-func initLogConf(cfg *ini.File) (_ *logConf, hasConsole bool, _ error) {
+func initLogConf(cfg *ini.File, hookMode bool) (_ *logConf, hasConsole bool, _ error) {
 	rootPath := cfg.Section("log").Key("ROOT_PATH").MustString(filepath.Join(WorkDir(), "log"))
+	if hookMode {
+		return &logConf{
+			RootPath: ensureAbs(rootPath),
+		}, false, nil
+	}
+
 	modes := strings.Split(cfg.Section("log").Key("MODE").MustString("console"), ",")
 	lc := &logConf{
 		RootPath: ensureAbs(rootPath),
@@ -118,12 +125,22 @@ func initLogConf(cfg *ini.File) (_ *logConf, hasConsole bool, _ error) {
 	return lc, hasConsole, nil
 }
 
-// InitLogging initializes the logging service of the application.
-func InitLogging() {
-	logConf, hasConsole, err := initLogConf(File)
+// InitLogging initializes the logging service of the application. When the
+// "hookMode" is true, it only initializes the root path for log files without
+// creating any logger. It will also not remove the primary logger in "hookMode"
+// and is up to the caller to decide when to remove it.
+func InitLogging(hookMode bool) {
+	logConf, hasConsole, err := initLogConf(File, hookMode)
 	if err != nil {
 		log.Fatal("Failed to init logging configuration: %v", err)
 	}
+	defer func() {
+		Log = logConf
+	}()
+
+	if hookMode {
+		return
+	}
 
 	err = os.MkdirAll(logConf.RootPath, os.ModePerm)
 	if err != nil {
@@ -159,9 +176,10 @@ func InitLogging() {
 		log.Trace("Log mode: %s (%s)", strings.Title(mode), strings.Title(strings.ToLower(level.String())))
 	}
 
+	// ⚠️ WARNING: It is only safe to remove the primary logger until
+	// there are other loggers that are initialized. Otherwise, the
+	// application will print errors to nowhere.
 	if !hasConsole {
 		log.Remove(log.DefaultConsoleName)
 	}
-
-	Log = logConf
 }

+ 3 - 3
internal/conf/log_test.go

@@ -23,7 +23,7 @@ MODE = console
 			t.Fatal(err)
 		}
 
-		got, hasConsole, err := initLogConf(f)
+		got, hasConsole, err := initLogConf(f, false)
 		assert.NotNil(t, err)
 		assert.Equal(t, `missing configuration section [log.console] for "console" logger`, err.Error())
 		assert.False(t, hasConsole)
@@ -41,7 +41,7 @@ MODE = file
 			t.Fatal(err)
 		}
 
-		got, hasConsole, err := initLogConf(f)
+		got, hasConsole, err := initLogConf(f, false)
 		if err != nil {
 			t.Fatal(err)
 		}
@@ -81,7 +81,7 @@ USERNAME = yoyo
 		t.Fatal(err)
 	}
 
-	got, hasConsole, err := initLogConf(f)
+	got, hasConsole, err := initLogConf(f, false)
 	if err != nil {
 		t.Fatal(err)
 	}

+ 8 - 7
internal/conf/static.go

@@ -300,7 +300,6 @@ var (
 	// Webhook settings
 	Webhook struct {
 		Types          []string
-		QueueLength    int
 		DeliverTimeout int
 		SkipTLSVerify  bool `ini:"SKIP_TLS_VERIFY"`
 		PagingNum      int
@@ -359,12 +358,12 @@ var (
 		// ⚠️ WARNING: Should only be set by "internal/db/repo.go".
 		Version string `ini:"-"`
 
-		DisableDiffHighlight     bool
-		MaxGitDiffLines          int
-		MaxGitDiffLineCharacters int
-		MaxGitDiffFiles          int
-		GCArgs                   []string `ini:"GC_ARGS" delim:" "`
-		Timeout                  struct {
+		DisableDiffHighlight bool
+		MaxDiffFiles         int      `ini:"MAX_GIT_DIFF_FILES"`
+		MaxDiffLines         int      `ini:"MAX_GIT_DIFF_LINES"`
+		MaxDiffLineChars     int      `ini:"MAX_GIT_DIFF_LINE_CHARACTERS"`
+		GCArgs               []string `ini:"GC_ARGS" delim:" "`
+		Timeout              struct {
 			Migrate int
 			Mirror  int
 			Clone   int
@@ -523,6 +522,8 @@ func handleDeprecated() {
 
 // HookMode indicates whether program starts as Git server-side hook callback.
 // All operations should be done synchronously to prevent program exits before finishing.
+//
+// ⚠️ WARNING: Should only be set by "internal/cmd/serv.go".
 var HookMode bool
 
 // Indicates which database backend is currently being used.

+ 1 - 1
internal/context/auth.go

@@ -41,7 +41,7 @@ func Toggle(options *ToggleOptions) macaron.Handler {
 
 		// Check non-logged users landing page.
 		if !c.IsLogged && c.Req.RequestURI == "/" && conf.Server.LandingURL != "/" {
-			c.Redirect(conf.Server.LandingURL)
+			c.SubURLRedirect(conf.Server.LandingURL)
 			return
 		}
 

+ 1 - 1
internal/context/context.go

@@ -173,7 +173,7 @@ func (c *Context) Handle(status int, msg string, err error) {
 		c.Data["Title"] = "Page Not Found"
 	case http.StatusInternalServerError:
 		c.Data["Title"] = "Internal Server Error"
-		log.Error("%s: %v", msg, err)
+		log.ErrorDepth(5, "%s: %v", msg, err)
 		if !conf.IsProdMode() || (c.IsLogged && c.User.IsAdmin) {
 			c.Data["ErrorMsg"] = err
 		}

+ 15 - 15
internal/context/context_gin.go

@@ -3,10 +3,10 @@ package context
 import (
 	"strings"
 
-	"github.com/G-Node/git-module"
 	"github.com/G-Node/gogs/internal/conf"
 	"github.com/G-Node/gogs/internal/db"
 	"github.com/G-Node/libgin/libgin"
+	"github.com/gogs/git-module"
 	log "gopkg.in/clog.v1"
 )
 
@@ -48,26 +48,26 @@ func getRepoDOI(c *Context) string {
 	// if multiple exit, get the latest one
 	doiBase := conf.DOI.Base
 
-	doiForkGit, err := git.OpenRepository(doiFork.RepoPath())
+	doiForkGit, err := git.Open(doiFork.RepoPath())
 	if err != nil {
 		log.Error(2, "failed to open git repository at %q (%d): %v", doiFork.RepoPath(), doiFork.ID, err)
 		return ""
 	}
-	if tags, err := doiForkGit.GetTags(); err == nil {
+	if tags, err := doiForkGit.Tags(); err == nil {
 		var latestTime int64
 		latestTag := ""
 		for _, tagName := range tags {
 			if strings.Contains(tagName, doiBase) {
-				tag, err := doiForkGit.GetTag(tagName)
+				tag, err := doiForkGit.Tag(tagName)
 				if err != nil {
 					// log the error and continue to the next tag
-					log.Error(2, "failed to get information for tag %q for repository at %q: %v", tagName, doiForkGit.Path, err)
+					log.Error(2, "failed to get information for tag %q for repository at %q: %v", tagName, doiForkGit.Path(), err)
 					continue
 				}
 				commit, err := tag.Commit()
 				if err != nil {
 					// log the error and continue to the next tag
-					log.Error(2, "failed to get commit for tag %q for repository at %q: %v", tagName, doiForkGit.Path, err)
+					log.Error(2, "failed to get commit for tag %q for repository at %q: %v", tagName, doiForkGit.Path(), err)
 					continue
 				}
 				commitTime := commit.Committer.When.Unix()
@@ -81,7 +81,7 @@ func getRepoDOI(c *Context) string {
 	} else {
 		// this shouldn't happen even if there are no tags
 		// log the error, but fall back to the old method anyway
-		log.Error(2, "failed to get tags for repository at %q: %v", doiForkGit.Path, err)
+		log.Error(2, "failed to get tags for repository at %q: %v", doiForkGit.Path(), err)
 	}
 
 	// Has DOI fork but isn't tagged: return old style has-based DOI
@@ -99,12 +99,12 @@ func getRepoDOI(c *Context) string {
 // valid.  If any error occurs, for example due to an uninitialised repository
 // or missing repository root, it returns 'false' without error.
 func hasDataCite(c *Context) bool {
-	commit, err := c.Repo.GitRepo.GetBranchCommit(c.Repo.Repository.DefaultBranch)
+	commit, err := c.Repo.GitRepo.BranchCommit(c.Repo.Repository.DefaultBranch)
 	if err != nil {
 		log.Trace("Couldn't get commit: %v", err)
 		return false
 	}
-	_, err = commit.GetBlobByPath("/datacite.yml")
+	_, err = commit.Blob("/datacite.yml")
 
 	log.Trace("Found datacite? %t", err == nil)
 	return err == nil
@@ -125,23 +125,23 @@ func isDOIReady(c *Context) bool {
 			return false
 		}
 
-		headBranch, err := gitrepo.GetHEADBranch()
+		headBranch, err := gitrepo.SymbolicRef(git.SymbolicRefOptions{Name: "HEAD"})
 		if err != nil {
-			log.Error(2, "Failed to get HEAD branch for repo at %q: %v", gitrepo.Path, err)
+			log.Error(2, "Failed to get HEAD branch for repo at %q: %v", gitrepo.Path(), err)
 			return false
 		}
 
-		headCommit, err := gitrepo.GetBranchCommitID(headBranch.Name)
+		headCommit, err := gitrepo.BranchCommitID(headBranch)
 		if err != nil {
-			log.Error(2, "Failed to get commit ID of branch %q for repo at %q: %v", headBranch.Name, gitrepo.Path, err)
+			log.Error(2, "Failed to get commit ID of branch %q for repo at %q: %v", headBranch, gitrepo.Path(), err)
 			return false
 		}
 
 		// if current valid and registered DOI matches the HEAD commit, can't
 		// register again
-		doiCommit, err := gitrepo.GetTagCommitID(currentDOI.(string))
+		doiCommit, err := gitrepo.TagCommitID(currentDOI.(string))
 		if err != nil {
-			log.Error(2, "Failed to get commit ID of tag %q for repo at %q: %v", currentDOI, gitrepo.Path, err)
+			log.Error(2, "Failed to get commit ID of tag %q for repo at %q: %v", currentDOI, gitrepo.Path(), err)
 			return false
 		}
 

+ 44 - 50
internal/context/repo.go

@@ -5,19 +5,20 @@
 package context
 
 import (
+	"bytes"
 	"fmt"
-	"io/ioutil"
 	"net/url"
 	"strings"
 
 	"github.com/editorconfig/editorconfig-core-go/v2"
+	"github.com/pkg/errors"
 	"gopkg.in/macaron.v1"
 
-	"github.com/G-Node/git-module"
+	"github.com/gogs/git-module"
 
 	"github.com/G-Node/gogs/internal/conf"
 	"github.com/G-Node/gogs/internal/db"
-	"github.com/G-Node/gogs/internal/db/errors"
+	dberrors "github.com/G-Node/gogs/internal/db/errors"
 	"github.com/G-Node/libgin/libgin"
 )
 
@@ -76,26 +77,23 @@ func (r *Repository) CanEnableEditor() bool {
 	return r.Repository.CanEnableEditor() && r.IsViewBranch && r.IsWriter() && !r.Repository.IsBranchRequirePullRequest(r.BranchName)
 }
 
-// GetEditorconfig returns the .editorconfig definition if found in the
-// HEAD of the default repo branch.
-func (r *Repository) GetEditorconfig() (*editorconfig.Editorconfig, error) {
-	commit, err := r.GitRepo.GetBranchCommit(r.Repository.DefaultBranch)
+// Editorconfig returns the ".editorconfig" definition if found in the HEAD of the default branch.
+func (r *Repository) Editorconfig() (*editorconfig.Editorconfig, error) {
+	commit, err := r.GitRepo.BranchCommit(r.Repository.DefaultBranch)
 	if err != nil {
-		return nil, err
+		return nil, errors.Wrapf(err, "get commit of branch %q ", r.Repository.DefaultBranch)
 	}
-	treeEntry, err := commit.GetTreeEntryByPath(".editorconfig")
-	if err != nil {
-		return nil, err
-	}
-	reader, err := treeEntry.Blob().Data()
+
+	entry, err := commit.TreeEntry(".editorconfig")
 	if err != nil {
-		return nil, err
+		return nil, errors.Wrap(err, "get .editorconfig")
 	}
-	data, err := ioutil.ReadAll(reader)
+
+	p, err := entry.Blob().Bytes()
 	if err != nil {
-		return nil, err
+		return nil, errors.Wrap(err, "read .editorconfig")
 	}
-	return editorconfig.ParseBytes(data)
+	return editorconfig.Parse(bytes.NewReader(p))
 }
 
 // MakeURL accepts a string or url.URL as argument and returns escaped URL prepended with repository URL.
@@ -143,10 +141,6 @@ func RepoAssignment(pages ...bool) macaron.Handler {
 
 		ownerName := c.Params(":username")
 		repoName := strings.TrimSuffix(c.Params(":reponame"), ".git")
-		refName := c.Params(":branchname")
-		if len(refName) == 0 {
-			refName = c.Params(":path")
-		}
 
 		// Check if the user is the same as the repository owner
 		if c.IsLogged && c.User.LowerName == strings.ToLower(ownerName) {
@@ -154,7 +148,7 @@ func RepoAssignment(pages ...bool) macaron.Handler {
 		} else {
 			owner, err = db.GetUserByName(ownerName)
 			if err != nil {
-				c.NotFoundOrServerError("GetUserByName", errors.IsUserNotExist, err)
+				c.NotFoundOrServerError("GetUserByName", dberrors.IsUserNotExist, err)
 				return
 			}
 		}
@@ -163,7 +157,7 @@ func RepoAssignment(pages ...bool) macaron.Handler {
 
 		repo, err := db.GetRepositoryByName(owner.ID, repoName)
 		if err != nil {
-			c.NotFoundOrServerError("GetRepositoryByName", errors.IsRepoNotExist, err)
+			c.NotFoundOrServerError("GetRepositoryByName", dberrors.IsRepoNotExist, err)
 			return
 		}
 
@@ -227,16 +221,16 @@ func RepoAssignment(pages ...bool) macaron.Handler {
 			c.Data["Mirror"] = c.Repo.Mirror
 		}
 
-		gitRepo, err := git.OpenRepository(db.RepoPath(ownerName, repoName))
+		gitRepo, err := git.Open(db.RepoPath(ownerName, repoName))
 		if err != nil {
-			c.ServerError(fmt.Sprintf("RepoAssignment Invalid repo '%s'", c.Repo.Repository.RepoPath()), err)
+			c.ServerError("open repository", err)
 			return
 		}
 		c.Repo.GitRepo = gitRepo
 
-		tags, err := c.Repo.GitRepo.GetTags()
+		tags, err := c.Repo.GitRepo.Tags()
 		if err != nil {
-			c.ServerError(fmt.Sprintf("GetTags '%s'", c.Repo.Repository.RepoPath()), err)
+			c.ServerError("get tags", err)
 			return
 		}
 		c.Data["Tags"] = tags
@@ -267,21 +261,21 @@ func RepoAssignment(pages ...bool) macaron.Handler {
 		}
 
 		c.Data["TagName"] = c.Repo.TagName
-		brs, err := c.Repo.GitRepo.GetBranches()
+		branches, err := c.Repo.GitRepo.Branches()
 		if err != nil {
-			c.ServerError("GetBranches", err)
+			c.ServerError("get branches", err)
 			return
 		}
-		c.Data["Branches"] = brs
-		c.Data["BrancheCount"] = len(brs)
+		c.Data["Branches"] = branches
+		c.Data["BrancheCount"] = len(branches)
 
 		// If not branch selected, try default one.
 		// If default branch doesn't exists, fall back to some other branch.
 		if len(c.Repo.BranchName) == 0 {
-			if len(c.Repo.Repository.DefaultBranch) > 0 && gitRepo.IsBranchExist(c.Repo.Repository.DefaultBranch) {
+			if len(c.Repo.Repository.DefaultBranch) > 0 && gitRepo.HasBranch(c.Repo.Repository.DefaultBranch) {
 				c.Repo.BranchName = c.Repo.Repository.DefaultBranch
-			} else if len(brs) > 0 {
-				c.Repo.BranchName = brs[0]
+			} else if len(branches) > 0 {
+				c.Repo.BranchName = branches[0]
 			}
 		}
 		c.Data["BranchName"] = c.Repo.BranchName
@@ -318,7 +312,7 @@ func RepoRef() macaron.Handler {
 		// For API calls.
 		if c.Repo.GitRepo == nil {
 			repoPath := db.RepoPath(c.Repo.Owner.Name, c.Repo.Repository.Name)
-			c.Repo.GitRepo, err = git.OpenRepository(repoPath)
+			c.Repo.GitRepo, err = git.Open(repoPath)
 			if err != nil {
 				c.Handle(500, "RepoRef Invalid repo "+repoPath, err)
 				return
@@ -328,17 +322,17 @@ func RepoRef() macaron.Handler {
 		// Get default branch.
 		if len(c.Params("*")) == 0 {
 			refName = c.Repo.Repository.DefaultBranch
-			if !c.Repo.GitRepo.IsBranchExist(refName) {
-				brs, err := c.Repo.GitRepo.GetBranches()
+			if !c.Repo.GitRepo.HasBranch(refName) {
+				branches, err := c.Repo.GitRepo.Branches()
 				if err != nil {
-					c.Handle(500, "GetBranches", err)
+					c.ServerError("get branches", err)
 					return
 				}
-				refName = brs[0]
+				refName = branches[0]
 			}
-			c.Repo.Commit, err = c.Repo.GitRepo.GetBranchCommit(refName)
+			c.Repo.Commit, err = c.Repo.GitRepo.BranchCommit(refName)
 			if err != nil {
-				c.Handle(500, "GetBranchCommit", err)
+				c.ServerError("get branch commit", err)
 				return
 			}
 			c.Repo.CommitID = c.Repo.Commit.ID.String()
@@ -350,8 +344,8 @@ func RepoRef() macaron.Handler {
 			for i, part := range parts {
 				refName = strings.TrimPrefix(refName+"/"+part, "/")
 
-				if c.Repo.GitRepo.IsBranchExist(refName) ||
-					c.Repo.GitRepo.IsTagExist(refName) {
+				if c.Repo.GitRepo.HasBranch(refName) ||
+					c.Repo.GitRepo.HasTag(refName) {
 					if i < len(parts)-1 {
 						c.Repo.TreePath = strings.Join(parts[i+1:], "/")
 					}
@@ -364,21 +358,21 @@ func RepoRef() macaron.Handler {
 				c.Repo.TreePath = strings.Join(parts[1:], "/")
 			}
 
-			if c.Repo.GitRepo.IsBranchExist(refName) {
+			if c.Repo.GitRepo.HasBranch(refName) {
 				c.Repo.IsViewBranch = true
 
-				c.Repo.Commit, err = c.Repo.GitRepo.GetBranchCommit(refName)
+				c.Repo.Commit, err = c.Repo.GitRepo.BranchCommit(refName)
 				if err != nil {
-					c.Handle(500, "GetBranchCommit", err)
+					c.ServerError("get branch commit", err)
 					return
 				}
 				c.Repo.CommitID = c.Repo.Commit.ID.String()
 
-			} else if c.Repo.GitRepo.IsTagExist(refName) {
+			} else if c.Repo.GitRepo.HasTag(refName) {
 				c.Repo.IsViewTag = true
-				c.Repo.Commit, err = c.Repo.GitRepo.GetTagCommit(refName)
+				c.Repo.Commit, err = c.Repo.GitRepo.TagCommit(refName)
 				if err != nil {
-					c.Handle(500, "GetTagCommit", err)
+					c.ServerError("get tag commit", err)
 					return
 				}
 				c.Repo.CommitID = c.Repo.Commit.ID.String()
@@ -386,7 +380,7 @@ func RepoRef() macaron.Handler {
 				c.Repo.IsViewCommit = true
 				c.Repo.CommitID = refName
 
-				c.Repo.Commit, err = c.Repo.GitRepo.GetCommit(refName)
+				c.Repo.Commit, err = c.Repo.GitRepo.CatFileCommit(refName)
 				if err != nil {
 					c.NotFound()
 					return

+ 5 - 5
internal/dav/middle.go

@@ -4,9 +4,9 @@ import (
 	"net/http"
 	"strings"
 
-	"github.com/G-Node/git-module"
 	"github.com/G-Node/gogs/internal/context"
 	"github.com/G-Node/gogs/internal/db"
+	"github.com/gogs/git-module"
 	"gopkg.in/macaron.v1"
 )
 
@@ -63,14 +63,14 @@ func DavMiddle() macaron.Handler {
 			}
 		}
 
-		gitRepo, err := git.OpenRepository(db.RepoPath(ownerName, repoName))
+		gitRepo, err := git.Open(db.RepoPath(ownerName, repoName))
 		if err != nil {
 			c.WriteHeader(http.StatusInternalServerError)
 			return
 		}
 		c.Repo.GitRepo = gitRepo
 
-		tags, err := c.Repo.GitRepo.GetTags()
+		tags, err := c.Repo.GitRepo.Tags()
 		if err != nil {
 			c.WriteHeader(http.StatusInternalServerError)
 			return
@@ -82,7 +82,7 @@ func DavMiddle() macaron.Handler {
 			return
 		}
 
-		brs, err := c.Repo.GitRepo.GetBranches()
+		brs, err := c.Repo.GitRepo.Branches()
 		if err != nil {
 			c.WriteHeader(http.StatusInternalServerError)
 			return
@@ -90,7 +90,7 @@ func DavMiddle() macaron.Handler {
 		// If not branch selected, try default one.
 		// If default branch doesn't exists, fall back to some other branch.
 		if len(c.Repo.BranchName) == 0 {
-			if len(c.Repo.Repository.DefaultBranch) > 0 && gitRepo.IsBranchExist(c.Repo.Repository.DefaultBranch) {
+			if len(c.Repo.Repository.DefaultBranch) > 0 && gitRepo.HasBranch(c.Repo.Repository.DefaultBranch) {
 				c.Repo.BranchName = c.Repo.Repository.DefaultBranch
 			} else if len(brs) > 0 {
 				c.Repo.BranchName = brs[0]

+ 15 - 15
internal/db/action.go

@@ -16,7 +16,7 @@ import (
 	log "unknwon.dev/clog/v2"
 	"xorm.io/xorm"
 
-	"github.com/G-Node/git-module"
+	"github.com/gogs/git-module"
 	api "github.com/gogs/go-gogs-client"
 
 	"github.com/G-Node/gogs/internal/conf"
@@ -268,9 +268,9 @@ func (pc *PushCommits) ToApiPayloadCommits(repoPath, repoURL string) ([]*api.Pay
 			return nil, fmt.Errorf("GetUserByEmail: %v", err)
 		}
 
-		fileStatus, err := git.GetCommitFileStatus(repoPath, commit.Sha1)
+		nameStatus, err := git.RepoShowNameStatus(repoPath, commit.Sha1)
 		if err != nil {
-			return nil, fmt.Errorf("FileStatus [commit_sha1: %s]: %v", commit.Sha1, err)
+			return nil, fmt.Errorf("show name status [commit_sha1: %s]: %v", commit.Sha1, err)
 		}
 
 		commits[i] = &api.PayloadCommit{
@@ -287,9 +287,9 @@ func (pc *PushCommits) ToApiPayloadCommits(repoPath, repoURL string) ([]*api.Pay
 				Email:    commit.CommitterEmail,
 				UserName: committerUsername,
 			},
-			Added:     fileStatus.Added,
-			Removed:   fileStatus.Removed,
-			Modified:  fileStatus.Modified,
+			Added:     nameStatus.Added,
+			Removed:   nameStatus.Removed,
+			Modified:  nameStatus.Modified,
 			Timestamp: commit.Timestamp,
 		}
 	}
@@ -298,21 +298,21 @@ func (pc *PushCommits) ToApiPayloadCommits(repoPath, repoURL string) ([]*api.Pay
 
 // AvatarLink tries to match user in database with e-mail
 // in order to show custom avatar, and falls back to general avatar link.
-func (push *PushCommits) AvatarLink(email string) string {
-	_, ok := push.avatars[email]
+func (pcs *PushCommits) AvatarLink(email string) string {
+	_, ok := pcs.avatars[email]
 	if !ok {
 		u, err := GetUserByEmail(email)
 		if err != nil {
-			push.avatars[email] = tool.AvatarLink(email)
+			pcs.avatars[email] = tool.AvatarLink(email)
 			if !errors.IsUserNotExist(err) {
 				log.Error("GetUserByEmail: %v", err)
 			}
 		} else {
-			push.avatars[email] = u.RelAvatarLink()
+			pcs.avatars[email] = u.RelAvatarLink()
 		}
 	}
 
-	return push.avatars[email]
+	return pcs.avatars[email]
 }
 
 // UpdateIssuesCommit checks if issues are manipulated by commit message.
@@ -474,12 +474,12 @@ func CommitRepoAction(opts CommitRepoActionOptions) error {
 		return fmt.Errorf("UpdateRepository: %v", err)
 	}
 
-	isNewRef := opts.OldCommitID == git.EMPTY_SHA
-	isDelRef := opts.NewCommitID == git.EMPTY_SHA
+	isNewRef := opts.OldCommitID == git.EmptyID
+	isDelRef := opts.NewCommitID == git.EmptyID
 
 	opType := ACTION_COMMIT_REPO
 	// Check if it's tag push or branch.
-	if strings.HasPrefix(opts.RefFullName, git.TAG_PREFIX) {
+	if strings.HasPrefix(opts.RefFullName, git.RefsTags) {
 		opType = ACTION_PUSH_TAG
 	} else {
 		// if not the first commit, set the compare URL.
@@ -504,7 +504,7 @@ func CommitRepoAction(opts CommitRepoActionOptions) error {
 		return fmt.Errorf("Marshal: %v", err)
 	}
 
-	refName := git.RefEndName(opts.RefFullName)
+	refName := git.RefShortName(opts.RefFullName)
 	action := &Action{
 		ActUserID:    pusher.ID,
 		ActUserName:  pusher.Name,

+ 0 - 194
internal/db/git_diff.go

@@ -1,194 +0,0 @@
-// Copyright 2014 The Gogs Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package db
-
-import (
-	"bytes"
-	"fmt"
-	"html"
-	"html/template"
-	"io"
-
-	"github.com/sergi/go-diff/diffmatchpatch"
-	"golang.org/x/net/html/charset"
-	"golang.org/x/text/transform"
-
-	"github.com/G-Node/git-module"
-
-	"github.com/G-Node/gogs/internal/conf"
-	"github.com/G-Node/gogs/internal/template/highlight"
-	"github.com/G-Node/gogs/internal/tool"
-)
-
-type DiffSection struct {
-	*git.DiffSection
-}
-
-var (
-	addedCodePrefix   = []byte("<span class=\"added-code\">")
-	removedCodePrefix = []byte("<span class=\"removed-code\">")
-	codeTagSuffix     = []byte("</span>")
-)
-
-func diffToHTML(diffs []diffmatchpatch.Diff, lineType git.DiffLineType) template.HTML {
-	buf := bytes.NewBuffer(nil)
-
-	// Reproduce signs which are cutted for inline diff before.
-	switch lineType {
-	case git.DIFF_LINE_ADD:
-		buf.WriteByte('+')
-	case git.DIFF_LINE_DEL:
-		buf.WriteByte('-')
-	}
-
-	for i := range diffs {
-		switch {
-		case diffs[i].Type == diffmatchpatch.DiffInsert && lineType == git.DIFF_LINE_ADD:
-			buf.Write(addedCodePrefix)
-			buf.WriteString(html.EscapeString(diffs[i].Text))
-			buf.Write(codeTagSuffix)
-		case diffs[i].Type == diffmatchpatch.DiffDelete && lineType == git.DIFF_LINE_DEL:
-			buf.Write(removedCodePrefix)
-			buf.WriteString(html.EscapeString(diffs[i].Text))
-			buf.Write(codeTagSuffix)
-		case diffs[i].Type == diffmatchpatch.DiffEqual:
-			buf.WriteString(html.EscapeString(diffs[i].Text))
-		}
-	}
-
-	return template.HTML(buf.Bytes())
-}
-
-var diffMatchPatch = diffmatchpatch.New()
-
-func init() {
-	diffMatchPatch.DiffEditCost = 100
-}
-
-// ComputedInlineDiffFor computes inline diff for the given line.
-func (diffSection *DiffSection) ComputedInlineDiffFor(diffLine *git.DiffLine) template.HTML {
-	if conf.Git.DisableDiffHighlight {
-		return template.HTML(html.EscapeString(diffLine.Content[1:]))
-	}
-	var (
-		compareDiffLine *git.DiffLine
-		diff1           string
-		diff2           string
-	)
-
-	// try to find equivalent diff line. ignore, otherwise
-	switch diffLine.Type {
-	case git.DIFF_LINE_ADD:
-		compareDiffLine = diffSection.Line(git.DIFF_LINE_DEL, diffLine.RightIdx)
-		if compareDiffLine == nil {
-			return template.HTML(html.EscapeString(diffLine.Content))
-		}
-		diff1 = compareDiffLine.Content
-		diff2 = diffLine.Content
-	case git.DIFF_LINE_DEL:
-		compareDiffLine = diffSection.Line(git.DIFF_LINE_ADD, diffLine.LeftIdx)
-		if compareDiffLine == nil {
-			return template.HTML(html.EscapeString(diffLine.Content))
-		}
-		diff1 = diffLine.Content
-		diff2 = compareDiffLine.Content
-	default:
-		return template.HTML(html.EscapeString(diffLine.Content))
-	}
-
-	diffRecord := diffMatchPatch.DiffMain(diff1[1:], diff2[1:], true)
-	diffRecord = diffMatchPatch.DiffCleanupEfficiency(diffRecord)
-
-	return diffToHTML(diffRecord, diffLine.Type)
-}
-
-type DiffFile struct {
-	*git.DiffFile
-	Sections []*DiffSection
-}
-
-func (diffFile *DiffFile) HighlightClass() string {
-	return highlight.FileNameToHighlightClass(diffFile.Name)
-}
-
-type Diff struct {
-	*git.Diff
-	Files []*DiffFile
-}
-
-func NewDiff(gitDiff *git.Diff) *Diff {
-	diff := &Diff{
-		Diff:  gitDiff,
-		Files: make([]*DiffFile, gitDiff.NumFiles()),
-	}
-
-	// FIXME: detect encoding while parsing.
-	var buf bytes.Buffer
-	for i := range gitDiff.Files {
-		buf.Reset()
-
-		diff.Files[i] = &DiffFile{
-			DiffFile: gitDiff.Files[i],
-			Sections: make([]*DiffSection, gitDiff.Files[i].NumSections()),
-		}
-
-		for j := range gitDiff.Files[i].Sections {
-			diff.Files[i].Sections[j] = &DiffSection{
-				DiffSection: gitDiff.Files[i].Sections[j],
-			}
-
-			for k := range diff.Files[i].Sections[j].Lines {
-				buf.WriteString(diff.Files[i].Sections[j].Lines[k].Content)
-				buf.WriteString("\n")
-			}
-		}
-
-		charsetLabel, err := tool.DetectEncoding(buf.Bytes())
-		if charsetLabel != "UTF-8" && err == nil {
-			encoding, _ := charset.Lookup(charsetLabel)
-			if encoding != nil {
-				d := encoding.NewDecoder()
-				for j := range diff.Files[i].Sections {
-					for k := range diff.Files[i].Sections[j].Lines {
-						if c, _, err := transform.String(d, diff.Files[i].Sections[j].Lines[k].Content); err == nil {
-							diff.Files[i].Sections[j].Lines[k].Content = c
-						}
-					}
-				}
-			}
-		}
-	}
-
-	return diff
-}
-
-func ParsePatch(maxLines, maxLineCharacteres, maxFiles int, reader io.Reader) (*Diff, error) {
-	done := make(chan error)
-	var gitDiff *git.Diff
-	go func() {
-		gitDiff = git.ParsePatch(done, maxLines, maxLineCharacteres, maxFiles, reader)
-	}()
-
-	if err := <-done; err != nil {
-		return nil, fmt.Errorf("ParsePatch: %v", err)
-	}
-	return NewDiff(gitDiff), nil
-}
-
-func GetDiffRange(repoPath, beforeCommitID, afterCommitID string, maxLines, maxLineCharacteres, maxFiles int) (*Diff, error) {
-	gitDiff, err := git.GetDiffRange(repoPath, beforeCommitID, afterCommitID, maxLines, maxLineCharacteres, maxFiles)
-	if err != nil {
-		return nil, fmt.Errorf("GetDiffRange: %v", err)
-	}
-	return NewDiff(gitDiff), nil
-}
-
-func GetDiffCommit(repoPath, commitID string, maxLines, maxLineCharacteres, maxFiles int) (*Diff, error) {
-	gitDiff, err := git.GetDiffCommit(repoPath, commitID, maxLines, maxLineCharacteres, maxFiles)
-	if err != nil {
-		return nil, fmt.Errorf("GetDiffCommit: %v", err)
-	}
-	return NewDiff(gitDiff), nil
-}

+ 0 - 41
internal/db/git_diff_test.go

@@ -1,41 +0,0 @@
-// Copyright 2016 The Gogs Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package db
-
-import (
-	"html/template"
-	"testing"
-
-	"github.com/G-Node/git-module"
-	dmp "github.com/sergi/go-diff/diffmatchpatch"
-)
-
-func assertEqual(t *testing.T, s1 string, s2 template.HTML) {
-	if s1 != string(s2) {
-		t.Errorf("%s should be equal %s", s2, s1)
-	}
-}
-
-func assertLineEqual(t *testing.T, d1 *git.DiffLine, d2 *git.DiffLine) {
-	if d1 != d2 {
-		t.Errorf("%v should be equal %v", d1, d2)
-	}
-}
-
-func Test_diffToHTML(t *testing.T) {
-	assertEqual(t, "+foo <span class=\"added-code\">bar</span> biz", diffToHTML([]dmp.Diff{
-		dmp.Diff{dmp.DiffEqual, "foo "},
-		dmp.Diff{dmp.DiffInsert, "bar"},
-		dmp.Diff{dmp.DiffDelete, " baz"},
-		dmp.Diff{dmp.DiffEqual, " biz"},
-	}, git.DIFF_LINE_ADD))
-
-	assertEqual(t, "-foo <span class=\"removed-code\">bar</span> biz", diffToHTML([]dmp.Diff{
-		dmp.Diff{dmp.DiffEqual, "foo "},
-		dmp.Diff{dmp.DiffDelete, "bar"},
-		dmp.Diff{dmp.DiffInsert, " baz"},
-		dmp.Diff{dmp.DiffEqual, " biz"},
-	}, git.DIFF_LINE_DEL))
-}

+ 3 - 3
internal/db/issue.go

@@ -801,7 +801,7 @@ func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, uuids []string)
 func GetIssueByRef(ref string) (*Issue, error) {
 	n := strings.IndexByte(ref, byte('#'))
 	if n == -1 {
-		return nil, errors.InvalidIssueReference{ref}
+		return nil, errors.InvalidIssueReference{Ref: ref}
 	}
 
 	index := com.StrTo(ref[n+1:]).MustInt64()
@@ -832,7 +832,7 @@ func GetRawIssueByIndex(repoID, index int64) (*Issue, error) {
 	if err != nil {
 		return nil, err
 	} else if !has {
-		return nil, errors.IssueNotExist{0, repoID, index}
+		return nil, errors.IssueNotExist{RepoID: repoID, Index: index}
 	}
 	return issue, nil
 }
@@ -852,7 +852,7 @@ func getRawIssueByID(e Engine, id int64) (*Issue, error) {
 	if err != nil {
 		return nil, err
 	} else if !has {
-		return nil, errors.IssueNotExist{id, 0, 0}
+		return nil, errors.IssueNotExist{ID: id}
 	}
 	return issue, nil
 }

+ 7 - 7
internal/db/login_source.go

@@ -439,7 +439,7 @@ func (s *LocalLoginSources) GetLoginSourceByID(id int64) (*LoginSource, error) {
 		}
 	}
 
-	return nil, errors.LoginSourceNotExist{id}
+	return nil, errors.LoginSourceNotExist{ID: id}
 }
 
 // UpdateLoginSource updates in-memory copy of the authentication source.
@@ -556,7 +556,7 @@ func LoginViaLDAP(user *User, login, password string, source *LoginSource, autoR
 	username, fn, sn, mail, isAdmin, succeed := source.Cfg.(*LDAPConfig).SearchEntry(login, password, source.Type == LOGIN_DLDAP)
 	if !succeed {
 		// User not in LDAP, do nothing
-		return nil, errors.UserNotExist{0, login}
+		return nil, errors.UserNotExist{Name: login}
 	}
 
 	if !autoRegister {
@@ -674,9 +674,9 @@ func LoginViaSMTP(user *User, login, password string, sourceID int64, cfg *SMTPC
 	if len(cfg.AllowedDomains) > 0 {
 		idx := strings.Index(login, "@")
 		if idx == -1 {
-			return nil, errors.UserNotExist{0, login}
+			return nil, errors.UserNotExist{Name: login}
 		} else if !com.IsSliceContainsStr(strings.Split(cfg.AllowedDomains, ","), login[idx+1:]) {
-			return nil, errors.UserNotExist{0, login}
+			return nil, errors.UserNotExist{Name: login}
 		}
 	}
 
@@ -794,7 +794,7 @@ func LoginViaGitHub(user *User, login, password string, sourceID int64, cfg *Git
 
 func remoteUserLogin(user *User, login, password string, source *LoginSource, autoRegister bool) (*User, error) {
 	if !source.IsActived {
-		return nil, errors.LoginSourceNotActivated{source.ID}
+		return nil, errors.LoginSourceNotActivated{SourceID: source.ID}
 	}
 
 	switch source.Type {
@@ -808,7 +808,7 @@ func remoteUserLogin(user *User, login, password string, source *LoginSource, au
 		return LoginViaGitHub(user, login, password, source.ID, source.Cfg.(*GitHubConfig), autoRegister)
 	}
 
-	return nil, errors.InvalidLoginSourceType{source.Type}
+	return nil, errors.InvalidLoginSourceType{Type: source.Type}
 }
 
 // UserLogin validates user name and password via given login source ID.
@@ -830,7 +830,7 @@ func UserLogin(username, password string, loginSourceID int64) (*User, error) {
 		// Note: This check is unnecessary but to reduce user confusion at login page
 		// and make it more consistent at user's perspective.
 		if loginSourceID >= 0 && user.LoginSource != loginSourceID {
-			return nil, errors.LoginSourceMismatch{loginSourceID, user.LoginSource}
+			return nil, errors.LoginSourceMismatch{Expect: loginSourceID, Actual: user.LoginSource}
 		}
 
 		// Validate password hash fetched from database for local accounts

+ 6 - 6
internal/db/migrations/v16.go

@@ -12,13 +12,13 @@ import (
 	log "unknwon.dev/clog/v2"
 	"xorm.io/xorm"
 
-	"github.com/G-Node/git-module"
+	"github.com/gogs/git-module"
 
 	"github.com/G-Node/gogs/internal/conf"
 )
 
 func updateRepositorySizes(x *xorm.Engine) (err error) {
-	log.Info("This migration could take up to minutes, please be patient.")
+	log.Info("[migrations.v16] This migration could take up to minutes, please be patient.")
 	type Repository struct {
 		ID      int64
 		OwnerID int64
@@ -41,7 +41,7 @@ func updateRepositorySizes(x *xorm.Engine) (err error) {
 			Find(&repos); err != nil {
 			return fmt.Errorf("select repos [offset: %d]: %v", offset, err)
 		}
-		log.Trace("Select [offset: %d, repos: %d]", offset, len(repos))
+		log.Trace("[migrations.v16] Select [offset: %d, repos: %d]", offset, len(repos))
 		if len(repos) == 0 {
 			break
 		}
@@ -60,10 +60,10 @@ func updateRepositorySizes(x *xorm.Engine) (err error) {
 				continue
 			}
 
-			repoPath := filepath.Join(conf.Repository.Root, strings.ToLower(user.Name), strings.ToLower(repo.Name)) + ".git"
-			countObject, err := git.GetRepoSize(repoPath)
+			repoPath := strings.ToLower(filepath.Join(conf.Repository.Root, user.Name, repo.Name)) + ".git"
+			countObject, err := git.RepoCountObjects(repoPath)
 			if err != nil {
-				log.Warn("GetRepoSize: %v", err)
+				log.Warn("[migrations.v16] Count repository objects: %v", err)
 				continue
 			}
 

+ 54 - 105
internal/db/mirror.go

@@ -5,7 +5,6 @@
 package db
 
 import (
-	"container/list"
 	"fmt"
 	"net/url"
 	"strings"
@@ -16,7 +15,7 @@ import (
 	log "unknwon.dev/clog/v2"
 	"xorm.io/xorm"
 
-	"github.com/G-Node/git-module"
+	"github.com/gogs/git-module"
 
 	"github.com/G-Node/gogs/internal/conf"
 	"github.com/G-Node/gogs/internal/db/errors"
@@ -72,54 +71,17 @@ func (m *Mirror) ScheduleNextSync() {
 	m.NextSync = time.Now().Add(time.Duration(m.Interval) * time.Hour)
 }
 
-// findPasswordInMirrorAddress returns start (inclusive) and end index (exclusive)
-// of password portion of credentials in given mirror address.
-// It returns a boolean value to indicate whether password portion is found.
-func findPasswordInMirrorAddress(addr string) (start int, end int, found bool) {
-	// Find end of credentials (start of path)
-	end = strings.LastIndex(addr, "@")
-	if end == -1 {
-		return -1, -1, false
-	}
-
-	// Find delimiter of credentials (end of username)
-	start = strings.Index(addr, "://")
-	if start == -1 {
-		return -1, -1, false
-	}
-	start += 3
-	delim := strings.Index(addr[start:], ":")
-	if delim == -1 {
-		return -1, -1, false
-	}
-	delim += 1
-
-	if start+delim >= end {
-		return -1, -1, false // No password portion presented
-	}
-
-	return start + delim, end, true
-}
-
-// unescapeMirrorCredentials returns mirror address with unescaped credentials.
-func unescapeMirrorCredentials(addr string) string {
-	start, end, found := findPasswordInMirrorAddress(addr)
-	if !found {
-		return addr
-	}
-
-	password, _ := url.QueryUnescape(addr[start:end])
-	return addr[:start] + password + addr[end:]
-}
-
 func (m *Mirror) readAddress() {
 	if len(m.address) > 0 {
 		return
 	}
 
-	cfg, err := ini.Load(m.Repo.GitConfigPath())
+	cfg, err := ini.LoadSources(
+		ini.LoadOptions{IgnoreInlineComment: true},
+		m.Repo.GitConfigPath(),
+	)
 	if err != nil {
-		log.Error("Load: %v", err)
+		log.Error("load config: %v", err)
 		return
 	}
 	m.address = cfg.Section("remote \"origin\"").Key("url").Value()
@@ -128,6 +90,7 @@ func (m *Mirror) readAddress() {
 // HandleMirrorCredentials replaces user credentials from HTTP/HTTPS URL
 // with placeholder <credentials>.
 // It returns original string if protocol is not HTTP/HTTPS.
+// TODO(unknwon): Use url.Parse.
 func HandleMirrorCredentials(url string, mosaics bool) string {
 	i := strings.Index(url, "@")
 	if i == -1 {
@@ -161,34 +124,21 @@ func (m *Mirror) RawAddress() string {
 	return m.address
 }
 
-// FullAddress returns mirror address from Git repository config with unescaped credentials.
-func (m *Mirror) FullAddress() string {
-	m.readAddress()
-	return unescapeMirrorCredentials(m.address)
-}
-
-// escapeCredentials returns mirror address with escaped credentials.
-func escapeMirrorCredentials(addr string) string {
-	start, end, found := findPasswordInMirrorAddress(addr)
-	if !found {
-		return addr
-	}
-
-	return addr[:start] + url.QueryEscape(addr[start:end]) + addr[end:]
-}
-
 // SaveAddress writes new address to Git repository config.
 func (m *Mirror) SaveAddress(addr string) error {
 	repoPath := m.Repo.RepoPath()
 
-	err := git.RemoveRemote(repoPath, "origin")
+	err := git.RepoRemoveRemote(repoPath, "origin")
 	if err != nil {
 		return fmt.Errorf("remove remote 'origin': %v", err)
 	}
 
-	err = git.AddRemote(repoPath, "origin", addr, git.AddRemoteOptions{
-		Mirror: true,
-	})
+	addrURL, err := url.Parse(addr)
+	if err != nil {
+		return err
+	}
+
+	err = git.RepoAddRemote(repoPath, "origin", addrURL.String(), git.AddRemoteOptions{MirrorFetch: true})
 	if err != nil {
 		return fmt.Errorf("add remote 'origin': %v", err)
 	}
@@ -196,7 +146,7 @@ func (m *Mirror) SaveAddress(addr string) error {
 	return nil
 }
 
-const GIT_SHORT_EMPTY_SHA = "0000000"
+const gitShortEmptyID = "0000000"
 
 // mirrorSyncResult contains information of a updated reference.
 // If the oldCommitID is "0000000", it means a new reference, the value of newCommitID is empty.
@@ -223,12 +173,12 @@ func parseRemoteUpdateOutput(output string) []*mirrorSyncResult {
 		case strings.HasPrefix(lines[i], " * "): // New reference
 			results = append(results, &mirrorSyncResult{
 				refName:     refName,
-				oldCommitID: GIT_SHORT_EMPTY_SHA,
+				oldCommitID: gitShortEmptyID,
 			})
 		case strings.HasPrefix(lines[i], " - "): // Delete reference
 			results = append(results, &mirrorSyncResult{
 				refName:     refName,
-				newCommitID: GIT_SHORT_EMPTY_SHA,
+				newCommitID: gitShortEmptyID,
 			})
 		case strings.HasPrefix(lines[i], "   "): // New commits of a reference
 			delimIdx := strings.Index(lines[i][3:], " ")
@@ -262,10 +212,7 @@ func (m *Mirror) runSync() ([]*mirrorSyncResult, bool) {
 
 	// Do a fast-fail testing against on repository URL to ensure it is accessible under
 	// good condition to prevent long blocking on URL resolution without syncing anything.
-	if !git.IsRepoURLAccessible(git.NetworkOptions{
-		URL:     m.RawAddress(),
-		Timeout: 10 * time.Second,
-	}) {
+	if !git.IsURLAccessible(time.Minute, m.RawAddress()) {
 		desc := fmt.Sprintf("Source URL of mirror repository '%s' is not accessible: %s", m.Repo.FullName(), m.MosaicsAddress())
 		if err := CreateRepositoryNotice(desc); err != nil {
 			log.Error("CreateRepositoryNotice: %v", err)
@@ -316,7 +263,7 @@ func getMirrorByRepoID(e Engine, repoID int64) (*Mirror, error) {
 	if err != nil {
 		return nil, err
 	} else if !has {
-		return nil, errors.MirrorNotExist{repoID}
+		return nil, errors.MirrorNotExist{RepoID: repoID}
 	}
 	return m, nil
 }
@@ -393,15 +340,14 @@ func SyncMirrors() {
 		// - Create "Mirror Sync" webhook event
 		// - Create mirror sync (create, push and delete) events and trigger the "mirror sync" webhooks
 
-		var gitRepo *git.Repository
 		if len(results) == 0 {
 			log.Trace("SyncMirrors [repo_id: %d]: no commits fetched", m.RepoID)
-		} else {
-			gitRepo, err = git.OpenRepository(m.Repo.RepoPath())
-			if err != nil {
-				log.Error("OpenRepository [%d]: %v", m.RepoID, err)
-				continue
-			}
+		}
+
+		gitRepo, err := git.Open(m.Repo.RepoPath())
+		if err != nil {
+			log.Error("Failed to open repository [repo_id: %d]: %v", m.RepoID, err)
+			continue
 		}
 
 		for _, result := range results {
@@ -411,7 +357,7 @@ func SyncMirrors() {
 			}
 
 			// Delete reference
-			if result.newCommitID == GIT_SHORT_EMPTY_SHA {
+			if result.newCommitID == gitShortEmptyID {
 				if err = MirrorSyncDeleteAction(m.Repo, result.refName); err != nil {
 					log.Error("MirrorSyncDeleteAction [repo_id: %d]: %v", m.RepoID, err)
 				}
@@ -420,7 +366,7 @@ func SyncMirrors() {
 
 			// New reference
 			isNewRef := false
-			if result.oldCommitID == GIT_SHORT_EMPTY_SHA {
+			if result.oldCommitID == gitShortEmptyID {
 				if err = MirrorSyncCreateAction(m.Repo, result.refName); err != nil {
 					log.Error("MirrorSyncCreateAction [repo_id: %d]: %v", m.RepoID, err)
 					continue
@@ -429,49 +375,52 @@ func SyncMirrors() {
 			}
 
 			// Push commits
-			var commits *list.List
+			var commits []*git.Commit
 			var oldCommitID string
 			var newCommitID string
 			if !isNewRef {
-				oldCommitID, err = git.GetFullCommitID(gitRepo.Path, result.oldCommitID)
+				oldCommitID, err = gitRepo.RevParse(result.oldCommitID)
 				if err != nil {
-					log.Error("GetFullCommitID [%d]: %v", m.RepoID, err)
+					log.Error("Failed to parse revision [repo_id: %d, old_commit_id: %s]: %v", m.RepoID, result.oldCommitID, err)
 					continue
 				}
-				newCommitID, err = git.GetFullCommitID(gitRepo.Path, result.newCommitID)
+				newCommitID, err = gitRepo.RevParse(result.newCommitID)
 				if err != nil {
-					log.Error("GetFullCommitID [%d]: %v", m.RepoID, err)
+					log.Error("Failed to parse revision [repo_id: %d, new_commit_id: %s]: %v", m.RepoID, result.newCommitID, err)
 					continue
 				}
-				commits, err = gitRepo.CommitsBetweenIDs(newCommitID, oldCommitID)
+				commits, err = gitRepo.RevList([]string{oldCommitID + "..." + newCommitID})
 				if err != nil {
-					log.Error("CommitsBetweenIDs [repo_id: %d, new_commit_id: %s, old_commit_id: %s]: %v", m.RepoID, newCommitID, oldCommitID, err)
+					log.Error("Failed to list commits [repo_id: %d, old_commit_id: %s, new_commit_id: %s]: %v", m.RepoID, oldCommitID, newCommitID, err)
 					continue
 				}
-			} else {
-				refNewCommitID, err := gitRepo.GetBranchCommitID(result.refName)
+
+			} else if gitRepo.HasBranch(result.refName) {
+				refNewCommit, err := gitRepo.BranchCommit(result.refName)
 				if err != nil {
-					log.Error("GetFullCommitID [%d]: %v", m.RepoID, err)
+					log.Error("Failed to get branch commit [repo_id: %d, branch: %s]: %v", m.RepoID, result.refName, err)
 					continue
 				}
-				if newCommit, err := gitRepo.GetCommit(refNewCommitID); err != nil {
-					log.Error("GetCommit [repo_id: %d, commit_id: %s]: %v", m.RepoID, refNewCommitID, err)
+
+				// TODO(unknwon): Get the commits for the new ref until the closest ancestor branch like GitHub does.
+				commits, err = refNewCommit.Ancestors(git.LogOptions{MaxCount: 9})
+				if err != nil {
+					log.Error("Failed to get ancestors [repo_id: %d, commit_id: %s]: %v", m.RepoID, refNewCommit.ID, err)
 					continue
-				} else {
-					// TODO: Get the commits for the new ref until the closest ancestor branch like Github does
-					commits, err = newCommit.CommitsBeforeLimit(10)
-					if err != nil {
-						log.Error("CommitsBeforeLimit [repo_id: %d, commit_id: %s]: %v", m.RepoID, refNewCommitID, err)
-					}
-					oldCommitID = git.EMPTY_SHA
-					newCommitID = refNewCommitID
 				}
+
+				// Put the latest commit in front of ancestors
+				commits = append([]*git.Commit{refNewCommit}, commits...)
+
+				oldCommitID = git.EmptyID
+				newCommitID = refNewCommit.ID.String()
 			}
+
 			if err = MirrorSyncPushAction(m.Repo, MirrorSyncPushActionOptions{
 				RefName:     result.refName,
 				OldCommitID: oldCommitID,
 				NewCommitID: newCommitID,
-				Commits:     ListToPushCommits(commits),
+				Commits:     CommitsToPushCommits(commits),
 			}); err != nil {
 				log.Error("MirrorSyncPushAction [repo_id: %d]: %v", m.RepoID, err)
 				continue
@@ -485,15 +434,15 @@ func SyncMirrors() {
 
 		// Get latest commit date and compare to current repository updated time,
 		// update if latest commit date is newer.
-		commitDate, err := git.GetLatestCommitDate(m.Repo.RepoPath(), "")
+		latestCommitTime, err := gitRepo.LatestCommitTime()
 		if err != nil {
 			log.Error("GetLatestCommitDate [%d]: %v", m.RepoID, err)
 			continue
-		} else if commitDate.Before(m.Repo.Updated) {
+		} else if !latestCommitTime.After(m.Repo.Updated) {
 			continue
 		}
 
-		if _, err = x.Exec("UPDATE repository SET updated_unix = ? WHERE id = ?", commitDate.Unix(), m.RepoID); err != nil {
+		if _, err = x.Exec("UPDATE repository SET updated_unix = ? WHERE id = ?", latestCommitTime.Unix(), m.RepoID); err != nil {
 			log.Error("Update 'repository.updated_unix' [%d]: %v", m.RepoID, err)
 			continue
 		}

+ 18 - 89
internal/db/mirror_test.go

@@ -7,102 +7,31 @@ package db
 import (
 	"testing"
 
-	. "github.com/smartystreets/goconvey/convey"
+	"github.com/stretchr/testify/assert"
 )
 
 func Test_parseRemoteUpdateOutput(t *testing.T) {
-	Convey("Parse mirror remote update output", t, func() {
-		testCases := []struct {
-			output  string
-			results []*mirrorSyncResult
-		}{
-			{
-				`
+	tests := []struct {
+		output     string
+		expResults []*mirrorSyncResult
+	}{
+		{
+			`
 From https://try.gogs.io/unknwon/upsteam
  * [new branch]      develop    -> develop
    b0bb24f..1d85a4f  master     -> master
  - [deleted]         (none)     -> bugfix
 `,
-				[]*mirrorSyncResult{
-					{"develop", GIT_SHORT_EMPTY_SHA, ""},
-					{"master", "b0bb24f", "1d85a4f"},
-					{"bugfix", "", GIT_SHORT_EMPTY_SHA},
-				},
+			[]*mirrorSyncResult{
+				{"develop", gitShortEmptyID, ""},
+				{"master", "b0bb24f", "1d85a4f"},
+				{"bugfix", "", gitShortEmptyID},
 			},
-		}
-
-		for _, tc := range testCases {
-			results := parseRemoteUpdateOutput(tc.output)
-			So(len(results), ShouldEqual, len(tc.results))
-
-			for i := range tc.results {
-				So(tc.results[i].refName, ShouldEqual, results[i].refName)
-				So(tc.results[i].oldCommitID, ShouldEqual, results[i].oldCommitID)
-				So(tc.results[i].newCommitID, ShouldEqual, results[i].newCommitID)
-			}
-		}
-	})
-}
-
-func Test_findPasswordInMirrorAddress(t *testing.T) {
-	Convey("Find password portion in mirror address", t, func() {
-		testCases := []struct {
-			addr       string
-			start, end int
-			found      bool
-			password   string
-		}{
-			{"http://localhost:3000/user/repo.git", -1, -1, false, ""},
-			{"http://user@localhost:3000/user/repo.git", -1, -1, false, ""},
-			{"http://user:@localhost:3000/user/repo.git", -1, -1, false, ""},
-			{"http://user:password@localhost:3000/user/repo.git", 12, 20, true, "password"},
-			{"http://username:my%3Asecure%3Bpassword@localhost:3000/user/repo.git", 16, 38, true, "my%3Asecure%3Bpassword"},
-			{"http://username:my%40secure%23password@localhost:3000/user/repo.git", 16, 38, true, "my%40secure%23password"},
-			{"http://username:@@localhost:3000/user/repo.git", 16, 17, true, "@"},
-		}
-
-		for _, tc := range testCases {
-			start, end, found := findPasswordInMirrorAddress(tc.addr)
-			So(start, ShouldEqual, tc.start)
-			So(end, ShouldEqual, tc.end)
-			So(found, ShouldEqual, tc.found)
-			if found {
-				So(tc.addr[start:end], ShouldEqual, tc.password)
-			}
-		}
-	})
-}
-
-func Test_unescapeMirrorCredentials(t *testing.T) {
-	Convey("Escape credentials in mirror address", t, func() {
-		testCases := []string{
-			"http://localhost:3000/user/repo.git", "http://localhost:3000/user/repo.git",
-			"http://user@localhost:3000/user/repo.git", "http://user@localhost:3000/user/repo.git",
-			"http://user:@localhost:3000/user/repo.git", "http://user:@localhost:3000/user/repo.git",
-			"http://user:password@localhost:3000/user/repo.git", "http://user:password@localhost:3000/user/repo.git",
-			"http://user:my%3Asecure%3Bpassword@localhost:3000/user/repo.git", "http://user:my:secure;password@localhost:3000/user/repo.git",
-			"http://user:my%40secure%23password@localhost:3000/user/repo.git", "http://user:my@secure#password@localhost:3000/user/repo.git",
-		}
-
-		for i := 0; i < len(testCases); i += 2 {
-			So(unescapeMirrorCredentials(testCases[i]), ShouldEqual, testCases[i+1])
-		}
-	})
-}
-
-func Test_escapeMirrorCredentials(t *testing.T) {
-	Convey("Escape credentials in mirror address", t, func() {
-		testCases := []string{
-			"http://localhost:3000/user/repo.git", "http://localhost:3000/user/repo.git",
-			"http://user@localhost:3000/user/repo.git", "http://user@localhost:3000/user/repo.git",
-			"http://user:@localhost:3000/user/repo.git", "http://user:@localhost:3000/user/repo.git",
-			"http://user:password@localhost:3000/user/repo.git", "http://user:password@localhost:3000/user/repo.git",
-			"http://user:my:secure;password@localhost:3000/user/repo.git", "http://user:my%3Asecure%3Bpassword@localhost:3000/user/repo.git",
-			"http://user:my@secure#password@localhost:3000/user/repo.git", "http://user:my%40secure%23password@localhost:3000/user/repo.git",
-		}
-
-		for i := 0; i < len(testCases); i += 2 {
-			So(escapeMirrorCredentials(testCases[i]), ShouldEqual, testCases[i+1])
-		}
-	})
+		},
+	}
+	for _, test := range tests {
+		t.Run("", func(t *testing.T) {
+			assert.Equal(t, test.expResults, parseRemoteUpdateOutput(test.output))
+		})
+	}
 }

+ 3 - 3
internal/db/models_gin.go

@@ -8,10 +8,10 @@ import (
 	"path/filepath"
 	"strings"
 
-	"github.com/G-Node/git-module"
 	"github.com/G-Node/gogs/internal/conf"
 	"github.com/G-Node/libgin/libgin"
 	"github.com/G-Node/libgin/libgin/annex"
+	"github.com/gogs/git-module"
 	log "gopkg.in/clog.v1"
 )
 
@@ -150,9 +150,9 @@ func annexSync(path string) error {
 func annexAdd(repoPath string, all bool, files ...string) error {
 	cmd := git.NewCommand("annex", "add")
 	if all {
-		cmd.AddArguments(".")
+		cmd.AddArgs(".")
 	}
-	_, err := cmd.AddArguments(files...).RunInDir(repoPath)
+	_, err := cmd.AddArgs(files...).RunInDir(repoPath)
 	return err
 }
 

+ 2 - 2
internal/db/org_team.go

@@ -275,7 +275,7 @@ func getTeamOfOrgByName(e Engine, orgID int64, name string) (*Team, error) {
 	if err != nil {
 		return nil, err
 	} else if !has {
-		return nil, errors.TeamNotExist{0, name}
+		return nil, errors.TeamNotExist{Name: name}
 	}
 	return t, nil
 }
@@ -291,7 +291,7 @@ func getTeamByID(e Engine, teamID int64) (*Team, error) {
 	if err != nil {
 		return nil, err
 	} else if !has {
-		return nil, errors.TeamNotExist{teamID, ""}
+		return nil, errors.TeamNotExist{TeamID: teamID}
 	}
 	return t, nil
 }

+ 59 - 44
internal/db/pull.go

@@ -7,7 +7,6 @@ package db
 import (
 	"fmt"
 	"os"
-	"path"
 	"path/filepath"
 	"strings"
 	"time"
@@ -16,7 +15,7 @@ import (
 	log "unknwon.dev/clog/v2"
 	"xorm.io/xorm"
 
-	"github.com/G-Node/git-module"
+	"github.com/gogs/git-module"
 	api "github.com/gogs/go-gogs-client"
 
 	"github.com/G-Node/gogs/internal/conf"
@@ -212,9 +211,9 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository, mergeStyle
 	}
 
 	headRepoPath := RepoPath(pr.HeadUserName, pr.HeadRepo.Name)
-	headGitRepo, err := git.OpenRepository(headRepoPath)
+	headGitRepo, err := git.Open(headRepoPath)
 	if err != nil {
-		return fmt.Errorf("OpenRepository: %v", err)
+		return fmt.Errorf("open repository: %v", err)
 	}
 
 	// Create temporary directory to store temporary copy of the base repository,
@@ -228,7 +227,7 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository, mergeStyle
 	var stderr string
 	if _, stderr, err = process.ExecTimeout(5*time.Minute,
 		fmt.Sprintf("PullRequest.Merge (git clone): %s", tmpBasePath),
-		"git", "clone", "-b", pr.BaseBranch, baseGitRepo.Path, tmpBasePath); err != nil {
+		"git", "clone", "-b", pr.BaseBranch, baseGitRepo.Path(), tmpBasePath); err != nil {
 		return fmt.Errorf("git clone: %s", stderr)
 	}
 
@@ -311,13 +310,13 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository, mergeStyle
 	// Push changes on base branch to upstream.
 	if _, stderr, err = process.ExecDir(-1, tmpBasePath,
 		fmt.Sprintf("PullRequest.Merge (git push): %s", tmpBasePath),
-		"git", "push", baseGitRepo.Path, pr.BaseBranch); err != nil {
+		"git", "push", baseGitRepo.Path(), pr.BaseBranch); err != nil {
 		return fmt.Errorf("git push: %s", stderr)
 	}
 
-	pr.MergedCommitID, err = headGitRepo.GetBranchCommitID(pr.HeadBranch)
+	pr.MergedCommitID, err = headGitRepo.BranchCommitID(pr.HeadBranch)
 	if err != nil {
-		return fmt.Errorf("GetBranchCommit: %v", err)
+		return fmt.Errorf("get head branch %q commit ID: %v", pr.HeadBranch, err)
 	}
 
 	pr.HasMerged = true
@@ -351,42 +350,42 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository, mergeStyle
 		return nil
 	}
 
-	l, err := headGitRepo.CommitsBetweenIDs(pr.MergedCommitID, pr.MergeBase)
+	commits, err := headGitRepo.RevList([]string{pr.MergeBase + "..." + pr.MergedCommitID})
 	if err != nil {
-		log.Error("CommitsBetweenIDs: %v", err)
+		log.Error("Failed to list commits [merge_base: %s, merged_commit_id: %s]: %v", pr.MergeBase, pr.MergedCommitID, err)
 		return nil
 	}
 
-	// It is possible that head branch is not fully sync with base branch for merge commits,
-	// so we need to get latest head commit and append merge commit manully
-	// to avoid strange diff commits produced.
-	mergeCommit, err := baseGitRepo.GetBranchCommit(pr.BaseBranch)
+	// NOTE: It is possible that head branch is not fully sync with base branch
+	// for merge commits, so we need to get latest head commit and append merge
+	// commit manully to avoid strange diff commits produced.
+	mergeCommit, err := baseGitRepo.BranchCommit(pr.BaseBranch)
 	if err != nil {
-		log.Error("GetBranchCommit: %v", err)
+		log.Error("Failed to get base branch %q commit: %v", pr.BaseBranch, err)
 		return nil
 	}
 	if mergeStyle == MERGE_STYLE_REGULAR {
-		l.PushFront(mergeCommit)
+		commits = append([]*git.Commit{mergeCommit}, commits...)
 	}
 
-	commits, err := ListToPushCommits(l).ToApiPayloadCommits(pr.BaseRepo.RepoPath(), pr.BaseRepo.HTMLURL())
+	pcs, err := CommitsToPushCommits(commits).ToApiPayloadCommits(pr.BaseRepo.RepoPath(), pr.BaseRepo.HTMLURL())
 	if err != nil {
-		log.Error("ToApiPayloadCommits: %v", err)
+		log.Error("Failed to convert to API payload commits: %v", err)
 		return nil
 	}
 
 	p := &api.PushPayload{
-		Ref:        git.BRANCH_PREFIX + pr.BaseBranch,
+		Ref:        git.RefsHeads + pr.BaseBranch,
 		Before:     pr.MergeBase,
 		After:      mergeCommit.ID.String(),
 		CompareURL: conf.Server.ExternalURL + pr.BaseRepo.ComposeCompareURL(pr.MergeBase, pr.MergedCommitID),
-		Commits:    commits,
+		Commits:    pcs,
 		Repo:       pr.BaseRepo.APIFormat(nil),
 		Pusher:     pr.HeadRepo.MustOwner().APIFormat(),
 		Sender:     doer.APIFormat(),
 	}
 	if err = PrepareWebhooks(pr.BaseRepo, HOOK_EVENT_PUSH, p); err != nil {
-		log.Error("PrepareWebhooks: %v", err)
+		log.Error("Failed to prepare webhooks: %v", err)
 		return nil
 	}
 	return nil
@@ -599,36 +598,42 @@ func (pr *PullRequest) UpdatePatch() (err error) {
 		return nil
 	}
 
-	headGitRepo, err := git.OpenRepository(pr.HeadRepo.RepoPath())
+	headGitRepo, err := git.Open(pr.HeadRepo.RepoPath())
 	if err != nil {
-		return fmt.Errorf("OpenRepository: %v", err)
+		return fmt.Errorf("open repository: %v", err)
 	}
 
 	// Add a temporary remote.
 	tmpRemote := com.ToStr(time.Now().UnixNano())
-	if err = headGitRepo.AddRemote(tmpRemote, RepoPath(pr.BaseRepo.MustOwner().Name, pr.BaseRepo.Name), true); err != nil {
-		return fmt.Errorf("AddRemote: %v", err)
+	baseRepoPath := RepoPath(pr.BaseRepo.MustOwner().Name, pr.BaseRepo.Name)
+	err = headGitRepo.AddRemote(tmpRemote, baseRepoPath, git.AddRemoteOptions{Fetch: true})
+	if err != nil {
+		return fmt.Errorf("add remote %q [repo_id: %d]: %v", tmpRemote, pr.HeadRepoID, err)
 	}
 	defer func() {
-		headGitRepo.RemoveRemote(tmpRemote)
+		if err := headGitRepo.RemoveRemote(tmpRemote); err != nil {
+			log.Error("Failed to remove remote %q [repo_id: %d]: %v", tmpRemote, pr.HeadRepoID, err)
+		}
 	}()
+
 	remoteBranch := "remotes/" + tmpRemote + "/" + pr.BaseBranch
-	pr.MergeBase, err = headGitRepo.GetMergeBase(remoteBranch, pr.HeadBranch)
+	pr.MergeBase, err = headGitRepo.MergeBase(remoteBranch, pr.HeadBranch)
 	if err != nil {
-		return fmt.Errorf("GetMergeBase: %v", err)
+		return fmt.Errorf("get merge base: %v", err)
 	} else if err = pr.Update(); err != nil {
-		return fmt.Errorf("Update: %v", err)
+		return fmt.Errorf("update: %v", err)
 	}
 
-	patch, err := headGitRepo.GetPatch(pr.MergeBase, pr.HeadBranch)
+	patch, err := headGitRepo.DiffBinary(pr.MergeBase, pr.HeadBranch)
 	if err != nil {
-		return fmt.Errorf("GetPatch: %v", err)
+		return fmt.Errorf("get binary patch: %v", err)
 	}
 
 	if err = pr.BaseRepo.SavePatch(pr.Index, patch); err != nil {
-		return fmt.Errorf("BaseRepo.SavePatch: %v", err)
+		return fmt.Errorf("save patch: %v", err)
 	}
 
+	log.Trace("PullRequest[%d].UpdatePatch: patch saved", pr.ID)
 	return nil
 }
 
@@ -639,25 +644,35 @@ func (pr *PullRequest) PushToBaseRepo() (err error) {
 	log.Trace("PushToBaseRepo[%d]: pushing commits to base repo 'refs/pull/%d/head'", pr.BaseRepoID, pr.Index)
 
 	headRepoPath := pr.HeadRepo.RepoPath()
-	headGitRepo, err := git.OpenRepository(headRepoPath)
+	headGitRepo, err := git.Open(headRepoPath)
 	if err != nil {
-		return fmt.Errorf("OpenRepository: %v", err)
+		return fmt.Errorf("open repository: %v", err)
 	}
 
-	tmpRemoteName := fmt.Sprintf("tmp-pull-%d", pr.ID)
-	if err = headGitRepo.AddRemote(tmpRemoteName, pr.BaseRepo.RepoPath(), false); err != nil {
-		return fmt.Errorf("headGitRepo.AddRemote: %v", err)
+	tmpRemote := fmt.Sprintf("tmp-pull-%d", pr.ID)
+	if err = headGitRepo.AddRemote(tmpRemote, pr.BaseRepo.RepoPath()); err != nil {
+		return fmt.Errorf("add remote %q [repo_id: %d]: %v", tmpRemote, pr.HeadRepoID, err)
 	}
-	// Make sure to remove the remote even if the push fails
-	defer headGitRepo.RemoveRemote(tmpRemoteName)
 
-	headFile := fmt.Sprintf("refs/pull/%d/head", pr.Index)
+	// Make sure to remove the remote even if the push fails
+	defer func() {
+		if err := headGitRepo.RemoveRemote(tmpRemote); err != nil {
+			log.Error("Failed to remove remote %q [repo_id: %d]: %v", tmpRemote, pr.HeadRepoID, err)
+		}
+	}()
 
-	// Remove head in case there is a conflict.
-	os.Remove(path.Join(pr.BaseRepo.RepoPath(), headFile))
+	headRefspec := fmt.Sprintf("refs/pull/%d/head", pr.Index)
+	headFile := filepath.Join(pr.BaseRepo.RepoPath(), headRefspec)
+	if osutil.IsExist(headFile) {
+		err = os.Remove(headFile)
+		if err != nil {
+			return fmt.Errorf("remove head file [repo_id: %d]: %v", pr.BaseRepoID, err)
+		}
+	}
 
-	if err = git.Push(headRepoPath, tmpRemoteName, fmt.Sprintf("%s:%s", pr.HeadBranch, headFile)); err != nil {
-		return fmt.Errorf("Push: %v", err)
+	err = headGitRepo.Push(tmpRemote, fmt.Sprintf("%s:%s", pr.HeadBranch, headRefspec))
+	if err != nil {
+		return fmt.Errorf("push: %v", err)
 	}
 
 	return nil

+ 7 - 7
internal/db/release.go

@@ -13,7 +13,7 @@ import (
 	log "unknwon.dev/clog/v2"
 	"xorm.io/xorm"
 
-	"github.com/G-Node/git-module"
+	"github.com/gogs/git-module"
 	api "github.com/gogs/go-gogs-client"
 
 	"github.com/G-Node/gogs/internal/db/errors"
@@ -119,10 +119,10 @@ func IsReleaseExist(repoID int64, tagName string) (bool, error) {
 func createTag(gitRepo *git.Repository, r *Release) error {
 	// Only actual create when publish.
 	if !r.IsDraft {
-		if !gitRepo.IsTagExist(r.TagName) {
-			commit, err := gitRepo.GetBranchCommit(r.Target)
+		if !gitRepo.HasTag(r.TagName) {
+			commit, err := gitRepo.BranchCommit(r.Target)
 			if err != nil {
-				return fmt.Errorf("GetBranchCommit: %v", err)
+				return fmt.Errorf("get branch commit: %v", err)
 			}
 
 			// Trim '--' prefix to prevent command line argument vulnerability.
@@ -134,15 +134,15 @@ func createTag(gitRepo *git.Repository, r *Release) error {
 				return err
 			}
 		} else {
-			commit, err := gitRepo.GetTagCommit(r.TagName)
+			commit, err := gitRepo.TagCommit(r.TagName)
 			if err != nil {
-				return fmt.Errorf("GetTagCommit: %v", err)
+				return fmt.Errorf("get tag commit: %v", err)
 			}
 
 			r.Sha1 = commit.ID.String()
 			r.NumCommits, err = commit.CommitsCount()
 			if err != nil {
-				return fmt.Errorf("CommitsCount: %v", err)
+				return fmt.Errorf("count commits: %v", err)
 			}
 		}
 	}

+ 70 - 65
internal/db/repo.go

@@ -27,7 +27,7 @@ import (
 	log "unknwon.dev/clog/v2"
 	"xorm.io/xorm"
 
-	git "github.com/G-Node/git-module"
+	"github.com/gogs/git-module"
 	api "github.com/gogs/go-gogs-client"
 
 	"github.com/G-Node/gogs/internal/avatar"
@@ -119,9 +119,6 @@ func NewRepoContext() {
 	if version.Compare("1.8.3", conf.Git.Version, ">") {
 		log.Fatal("Gogs requires Git version greater or equal to 1.8.3")
 	}
-	git.HookDir = "custom_hooks"
-	git.HookSampleDir = "hooks"
-	git.DefaultCommitsPageSize = conf.UI.User.CommitsPagingNum
 
 	// Git requires setting user.name and user.email in order to commit changes.
 	for configKey, defaultValue := range map[string]string{"user.name": "Gogs", "user.email": "gogs@fake.local"} {
@@ -421,9 +418,9 @@ func (repo *Repository) mustOwner(e Engine) *User {
 }
 
 func (repo *Repository) UpdateSize() error {
-	countObject, err := git.GetRepoSize(repo.RepoPath())
+	countObject, err := git.RepoCountObjects(repo.RepoPath())
 	if err != nil {
-		return fmt.Errorf("GetRepoSize: %v", err)
+		return fmt.Errorf("count repository objects: %v", err)
 	}
 
 	repo.Size = countObject.Size + countObject.SizePack
@@ -603,33 +600,41 @@ func (repo *Repository) LocalCopyPath() string {
 // assume subsequent operations are against target branch when caller has confidence
 // about no race condition.
 func UpdateLocalCopyBranch(repoPath, localPath, branch string, isWiki bool) (err error) {
-	if !com.IsExist(localPath) {
+	if !osutil.IsExist(localPath) {
 		// Checkout to a specific branch fails when wiki is an empty repository.
 		if isWiki {
 			branch = ""
 		}
-		if err = git.Clone(repoPath, localPath, git.CloneRepoOptions{
-			Timeout: time.Duration(conf.Git.Timeout.Clone) * time.Second,
+		if err = git.Clone(repoPath, localPath, git.CloneOptions{
 			Branch:  branch,
+			Timeout: time.Duration(conf.Git.Timeout.Clone) * time.Second,
 		}); err != nil {
-			return fmt.Errorf("git clone %s: %v", branch, err)
-		}
-	} else {
-		if err = git.Fetch(localPath, git.FetchRemoteOptions{
-			Prune: true,
-		}); err != nil {
-			return fmt.Errorf("git fetch: %v", err)
-		}
-		if err = git.Checkout(localPath, git.CheckoutOptions{
-			Branch: branch,
-		}); err != nil {
-			return fmt.Errorf("git checkout %s: %v", branch, err)
+			return fmt.Errorf("git clone [branch: %s]: %v", branch, err)
 		}
+		return nil
+	}
 
-		// Reset to align with remote in case of force push.
-		if err = git.ResetHEAD(localPath, true, "origin/"+branch); err != nil {
-			return fmt.Errorf("git reset --hard origin/%s: %v", branch, err)
-		}
+	gitRepo, err := git.Open(localPath)
+	if err != nil {
+		return fmt.Errorf("open repository: %v", err)
+	}
+
+	if err = gitRepo.Fetch(git.FetchOptions{
+		Prune: true,
+	}); err != nil {
+		return fmt.Errorf("fetch: %v", err)
+	}
+
+	if err = gitRepo.Checkout(branch); err != nil {
+		return fmt.Errorf("checkout [branch: %s]: %v", branch, err)
+	}
+
+	// Reset to align with remote in case of force push.
+	rev := "origin/" + branch
+	if err = gitRepo.Reset(rev, git.ResetOptions{
+		Hard: true,
+	}); err != nil {
+		return fmt.Errorf("reset [revision: %s]: %v", rev, err)
 	}
 	return nil
 }
@@ -732,9 +737,7 @@ func wikiRemoteURL(remote string) string {
 	remote = strings.TrimSuffix(remote, ".git")
 	for _, suffix := range commonWikiURLSuffixes {
 		wikiURL := remote + suffix
-		if git.IsRepoURLAccessible(git.NetworkOptions{
-			URL: wikiURL,
-		}) {
+		if git.IsURLAccessible(time.Minute, wikiURL) {
 			return wikiURL
 		}
 	}
@@ -769,23 +772,23 @@ func MigrateRepository(doer, owner *User, opts MigrateRepoOptions) (*Repository,
 	migrateTimeout := time.Duration(conf.Git.Timeout.Migrate) * time.Second
 
 	RemoveAllWithNotice("Repository path erase before creation", repoPath)
-	if err = git.Clone(opts.RemoteAddr, repoPath, git.CloneRepoOptions{
+	if err = git.Clone(opts.RemoteAddr, repoPath, git.CloneOptions{
 		Mirror:  true,
 		Quiet:   true,
 		Timeout: migrateTimeout,
 	}); err != nil {
-		return repo, fmt.Errorf("Clone: %v", err)
+		return repo, fmt.Errorf("clone: %v", err)
 	}
 
 	wikiRemotePath := wikiRemoteURL(opts.RemoteAddr)
 	if len(wikiRemotePath) > 0 {
 		RemoveAllWithNotice("Repository wiki path erase before creation", wikiPath)
-		if err = git.Clone(wikiRemotePath, wikiPath, git.CloneRepoOptions{
+		if err = git.Clone(wikiRemotePath, wikiPath, git.CloneOptions{
 			Mirror:  true,
 			Quiet:   true,
 			Timeout: migrateTimeout,
 		}); err != nil {
-			log.Trace("Failed to clone wiki: %v", err)
+			log.Error("Failed to clone wiki: %v", err)
 			RemoveAllWithNotice("Delete repository wiki for initialization failure", wikiPath)
 		}
 	}
@@ -802,17 +805,15 @@ func MigrateRepository(doer, owner *User, opts MigrateRepoOptions) (*Repository,
 
 	if !repo.IsBare {
 		// Try to get HEAD branch and set it as default branch.
-		gitRepo, err := git.OpenRepository(repoPath)
+		gitRepo, err := git.Open(repoPath)
 		if err != nil {
-			return repo, fmt.Errorf("OpenRepository: %v", err)
+			return repo, fmt.Errorf("open repository: %v", err)
 		}
-		headBranch, err := gitRepo.GetHEADBranch()
+		refspec, err := gitRepo.SymbolicRef()
 		if err != nil {
-			return repo, fmt.Errorf("GetHEADBranch: %v", err)
-		}
-		if headBranch != nil {
-			repo.DefaultBranch = headBranch.Name
+			return repo, fmt.Errorf("get HEAD branch: %v", err)
 		}
+		repo.DefaultBranch = git.RefShortName(refspec)
 
 		if err = repo.UpdateSize(); err != nil {
 			log.Error("UpdateSize [repo_id: %d]: %v", repo.ID, err)
@@ -850,15 +851,15 @@ func cleanUpMigrateGitConfig(configPath string) error {
 	return nil
 }
 
-var hooksTpls = map[string]string{
+var hooksTpls = map[git.HookName]string{
 	"pre-receive":  "#!/usr/bin/env %s\n\"%s\" hook --config='%s' pre-receive\n",
 	"update":       "#!/usr/bin/env %s\n\"%s\" hook --config='%s' update $1 $2 $3\n",
 	"post-receive": "#!/usr/bin/env %s\n\"%s\" hook --config='%s' post-receive\n",
 }
 
 func createDelegateHooks(repoPath string) (err error) {
-	for _, name := range git.HookNames {
-		hookPath := filepath.Join(repoPath, "hooks", name)
+	for _, name := range git.ServerSideHooks {
+		hookPath := filepath.Join(repoPath, "hooks", string(name))
 		if err = ioutil.WriteFile(hookPath,
 			[]byte(fmt.Sprintf(hooksTpls[name], conf.Repository.ScriptType, conf.AppPath(), conf.CustomConf)),
 			os.ModePerm); err != nil {
@@ -1008,8 +1009,8 @@ func initRepository(e Engine, repoPath string, doer *User, repo *Repository, opt
 	}
 
 	// Init bare new repository.
-	if err = git.InitRepository(repoPath, true); err != nil {
-		return fmt.Errorf("InitRepository: %v", err)
+	if err = git.Init(repoPath, git.InitOptions{Bare: true}); err != nil {
+		return fmt.Errorf("init repository: %v", err)
 	} else if err = createDelegateHooks(repoPath); err != nil {
 		return fmt.Errorf("createDelegateHooks: %v", err)
 	}
@@ -1109,7 +1110,7 @@ func createRepository(e *xorm.Session, doer, owner *User, repo *Repository) (err
 // CreateRepository creates a repository for given user or organization.
 func CreateRepository(doer, owner *User, opts CreateRepoOptions) (_ *Repository, err error) {
 	if !owner.CanCreateRepo() {
-		return nil, errors.ReachLimitOfRepo{owner.RepoCreationNum()}
+		return nil, errors.ReachLimitOfRepo{Limit: owner.RepoCreationNum()}
 	}
 
 	repo := &Repository{
@@ -1489,7 +1490,7 @@ func DeleteRepository(uid, repoID int64) error {
 	if err != nil {
 		return err
 	} else if !has {
-		return errors.RepoNotExist{repoID, uid, ""}
+		return errors.RepoNotExist{ID: repoID, UserID: uid}
 	}
 
 	// In case is a organization.
@@ -1606,7 +1607,7 @@ func DeleteRepository(uid, repoID int64) error {
 func GetRepositoryByRef(ref string) (*Repository, error) {
 	n := strings.IndexByte(ref, byte('/'))
 	if n < 2 {
-		return nil, errors.InvalidRepoReference{ref}
+		return nil, errors.InvalidRepoReference{Ref: ref}
 	}
 
 	userName, repoName := ref[:n], ref[n+1:]
@@ -1628,7 +1629,7 @@ func GetRepositoryByName(ownerID int64, name string) (*Repository, error) {
 	if err != nil {
 		return nil, err
 	} else if !has {
-		return nil, errors.RepoNotExist{0, ownerID, name}
+		return nil, errors.RepoNotExist{UserID: ownerID, Name: name}
 	}
 	return repo, repo.LoadAttributes()
 }
@@ -1639,7 +1640,7 @@ func getRepositoryByID(e Engine, id int64) (*Repository, error) {
 	if err != nil {
 		return nil, err
 	} else if !has {
-		return nil, errors.RepoNotExist{id, 0, ""}
+		return nil, errors.RepoNotExist{ID: id}
 	}
 	return repo, repo.loadAttributes(e)
 }
@@ -1883,9 +1884,9 @@ func ReinitMissingRepositories() error {
 
 	for _, repo := range repos {
 		log.Trace("Initializing %d/%d...", repo.OwnerID, repo.ID)
-		if err := git.InitRepository(repo.RepoPath(), true); err != nil {
-			if err2 := CreateRepositoryNotice(fmt.Sprintf("InitRepository [%d]: %v", repo.ID, err)); err2 != nil {
-				return fmt.Errorf("CreateRepositoryNotice: %v", err)
+		if err := git.Init(repo.RepoPath(), git.InitOptions{Bare: true}); err != nil {
+			if err2 := CreateRepositoryNotice(fmt.Sprintf("init repository [repo_id: %d]: %v", repo.ID, err)); err2 != nil {
+				return fmt.Errorf("create repository notice: %v", err)
 			}
 		}
 	}
@@ -1933,7 +1934,11 @@ func GitFsck() {
 		func(idx int, bean interface{}) error {
 			repo := bean.(*Repository)
 			repoPath := repo.RepoPath()
-			if err := git.Fsck(repoPath, conf.Cron.RepoHealthCheck.Timeout, conf.Cron.RepoHealthCheck.Args...); err != nil {
+			err := git.RepoFsck(repoPath, git.FsckOptions{
+				Args:    conf.Cron.RepoHealthCheck.Args,
+				Timeout: conf.Cron.RepoHealthCheck.Timeout,
+			})
+			if err != nil {
 				desc := fmt.Sprintf("Failed to perform health check on repository '%s': %v", repoPath, err)
 				log.Warn(desc)
 				if err = CreateRepositoryNotice(desc); err != nil {
@@ -2359,7 +2364,7 @@ func HasForkedRepo(ownerID, repoID int64) (*Repository, bool, error) {
 // ForkRepository creates a fork of target repository under another user domain.
 func ForkRepository(doer, owner *User, baseRepo *Repository, name, desc string) (_ *Repository, err error) {
 	if !owner.CanCreateRepo() {
-		return nil, errors.ReachLimitOfRepo{owner.RepoCreationNum()}
+		return nil, errors.ReachLimitOfRepo{Limit: owner.RepoCreationNum()}
 	}
 
 	repo := &Repository{
@@ -2393,14 +2398,14 @@ func ForkRepository(doer, owner *User, baseRepo *Repository, name, desc string)
 		fmt.Sprintf("ForkRepository 'git clone': %s/%s", owner.Name, repo.Name),
 		"git", "clone", "--bare", baseRepo.RepoPath(), repoPath)
 	if err != nil {
-		return nil, fmt.Errorf("git clone: %v", stderr)
+		return nil, fmt.Errorf("git clone: %v - %s", err, stderr)
 	}
 
 	_, stderr, err = process.ExecDir(-1,
 		repoPath, fmt.Sprintf("ForkRepository 'git update-server-info': %s", repoPath),
 		"git", "update-server-info")
 	if err != nil {
-		return nil, fmt.Errorf("git update-server-info: %v", err)
+		return nil, fmt.Errorf("git update-server-info: %v - %s", err, stderr)
 	}
 
 	if err = createDelegateHooks(repoPath); err != nil {
@@ -2444,24 +2449,24 @@ func (repo *Repository) GetForks() ([]*Repository, error) {
 //         \/             \/     \/     \/     \/
 //
 
-func (repo *Repository) CreateNewBranch(doer *User, oldBranchName, branchName string) (err error) {
+func (repo *Repository) CreateNewBranch(oldBranch, newBranch string) (err error) {
 	repoWorkingPool.CheckIn(com.ToStr(repo.ID))
 	defer repoWorkingPool.CheckOut(com.ToStr(repo.ID))
 
 	localPath := repo.LocalCopyPath()
 
-	if err = discardLocalRepoBranchChanges(localPath, oldBranchName); err != nil {
-		return fmt.Errorf("discardLocalRepoChanges: %v", err)
-	} else if err = repo.UpdateLocalCopyBranch(oldBranchName); err != nil {
-		return fmt.Errorf("UpdateLocalCopyBranch: %v", err)
+	if err = discardLocalRepoBranchChanges(localPath, oldBranch); err != nil {
+		return fmt.Errorf("discard changes in local copy [path: %s, branch: %s]: %v", localPath, oldBranch, err)
+	} else if err = repo.UpdateLocalCopyBranch(oldBranch); err != nil {
+		return fmt.Errorf("update branch for local copy [path: %s, branch: %s]: %v", localPath, oldBranch, err)
 	}
 
-	if err = repo.CheckoutNewBranch(oldBranchName, branchName); err != nil {
-		return fmt.Errorf("CreateNewBranch: %v", err)
+	if err = repo.CheckoutNewBranch(oldBranch, newBranch); err != nil {
+		return fmt.Errorf("create new branch [base: %s, new: %s]: %v", oldBranch, newBranch, err)
 	}
 
-	if err = git.Push(localPath, "origin", branchName); err != nil {
-		return fmt.Errorf("Push: %v", err)
+	if err = git.RepoPush(localPath, "origin", newBranch); err != nil {
+		return fmt.Errorf("push [branch: %s]: %v", newBranch, err)
 	}
 
 	return nil

+ 16 - 16
internal/db/repo_branch.go

@@ -8,7 +8,7 @@ import (
 	"fmt"
 	"strings"
 
-	"github.com/G-Node/git-module"
+	"github.com/gogs/git-module"
 	"github.com/unknwon/com"
 
 	"github.com/G-Node/gogs/internal/db/errors"
@@ -24,33 +24,33 @@ type Branch struct {
 }
 
 func GetBranchesByPath(path string) ([]*Branch, error) {
-	gitRepo, err := git.OpenRepository(path)
+	gitRepo, err := git.Open(path)
 	if err != nil {
-		return nil, err
+		return nil, fmt.Errorf("open repository: %v", err)
 	}
 
-	brs, err := gitRepo.GetBranches()
+	names, err := gitRepo.Branches()
 	if err != nil {
-		return nil, err
+		return nil, fmt.Errorf("list branches")
 	}
 
-	branches := make([]*Branch, len(brs))
-	for i := range brs {
+	branches := make([]*Branch, len(names))
+	for i := range names {
 		branches[i] = &Branch{
 			RepoPath: path,
-			Name:     brs[i],
+			Name:     names[i],
 		}
 	}
 	return branches, nil
 }
 
-func (repo *Repository) GetBranch(br string) (*Branch, error) {
-	if !git.IsBranchExist(repo.RepoPath(), br) {
-		return nil, errors.ErrBranchNotExist{br}
+func (repo *Repository) GetBranch(name string) (*Branch, error) {
+	if !git.RepoHasBranch(repo.RepoPath(), name) {
+		return nil, errors.ErrBranchNotExist{Name: name}
 	}
 	return &Branch{
 		RepoPath: repo.RepoPath(),
-		Name:     br,
+		Name:     name,
 	}, nil
 }
 
@@ -59,11 +59,11 @@ func (repo *Repository) GetBranches() ([]*Branch, error) {
 }
 
 func (br *Branch) GetCommit() (*git.Commit, error) {
-	gitRepo, err := git.OpenRepository(br.RepoPath)
+	gitRepo, err := git.Open(br.RepoPath)
 	if err != nil {
-		return nil, err
+		return nil, fmt.Errorf("open repository: %v", err)
 	}
-	return gitRepo.GetBranchCommit(br.Name)
+	return gitRepo.BranchCommit(br.Name)
 }
 
 type ProtectBranchWhitelist struct {
@@ -102,7 +102,7 @@ func GetProtectBranchOfRepoByName(repoID int64, name string) (*ProtectBranch, er
 	if err != nil {
 		return nil, err
 	} else if !has {
-		return nil, errors.ErrBranchNotExist{name}
+		return nil, errors.ErrBranchNotExist{Name: name}
 	}
 	return protectBranch, nil
 }

+ 61 - 67
internal/db/repo_editor.go

@@ -19,10 +19,11 @@ import (
 	gouuid "github.com/satori/go.uuid"
 	"github.com/unknwon/com"
 
-	git "github.com/G-Node/git-module"
+	"github.com/gogs/git-module"
 
 	"github.com/G-Node/gogs/internal/conf"
 	"github.com/G-Node/gogs/internal/db/errors"
+	"github.com/G-Node/gogs/internal/gitutil"
 	"github.com/G-Node/gogs/internal/osutil"
 	"github.com/G-Node/gogs/internal/process"
 	"github.com/G-Node/gogs/internal/tool"
@@ -58,7 +59,7 @@ func ComposeHookEnvs(opts ComposeHookEnvsOptions) []string {
 		ENV_REPO_OWNER_SALT_MD5 + "=" + tool.MD5(opts.OwnerSalt),
 		ENV_REPO_ID + "=" + com.ToStr(opts.RepoID),
 		ENV_REPO_NAME + "=" + opts.RepoName,
-		ENV_REPO_CUSTOM_HOOKS_PATH + "=" + path.Join(opts.RepoPath, "custom_hooks"),
+		ENV_REPO_CUSTOM_HOOKS_PATH + "=" + filepath.Join(opts.RepoPath, "custom_hooks"),
 	}
 	return envs
 }
@@ -76,14 +77,15 @@ func discardLocalRepoBranchChanges(localPath, branch string) error {
 	if !com.IsExist(localPath) {
 		return nil
 	}
+
 	// No need to check if nothing in the repository.
-	if !git.IsBranchExist(localPath, branch) {
+	if !git.RepoHasBranch(localPath, branch) {
 		return nil
 	}
 
-	refName := "origin/" + branch
-	if err := git.ResetHEAD(localPath, true, refName); err != nil {
-		return fmt.Errorf("git reset --hard %s: %v", refName, err)
+	rev := "origin/" + branch
+	if err := git.RepoReset(localPath, rev, git.ResetOptions{Hard: true}); err != nil {
+		return fmt.Errorf("reset [revision: %s]: %v", rev, err)
 	}
 	return nil
 }
@@ -92,22 +94,17 @@ func (repo *Repository) DiscardLocalRepoBranchChanges(branch string) error {
 	return discardLocalRepoBranchChanges(repo.LocalCopyPath(), branch)
 }
 
-// checkoutNewBranch checks out to a new branch from the a branch name.
-func checkoutNewBranch(repoPath, localPath, oldBranch, newBranch string) error {
-	if err := git.Checkout(localPath, git.CheckoutOptions{
-		Timeout:   time.Duration(conf.Git.Timeout.Pull) * time.Second,
-		Branch:    newBranch,
-		OldBranch: oldBranch,
+// CheckoutNewBranch checks out to a new branch from the a branch name.
+func (repo *Repository) CheckoutNewBranch(oldBranch, newBranch string) error {
+	if err := git.RepoCheckout(repo.LocalCopyPath(), newBranch, git.CheckoutOptions{
+		BaseBranch: oldBranch,
+		Timeout:    time.Duration(conf.Git.Timeout.Pull) * time.Second,
 	}); err != nil {
-		return fmt.Errorf("git checkout -b %s %s: %v", newBranch, oldBranch, err)
+		return fmt.Errorf("checkout [base: %s, new: %s]: %v", oldBranch, newBranch, err)
 	}
 	return nil
 }
 
-func (repo *Repository) CheckoutNewBranch(oldBranch, newBranch string) error {
-	return checkoutNewBranch(repo.RepoPath(), repo.LocalCopyPath(), oldBranch, newBranch)
-}
-
 type UpdateRepoFileOptions struct {
 	LastCommitID string
 	OldBranch    string
@@ -135,16 +132,16 @@ func (repo *Repository) UpdateRepoFile(doer *User, opts UpdateRepoFileOptions) (
 
 	if opts.OldBranch != opts.NewBranch {
 		// Directly return error if new branch already exists in the server
-		if git.IsBranchExist(repoPath, opts.NewBranch) {
-			return errors.BranchAlreadyExists{opts.NewBranch}
+		if git.RepoHasBranch(repoPath, opts.NewBranch) {
+			return errors.BranchAlreadyExists{Name: opts.NewBranch}
 		}
 
 		// Otherwise, delete branch from local copy in case out of sync
-		if git.IsBranchExist(localPath, opts.NewBranch) {
-			if err = git.DeleteBranch(localPath, opts.NewBranch, git.DeleteBranchOptions{
+		if git.RepoHasBranch(localPath, opts.NewBranch) {
+			if err = git.RepoDeleteBranch(localPath, opts.NewBranch, git.DeleteBranchOptions{
 				Force: true,
 			}); err != nil {
-				return fmt.Errorf("delete branch[%s]: %v", opts.NewBranch, err)
+				return fmt.Errorf("delete branch %q: %v", opts.NewBranch, err)
 			}
 		}
 
@@ -167,7 +164,7 @@ func (repo *Repository) UpdateRepoFile(doer *User, opts UpdateRepoFileOptions) (
 	// Ignore move step if it's a new file under a directory.
 	// Otherwise, move the file when name changed.
 	if osutil.IsFile(oldFilePath) && opts.OldTreeName != opts.NewTreeName {
-		if err = git.MoveFile(localPath, opts.OldTreeName, opts.NewTreeName); err != nil {
+		if err = git.RepoMove(localPath, opts.OldTreeName, opts.NewTreeName); err != nil {
 			return fmt.Errorf("git mv %q %q: %v", opts.OldTreeName, opts.NewTreeName, err)
 		}
 	}
@@ -176,22 +173,21 @@ func (repo *Repository) UpdateRepoFile(doer *User, opts UpdateRepoFileOptions) (
 		return fmt.Errorf("write file: %v", err)
 	}
 
-	if err = git.AddChanges(localPath, true); err != nil {
+	if err = git.RepoAdd(localPath, git.AddOptions{All: true}); err != nil {
 		return fmt.Errorf("git add --all: %v", err)
-	} else if err = git.CommitChanges(localPath, git.CommitChangesOptions{
-		Committer: doer.NewGitSig(),
-		Message:   opts.Message,
-	}); err != nil {
+	} else if err = git.RepoCommit(localPath, doer.NewGitSig(), opts.Message); err != nil {
 		return fmt.Errorf("commit changes on %q: %v", localPath, err)
-	} else if err = git.PushWithEnvs(localPath, "origin", opts.NewBranch,
-		ComposeHookEnvs(ComposeHookEnvsOptions{
-			AuthUser:  doer,
-			OwnerName: repo.MustOwner().Name,
-			OwnerSalt: repo.MustOwner().Salt,
-			RepoID:    repo.ID,
-			RepoName:  repo.Name,
-			RepoPath:  repo.RepoPath(),
-		})); err != nil {
+	}
+
+	envs := ComposeHookEnvs(ComposeHookEnvsOptions{
+		AuthUser:  doer,
+		OwnerName: repo.MustOwner().Name,
+		OwnerSalt: repo.MustOwner().Salt,
+		RepoID:    repo.ID,
+		RepoName:  repo.Name,
+		RepoPath:  repo.RepoPath(),
+	})
+	if err = git.RepoPush(localPath, "origin", opts.NewBranch, git.PushOptions{Envs: envs}); err != nil {
 		return fmt.Errorf("git push origin %s: %v", opts.NewBranch, err)
 	}
 
@@ -200,7 +196,7 @@ func (repo *Repository) UpdateRepoFile(doer *User, opts UpdateRepoFileOptions) (
 }
 
 // GetDiffPreview produces and returns diff result of a file which is not yet committed.
-func (repo *Repository) GetDiffPreview(branch, treePath, content string) (diff *Diff, err error) {
+func (repo *Repository) GetDiffPreview(branch, treePath, content string) (diff *gitutil.Diff, err error) {
 	repoWorkingPool.CheckIn(com.ToStr(repo.ID))
 	defer repoWorkingPool.CheckOut(com.ToStr(repo.ID))
 
@@ -233,9 +229,9 @@ func (repo *Repository) GetDiffPreview(branch, treePath, content string) (diff *
 	pid := process.Add(fmt.Sprintf("GetDiffPreview [repo_path: %s]", repo.RepoPath()), cmd)
 	defer process.Remove(pid)
 
-	diff, err = ParsePatch(conf.Git.MaxGitDiffLines, conf.Git.MaxGitDiffLineCharacters, conf.Git.MaxGitDiffFiles, stdout)
+	diff, err = gitutil.ParseDiff(stdout, conf.Git.MaxDiffFiles, conf.Git.MaxDiffLines, conf.Git.MaxDiffLineChars)
 	if err != nil {
-		return nil, fmt.Errorf("parse path: %v", err)
+		return nil, fmt.Errorf("parse diff: %v", err)
 	}
 
 	if err = cmd.Wait(); err != nil {
@@ -282,22 +278,21 @@ func (repo *Repository) DeleteRepoFile(doer *User, opts DeleteRepoFileOptions) (
 		return fmt.Errorf("remove file %q: %v", opts.TreePath, err)
 	}
 
-	if err = git.AddChanges(localPath, true); err != nil {
+	if err = git.RepoAdd(localPath, git.AddOptions{All: true}); err != nil {
 		return fmt.Errorf("git add --all: %v", err)
-	} else if err = git.CommitChanges(localPath, git.CommitChangesOptions{
-		Committer: doer.NewGitSig(),
-		Message:   opts.Message,
-	}); err != nil {
+	} else if err = git.RepoCommit(localPath, doer.NewGitSig(), opts.Message); err != nil {
 		return fmt.Errorf("commit changes to %q: %v", localPath, err)
-	} else if err = git.PushWithEnvs(localPath, "origin", opts.NewBranch,
-		ComposeHookEnvs(ComposeHookEnvsOptions{
-			AuthUser:  doer,
-			OwnerName: repo.MustOwner().Name,
-			OwnerSalt: repo.MustOwner().Salt,
-			RepoID:    repo.ID,
-			RepoName:  repo.Name,
-			RepoPath:  repo.RepoPath(),
-		})); err != nil {
+	}
+
+	envs := ComposeHookEnvs(ComposeHookEnvsOptions{
+		AuthUser:  doer,
+		OwnerName: repo.MustOwner().Name,
+		OwnerSalt: repo.MustOwner().Salt,
+		RepoID:    repo.ID,
+		RepoName:  repo.Name,
+		RepoPath:  repo.RepoPath(),
+	})
+	if err = git.RepoPush(localPath, "origin", opts.NewBranch, git.PushOptions{Envs: envs}); err != nil {
 		return fmt.Errorf("git push origin %s: %v", opts.NewBranch, err)
 	}
 	return nil
@@ -505,20 +500,19 @@ func (repo *Repository) UploadRepoFiles(doer *User, opts UploadRepoFileOptions)
 	annexSetup(localPath) // Initialise annex and set configuration (with add filter for filesizes)
 	if err = annexAdd(localPath, true); err != nil {
 		return fmt.Errorf("git annex add: %v", err)
-	} else if err = git.CommitChanges(localPath, git.CommitChangesOptions{
-		Committer: doer.NewGitSig(),
-		Message:   opts.Message,
-	}); err != nil {
+	} else if err = git.RepoCommit(localPath, doer.NewGitSig(), opts.Message); err != nil {
 		return fmt.Errorf("commit changes on %q: %v", localPath, err)
-	} else if err = git.PushWithEnvs(localPath, "origin", opts.NewBranch,
-		ComposeHookEnvs(ComposeHookEnvsOptions{
-			AuthUser:  doer,
-			OwnerName: repo.MustOwner().Name,
-			OwnerSalt: repo.MustOwner().Salt,
-			RepoID:    repo.ID,
-			RepoName:  repo.Name,
-			RepoPath:  repo.RepoPath(),
-		})); err != nil {
+	}
+
+	envs := ComposeHookEnvs(ComposeHookEnvsOptions{
+		AuthUser:  doer,
+		OwnerName: repo.MustOwner().Name,
+		OwnerSalt: repo.MustOwner().Salt,
+		RepoID:    repo.ID,
+		RepoName:  repo.Name,
+		RepoPath:  repo.RepoPath(),
+	})
+	if err = git.RepoPush(localPath, "origin", opts.NewBranch, git.PushOptions{Envs: envs}); err != nil {
 		return fmt.Errorf("git push origin %s: %v", opts.NewBranch, err)
 	}
 

+ 1 - 1
internal/db/token.go

@@ -58,7 +58,7 @@ func NewAccessToken(t *AccessToken) error {
 	if err != nil {
 		return err
 	} else if has {
-		return errors.AccessTokenNameAlreadyExist{t.Name}
+		return errors.AccessTokenNameAlreadyExist{Name: t.Name}
 	}
 
 	_, err = x.Insert(t)

+ 2 - 2
internal/db/two_factor.go

@@ -118,7 +118,7 @@ func GetTwoFactorByUserID(userID int64) (*TwoFactor, error) {
 	if err != nil {
 		return nil, err
 	} else if !has {
-		return nil, errors.TwoFactorNotFound{userID}
+		return nil, errors.TwoFactorNotFound{UserID: userID}
 	}
 
 	return t, nil
@@ -189,7 +189,7 @@ func UseRecoveryCode(userID int64, code string) error {
 	if err != nil {
 		return fmt.Errorf("get unused code: %v", err)
 	} else if !has {
-		return errors.TwoFactorRecoveryCodeNotFound{code}
+		return errors.TwoFactorRecoveryCodeNotFound{Code: code}
 	}
 
 	recoveryCode.IsUsed = true

+ 23 - 28
internal/db/update.go

@@ -5,19 +5,18 @@
 package db
 
 import (
-	"container/list"
 	"fmt"
 	"os/exec"
 	"strings"
 
-	git "github.com/G-Node/git-module"
+	"github.com/gogs/git-module"
 )
 
 // CommitToPushCommit transforms a git.Commit to PushCommit type.
 func CommitToPushCommit(commit *git.Commit) *PushCommit {
 	return &PushCommit{
 		Sha1:           commit.ID.String(),
-		Message:        commit.Message(),
+		Message:        commit.Message,
 		AuthorEmail:    commit.Author.Email,
 		AuthorName:     commit.Author.Name,
 		CommitterEmail: commit.Committer.Email,
@@ -26,27 +25,22 @@ func CommitToPushCommit(commit *git.Commit) *PushCommit {
 	}
 }
 
-func ListToPushCommits(l *list.List) *PushCommits {
-	if l == nil {
+func CommitsToPushCommits(commits []*git.Commit) *PushCommits {
+	if len(commits) == 0 {
 		return &PushCommits{}
 	}
 
-	commits := make([]*PushCommit, 0)
-	var actEmail string
-	for e := l.Front(); e != nil; e = e.Next() {
-		commit := e.Value.(*git.Commit)
-		if actEmail == "" {
-			actEmail = commit.Committer.Email
-		}
-		commits = append(commits, CommitToPushCommit(commit))
+	pcs := make([]*PushCommit, len(commits))
+	for i := range commits {
+		pcs[i] = CommitToPushCommit(commits[i])
 	}
-	return &PushCommits{l.Len(), commits, "", nil}
+	return &PushCommits{len(pcs), pcs, "", nil}
 }
 
 type PushUpdateOptions struct {
 	OldCommitID  string
 	NewCommitID  string
-	RefFullName  string
+	FullRefspec  string
 	PusherID     int64
 	PusherName   string
 	RepoUserName string
@@ -56,10 +50,10 @@ type PushUpdateOptions struct {
 // PushUpdate must be called for any push actions in order to
 // generates necessary push action history feeds.
 func PushUpdate(opts PushUpdateOptions) (err error) {
-	isNewRef := opts.OldCommitID == git.EMPTY_SHA
-	isDelRef := opts.NewCommitID == git.EMPTY_SHA
+	isNewRef := strings.HasPrefix(opts.OldCommitID, git.EmptyID)
+	isDelRef := strings.HasPrefix(opts.NewCommitID, git.EmptyID)
 	if isNewRef && isDelRef {
-		return fmt.Errorf("Old and new revisions are both %s", git.EMPTY_SHA)
+		return fmt.Errorf("both old and new revisions are %q", git.EmptyID)
 	}
 
 	repoPath := RepoPath(opts.RepoUserName, opts.RepoName)
@@ -70,9 +64,9 @@ func PushUpdate(opts PushUpdateOptions) (err error) {
 		return fmt.Errorf("run 'git update-server-info': %v", err)
 	}
 
-	gitRepo, err := git.OpenRepository(repoPath)
+	gitRepo, err := git.Open(repoPath)
 	if err != nil {
-		return fmt.Errorf("OpenRepository: %v", err)
+		return fmt.Errorf("open repository: %v", err)
 	}
 
 	owner, err := GetUserByName(opts.RepoUserName)
@@ -90,12 +84,12 @@ func PushUpdate(opts PushUpdateOptions) (err error) {
 	}
 
 	// Push tags
-	if strings.HasPrefix(opts.RefFullName, git.TAG_PREFIX) {
+	if strings.HasPrefix(opts.FullRefspec, git.RefsTags) {
 		if err := CommitRepoAction(CommitRepoActionOptions{
 			PusherName:  opts.PusherName,
 			RepoOwnerID: owner.ID,
 			RepoName:    repo.Name,
-			RefFullName: opts.RefFullName,
+			RefFullName: opts.FullRefspec,
 			OldCommitID: opts.OldCommitID,
 			NewCommitID: opts.NewCommitID,
 			Commits:     &PushCommits{},
@@ -105,22 +99,23 @@ func PushUpdate(opts PushUpdateOptions) (err error) {
 		return nil
 	}
 
-	var l *list.List
+	var commits []*git.Commit
 	// Skip read parent commits when delete branch
 	if !isDelRef {
 		// Push new branch
-		newCommit, err := gitRepo.GetCommit(opts.NewCommitID)
+		newCommit, err := gitRepo.CatFileCommit(opts.NewCommitID)
 		if err != nil {
 			return fmt.Errorf("GetCommit [commit_id: %s]: %v", opts.NewCommitID, err)
 		}
 
 		if isNewRef {
-			l, err = newCommit.CommitsBeforeLimit(10)
+			commits, err = newCommit.Ancestors(git.LogOptions{MaxCount: 9})
 			if err != nil {
 				return fmt.Errorf("CommitsBeforeLimit [commit_id: %s]: %v", newCommit.ID, err)
 			}
+			commits = append([]*git.Commit{newCommit}, commits...)
 		} else {
-			l, err = newCommit.CommitsBeforeUntil(opts.OldCommitID)
+			commits, err = newCommit.CommitsAfter(opts.OldCommitID)
 			if err != nil {
 				return fmt.Errorf("CommitsBeforeUntil [commit_id: %s]: %v", opts.OldCommitID, err)
 			}
@@ -131,10 +126,10 @@ func PushUpdate(opts PushUpdateOptions) (err error) {
 		PusherName:  opts.PusherName,
 		RepoOwnerID: owner.ID,
 		RepoName:    repo.Name,
-		RefFullName: opts.RefFullName,
+		RefFullName: opts.FullRefspec,
 		OldCommitID: opts.OldCommitID,
 		NewCommitID: opts.NewCommitID,
-		Commits:     ListToPushCommits(l),
+		Commits:     CommitsToPushCommits(commits),
 	}); err != nil {
 		return fmt.Errorf("CommitRepoAction.(branch): %v", err)
 	}

+ 19 - 26
internal/db/user.go

@@ -7,7 +7,6 @@ package db
 import (
 	"bufio"
 	"bytes"
-	"container/list"
 	"crypto/sha256"
 	"crypto/subtle"
 	"encoding/hex"
@@ -28,7 +27,7 @@ import (
 	log "unknwon.dev/clog/v2"
 	"xorm.io/xorm"
 
-	"github.com/G-Node/git-module"
+	"github.com/gogs/git-module"
 	api "github.com/gogs/go-gogs-client"
 
 	"github.com/G-Node/gogs/internal/avatar"
@@ -926,7 +925,7 @@ func GetUserByKeyID(keyID int64) (*User, error) {
 	if err != nil {
 		return nil, err
 	} else if !has {
-		return nil, errors.UserNotKeyOwner{keyID}
+		return nil, errors.UserNotKeyOwner{KeyID: keyID}
 	}
 	return user, nil
 }
@@ -937,7 +936,7 @@ func getUserByID(e Engine, id int64) (*User, error) {
 	if err != nil {
 		return nil, err
 	} else if !has {
-		return nil, errors.UserNotExist{id, ""}
+		return nil, errors.UserNotExist{UserID: id}
 	}
 	return u, nil
 }
@@ -953,7 +952,7 @@ func GetAssigneeByID(repo *Repository, userID int64) (*User, error) {
 	if err != nil {
 		return nil, err
 	} else if !has {
-		return nil, errors.UserNotExist{userID, ""}
+		return nil, errors.UserNotExist{UserID: userID}
 	}
 	return GetUserByID(userID)
 }
@@ -961,14 +960,14 @@ func GetAssigneeByID(repo *Repository, userID int64) (*User, error) {
 // GetUserByName returns a user by given name.
 func GetUserByName(name string) (*User, error) {
 	if len(name) == 0 {
-		return nil, errors.UserNotExist{0, name}
+		return nil, errors.UserNotExist{Name: name}
 	}
 	u := &User{LowerName: strings.ToLower(name)}
 	has, err := x.Get(u)
 	if err != nil {
 		return nil, err
 	} else if !has {
-		return nil, errors.UserNotExist{0, name}
+		return nil, errors.UserNotExist{Name: name}
 	}
 	return u, nil
 }
@@ -1017,28 +1016,22 @@ func ValidateCommitWithEmail(c *git.Commit) *User {
 }
 
 // ValidateCommitsWithEmails checks if authors' e-mails of commits are corresponding to users.
-func ValidateCommitsWithEmails(oldCommits *list.List) *list.List {
-	var (
-		u          *User
-		emails     = map[string]*User{}
-		newCommits = list.New()
-		e          = oldCommits.Front()
-	)
-	for e != nil {
-		c := e.Value.(*git.Commit)
-
-		if v, ok := emails[c.Author.Email]; !ok {
-			u, _ = GetUserByEmail(c.Author.Email)
-			emails[c.Author.Email] = u
+func ValidateCommitsWithEmails(oldCommits []*git.Commit) []*UserCommit {
+	emails := make(map[string]*User)
+	newCommits := make([]*UserCommit, len(oldCommits))
+	for i := range oldCommits {
+		var u *User
+		if v, ok := emails[oldCommits[i].Author.Email]; !ok {
+			u, _ = GetUserByEmail(oldCommits[i].Author.Email)
+			emails[oldCommits[i].Author.Email] = u
 		} else {
 			u = v
 		}
 
-		newCommits.PushBack(UserCommit{
+		newCommits[i] = &UserCommit{
 			User:   u,
-			Commit: c,
-		})
-		e = e.Next()
+			Commit: oldCommits[i],
+		}
 	}
 	return newCommits
 }
@@ -1046,7 +1039,7 @@ func ValidateCommitsWithEmails(oldCommits *list.List) *list.List {
 // GetUserByEmail returns the user object by given e-mail if exists.
 func GetUserByEmail(email string) (*User, error) {
 	if len(email) == 0 {
-		return nil, errors.UserNotExist{0, "email"}
+		return nil, errors.UserNotExist{Name: "email"}
 	}
 
 	email = strings.ToLower(email)
@@ -1070,7 +1063,7 @@ func GetUserByEmail(email string) (*User, error) {
 		return GetUserByID(emailAddress.UID)
 	}
 
-	return nil, errors.UserNotExist{0, email}
+	return nil, errors.UserNotExist{Name: email}
 }
 
 type SearchUserOptions struct {

+ 3 - 3
internal/db/user_mail.go

@@ -165,11 +165,11 @@ func MakeEmailPrimary(email *EmailAddress) error {
 	if err != nil {
 		return err
 	} else if !has {
-		return errors.EmailNotFound{email.Email}
+		return errors.EmailNotFound{Email: email.Email}
 	}
 
 	if !email.IsActivated {
-		return errors.EmailNotVerified{email.Email}
+		return errors.EmailNotVerified{Email: email.Email}
 	}
 
 	user := &User{ID: email.UID}
@@ -177,7 +177,7 @@ func MakeEmailPrimary(email *EmailAddress) error {
 	if err != nil {
 		return err
 	} else if !has {
-		return errors.UserNotExist{email.UID, ""}
+		return errors.UserNotExist{UserID: email.UID}
 	}
 
 	// Make sure the former primary email doesn't disappear.

+ 3 - 3
internal/db/webhook.go

@@ -27,7 +27,7 @@ import (
 	"github.com/G-Node/gogs/internal/sync"
 )
 
-var HookQueue = sync.NewUniqueQueue(conf.Webhook.QueueLength)
+var HookQueue = sync.NewUniqueQueue(1000)
 
 type HookContentType int
 
@@ -242,7 +242,7 @@ func getWebhook(bean *Webhook) (*Webhook, error) {
 	if err != nil {
 		return nil, err
 	} else if !has {
-		return nil, errors.WebhookNotExist{bean.ID}
+		return nil, errors.WebhookNotExist{ID: bean.ID}
 	}
 	return bean, nil
 }
@@ -509,7 +509,7 @@ func GetHookTaskOfWebhookByUUID(webhookID int64, uuid string) (*HookTask, error)
 	if err != nil {
 		return nil, err
 	} else if !has {
-		return nil, errors.HookTaskNotExist{webhookID, uuid}
+		return nil, errors.HookTaskNotExist{HookID: webhookID, UUID: uuid}
 	}
 	return hookTask, nil
 }

+ 4 - 4
internal/db/webhook_dingtalk.go

@@ -8,7 +8,7 @@ import (
 	"fmt"
 	"strings"
 
-	"github.com/G-Node/git-module"
+	"github.com/gogs/git-module"
 	api "github.com/gogs/go-gogs-client"
 	jsoniter "github.com/json-iterator/go"
 )
@@ -85,7 +85,7 @@ func GetDingtalkPayload(p api.Payloader, event HookEventType) (payload *Dingtalk
 }
 
 func getDingtalkCreatePayload(p *api.CreatePayload) (*DingtalkPayload, error) {
-	refName := git.RefEndName(p.Ref)
+	refName := git.RefShortName(p.Ref)
 	refType := strings.Title(p.RefType)
 
 	actionCard := NewDingtalkActionCard("View "+refType, p.Repo.HTMLURL+"/src/"+refName)
@@ -98,7 +98,7 @@ func getDingtalkCreatePayload(p *api.CreatePayload) (*DingtalkPayload, error) {
 }
 
 func getDingtalkDeletePayload(p *api.DeletePayload) (*DingtalkPayload, error) {
-	refName := git.RefEndName(p.Ref)
+	refName := git.RefShortName(p.Ref)
 	refType := strings.Title(p.RefType)
 
 	actionCard := NewDingtalkActionCard("View Repo", p.Repo.HTMLURL)
@@ -121,7 +121,7 @@ func getDingtalkForkPayload(p *api.ForkPayload) (*DingtalkPayload, error) {
 }
 
 func getDingtalkPushPayload(p *api.PushPayload) (*DingtalkPayload, error) {
-	refName := git.RefEndName(p.Ref)
+	refName := git.RefShortName(p.Ref)
 
 	pusher := p.Pusher.FullName
 	if pusher == "" {

+ 4 - 4
internal/db/webhook_discord.go

@@ -9,7 +9,7 @@ import (
 	"strconv"
 	"strings"
 
-	"github.com/G-Node/git-module"
+	"github.com/gogs/git-module"
 	api "github.com/gogs/go-gogs-client"
 	jsoniter "github.com/json-iterator/go"
 
@@ -70,7 +70,7 @@ func DiscordSHALinkFormatter(url string, text string) string {
 
 // getDiscordCreatePayload composes Discord payload for create new branch or tag.
 func getDiscordCreatePayload(p *api.CreatePayload) (*DiscordPayload, error) {
-	refName := git.RefEndName(p.Ref)
+	refName := git.RefShortName(p.Ref)
 	repoLink := DiscordLinkFormatter(p.Repo.HTMLURL, p.Repo.Name)
 	refLink := DiscordLinkFormatter(p.Repo.HTMLURL+"/src/"+refName, refName)
 	content := fmt.Sprintf("Created new %s: %s/%s", p.RefType, repoLink, refLink)
@@ -88,7 +88,7 @@ func getDiscordCreatePayload(p *api.CreatePayload) (*DiscordPayload, error) {
 
 // getDiscordDeletePayload composes Discord payload for delete a branch or tag.
 func getDiscordDeletePayload(p *api.DeletePayload) (*DiscordPayload, error) {
-	refName := git.RefEndName(p.Ref)
+	refName := git.RefShortName(p.Ref)
 	repoLink := DiscordLinkFormatter(p.Repo.HTMLURL, p.Repo.Name)
 	content := fmt.Sprintf("Deleted %s: %s/%s", p.RefType, repoLink, refName)
 	return &DiscordPayload{
@@ -123,7 +123,7 @@ func getDiscordForkPayload(p *api.ForkPayload) (*DiscordPayload, error) {
 func getDiscordPushPayload(p *api.PushPayload, slack *SlackMeta) (*DiscordPayload, error) {
 	// n new commits
 	var (
-		branchName   = git.RefEndName(p.Ref)
+		branchName   = git.RefShortName(p.Ref)
 		commitDesc   string
 		commitString string
 	)

+ 4 - 4
internal/db/webhook_slack.go

@@ -8,7 +8,7 @@ import (
 	"fmt"
 	"strings"
 
-	"github.com/G-Node/git-module"
+	"github.com/gogs/git-module"
 	api "github.com/gogs/go-gogs-client"
 	jsoniter "github.com/json-iterator/go"
 
@@ -71,7 +71,7 @@ func SlackLinkFormatter(url string, text string) string {
 
 // getSlackCreatePayload composes Slack payload for create new branch or tag.
 func getSlackCreatePayload(p *api.CreatePayload) (*SlackPayload, error) {
-	refName := git.RefEndName(p.Ref)
+	refName := git.RefShortName(p.Ref)
 	repoLink := SlackLinkFormatter(p.Repo.HTMLURL, p.Repo.Name)
 	refLink := SlackLinkFormatter(p.Repo.HTMLURL+"/src/"+refName, refName)
 	text := fmt.Sprintf("[%s:%s] %s created by %s", repoLink, refLink, p.RefType, p.Sender.UserName)
@@ -82,7 +82,7 @@ func getSlackCreatePayload(p *api.CreatePayload) (*SlackPayload, error) {
 
 // getSlackDeletePayload composes Slack payload for delete a branch or tag.
 func getSlackDeletePayload(p *api.DeletePayload) (*SlackPayload, error) {
-	refName := git.RefEndName(p.Ref)
+	refName := git.RefShortName(p.Ref)
 	repoLink := SlackLinkFormatter(p.Repo.HTMLURL, p.Repo.Name)
 	text := fmt.Sprintf("[%s:%s] %s deleted by %s", repoLink, refName, p.RefType, p.Sender.UserName)
 	return &SlackPayload{
@@ -103,7 +103,7 @@ func getSlackForkPayload(p *api.ForkPayload) (*SlackPayload, error) {
 func getSlackPushPayload(p *api.PushPayload, slack *SlackMeta) (*SlackPayload, error) {
 	// n new commits
 	var (
-		branchName   = git.RefEndName(p.Ref)
+		branchName   = git.RefShortName(p.Ref)
 		commitDesc   string
 		commitString string
 	)

+ 15 - 21
internal/db/wiki.go

@@ -15,7 +15,7 @@ import (
 
 	"github.com/unknwon/com"
 
-	"github.com/G-Node/git-module"
+	"github.com/gogs/git-module"
 
 	"github.com/G-Node/gogs/internal/conf"
 	"github.com/G-Node/gogs/internal/sync"
@@ -62,8 +62,8 @@ func (repo *Repository) InitWiki() error {
 		return nil
 	}
 
-	if err := git.InitRepository(repo.WikiPath(), true); err != nil {
-		return fmt.Errorf("InitRepository: %v", err)
+	if err := git.Init(repo.WikiPath(), git.InitOptions{Bare: true}); err != nil {
+		return fmt.Errorf("init repository: %v", err)
 	} else if err = createDelegateHooks(repo.WikiPath()); err != nil {
 		return fmt.Errorf("createDelegateHooks: %v", err)
 	}
@@ -125,15 +125,12 @@ func (repo *Repository) updateWikiPage(doer *User, oldTitle, title, content, mes
 	if len(message) == 0 {
 		message = "Update page '" + title + "'"
 	}
-	if err = git.AddChanges(localPath, true); err != nil {
-		return fmt.Errorf("AddChanges: %v", err)
-	} else if err = git.CommitChanges(localPath, git.CommitChangesOptions{
-		Committer: doer.NewGitSig(),
-		Message:   message,
-	}); err != nil {
-		return fmt.Errorf("CommitChanges: %v", err)
-	} else if err = git.Push(localPath, "origin", "master"); err != nil {
-		return fmt.Errorf("Push: %v", err)
+	if err = git.RepoAdd(localPath, git.AddOptions{All: true}); err != nil {
+		return fmt.Errorf("add all changes: %v", err)
+	} else if err = git.RepoCommit(localPath, doer.NewGitSig(), message); err != nil {
+		return fmt.Errorf("commit changes: %v", err)
+	} else if err = git.RepoPush(localPath, "origin", "master"); err != nil {
+		return fmt.Errorf("push: %v", err)
 	}
 
 	return nil
@@ -164,15 +161,12 @@ func (repo *Repository) DeleteWikiPage(doer *User, title string) (err error) {
 
 	message := "Delete page '" + title + "'"
 
-	if err = git.AddChanges(localPath, true); err != nil {
-		return fmt.Errorf("AddChanges: %v", err)
-	} else if err = git.CommitChanges(localPath, git.CommitChangesOptions{
-		Committer: doer.NewGitSig(),
-		Message:   message,
-	}); err != nil {
-		return fmt.Errorf("CommitChanges: %v", err)
-	} else if err = git.Push(localPath, "origin", "master"); err != nil {
-		return fmt.Errorf("Push: %v", err)
+	if err = git.RepoAdd(localPath, git.AddOptions{All: true}); err != nil {
+		return fmt.Errorf("add all changes: %v", err)
+	} else if err = git.RepoCommit(localPath, doer.NewGitSig(), message); err != nil {
+		return fmt.Errorf("commit changes: %v", err)
+	} else if err = git.RepoPush(localPath, "origin", "master"); err != nil {
+		return fmt.Errorf("push: %v", err)
 	}
 
 	return nil

+ 7 - 11
internal/email/message.go

@@ -203,18 +203,14 @@ func (s *Sender) Send(from string, to []string, msg io.WriterTo) error {
 
 func processMailQueue() {
 	sender := &Sender{}
-
-	for {
-		select {
-		case msg := <-mailQueue:
-			log.Trace("New e-mail sending request %s: %s", msg.GetHeader("To"), msg.Info)
-			if err := gomail.Send(sender, msg.Message); err != nil {
-				log.Error("Failed to send emails %s: %s - %v", msg.GetHeader("To"), msg.Info, err)
-			} else {
-				log.Trace("E-mails sent %s: %s", msg.GetHeader("To"), msg.Info)
-			}
-			msg.confirmChan <- struct{}{}
+	for msg := range mailQueue {
+		log.Trace("New e-mail sending request %s: %s", msg.GetHeader("To"), msg.Info)
+		if err := gomail.Send(sender, msg.Message); err != nil {
+			log.Error("Failed to send emails %s: %s - %v", msg.GetHeader("To"), msg.Info, err)
+		} else {
+			log.Trace("E-mails sent %s: %s", msg.GetHeader("To"), msg.Info)
 		}
+		msg.confirmChan <- struct{}{}
 	}
 }
 

+ 4 - 4
internal/form/repo.go

@@ -341,7 +341,7 @@ func (f *NewWiki) Validate(ctx *macaron.Context, errs binding.Errors) binding.Er
 type EditRepoFile struct {
 	TreePath      string `binding:"Required;MaxSize(500)"`
 	Content       string `binding:"Required"`
-	CommitSummary string `binding:"MaxSize(100)`
+	CommitSummary string `binding:"MaxSize(100)"`
 	CommitMessage string
 	CommitChoice  string `binding:"Required;MaxSize(50)"`
 	NewBranchName string `binding:"AlphaDashDotSlash;MaxSize(100)"`
@@ -373,8 +373,8 @@ func (f *EditPreviewDiff) Validate(ctx *macaron.Context, errs binding.Errors) bi
 //
 
 type UploadRepoFile struct {
-	TreePath      string `binding:MaxSize(500)"`
-	CommitSummary string `binding:"MaxSize(100)`
+	TreePath      string `binding:"MaxSize(500)"`
+	CommitSummary string `binding:"MaxSize(100)"`
 	CommitMessage string
 	CommitChoice  string `binding:"Required;MaxSize(50)"`
 	NewBranchName string `binding:"AlphaDashDot;MaxSize(100)"`
@@ -405,7 +405,7 @@ func (f *RemoveUploadFile) Validate(ctx *macaron.Context, errs binding.Errors) b
 //         \/     \/          \/          \/
 
 type DeleteRepoFile struct {
-	CommitSummary string `binding:"MaxSize(100)`
+	CommitSummary string `binding:"MaxSize(100)"`
 	CommitMessage string
 	CommitChoice  string `binding:"Required;MaxSize(50)"`
 	NewBranchName string `binding:"AlphaDashDot;MaxSize(100)"`

+ 196 - 0
internal/gitutil/diff.go

@@ -0,0 +1,196 @@
+// Copyright 2014 The Gogs Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package gitutil
+
+import (
+	"bytes"
+	"fmt"
+	"html"
+	"html/template"
+	"io"
+	"sync"
+
+	"github.com/sergi/go-diff/diffmatchpatch"
+	"golang.org/x/net/html/charset"
+	"golang.org/x/text/transform"
+
+	"github.com/gogs/git-module"
+
+	"github.com/G-Node/gogs/internal/conf"
+	"github.com/G-Node/gogs/internal/template/highlight"
+	"github.com/G-Node/gogs/internal/tool"
+)
+
+// DiffSection is a wrapper to git.DiffSection with helper methods.
+type DiffSection struct {
+	*git.DiffSection
+
+	initOnce sync.Once
+	dmp      *diffmatchpatch.DiffMatchPatch
+}
+
+// ComputedInlineDiffFor computes inline diff for the given line.
+func (s *DiffSection) ComputedInlineDiffFor(line *git.DiffLine) template.HTML {
+	fallback := template.HTML(html.EscapeString(line.Content))
+	if conf.Git.DisableDiffHighlight {
+		return fallback
+	}
+
+	// Find equivalent diff line, ignore when not found.
+	var diff1, diff2 string
+	switch line.Type {
+	case git.DiffLineAdd:
+		compareLine := s.Line(git.DiffLineDelete, line.RightLine)
+		if compareLine == nil {
+			return fallback
+		}
+
+		diff1 = compareLine.Content
+		diff2 = line.Content
+
+	case git.DiffLineDelete:
+		compareLine := s.Line(git.DiffLineAdd, line.LeftLine)
+		if compareLine == nil {
+			return fallback
+		}
+
+		diff1 = line.Content
+		diff2 = compareLine.Content
+
+	default:
+		return fallback
+	}
+
+	s.initOnce.Do(func() {
+		s.dmp = diffmatchpatch.New()
+		s.dmp.DiffEditCost = 100
+	})
+
+	diffs := s.dmp.DiffMain(diff1[1:], diff2[1:], true)
+	diffs = s.dmp.DiffCleanupEfficiency(diffs)
+
+	return diffsToHTML(diffs, line.Type)
+}
+
+func diffsToHTML(diffs []diffmatchpatch.Diff, lineType git.DiffLineType) template.HTML {
+	buf := bytes.NewBuffer(nil)
+
+	// Reproduce signs which are cutted for inline diff before.
+	switch lineType {
+	case git.DiffLineAdd:
+		buf.WriteByte('+')
+	case git.DiffLineDelete:
+		buf.WriteByte('-')
+	}
+	buf.WriteByte(' ')
+
+	const (
+		addedCodePrefix   = `<span class="added-code">`
+		removedCodePrefix = `<span class="removed-code">`
+		codeTagSuffix     = `</span>`
+	)
+
+	for i := range diffs {
+		switch {
+		case diffs[i].Type == diffmatchpatch.DiffInsert && lineType == git.DiffLineAdd:
+			buf.WriteString(addedCodePrefix)
+			buf.WriteString(html.EscapeString(diffs[i].Text))
+			buf.WriteString(codeTagSuffix)
+		case diffs[i].Type == diffmatchpatch.DiffDelete && lineType == git.DiffLineDelete:
+			buf.WriteString(removedCodePrefix)
+			buf.WriteString(html.EscapeString(diffs[i].Text))
+			buf.WriteString(codeTagSuffix)
+		case diffs[i].Type == diffmatchpatch.DiffEqual:
+			buf.WriteString(html.EscapeString(diffs[i].Text))
+		}
+	}
+
+	return template.HTML(buf.Bytes())
+}
+
+// DiffFile is a wrapper to git.DiffFile with helper methods.
+type DiffFile struct {
+	*git.DiffFile
+	Sections []*DiffSection
+}
+
+// HighlightClass returns the detected highlight class for the file.
+func (diffFile *DiffFile) HighlightClass() string {
+	return highlight.FileNameToHighlightClass(diffFile.Name)
+}
+
+// Diff is a wrapper to git.Diff with helper methods.
+type Diff struct {
+	*git.Diff
+	Files []*DiffFile
+}
+
+// NewDiff returns a new wrapper of given git.Diff.
+func NewDiff(oldDiff *git.Diff) *Diff {
+	newDiff := &Diff{
+		Diff:  oldDiff,
+		Files: make([]*DiffFile, oldDiff.NumFiles()),
+	}
+
+	// FIXME: detect encoding while parsing.
+	var buf bytes.Buffer
+	for i := range oldDiff.Files {
+		buf.Reset()
+
+		newDiff.Files[i] = &DiffFile{
+			DiffFile: oldDiff.Files[i],
+			Sections: make([]*DiffSection, oldDiff.Files[i].NumSections()),
+		}
+
+		for j := range oldDiff.Files[i].Sections {
+			newDiff.Files[i].Sections[j] = &DiffSection{
+				DiffSection: oldDiff.Files[i].Sections[j],
+			}
+
+			for k := range newDiff.Files[i].Sections[j].Lines {
+				buf.WriteString(newDiff.Files[i].Sections[j].Lines[k].Content)
+				buf.WriteString("\n")
+			}
+		}
+
+		charsetLabel, err := tool.DetectEncoding(buf.Bytes())
+		if charsetLabel != "UTF-8" && err == nil {
+			encoding, _ := charset.Lookup(charsetLabel)
+			if encoding != nil {
+				d := encoding.NewDecoder()
+				for j := range newDiff.Files[i].Sections {
+					for k := range newDiff.Files[i].Sections[j].Lines {
+						if c, _, err := transform.String(d, newDiff.Files[i].Sections[j].Lines[k].Content); err == nil {
+							newDiff.Files[i].Sections[j].Lines[k].Content = c
+						}
+					}
+				}
+			}
+		}
+	}
+
+	return newDiff
+}
+
+// ParseDiff parses the diff from given io.Reader.
+func ParseDiff(r io.Reader, maxFiles, maxFileLines, maxLineChars int) (*Diff, error) {
+	done := make(chan git.SteamParseDiffResult)
+	go git.StreamParseDiff(r, done, maxFiles, maxFileLines, maxLineChars)
+
+	result := <-done
+	if result.Err != nil {
+		return nil, fmt.Errorf("stream parse diff: %v", result.Err)
+	}
+	return NewDiff(result.Diff), nil
+}
+
+// RepoDiff parses the diff on given revisions of given repository.
+func RepoDiff(repo *git.Repository, rev string, maxFiles, maxFileLines, maxLineChars int, opts ...git.DiffOptions) (*Diff, error) {
+	diff, err := repo.Diff(rev, maxFiles, maxFileLines, maxLineChars, opts...)
+	if err != nil {
+		return nil, fmt.Errorf("get diff: %v", err)
+	}
+	return NewDiff(diff), nil
+}

+ 49 - 0
internal/gitutil/diff_test.go

@@ -0,0 +1,49 @@
+// Copyright 2016 The Gogs Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package gitutil
+
+import (
+	"html/template"
+	"testing"
+
+	dmp "github.com/sergi/go-diff/diffmatchpatch"
+	"github.com/stretchr/testify/assert"
+
+	"github.com/gogs/git-module"
+)
+
+func Test_diffsToHTML(t *testing.T) {
+	tests := []struct {
+		diffs    []dmp.Diff
+		lineType git.DiffLineType
+		expHTML  template.HTML
+	}{
+		{
+			diffs: []dmp.Diff{
+				{Type: dmp.DiffEqual, Text: "foo "},
+				{Type: dmp.DiffInsert, Text: "bar"},
+				{Type: dmp.DiffDelete, Text: " baz"},
+				{Type: dmp.DiffEqual, Text: " biz"},
+			},
+			lineType: git.DiffLineAdd,
+			expHTML:  template.HTML(`+ foo <span class="added-code">bar</span> biz`),
+		},
+		{
+			diffs: []dmp.Diff{
+				{Type: dmp.DiffEqual, Text: "foo "},
+				{Type: dmp.DiffDelete, Text: "bar"},
+				{Type: dmp.DiffInsert, Text: " baz"},
+				{Type: dmp.DiffEqual, Text: " biz"},
+			},
+			lineType: git.DiffLineDelete,
+			expHTML:  template.HTML(`- foo <span class="removed-code">bar</span> biz`),
+		},
+	}
+	for _, test := range tests {
+		t.Run("", func(t *testing.T) {
+			assert.Equal(t, test.expHTML, diffsToHTML(test.diffs, test.lineType))
+		})
+	}
+}

+ 19 - 0
internal/gitutil/error.go

@@ -0,0 +1,19 @@
+// Copyright 2020 The Gogs Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package gitutil
+
+import (
+	"github.com/gogs/git-module"
+)
+
+// IsErrRevisionNotExist returns true if the error is git.ErrRevisionNotExist.
+func IsErrRevisionNotExist(err error) bool {
+	return err == git.ErrRevisionNotExist
+}
+
+// IsErrNoMergeBase returns true if the error is git.ErrNoMergeBase.
+func IsErrNoMergeBase(err error) bool {
+	return err == git.ErrNoMergeBase
+}

+ 23 - 0
internal/gitutil/error_test.go

@@ -0,0 +1,23 @@
+// Copyright 2020 The Gogs Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package gitutil
+
+import (
+	"os"
+	"testing"
+
+	"github.com/gogs/git-module"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestIsErrRevisionNotExist(t *testing.T) {
+	assert.True(t, IsErrRevisionNotExist(git.ErrRevisionNotExist))
+	assert.False(t, IsErrRevisionNotExist(os.ErrNotExist))
+}
+
+func TestIsErrNoMergeBase(t *testing.T) {
+	assert.True(t, IsErrNoMergeBase(git.ErrNoMergeBase))
+	assert.False(t, IsErrNoMergeBase(os.ErrNotExist))
+}

+ 23 - 0
internal/gitutil/mock.go

@@ -0,0 +1,23 @@
+// Copyright 2020 The Gogs Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package gitutil
+
+import (
+	"github.com/gogs/git-module"
+)
+
+type MockModuleStore struct {
+	RepoAddRemote    func(repoPath, name, url string, opts ...git.AddRemoteOptions) error
+	RepoDiffNameOnly func(repoPath, base, head string, opts ...git.DiffNameOnlyOptions) ([]string, error)
+	RepoLog          func(repoPath, rev string, opts ...git.LogOptions) ([]*git.Commit, error)
+	RepoMergeBase    func(repoPath, base, head string, opts ...git.MergeBaseOptions) (string, error)
+	RepoRemoveRemote func(repoPath, name string, opts ...git.RemoveRemoteOptions) error
+	RepoTags         func(repoPath string, opts ...git.TagsOptions) ([]string, error)
+}
+
+// MockModule holds mock implementation of each method for Modulers interface.
+// When the field is non-nil, it is considered mocked. Otherwise, the real
+// implementation will be executed.
+var MockModule MockModuleStore

+ 90 - 0
internal/gitutil/module.go

@@ -0,0 +1,90 @@
+// Copyright 2020 The Gogs Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package gitutil
+
+import (
+	"github.com/gogs/git-module"
+)
+
+// Moduler is the interface for Git operations.
+//
+// NOTE: All methods are sorted in alphabetically.
+type Moduler interface {
+	// AddRemote adds a new remote to the repository in given path.
+	RepoAddRemote(repoPath, name, url string, opts ...git.AddRemoteOptions) error
+	// RepoDiffNameOnly returns a list of changed files between base and head revisions
+	// of the repository in given path.
+	RepoDiffNameOnly(repoPath, base, head string, opts ...git.DiffNameOnlyOptions) ([]string, error)
+	// RepoLog returns a list of commits in the state of given revision of the repository
+	// in given path. The returned list is in reverse chronological order.
+	RepoLog(repoPath, rev string, opts ...git.LogOptions) ([]*git.Commit, error)
+	// RepoMergeBase returns merge base between base and head revisions of the repository
+	// in given path.
+	RepoMergeBase(repoPath, base, head string, opts ...git.MergeBaseOptions) (string, error)
+	// RepoRemoveRemote removes a remote from the repository in given path.
+	RepoRemoveRemote(repoPath, name string, opts ...git.RemoveRemoteOptions) error
+	// RepoTags returns a list of tags of the repository in given path.
+	RepoTags(repoPath string, opts ...git.TagsOptions) ([]string, error)
+
+	Utiler
+}
+
+// Utiler is the interface for utility helpers implemented in this package.
+//
+// NOTE: All methods are sorted in alphabetically.
+type Utiler interface {
+	// GetPullRequestMeta gathers pull request metadata based on given head and base information.
+	PullRequestMeta(headPath, basePath, headBranch, baseBranch string) (*PullRequestMeta, error)
+	// ListTagsAfter returns a list of tags "after" (exlusive) given tag.
+	ListTagsAfter(repoPath, after string, limit int) (*TagsPage, error)
+}
+
+// moduler is holds real implementation.
+type moduler struct{}
+
+func (moduler) RepoAddRemote(repoPath, name, url string, opts ...git.AddRemoteOptions) error {
+	if MockModule.RepoAddRemote != nil {
+		return MockModule.RepoAddRemote(repoPath, name, url, opts...)
+	}
+	return git.RepoAddRemote(repoPath, name, url, opts...)
+}
+
+func (moduler) RepoDiffNameOnly(repoPath, base, head string, opts ...git.DiffNameOnlyOptions) ([]string, error) {
+	if MockModule.RepoDiffNameOnly != nil {
+		return MockModule.RepoDiffNameOnly(repoPath, base, head, opts...)
+	}
+	return git.RepoDiffNameOnly(repoPath, base, head, opts...)
+}
+
+func (moduler) RepoLog(repoPath, rev string, opts ...git.LogOptions) ([]*git.Commit, error) {
+	if MockModule.RepoLog != nil {
+		return MockModule.RepoLog(repoPath, rev, opts...)
+	}
+	return git.RepoLog(repoPath, rev, opts...)
+}
+
+func (moduler) RepoMergeBase(repoPath, base, head string, opts ...git.MergeBaseOptions) (string, error) {
+	if MockModule.RepoMergeBase != nil {
+		return MockModule.RepoMergeBase(repoPath, base, head, opts...)
+	}
+	return git.RepoMergeBase(repoPath, base, head, opts...)
+}
+
+func (moduler) RepoRemoveRemote(repoPath, name string, opts ...git.RemoveRemoteOptions) error {
+	if MockModule.RepoRemoveRemote != nil {
+		return MockModule.RepoRemoveRemote(repoPath, name, opts...)
+	}
+	return git.RepoRemoveRemote(repoPath, name, opts...)
+}
+
+func (moduler) RepoTags(repoPath string, opts ...git.TagsOptions) ([]string, error) {
+	if MockModule.RepoTags != nil {
+		return MockModule.RepoTags(repoPath, opts...)
+	}
+	return git.RepoTags(repoPath, opts...)
+}
+
+// Module is a mockable interface for Git operations.
+var Module Moduler = moduler{}

+ 69 - 0
internal/gitutil/pull_request.go

@@ -0,0 +1,69 @@
+// Copyright 2020 The Gogs Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package gitutil
+
+import (
+	"fmt"
+	"strconv"
+	"time"
+
+	"github.com/gogs/git-module"
+	"github.com/pkg/errors"
+	log "unknwon.dev/clog/v2"
+)
+
+// PullRequestMeta contains metadata for a pull request.
+type PullRequestMeta struct {
+	// The merge base of the pull request.
+	MergeBase string
+	// The commits that are requested to be merged.
+	Commits []*git.Commit
+	// The number of files changed.
+	NumFiles int
+}
+
+func (moduler) PullRequestMeta(headPath, basePath, headBranch, baseBranch string) (*PullRequestMeta, error) {
+	tmpRemoteBranch := baseBranch
+
+	// We need to create a temporary remote when the pull request is sent from a forked repository.
+	if headPath != basePath {
+		tmpRemote := strconv.FormatInt(time.Now().UnixNano(), 10)
+		err := Module.RepoAddRemote(headPath, tmpRemote, basePath, git.AddRemoteOptions{Fetch: true})
+		if err != nil {
+			return nil, fmt.Errorf("add remote: %v", err)
+		}
+		defer func() {
+			err := Module.RepoRemoveRemote(headPath, tmpRemote)
+			if err != nil {
+				log.Error("Failed to remove remote %q [path: %s]: %v", tmpRemote, headPath, err)
+				return
+			}
+		}()
+
+		tmpRemoteBranch = "remotes/" + tmpRemote + "/" + baseBranch
+	}
+
+	mergeBase, err := Module.RepoMergeBase(headPath, tmpRemoteBranch, headBranch)
+	if err != nil {
+		return nil, errors.Wrap(err, "get merge base")
+	}
+
+	commits, err := Module.RepoLog(headPath, mergeBase+"..."+headBranch)
+	if err != nil {
+		return nil, errors.Wrap(err, "get commits")
+	}
+
+	// Count number of changed files
+	names, err := Module.RepoDiffNameOnly(headPath, tmpRemoteBranch, headBranch, git.DiffNameOnlyOptions{NeedsMergeBase: true})
+	if err != nil {
+		return nil, errors.Wrap(err, "get changed files")
+	}
+
+	return &PullRequestMeta{
+		MergeBase: mergeBase,
+		Commits:   commits,
+		NumFiles:  len(names),
+	}, nil
+}

+ 108 - 0
internal/gitutil/pull_request_test.go

@@ -0,0 +1,108 @@
+// Copyright 2020 The Gogs Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package gitutil
+
+import (
+	"fmt"
+	"testing"
+
+	"github.com/gogs/git-module"
+	"github.com/pkg/errors"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestModuler_PullRequestMeta(t *testing.T) {
+	headPath := "/head/path"
+	basePath := "/base/path"
+	headBranch := "head_branch"
+	baseBranch := "base_branch"
+	mergeBase := "MERGE-BASE"
+	changedFiles := []string{"a.go", "b.txt"}
+	commits := []*git.Commit{
+		{ID: git.MustIDFromString("adfd6da3c0a3fb038393144becbf37f14f780087")},
+	}
+
+	MockModule.RepoAddRemote = func(repoPath, name, url string, opts ...git.AddRemoteOptions) error {
+		if repoPath != headPath {
+			return fmt.Errorf("repoPath: want %q but got %q", headPath, repoPath)
+		} else if name == "" {
+			return errors.New("empty name")
+		} else if url != basePath {
+			return fmt.Errorf("url: want %q but got %q", basePath, url)
+		}
+
+		if len(opts) == 0 {
+			return errors.New("no options")
+		} else if !opts[0].Fetch {
+			return fmt.Errorf("opts.Fetch: want %v but got %v", true, opts[0].Fetch)
+		}
+
+		return nil
+	}
+	MockModule.RepoMergeBase = func(repoPath, base, head string, opts ...git.MergeBaseOptions) (string, error) {
+		if repoPath != headPath {
+			return "", fmt.Errorf("repoPath: want %q but got %q", headPath, repoPath)
+		} else if base == "" {
+			return "", errors.New("empty base")
+		} else if head != headBranch {
+			return "", fmt.Errorf("head: want %q but got %q", headBranch, head)
+		}
+
+		return mergeBase, nil
+	}
+	MockModule.RepoLog = func(repoPath, rev string, opts ...git.LogOptions) ([]*git.Commit, error) {
+		if repoPath != headPath {
+			return nil, fmt.Errorf("repoPath: want %q but got %q", headPath, repoPath)
+		}
+
+		expRev := mergeBase + "..." + headBranch
+		if rev != expRev {
+			return nil, fmt.Errorf("rev: want %q but got %q", expRev, rev)
+		}
+
+		return commits, nil
+	}
+	MockModule.RepoDiffNameOnly = func(repoPath, base, head string, opts ...git.DiffNameOnlyOptions) ([]string, error) {
+		if repoPath != headPath {
+			return nil, fmt.Errorf("repoPath: want %q but got %q", headPath, repoPath)
+		} else if base == "" {
+			return nil, errors.New("empty base")
+		} else if head != headBranch {
+			return nil, fmt.Errorf("head: want %q but got %q", headBranch, head)
+		}
+
+		if len(opts) == 0 {
+			return nil, errors.New("no options")
+		} else if !opts[0].NeedsMergeBase {
+			return nil, fmt.Errorf("opts.NeedsMergeBase: want %v but got %v", true, opts[0].NeedsMergeBase)
+		}
+
+		return changedFiles, nil
+	}
+	MockModule.RepoRemoveRemote = func(repoPath, name string, opts ...git.RemoveRemoteOptions) error {
+		if repoPath != headPath {
+			return fmt.Errorf("repoPath: want %q but got %q", headPath, repoPath)
+		} else if name == "" {
+			return errors.New("empty name")
+		}
+
+		return nil
+	}
+	defer func() {
+		MockModule = MockModuleStore{}
+	}()
+
+	meta, err := Module.PullRequestMeta(headPath, basePath, headBranch, baseBranch)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	expMeta := &PullRequestMeta{
+		MergeBase: mergeBase,
+		Commits:   commits,
+		NumFiles:  2,
+	}
+	assert.Equal(t, expMeta, meta)
+}

+ 48 - 0
internal/gitutil/submodule.go

@@ -0,0 +1,48 @@
+// Copyright 2020 The Gogs Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package gitutil
+
+import (
+	"fmt"
+	"net/url"
+	"strings"
+
+	"github.com/gogs/git-module"
+
+	"github.com/G-Node/gogs/internal/lazyregexp"
+)
+
+var scpSyntax = lazyregexp.New(`^([a-zA-Z0-9_]+@)?([a-zA-Z0-9._-]+):(.*)$`)
+
+// InferSubmoduleURL returns the inferred external URL of the submodule at best effort.
+func InferSubmoduleURL(mod *git.Submodule) string {
+	raw := strings.TrimSuffix(mod.URL, "/")
+	raw = strings.TrimSuffix(raw, ".git")
+
+	parsed, err := url.Parse(raw)
+	if err != nil {
+		// Try parse as SCP syntax again
+		match := scpSyntax.FindAllStringSubmatch(raw, -1)
+		if len(match) == 0 {
+			return mod.URL
+		}
+		parsed = &url.URL{
+			Scheme: "http",
+			Host:   match[0][2],
+			Path:   match[0][3],
+		}
+	}
+
+	switch parsed.Scheme {
+	case "http", "https":
+		raw = parsed.String()
+	case "ssh":
+		raw = fmt.Sprintf("http://%s%s", parsed.Host, parsed.Path)
+	default:
+		return raw
+	}
+
+	return fmt.Sprintf("%s/commit/%s", raw, mod.Commit)
+}

+ 58 - 0
internal/gitutil/submodule_test.go

@@ -0,0 +1,58 @@
+// Copyright 2020 The Gogs Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package gitutil
+
+import (
+	"testing"
+
+	"github.com/gogs/git-module"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestInferSubmoduleURL(t *testing.T) {
+	tests := []struct {
+		name      string
+		submodule *git.Submodule
+		expURL    string
+	}{
+		{
+			name: "HTTPS URL",
+			submodule: &git.Submodule{
+				URL:    "https://github.com/gogs/docs-api.git",
+				Commit: "6b08f76a5313fa3d26859515b30aa17a5faa2807",
+			},
+			expURL: "https://github.com/gogs/docs-api/commit/6b08f76a5313fa3d26859515b30aa17a5faa2807",
+		},
+		{
+			name: "SSH URL with port",
+			submodule: &git.Submodule{
+				URL:    "ssh://user@github.com:22/gogs/docs-api.git",
+				Commit: "6b08f76a5313fa3d26859515b30aa17a5faa2807",
+			},
+			expURL: "http://github.com:22/gogs/docs-api/commit/6b08f76a5313fa3d26859515b30aa17a5faa2807",
+		},
+		{
+			name: "SSH URL in SCP syntax",
+			submodule: &git.Submodule{
+				URL:    "git@github.com:gogs/docs-api.git",
+				Commit: "6b08f76a5313fa3d26859515b30aa17a5faa2807",
+			},
+			expURL: "http://github.com/gogs/docs-api/commit/6b08f76a5313fa3d26859515b30aa17a5faa2807",
+		},
+		{
+			name: "bad URL",
+			submodule: &git.Submodule{
+				URL:    "ftp://example.com",
+				Commit: "6b08f76a5313fa3d26859515b30aa17a5faa2807",
+			},
+			expURL: "ftp://example.com",
+		},
+	}
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			assert.Equal(t, test.expURL, InferSubmoduleURL(test.submodule))
+		})
+	}
+}

+ 95 - 0
internal/gitutil/tag.go

@@ -0,0 +1,95 @@
+// Copyright 2020 The Gogs Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package gitutil
+
+import (
+	"github.com/pkg/errors"
+)
+
+// TagsPage contains a list of tags and pagination information.
+type TagsPage struct {
+	// List of tags in the current page.
+	Tags []string
+	// Whether the results include the latest tag.
+	HasLatest bool
+	// When results do not include the latest tag, an indicator of 'after' to go back.
+	PreviousAfter string
+	// Whether there are more tags in the next page.
+	HasNext bool
+}
+
+func (moduler) ListTagsAfter(repoPath, after string, limit int) (*TagsPage, error) {
+	all, err := Module.RepoTags(repoPath)
+	if err != nil {
+		return nil, errors.Wrap(err, "get tags")
+	}
+	total := len(all)
+
+	if limit < 0 {
+		limit = 0
+	}
+
+	// Returns everything when no filter and no limit
+	if after == "" && limit == 0 {
+		return &TagsPage{
+			Tags:      all,
+			HasLatest: true,
+		}, nil
+	}
+
+	// No filter but has a limit, returns first X tags
+	if after == "" && limit > 0 {
+		endIdx := limit
+		if limit > total {
+			endIdx = total
+		}
+		return &TagsPage{
+			Tags:      all[:endIdx],
+			HasLatest: true,
+			HasNext:   limit < total,
+		}, nil
+	}
+
+	// Loop over all tags see if we can find the filter
+	previousAfter := ""
+	found := false
+	tags := make([]string, 0, len(all))
+	for i := range all {
+		if all[i] != after {
+			continue
+		}
+
+		found = true
+		if limit > 0 && i-limit >= 0 {
+			previousAfter = all[i-limit]
+		}
+
+		// In case filter is the oldest one
+		if i+1 < total {
+			tags = all[i+1:]
+		}
+		break
+	}
+
+	if !found {
+		tags = all
+	}
+
+	// If all tags after match is equal to the limit, it reaches the oldest tag as well.
+	if limit == 0 || len(tags) <= limit {
+		return &TagsPage{
+			Tags:          tags,
+			HasLatest:     !found,
+			PreviousAfter: previousAfter,
+		}, nil
+	}
+
+	return &TagsPage{
+		Tags:          tags[:limit],
+		HasLatest:     !found,
+		PreviousAfter: previousAfter,
+		HasNext:       true,
+	}, nil
+}

+ 109 - 0
internal/gitutil/tag_test.go

@@ -0,0 +1,109 @@
+// Copyright 2020 The Gogs Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package gitutil
+
+import (
+	"testing"
+
+	"github.com/gogs/git-module"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestModuler_ListTagsAfter(t *testing.T) {
+	MockModule.RepoTags = func(string, ...git.TagsOptions) ([]string, error) {
+		return []string{
+			"v2.3.0", "v2.2.1", "v2.1.0",
+			"v1.3.0", "v1.2.0", "v1.1.0",
+			"v0.8.0", "v0.5.0", "v0.1.0",
+		}, nil
+	}
+	defer func() {
+		MockModule = MockModuleStore{}
+	}()
+
+	tests := []struct {
+		name        string
+		after       string
+		expTagsPage *TagsPage
+	}{
+		{
+			name: "first page",
+			expTagsPage: &TagsPage{
+				Tags: []string{
+					"v2.3.0", "v2.2.1", "v2.1.0",
+				},
+				HasLatest: true,
+				HasNext:   true,
+			},
+		},
+		{
+			name:  "second page",
+			after: "v2.1.0",
+			expTagsPage: &TagsPage{
+				Tags: []string{
+					"v1.3.0", "v1.2.0", "v1.1.0",
+				},
+				HasLatest: false,
+				HasNext:   true,
+			},
+		},
+		{
+			name:  "last page",
+			after: "v1.1.0",
+			expTagsPage: &TagsPage{
+				Tags: []string{
+					"v0.8.0", "v0.5.0", "v0.1.0",
+				},
+				HasLatest:     false,
+				PreviousAfter: "v2.1.0",
+				HasNext:       false,
+			},
+		},
+
+		{
+			name:  "arbitrary after",
+			after: "v1.2.0",
+			expTagsPage: &TagsPage{
+				Tags: []string{
+					"v1.1.0", "v0.8.0", "v0.5.0",
+				},
+				HasLatest:     false,
+				PreviousAfter: "v2.2.1",
+				HasNext:       true,
+			},
+		},
+		{
+			name:  "after the oldest one",
+			after: "v0.1.0",
+			expTagsPage: &TagsPage{
+				Tags:          []string{},
+				HasLatest:     false,
+				PreviousAfter: "v1.1.0",
+				HasNext:       false,
+			},
+		},
+		{
+			name:  "after does not exist",
+			after: "v2.2.9",
+			expTagsPage: &TagsPage{
+				Tags: []string{
+					"v2.3.0", "v2.2.1", "v2.1.0",
+				},
+				HasLatest: true,
+				HasNext:   true,
+			},
+		},
+	}
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			tagsPage, err := Module.ListTagsAfter("", test.after, 3)
+			if err != nil {
+				t.Fatal(err)
+			}
+
+			assert.Equal(t, test.expTagsPage, tagsPage)
+		})
+	}
+}

+ 1 - 1
internal/httplib/httplib.go

@@ -250,7 +250,7 @@ func (r *Request) getResponse() (*http.Response, error) {
 	}
 
 	if r.req.Method == "GET" && len(paramBody) > 0 {
-		if strings.Index(r.url, "?") != -1 {
+		if strings.Contains(r.url, "?") {
 			r.url += "&" + paramBody
 		} else {
 			r.url = r.url + "?" + paramBody

+ 1 - 6
internal/route/admin/admin.go

@@ -212,16 +212,11 @@ func Config(c *context.Context) {
 	c.Data["User"] = conf.User
 	c.Data["Session"] = conf.Session
 	c.Data["Cache"] = conf.Cache
-	c.Data["HTTP"] = conf.HTTP
-
-	// TODO
 	c.Data["Attachment"] = conf.Attachment
 	c.Data["Release"] = conf.Release
-	c.Data["Time"] = conf.Time
 	c.Data["Picture"] = conf.Picture
+	c.Data["HTTP"] = conf.HTTP
 	c.Data["Mirror"] = conf.Mirror
-
-	// ???
 	c.Data["Webhook"] = conf.Webhook
 	c.Data["Git"] = conf.Git
 

+ 1 - 0
internal/route/api/v1/api.go

@@ -276,6 +276,7 @@ func RegisterRoutes(m *macaron.Macaron) {
 				}, reqRepoAdmin())
 
 				m.Get("/raw/*", context.RepoRef(), repo2.GetRawFile)
+				m.Get("/contents/*", context.RepoRef(), repo2.GetContents)
 				m.Get("/archive/*", repo2.GetArchive)
 				m.Group("/git/trees", func() {
 					m.Get("/:sha", context.RepoRef(), repo2.GetRepoGitTree)

+ 2 - 2
internal/route/api/v1/convert/convert.go

@@ -9,7 +9,7 @@ import (
 
 	"github.com/unknwon/com"
 
-	"github.com/G-Node/git-module"
+	"github.com/gogs/git-module"
 	api "github.com/gogs/go-gogs-client"
 
 	"github.com/G-Node/gogs/internal/db"
@@ -43,7 +43,7 @@ func ToCommit(c *git.Commit) *api.PayloadCommit {
 	}
 	return &api.PayloadCommit{
 		ID:      c.ID.String(),
-		Message: c.Message(),
+		Message: c.Message,
 		URL:     "Not implemented",
 		Author: &api.PayloadUser{
 			Name:     c.Author.Name,

+ 20 - 19
internal/route/api/v1/repo/commits.go

@@ -9,13 +9,14 @@ import (
 	"strings"
 	"time"
 
-	"github.com/G-Node/git-module"
+	"github.com/gogs/git-module"
 	api "github.com/gogs/go-gogs-client"
 
 	"github.com/G-Node/gogs/internal/conf"
 	"github.com/G-Node/gogs/internal/context"
 	"github.com/G-Node/gogs/internal/db"
 	"github.com/G-Node/gogs/internal/db/errors"
+	"github.com/G-Node/gogs/internal/gitutil"
 )
 
 func GetSingleCommit(c *context.APIContext) {
@@ -25,14 +26,14 @@ func GetSingleCommit(c *context.APIContext) {
 		return
 	}
 
-	gitRepo, err := git.OpenRepository(c.Repo.Repository.RepoPath())
+	gitRepo, err := git.Open(c.Repo.Repository.RepoPath())
 	if err != nil {
-		c.ServerError("OpenRepository", err)
+		c.ServerError("open repository", err)
 		return
 	}
-	commit, err := gitRepo.GetCommit(c.Params(":sha"))
+	commit, err := gitRepo.CatFileCommit(c.Params(":sha"))
 	if err != nil {
-		c.NotFoundOrServerError("GetCommit", git.IsErrNotExist, err)
+		c.NotFoundOrServerError("get commit", gitutil.IsErrRevisionNotExist, err)
 		return
 	}
 
@@ -59,8 +60,8 @@ func GetSingleCommit(c *context.APIContext) {
 	}
 
 	// Retrieve parent(s) of the commit
-	apiParents := make([]*api.CommitMeta, commit.ParentCount())
-	for i := 0; i < commit.ParentCount(); i++ {
+	apiParents := make([]*api.CommitMeta, commit.ParentsCount())
+	for i := 0; i < commit.ParentsCount(); i++ {
 		sha, _ := commit.ParentID(i)
 		apiParents[i] = &api.CommitMeta{
 			URL: c.BaseURL + "/repos/" + c.Repo.Repository.FullName() + "/commits/" + sha.String(),
@@ -99,24 +100,24 @@ func GetSingleCommit(c *context.APIContext) {
 }
 
 func GetReferenceSHA(c *context.APIContext) {
-	gitRepo, err := git.OpenRepository(c.Repo.Repository.RepoPath())
+	gitRepo, err := git.Open(c.Repo.Repository.RepoPath())
 	if err != nil {
-		c.ServerError("OpenRepository", err)
+		c.ServerError("open repository", err)
 		return
 	}
 
 	ref := c.Params("*")
-	refType := 0 // 0-undetermined, 1-branch, 2-tag
-	if strings.HasPrefix(ref, git.BRANCH_PREFIX) {
-		ref = strings.TrimPrefix(ref, git.BRANCH_PREFIX)
+	refType := 0 // 0-unknown, 1-branch, 2-tag
+	if strings.HasPrefix(ref, git.RefsHeads) {
+		ref = strings.TrimPrefix(ref, git.RefsHeads)
 		refType = 1
-	} else if strings.HasPrefix(ref, git.TAG_PREFIX) {
-		ref = strings.TrimPrefix(ref, git.TAG_PREFIX)
+	} else if strings.HasPrefix(ref, git.RefsTags) {
+		ref = strings.TrimPrefix(ref, git.RefsTags)
 		refType = 2
 	} else {
-		if gitRepo.IsBranchExist(ref) {
+		if gitRepo.HasBranch(ref) {
 			refType = 1
-		} else if gitRepo.IsTagExist(ref) {
+		} else if gitRepo.HasTag(ref) {
 			refType = 2
 		} else {
 			c.NotFound()
@@ -126,12 +127,12 @@ func GetReferenceSHA(c *context.APIContext) {
 
 	var sha string
 	if refType == 1 {
-		sha, err = gitRepo.GetBranchCommitID(ref)
+		sha, err = gitRepo.BranchCommitID(ref)
 	} else if refType == 2 {
-		sha, err = gitRepo.GetTagCommitID(ref)
+		sha, err = gitRepo.TagCommitID(ref)
 	}
 	if err != nil {
-		c.NotFoundOrServerError("get reference commit ID", git.IsErrNotExist, err)
+		c.NotFoundOrServerError("get reference commit ID", gitutil.IsErrRevisionNotExist, err)
 		return
 	}
 	c.PlainText(http.StatusOK, []byte(sha))

+ 188 - 0
internal/route/api/v1/repo/contents.go

@@ -0,0 +1,188 @@
+// Copyright 2020 The Gogs Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package repo
+
+import (
+	"encoding/base64"
+	"fmt"
+
+	"github.com/G-Node/gogs/internal/context"
+	"github.com/G-Node/gogs/internal/gitutil"
+)
+
+type repoContent struct {
+	Type            string `json:"type"`
+	Target          string `json:"target,omitempty"`
+	SubmoduleGitURL string `json:"submodule_git_url,omitempty"`
+	Encoding        string `json:"encoding,omitempty"`
+	Size            int64  `json:"size"`
+	Name            string `json:"name"`
+	Path            string `json:"path"`
+	Content         string `json:"content,omitempty"`
+	Sha             string `json:"sha"`
+	URL             string `json:"url"`
+	GitURL          string `json:"git_url"`
+	HTMLURL         string `json:"html_url"`
+	DownloadURL     string `json:"download_url"`
+	Links           Links  `json:"_links"`
+}
+
+type Links struct {
+	Git  string `json:"git"`
+	Self string `json:"self"`
+	HTML string `json:"html"`
+}
+
+func GetContents(c *context.APIContext) {
+	treeEntry, err := c.Repo.Commit.TreeEntry(c.Repo.TreePath)
+	if err != nil {
+		c.NotFoundOrServerError("get tree entry", gitutil.IsErrRevisionNotExist, err)
+		return
+	}
+	username := c.Params(":username")
+	reponame := c.Params(":reponame")
+
+	// TODO: figure out the best way to do this
+	// :base-url/:username/:project/raw/:refs/:path
+	templateDownloadURL := "%s/%s/%s/raw/%s"
+	// :base-url/repos/:username/:project/contents/:path
+	templateSelfLink := "%s/repos/%s/%s/contents/%s"
+	// :baseurl/repos/:username/:project/git/trees/:sha
+	templateGitURLLink := "%s/repos/%s/%s/trees/%s"
+	// :baseurl/repos/:username/:project/tree/:sha
+	templateHTMLLLink := "%s/repos/%s/%s/tree/%s"
+
+	gitURL := fmt.Sprintf(templateGitURLLink, c.BaseURL, username, reponame, treeEntry.ID().String())
+	htmlURL := fmt.Sprintf(templateHTMLLLink, c.BaseURL, username, reponame, treeEntry.ID().String())
+	selfURL := fmt.Sprintf(templateSelfLink, c.BaseURL, username, reponame, c.Repo.TreePath)
+
+	// TODO(unknwon): Make a treeEntryToRepoContent helper.
+	contents := &repoContent{
+		Size:        treeEntry.Size(),
+		Name:        treeEntry.Name(),
+		Path:        c.Repo.TreePath,
+		Sha:         treeEntry.ID().String(),
+		URL:         selfURL,
+		GitURL:      gitURL,
+		HTMLURL:     htmlURL,
+		DownloadURL: fmt.Sprintf(templateDownloadURL, c.BaseURL, username, reponame, c.Repo.TreePath),
+		Links: Links{
+			Git:  gitURL,
+			Self: selfURL,
+			HTML: htmlURL,
+		},
+	}
+
+	// A tree entry can only be one of the following types:
+	//   1. Tree (directory)
+	//   2. SubModule
+	//   3. SymLink
+	//   4. Blob (file)
+	if treeEntry.IsCommit() {
+		// TODO(unknwon): submoduleURL is not set as current git-module doesn't handle it properly
+		contents.Type = "submodule"
+		c.JSONSuccess(contents)
+		return
+
+	} else if treeEntry.IsSymlink() {
+		contents.Type = "symlink"
+		blob, err := c.Repo.Commit.Blob(c.Repo.TreePath)
+		if err != nil {
+			c.ServerError("GetBlobByPath", err)
+			return
+		}
+		p, err := blob.Bytes()
+		if err != nil {
+			c.ServerError("Data", err)
+			return
+		}
+		contents.Target = string(p)
+		c.JSONSuccess(contents)
+		return
+
+	} else if treeEntry.IsBlob() {
+		blob, err := c.Repo.Commit.Blob(c.Repo.TreePath)
+		if err != nil {
+			c.ServerError("GetBlobByPath", err)
+			return
+		}
+		p, err := blob.Bytes()
+		if err != nil {
+			c.ServerError("Data", err)
+			return
+		}
+		contents.Content = base64.StdEncoding.EncodeToString(p)
+		contents.Type = "file"
+		c.JSONSuccess(contents)
+		return
+	}
+
+	// TODO: treeEntry.IsExec()
+
+	// treeEntry is a directory
+	dirTree, err := c.Repo.GitRepo.LsTree(treeEntry.ID().String())
+	if err != nil {
+		c.NotFoundOrServerError("get tree", gitutil.IsErrRevisionNotExist, err)
+		return
+	}
+
+	entries, err := dirTree.Entries()
+	if err != nil {
+		c.NotFoundOrServerError("list entries", gitutil.IsErrRevisionNotExist, err)
+		return
+	}
+
+	if len(entries) == 0 {
+		c.JSONSuccess([]string{})
+		return
+	}
+
+	var results = make([]*repoContent, 0, len(entries))
+	for _, entry := range entries {
+		gitURL := fmt.Sprintf(templateGitURLLink, c.BaseURL, username, reponame, entry.ID().String())
+		htmlURL := fmt.Sprintf(templateHTMLLLink, c.BaseURL, username, reponame, entry.ID().String())
+		selfURL := fmt.Sprintf(templateSelfLink, c.BaseURL, username, reponame, c.Repo.TreePath)
+		var contentType string
+		if entry.IsTree() {
+			contentType = "dir"
+		} else if entry.IsCommit() {
+			// TODO(unknwon): submoduleURL is not set as current git-module doesn't handle it properly
+			contentType = "submodule"
+		} else if entry.IsSymlink() {
+			contentType = "symlink"
+			blob, err := c.Repo.Commit.Blob(c.Repo.TreePath)
+			if err != nil {
+				c.ServerError("GetBlobByPath", err)
+				return
+			}
+			p, err := blob.Bytes()
+			if err != nil {
+				c.ServerError("Data", err)
+				return
+			}
+			contents.Target = string(p)
+		} else {
+			contentType = "file"
+		}
+
+		results = append(results, &repoContent{
+			Type:        contentType,
+			Size:        entry.Size(),
+			Name:        entry.Name(),
+			Path:        c.Repo.TreePath,
+			Sha:         entry.ID().String(),
+			URL:         selfURL,
+			GitURL:      gitURL,
+			HTMLURL:     htmlURL,
+			DownloadURL: fmt.Sprintf(templateDownloadURL, c.BaseURL, username, reponame, c.Repo.TreePath),
+			Links: Links{
+				Git:  gitURL,
+				Self: selfURL,
+				HTML: htmlURL,
+			},
+		})
+	}
+	c.JSONSuccess(results)
+}

+ 10 - 11
internal/route/api/v1/repo/file.go

@@ -5,11 +5,11 @@
 package repo
 
 import (
-	"github.com/G-Node/git-module"
-	"github.com/go-macaron/captcha"
+	"github.com/gogs/git-module"
 
 	"github.com/G-Node/gogs/internal/context"
 	"github.com/G-Node/gogs/internal/db"
+	"github.com/G-Node/gogs/internal/gitutil"
 	"github.com/G-Node/gogs/internal/route/repo"
 )
 
@@ -24,22 +24,21 @@ func GetRawFile(c *context.APIContext) {
 		return
 	}
 
-	blob, err := c.Repo.Commit.GetBlobByPath(c.Repo.TreePath)
+	blob, err := c.Repo.Commit.Blob(c.Repo.TreePath)
 	if err != nil {
-		c.NotFoundOrServerError("GetBlobByPath", git.IsErrNotExist, err)
+		c.NotFoundOrServerError("get blob", gitutil.IsErrRevisionNotExist, err)
 		return
 	}
-	cp := captcha.NewCaptcha(captcha.Options{})
-	if err = repo.ServeBlob(c.Context, blob, cp); err != nil {
+	if err = repo.ServeBlob(c.Context, blob); err != nil {
 		c.ServerError("ServeBlob", err)
 	}
 }
 
 func GetArchive(c *context.APIContext) {
 	repoPath := db.RepoPath(c.Params(":username"), c.Params(":reponame"))
-	gitRepo, err := git.OpenRepository(repoPath)
+	gitRepo, err := git.Open(repoPath)
 	if err != nil {
-		c.ServerError("OpenRepository", err)
+		c.ServerError("open repository", err)
 		return
 	}
 	c.Repo.GitRepo = gitRepo
@@ -48,16 +47,16 @@ func GetArchive(c *context.APIContext) {
 }
 
 func GetEditorconfig(c *context.APIContext) {
-	ec, err := c.Repo.GetEditorconfig()
+	ec, err := c.Repo.Editorconfig()
 	if err != nil {
-		c.NotFoundOrServerError("GetEditorconfig", git.IsErrNotExist, err)
+		c.NotFoundOrServerError("get .editorconfig", gitutil.IsErrRevisionNotExist, err)
 		return
 	}
 
 	fileName := c.Params("filename")
 	def, err := ec.GetDefinitionForFilename(fileName)
 	if err != nil {
-		c.ServerError("GetDefinitionForFilename", err)
+		c.ServerError("get definition for filename", err)
 		return
 	}
 	if def == nil {

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است